@twilio/conversations 3.0.0-canary.9 → 3.0.0-canary2.100

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 (42) hide show
  1. package/README.md +22 -18
  2. package/builds/browser.js +1018 -2070
  3. package/builds/browser.js.map +1 -1
  4. package/builds/lib.d.ts +69 -67
  5. package/builds/lib.js +1018 -2070
  6. package/builds/lib.js.map +1 -1
  7. package/builds/twilio-conversations.js +24737 -25259
  8. package/builds/twilio-conversations.min.js +1 -1
  9. package/dist/aggregated-delivery-receipt.js +1 -1
  10. package/dist/aggregated-delivery-receipt.js.map +1 -1
  11. package/dist/client.js +85 -69
  12. package/dist/client.js.map +1 -1
  13. package/dist/command-executor.js +30 -12
  14. package/dist/command-executor.js.map +1 -1
  15. package/dist/conversation.js +87 -19
  16. package/dist/conversation.js.map +1 -1
  17. package/dist/data/conversations.js +20 -4
  18. package/dist/data/conversations.js.map +1 -1
  19. package/dist/data/messages.js +13 -19
  20. package/dist/data/messages.js.map +1 -1
  21. package/dist/data/participants.js +6 -4
  22. package/dist/data/participants.js.map +1 -1
  23. package/dist/data/users.js +4 -2
  24. package/dist/data/users.js.map +1 -1
  25. package/dist/index.js +5 -0
  26. package/dist/index.js.map +1 -1
  27. package/dist/message-builder.js.map +1 -1
  28. package/dist/message.js +15 -12
  29. package/dist/message.js.map +1 -1
  30. package/dist/node_modules/tslib/tslib.es6.js.map +1 -1
  31. package/dist/packages/conversations/package.json.js +1 -1
  32. package/dist/participant.js.map +1 -1
  33. package/dist/push-notification.js.map +1 -1
  34. package/dist/services/network.js +38 -15
  35. package/dist/services/network.js.map +1 -1
  36. package/dist/services/typing-indicator.js +7 -5
  37. package/dist/services/typing-indicator.js.map +1 -1
  38. package/dist/unsent-message.js.map +1 -1
  39. package/dist/user.js +1 -1
  40. package/dist/user.js.map +1 -1
  41. package/dist/util/index.js.map +1 -1
  42. package/package.json +18 -16
@@ -130,11 +130,11 @@ This software includes platform.js under the following license.
130
130
 
131
131
  Object.defineProperty(exports, '__esModule', { value: true });
132
132
 
133
- var uuid = require('uuid');
134
133
  var operationRetrier = require('@twilio/operation-retrier');
134
+ var nanoid = require('nanoid');
135
135
 
136
136
  const trimSlashes = (url) => url.replace(/(^\/+|\/+$)/g, "");
