@twilio/conversations 2.1.0-rc.1 → 2.1.0-rc.5
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 +34 -0
- package/NOTICE.txt +679 -0
- package/builds/browser.js +676 -587
- package/builds/browser.js.map +1 -1
- package/builds/lib.d.ts +287 -117
- package/builds/lib.js +676 -587
- package/builds/lib.js.map +1 -1
- package/builds/twilio-conversations.js +854 -909
- 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 +81 -77
- 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 +130 -81
- 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/classes/Client.html +24 -30
- package/docs/classes/Conversation.html +30 -30
- package/docs/classes/DetailedDeliveryReceipt.html +1 -1
- package/docs/classes/Message.html +7 -7
- package/docs/classes/MessageBuilder.html +2 -2
- package/docs/classes/Participant.html +7 -7
- package/docs/classes/User.html +7 -7
- package/docs/interfaces/CreateConversationOptions.html +1 -1
- package/package.json +23 -17
@@ -133,7 +133,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
133
133
|
var logger = require('../logger.js');
|
134
134
|
var notificationTypes = require('../interfaces/notification-types.js');
|
135
135
|
|
136
|
-
const log = logger.Logger.scope(
|
136
|
+
const log = logger.Logger.scope("TypingIndicator");
|
137
137
|
/**
|
138
138
|
* An important note in regards to typing timeout timers. There are two places that the SDK can get the "typing_timeout" attribute from. The first
|
139
139
|
* place that the attribute appears in is the response received from POST -> /v1/typing REST call. In the body of that response, the value of the
|
@@ -159,9 +159,9 @@ class TypingIndicator {
|
|
159
159
|
this.sentUpdates = new Map();
|
160
160
|
}
|
161
161
|
get typingTimeout() {
|
162
|
-
return this.configuration.typingIndicatorTimeoutOverride
|
163
|
-
|
164
|
-
|
162
|
+
return (this.configuration.typingIndicatorTimeoutOverride ||
|
163
|
+
this.serviceTypingTimeout ||
|
164
|
+
this.configuration.typingIndicatorTimeoutDefault);
|
165
165
|
}
|
166
166
|
/**
|
167
167
|
* Initialize TypingIndicator controller
|
@@ -170,7 +170,7 @@ class TypingIndicator {
|
|
170
170
|
*/
|
171
171
|
initialize() {
|
172
172
|
// this.services.notificationClient.subscribe(NotificationTypes.TYPING_INDICATOR, 'twilsock');
|
173
|
-
this.services.notificationClient.on(
|
173
|
+
this.services.notificationClient.on("message", async (type, message) => {
|
174
174
|
if (type === notificationTypes.NotificationTypes.TYPING_INDICATOR) {
|
175
175
|
await this._handleRemoteTyping(message);
|
176
176
|
}
|
@@ -180,21 +180,23 @@ class TypingIndicator {
|
|
180
180
|
* Remote participants typing events handler
|
181
181
|
*/
|
182
182
|
async _handleRemoteTyping(message) {
|
183
|
-
log.trace(
|
183
|
+
log.trace("Got new typing indicator ", message);
|
184
184
|
this.getConversation(message.channel_sid)
|
185
|
-
.then(conversation => {
|
185
|
+
.then((conversation) => {
|
186
186
|
if (!conversation) {
|
187
187
|
return;
|
188
188
|
}
|
189
|
-
conversation.participants.forEach(participant => {
|
189
|
+
conversation.participants.forEach((participant) => {
|
190
190
|
if (participant.identity !== message.identity) {
|
191
191
|
return;
|
192
192
|
}
|
193
|
-
const timeout = this.configuration.typingIndicatorTimeoutOverride
|
193
|
+
const timeout = this.configuration.typingIndicatorTimeoutOverride
|
194
|
+
? this.configuration.typingIndicatorTimeoutOverride + 1000
|
195
|
+
: message.typing_timeout * 1000;
|
194
196
|
participant._startTyping(timeout);
|
195
197
|
});
|
196
198
|
})
|
197
|
-
.catch(err => {
|
199
|
+
.catch((err) => {
|
198
200
|
log.error(err);
|
199
201
|
throw err;
|
200
202
|
});
|
@@ -205,29 +207,30 @@ class TypingIndicator {
|
|
205
207
|
*/
|
206
208
|
send(conversationSid) {
|
207
209
|
const lastUpdate = this.sentUpdates.get(conversationSid);
|
208
|
-
if (lastUpdate && lastUpdate >
|
210
|
+
if (lastUpdate && lastUpdate > Date.now() - this.typingTimeout) {
|
209
211
|
return Promise.resolve();
|
210
212
|
}
|
211
213
|
this.sentUpdates.set(conversationSid, Date.now());
|
212
214
|
return this._send(conversationSid);
|
213
215
|
}
|
214
216
|
_send(conversationSid) {
|
215
|
-
log.trace(
|
217
|
+
log.trace("Sending typing indicator");
|
216
218
|
const url = this.configuration.links.typing;
|
217
219
|
const headers = {
|
218
|
-
|
220
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
219
221
|
};
|
220
222
|
const body = `ChannelSid=${conversationSid}`;
|
221
|
-
return
|
223
|
+
return this.services.twilsockClient
|
224
|
+
.post(url, headers, body, this.configuration.productId)
|
222
225
|
.then((response) => {
|
223
|
-
if (response.body.hasOwnProperty(
|
226
|
+
if (response.body.hasOwnProperty("typing_timeout")) {
|
224
227
|
this.serviceTypingTimeout = response.body.typing_timeout * 1000;
|
225
228
|
}
|
226
229
|
})
|
227
230
|
.catch((err) => {
|
228
|
-
log.error(
|
231
|
+
log.error("Failed to send typing indicator:", err);
|
229
232
|
throw err;
|
230
|
-
})
|
233
|
+
});
|
231
234
|
}
|
232
235
|
}
|
233
236
|
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"typing-indicator.js","sources":["../../src/services/typing-indicator.ts"],"sourcesContent":["import { Logger } from
|
1
|
+
{"version":3,"file":"typing-indicator.js","sources":["../../src/services/typing-indicator.ts"],"sourcesContent":["import { Logger } from \"../logger\";\n\nimport { Notifications } from \"@twilio/notifications\";\n\nimport { NotificationTypes } from \"../interfaces/notification-types\";\nimport { TwilsockClient } from \"twilsock\";\nimport { Configuration } from \"../configuration\";\n\nconst log = Logger.scope(\"TypingIndicator\");\n\nexport interface TypingIndicatorServices {\n twilsockClient: TwilsockClient;\n notificationClient: Notifications;\n}\n\n/**\n * An important note in regards to typing timeout timers. There are two places that the SDK can get the \"typing_timeout\" attribute from. The first\n * place that the attribute appears in is the response received from POST -> /v1/typing REST call. In the body of that response, the value of the\n * \"typing_timeout\" attribute will be exactly the same as defined in the console. The second place that the attribute appears in is from a\n * notification of type \"twilio.ipmsg.typing_indicator\". In this case, the \"typing_timeout\" value will be +1 of that in the console. This\n * intentional. The timeout returned from the POST -> /v1/typing call should be used to disable further calls for that period of time. On contrary,\n * the timeout returned from the notification should be used as the timeout for the \"typingEnded\" event, +1 is to account for latency.\n *\n * @private\n */\n\n/**\n * @class TypingIndicator\n *\n * @constructor\n * @private\n */\nclass TypingIndicator {\n private readonly services: TypingIndicatorServices;\n private readonly configuration: Configuration;\n\n private sentUpdates: Map<string, number>;\n private getConversation;\n private serviceTypingTimeout;\n\n constructor(\n getConversation,\n config: Configuration,\n services: TypingIndicatorServices\n ) {\n this.configuration = config;\n this.services = services;\n this.getConversation = getConversation;\n\n this.serviceTypingTimeout = null;\n this.sentUpdates = new Map();\n }\n\n public get typingTimeout(): number {\n return (\n this.configuration.typingIndicatorTimeoutOverride ||\n this.serviceTypingTimeout ||\n this.configuration.typingIndicatorTimeoutDefault\n );\n }\n\n /**\n * Initialize TypingIndicator controller\n * Registers for needed message types and sets listeners\n * @private\n */\n initialize(): void {\n // this.services.notificationClient.subscribe(NotificationTypes.TYPING_INDICATOR, 'twilsock');\n this.services.notificationClient.on(\"message\", async (type, message) => {\n if (type === NotificationTypes.TYPING_INDICATOR) {\n await this._handleRemoteTyping(message);\n }\n });\n }\n\n /**\n * Remote participants typing events handler\n */\n private async _handleRemoteTyping(message) {\n log.trace(\"Got new typing indicator \", message);\n\n this.getConversation(message.channel_sid)\n .then((conversation) => {\n if (!conversation) {\n return;\n }\n\n conversation.participants.forEach((participant) => {\n if (participant.identity !== message.identity) {\n return;\n }\n\n const timeout = this.configuration.typingIndicatorTimeoutOverride\n ? this.configuration.typingIndicatorTimeoutOverride + 1000\n : message.typing_timeout * 1000;\n participant._startTyping(timeout);\n });\n })\n .catch((err) => {\n log.error(err);\n throw err;\n });\n }\n\n /**\n * Send typing event for the given conversation sid\n * @param {String} conversationSid\n */\n send(conversationSid: string) {\n const lastUpdate = this.sentUpdates.get(conversationSid);\n if (lastUpdate && lastUpdate > Date.now() - this.typingTimeout) {\n return Promise.resolve();\n }\n\n this.sentUpdates.set(conversationSid, Date.now());\n return this._send(conversationSid);\n }\n\n private _send(conversationSid: string) {\n log.trace(\"Sending typing indicator\");\n\n const url = this.configuration.links.typing;\n const headers = {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n };\n const body = `ChannelSid=${conversationSid}`;\n\n return this.services.twilsockClient\n .post<{ typing_timeout: number }>(\n url,\n headers,\n body,\n this.configuration.productId\n )\n .then((response) => {\n if (response.body.hasOwnProperty(\"typing_timeout\")) {\n this.serviceTypingTimeout = response.body.typing_timeout * 1000;\n }\n })\n .catch((err) => {\n log.error(\"Failed to send typing indicator:\", err);\n throw err;\n });\n }\n}\n\nexport { TypingIndicator };\n"],"names":["Logger","NotificationTypes"],"mappings":"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"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"unsent-message.js","sources":["../src/unsent-message.ts"],"sourcesContent":["import { MediaCategory } from
|
1
|
+
{"version":3,"file":"unsent-message.js","sources":["../src/unsent-message.ts"],"sourcesContent":["import { MediaCategory } from \"@twilio/mcs-client\";\nimport { parseToNumber } from \"./util\";\nimport { SendEmailOptions, SendMediaOptions } from \"./conversation\";\nimport { JSONValue } from \"./types\";\n\n/**\n * An unsent message. Returned from {@link MessageBuilder.build}.\n */\nclass UnsentMessage {\n public text?: string;\n public attributes: JSONValue = {};\n public mediaContent: [MediaCategory, FormData | SendMediaOptions][] = [];\n public emailOptions: SendEmailOptions = {};\n\n /**\n * @internal\n */\n constructor(private messagesEntity) {}\n\n /**\n * Send the prepared message to the conversation.\n * @returns Index of the new message in the conversation.\n */\n async send(): Promise<number | null> {\n const response = await this.messagesEntity.sendV2(this);\n return parseToNumber(response.index);\n }\n}\n\nexport { UnsentMessage };\n"],"names":["parseToNumber"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA;;;AAGA,MAAM,aAAa;;;;IASjB,YAAoB,cAAc;QAAd,mBAAc,GAAd,cAAc,CAAA;QAP3B,eAAU,GAAc,EAAE,CAAC;QAC3B,iBAAY,GAAmD,EAAE,CAAC;QAClE,iBAAY,GAAqB,EAAE,CAAC;KAKL;;;;;IAMtC,MAAM,IAAI;QACR,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxD,OAAOA,mBAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;KACtC;;;;;"}
|
package/dist/user.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("User");
|
146
146
|
/**
|
147
147
|
* Extended user information.
|
148
148
|
* Note that `isOnline` and `isNotifiable` properties are eligible
|
@@ -165,7 +165,7 @@ class User extends replayEventEmitter.ReplayEventEmitter {
|
|
165
165
|
* * {@link UserUpdateReason}[] `updateReasons` - array of reasons for the update
|
166
166
|
* @event
|
167
167
|
*/
|
168
|
-
this.updated =
|
168
|
+
this.updated = "updated";
|
169
169
|
/**
|
170
170
|
* Fired when the client has subscribed to the user.
|
171
171
|
*
|
@@ -173,7 +173,7 @@ class User extends replayEventEmitter.ReplayEventEmitter {
|
|
173
173
|
* 1. {@link User} `user` - the user in question
|
174
174
|
* @event
|
175
175
|
*/
|
176
|
-
this.userSubscribed =
|
176
|
+
this.userSubscribed = "userSubscribed";
|
177
177
|
/**
|
178
178
|
* Fired when the client has unsubscribed from the user.
|
179
179
|
*
|
@@ -181,9 +181,9 @@ class User extends replayEventEmitter.ReplayEventEmitter {
|
|
181
181
|
* 1. {@link User} `user` - the user in question
|
182
182
|
* @event
|
183
183
|
*/
|
184
|
-
this.userUnsubscribed =
|
184
|
+
this.userUnsubscribed = "userUnsubscribed";
|
185
185
|
this.services = services;
|
186
|
-
this.subscribed =
|
186
|
+
this.subscribed = "initializing";
|
187
187
|
this.setMaxListeners(0);
|
188
188
|
this.state = {
|
189
189
|
identity,
|
@@ -191,7 +191,7 @@ class User extends replayEventEmitter.ReplayEventEmitter {
|
|
191
191
|
friendlyName: null,
|
192
192
|
attributes: {},
|
193
193
|
online: null,
|
194
|
-
notifiable: null
|
194
|
+
notifiable: null,
|
195
195
|
};
|
196
196
|
this._initializationPromise = new Promise((resolve) => {
|
197
197
|
this._resolveInitializationPromise = resolve;
|
@@ -203,63 +203,79 @@ class User extends replayEventEmitter.ReplayEventEmitter {
|
|
203
203
|
/**
|
204
204
|
* User identity.
|
205
205
|
*/
|
206
|
-
get identity() {
|
207
|
-
|
208
|
-
|
206
|
+
get identity() {
|
207
|
+
return this.state.identity;
|
208
|
+
}
|
209
|
+
set identity(identity) {
|
210
|
+
this.state.identity = identity;
|
211
|
+
}
|
212
|
+
set entityName(name) {
|
213
|
+
this.state.entityName = name;
|
214
|
+
}
|
209
215
|
/**
|
210
216
|
* Custom attributes of the user.
|
211
217
|
*/
|
212
|
-
get attributes() {
|
218
|
+
get attributes() {
|
219
|
+
return this.state.attributes;
|
220
|
+
}
|
213
221
|
/**
|
214
222
|
* Friendly name of the user, null if not set.
|
215
223
|
*/
|
216
|
-
get friendlyName() {
|
224
|
+
get friendlyName() {
|
225
|
+
return this.state.friendlyName;
|
226
|
+
}
|
217
227
|
/**
|
218
228
|
* Status of the real-time conversation connection of the user.
|
219
229
|
*/
|
220
|
-
get isOnline() {
|
230
|
+
get isOnline() {
|
231
|
+
return this.state.online;
|
232
|
+
}
|
221
233
|
/**
|
222
234
|
* User push notification registration status.
|
223
235
|
*/
|
224
|
-
get isNotifiable() {
|
236
|
+
get isNotifiable() {
|
237
|
+
return this.state.notifiable;
|
238
|
+
}
|
225
239
|
/**
|
226
240
|
* True if this user is receiving real-time status updates.
|
227
241
|
*/
|
228
|
-
get isSubscribed() {
|
242
|
+
get isSubscribed() {
|
243
|
+
return this.subscribed == "subscribed";
|
244
|
+
}
|
229
245
|
// Handles service updates
|
230
246
|
async _update(key, value) {
|
231
247
|
await this._initializationPromise;
|
232
|
-
|
233
|
-
log.debug(
|
248
|
+
const updateReasons = [];
|
249
|
+
log.debug("User for", this.state.identity, "updated:", key, value);
|
234
250
|
switch (key) {
|
235
|
-
case
|
251
|
+
case "friendlyName":
|
236
252
|
if (this.state.friendlyName !== value.value) {
|
237
|
-
updateReasons.push(
|
253
|
+
updateReasons.push("friendlyName");
|
238
254
|
this.state.friendlyName = value.value;
|
239
255
|
}
|
240
256
|
break;
|
241
|
-
case
|
257
|
+
case "attributes":
|
242
258
|
const updateAttributes = index.parseAttributes(value.value, `Retrieved malformed attributes from the server for user: ${this.state.identity}`, log);
|
243
259
|
if (!isEqual__default['default'](this.state.attributes, updateAttributes)) {
|
244
260
|
this.state.attributes = updateAttributes;
|
245
|
-
updateReasons.push(
|
261
|
+
updateReasons.push("attributes");
|
246
262
|
}
|
247
263
|
break;
|
248
|
-
case
|
264
|
+
case "reachability":
|
249
265
|
if (this.state.online !== value.online) {
|
250
266
|
this.state.online = value.online;
|
251
|
-
updateReasons.push(
|
267
|
+
updateReasons.push("reachabilityOnline");
|
252
268
|
}
|
253
269
|
if (this.state.notifiable !== value.notifiable) {
|
254
270
|
this.state.notifiable = value.notifiable;
|
255
|
-
updateReasons.push(
|
271
|
+
updateReasons.push("reachabilityNotifiable");
|
256
272
|
}
|
257
273
|
break;
|
258
274
|
default:
|
259
275
|
return;
|
260
276
|
}
|
261
277
|
if (updateReasons.length > 0) {
|
262
|
-
this.emit(
|
278
|
+
this.emit("updated", { user: this, updateReasons: updateReasons });
|
263
279
|
}
|
264
280
|
}
|
265
281
|
// Fetch reachability info
|
@@ -268,9 +284,12 @@ class User extends replayEventEmitter.ReplayEventEmitter {
|
|
268
284
|
if (!this.configuration.reachabilityEnabled) {
|
269
285
|
return Promise.resolve();
|
270
286
|
}
|
271
|
-
return map
|
287
|
+
return map
|
288
|
+
.get("reachability")
|
272
289
|
.then(update)
|
273
|
-
.catch(err => {
|
290
|
+
.catch((err) => {
|
291
|
+
log.warn("Failed to get reachability info for ", this.state.identity, err);
|
292
|
+
});
|
274
293
|
}
|
275
294
|
// Fetch user
|
276
295
|
async _fetch() {
|
@@ -278,32 +297,39 @@ class User extends replayEventEmitter.ReplayEventEmitter {
|
|
278
297
|
if (!this.state.entityName) {
|
279
298
|
return this;
|
280
299
|
}
|
281
|
-
this.promiseToFetch = this.services.syncClient
|
300
|
+
this.promiseToFetch = this.services.syncClient
|
301
|
+
.map({
|
282
302
|
id: this.state.entityName,
|
283
|
-
mode:
|
284
|
-
includeItems: true
|
303
|
+
mode: "open_existing",
|
304
|
+
includeItems: true,
|
285
305
|
})
|
286
|
-
.then(map => {
|
306
|
+
.then((map) => {
|
287
307
|
this.entity = map;
|
288
|
-
map.on(
|
289
|
-
log.debug(this.state.entityName +
|
308
|
+
map.on("itemUpdated", (args) => {
|
309
|
+
log.debug(this.state.entityName +
|
310
|
+
" (" +
|
311
|
+
this.state.identity +
|
312
|
+
") itemUpdated: " +
|
313
|
+
args.item.key);
|
290
314
|
return this._update(args.item.key, args.item.data);
|
291
315
|
});
|
292
316
|
return Promise.all([
|
293
|
-
map
|
294
|
-
.
|
295
|
-
|
296
|
-
|
297
|
-
|
317
|
+
map
|
318
|
+
.get("friendlyName")
|
319
|
+
.then((item) => this._update(item.key, item.data)),
|
320
|
+
map
|
321
|
+
.get("attributes")
|
322
|
+
.then((item) => this._update(item.key, item.data)),
|
323
|
+
this._updateReachabilityInfo(map, (item) => this._update(item.key, item.data)),
|
298
324
|
]);
|
299
325
|
})
|
300
326
|
.then(() => {
|
301
|
-
log.debug(
|
302
|
-
this.subscribed =
|
303
|
-
this.emit(
|
327
|
+
log.debug("Fetched for", this.identity);
|
328
|
+
this.subscribed = "subscribed";
|
329
|
+
this.emit("userSubscribed", this);
|
304
330
|
return this;
|
305
331
|
})
|
306
|
-
.catch(err => {
|
332
|
+
.catch((err) => {
|
307
333
|
this.promiseToFetch = null;
|
308
334
|
throw err;
|
309
335
|
});
|
@@ -319,11 +345,11 @@ class User extends replayEventEmitter.ReplayEventEmitter {
|
|
319
345
|
*/
|
320
346
|
async updateAttributes(attributes) {
|
321
347
|
await this._initializationPromise;
|
322
|
-
if (this.subscribed ==
|
323
|
-
throw new Error(
|
348
|
+
if (this.subscribed == "unsubscribed") {
|
349
|
+
throw new Error("Can't modify unsubscribed object");
|
324
350
|
}
|
325
|
-
await this.services.commandExecutor.mutateResource(
|
326
|
-
attributes: JSON.stringify(attributes)
|
351
|
+
await this.services.commandExecutor.mutateResource("post", this.links.self, {
|
352
|
+
attributes: JSON.stringify(attributes),
|
327
353
|
});
|
328
354
|
return this;
|
329
355
|
}
|
@@ -333,11 +359,11 @@ class User extends replayEventEmitter.ReplayEventEmitter {
|
|
333
359
|
*/
|
334
360
|
async updateFriendlyName(friendlyName) {
|
335
361
|
await this._initializationPromise;
|
336
|
-
if (this.subscribed ==
|
337
|
-
throw new Error(
|
362
|
+
if (this.subscribed == "unsubscribed") {
|
363
|
+
throw new Error("Can't modify unsubscribed object");
|
338
364
|
}
|
339
|
-
await this.services.commandExecutor.mutateResource(
|
340
|
-
friendly_name: friendlyName
|
365
|
+
await this.services.commandExecutor.mutateResource("post", this.links.self, {
|
366
|
+
friendly_name: friendlyName,
|
341
367
|
});
|
342
368
|
return this;
|
343
369
|
}
|
@@ -351,8 +377,8 @@ class User extends replayEventEmitter.ReplayEventEmitter {
|
|
351
377
|
await this.promiseToFetch;
|
352
378
|
this.entity.close();
|
353
379
|
this.promiseToFetch = null;
|
354
|
-
this.subscribed =
|
355
|
-
this.emit(
|
380
|
+
this.subscribed = "unsubscribed";
|
381
|
+
this.emit("userUnsubscribed", this);
|
356
382
|
}
|
357
383
|
}
|
358
384
|
_resolveInitialization(configuration, identity, entityName, emitUpdated) {
|
@@ -360,18 +386,18 @@ class User extends replayEventEmitter.ReplayEventEmitter {
|
|
360
386
|
this.identity = identity;
|
361
387
|
this.entityName = entityName;
|
362
388
|
this.links = {
|
363
|
-
self: `${this.configuration.links.users}/${this.identity}
|
389
|
+
self: `${this.configuration.links.users}/${this.identity}`,
|
364
390
|
};
|
365
391
|
this._resolveInitializationPromise();
|
366
392
|
if (emitUpdated) {
|
367
|
-
this.emit(
|
393
|
+
this.emit("updated", {
|
368
394
|
user: this,
|
369
395
|
updateReasons: [
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
]
|
396
|
+
"friendlyName",
|
397
|
+
"attributes",
|
398
|
+
"reachabilityOnline",
|
399
|
+
"reachabilityNotifiable",
|
400
|
+
],
|
375
401
|
});
|
376
402
|
}
|
377
403
|
}
|
@@ -383,7 +409,7 @@ tslib_es6.__decorate([
|
|
383
409
|
tslib_es6.__metadata("design:returntype", Promise)
|
384
410
|
], User.prototype, "updateAttributes", null);
|
385
411
|
tslib_es6.__decorate([
|
386
|
-
declarativeTypeValidator.validateTypesAsync([
|
412
|
+
declarativeTypeValidator.validateTypesAsync(["string"]),
|
387
413
|
tslib_es6.__metadata("design:type", Function),
|
388
414
|
tslib_es6.__metadata("design:paramtypes", [String]),
|
389
415
|
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 { 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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"}
|
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 } from \"@twilio/declarative-type-validator\";\nimport { attributesValidator } from \"./interfaces/attributes\";\nimport { Configuration } from \"./configuration\";\nimport { CommandExecutor } from \"./command-executor\";\nimport {\n EditUserRequest,\n EditUserResponse,\n} from \"./interfaces/commands/edit-user\";\nimport { ReplayEventEmitter } from \"@twilio/replay-event-emitter\";\nimport isEqual from \"lodash.isequal\";\nimport { JSONValue } from \"./types\";\n\ntype UserEvents = {\n updated: (data: { user: User; updateReasons: UserUpdateReason[] }) => 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 | null;\n attributes: JSONValue;\n online: boolean | null;\n notifiable: boolean | null;\n}\n\ninterface UpdateValue {\n value: string;\n notifiable: boolean | null;\n online: boolean | null;\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;\n private state: UserState;\n private promiseToFetch: Promise<User> | null = null;\n private subscribed: SubscriptionState;\n\n private _initializationPromise: Promise<void>;\n private _resolveInitializationPromise;\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(configuration, identity, entityName, false);\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 {\n return this.state.identity;\n }\n\n public set identity(identity: string) {\n this.state.identity = identity;\n }\n\n public set entityName(name: string) {\n this.state.entityName = name;\n }\n\n /**\n * Custom attributes of the user.\n */\n public get attributes() {\n return this.state.attributes;\n }\n\n /**\n * Friendly name of the user, null if not set.\n */\n public get friendlyName(): string | null {\n return this.state.friendlyName;\n }\n\n /**\n * Status of the real-time conversation connection of the user.\n */\n public get isOnline(): boolean | null {\n return this.state.online;\n }\n\n /**\n * User push notification registration status.\n */\n public get isNotifiable(): boolean | null {\n return this.state.notifiable;\n }\n\n /**\n * True if this user is receiving real-time status updates.\n */\n public get isSubscribed(): boolean {\n return this.subscribed == \"subscribed\";\n }\n\n // Handles service updates\n async _update(\n key: string,\n value: { value: string; notifiable: boolean | null; online: boolean | null }\n ) {\n await this._initializationPromise;\n\n const 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(\n value.value,\n `Retrieved malformed attributes from the server for user: ${this.state.identity}`,\n log\n );\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\n .get(\"reachability\")\n .then(update)\n .catch((err) => {\n log.warn(\n \"Failed to get reachability info for \",\n this.state.identity,\n err\n );\n });\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\n .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(\n this.state.entityName +\n \" (\" +\n this.state.identity +\n \") itemUpdated: \" +\n args.item.key\n );\n return this._update(args.item.key, args.item.data);\n });\n return Promise.all([\n map\n .get(\"friendlyName\")\n .then((item) => this._update(item.key, item.data as UpdateValue)),\n map\n .get(\"attributes\")\n .then((item) => this._update(item.key, item.data as UpdateValue)),\n this._updateReachabilityInfo(map, (item) =>\n this._update(item.key, item.data)\n ),\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: JSONValue): 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<\n EditUserRequest,\n EditUserResponse\n >(\"post\", this.links.self, {\n attributes: JSON.stringify(attributes),\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<\n EditUserRequest,\n EditUserResponse\n >(\"post\", this.links.self, {\n friendly_name: friendlyName,\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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"}
|
package/dist/util/deferred.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"deferred.js","sources":["../../src/util/deferred.ts"],"sourcesContent":["class Deferred<T> {\n private _promise: Promise<T>;\n private _resolve;\n private _reject;\n\n public current
|
1
|
+
{"version":3,"file":"deferred.js","sources":["../../src/util/deferred.ts"],"sourcesContent":["class Deferred<T> {\n private _promise: Promise<T>;\n private _resolve;\n private _reject;\n\n public current!: T;\n\n constructor() {\n this._promise = new Promise<T>((resolve, reject) => {\n this._resolve = resolve;\n this._reject = reject;\n });\n }\n\n public get promise(): Promise<T> {\n return this._promise;\n }\n\n update(value: T) {\n this._resolve(value);\n }\n\n set(value: T) {\n this.current = value;\n this._resolve(value);\n }\n\n fail(e) {\n this._reject(e);\n }\n}\n\nexport { Deferred };\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,MAAM,QAAQ;IAOZ;QACE,IAAI,CAAC,QAAQ,GAAG,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM;YAC7C,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;YACxB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;SACvB,CAAC,CAAC;KACJ;IAED,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC;KACtB;IAED,MAAM,CAAC,KAAQ;QACb,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;KACtB;IAED,GAAG,CAAC,KAAQ;QACV,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;KACtB;IAED,IAAI,CAAC,CAAC;QACJ,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;KACjB;;;;;"}
|
package/dist/util/index.js
CHANGED
@@ -140,7 +140,7 @@ function deepClone(obj) {
|
|
140
140
|
return JSON.parse(JSON.stringify(obj));
|
141
141
|
}
|
142
142
|
function parseToNumber(value) {
|
143
|
-
if (typeof value !==
|
143
|
+
if (typeof value !== "undefined" && !isNaN(Number(value))) {
|
144
144
|
return Number(value);
|
145
145
|
}
|
146
146
|
return null;
|
@@ -172,13 +172,13 @@ function parseAttributes(rawAttributes, warningMessage, log) {
|
|
172
172
|
*/
|
173
173
|
class UriBuilder {
|
174
174
|
constructor(base) {
|
175
|
-
this.base = base.replace(/\/$/,
|
175
|
+
this.base = base.replace(/\/$/, "");
|
176
176
|
this.args = [];
|
177
177
|
this.paths = [];
|
178
178
|
}
|
179
179
|
arg(name, value) {
|
180
|
-
if (typeof value !==
|
181
|
-
this.args.push(encodeURIComponent(name) +
|
180
|
+
if (typeof value !== "undefined") {
|
181
|
+
this.args.push(encodeURIComponent(name) + "=" + encodeURIComponent(value));
|
182
182
|
}
|
183
183
|
return this;
|
184
184
|
}
|
@@ -189,10 +189,10 @@ class UriBuilder {
|
|
189
189
|
build() {
|
190
190
|
let result = this.base;
|
191
191
|
if (this.paths.length) {
|
192
|
-
result +=
|
192
|
+
result += "/" + this.paths.join("/");
|
193
193
|
}
|
194
194
|
if (this.args.length) {
|
195
|
-
result +=
|
195
|
+
result += "?" + this.args.join("&");
|
196
196
|
}
|
197
197
|
return result;
|
198
198
|
}
|
package/dist/util/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/util/index.ts"],"sourcesContent":["import { Logger } from
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/util/index.ts"],"sourcesContent":["import { Logger } from \"../logger\";\nimport { JSONValue } from \"../types\";\n\n/**\n * Deep-clone an object. Note that this does not work on object containing\n * functions.\n * @param {object} obj - the object to deep-clone\n * @returns {object}\n */\nfunction deepClone<T>(obj: T): T {\n return JSON.parse(JSON.stringify(obj)) as T;\n}\n\nfunction parseToNumber(value) {\n if (typeof value !== \"undefined\" && !isNaN(Number(value))) {\n return Number(value);\n }\n return null;\n}\n\n// timeString cannot be typed `string` because in member.ts\n// call to parseTime(data.lastReadTimestamp) uses number not a string for timestamp.\nfunction parseTime(timeString): Date | null {\n try {\n return new Date(timeString);\n } catch (e) {\n return null;\n }\n}\n\nfunction parseAttributes(\n rawAttributes,\n warningMessage: string,\n log: Logger\n): JSONValue {\n let attributes = {};\n if (rawAttributes) {\n try {\n attributes = JSON.parse(rawAttributes);\n } catch (e) {\n log.warn(warningMessage, e);\n }\n }\n\n return attributes;\n}\n\n/**\n * Construct URI with query parameters\n */\nclass UriBuilder {\n private base: string;\n private args: string[];\n private paths: string[];\n\n constructor(base: string) {\n this.base = base.replace(/\\/$/, \"\");\n this.args = [];\n this.paths = [];\n }\n\n public arg(name: string, value: string | number | boolean): UriBuilder {\n if (typeof value !== \"undefined\") {\n this.args.push(\n encodeURIComponent(name) + \"=\" + encodeURIComponent(value)\n );\n }\n return this;\n }\n\n public path(name: string): UriBuilder {\n this.paths.push(encodeURIComponent(name));\n return this;\n }\n\n public build(): string {\n let result = this.base;\n if (this.paths.length) {\n result += \"/\" + this.paths.join(\"/\");\n }\n\n if (this.args.length) {\n result += \"?\" + this.args.join(\"&\");\n }\n return result;\n }\n}\n\nexport { deepClone, UriBuilder, parseToNumber, parseTime, parseAttributes };\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA;;;;;;AAMA,SAAS,SAAS,CAAI,GAAM;IAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAM,CAAC;AAC9C,CAAC;AAED,SAAS,aAAa,CAAC,KAAK;IAC1B,IAAI,OAAO,KAAK,KAAK,WAAW,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE;QACzD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;KACtB;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;AACA;AACA,SAAS,SAAS,CAAC,UAAU;IAC3B,IAAI;QACF,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;KAC7B;IAAC,OAAO,CAAC,EAAE;QACV,OAAO,IAAI,CAAC;KACb;AACH,CAAC;AAED,SAAS,eAAe,CACtB,aAAa,EACb,cAAsB,EACtB,GAAW;IAEX,IAAI,UAAU,GAAG,EAAE,CAAC;IACpB,IAAI,aAAa,EAAE;QACjB,IAAI;YACF,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;SACxC;QAAC,OAAO,CAAC,EAAE;YACV,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC;SAC7B;KACF;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;AAGA,MAAM,UAAU;IAKd,YAAY,IAAY;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACf,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;KACjB;IAEM,GAAG,CAAC,IAAY,EAAE,KAAgC;QACvD,IAAI,OAAO,KAAK,KAAK,WAAW,EAAE;YAChC,IAAI,CAAC,IAAI,CAAC,IAAI,CACZ,kBAAkB,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAC3D,CAAC;SACH;QACD,OAAO,IAAI,CAAC;KACb;IAEM,IAAI,CAAC,IAAY;QACtB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC;KACb;IAEM,KAAK;QACV,IAAI,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YACrB,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SACtC;QAED,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YACpB,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SACrC;QACD,OAAO,MAAM,CAAC;KACf;;;;;;;;;"}
|