@whitewall/blip-sdk 0.0.174 → 0.0.176

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/README.md +14 -7
  2. package/dist/cjs/client.js +3 -0
  3. package/dist/cjs/client.js.map +1 -1
  4. package/dist/cjs/index.js +3 -0
  5. package/dist/cjs/index.js.map +1 -1
  6. package/dist/cjs/namespaces/account.js +21 -10
  7. package/dist/cjs/namespaces/account.js.map +1 -1
  8. package/dist/cjs/namespaces/analytics.js +54 -0
  9. package/dist/cjs/namespaces/analytics.js.map +1 -1
  10. package/dist/cjs/namespaces/desk.js +264 -45
  11. package/dist/cjs/namespaces/desk.js.map +1 -1
  12. package/dist/cjs/namespaces/plugins.js +1 -0
  13. package/dist/cjs/namespaces/plugins.js.map +1 -1
  14. package/dist/cjs/namespaces/portal.js +45 -0
  15. package/dist/cjs/namespaces/portal.js.map +1 -1
  16. package/dist/cjs/namespaces/tunnel.js +46 -0
  17. package/dist/cjs/namespaces/tunnel.js.map +1 -0
  18. package/dist/cjs/namespaces/whatsapp.js +2 -23
  19. package/dist/cjs/namespaces/whatsapp.js.map +1 -1
  20. package/dist/cjs/sender/http/httpsender.js +14 -5
  21. package/dist/cjs/sender/http/httpsender.js.map +1 -1
  22. package/dist/cjs/sender/multi/multisender.js +28 -9
  23. package/dist/cjs/sender/multi/multisender.js.map +1 -1
  24. package/dist/cjs/sender/sessionnegotiator.js +1 -1
  25. package/dist/cjs/sender/sessionnegotiator.js.map +1 -1
  26. package/dist/cjs/sender/tcp/tcpsender.js +35 -2
  27. package/dist/cjs/sender/tcp/tcpsender.js.map +1 -1
  28. package/dist/cjs/sender/websocket/websocketsender.js +1 -1
  29. package/dist/cjs/sender/websocket/websocketsender.js.map +1 -1
  30. package/dist/cjs/types/desk.js.map +1 -1
  31. package/dist/cjs/types/flow.js +344 -0
  32. package/dist/cjs/types/flow.js.map +1 -1
  33. package/dist/cjs/utils/desk.js +65 -0
  34. package/dist/cjs/utils/desk.js.map +1 -0
  35. package/dist/cjs/utils/thread.js +84 -0
  36. package/dist/cjs/utils/thread.js.map +1 -0
  37. package/dist/cjs/utils/whatsapp.js +268 -0
  38. package/dist/cjs/utils/whatsapp.js.map +1 -0
  39. package/dist/esm/client.js +3 -0
  40. package/dist/esm/client.js.map +1 -1
  41. package/dist/esm/index.js +3 -0
  42. package/dist/esm/index.js.map +1 -1
  43. package/dist/esm/namespaces/account.js +17 -9
  44. package/dist/esm/namespaces/account.js.map +1 -1
  45. package/dist/esm/namespaces/analytics.js +54 -0
  46. package/dist/esm/namespaces/analytics.js.map +1 -1
  47. package/dist/esm/namespaces/desk.js +264 -45
  48. package/dist/esm/namespaces/desk.js.map +1 -1
  49. package/dist/esm/namespaces/plugins.js +1 -0
  50. package/dist/esm/namespaces/plugins.js.map +1 -1
  51. package/dist/esm/namespaces/portal.js +45 -0
  52. package/dist/esm/namespaces/portal.js.map +1 -1
  53. package/dist/esm/namespaces/tunnel.js +42 -0
  54. package/dist/esm/namespaces/tunnel.js.map +1 -0
  55. package/dist/esm/namespaces/whatsapp.js +2 -23
  56. package/dist/esm/namespaces/whatsapp.js.map +1 -1
  57. package/dist/esm/sender/http/httpsender.js +14 -5
  58. package/dist/esm/sender/http/httpsender.js.map +1 -1
  59. package/dist/esm/sender/multi/multisender.js +28 -9
  60. package/dist/esm/sender/multi/multisender.js.map +1 -1
  61. package/dist/esm/sender/sessionnegotiator.js +1 -1
  62. package/dist/esm/sender/sessionnegotiator.js.map +1 -1
  63. package/dist/esm/sender/tcp/tcpsender.js +1 -1
  64. package/dist/esm/sender/tcp/tcpsender.js.map +1 -1
  65. package/dist/esm/sender/websocket/websocketsender.js +1 -1
  66. package/dist/esm/sender/websocket/websocketsender.js.map +1 -1
  67. package/dist/esm/types/desk.js.map +1 -1
  68. package/dist/esm/types/flow.js +343 -1
  69. package/dist/esm/types/flow.js.map +1 -1
  70. package/dist/esm/utils/desk.js +59 -0
  71. package/dist/esm/utils/desk.js.map +1 -0
  72. package/dist/esm/utils/thread.js +80 -0
  73. package/dist/esm/utils/thread.js.map +1 -0
  74. package/dist/esm/utils/whatsapp.js +263 -0
  75. package/dist/esm/utils/whatsapp.js.map +1 -0
  76. package/dist/types/client.d.ts +2 -0
  77. package/dist/types/client.d.ts.map +1 -1
  78. package/dist/types/index.d.ts +3 -0
  79. package/dist/types/index.d.ts.map +1 -1
  80. package/dist/types/namespaces/account.d.ts +1790 -2
  81. package/dist/types/namespaces/account.d.ts.map +1 -1
  82. package/dist/types/namespaces/analytics.d.ts +60 -0
  83. package/dist/types/namespaces/analytics.d.ts.map +1 -1
  84. package/dist/types/namespaces/desk.d.ts +124 -4
  85. package/dist/types/namespaces/desk.d.ts.map +1 -1
  86. package/dist/types/namespaces/plugins.d.ts +1 -0
  87. package/dist/types/namespaces/plugins.d.ts.map +1 -1
  88. package/dist/types/namespaces/portal.d.ts +45 -0
  89. package/dist/types/namespaces/portal.d.ts.map +1 -1
  90. package/dist/types/namespaces/tunnel.d.ts +28 -0
  91. package/dist/types/namespaces/tunnel.d.ts.map +1 -0
  92. package/dist/types/namespaces/whatsapp.d.ts +3 -2
  93. package/dist/types/namespaces/whatsapp.d.ts.map +1 -1
  94. package/dist/types/schemas/webhook.d.ts +2 -2
  95. package/dist/types/sender/gateway/customgatewaysender.d.ts +1 -1
  96. package/dist/types/sender/http/httpsender.d.ts +3 -3
  97. package/dist/types/sender/http/httpsender.d.ts.map +1 -1
  98. package/dist/types/sender/multi/multisender.d.ts +1 -0
  99. package/dist/types/sender/multi/multisender.d.ts.map +1 -1
  100. package/dist/types/sender/sender.d.ts +1 -1
  101. package/dist/types/sender/tcp/tcpsender.d.ts +1 -1
  102. package/dist/types/sender/websocket/websocketsender.d.ts +1 -1
  103. package/dist/types/types/desk.d.ts +57 -1
  104. package/dist/types/types/desk.d.ts.map +1 -1
  105. package/dist/types/types/flow.d.ts +3269 -142
  106. package/dist/types/types/flow.d.ts.map +1 -1
  107. package/dist/types/types/message.d.ts +1 -1
  108. package/dist/types/types/whatsapp.d.ts +10 -2
  109. package/dist/types/types/whatsapp.d.ts.map +1 -1
  110. package/dist/types/utils/desk.d.ts +6 -0
  111. package/dist/types/utils/desk.d.ts.map +1 -0
  112. package/dist/types/utils/thread.d.ts +4 -0
  113. package/dist/types/utils/thread.d.ts.map +1 -0
  114. package/dist/types/utils/whatsapp.d.ts +103 -0
  115. package/dist/types/utils/whatsapp.d.ts.map +1 -0
  116. package/package.json +8 -11
  117. package/src/client.ts +3 -0
  118. package/src/index.ts +3 -0
  119. package/src/namespaces/account.ts +20 -12
  120. package/src/namespaces/analytics.ts +154 -0
  121. package/src/namespaces/desk.ts +428 -77
  122. package/src/namespaces/plugins.ts +2 -0
  123. package/src/namespaces/portal.ts +110 -0
  124. package/src/namespaces/tunnel.ts +58 -0
  125. package/src/namespaces/whatsapp.ts +4 -39
  126. package/src/sender/http/httpsender.ts +20 -6
  127. package/src/sender/multi/multisender.ts +38 -14
  128. package/src/sender/sessionnegotiator.ts +1 -1
  129. package/src/sender/tcp/tcpsender.ts +1 -1
  130. package/src/sender/websocket/websocketsender.ts +1 -1
  131. package/src/types/desk.ts +66 -1
  132. package/src/types/flow.ts +387 -246
  133. package/src/types/message.ts +1 -1
  134. package/src/types/whatsapp.ts +11 -2
  135. package/src/utils/desk.ts +78 -0
  136. package/src/utils/thread.ts +119 -0
  137. package/src/utils/whatsapp.ts +530 -0
