@relaymessenger/sdk 0.2.0 → 0.3.0-staging.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/LICENSES/Apache-2.0.txt +201 -0
  3. package/NOTICE +6 -0
  4. package/README.md +189 -17
  5. package/dist/client.d.ts +135 -57
  6. package/dist/client.d.ts.map +1 -0
  7. package/dist/client.js +520 -144
  8. package/dist/client.js.map +1 -1
  9. package/dist/errors.d.ts +26 -19
  10. package/dist/errors.d.ts.map +1 -0
  11. package/dist/errors.js +28 -37
  12. package/dist/errors.js.map +1 -1
  13. package/dist/index.d.ts +9 -9
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +7 -8
  16. package/dist/index.js.map +1 -1
  17. package/dist/operations.d.ts +144 -0
  18. package/dist/operations.d.ts.map +1 -0
  19. package/dist/operations.js +190 -0
  20. package/dist/operations.js.map +1 -0
  21. package/dist/pagination.d.ts +24 -0
  22. package/dist/pagination.d.ts.map +1 -0
  23. package/dist/pagination.js +48 -0
  24. package/dist/pagination.js.map +1 -0
  25. package/dist/types.d.ts +436 -74
  26. package/dist/types.d.ts.map +1 -0
  27. package/dist/types.js +0 -1
  28. package/dist/types.js.map +1 -1
  29. package/dist/webhooks.d.ts +19 -0
  30. package/dist/webhooks.d.ts.map +1 -0
  31. package/dist/webhooks.js +36 -0
  32. package/dist/webhooks.js.map +1 -0
  33. package/dist/websocket.d.ts +38 -0
  34. package/dist/websocket.d.ts.map +1 -0
  35. package/dist/websocket.js +547 -0
  36. package/dist/websocket.js.map +1 -0
  37. package/package.json +22 -15
  38. package/dist/file-cursor.d.ts +0 -10
  39. package/dist/file-cursor.js +0 -53
  40. package/dist/file-cursor.js.map +0 -1
  41. package/dist/idempotency.d.ts +0 -8
  42. package/dist/idempotency.js +0 -35
  43. package/dist/idempotency.js.map +0 -1
  44. package/dist/memory-dedupe.d.ts +0 -13
  45. package/dist/memory-dedupe.js +0 -25
  46. package/dist/memory-dedupe.js.map +0 -1
  47. package/dist/poll-loop.d.ts +0 -43
  48. package/dist/poll-loop.js +0 -164
  49. package/dist/poll-loop.js.map +0 -1
  50. package/dist/signature.d.ts +0 -18
  51. package/dist/signature.js +0 -61
  52. package/dist/signature.js.map +0 -1
  53. package/dist/url.d.ts +0 -6
  54. package/dist/url.js +0 -40
  55. package/dist/url.js.map +0 -1
