@twilio/conversations 2.1.0-rc.0 → 2.1.0-rc.7
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.
- package/CHANGELOG.md +61 -0
- package/NOTICE.txt +679 -0
- package/builds/browser.js +675 -588
- package/builds/browser.js.map +1 -1
- package/builds/lib.d.ts +301 -122
- package/builds/lib.js +675 -588
- package/builds/lib.js.map +1 -1
- package/builds/twilio-conversations.js +853 -910
- package/builds/twilio-conversations.min.js +2 -14
- package/dist/aggregated-delivery-receipt.js +6 -1
- package/dist/aggregated-delivery-receipt.js.map +1 -1
- package/dist/client.js +165 -142
- package/dist/client.js.map +1 -1
- package/dist/command-executor.js +16 -14
- package/dist/command-executor.js.map +1 -1
- package/dist/configuration.js +14 -10
- package/dist/configuration.js.map +1 -1
- package/dist/conversation.js +212 -153
- package/dist/conversation.js.map +1 -1
- package/dist/data/conversations.js +82 -78
- package/dist/data/conversations.js.map +1 -1
- package/dist/data/messages.js +42 -38
- package/dist/data/messages.js.map +1 -1
- package/dist/data/participants.js +93 -75
- package/dist/data/participants.js.map +1 -1
- package/dist/data/users.js +24 -22
- package/dist/data/users.js.map +1 -1
- package/dist/detailed-delivery-receipt.js +1 -1
- package/dist/detailed-delivery-receipt.js.map +1 -1
- package/dist/interfaces/attributes.js +4 -4
- package/dist/interfaces/attributes.js.map +1 -1
- package/dist/interfaces/notification-types.js +5 -5
- package/dist/interfaces/notification-types.js.map +1 -1
- package/dist/logger.js +36 -15
- package/dist/logger.js.map +1 -1
- package/dist/media.js +21 -9
- package/dist/media.js.map +1 -1
- package/dist/message-builder.js +10 -9
- package/dist/message-builder.js.map +1 -1
- package/dist/message.js +131 -83
- package/dist/message.js.map +1 -1
- package/dist/packages/conversations/package.json.js +1 -1
- package/dist/participant.js +85 -51
- package/dist/participant.js.map +1 -1
- package/dist/push-notification.js.map +1 -1
- package/dist/rest-paginator.js +16 -6
- package/dist/rest-paginator.js.map +1 -1
- package/dist/services/network.js +18 -14
- package/dist/services/network.js.map +1 -1
- package/dist/services/typing-indicator.js +20 -17
- package/dist/services/typing-indicator.js.map +1 -1
- package/dist/unsent-message.js.map +1 -1
- package/dist/user.js +85 -59
- package/dist/user.js.map +1 -1
- package/dist/util/deferred.js +3 -1
- package/dist/util/deferred.js.map +1 -1
- package/dist/util/index.js +6 -6
- package/dist/util/index.js.map +1 -1
- package/docs/assets/js/search.js +1 -1
- package/docs/classes/AggregatedDeliveryReceipt.html +0 -117
- package/docs/classes/Client.html +24 -147
- package/docs/classes/Conversation.html +30 -147
- package/docs/classes/DetailedDeliveryReceipt.html +1 -118
- package/docs/classes/Media.html +0 -117
- package/docs/classes/Message.html +7 -124
- package/docs/classes/MessageBuilder.html +2 -119
- package/docs/classes/Participant.html +7 -124
- package/docs/classes/PushNotification.html +0 -117
- package/docs/classes/RestPaginator.html +0 -117
- package/docs/classes/UnsentMessage.html +0 -117
- package/docs/classes/User.html +7 -124
- package/docs/index.html +56 -0
- package/docs/interfaces/ClientOptions.html +0 -117
- package/docs/interfaces/ConversationBindings.html +0 -117
- package/docs/interfaces/ConversationEmailBinding.html +0 -117
- package/docs/interfaces/ConversationState.html +0 -117
- package/docs/interfaces/CreateConversationOptions.html +1 -118
- package/docs/interfaces/LastMessage.html +0 -117
- package/docs/interfaces/Paginator.html +0 -117
- package/docs/interfaces/ParticipantBindings.html +0 -117
- package/docs/interfaces/ParticipantEmailBinding.html +0 -117
- package/docs/interfaces/PushNotificationData.html +0 -117
- package/docs/interfaces/SendEmailOptions.html +0 -117
- package/docs/interfaces/SendMediaOptions.html +0 -117
- package/docs/modules.html +56 -0
- package/package.json +23 -17
package/dist/participant.js
CHANGED
@@ -142,7 +142,7 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
|
|
142
142
|
|
143
143
|
var isEqual__default = /*#__PURE__*/_interopDefaultLegacy(isEqual);
|
144
144
|
|
145
|
-
const log = logger.Logger.scope(
|
145
|
+
const log = logger.Logger.scope("Participant");
|
146
146
|
/**
|
147
147
|
* A participant represents a remote client in a conversation.
|
148
148
|
*/
|
@@ -151,70 +151,95 @@ class Participant extends replayEventEmitter.ReplayEventEmitter {
|
|
151
151
|
* @internal
|
152
152
|
*/
|
153
153
|
constructor(data, sid, conversation, links, services) {
|
154
|
-
var _a;
|
154
|
+
var _a, _b;
|
155
155
|
super();
|
156
156
|
this.conversation = conversation;
|
157
157
|
this.links = links;
|
158
158
|
this.services = services;
|
159
159
|
this.state = {
|
160
|
-
attributes: index.parseAttributes(data.attributes,
|
160
|
+
attributes: index.parseAttributes(data.attributes, "Retrieved malformed attributes from the server for participant: " +
|
161
|
+
sid, log),
|
161
162
|
dateCreated: data.dateCreated ? index.parseTime(data.dateCreated) : null,
|
162
163
|
dateUpdated: data.dateCreated ? index.parseTime(data.dateUpdated) : null,
|
163
164
|
sid: sid,
|
164
165
|
typingTimeout: null,
|
165
166
|
isTyping: false,
|
166
|
-
identity: data.identity
|
167
|
-
roleSid: data.roleSid
|
168
|
-
lastReadMessageIndex: Number.isInteger(data.lastConsumedMessageIndex)
|
169
|
-
|
170
|
-
|
167
|
+
identity: data.identity,
|
168
|
+
roleSid: (_a = data.roleSid) !== null && _a !== void 0 ? _a : "",
|
169
|
+
lastReadMessageIndex: Number.isInteger(data.lastConsumedMessageIndex)
|
170
|
+
? data.lastConsumedMessageIndex
|
171
|
+
: null,
|
172
|
+
lastReadTimestamp: data.lastConsumptionTimestamp
|
173
|
+
? index.parseTime(data.lastConsumptionTimestamp)
|
174
|
+
: null,
|
175
|
+
type: data.type || "chat",
|
171
176
|
userInfo: data.userInfo,
|
172
|
-
bindings: (
|
177
|
+
bindings: (_b = data.bindings) !== null && _b !== void 0 ? _b : {},
|
173
178
|
};
|
174
179
|
if (!data.identity && !data.type) {
|
175
|
-
throw new Error(
|
180
|
+
throw new Error("Received invalid Participant object from server: Missing identity or type of Participant.");
|
176
181
|
}
|
177
182
|
}
|
178
183
|
/**
|
179
184
|
* The server-assigned unique identifier for the participant.
|
180
185
|
*/
|
181
|
-
get sid() {
|
186
|
+
get sid() {
|
187
|
+
return this.state.sid;
|
188
|
+
}
|
182
189
|
/**
|
183
190
|
* Custom attributes of the participant.
|
184
191
|
*/
|
185
|
-
get attributes() {
|
192
|
+
get attributes() {
|
193
|
+
return this.state.attributes;
|
194
|
+
}
|
186
195
|
/**
|
187
196
|
* Date this participant was created on.
|
188
197
|
*/
|
189
|
-
get dateCreated() {
|
198
|
+
get dateCreated() {
|
199
|
+
return this.state.dateCreated;
|
200
|
+
}
|
190
201
|
/**
|
191
202
|
* Date this participant was last updated on.
|
192
203
|
*/
|
193
|
-
get dateUpdated() {
|
204
|
+
get dateUpdated() {
|
205
|
+
return this.state.dateUpdated;
|
206
|
+
}
|
194
207
|
/**
|
195
208
|
* Identity of the participant.
|
196
209
|
*/
|
197
|
-
get identity() {
|
210
|
+
get identity() {
|
211
|
+
return this.state.identity;
|
212
|
+
}
|
198
213
|
/**
|
199
214
|
* Indicates whether the participant is currently typing.
|
200
215
|
*/
|
201
|
-
get isTyping() {
|
216
|
+
get isTyping() {
|
217
|
+
return this.state.isTyping;
|
218
|
+
}
|
202
219
|
/**
|
203
220
|
* The index of the last read message by the participant.
|
204
221
|
* Note that retrieving messages on a client endpoint does not mean that messages are read,
|
205
222
|
* please consider reading about the [Read Horizon feature](https://www.twilio.com/docs/api/chat/guides/consumption-horizon)
|
206
223
|
* to find out about the proper way to mark messages as read.
|
207
224
|
*/
|
208
|
-
get lastReadMessageIndex() {
|
225
|
+
get lastReadMessageIndex() {
|
226
|
+
return this.state.lastReadMessageIndex;
|
227
|
+
}
|
209
228
|
/**
|
210
229
|
* Date of the most recent read horizon update.
|
211
230
|
*/
|
212
|
-
get lastReadTimestamp() {
|
213
|
-
|
231
|
+
get lastReadTimestamp() {
|
232
|
+
return this.state.lastReadTimestamp;
|
233
|
+
}
|
234
|
+
get roleSid() {
|
235
|
+
return this.state.roleSid;
|
236
|
+
}
|
214
237
|
/**
|
215
238
|
* Type of the participant.
|
216
239
|
*/
|
217
|
-
get type() {
|
240
|
+
get type() {
|
241
|
+
return this.state.type;
|
242
|
+
}
|
218
243
|
/**
|
219
244
|
* Get the bindings mapping for the current participant.
|
220
245
|
* Available binding depends on the participant type.
|
@@ -224,17 +249,22 @@ class Participant extends replayEventEmitter.ReplayEventEmitter {
|
|
224
249
|
* each participant type.
|
225
250
|
* See also {ParticipantEmailBinding}, the only available currently binding descriptor.
|
226
251
|
*/
|
227
|
-
get bindings() {
|
252
|
+
get bindings() {
|
253
|
+
var _a;
|
254
|
+
return (_a = this.state.bindings) !== null && _a !== void 0 ? _a : {};
|
255
|
+
}
|
228
256
|
/**
|
229
257
|
* Internal method used to start or reset the typing indicator timeout (with event emitting).
|
230
258
|
* @internal
|
231
259
|
*/
|
232
260
|
_startTyping(timeout) {
|
233
|
-
|
261
|
+
if (this.state.typingTimeout) {
|
262
|
+
clearTimeout(this.state.typingTimeout);
|
263
|
+
}
|
234
264
|
this.state.isTyping = true;
|
235
|
-
this.emit(
|
236
|
-
this.conversation.emit(
|
237
|
-
this.state.typingTimeout = setTimeout(() => this._endTyping(), timeout);
|
265
|
+
this.emit("typingStarted", this);
|
266
|
+
this.conversation.emit("typingStarted", this);
|
267
|
+
this.state.typingTimeout = Number(setTimeout(() => this._endTyping(), timeout));
|
238
268
|
return this;
|
239
269
|
}
|
240
270
|
/**
|
@@ -246,8 +276,8 @@ class Participant extends replayEventEmitter.ReplayEventEmitter {
|
|
246
276
|
return;
|
247
277
|
}
|
248
278
|
this.state.isTyping = false;
|
249
|
-
this.emit(
|
250
|
-
this.conversation.emit(
|
279
|
+
this.emit("typingEnded", this);
|
280
|
+
this.conversation.emit("typingEnded", this);
|
251
281
|
clearInterval(this.state.typingTimeout);
|
252
282
|
this.state.typingTimeout = null;
|
253
283
|
}
|
@@ -256,47 +286,51 @@ class Participant extends replayEventEmitter.ReplayEventEmitter {
|
|
256
286
|
* @internal
|
257
287
|
*/
|
258
288
|
_update(data) {
|
259
|
-
|
260
|
-
|
289
|
+
const updateReasons = [];
|
290
|
+
const updateAttributes = index.parseAttributes(data.attributes, "Retrieved malformed attributes from the server for participant: " +
|
291
|
+
this.state.sid, log);
|
261
292
|
if (data.attributes && !isEqual__default['default'](this.state.attributes, updateAttributes)) {
|
262
293
|
this.state.attributes = updateAttributes;
|
263
|
-
updateReasons.push(
|
294
|
+
updateReasons.push("attributes");
|
264
295
|
}
|
265
|
-
|
296
|
+
const updatedDateUpdated = index.parseTime(data.dateUpdated);
|
266
297
|
if (data.dateUpdated &&
|
267
|
-
updatedDateUpdated
|
298
|
+
(updatedDateUpdated === null || updatedDateUpdated === void 0 ? void 0 : updatedDateUpdated.getTime()) !==
|
299
|
+
(this.state.dateUpdated && this.state.dateUpdated.getTime())) {
|
268
300
|
this.state.dateUpdated = updatedDateUpdated;
|
269
|
-
updateReasons.push(
|
301
|
+
updateReasons.push("dateUpdated");
|
270
302
|
}
|
271
|
-
|
303
|
+
const updatedDateCreated = index.parseTime(data.dateCreated);
|
272
304
|
if (data.dateCreated &&
|
273
|
-
updatedDateCreated
|
305
|
+
(updatedDateCreated === null || updatedDateCreated === void 0 ? void 0 : updatedDateCreated.getTime()) !==
|
306
|
+
(this.state.dateCreated && this.state.dateCreated.getTime())) {
|
274
307
|
this.state.dateCreated = updatedDateCreated;
|
275
|
-
updateReasons.push(
|
308
|
+
updateReasons.push("dateCreated");
|
276
309
|
}
|
277
310
|
if (data.roleSid && this.state.roleSid !== data.roleSid) {
|
278
311
|
this.state.roleSid = data.roleSid;
|
279
|
-
updateReasons.push(
|
312
|
+
updateReasons.push("roleSid");
|
280
313
|
}
|
281
|
-
if ((Number.isInteger(data.lastConsumedMessageIndex) ||
|
282
|
-
|
314
|
+
if ((Number.isInteger(data.lastConsumedMessageIndex) ||
|
315
|
+
data.lastConsumedMessageIndex === null) &&
|
316
|
+
this.state.lastReadMessageIndex !== data.lastConsumedMessageIndex) {
|
283
317
|
this.state.lastReadMessageIndex = data.lastConsumedMessageIndex;
|
284
|
-
updateReasons.push(
|
318
|
+
updateReasons.push("lastReadMessageIndex");
|
285
319
|
}
|
286
320
|
if (data.lastConsumptionTimestamp) {
|
287
|
-
|
321
|
+
const lastReadTimestamp = new Date(data.lastConsumptionTimestamp);
|
288
322
|
if (!this.state.lastReadTimestamp ||
|
289
323
|
this.state.lastReadTimestamp.getTime() !== lastReadTimestamp.getTime()) {
|
290
324
|
this.state.lastReadTimestamp = lastReadTimestamp;
|
291
|
-
updateReasons.push(
|
325
|
+
updateReasons.push("lastReadTimestamp");
|
292
326
|
}
|
293
327
|
}
|
294
328
|
if (data.bindings && !isEqual__default['default'](this.state.bindings, data.bindings)) {
|
295
329
|
this.state.bindings = data.bindings;
|
296
|
-
updateReasons.push(
|
330
|
+
updateReasons.push("bindings");
|
297
331
|
}
|
298
332
|
if (updateReasons.length > 0) {
|
299
|
-
this.emit(
|
333
|
+
this.emit("updated", { participant: this, updateReasons: updateReasons });
|
300
334
|
}
|
301
335
|
return this;
|
302
336
|
}
|
@@ -304,8 +338,8 @@ class Participant extends replayEventEmitter.ReplayEventEmitter {
|
|
304
338
|
* Get the user for this participant and subscribes to it. Supported only for participants of type `chat`.
|
305
339
|
*/
|
306
340
|
async getUser() {
|
307
|
-
if (this.type !=
|
308
|
-
throw new Error(
|
341
|
+
if (this.type != "chat") {
|
342
|
+
throw new Error("Getting User is not supported for this Participant type: " + this.type);
|
309
343
|
}
|
310
344
|
return this.services.users.getUser(this.state.identity, this.state.userInfo);
|
311
345
|
}
|
@@ -320,8 +354,8 @@ class Participant extends replayEventEmitter.ReplayEventEmitter {
|
|
320
354
|
* @param attributes New attributes.
|
321
355
|
*/
|
322
356
|
async updateAttributes(attributes) {
|
323
|
-
await this.services.commandExecutor.mutateResource(
|
324
|
-
attributes: JSON.stringify(attributes)
|
357
|
+
await this.services.commandExecutor.mutateResource("post", this.links.self, {
|
358
|
+
attributes: JSON.stringify(attributes),
|
325
359
|
});
|
326
360
|
return this;
|
327
361
|
}
|
@@ -333,7 +367,7 @@ class Participant extends replayEventEmitter.ReplayEventEmitter {
|
|
333
367
|
* 1. {@link Participant} `participant` - the participant in question
|
334
368
|
* @event
|
335
369
|
*/
|
336
|
-
Participant.typingStarted =
|
370
|
+
Participant.typingStarted = "typingStarted";
|
337
371
|
/**
|
338
372
|
* Fired when the participant has stopped typing.
|
339
373
|
*
|
@@ -341,7 +375,7 @@ Participant.typingStarted = 'typingStarted';
|
|
341
375
|
* 1. {@link Participant} `participant` - the participant in question
|
342
376
|
* @event
|
343
377
|
*/
|
344
|
-
Participant.typingEnded =
|
378
|
+
Participant.typingEnded = "typingEnded";
|
345
379
|
/**
|
346
380
|
* Fired when the fields of the participant have been updated.
|
347
381
|
*
|
@@ -351,7 +385,7 @@ Participant.typingEnded = 'typingEnded';
|
|
351
385
|
* * {@link ParticipantUpdateReason}[] updateReasons - array of reasons for the update
|
352
386
|
* @event
|
353
387
|
*/
|
354
|
-
Participant.updated =
|
388
|
+
Participant.updated = "updated";
|
355
389
|
tslib_es6.__decorate([
|
356
390
|
declarativeTypeValidator.validateTypesAsync(attributes.attributesValidator),
|
357
391
|
tslib_es6.__metadata("design:type", Function),
|
package/dist/participant.js.map
CHANGED
@@ -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 { 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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"}
|
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 } 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\";\nimport { JSONValue } from \"./types\";\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?: JSONValue;\n dateCreated: Date | null;\n dateUpdated: Date | null;\n identity: string;\n roleSid?: string;\n lastConsumedMessageIndex: number | null;\n lastConsumptionTimestamp: number;\n type: ParticipantType;\n userInfo: string;\n bindings?: ParticipantBindings;\n}\n\ninterface ParticipantState {\n attributes: JSONValue;\n dateCreated: Date | null;\n dateUpdated: Date | null;\n identity: string;\n isTyping: boolean;\n lastReadMessageIndex: number | null;\n lastReadTimestamp: Date | null;\n roleSid: string;\n sid: string;\n type: ParticipantType;\n typingTimeout: number | null;\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 {\n return this.state.sid;\n }\n\n /**\n * Custom attributes of the participant.\n */\n public get attributes(): JSONValue {\n return this.state.attributes;\n }\n\n /**\n * Date this participant was created on.\n */\n public get dateCreated(): Date | null {\n return this.state.dateCreated;\n }\n\n /**\n * Date this participant was last updated on.\n */\n public get dateUpdated(): Date | null {\n return this.state.dateUpdated;\n }\n\n /**\n * Identity of the participant.\n */\n public get identity(): string | null {\n return this.state.identity;\n }\n\n /**\n * Indicates whether the participant is currently typing.\n */\n public get isTyping(): boolean {\n return this.state.isTyping;\n }\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 {\n return this.state.lastReadMessageIndex;\n }\n\n /**\n * Date of the most recent read horizon update.\n */\n public get lastReadTimestamp(): Date | null {\n return this.state.lastReadTimestamp;\n }\n\n public get roleSid(): string {\n return this.state.roleSid;\n }\n\n /**\n * Type of the participant.\n */\n public get type(): ParticipantType {\n return this.state.type;\n }\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 {\n return this.state.bindings ?? {};\n }\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(\n data.attributes,\n \"Retrieved malformed attributes from the server for participant: \" +\n sid,\n log\n ),\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,\n roleSid: data.roleSid ?? \"\",\n lastReadMessageIndex: Number.isInteger(data.lastConsumedMessageIndex)\n ? data.lastConsumedMessageIndex\n : null,\n lastReadTimestamp: data.lastConsumptionTimestamp\n ? parseTime(data.lastConsumptionTimestamp)\n : 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(\n \"Received invalid Participant object from server: Missing identity or type of Participant.\"\n );\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 if (this.state.typingTimeout) {\n clearTimeout(this.state.typingTimeout);\n }\n\n this.state.isTyping = true;\n this.emit(\"typingStarted\", this);\n\n this.conversation.emit(\"typingStarted\", this);\n\n this.state.typingTimeout = Number(\n setTimeout(() => this._endTyping(), timeout)\n );\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) {\n return;\n }\n\n this.state.isTyping = false;\n this.emit(\"typingEnded\", this);\n\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 const updateReasons: ParticipantUpdateReason[] = [];\n\n const updateAttributes = parseAttributes(\n data.attributes,\n \"Retrieved malformed attributes from the server for participant: \" +\n this.state.sid,\n log\n );\n\n if (data.attributes && !isEqual(this.state.attributes, updateAttributes)) {\n this.state.attributes = updateAttributes;\n updateReasons.push(\"attributes\");\n }\n\n const updatedDateUpdated = parseTime(data.dateUpdated);\n if (\n data.dateUpdated &&\n updatedDateUpdated?.getTime() !==\n (this.state.dateUpdated && this.state.dateUpdated.getTime())\n ) {\n this.state.dateUpdated = updatedDateUpdated;\n updateReasons.push(\"dateUpdated\");\n }\n\n const updatedDateCreated = parseTime(data.dateCreated);\n if (\n data.dateCreated &&\n updatedDateCreated?.getTime() !==\n (this.state.dateCreated && this.state.dateCreated.getTime())\n ) {\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 (\n (Number.isInteger(data.lastConsumedMessageIndex) ||\n data.lastConsumedMessageIndex === null) &&\n this.state.lastReadMessageIndex !== data.lastConsumedMessageIndex\n ) {\n this.state.lastReadMessageIndex = data.lastConsumedMessageIndex;\n updateReasons.push(\"lastReadMessageIndex\");\n }\n\n if (data.lastConsumptionTimestamp) {\n const lastReadTimestamp = new Date(data.lastConsumptionTimestamp);\n if (\n !this.state.lastReadTimestamp ||\n this.state.lastReadTimestamp.getTime() !== lastReadTimestamp.getTime()\n ) {\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(\n \"Getting User is not supported for this Participant type: \" + this.type\n );\n }\n\n return this.services.users.getUser(\n this.state.identity,\n this.state.userInfo\n );\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: JSONValue): Promise<Participant> {\n await this.services.commandExecutor.mutateResource<\n EditParticipantRequest,\n ParticipantResponse\n >(\"post\", this.links.self, {\n attributes: JSON.stringify(attributes),\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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"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"push-notification.js","sources":["../src/push-notification.ts"],"sourcesContent":["/**\n * Push notification type.\n */\ntype PushNotificationType =\n |
|
1
|
+
{"version":3,"file":"push-notification.js","sources":["../src/push-notification.ts"],"sourcesContent":["/**\n * Push notification type.\n */\ntype PushNotificationType =\n | \"twilio.conversations.new_message\"\n | \"twilio.conversations.added_to_conversation\"\n | \"twilio.conversations.removed_from_conversation\";\n\ninterface PushNotificationDescriptor {\n title: string | null;\n body: string | null;\n sound: string | null;\n badge: number | null;\n action: string | null;\n type: PushNotificationType;\n data: Record<string, unknown>;\n}\n\n/**\n * Additional data for a given push notification.\n */\ninterface PushNotificationData {\n /**\n * SID of the conversation.\n */\n conversationSid?: string;\n\n /**\n * Index of the message in the conversation.\n */\n messageIndex?: number;\n\n /**\n * SID of the message in the conversation.\n */\n messageSid?: string;\n}\n\n/**\n * Push notification for a Conversations client.\n */\nclass PushNotification {\n /**\n * Title of the notification.\n */\n public readonly title: string | null;\n\n /**\n * Text of the notification.\n */\n public readonly body: string | null;\n\n /**\n * Sound of the notification.\n */\n public readonly sound: string | null;\n\n /**\n * Number of the badge.\n */\n public readonly badge: number | null;\n\n /**\n * Notification action (`click_action` in FCM terms and `category` in APN terms).\n */\n public readonly action: string | null;\n\n /**\n * Type of the notification.\n */\n public readonly type: PushNotificationType;\n\n /**\n * Additional data of the conversation.\n */\n public readonly data: PushNotificationData;\n\n /**\n * @internal\n */\n constructor(data: PushNotificationDescriptor) {\n this.title = data.title || null;\n this.body = data.body || null;\n this.sound = data.sound || null;\n this.badge = data.badge || null;\n this.action = data.action || null;\n this.type = data.type || null;\n this.data = data.data || {};\n }\n}\n\nexport {\n PushNotification,\n PushNotificationType,\n PushNotificationDescriptor,\n PushNotificationData,\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA;;;AAGA,MAAM,gBAAgB;;;;IAuCpB,YAAY,IAAgC;QAC1C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;QAC9B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC;QAChC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC;QAChC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;KAC7B;;;;;"}
|
package/dist/rest-paginator.js
CHANGED
@@ -142,32 +142,42 @@ class RestPaginator {
|
|
142
142
|
prevToken,
|
143
143
|
nextToken,
|
144
144
|
source,
|
145
|
-
items
|
145
|
+
items,
|
146
146
|
};
|
147
147
|
}
|
148
148
|
/**
|
149
149
|
* Indicates the existence of the next page.
|
150
150
|
*/
|
151
|
-
get hasNextPage() {
|
151
|
+
get hasNextPage() {
|
152
|
+
return !!this.state.nextToken;
|
153
|
+
}
|
152
154
|
/**
|
153
155
|
* Indicates the existence of the previous page
|
154
156
|
*/
|
155
|
-
get hasPrevPage() {
|
157
|
+
get hasPrevPage() {
|
158
|
+
return !!this.state.prevToken;
|
159
|
+
}
|
156
160
|
/**
|
157
161
|
* Array of elements on the current page.
|
158
162
|
*/
|
159
|
-
get items() {
|
163
|
+
get items() {
|
164
|
+
return this.state.items;
|
165
|
+
}
|
160
166
|
/**
|
161
167
|
* Request the next page. Does not modify the existing object.
|
162
168
|
*/
|
163
169
|
nextPage() {
|
164
|
-
return this.hasNextPage
|
170
|
+
return this.hasNextPage
|
171
|
+
? this.state.source(this.state.nextToken)
|
172
|
+
: Promise.reject(new Error("No next page"));
|
165
173
|
}
|
166
174
|
/**
|
167
175
|
* Request the previous page. Does not modify the existing object.
|
168
176
|
*/
|
169
177
|
prevPage() {
|
170
|
-
return this.hasPrevPage
|
178
|
+
return this.hasPrevPage
|
179
|
+
? this.state.source(this.state.prevToken)
|
180
|
+
: Promise.reject(new Error("No previous page"));
|
171
181
|
}
|
172
182
|
}
|
173
183
|
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"rest-paginator.js","sources":["../src/rest-paginator.ts"],"sourcesContent":["import { Paginator } from
|
1
|
+
{"version":3,"file":"rest-paginator.js","sources":["../src/rest-paginator.ts"],"sourcesContent":["import { Paginator } from \"./interfaces/paginator\";\n\ninterface PaginatorState<T> {\n source: (token: string) => Promise<RestPaginator<T>>;\n nextToken: string;\n prevToken: string;\n items: T[];\n}\n\n/**\n * Pagination helper class.\n */\nclass RestPaginator<T> implements Paginator<T> {\n private state: PaginatorState<T>;\n\n /**\n * Indicates the existence of the next page.\n */\n public get hasNextPage(): boolean {\n return !!this.state.nextToken;\n }\n\n /**\n * Indicates the existence of the previous page\n */\n public get hasPrevPage(): boolean {\n return !!this.state.prevToken;\n }\n\n /**\n * Array of elements on the current page.\n */\n public get items(): T[] {\n return this.state.items;\n }\n\n /**\n * @internal\n */\n constructor(items, source, prevToken, nextToken) {\n this.state = {\n prevToken,\n nextToken,\n source,\n items,\n };\n }\n\n /**\n * Request the next page. Does not modify the existing object.\n */\n nextPage(): Promise<RestPaginator<T>> {\n return this.hasNextPage\n ? this.state.source(this.state.nextToken)\n : Promise.reject(new Error(\"No next page\"));\n }\n\n /**\n * Request the previous page. Does not modify the existing object.\n */\n prevPage(): Promise<RestPaginator<T>> {\n return this.hasPrevPage\n ? this.state.source(this.state.prevToken)\n : Promise.reject(new Error(\"No previous page\"));\n }\n}\n\nexport { RestPaginator };\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA;;;AAGA,MAAM,aAAa;;;;IA2BjB,YAAY,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS;QAC7C,IAAI,CAAC,KAAK,GAAG;YACX,SAAS;YACT,SAAS;YACT,MAAM;YACN,KAAK;SACN,CAAC;KACH;;;;IA5BD,IAAW,WAAW;QACpB,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;KAC/B;;;;IAKD,IAAW,WAAW;QACpB,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;KAC/B;;;;IAKD,IAAW,KAAK;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;KACzB;;;;IAiBD,QAAQ;QACN,OAAO,IAAI,CAAC,WAAW;cACnB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;cACvC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;KAC/C;;;;IAKD,QAAQ;QACN,OAAO,IAAI,CAAC,WAAW;cACnB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;cACvC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC;KACnD;;;;;"}
|
package/dist/services/network.js
CHANGED
@@ -141,10 +141,10 @@ class Network {
|
|
141
141
|
this.cleanupCache();
|
142
142
|
}
|
143
143
|
isExpired(timestamp) {
|
144
|
-
return !this.cacheLifetime ||
|
144
|
+
return !this.cacheLifetime || Date.now() - timestamp > this.cacheLifetime;
|
145
145
|
}
|
146
146
|
cleanupCache() {
|
147
|
-
for (
|
147
|
+
for (const [k, v] of this.cache) {
|
148
148
|
if (this.isExpired(v.timestamp)) {
|
149
149
|
this.cache.delete(k);
|
150
150
|
}
|
@@ -154,23 +154,25 @@ class Network {
|
|
154
154
|
}
|
155
155
|
}
|
156
156
|
pokeTimer() {
|
157
|
-
this.timer =
|
157
|
+
this.timer =
|
158
|
+
this.timer ||
|
159
|
+
setInterval(() => this.cleanupCache(), this.cacheLifetime * 2);
|
158
160
|
}
|
159
161
|
executeWithRetry(request, retryWhenThrottled = false) {
|
160
162
|
return new Promise((resolve, reject) => {
|
161
|
-
|
163
|
+
const codesToRetryOn = [502, 503, 504];
|
162
164
|
if (retryWhenThrottled) {
|
163
165
|
codesToRetryOn.push(429);
|
164
166
|
}
|
165
|
-
|
166
|
-
retrier.on(
|
167
|
+
const retrier = new operationRetrier.Retrier(this.configuration.backoffConfiguration);
|
168
|
+
retrier.on("attempt", () => {
|
167
169
|
request()
|
168
|
-
.then(result => retrier.succeeded(result))
|
169
|
-
.catch(err => {
|
170
|
+
.then((result) => retrier.succeeded(result))
|
171
|
+
.catch((err) => {
|
170
172
|
if (codesToRetryOn.indexOf(err.status) > -1) {
|
171
173
|
retrier.failed(err);
|
172
174
|
}
|
173
|
-
else if (err.message ===
|
175
|
+
else if (err.message === "Twilsock disconnected") {
|
174
176
|
// Ugly hack. We must make a proper exceptions for twilsock
|
175
177
|
retrier.failed(err);
|
176
178
|
}
|
@@ -182,19 +184,21 @@ class Network {
|
|
182
184
|
}
|
183
185
|
});
|
184
186
|
});
|
185
|
-
retrier.on(
|
186
|
-
|
187
|
-
|
187
|
+
retrier.on("succeeded", (result) => {
|
188
|
+
resolve(result);
|
189
|
+
});
|
190
|
+
retrier.on("cancelled", (err) => reject(err));
|
191
|
+
retrier.on("failed", (err) => reject(err));
|
188
192
|
retrier.start();
|
189
193
|
});
|
190
194
|
}
|
191
195
|
async get(url) {
|
192
|
-
|
196
|
+
const cacheEntry = this.cache.get(url);
|
193
197
|
if (cacheEntry && !this.isExpired(cacheEntry.timestamp)) {
|
194
198
|
return cacheEntry.response;
|
195
199
|
}
|
196
200
|
const headers = {};
|
197
|
-
|
201
|
+
const response = await this.executeWithRetry(() => this.services.transport.get(url, headers, this.configuration.productId), this.configuration.retryWhenThrottled);
|
198
202
|
this.cache.set(url, { response, timestamp: Date.now() });
|
199
203
|
this.pokeTimer();
|
200
204
|
return response;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"network.js","sources":["../../src/services/network.ts"],"sourcesContent":["import { Retrier } from
|
1
|
+
{"version":3,"file":"network.js","sources":["../../src/services/network.ts"],"sourcesContent":["import { Retrier } from \"@twilio/operation-retrier\";\nimport { Transport, TransportResult } from \"twilsock\";\nimport { Configuration } from \"../configuration\";\n\nimport Timeout = NodeJS.Timeout;\n\ninterface CacheEntry {\n response: TransportResult<unknown>;\n timestamp: number;\n}\n\nexport interface NetworkServices {\n transport: Transport;\n}\n\nclass Network {\n private readonly configuration: Configuration;\n private readonly services: NetworkServices;\n private cacheLifetime: number;\n\n private readonly cache: Map<string, CacheEntry>;\n private timer!: number | NodeJS.Timeout;\n\n constructor(configuration, services) {\n this.configuration = configuration;\n this.services = services;\n this.cache = new Map<string, CacheEntry>();\n this.cacheLifetime = this.configuration.httpCacheInterval * 100;\n this.cleanupCache();\n }\n\n private isExpired(timestamp: number): boolean {\n return !this.cacheLifetime || Date.now() - timestamp > this.cacheLifetime;\n }\n\n private cleanupCache() {\n for (const [k, v] of this.cache) {\n if (this.isExpired(v.timestamp)) {\n this.cache.delete(k);\n }\n }\n\n if (this.cache.size === 0) {\n clearInterval(this.timer as Timeout);\n }\n }\n\n pokeTimer() {\n this.timer =\n this.timer ||\n setInterval(() => this.cleanupCache(), this.cacheLifetime * 2);\n }\n\n private executeWithRetry<T>(\n request,\n retryWhenThrottled = false\n ): Promise<TransportResult<T>> {\n return new Promise((resolve, reject) => {\n const codesToRetryOn = [502, 503, 504];\n if (retryWhenThrottled) {\n codesToRetryOn.push(429);\n }\n\n const retrier = new Retrier(this.configuration.backoffConfiguration);\n retrier.on(\"attempt\", () => {\n request()\n .then((result) => retrier.succeeded(result))\n .catch((err) => {\n if (codesToRetryOn.indexOf(err.status) > -1) {\n retrier.failed(err);\n } else if (err.message === \"Twilsock disconnected\") {\n // Ugly hack. We must make a proper exceptions for twilsock\n retrier.failed(err);\n } else {\n // Fatal error\n retrier.removeAllListeners();\n retrier.cancel();\n reject(err);\n }\n });\n });\n\n retrier.on(\"succeeded\", (result) => {\n resolve(result);\n });\n retrier.on(\"cancelled\", (err) => reject(err));\n retrier.on(\"failed\", (err) => reject(err));\n\n retrier.start();\n });\n }\n\n async get<T>(url: string): Promise<TransportResult<T>> {\n const cacheEntry = this.cache.get(url);\n if (cacheEntry && !this.isExpired(cacheEntry.timestamp)) {\n return cacheEntry.response as TransportResult<T>;\n }\n\n const headers = {};\n const response = await this.executeWithRetry<T>(\n () =>\n this.services.transport.get<T>(\n url,\n headers,\n this.configuration.productId\n ),\n this.configuration.retryWhenThrottled\n );\n this.cache.set(url, { response, timestamp: Date.now() });\n this.pokeTimer();\n return response;\n }\n}\n\nexport { Network };\n"],"names":["Retrier"],"mappings":"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"}
|