137
- const isMutationConflictResponse = (response) => response.status.code === 202;
137
+ const isMutationConflictResponse = (response) => response.statusCode === 202;
138
138
  class CommandExecutor {
139
139
  constructor(_serviceUrl, _services, _productId) {
140
140
  this._serviceUrl = _serviceUrl;
@@ -159,45 +159,63 @@ class CommandExecutor {
159
159
  getUrl +=
160
160
  "?" +
161
161
  Object.entries(requestBody)
162
- .map((entry) => entry.map(encodeURIComponent).join("="))
162
+ .map((entry) => entry
163
+ .map((component) => encodeURIComponent(String(component)))
164
+ .join("="))
163
165
  .join("&");
164
166
  }
165
- response = await this._services.transport.get(getUrl, finalHeaders, this._productId);
167
+ response = await this._services.transport.get({
168
+ url: getUrl,
169
+ headers: finalHeaders,
170
+ grant: this._productId,
171
+ });
166
172
  break;
167
173
  case "post":
168
- response = await this._services.transport.post(preProcessedUrl, finalHeaders, JSON.stringify(requestBody), this._productId);
174
+ response = await this._services.transport.post({
175
+ url: preProcessedUrl,
176
+ headers: finalHeaders,
177
+ body: JSON.stringify(requestBody),
178
+ grant: this._productId,
179
+ });
169
180
  break;
170
181
  case "delete":
171
- response = await this._services.transport.delete(preProcessedUrl, finalHeaders, {}, this._productId);
182
+ response = await this._services.transport.delete({
183
+ url: preProcessedUrl,
184
+ headers: finalHeaders,
185
+ grant: this._productId,
186
+ });
172
187
  break;
173
188
  }
174
- if (response.status.code < 200 || response.status.code >= 300) {
175
- throw new Error(`Request responded with a non-success code ${response.status.code}`);
189
+ if (response.statusCode < 200 || response.statusCode >= 300) {
190
+ throw new Error(`Request responded with a non-success code ${response.statusCode}`);
176
191
  }
177
192
  return response;
178
193
  }
179
194
  async fetchResource(url, requestBody) {
180
195
  const maxAttemptsCount = 6;
181
196
  try {
197
+ // todo: remove any after the release of new Twilsock
182
198
  const result = await new operationRetrier.AsyncRetrier({
183
199
  min: 50,
184
200
  max: 1600,
185
201
  maxAttemptsCount,
186
202
  }).run(() => this._makeRequest("get", url, requestBody));
187
- return result.body;
203
+ return JSON.parse(result.payload);
188
204
  }
189
205
  catch (_a) {
190
206
  throw new Error(`Fetch resource from "${url}" failed.`);
191
207
  }
192
208
  }
193
209
  async mutateResource(method, url, requestBody) {
210
+ // todo: remove any after the release of new Twilsock
194
211
  const result = await this._makeRequest(method, url, requestBody, {
195
- "X-Twilio-Mutation-Id": uuid.v4(),
212
+ "X-Twilio-Mutation-Id": nanoid.nanoid(),
196
213
  });
214
+ const parsedPayload = JSON.parse(result.payload);
197
215
  if (isMutationConflictResponse(result)) {
198
- return await this.fetchResource(result.body.resource_url);
216
+ return await this.fetchResource(parsedPayload.resource_url);
199
217
  }
200
- return result.body;
218
+ return parsedPayload;
201
219
  }
202
220
  }
203
221
 