@@ -192,6 +192,116 @@ export class PortalNamespace extends Namespace {
192
192
  })
193
193
  }
194
194
 
195
+ public async getTenantActiveMessagesMetrics(
196
+ tenantId: string,
197
+ interval: 'D' | 'M' | 'NI',
198
+ filters?: {
199
+ applicationIdentity?: Identity
200
+ startDate?: Date | string
201
+ endDate?: Date | string
202
+ },
203
+ opts?: ConsumeOptions,
204
+ ): Promise<Array<{ intervalStart: string; intervalEnd: string; count: number }>> {
205
+ return await this.sendCommand(
206
+ {
207
+ method: 'get',
208
+ uri: uri`/metrics/${tenantId}/active-messages/${interval}?${filters}`,
209
+ },
210
+ {
211
+ collection: true,
212
+ ...opts,
213
+ },
214
+ )
215
+ }
216
+
217
+ public async getTenantReceivedMessagesMetrics(
218
+ tenantId: string,
219
+ interval: 'D' | 'M' | 'NI',
220
+ filters?: {
221
+ applicationIdentity?: Identity
222
+ startDate?: Date | string
223
+ endDate?: Date | string
224
+ },
225
+ opts?: ConsumeOptions,
226
+ ): Promise<Array<{ intervalStart: string; intervalEnd: string; count: number }>> {
227
+ return await this.sendCommand(
228
+ {
229
+ method: 'get',
230
+ uri: uri`/metrics/${tenantId}/received-messages/${interval}?${filters}`,
231
+ },
232
+ {
233
+ collection: true,
234
+ ...opts,
235
+ },
236
+ )
237
+ }
238
+
239
+ public async getTenantSentMessagesMetrics(
240
+ tenantId: string,
241
+ interval: 'D' | 'M' | 'NI',
242
+ filters?: {
243
+ applicationIdentity?: Identity
244
+ startDate?: Date | string
245
+ endDate?: Date | string
246
+ },
247
+ opts?: ConsumeOptions,
248
+ ): Promise<Array<{ intervalStart: string; intervalEnd: string; count: number }>> {
249
+ return await this.sendCommand(
250
+ {
251
+ method: 'get',
252
+ uri: uri`/metrics/${tenantId}/sent-messages/${interval}?${filters}`,
253
+ },
254
+ {
255
+ collection: true,
256
+ ...opts,
257
+ },
258
+ )
259
+ }
260
+
261
+ public async getTenantActiveUsersMetrics(
262
+ tenantId: string,
263
+ interval: 'D' | 'M' | 'NI',
264
+ filters?: {
265
+ applicationIdentity?: Identity
266
+ startDate?: Date | string
267
+ endDate?: Date | string
268
+ },
269
+ opts?: ConsumeOptions,
270
+ ): Promise<Array<{ intervalStart: string; intervalEnd: string; count: number }>> {
271
+ return await this.sendCommand(
272
+ {
273
+ method: 'get',
274
+ uri: uri`/metrics/${tenantId}/active-users/${interval}?${filters}`,
275
+ },
276
+ {
277
+ collection: true,
278
+ ...opts,
279
+ },
280
+ )
281
+ }
282
+
283
+ public async getTenantEngagedUsersMetrics(
284
+ tenantId: string,
285
+ interval: 'D' | 'M' | 'NI',
286
+ filters?: {
287
+ applicationIdentity?: Identity
288
+ startDate?: Date | string
289
+ endDate?: Date | string
290
+ },
291
+ opts?: ConsumeOptions,
292
+ ): Promise<Array<{ intervalStart: string; intervalEnd: string; count: number }>> {
293
+ return await this.sendCommand(
294
+ {
295
+ method: 'get',
296
+ uri: uri`/metrics/${tenantId}/engaged-users/${interval}?${filters}`,
297
+ },
298
+ {
299
+ collection: true,
300
+ ...opts,
301
+ },
302
+ )
303
+ }
304
+
195
305
  public async tenantExists(tenantId: string): Promise<boolean> {
196
306
  try {
197
307
  await this.sendCommand({
@@ -0,0 +1,58 @@
1
+ import type { BlipClient } from '../client.ts'
2
+ import { type Identity, Node } from '../types/index.ts'
3
+ import { uri } from '../utils/uri.ts'
4
+ import { type ConsumeOptions, Namespace, type SendCommandOptions } from './namespace.ts'
5
+
6
+ export class TunnelNamespace extends Namespace {
7
+ constructor(blipClient: BlipClient, defaultOptions?: SendCommandOptions) {
8
+ super(blipClient, 'tunnel', defaultOptions)
9
+ }
10
+
11
+ /**
12
+ * Retrieves metadata information about the tunnel origin and destination
13
+ * This must only be called by a subbot
14
+ * @returns An object containing:
15
+ * - `owner` - The identity of the subbot owner (router)
16
+ * - `originator` - The identity of the originator on the router (user)
17
+ * - `destination` - The identity of the destination child (subbot)
18
+ */
19
+ public getTunnel(
20
+ tunnelIdentityOrName: Identity | string,
21
+ opts?: ConsumeOptions,
22
+ ): Promise<{
23
+ owner: Identity
24
+ originator: Identity
25
+ destination: Identity
26
+ }> {
27
+ const node =
28
+ typeof tunnelIdentityOrName === 'string'
29
+ ? new Node(tunnelIdentityOrName, 'tunnel.msging.net')
30
+ : Node.from(tunnelIdentityOrName)
31
+
32
+ if (node.getSource() !== 'Tunnel') {
33
+ throw new Error('Invalid tunnel identity or name')
34
+ }
35
+
36
+ return this.sendCommand(
37
+ {
38
+ method: 'get',
39
+ uri: uri`/tunnels/${node.name}`,
40
+ },
41
+ opts,
42
+ )
43
+ }
44
+
45
+ /**
46
+ * Retrieves the tunnel ID for a given originator and destination
47
+ * Must only be called by a router
48
+ * @param originator - The identity of the originator on the router (user)
49
+ * @param destination - The identity of the destination child (subbot)
50
+ * @returns The tunnel ID
51
+ */
52
+ public getTunnelId(originator: Identity, destination: Identity) {
53
+ return this.sendCommand({
54
+ method: 'get',
55
+ uri: uri`/tunnels/${originator}/${destination}`,
56
+ })
57
+ }
58
+ }
@@ -1,16 +1,8 @@
1
1
  import type { BlipClient } from '../client.ts'
2
2
  import type { Identity } from '../types/index.ts'
3
- import type {
4
- BodyComponent,
5
- ButtonComponent,
6
- HandleFormats,
7
- HeaderComponent,
8
- MessageTemplate,
9
- MessageTemplateVariable,
10
- WhatsAppTemplateLanguage,
11
- WhatsappFlow,
12
- } from '../types/whatsapp.ts'
3
+ import type { MessageTemplate, WhatsAppTemplateLanguage, WhatsappFlow } from '../types/whatsapp.ts'
13
4
  import { uri } from '../utils/uri.ts'
5
+ import { getMessageTemplateVariables } from '../utils/whatsapp.ts'
14
6
  import { type ConsumeOptions, Namespace, type SendCommandOptions } from './namespace.ts'
15
7
 
16
8
  export class WhatsAppNamespace extends Namespace {
@@ -69,7 +61,7 @@ export class WhatsAppNamespace extends Namespace {
69
61
  templateName: string,
70
62
  language?: WhatsAppTemplateLanguage,
71
63
  opts?: ConsumeOptions,
72
- ): Promise<(MessageTemplate & { variables: Array<MessageTemplateVariable> }) | undefined> {
64
+ ): Promise<(MessageTemplate & { variables: ReturnType<typeof getMessageTemplateVariables> }) | undefined> {
73
65
  let templates = await this.getMessageTemplates({ name: templateName }, opts)
74
66
  if (language) {
75
67
  templates = templates.filter((template) => template.language === language)
@@ -79,36 +71,9 @@ export class WhatsAppNamespace extends Namespace {
79
71
  return
80
72
  }
81
73
 
82
- const variables: Array<MessageTemplateVariable> = []
83
-
84
- const handleHeader = template.components.find(
85
- (c): c is HeaderComponent<HandleFormats> =>
86
- c.type === 'HEADER' && ['IMAGE', 'VIDEO', 'DOCUMENT'].includes(c.format),
87
- )
88
- if (handleHeader) {
89
- variables.push({ type: 'MEDIA', example: handleHeader.example.header_handle?.[0] })
90
- }
91
-
92
- const body = template.components.find((c): c is BodyComponent => c.type === 'BODY')
93
- if (body?.example?.body_text) {
94
- variables.push(...body.example.body_text[0].map((text) => ({ type: 'BODY' as const, example: text })))
95
- } else if (body) {
96
- variables.push(...(body.text.match(/{{(\d)}}/g)?.map(() => ({ type: 'BODY' as const })) ?? []))
97
- }
98
-
99
- const button = template.components.find((c): c is ButtonComponent => c.type === 'BUTTONS')
100
- if (button) {
101
- const urlButton = button.buttons.find((b) => b.type === 'URL')
102
- if (urlButton?.example?.length) {
103
- variables.push(...urlButton.example.map((example: string) => ({ type: 'BUTTON', example })))
104
- } else if (urlButton) {
105
- variables.push(...(urlButton.url.match(/{{(\d)}}/g)?.map(() => ({ type: 'BUTTON' })) ?? []))
106
- }
107
- }
108
-
109
74
  return {
110
75
  ...template,
111
- variables,
76
+ variables: getMessageTemplateVariables(template.components),
112
77
  }
113
78
  }
114
79
 
@@ -1,4 +1,11 @@
1
- import type { Command, CommandMethods, Message, MessageTypes, UnknownCommandResponse } from '../../types/index.ts'
1
+ import {
2
+ type Command,
3
+ type CommandMethods,
4
+ type Message,
5
+ type MessageTypes,
6
+ Node,
7
+ type UnknownCommandResponse,
8
+ } from '../../types/index.ts'
2
9
  import { BlipError } from '../bliperror.ts'
3
10
  import { RetryableError } from '../retryableerror.ts'
4
11
  import { ConnectionSender, type ConnectionSenderConstructor, type Sender } from '../sender.ts'
@@ -6,7 +13,7 @@ import { EnvelopeThrottler } from '../throttler.ts'
6
13
 
7
14
  export class HttpSender extends ConnectionSender implements Sender {
8
15
  private readonly baseurl: string
9
- private readonly token: string
16
+ private readonly authHeaders: Record<string, string>
10
17
  private readonly throttler = new EnvelopeThrottler()
11
18
 
12
19
  constructor(options: ConstructorParameters<ConnectionSenderConstructor>[0]) {
@@ -16,11 +23,18 @@ export class HttpSender extends ConnectionSender implements Sender {
16
23
  this.baseurl = `https://${prefix}http.${this.domain}`
17
24
 
18
25
  if (options.authentication.scheme === 'key') {
19
- this.token = HttpSender.createToken(options.node, options.authentication.key)
26
+ const token = HttpSender.createToken(options.node, options.authentication.key)
27
+ this.authHeaders = { Authorization: `Key ${token}` }
20
28
  } else if (options.authentication.scheme === 'token') {
21
- this.token = options.authentication.token
29
+ this.authHeaders = { Authorization: `Key ${options.authentication.token}` }
30
+ } else if (options.authentication.scheme === 'external') {
31
+ this.authHeaders = {
32
+ Authorization: `Bearer ${options.authentication.token}`,
33
+ 'http-session-authentication-external-issuer': options.authentication.issuer,
34
+ 'http-session-identity': Node.from(options.node).toIdentity(),
35
+ }
22
36
  } else {
23
- throw new Error('HttpSender only supports key or token authentication')
37
+ throw new Error('HttpSender only supports key, token, or external authentication')
24
38
  }
25
39
  }
26
40
 
@@ -62,7 +76,7 @@ export class HttpSender extends ConnectionSender implements Sender {
62
76
  method: 'POST',
63
77
  headers: {
64
78
  'Content-Type': 'application/json',
65
- Authorization: `Key ${this.token}`,
79
+ ...this.authHeaders,
66
80
  },
67
81
  body,
68
82
  })
@@ -4,12 +4,17 @@ import type { Sender } from '../sender.ts'
4
4
 
5
5
  export type SenderFactory = () => MaybePromise<Sender>
6
6
 
7
+ const isSenderFactory = (value: Sender | SenderFactory): value is SenderFactory => value instanceof Function
8
+
9
+ type SenderEntry = {
10
+ filter: (envelope: Envelope) => boolean | undefined
11
+ factory: () => Promise<Sender>
12
+ resolved?: Sender
13
+ resolving?: Promise<Sender>
14
+ }
15
+
7
16
  export class MultiSender implements Sender, Closable {
8
- private senders: Array<{
9
- filter: (envelope: Envelope) => boolean | undefined
10
- sender: Sender | SenderFactory
11
- resolved?: Sender
12
- }>
17
+ private senders: Array<SenderEntry>
13
18
 
14
19
  /**
15
20
  * @param initializers Array of objects containing a filter function and a sender or a factory function that returns a sender.
@@ -23,11 +28,14 @@ export class MultiSender implements Sender, Closable {
23
28
  sender: Sender | SenderFactory
24
29
  }>,
25
30
  ) {
26
- this.senders = initializers.map(({ filter, sender }) => ({
27
- filter: filter ?? (() => true),
28
- sender,
29
- resolved: sender instanceof Function ? undefined : sender,
30
- }))
31
+ this.senders = initializers.map(({ filter, sender }) => {
32
+ const isFactory = isSenderFactory(sender)
33
+ return {
34
+ filter: filter ?? (() => true),
35
+ factory: isFactory ? () => Promise.resolve(sender()) : () => Promise.resolve(sender),
36
+ resolved: isFactory ? undefined : sender,
37
+ }
38
+ })
31
39
  }
32
40
 
33
41
  async sendMessage<Type extends MessageTypes>(message: Message<Type>): Promise<void> {
@@ -57,14 +65,30 @@ export class MultiSender implements Sender, Closable {
57
65
  return matched.resolved! as InstanceType<TProto>
58
66
  }
59
67
 
60
- private async getSender(envelope: Envelope): Promise<Sender> {
68
+ private getSender(envelope: Envelope): Promise<Sender> {
61
69
  const matched = this.senders.find(({ filter }) => filter(envelope))
62
70
  if (!matched) throw new Error('No sender matched for envelope')
63
71
 
64
- if (!matched.resolved) {
65
- matched.resolved = typeof matched.sender === 'function' ? await matched.sender() : matched.sender
72
+ return this.resolveSender(matched)
73
+ }
74
+
75
+ private resolveSender(entry: SenderEntry): Promise<Sender> {
76
+ if (entry.resolved) return Promise.resolve(entry.resolved)
77
+
78
+ if (!entry.resolving) {
79
+ entry.resolving = entry
80
+ .factory()
81
+ .then((sender) => {
82
+ entry.resolved = sender
83
+ entry.resolving = undefined
84
+ return sender
85
+ })
86
+ .catch((error) => {
87
+ entry.resolving = undefined
88
+ throw error
89
+ })
66
90
  }
67
91
 
68
- return matched.resolved
92
+ return entry.resolving
69
93
  }
70
94
  }
@@ -125,7 +125,7 @@ export class SessionNegotiator {
125
125
  return
126
126
  }
127
127
 
128
- if (this.presencePromise) {
128
+ if (this.presencePromise !== null) {
129
129
  return this.presencePromise
130
130
  }
131
131
 
@@ -144,7 +144,7 @@ class TCPHandle<T> {
144
144
  }
145
145
 
146
146
  public async close() {
147
- if (!this.closing && this.currentSocketPromise) {
147
+ if (!this.closing && this.currentSocketPromise !== null) {
148
148
  this.closing = true
149
149
  const current = await this.currentSocketPromise
150
150
  current.end().removeAllListeners().destroySoon()
@@ -138,7 +138,7 @@ class WebSocketHandle<T> {
138
138
  }
139
139
 
140
140
  public async close() {
141
- if (!this.closing && this.currentWebSocketPromise) {
141
+ if (!this.closing && this.currentWebSocketPromise !== null) {
142
142
  this.closing = true
143
143
  const current = await this.currentWebSocketPromise
144
144
  current.close()
package/src/types/desk.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import type { Identity } from './node.ts'
2
+
1
3
  export type TicketStatus =
2
4
  | 'Waiting'
3
5
  | 'Open'
@@ -12,6 +14,8 @@ export type AttendanceHour = {
12
14
  title: string
13
15
  description: string
14
16
  isMain: boolean
17
+ storageDate?: string
18
+ timeZoneId?: string
15
19
  }
16
20
 
17
21
  export enum DayOfWeek {
@@ -38,14 +42,75 @@ export type AttendanceHourOffItem = {
38
42
  endDate: string
39
43
  }
40
44
 
41
- export type Queue = {
45
+ export type DescriptionDocument = {
42
46
  id: string
43
47
  description: string
44
48
  }
45
49
 
50
+ export type Queue = DescriptionDocument
51
+
46
52
  export type DetailedAttendanceHour = {
47
53
  attendanceHour: AttendanceHour
48
54
  attendanceHourScheduleItems: Array<AttendanceHourScheduleItem>
49
55
  attendanceHourOffItems: Array<AttendanceHourOffItem>
50
56
  queues: Array<Queue>
57
+ attendants: Array<DescriptionDocument>
58
+ }
59
+
60
+ export type DeskAttendanceQueue = {
61
+ id?: string
62
+ ownerIdentity?: Identity
63
+ name: string
64
+ isActive: boolean
65
+ storageDate?: string
66
+ priority?: number
67
+ uniqueId?: string
68
+ attendanceHourId?: string
69
+ }
70
+
71
+ export type DeskAttendanceQueueTag = {
72
+ id?: string
73
+ attendanceQueueId?: string
74
+ ownerIdentity?: Identity
75
+ tag: string
76
+ }
77
+
78
+ export type DeskRuleRelation = 'Contains' | 'NotContains' | 'Equals' | 'NotEquals'
79
+
80
+ export type DeskRuleOperator = 'Or' | 'And'
81
+
82
+ export type DeskRuleCondition = {
83
+ property: string
84
+ relation: DeskRuleRelation
85
+ values: Array<string>
86
+ }
87
+
88
+ export type DeskRule = {
89
+ id?: string
90
+ ownerIdentity?: Identity
91
+ title: string
92
+ team: string
93
+ property?: string
94
+ relation?: DeskRuleRelation
95
+ isActive?: boolean
96
+ values?: Array<string>
97
+ conditions?: Array<DeskRuleCondition>
98
+ operator?: DeskRuleOperator
99
+ priority?: number
100
+ storageDate?: string
101
+ queueId?: string
102
+ }
103
+
104
+ export type DeskPriorityRule = {
105
+ id?: string
106
+ ownerIdentity?: Identity
107
+ title: string
108
+ queueId: string
109
+ isActive?: boolean
110
+ conditions?: Array<DeskRuleCondition>
111
+ operator?: DeskRuleOperator
112
+ priority?: number
113
+ urgency: number
114
+ applyConditions: boolean
115
+ storageDate?: string
51
116
  }