package/dist/client.js CHANGED
@@ -1,156 +1,532 @@
1
- import { RelayApiError, classifyRelayHttpStatus, isAbortError, } from "./errors.js";
2
- import { normalizeRelayBaseUrl } from "./url.js";
3
- async function readErrorDetail(response) {
4
- try {
5
- const body = (await response.json());
6
- return {
7
- ...(body?.error?.code ? { code: body.error.code } : {}),
8
- ...(body?.error?.details ? { details: body.error.details } : {}),
9
- message: body?.error?.message ?? body?.message ?? "",
10
- };
11
- }
12
- catch {
13
- return { message: "" };
1
+ import { RelayAPIError, isAbortError } from "./errors.js";
2
+ import { ChatsPage, MessagesPage } from "./pagination.js";
3
+ import { Webhooks } from "./webhooks.js";
4
+ import { runWebSocket, } from "./websocket.js";
5
+ const delay = async (milliseconds, signal) => {
6
+ if (milliseconds <= 0)
7
+ return;
8
+ await new Promise((resolve, reject) => {
9
+ const timer = setTimeout(resolve, milliseconds);
10
+ signal?.addEventListener("abort", () => {
11
+ clearTimeout(timer);
12
+ reject(signal.reason);
13
+ }, { once: true });
14
+ });
15
+ };
16
+ const pathID = (value) => encodeURIComponent(value);
17
+ class Transport {
18
+ baseURL;
19
+ #apiKey;
20
+ #fetch;
21
+ #maxRetries;
22
+ #timeout;
23
+ #retryBaseDelayMs;
24
+ constructor(options) {
25
+ if (!options.apiKey?.trim())
26
+ throw new Error("Relay API key is required.");
27
+ this.baseURL = (options.baseURL ?? "https://api.relayapp.im").replace(/\/+$/, "");
28
+ this.#apiKey = options.apiKey;
29
+ this.#fetch = options.fetch ?? globalThis.fetch;
30
+ this.#maxRetries = options.maxRetries ?? 2;
31
+ this.#timeout = options.timeout ?? 15_000;
32
+ this.#retryBaseDelayMs = options.retryBaseDelayMs ?? 250;
14
33
  }
15
- }
16
- export function createRelayClient(options) {
17
- if (!options.token.trim()) {
18
- throw new Error("relay: Agent Token is required");
19
- }
20
- const baseUrl = normalizeRelayBaseUrl(options.baseUrl);
21
- const fetchImpl = options.fetchImpl ?? ((input, init) => fetch(input, init));
22
- const requestTimeoutMs = options.requestTimeoutMs ?? 15_000;
23
- const request = async (params) => {
24
- const url = new URL(`${baseUrl}${params.path}`);
25
- for (const [key, value] of Object.entries(params.query ?? {})) {
34
+ async request(request) {
35
+ const url = new URL(`${this.baseURL}${request.path}`);
36
+ for (const [name, value] of Object.entries(request.query ?? {})) {
26
37
  if (value !== undefined)
27
- url.searchParams.set(key, String(value));
38
+ url.searchParams.set(name, String(value));
39
+ }
40
+ const maxRetries = request.options?.maxRetries ?? this.#maxRetries;
41
+ const mayRetry = request.retryable === true
42
+ || request.method === "GET"
43
+ || request.method === "PUT"
44
+ || request.method === "PATCH"
45
+ || request.method === "DELETE"
46
+ || request.idempotencyKey !== undefined;
47
+ for (let attempt = 0;; attempt += 1) {
48
+ const timeout = request.options?.timeout ?? this.#timeout;
49
+ const timeoutSignal = AbortSignal.timeout(timeout);
50
+ const signal = request.options?.signal
51
+ ? AbortSignal.any([request.options.signal, timeoutSignal])
52
+ : timeoutSignal;
53
+ const headers = new Headers(request.options?.headers);
54
+ headers.set("authorization", `Bearer ${this.#apiKey}`);
55
+ headers.set("accept", "application/json");
56
+ if (request.body !== undefined)
57
+ headers.set("content-type", "application/json");
58
+ if (request.idempotencyKey) {
59
+ headers.set("idempotency-key", request.idempotencyKey);
60
+ }
61
+ let response;
62
+ try {
63
+ response = await this.#fetch(url, {
64
+ method: request.method,
65
+ headers,
66
+ ...(request.body === undefined
67
+ ? {}
68
+ : { body: JSON.stringify(request.body) }),
69
+ signal,
70
+ });
71
+ }
72
+ catch (cause) {
73
+ if (request.options?.signal?.aborted)
74
+ throw cause;
75
+ if (isAbortError(cause) && !timeoutSignal.aborted)
76
+ throw cause;
77
+ const error = new RelayAPIError(timeoutSignal.aborted
78
+ ? `Relay request timed out after ${timeout}ms.`
79
+ : "Relay network request failed.", { cause });
80
+ if (!mayRetry || attempt >= maxRetries)
81
+ throw error;
82
+ await delay(this.#retryBaseDelayMs * 2 ** attempt, request.options?.signal);
83
+ continue;
84
+ }
85
+ if (response.ok) {
86
+ if (response.status === 204)
87
+ return undefined;
88
+ const text = await response.text();
89
+ return (text ? JSON.parse(text) : undefined);
90
+ }
91
+ const text = await response.text();
92
+ let body;
93
+ try {
94
+ body = text ? JSON.parse(text) : undefined;
95
+ }
96
+ catch {
97
+ body = undefined;
98
+ }
99
+ const retryAfter = body?.error?.retry_after
100
+ ?? Number(response.headers.get("retry-after") ?? NaN);
101
+ const error = new RelayAPIError(body?.error?.message
102
+ ?? `Relay request failed with HTTP ${response.status}.`, {
103
+ status: response.status,
104
+ ...(body?.error?.code === undefined ? {} : { code: body.error.code }),
105
+ ...(body?.trace_id === undefined ? {} : { traceId: body.trace_id }),
106
+ ...(body?.error?.doc_url === undefined
107
+ ? {}
108
+ : { docURL: body.error.doc_url }),
109
+ ...(Number.isFinite(retryAfter) ? { retryAfter } : {}),
110
+ body: body ?? text,
111
+ });
112
+ if (!mayRetry || !error.retryable || attempt >= maxRetries)
113
+ throw error;
114
+ const wait = Number.isFinite(retryAfter)
115
+ ? retryAfter * 1_000
116
+ : this.#retryBaseDelayMs * 2 ** attempt;
117
+ await delay(wait, request.options?.signal);
118
+ }
119
+ }
120
+ async upload(allocation, data, options = {}) {
121
+ const headers = new Headers(allocation.required_headers);
122
+ for (const [name, value] of new Headers(options.headers)) {
123
+ headers.set(name, value);
28
124
  }
29
- const timeoutSignal = AbortSignal.timeout(params.timeoutMs ?? requestTimeoutMs);
30
- const signal = params.signal
31
- ? AbortSignal.any([params.signal, timeoutSignal])
32
- : timeoutSignal;
33
125
  let response;
34
126
  try {
35
- response = await fetchImpl(url.toString(), {
36
- method: params.method,
37
- headers: {
38
- authorization: `Bearer ${options.token}`,
39
- ...(params.body === undefined ? {} : { "content-type": "application/json" }),
40
- ...params.headers,
41
- },
42
- ...(params.body === undefined ? {} : { body: JSON.stringify(params.body) }),
43
- signal,
127
+ response = await this.#fetch(allocation.upload_url, {
128
+ method: "PUT",
129
+ headers,
130
+ body: data,
131
+ ...(options.signal ? { signal: options.signal } : {}),
44
132
  });
45
133
  }
46
- catch (error) {
47
- if (timeoutSignal.aborted && !params.signal?.aborted) {
48
- throw new RelayApiError(`relay: ${params.method} ${params.path} timed out after ${params.timeoutMs ?? requestTimeoutMs}ms`, { kind: "retryable" });
49
- }
50
- if (isAbortError(error))
51
- throw error;
52
- throw new RelayApiError(`relay: network error: ${String(error)}`, {
53
- kind: "retryable",
54
- });
134
+ catch (cause) {
135
+ throw new RelayAPIError("Relay attachment upload failed.", { cause });
55
136
  }
56
137
  if (!response.ok) {
57
- const detail = await readErrorDetail(response);
58
- throw new RelayApiError(`relay: ${params.method} ${params.path} failed with ${response.status}${detail.message ? `: ${detail.message}` : ""}`, {
59
- status: response.status,
60
- kind: classifyRelayHttpStatus(response.status),
61
- ...(detail.code ? { code: detail.code } : {}),
62
- ...(detail.details ? { details: detail.details } : {}),
63
- });
138
+ throw new RelayAPIError(`Relay attachment upload failed with HTTP ${response.status}.`, { status: response.status });
64
139
  }
65
- return response;
66
- };
67
- const client = {
68
- baseUrl,
69
- getMe: async (params) => {
70
- const response = await request({
71
- method: "GET",
72
- path: "/v1/agents/me",
73
- ...(params?.signal ? { signal: params.signal } : {}),
74
- });
75
- const body = (await response.json());
76
- return body.agent;
77
- },
78
- pollEvents: async (params) => {
79
- const timeoutSeconds = Math.min(Math.max(params.timeoutSeconds ?? 30, 1), 30);
80
- const response = await request({
81
- method: "GET",
82
- path: "/v1/events",
83
- query: {
84
- cursor: params.cursor,
85
- timeout: timeoutSeconds,
86
- ...(params.limit === undefined ? {} : { limit: params.limit }),
87
- },
88
- ...(params.signal ? { signal: params.signal } : {}),
89
- timeoutMs: (timeoutSeconds + 15) * 1_000,
90
- });
91
- const body = (await response.json());
92
- const events = Array.isArray(body.events) ? body.events : [];
93
- const nextCursor = typeof body.next_cursor === "number" && Number.isSafeInteger(body.next_cursor)
94
- ? body.next_cursor
95
- : params.cursor;
96
- return { events, nextCursor };
97
- },
98
- sendMessage: async (params) => {
99
- const response = await request({
100
- method: "POST",
101
- path: "/v1/messages",
102
- headers: { "idempotency-key": params.idempotencyKey },
103
- body: {
104
- conversation_id: params.conversationId,
105
- parts: params.parts,
106
- ...(params.invocationId ? { invocation_id: params.invocationId } : {}),
107
- ...(params.replyTo ? { reply_to: params.replyTo } : {}),
108
- },
109
- ...(params.signal ? { signal: params.signal } : {}),
110
- });
111
- const body = (await response.json());
112
- return { messages: body.messages };
113
- },
114
- sendText: async (params) => {
115
- const { text, ...rest } = params;
116
- return client.sendMessage({
117
- ...rest,
118
- parts: [{ type: "text", text }],
119
- });
120
- },
121
- setTyping: async (params) => {
122
- await request({
123
- method: "POST",
124
- path: `/v1/conversations/${encodeURIComponent(params.conversationId)}/typing`,
125
- body: {
126
- started: params.started,
127
- ...(params.label ? { label: params.label } : {}),
128
- ...(params.invocationId ? { invocation_id: params.invocationId } : {}),
129
- },
130
- ...(params.signal ? { signal: params.signal } : {}),
131
- });
132
- },
133
- setResponding: async (params) => {
134
- await request({
135
- method: "POST",
136
- path: `/v1/conversations/${encodeURIComponent(params.conversationId)}/responding`,
137
- body: {
138
- message_id: params.messageId,
139
- ...(params.label ? { label: params.label } : {}),
140
- ...(params.invocationId ? { invocation_id: params.invocationId } : {}),
141
- },
142
- ...(params.signal ? { signal: params.signal } : {}),
143
- });
144
- },
145
- markRead: async (params) => {
146
- await request({
147
- method: "POST",
148
- path: `/v1/conversations/${encodeURIComponent(params.conversationId)}/read`,
149
- body: { message_id: params.messageId },
150
- ...(params.signal ? { signal: params.signal } : {}),
151
- });
152
- },
153
- };
154
- return client;
140
+ }
141
+ runWebSocket(options) {
142
+ return runWebSocket(this.baseURL, this.#apiKey, options);
143
+ }
144
+ }
145
+ class ChatMessages {
146
+ transport;
147
+ constructor(transport) {
148
+ this.transport = transport;
149
+ }
150
+ async list(chatID, query = {}, options) {
151
+ const body = await this.transport.request({
152
+ method: "GET",
153
+ path: `/v1/chats/${pathID(chatID)}/messages`,
154
+ query,
155
+ options,
156
+ });
157
+ return new MessagesPage({ data: body.messages, nextCursor: body.next_cursor ?? null }, (cursor) => this.list(chatID, { ...query, cursor }, options));
158
+ }
159
+ send(chatID, body, options) {
160
+ return this.transport.request({
161
+ method: "POST",
162
+ path: `/v1/chats/${pathID(chatID)}/messages`,
163
+ body,
164
+ options,
165
+ ...(body.message.idempotency_key
166
+ ? { idempotencyKey: body.message.idempotency_key }
167
+ : {}),
168
+ });
169
+ }
170
+ }
171
+ class ChatParticipants {
172
+ transport;
173
+ constructor(transport) {
174
+ this.transport = transport;
175
+ }
176
+ add(chatID, body, options) {
177
+ return this.transport.request({
178
+ method: "POST",
179
+ path: `/v1/chats/${pathID(chatID)}/participants`,
180
+ body,
181
+ options,
182
+ });
183
+ }
184
+ remove(chatID, body, options) {
185
+ return this.transport.request({
186
+ method: "DELETE",
187
+ path: `/v1/chats/${pathID(chatID)}/participants`,
188
+ body,
189
+ options,
190
+ });
191
+ }
192
+ }
193
+ export class Chats {
194
+ transport;
195
+ messages;
196
+ participants;
197
+ constructor(transport) {
198
+ this.transport = transport;
199
+ this.messages = new ChatMessages(transport);
200
+ this.participants = new ChatParticipants(transport);
201
+ }
202
+ create(body, options) {
203
+ return this.transport.request({
204
+ method: "POST",
205
+ path: "/v1/chats",
206
+ body,
207
+ options,
208
+ ...(body.message.idempotency_key
209
+ ? { idempotencyKey: body.message.idempotency_key }
210
+ : {}),
211
+ });
212
+ }
213
+ retrieve(chatID, options) {
214
+ return this.transport.request({
215
+ method: "GET",
216
+ path: `/v1/chats/${pathID(chatID)}`,
217
+ options,
218
+ });
219
+ }
220
+ update(chatID, body, options) {
221
+ return this.transport.request({
222
+ method: "PUT",
223
+ path: `/v1/chats/${pathID(chatID)}`,
224
+ body,
225
+ options,
226
+ });
227
+ }
228
+ async listChats(query = {}, options) {
229
+ const body = await this.transport.request({
230
+ method: "GET",
231
+ path: "/v1/chats",
232
+ query,
233
+ options,
234
+ });
235
+ return new ChatsPage({ data: body.chats, nextCursor: body.next_cursor ?? null }, (cursor) => this.listChats({ ...query, cursor }, options));
236
+ }
237
+ leaveChat(chatID, options) {
238
+ return this.transport.request({
239
+ method: "POST",
240
+ path: `/v1/chats/${pathID(chatID)}/leave`,
241
+ options,
242
+ });
243
+ }
244
+ startTyping(chatID, options) {
245
+ return this.transport.request({
246
+ method: "POST",
247
+ path: `/v1/chats/${pathID(chatID)}/typing`,
248
+ options,
249
+ retryable: true,
250
+ });
251
+ }
252
+ stopTyping(chatID, options) {
253
+ return this.transport.request({
254
+ method: "DELETE",
255
+ path: `/v1/chats/${pathID(chatID)}/typing`,
256
+ options,
257
+ retryable: true,
258
+ });
259
+ }
260
+ markAsRead(chatID, options) {
261
+ return this.transport.request({
262
+ method: "POST",
263
+ path: `/v1/chats/${pathID(chatID)}/read`,
264
+ options,
265
+ retryable: true,
266
+ });
267
+ }
268
+ shareContactCard(chatID, options) {
269
+ return this.transport.request({
270
+ method: "POST",
271
+ path: `/v1/chats/${pathID(chatID)}/share_contact_card`,
272
+ options,
273
+ });
274
+ }
275
+ sendVoicememo(chatID, body, options) {
276
+ return this.transport.request({
277
+ method: "POST",
278
+ path: `/v1/chats/${pathID(chatID)}/voicememo`,
279
+ body,
280
+ options,
281
+ });
282
+ }
283
+ }
284
+ export class Messages {
285
+ transport;
286
+ constructor(transport) {
287
+ this.transport = transport;
288
+ }
289
+ create(params, options) {
290
+ const { "Idempotency-Key": headerKey, ...body } = params;
291
+ const idempotencyKey = headerKey ?? body.message.idempotency_key;
292
+ return this.transport.request({
293
+ method: "POST",
294
+ path: "/v1/messages",
295
+ body,
296
+ options,
297
+ ...(idempotencyKey ? { idempotencyKey } : {}),
298
+ });
299
+ }
300
+ retrieve(messageID, options) {
301
+ return this.transport.request({
302
+ method: "GET",
303
+ path: `/v1/messages/${pathID(messageID)}`,
304
+ options,
305
+ });
306
+ }
307
+ addReaction(messageID, body, options) {
308
+ return this.transport.request({
309
+ method: "POST",
310
+ path: `/v1/messages/${pathID(messageID)}/reactions`,
311
+ body,
312
+ options,
313
+ });
314
+ }
315
+ async listMessagesThread(messageID, query = {}, options) {
316
+ const body = await this.transport.request({
317
+ method: "GET",
318
+ path: `/v1/messages/${pathID(messageID)}/thread`,
319
+ query,
320
+ options,
321
+ });
322
+ return new MessagesPage({ data: body.messages, nextCursor: body.next_cursor ?? null }, (cursor) => this.listMessagesThread(messageID, { ...query, cursor }, options));
323
+ }
324
+ }
325
+ export class Attachments {
326
+ transport;
327
+ constructor(transport) {
328
+ this.transport = transport;
329
+ }
330
+ create(body, options) {
331
+ return this.transport.request({
332
+ method: "POST",
333
+ path: "/v1/attachments",
334
+ body,
335
+ options,
336
+ });
337
+ }
338
+ retrieve(attachmentID, options) {
339
+ return this.transport.request({
340
+ method: "GET",
341
+ path: `/v1/attachments/${pathID(attachmentID)}`,
342
+ options,
343
+ });
344
+ }
345
+ delete(attachmentID, options) {
346
+ return this.transport.request({
347
+ method: "DELETE",
348
+ path: `/v1/attachments/${pathID(attachmentID)}`,
349
+ options,
350
+ });
351
+ }
352
+ upload(allocation, data, options) {
353
+ return this.transport.upload(allocation, data, options);
354
+ }
355
+ }
356
+ export class WebhookEvents {
357
+ transport;
358
+ constructor(transport) {
359
+ this.transport = transport;
360
+ }
361
+ list(options) {
362
+ return this.transport.request({
363
+ method: "GET",
364
+ path: "/v1/webhook-events",
365
+ options,
366
+ });
367
+ }
368
+ }
369
+ export class WebhookSubscriptions {
370
+ transport;
371
+ constructor(transport) {
372
+ this.transport = transport;
373
+ }
374
+ create(body, options) {
375
+ return this.transport.request({
376
+ method: "POST",
377
+ path: "/v1/webhook-subscriptions",
378
+ body,
379
+ options,
380
+ });
381
+ }
382
+ retrieve(subscriptionID, options) {
383
+ return this.transport.request({
384
+ method: "GET",
385
+ path: `/v1/webhook-subscriptions/${pathID(subscriptionID)}`,
386
+ options,
387
+ });
388
+ }
389
+ update(subscriptionID, body, options) {
390
+ return this.transport.request({
391
+ method: "PUT",
392
+ path: `/v1/webhook-subscriptions/${pathID(subscriptionID)}`,
393
+ body,
394
+ options,
395
+ });
396
+ }
397
+ list(options) {
398
+ return this.transport.request({
399
+ method: "GET",
400
+ path: "/v1/webhook-subscriptions",
401
+ options,
402
+ });
403
+ }
404
+ delete(subscriptionID, options) {
405
+ return this.transport.request({
406
+ method: "DELETE",
407
+ path: `/v1/webhook-subscriptions/${pathID(subscriptionID)}`,
408
+ options,
409
+ });
410
+ }
411
+ }
412
+ export class ContactCard {
413
+ transport;
414
+ constructor(transport) {
415
+ this.transport = transport;
416
+ }
417
+ create(body, options) {
418
+ return this.transport.request({
419
+ method: "POST",
420
+ path: "/v1/contact_card",
421
+ body,
422
+ options,
423
+ });
424
+ }
425
+ retrieve(query = {}, options) {
426
+ return this.transport.request({
427
+ method: "GET",
428
+ path: "/v1/contact_card",
429
+ query,
430
+ options,
431
+ });
432
+ }
433
+ update(params, options) {
434
+ const { handle, ...body } = params;
435
+ return this.transport.request({
436
+ method: "PATCH",
437
+ path: "/v1/contact_card",
438
+ query: { handle },
439
+ body,
440
+ options,
441
+ });
442
+ }
443
+ }
444
+ export class ContactRequests {
445
+ transport;
446
+ constructor(transport) {
447
+ this.transport = transport;
448
+ }
449
+ create(params, options) {
450
+ const { "Idempotency-Key": idempotencyKey, ...body } = params;
451
+ return this.transport.request({
452
+ method: "POST",
453
+ path: "/v1/contact_requests",
454
+ body,
455
+ options,
456
+ ...(idempotencyKey ? { idempotencyKey } : {}),
457
+ });
458
+ }
459
+ }
460
+ export class BlockedHandles {
461
+ transport;
462
+ constructor(transport) {
463
+ this.transport = transport;
464
+ }
465
+ list(options) {
466
+ return this.transport.request({
467
+ method: "GET",
468
+ path: "/v1/blocked_handles",
469
+ options,
470
+ });
471
+ }
472
+ block(body, options) {
473
+ return this.transport.request({
474
+ method: "POST",
475
+ path: "/v1/blocked_handles",
476
+ body,
477
+ options,
478
+ });
479
+ }
480
+ unblock(body, options) {
481
+ return this.transport.request({
482
+ method: "DELETE",
483
+ path: "/v1/blocked_handles",
484
+ body,
485
+ options,
486
+ });
487
+ }
488
+ }
489
+ export class WebSocket {
490
+ transport;
491
+ constructor(transport) {
492
+ this.transport = transport;
493
+ }
494
+ /**
495
+ * Keeps one outbound WebSocket connection alive. `onEvent` must return
496
+ * only after the event is committed to a durable inbox; the SDK sends the
497
+ * cumulative ACK after that promise resolves. `onFullSync` must return only
498
+ * after a complete REST snapshot is durably applied.
499
+ */
500
+ run(options) {
501
+ return this.transport.runWebSocket(options);
502
+ }
503
+ }
504
+ export class Relay {
505
+ baseURL;
506
+ chats;
507
+ messages;
508
+ attachments;
509
+ webhookEvents;
510
+ webhookSubscriptions;
511
+ contactCard;
512
+ contactRequests;
513
+ blockedHandles;
514
+ websocket;
515
+ webhooks;
516
+ constructor(options) {
517
+ const transport = new Transport(options);
518
+ this.baseURL = transport.baseURL;
519
+ this.chats = new Chats(transport);
520
+ this.messages = new Messages(transport);
521
+ this.attachments = new Attachments(transport);
522
+ this.webhookEvents = new WebhookEvents(transport);
523
+ this.webhookSubscriptions = new WebhookSubscriptions(transport);
524
+ this.contactCard = new ContactCard(transport);
525
+ this.contactRequests = new ContactRequests(transport);
526
+ this.blockedHandles = new BlockedHandles(transport);
527
+ this.websocket = new WebSocket(transport);
528
+ this.webhooks = new Webhooks(options.webhookSecret ?? null);
529
+ }
155
530
  }
531
+ export default Relay;
156
532
  //# sourceMappingURL=client.js.map