@@ -1 +1 @@
1
- {"version":3,"file":"command-executor.js","sources":["../src/command-executor.ts"],"sourcesContent":["import { TransportResult as Result, Transport } from \"twilsock\";\nimport { MutationConflictResponse } from \"./interfaces/commands/mutation-conflict\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { AsyncRetrier } from \"@twilio/operation-retrier\";\n\nexport interface CommandExecutorServices {\n transport: Transport;\n}\n\nconst trimSlashes = (url: string): string => url.replace(/(^\\/+|\\/+$)/g, \"\");\n\nconst isMutationConflictResponse = (\n response: Result<unknown>\n): response is Result<MutationConflictResponse> => response.status.code === 202;\n\nclass CommandExecutor {\n constructor(\n private _serviceUrl: string,\n private _services: CommandExecutorServices,\n private _productId?: string\n ) {}\n\n private _preProcessUrl(url: string): string {\n const trimmedUrl = trimSlashes(url);\n\n if (/^https?:\\/\\//.test(url)) {\n return trimmedUrl;\n }\n\n return `${trimSlashes(this._serviceUrl)}/${trimmedUrl}`;\n }\n\n private async _makeRequest<REQ = void, RESP = void>(\n method: \"get\" | \"post\" | \"delete\",\n url: string,\n requestBody?: REQ,\n headers?: Record<string, string>\n ): Promise<Result<RESP>> {\n const preProcessedUrl = this._preProcessUrl(url);\n const finalHeaders = {\n \"Content-Type\": \"application/json; charset=utf-8\",\n ...(headers || {}),\n };\n let response: Result<RESP>;\n\n switch (method) {\n case \"get\":\n let getUrl = preProcessedUrl;\n\n if (requestBody) {\n getUrl +=\n \"?\" +\n Object.entries(requestBody)\n .map((entry) => entry.map(encodeURIComponent).join(\"=\"))\n .join(\"&\");\n }\n\n response = await this._services.transport.get(\n getUrl,\n finalHeaders,\n this._productId\n );\n break;\n case \"post\":\n response = await this._services.transport.post(\n preProcessedUrl,\n finalHeaders,\n JSON.stringify(requestBody),\n this._productId\n );\n break;\n case \"delete\":\n response = await this._services.transport.delete(\n preProcessedUrl,\n finalHeaders,\n {},\n this._productId\n );\n break;\n }\n\n if (response.status.code < 200 || response.status.code >= 300) {\n throw new Error(\n `Request responded with a non-success code ${response.status.code}`\n );\n }\n\n return response;\n }\n\n public async fetchResource<REQ = void, RESP = void>(\n url: string,\n requestBody?: REQ\n ): Promise<RESP> {\n const maxAttemptsCount = 6;\n try {\n const result = await new AsyncRetrier({\n min: 50,\n max: 1600,\n maxAttemptsCount,\n }).run(() => this._makeRequest<REQ, RESP>(\"get\", url, requestBody));\n return result.body;\n } catch {\n throw new Error(`Fetch resource from \"${url}\" failed.`);\n }\n }\n\n public async mutateResource<REQ = void, RESP = void>(\n method: \"post\" | \"delete\",\n url: string,\n requestBody?: REQ\n ): Promise<RESP> {\n const result = await this._makeRequest<REQ, RESP>(\n method,\n url,\n requestBody,\n {\n \"X-Twilio-Mutation-Id\": uuidv4(),\n }\n );\n\n if (isMutationConflictResponse(result)) {\n return await this.fetchResource<undefined, RESP>(\n result.body.resource_url\n );\n }\n\n return result.body;\n }\n}\n\nexport { CommandExecutor };\n"],"names":["AsyncRetrier","uuidv4"],"mappings":"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"}
1
+ {"version":3,"file":"command-executor.js","sources":["../src/command-executor.ts"],"sourcesContent":["import { TwilsockClient, HttpResponse } from \"twilsock\";\nimport { AsyncRetrier } from \"@twilio/operation-retrier\";\nimport { nanoid } from \"nanoid\";\n\nexport interface CommandExecutorServices {\n transport: TwilsockClient;\n}\n\nconst trimSlashes = (url: string): string => url.replace(/(^\\/+|\\/+$)/g, \"\");\n\nconst isMutationConflictResponse = (response: HttpResponse): boolean =>\n response.statusCode === 202;\n\nclass CommandExecutor {\n constructor(\n private _serviceUrl: string,\n private _services: CommandExecutorServices,\n private _productId?: string\n ) {}\n\n private _preProcessUrl(url: string): string {\n const trimmedUrl = trimSlashes(url);\n\n if (/^https?:\\/\\//.test(url)) {\n return trimmedUrl;\n }\n\n return `${trimSlashes(this._serviceUrl)}/${trimmedUrl}`;\n }\n\n private async _makeRequest<REQ = void, RESP = void>(\n method: \"get\" | \"post\" | \"delete\",\n url: string,\n requestBody?: REQ,\n headers?: Record<string, string>\n ): Promise<HttpResponse> {\n const preProcessedUrl = this._preProcessUrl(url);\n const finalHeaders = {\n \"Content-Type\": \"application/json; charset=utf-8\",\n ...(headers || {}),\n };\n let response: HttpResponse;\n\n switch (method) {\n case \"get\":\n let getUrl = preProcessedUrl;\n\n if (requestBody) {\n getUrl +=\n \"?\" +\n Object.entries(requestBody)\n .map((entry) =>\n entry\n .map((component) => encodeURIComponent(String(component)))\n .join(\"=\")\n )\n .join(\"&\");\n }\n\n response = await this._services.transport.get({\n url: getUrl,\n headers: finalHeaders,\n grant: this._productId,\n });\n break;\n case \"post\":\n response = await this._services.transport.post({\n url: preProcessedUrl,\n headers: finalHeaders,\n body: JSON.stringify(requestBody),\n grant: this._productId,\n });\n break;\n case \"delete\":\n response = await this._services.transport.delete({\n url: preProcessedUrl,\n headers: finalHeaders,\n grant: this._productId,\n });\n break;\n }\n\n if (response.statusCode < 200 || response.statusCode >= 300) {\n throw new Error(\n `Request responded with a non-success code ${response.statusCode}`\n );\n }\n\n return response;\n }\n\n public async fetchResource<REQ = void, RESP = void>(\n url: string,\n requestBody?: REQ\n ): Promise<RESP> {\n const maxAttemptsCount = 6;\n try {\n // todo: remove any after the release of new Twilsock\n const result = await new AsyncRetrier({\n min: 50,\n max: 1600,\n maxAttemptsCount,\n }).run(() => this._makeRequest<REQ, RESP>(\"get\", url, requestBody));\n return JSON.parse(result.payload);\n } catch {\n throw new Error(`Fetch resource from \"${url}\" failed.`);\n }\n }\n\n public async mutateResource<REQ = void, RESP = void>(\n method: \"post\" | \"delete\",\n url: string,\n requestBody?: REQ\n ): Promise<RESP> {\n // todo: remove any after the release of new Twilsock\n const result = await this._makeRequest<REQ, RESP>(\n method,\n url,\n requestBody,\n {\n \"X-Twilio-Mutation-Id\": nanoid(),\n }\n );\n\n const parsedPayload = JSON.parse(result.payload);\n\n if (isMutationConflictResponse(result)) {\n return await this.fetchResource<undefined, RESP>(\n parsedPayload.resource_url\n );\n }\n\n return parsedPayload;\n }\n}\n\nexport { CommandExecutor };\n"],"names":["AsyncRetrier","nanoid"],"mappings":"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"}
@@ -324,7 +324,9 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
324
324
  update.attributes = {};
325
325
  }
326
326
  try {
327
- update.dateCreated && (update.dateCreated = new Date(update.dateCreated));
327
+ if (update.dateCreated) {
328
+ update.dateCreated = new Date(update.dateCreated);
329
+ }
328
330
  }
329
331
  catch (e) {
330
332
  Conversation._logger.warn("Retrieved malformed dateCreated from the server for conversation: " +
@@ -332,7 +334,9 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
332
334
  delete update.dateCreated;
333
335
  }
334
336
  try {
335
- update.dateUpdated && (update.dateUpdated = new Date(update.dateUpdated));
337
+ if (update.dateUpdated) {
338
+ update.dateUpdated = new Date(update.dateUpdated);
339
+ }
336
340
  }
337
341
  catch (e) {
338
342
  Conversation._logger.warn("Retrieved malformed dateUpdated from the server for conversation: " +
@@ -439,6 +443,7 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
439
443
  const url = new index.UriBuilder(this._configuration.links.conversations)
440
444
  .path(this.sid)
441
445
  .build();
446
+ // todo: remove any after the release of new Twilsock
442
447
  const response = await this._services.network.get(url);
443
448
  return (_a = response.body.participants_count) !== null && _a !== void 0 ? _a : 0;
444
449
  }
@@ -472,11 +477,12 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
472
477
  const url = new index.UriBuilder(this._configuration.links.conversations)
473
478
  .path(this.sid)
474
479
  .build();
480
+ // todo: remove any after the release of new Twilsock
475
481
  const response = await this._services.network.get(url);
476
482
  return (_a = response.body.messages_count) !== null && _a !== void 0 ? _a : 0;
477
483
  }
478
484
  /**
479
- * Get unread messages count for the user if they are a participant of this
485
+ * Get count of unread messages for the user if they are a participant of this
480
486
  * conversation. Rejects if the user is not a participant of the conversation.
481
487
  *
482
488
  * Use this method to obtain the number of unread messages together with
@@ -484,17 +490,25 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
484
490
  * message indices which may have gaps. See {@link Message.index} for details.
485
491
  *
486
492
  * This method is semi-realtime. This means that this data will be eventually
487
- * correct, but will also be possibly incorrect for a few seconds. The
493
+ * correct, but it will also be possibly incorrect for a few seconds. The
488
494
  * Conversations system does not provide real time events for counter values
489
495
  * changes.
490
496
  *
491
497
  * This is useful for any UI badges, but it is not recommended to build any
492
498
  * core application logic based on these counters being accurate in real time.
499
+ *
500
+ * If the read horizon is not set, this function will return null. This could mean
501
+ * that all messages in the conversation are unread, or that the read horizon system
502
+ * is not being used. How to interpret this `null` value is up to the customer application.
503
+ *
504
+ * @return Number of unread messages based on the current read horizon set for
505
+ * the user or `null` if the read horizon is not set.
493
506
  */
494
507
  async getUnreadMessagesCount() {
495
508
  const url = new index.UriBuilder(this._configuration.links.myConversations)
496
509
  .path(this.sid)
497
510
  .build();
511
+ // todo: remove any after the release of new Twilsock
498
512
  const response = await this._services.network.get(url);
499
513
  if (response.body.conversation_sid !== this.sid) {
500
514
  throw new Error("Conversation was not found in the user conversations list");
@@ -528,8 +542,6 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
528
542
  * argument, it will assume that the string is an identity or SID.
529
543
  * @param participant Identity, SID or the participant object to remove.
530
544
  */
531
- /* eslint-disable @typescript-eslint/ban-ts-comment */
532
- // @ts-ignore TODO: fix validateTypesAsync typing
533
545
  async removeParticipant(participant) {
534
546
  await this._participantsEntity.remove(typeof participant === "string" ? participant : participant.sid);
535
547
  }
@@ -543,13 +555,48 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
543
555
  * @return Index of the new message.
544
556
  */
545
557
  async sendMessage(message, messageAttributes, emailOptions) {
546
- var _a, _b;
547
- if (typeof message === "string" || message === null) {
548
- const response = await this._messagesEntity.send(message, messageAttributes, emailOptions);
549
- return (_a = index.parseToNumber(response.index)) !== null && _a !== void 0 ? _a : 0;
558
+ const response = typeof message === "string" || message === null
559
+ ? await this._messagesEntity.send(message, messageAttributes, emailOptions)
560
+ : await this._messagesEntity.sendMedia(message, messageAttributes, emailOptions);
561
+ const type = typeof message === "string" || message === null ? "text" : "media";
562
+ let responseAttributes;
563
+ try {
564
+ responseAttributes = JSON.parse(response.attributes);
550
565
  }
551
- const response = await this._messagesEntity.sendMedia(message, messageAttributes, emailOptions);
552
- return (_b = index.parseToNumber(response.index)) !== null && _b !== void 0 ? _b : 0;
566
+ catch (e) { }
567
+ const messageData = {
568
+ sid: response.sid,
569
+ text: response.body,
570
+ type,
571
+ author: response.author,
572
+ subject: response.subject,
573
+ lastUpdatedBy: response.participant_sid,
574
+ attributes: responseAttributes,
575
+ dateUpdated: response.date_updated,
576
+ timestamp: response.date_created,
577
+ memberSid: response.participant_sid,
578
+ medias: Array.isArray(response.media)
579
+ ? response.media.map((media) => ({
580
+ sid: media["sid"],
581
+ size: Number(media["size"]),
582
+ category: media["category"],
583
+ filename: media["filename"],
584
+ contentType: media["content_type"],
585
+ }))
586
+ : null,
587
+ media: response.media &&
588
+ typeof response.media === "object" &&
589
+ !Array.isArray(response.media)
590
+ ? {
591
+ sid: response.media["sid"],
592
+ size: Number(response.media["size"]),
593
+ category: response.media["category"],
594
+ filename: response.media["filename"],
595
+ contentType: response.media["content_type"],
596
+ }
597
+ : null,
598
+ };
599
+ return this._messagesEntity._upsertMessage(response.index, messageData);
553
600
  }
554
601
  /**
555
602
  * New interface to prepare for sending a message.
@@ -574,7 +621,7 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
574
621
  }
575
622
  /**
576
623
  * Set all messages in the conversation unread.
577
- * @return Resulting unread messages count in the conversation.
624
+ * @returns New count of unread messages after this update.
578
625
  */
579
626
  async setAllMessagesUnread() {
580
627
  await this._subscribeStreams();
@@ -622,7 +669,7 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
622
669
  * Set the last read message index to the current read horizon.
623
670
  * @param index Message index to set as last read. If null is provided, then
624
671
  * the behavior is identical to {@link Conversation.setAllMessagesUnread}.
625
- * @returns Resulting unread messages count in the conversation.
672
+ * @returns New count of unread messages after this update.
626
673
  */
627
674
  async updateLastReadMessageIndex(index) {
628
675
  await this._subscribeStreams();
@@ -673,6 +720,29 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
673
720
  throw err;
674
721
  }
675
722
  }
723
+ /**
724
+ * Fetch participants and messages of the conversation. This method needs to
725
+ * be called during conversation initialization to catch broken conversations
726
+ * (broken conversations are conversations that have essential Sync entities
727
+ * missing, i.e. the conversation document, the messages list or the
728
+ * participant map). In case of this conversation being broken, the method
729
+ * will throw an exception that will be caught and handled gracefully.
730
+ * @internal
731
+ */
732
+ async _fetchStreams() {
733
+ var _a, _b;
734
+ await this._subscribe();
735
+ Conversation._logger.trace("_streamsAvailable, this.entity.data=", (_a = this._entity) === null || _a === void 0 ? void 0 : _a.data);
736
+ const data = (_b = this._entity) === null || _b === void 0 ? void 0 : _b.data;
737
+ this._messagesList = await this._services.syncClient.list({
738
+ id: data.messages,
739
+ mode: "open_existing",
740
+ });
741
+ this._participantsMap = await this._services.syncClient.map({
742
+ id: data.roster,
743
+ mode: "open_existing",
744
+ });
745
+ }
676
746
  /**
677
747
  * Load the attributes of this conversation and instantiate its participants
678
748
  * and messages. This or _subscribe will need to be called before any events
@@ -681,7 +751,7 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
681
751
  * @internal
682
752
  */
683
753
  async _subscribeStreams() {
684
- var _a, _b;
754
+ var _a, _b, _c, _d;
685
755
  try {
686
756
  await this._subscribe();
687
757
  Conversation._logger.trace("_subscribeStreams, this.entity.data=", (_a = this._entity) === null || _a === void 0 ? void 0 : _a.data);
@@ -689,8 +759,8 @@ class Conversation extends replayEventEmitter.ReplayEventEmitter {
689
759
  const messagesObjectName = data.messages;
690
760
  const rosterObjectName = data.roster;
691
761
  await Promise.all([
692
- this._messagesEntity.subscribe(messagesObjectName),
693
- this._participantsEntity.subscribe(rosterObjectName),
762
+ this._messagesEntity.subscribe((_c = this._messagesList) !== null && _c !== void 0 ? _c : messagesObjectName),
763
+ this._participantsEntity.subscribe((_d = this._participantsMap) !== null && _d !== void 0 ? _d : rosterObjectName),
694
764
  ]);
695
765
  }
696
766
  catch (err) {
@@ -1017,8 +1087,6 @@ tslib_es6.__decorate([
1017
1087
  tslib_es6.__decorate([
1018
1088
  declarativeTypeValidator.validateTypesAsync([
1019
1089
  "string",
1020
- /* eslint-disable @typescript-eslint/ban-ts-comment */
1021
- // @ts-ignore TODO: fix validateTypesAsync typing
1022
1090
  FormData,
1023
1091
  declarativeTypeValidator.literal(null),
1024
1092
  declarativeTypeValidator.objectSchema("media options", {