@noematicsllc/talk-sdk 0.0.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.
package/dist/index.js ADDED
@@ -0,0 +1,1864 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ ActorType: () => ActorType,
24
+ BreakoutRoomMode: () => BreakoutRoomMode,
25
+ CallResource: () => CallResource,
26
+ ChatResource: () => ChatResource,
27
+ ConversationType: () => ConversationType,
28
+ HttpClient: () => HttpClient,
29
+ HttpClientError: () => HttpClientError,
30
+ InCallFlag: () => InCallFlag,
31
+ ListableScope: () => ListableScope,
32
+ LobbyState: () => LobbyState,
33
+ MessageType: () => MessageType,
34
+ NotificationLevel: () => NotificationLevel,
35
+ ParticipantResource: () => ParticipantResource,
36
+ ParticipantType: () => ParticipantType,
37
+ Permission: () => Permission,
38
+ PollResource: () => PollResource,
39
+ PollResultMode: () => PollResultMode,
40
+ ReactionResource: () => ReactionResource,
41
+ ReadOnlyState: () => ReadOnlyState,
42
+ RecordingStatus: () => RecordingStatus,
43
+ Room: () => Room,
44
+ RoomResource: () => RoomResource,
45
+ RoomsAccessor: () => RoomsAccessor,
46
+ SIPState: () => SIPState,
47
+ SharedObjectType: () => SharedObjectType,
48
+ TalkClient: () => TalkClient,
49
+ normalizeMessage: () => normalizeMessage,
50
+ normalizeMessageWithParent: () => normalizeMessageWithParent,
51
+ normalizeMessages: () => normalizeMessages,
52
+ normalizeParticipant: () => normalizeParticipant,
53
+ normalizeParticipants: () => normalizeParticipants,
54
+ normalizeRoom: () => normalizeRoom,
55
+ normalizeRooms: () => normalizeRooms
56
+ });
57
+ module.exports = __toCommonJS(index_exports);
58
+
59
+ // src/transport/http-client.ts
60
+ var HttpClientError = class extends Error {
61
+ constructor(message, status, ocsStatus, ocsMessage) {
62
+ super(message);
63
+ this.status = status;
64
+ this.ocsStatus = ocsStatus;
65
+ this.ocsMessage = ocsMessage;
66
+ this.name = "HttpClientError";
67
+ }
68
+ };
69
+ var HttpClient = class {
70
+ baseUrl;
71
+ authHeader;
72
+ fetchImpl;
73
+ constructor(config) {
74
+ this.baseUrl = config.host.replace(/\/$/, "");
75
+ const credentials = `${config.username}:${config.password}`;
76
+ const encoded = typeof btoa === "function" ? btoa(credentials) : Buffer.from(credentials).toString("base64");
77
+ this.authHeader = `Basic ${encoded}`;
78
+ const globalFetch = globalThis.fetch;
79
+ this.fetchImpl = config.fetch ?? (globalFetch ? globalFetch.bind(globalThis) : void 0);
80
+ if (!this.fetchImpl) {
81
+ throw new Error("Fetch API is not available. Please provide a fetch implementation.");
82
+ }
83
+ }
84
+ /**
85
+ * Build the full URL with query parameters
86
+ */
87
+ buildUrl(path, params) {
88
+ const url = new URL(path, this.baseUrl);
89
+ if (params) {
90
+ Object.entries(params).forEach(([key, value]) => {
91
+ if (value !== void 0) {
92
+ url.searchParams.set(key, String(value));
93
+ }
94
+ });
95
+ }
96
+ return url.toString();
97
+ }
98
+ /**
99
+ * Extract Nextcloud-specific headers from response
100
+ */
101
+ extractMeta(headers) {
102
+ const meta = {};
103
+ const talkHash = headers.get("X-Nextcloud-Talk-Hash");
104
+ if (talkHash) meta.talkHash = talkHash;
105
+ const modifiedBefore = headers.get("X-Nextcloud-Talk-Modified-Before");
106
+ if (modifiedBefore) meta.modifiedBefore = parseInt(modifiedBefore, 10);
107
+ const chatLastGiven = headers.get("X-Chat-Last-Given");
108
+ if (chatLastGiven) meta.chatLastGiven = parseInt(chatLastGiven, 10);
109
+ const chatLastCommonRead = headers.get("X-Chat-Last-Common-Read");
110
+ if (chatLastCommonRead) meta.chatLastCommonRead = parseInt(chatLastCommonRead, 10);
111
+ const federationInvites = headers.get("X-Nextcloud-Talk-Federation-Invites");
112
+ if (federationInvites) meta.federationInvites = parseInt(federationInvites, 10);
113
+ return meta;
114
+ }
115
+ /**
116
+ * Make an HTTP request to the Nextcloud OCS API
117
+ *
118
+ * @param path - API path (e.g., '/ocs/v2.php/apps/spreed/api/v4/room')
119
+ * @param options - Request options
120
+ * @returns Promise resolving to the unwrapped OCS data
121
+ *
122
+ * @throws {HttpClientError} When the request fails or returns an error status
123
+ *
124
+ * @remarks
125
+ * OCS API returns status codes in the response body:
126
+ * - 100: Success (OCS v1)
127
+ * - 200: Success (OCS v2)
128
+ * - Other codes indicate errors specific to the endpoint
129
+ */
130
+ async request(path, options = {}) {
131
+ const {
132
+ method = "GET",
133
+ body,
134
+ params,
135
+ headers: customHeaders = {},
136
+ timeout = 3e4
137
+ } = options;
138
+ const url = this.buildUrl(path, params);
139
+ const headers = {
140
+ "OCS-APIRequest": "true",
141
+ "Accept": "application/json",
142
+ "Authorization": this.authHeader,
143
+ ...customHeaders
144
+ };
145
+ if (body !== void 0) {
146
+ headers["Content-Type"] = "application/json";
147
+ }
148
+ const controller = new AbortController();
149
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
150
+ try {
151
+ const response = await this.fetchImpl(url, {
152
+ method,
153
+ headers,
154
+ body: body !== void 0 ? JSON.stringify(body) : void 0,
155
+ signal: controller.signal
156
+ });
157
+ if (response.status === 304) {
158
+ return {
159
+ data: [],
160
+ status: response.status,
161
+ meta: this.extractMeta(response.headers),
162
+ headers: response.headers
163
+ };
164
+ }
165
+ if (!response.ok) {
166
+ let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
167
+ let ocsStatus;
168
+ let ocsMessage;
169
+ try {
170
+ const errorBody = await response.json();
171
+ ocsStatus = errorBody.ocs?.meta?.statuscode;
172
+ ocsMessage = errorBody.ocs?.meta?.message;
173
+ if (ocsMessage) {
174
+ errorMessage = `${errorMessage} - ${ocsMessage}`;
175
+ }
176
+ } catch {
177
+ }
178
+ throw new HttpClientError(errorMessage, response.status, ocsStatus, ocsMessage);
179
+ }
180
+ const json = await response.json();
181
+ if (!json.ocs) {
182
+ throw new HttpClientError("Invalid OCS response: missing ocs envelope", response.status);
183
+ }
184
+ return {
185
+ data: json.ocs.data,
186
+ status: response.status,
187
+ meta: this.extractMeta(response.headers),
188
+ headers: response.headers
189
+ };
190
+ } catch (error) {
191
+ if (error instanceof HttpClientError) {
192
+ throw error;
193
+ }
194
+ if (error instanceof Error && error.name === "AbortError") {
195
+ throw new HttpClientError("Request timeout", 408);
196
+ }
197
+ throw new HttpClientError(
198
+ error instanceof Error ? error.message : "Unknown error",
199
+ 0
200
+ );
201
+ } finally {
202
+ clearTimeout(timeoutId);
203
+ }
204
+ }
205
+ /** GET request helper */
206
+ async get(path, params) {
207
+ return this.request(path, { method: "GET", params });
208
+ }
209
+ /** POST request helper */
210
+ async post(path, body, params) {
211
+ return this.request(path, { method: "POST", body, params });
212
+ }
213
+ /** PUT request helper */
214
+ async put(path, body, params) {
215
+ return this.request(path, { method: "PUT", body, params });
216
+ }
217
+ /** DELETE request helper */
218
+ async delete(path, params) {
219
+ return this.request(path, { method: "DELETE", params });
220
+ }
221
+ /** Get the base URL for this client */
222
+ get host() {
223
+ return this.baseUrl;
224
+ }
225
+ };
226
+
227
+ // src/normalization/room-mapper.ts
228
+ function normalizeRoom(raw) {
229
+ return {
230
+ // Identifiers
231
+ id: raw.id,
232
+ token: raw.token,
233
+ // Basic info
234
+ type: raw.type,
235
+ name: raw.name,
236
+ displayName: raw.displayName,
237
+ description: raw.description,
238
+ // Current user context
239
+ actorType: raw.actorType,
240
+ actorId: raw.actorId,
241
+ attendeeId: raw.attendeeId,
242
+ participantType: raw.participantType,
243
+ permissions: raw.permissions,
244
+ attendeePermissions: raw.attendeePermissions,
245
+ // Room state
246
+ hasPassword: raw.hasPassword,
247
+ hasCall: raw.hasCall,
248
+ callFlag: raw.callFlag,
249
+ callStartTime: raw.callStartTime,
250
+ callRecording: raw.callRecording,
251
+ // Settings
252
+ readOnly: raw.readOnly,
253
+ listable: raw.listable,
254
+ lobbyState: raw.lobbyState,
255
+ lobbyTimer: raw.lobbyTimer,
256
+ sipEnabled: raw.sipEnabled,
257
+ mentionPermissions: raw.mentionPermissions,
258
+ messageExpiration: raw.messageExpiration,
259
+ recordingConsent: raw.recordingConsent,
260
+ // Chat state
261
+ lastActivity: raw.lastActivity,
262
+ lastReadMessage: raw.lastReadMessage,
263
+ lastCommonReadMessage: raw.lastCommonReadMessage,
264
+ unreadMessages: raw.unreadMessages,
265
+ unreadMention: raw.unreadMention,
266
+ unreadMentionDirect: raw.unreadMentionDirect,
267
+ // Capabilities
268
+ canStartCall: raw.canStartCall,
269
+ canLeaveConversation: raw.canLeaveConversation,
270
+ canDeleteConversation: raw.canDeleteConversation,
271
+ canEnableSIP: raw.canEnableSIP,
272
+ // Flags
273
+ isFavorite: raw.isFavorite,
274
+ isArchived: raw.isArchived,
275
+ isImportant: raw.isImportant,
276
+ isSensitive: raw.isSensitive,
277
+ // Optional status
278
+ status: raw.status,
279
+ statusIcon: raw.statusIcon,
280
+ statusMessage: raw.statusMessage,
281
+ statusClearAt: raw.statusClearAt,
282
+ // Federation
283
+ remoteServer: raw.remoteServer,
284
+ remoteToken: raw.remoteToken
285
+ };
286
+ }
287
+ function normalizeRooms(rawRooms) {
288
+ return rawRooms.map(normalizeRoom);
289
+ }
290
+
291
+ // src/normalization/message-mapper.ts
292
+ function isDeletedRef(parent) {
293
+ return "deleted" in parent && parent.deleted === true;
294
+ }
295
+ function normalizeMessage(raw) {
296
+ return {
297
+ id: raw.id,
298
+ token: raw.token,
299
+ actorType: raw.actorType,
300
+ actorId: raw.actorId,
301
+ actorDisplayName: raw.actorDisplayName,
302
+ timestamp: raw.timestamp,
303
+ message: raw.message,
304
+ messageType: raw.messageType,
305
+ systemMessage: raw.systemMessage,
306
+ messageParameters: raw.messageParameters,
307
+ // Features
308
+ isReplyable: raw.isReplyable,
309
+ markdown: raw.markdown,
310
+ referenceId: raw.referenceId,
311
+ expirationTimestamp: raw.expirationTimestamp,
312
+ // Reactions
313
+ reactions: raw.reactions,
314
+ reactionsSelf: raw.reactionsSelf ?? [],
315
+ // Editing
316
+ lastEditActorType: raw.lastEditActorType,
317
+ lastEditActorId: raw.lastEditActorId,
318
+ lastEditActorDisplayName: raw.lastEditActorDisplayName,
319
+ lastEditTimestamp: raw.lastEditTimestamp,
320
+ // Threads
321
+ threadId: raw.threadId,
322
+ isThread: raw.isThread ?? false,
323
+ threadTitle: raw.threadTitle,
324
+ threadReplies: raw.threadReplies,
325
+ // Metadata
326
+ metaData: raw.metaData
327
+ };
328
+ }
329
+ function normalizeMessageWithParent(raw) {
330
+ const normalized = normalizeMessage(raw);
331
+ if (raw.parent) {
332
+ if (isDeletedRef(raw.parent)) {
333
+ normalized.parent = { id: raw.parent.id, deleted: true };
334
+ } else {
335
+ normalized.parent = normalizeMessage(raw.parent);
336
+ }
337
+ }
338
+ return normalized;
339
+ }
340
+ function normalizeMessages(rawMessages) {
341
+ return rawMessages.map(normalizeMessageWithParent);
342
+ }
343
+
344
+ // src/normalization/participant-mapper.ts
345
+ function normalizeParticipant(raw) {
346
+ return {
347
+ actorType: raw.actorType,
348
+ actorId: raw.actorId,
349
+ displayName: raw.displayName,
350
+ attendeeId: raw.attendeeId,
351
+ participantType: raw.participantType,
352
+ permissions: raw.permissions,
353
+ attendeePermissions: raw.attendeePermissions,
354
+ attendeePin: raw.attendeePin,
355
+ roomToken: raw.roomToken,
356
+ sessionIds: raw.sessionIds,
357
+ inCall: raw.inCall,
358
+ lastPing: raw.lastPing,
359
+ // Status
360
+ status: raw.status,
361
+ statusIcon: raw.statusIcon,
362
+ statusMessage: raw.statusMessage,
363
+ statusClearAt: raw.statusClearAt,
364
+ // Phone
365
+ phoneNumber: raw.phoneNumber,
366
+ callId: raw.callId,
367
+ // Computed helpers (based on InCallFlag enum values)
368
+ isInCall: (raw.inCall & 1) !== 0,
369
+ // IN_CALL = 1
370
+ hasAudio: (raw.inCall & 2) !== 0,
371
+ // WITH_AUDIO = 2
372
+ hasVideo: (raw.inCall & 4) !== 0,
373
+ // WITH_VIDEO = 4
374
+ isOnPhone: (raw.inCall & 8) !== 0
375
+ // WITH_PHONE = 8
376
+ };
377
+ }
378
+ function normalizeParticipants(rawParticipants) {
379
+ return rawParticipants.map(normalizeParticipant);
380
+ }
381
+
382
+ // src/resources/room-resource.ts
383
+ var BASE_PATH = "/ocs/v2.php/apps/spreed/api/v4/room";
384
+ var RoomResource = class {
385
+ constructor(http) {
386
+ this.http = http;
387
+ }
388
+ /**
389
+ * List all conversations the current user is part of
390
+ *
391
+ * @param options - List options (includeStatus, modifiedSince, etc.)
392
+ * @returns Array of normalized room objects
393
+ *
394
+ * @remarks
395
+ * OCS Status Codes:
396
+ * - 200: Success
397
+ */
398
+ async list(options = {}) {
399
+ const response = await this.http.get(BASE_PATH, {
400
+ noStatusUpdate: options.noStatusUpdate ? 1 : void 0,
401
+ includeStatus: options.includeStatus,
402
+ modifiedSince: options.modifiedSince,
403
+ includeLastMessage: options.includeLastMessage
404
+ });
405
+ return normalizeRooms(response.data);
406
+ }
407
+ /**
408
+ * Get a single room by token
409
+ *
410
+ * @param token - Room token
411
+ * @returns Normalized room object
412
+ *
413
+ * @remarks
414
+ * OCS Status Codes:
415
+ * - 200: Success
416
+ * - 401: Unauthorized
417
+ * - 404: Room not found
418
+ */
419
+ async get(token) {
420
+ const response = await this.http.get(`${BASE_PATH}/${token}`);
421
+ return normalizeRoom(response.data);
422
+ }
423
+ /**
424
+ * Create a new room
425
+ *
426
+ * @param options - Room creation options
427
+ * @returns Created room object
428
+ *
429
+ * @remarks
430
+ * OCS Status Codes:
431
+ * - 200: Existing room returned (for 1-1 conversations)
432
+ * - 201: Room created
433
+ * - 202: Room created with invalid invitations
434
+ */
435
+ async create(options) {
436
+ const response = await this.http.post(BASE_PATH, options);
437
+ return normalizeRoom(response.data);
438
+ }
439
+ /**
440
+ * Update room name
441
+ *
442
+ * @param token - Room token
443
+ * @param roomName - New room name
444
+ *
445
+ * @remarks
446
+ * Requires moderator permissions.
447
+ */
448
+ async rename(token, roomName) {
449
+ await this.http.put(`${BASE_PATH}/${token}`, { roomName });
450
+ }
451
+ /**
452
+ * Update room description
453
+ *
454
+ * @param token - Room token
455
+ * @param description - New description (max 2000 chars)
456
+ *
457
+ * @remarks
458
+ * Requires moderator permissions.
459
+ */
460
+ async setDescription(token, description) {
461
+ await this.http.put(`${BASE_PATH}/${token}/description`, { description });
462
+ }
463
+ /**
464
+ * Delete a room
465
+ *
466
+ * @param token - Room token
467
+ *
468
+ * @remarks
469
+ * Requires moderator permissions.
470
+ */
471
+ async delete(token) {
472
+ await this.http.delete(`${BASE_PATH}/${token}`);
473
+ }
474
+ /**
475
+ * Set room password
476
+ *
477
+ * @param token - Room token
478
+ * @param password - Room password (empty string to remove)
479
+ *
480
+ * @remarks
481
+ * Requires moderator permissions. Only for public rooms.
482
+ */
483
+ async setPassword(token, password) {
484
+ await this.http.put(`${BASE_PATH}/${token}/password`, { password });
485
+ }
486
+ /**
487
+ * Make room public (allow guests)
488
+ *
489
+ * @param token - Room token
490
+ *
491
+ * @remarks
492
+ * Requires logged-in moderator.
493
+ */
494
+ async makePublic(token) {
495
+ await this.http.post(`${BASE_PATH}/${token}/public`);
496
+ }
497
+ /**
498
+ * Make room private
499
+ *
500
+ * @param token - Room token
501
+ *
502
+ * @remarks
503
+ * Requires logged-in moderator.
504
+ */
505
+ async makePrivate(token) {
506
+ await this.http.delete(`${BASE_PATH}/${token}/public`);
507
+ }
508
+ /**
509
+ * Set read-only state
510
+ *
511
+ * @param token - Room token
512
+ * @param state - Read-only state (0 = read-write, 1 = read-only)
513
+ */
514
+ async setReadOnly(token, state) {
515
+ await this.http.put(`${BASE_PATH}/${token}/read-only`, { state });
516
+ }
517
+ /**
518
+ * Set listable scope
519
+ *
520
+ * @param token - Room token
521
+ * @param scope - Listable scope (0 = none, 1 = users, 2 = everyone)
522
+ */
523
+ async setListable(token, scope) {
524
+ await this.http.put(`${BASE_PATH}/${token}/listable`, { scope });
525
+ }
526
+ /**
527
+ * Add room to favorites
528
+ *
529
+ * @param token - Room token
530
+ */
531
+ async addToFavorites(token) {
532
+ await this.http.post(`${BASE_PATH}/${token}/favorite`);
533
+ }
534
+ /**
535
+ * Remove room from favorites
536
+ *
537
+ * @param token - Room token
538
+ */
539
+ async removeFromFavorites(token) {
540
+ await this.http.delete(`${BASE_PATH}/${token}/favorite`);
541
+ }
542
+ /**
543
+ * Archive room
544
+ *
545
+ * @param token - Room token
546
+ */
547
+ async archive(token) {
548
+ await this.http.post(`${BASE_PATH}/${token}/archive`);
549
+ }
550
+ /**
551
+ * Unarchive room
552
+ *
553
+ * @param token - Room token
554
+ */
555
+ async unarchive(token) {
556
+ await this.http.delete(`${BASE_PATH}/${token}/archive`);
557
+ }
558
+ /**
559
+ * Mark room as important (notifications on DND)
560
+ *
561
+ * @param token - Room token
562
+ */
563
+ async markImportant(token) {
564
+ await this.http.post(`${BASE_PATH}/${token}/important`);
565
+ }
566
+ /**
567
+ * Unmark room as important
568
+ *
569
+ * @param token - Room token
570
+ */
571
+ async unmarkImportant(token) {
572
+ await this.http.delete(`${BASE_PATH}/${token}/important`);
573
+ }
574
+ /**
575
+ * Mark room as sensitive (hide preview)
576
+ *
577
+ * @param token - Room token
578
+ */
579
+ async markSensitive(token) {
580
+ await this.http.post(`${BASE_PATH}/${token}/sensitive`);
581
+ }
582
+ /**
583
+ * Unmark room as sensitive
584
+ *
585
+ * @param token - Room token
586
+ */
587
+ async unmarkSensitive(token) {
588
+ await this.http.delete(`${BASE_PATH}/${token}/sensitive`);
589
+ }
590
+ /**
591
+ * Set notification level
592
+ *
593
+ * @param token - Room token
594
+ * @param level - Notification level (0-3)
595
+ */
596
+ async setNotificationLevel(token, level) {
597
+ await this.http.post(`${BASE_PATH}/${token}/notify`, { level });
598
+ }
599
+ /**
600
+ * Set call notification setting
601
+ *
602
+ * @param token - Room token
603
+ * @param level - Call notification level (0 = off, 1 = on)
604
+ */
605
+ async setCallNotifications(token, level) {
606
+ await this.http.post(`${BASE_PATH}/${token}/notify-calls`, { level });
607
+ }
608
+ /**
609
+ * Configure lobby
610
+ *
611
+ * @param token - Room token
612
+ * @param state - Lobby state (0 = disabled, 1 = enabled)
613
+ * @param timer - Optional Unix timestamp when lobby opens
614
+ */
615
+ async setLobby(token, state, timer) {
616
+ await this.http.put(`${BASE_PATH}/${token}/webinar/lobby`, { state, timer });
617
+ }
618
+ /**
619
+ * Set default or call permissions for the room
620
+ *
621
+ * @param token - Room token
622
+ * @param mode - Permission mode ('default' or 'call')
623
+ * @param permissions - Permission bitmask
624
+ */
625
+ async setPermissions(token, mode, permissions) {
626
+ await this.http.put(`${BASE_PATH}/${token}/permissions/${mode}`, { permissions });
627
+ }
628
+ /**
629
+ * Set message expiration time
630
+ *
631
+ * @param token - Room token
632
+ * @param seconds - Expiration time in seconds (0 = never)
633
+ */
634
+ async setMessageExpiration(token, seconds) {
635
+ await this.http.post(`${BASE_PATH}/${token}/message-expiration`, { seconds });
636
+ }
637
+ /**
638
+ * Get raw response with metadata headers (for advanced use)
639
+ *
640
+ * @param token - Room token
641
+ * @returns Full HTTP response with data and metadata
642
+ */
643
+ async getRaw(token) {
644
+ return this.http.get(`${BASE_PATH}/${token}`);
645
+ }
646
+ };
647
+
648
+ // src/resources/chat-resource.ts
649
+ var BASE_PATH2 = "/ocs/v2.php/apps/spreed/api/v1/chat";
650
+ var ChatResource = class {
651
+ constructor(http) {
652
+ this.http = http;
653
+ }
654
+ /**
655
+ * Receive messages from a room
656
+ *
657
+ * @param token - Room token
658
+ * @param options - Receive options (lookIntoFuture, limit, lastKnownMessageId, etc.)
659
+ * @returns Array of normalized messages
660
+ *
661
+ * @remarks
662
+ * OCS Status Codes:
663
+ * - 200: Messages returned
664
+ * - 304: No new messages (long-poll timeout)
665
+ */
666
+ async receiveMessages(token, options) {
667
+ const response = await this.http.get(
668
+ `${BASE_PATH2}/${token}`,
669
+ {
670
+ lookIntoFuture: options.lookIntoFuture,
671
+ limit: options.limit,
672
+ lastKnownMessageId: options.lastKnownMessageId,
673
+ timeout: options.timeout,
674
+ setReadMarker: options.setReadMarker === false ? 0 : 1,
675
+ includeLastKnown: options.includeLastKnown ? 1 : 0,
676
+ markNotificationsAsRead: options.markNotificationsAsRead === false ? 0 : 1,
677
+ threadId: options.threadId
678
+ }
679
+ );
680
+ return normalizeMessages(response.data);
681
+ }
682
+ /**
683
+ * Get message history (past messages)
684
+ *
685
+ * @param token - Room token
686
+ * @param options - Optional limit and lastKnownMessageId for pagination
687
+ * @returns Array of normalized messages
688
+ */
689
+ async getHistory(token, options = {}) {
690
+ return this.receiveMessages(token, {
691
+ lookIntoFuture: 0,
692
+ ...options
693
+ });
694
+ }
695
+ /**
696
+ * Poll for new messages (long-polling)
697
+ *
698
+ * This implements the spec's efficient update pattern for receiving
699
+ * new messages. The server holds the connection for up to `timeout` seconds.
700
+ *
701
+ * @param token - Room token
702
+ * @param options - Poll options with required lastKnownMessageId
703
+ * @returns Poll result with messages and metadata for next poll
704
+ *
705
+ * @example
706
+ * ```ts
707
+ * let lastKnownMessageId = 0;
708
+ *
709
+ * while (polling) {
710
+ * const result = await chat.pollMessages(token, { lastKnownMessageId });
711
+ * for (const message of result.messages) {
712
+ * console.log(message.message);
713
+ * }
714
+ * if (result.lastKnownMessageId) {
715
+ * lastKnownMessageId = result.lastKnownMessageId;
716
+ * }
717
+ * }
718
+ * ```
719
+ */
720
+ async pollMessages(token, options) {
721
+ const response = await this.http.request(
722
+ `${BASE_PATH2}/${token}`,
723
+ {
724
+ method: "GET",
725
+ params: {
726
+ lookIntoFuture: 1,
727
+ limit: options.limit ?? 100,
728
+ lastKnownMessageId: options.lastKnownMessageId,
729
+ timeout: options.timeout ?? 30,
730
+ threadId: options.threadId
731
+ },
732
+ timeout: ((options.timeout ?? 30) + 5) * 1e3
733
+ // Add buffer to server timeout
734
+ }
735
+ );
736
+ return {
737
+ messages: normalizeMessages(response.data),
738
+ lastKnownMessageId: response.meta.chatLastGiven,
739
+ lastCommonRead: response.meta.chatLastCommonRead
740
+ };
741
+ }
742
+ /**
743
+ * Send a message to a room
744
+ *
745
+ * @param token - Room token
746
+ * @param options - Message options
747
+ * @returns Sent message
748
+ *
749
+ * @remarks
750
+ * OCS Status Codes:
751
+ * - 201: Message sent
752
+ * - 400: Sending not possible
753
+ * - 404: Actor not found
754
+ * - 413: Message too long (max 32000 chars)
755
+ * - 429: Mention rate limit exceeded
756
+ */
757
+ async sendMessage(token, options) {
758
+ const response = await this.http.post(
759
+ `${BASE_PATH2}/${token}`,
760
+ {
761
+ message: options.message,
762
+ actorDisplayName: options.actorDisplayName,
763
+ referenceId: options.referenceId,
764
+ replyTo: options.replyTo,
765
+ silent: options.silent,
766
+ threadId: options.threadId,
767
+ threadTitle: options.threadTitle
768
+ }
769
+ );
770
+ return normalizeMessageWithParent(response.data);
771
+ }
772
+ /**
773
+ * Edit a message
774
+ *
775
+ * @param token - Room token
776
+ * @param messageId - Message ID to edit
777
+ * @param message - New message content
778
+ * @returns Updated message
779
+ */
780
+ async editMessage(token, messageId, message) {
781
+ const response = await this.http.put(
782
+ `${BASE_PATH2}/${token}/${messageId}`,
783
+ { message }
784
+ );
785
+ return normalizeMessageWithParent(response.data);
786
+ }
787
+ /**
788
+ * Delete a message
789
+ *
790
+ * @param token - Room token
791
+ * @param messageId - Message ID to delete
792
+ * @returns Deleted message placeholder
793
+ */
794
+ async deleteMessage(token, messageId) {
795
+ const response = await this.http.delete(
796
+ `${BASE_PATH2}/${token}/${messageId}`
797
+ );
798
+ return normalizeMessageWithParent(response.data);
799
+ }
800
+ /**
801
+ * Get message context (surrounding messages)
802
+ *
803
+ * @param token - Room token
804
+ * @param messageId - Message ID to get context for
805
+ * @param options - Optional limit and threadId
806
+ * @returns Array of messages around the target message
807
+ */
808
+ async getContext(token, messageId, options = {}) {
809
+ const response = await this.http.get(
810
+ `${BASE_PATH2}/${token}/${messageId}/context`,
811
+ {
812
+ limit: options.limit,
813
+ threadId: options.threadId
814
+ }
815
+ );
816
+ return normalizeMessages(response.data);
817
+ }
818
+ /**
819
+ * Share a rich object (file, deck card, etc.)
820
+ *
821
+ * @param token - Room token
822
+ * @param options - Share options
823
+ * @returns Shared message
824
+ */
825
+ async shareObject(token, options) {
826
+ const response = await this.http.post(
827
+ `${BASE_PATH2}/${token}/share`,
828
+ {
829
+ objectType: options.objectType,
830
+ objectId: options.objectId,
831
+ metaData: options.metaData,
832
+ referenceId: options.referenceId,
833
+ threadId: options.threadId
834
+ }
835
+ );
836
+ return normalizeMessageWithParent(response.data);
837
+ }
838
+ /**
839
+ * Clear chat history
840
+ *
841
+ * @param token - Room token
842
+ *
843
+ * @remarks
844
+ * Requires moderator permissions.
845
+ */
846
+ async clearHistory(token) {
847
+ await this.http.delete(`${BASE_PATH2}/${token}`);
848
+ }
849
+ /**
850
+ * Set read marker to a specific message
851
+ *
852
+ * @param token - Room token
853
+ * @param lastReadMessage - Message ID to mark as last read
854
+ */
855
+ async setReadMarker(token, lastReadMessage) {
856
+ await this.http.post(`${BASE_PATH2}/${token}/read`, { lastReadMessage });
857
+ }
858
+ /**
859
+ * Mark chat as unread
860
+ *
861
+ * @param token - Room token
862
+ */
863
+ async markUnread(token) {
864
+ await this.http.delete(`${BASE_PATH2}/${token}/read`);
865
+ }
866
+ /**
867
+ * Search for mention suggestions
868
+ *
869
+ * @param token - Room token
870
+ * @param search - Search query
871
+ * @param options - Optional limit and includeStatus
872
+ * @returns Array of mention suggestions
873
+ */
874
+ async searchMentions(token, search, options = {}) {
875
+ const response = await this.http.get(
876
+ `${BASE_PATH2}/${token}/mentions`,
877
+ {
878
+ search,
879
+ limit: options.limit ?? 20,
880
+ includeStatus: options.includeStatus
881
+ }
882
+ );
883
+ return response.data;
884
+ }
885
+ /**
886
+ * Pin a message
887
+ *
888
+ * @param token - Room token
889
+ * @param messageId - Message ID to pin
890
+ * @param pinUntil - Optional Unix timestamp when pin expires
891
+ *
892
+ * @remarks
893
+ * Requires moderator permissions.
894
+ */
895
+ async pinMessage(token, messageId, pinUntil) {
896
+ await this.http.post(`${BASE_PATH2}/${token}/${messageId}/pin`, { pinUntil });
897
+ }
898
+ /**
899
+ * Unpin a message
900
+ *
901
+ * @param token - Room token
902
+ * @param messageId - Message ID to unpin
903
+ *
904
+ * @remarks
905
+ * Requires moderator permissions.
906
+ */
907
+ async unpinMessage(token, messageId) {
908
+ await this.http.delete(`${BASE_PATH2}/${token}/${messageId}/pin`);
909
+ }
910
+ /**
911
+ * Hide a pinned message for the current user only
912
+ *
913
+ * @param token - Room token
914
+ * @param messageId - Message ID to hide
915
+ */
916
+ async hidePinnedMessage(token, messageId) {
917
+ await this.http.delete(`${BASE_PATH2}/${token}/${messageId}/pin/self`);
918
+ }
919
+ /**
920
+ * Set a reminder for a message
921
+ *
922
+ * @param token - Room token
923
+ * @param messageId - Message ID
924
+ * @param timestamp - Unix timestamp for reminder
925
+ */
926
+ async setReminder(token, messageId, timestamp) {
927
+ await this.http.post(`${BASE_PATH2}/${token}/${messageId}/reminder`, { timestamp });
928
+ }
929
+ /**
930
+ * Delete a message reminder
931
+ *
932
+ * @param token - Room token
933
+ * @param messageId - Message ID
934
+ */
935
+ async deleteReminder(token, messageId) {
936
+ await this.http.delete(`${BASE_PATH2}/${token}/${messageId}/reminder`);
937
+ }
938
+ };
939
+
940
+ // src/resources/participant-resource.ts
941
+ var BASE_PATH3 = "/ocs/v2.php/apps/spreed/api/v4/room";
942
+ var ParticipantResource = class {
943
+ constructor(http) {
944
+ this.http = http;
945
+ }
946
+ /**
947
+ * Get list of participants in a room
948
+ *
949
+ * @param token - Room token
950
+ * @param includeStatus - Include user status information
951
+ * @returns Array of normalized participants
952
+ */
953
+ async list(token, includeStatus = false) {
954
+ const response = await this.http.get(
955
+ `${BASE_PATH3}/${token}/participants`,
956
+ { includeStatus }
957
+ );
958
+ return normalizeParticipants(response.data);
959
+ }
960
+ /**
961
+ * Add a participant to a room
962
+ *
963
+ * @param token - Room token
964
+ * @param options - Participant options
965
+ *
966
+ * @remarks
967
+ * Requires logged-in moderator.
968
+ */
969
+ async add(token, options) {
970
+ await this.http.post(`${BASE_PATH3}/${token}/participants`, {
971
+ newParticipant: options.newParticipant,
972
+ source: options.source
973
+ });
974
+ }
975
+ /**
976
+ * Remove a participant from a room
977
+ *
978
+ * @param token - Room token
979
+ * @param attendeeId - Attendee ID to remove
980
+ *
981
+ * @remarks
982
+ * Requires moderator permissions.
983
+ */
984
+ async remove(token, attendeeId) {
985
+ await this.http.delete(`${BASE_PATH3}/${token}/attendees`, { attendeeId });
986
+ }
987
+ /**
988
+ * Remove self from a room
989
+ *
990
+ * @param token - Room token
991
+ */
992
+ async removeSelf(token) {
993
+ await this.http.delete(`${BASE_PATH3}/${token}/participants/self`);
994
+ }
995
+ /**
996
+ * Join a room (create session)
997
+ *
998
+ * @param token - Room token
999
+ * @param options - Join options
1000
+ * @returns Room data after joining
1001
+ *
1002
+ * @remarks
1003
+ * OCS Status Codes:
1004
+ * - 200: Joined successfully
1005
+ * - 409: Conflict - already joined on another device
1006
+ *
1007
+ * On 409, the response contains session conflict info.
1008
+ */
1009
+ async join(token, options = {}) {
1010
+ const response = await this.http.post(
1011
+ `${BASE_PATH3}/${token}/participants/active`,
1012
+ {
1013
+ password: options.password,
1014
+ force: options.force
1015
+ }
1016
+ );
1017
+ return normalizeRoom(response.data);
1018
+ }
1019
+ /**
1020
+ * Leave a room (end session)
1021
+ *
1022
+ * @param token - Room token
1023
+ */
1024
+ async leave(token) {
1025
+ await this.http.delete(`${BASE_PATH3}/${token}/participants/active`);
1026
+ }
1027
+ /**
1028
+ * Set session state (active/inactive)
1029
+ *
1030
+ * @param token - Room token
1031
+ * @param state - 0 = inactive, 1 = active
1032
+ */
1033
+ async setSessionState(token, state) {
1034
+ await this.http.put(`${BASE_PATH3}/${token}/participants/state`, { state });
1035
+ }
1036
+ /**
1037
+ * Promote a participant to moderator
1038
+ *
1039
+ * @param token - Room token
1040
+ * @param attendeeId - Attendee ID to promote
1041
+ */
1042
+ async promoteModerator(token, attendeeId) {
1043
+ await this.http.post(`${BASE_PATH3}/${token}/moderators`, { attendeeId });
1044
+ }
1045
+ /**
1046
+ * Demote a moderator to regular participant
1047
+ *
1048
+ * @param token - Room token
1049
+ * @param attendeeId - Attendee ID to demote
1050
+ */
1051
+ async demoteModerator(token, attendeeId) {
1052
+ await this.http.delete(`${BASE_PATH3}/${token}/moderators`, { attendeeId });
1053
+ }
1054
+ /**
1055
+ * Set permissions for an attendee
1056
+ *
1057
+ * @param token - Room token
1058
+ * @param options - Permission options
1059
+ */
1060
+ async setPermissions(token, options) {
1061
+ await this.http.put(`${BASE_PATH3}/${token}/attendees/permissions`, {
1062
+ attendeeId: options.attendeeId,
1063
+ method: options.method,
1064
+ permissions: options.permissions
1065
+ });
1066
+ }
1067
+ /**
1068
+ * Resend invitations to pending participants
1069
+ *
1070
+ * @param token - Room token
1071
+ * @param attendeeId - Optional specific attendee, or all if omitted
1072
+ */
1073
+ async resendInvitations(token, attendeeId) {
1074
+ await this.http.post(`${BASE_PATH3}/${token}/participants/resend-invitations`, {
1075
+ attendeeId
1076
+ });
1077
+ }
1078
+ };
1079
+
1080
+ // src/types/constants.ts
1081
+ var ConversationType = /* @__PURE__ */ ((ConversationType2) => {
1082
+ ConversationType2[ConversationType2["ONE_TO_ONE"] = 1] = "ONE_TO_ONE";
1083
+ ConversationType2[ConversationType2["GROUP"] = 2] = "GROUP";
1084
+ ConversationType2[ConversationType2["PUBLIC"] = 3] = "PUBLIC";
1085
+ ConversationType2[ConversationType2["CHANGELOG"] = 4] = "CHANGELOG";
1086
+ ConversationType2[ConversationType2["ONE_TO_ONE_FORMER"] = 5] = "ONE_TO_ONE_FORMER";
1087
+ ConversationType2[ConversationType2["NOTE_TO_SELF"] = 6] = "NOTE_TO_SELF";
1088
+ return ConversationType2;
1089
+ })(ConversationType || {});
1090
+ var ParticipantType = /* @__PURE__ */ ((ParticipantType2) => {
1091
+ ParticipantType2[ParticipantType2["OWNER"] = 1] = "OWNER";
1092
+ ParticipantType2[ParticipantType2["MODERATOR"] = 2] = "MODERATOR";
1093
+ ParticipantType2[ParticipantType2["USER"] = 3] = "USER";
1094
+ ParticipantType2[ParticipantType2["GUEST"] = 4] = "GUEST";
1095
+ ParticipantType2[ParticipantType2["USER_SELF_JOINED"] = 5] = "USER_SELF_JOINED";
1096
+ ParticipantType2[ParticipantType2["GUEST_MODERATOR"] = 6] = "GUEST_MODERATOR";
1097
+ return ParticipantType2;
1098
+ })(ParticipantType || {});
1099
+ var Permission = /* @__PURE__ */ ((Permission2) => {
1100
+ Permission2[Permission2["DEFAULT"] = 0] = "DEFAULT";
1101
+ Permission2[Permission2["CUSTOM"] = 1] = "CUSTOM";
1102
+ Permission2[Permission2["CALL_START"] = 2] = "CALL_START";
1103
+ Permission2[Permission2["CALL_JOIN"] = 4] = "CALL_JOIN";
1104
+ Permission2[Permission2["LOBBY_IGNORE"] = 8] = "LOBBY_IGNORE";
1105
+ Permission2[Permission2["PUBLISH_AUDIO"] = 16] = "PUBLISH_AUDIO";
1106
+ Permission2[Permission2["PUBLISH_VIDEO"] = 32] = "PUBLISH_VIDEO";
1107
+ Permission2[Permission2["PUBLISH_SCREEN"] = 64] = "PUBLISH_SCREEN";
1108
+ Permission2[Permission2["CHAT"] = 128] = "CHAT";
1109
+ Permission2[Permission2["FILE_SHARE"] = 256] = "FILE_SHARE";
1110
+ return Permission2;
1111
+ })(Permission || {});
1112
+ var InCallFlag = /* @__PURE__ */ ((InCallFlag2) => {
1113
+ InCallFlag2[InCallFlag2["DISCONNECTED"] = 0] = "DISCONNECTED";
1114
+ InCallFlag2[InCallFlag2["IN_CALL"] = 1] = "IN_CALL";
1115
+ InCallFlag2[InCallFlag2["WITH_AUDIO"] = 2] = "WITH_AUDIO";
1116
+ InCallFlag2[InCallFlag2["WITH_VIDEO"] = 4] = "WITH_VIDEO";
1117
+ InCallFlag2[InCallFlag2["WITH_PHONE"] = 8] = "WITH_PHONE";
1118
+ return InCallFlag2;
1119
+ })(InCallFlag || {});
1120
+ var ActorType = /* @__PURE__ */ ((ActorType2) => {
1121
+ ActorType2["USERS"] = "users";
1122
+ ActorType2["GUESTS"] = "guests";
1123
+ ActorType2["EMAILS"] = "emails";
1124
+ ActorType2["GROUPS"] = "groups";
1125
+ ActorType2["CIRCLES"] = "circles";
1126
+ ActorType2["BOTS"] = "bots";
1127
+ ActorType2["BRIDGED"] = "bridged";
1128
+ ActorType2["FEDERATED_USERS"] = "federated_users";
1129
+ ActorType2["PHONES"] = "phones";
1130
+ return ActorType2;
1131
+ })(ActorType || {});
1132
+ var MessageType = /* @__PURE__ */ ((MessageType2) => {
1133
+ MessageType2["COMMENT"] = "comment";
1134
+ MessageType2["SYSTEM"] = "system";
1135
+ MessageType2["COMMAND"] = "command";
1136
+ MessageType2["COMMENT_DELETED"] = "comment_deleted";
1137
+ MessageType2["VOICE_MESSAGE"] = "voice-message";
1138
+ MessageType2["RECORD_AUDIO"] = "record-audio";
1139
+ MessageType2["RECORD_VIDEO"] = "record-video";
1140
+ MessageType2["POLL"] = "poll";
1141
+ return MessageType2;
1142
+ })(MessageType || {});
1143
+ var NotificationLevel = /* @__PURE__ */ ((NotificationLevel2) => {
1144
+ NotificationLevel2[NotificationLevel2["DEFAULT"] = 0] = "DEFAULT";
1145
+ NotificationLevel2[NotificationLevel2["ALWAYS"] = 1] = "ALWAYS";
1146
+ NotificationLevel2[NotificationLevel2["MENTION"] = 2] = "MENTION";
1147
+ NotificationLevel2[NotificationLevel2["NEVER"] = 3] = "NEVER";
1148
+ return NotificationLevel2;
1149
+ })(NotificationLevel || {});
1150
+ var ReadOnlyState = /* @__PURE__ */ ((ReadOnlyState2) => {
1151
+ ReadOnlyState2[ReadOnlyState2["READ_WRITE"] = 0] = "READ_WRITE";
1152
+ ReadOnlyState2[ReadOnlyState2["READ_ONLY"] = 1] = "READ_ONLY";
1153
+ return ReadOnlyState2;
1154
+ })(ReadOnlyState || {});
1155
+ var LobbyState = /* @__PURE__ */ ((LobbyState2) => {
1156
+ LobbyState2[LobbyState2["DISABLED"] = 0] = "DISABLED";
1157
+ LobbyState2[LobbyState2["ENABLED"] = 1] = "ENABLED";
1158
+ return LobbyState2;
1159
+ })(LobbyState || {});
1160
+ var SIPState = /* @__PURE__ */ ((SIPState2) => {
1161
+ SIPState2[SIPState2["DISABLED"] = 0] = "DISABLED";
1162
+ SIPState2[SIPState2["ENABLED_NO_PIN"] = 1] = "ENABLED_NO_PIN";
1163
+ SIPState2[SIPState2["ENABLED_WITH_PIN"] = 2] = "ENABLED_WITH_PIN";
1164
+ return SIPState2;
1165
+ })(SIPState || {});
1166
+ var RecordingStatus = /* @__PURE__ */ ((RecordingStatus2) => {
1167
+ RecordingStatus2[RecordingStatus2["NONE"] = 0] = "NONE";
1168
+ RecordingStatus2[RecordingStatus2["VIDEO"] = 1] = "VIDEO";
1169
+ RecordingStatus2[RecordingStatus2["AUDIO"] = 2] = "AUDIO";
1170
+ RecordingStatus2[RecordingStatus2["STARTING_VIDEO"] = 3] = "STARTING_VIDEO";
1171
+ RecordingStatus2[RecordingStatus2["STARTING_AUDIO"] = 4] = "STARTING_AUDIO";
1172
+ RecordingStatus2[RecordingStatus2["FAILED"] = 5] = "FAILED";
1173
+ return RecordingStatus2;
1174
+ })(RecordingStatus || {});
1175
+ var ListableScope = /* @__PURE__ */ ((ListableScope2) => {
1176
+ ListableScope2[ListableScope2["NONE"] = 0] = "NONE";
1177
+ ListableScope2[ListableScope2["USERS"] = 1] = "USERS";
1178
+ ListableScope2[ListableScope2["EVERYONE"] = 2] = "EVERYONE";
1179
+ return ListableScope2;
1180
+ })(ListableScope || {});
1181
+ var PollResultMode = /* @__PURE__ */ ((PollResultMode2) => {
1182
+ PollResultMode2[PollResultMode2["PUBLIC"] = 0] = "PUBLIC";
1183
+ PollResultMode2[PollResultMode2["HIDDEN"] = 1] = "HIDDEN";
1184
+ return PollResultMode2;
1185
+ })(PollResultMode || {});
1186
+ var BreakoutRoomMode = /* @__PURE__ */ ((BreakoutRoomMode2) => {
1187
+ BreakoutRoomMode2[BreakoutRoomMode2["NOT_CONFIGURED"] = 0] = "NOT_CONFIGURED";
1188
+ BreakoutRoomMode2[BreakoutRoomMode2["AUTOMATIC"] = 1] = "AUTOMATIC";
1189
+ BreakoutRoomMode2[BreakoutRoomMode2["MANUAL"] = 2] = "MANUAL";
1190
+ BreakoutRoomMode2[BreakoutRoomMode2["FREE"] = 3] = "FREE";
1191
+ return BreakoutRoomMode2;
1192
+ })(BreakoutRoomMode || {});
1193
+ var SharedObjectType = /* @__PURE__ */ ((SharedObjectType2) => {
1194
+ SharedObjectType2["FILE"] = "file";
1195
+ SharedObjectType2["AUDIO"] = "audio";
1196
+ SharedObjectType2["VOICE"] = "voice";
1197
+ SharedObjectType2["VIDEO"] = "video";
1198
+ SharedObjectType2["LOCATION"] = "location";
1199
+ SharedObjectType2["DECK_CARD"] = "deckcard";
1200
+ SharedObjectType2["OTHER"] = "other";
1201
+ SharedObjectType2["POLL"] = "poll";
1202
+ SharedObjectType2["RECORDING"] = "recording";
1203
+ return SharedObjectType2;
1204
+ })(SharedObjectType || {});
1205
+
1206
+ // src/resources/call-resource.ts
1207
+ var CALL_PATH = "/ocs/v2.php/apps/spreed/api/v4/call";
1208
+ var SIGNALING_PATH = "/ocs/v2.php/apps/spreed/api/v3/signaling";
1209
+ var CallResource = class {
1210
+ constructor(http) {
1211
+ this.http = http;
1212
+ }
1213
+ /**
1214
+ * Get peers currently in a call
1215
+ *
1216
+ * @param token - Room token
1217
+ * @returns Array of call peers
1218
+ */
1219
+ async getPeers(token) {
1220
+ const response = await this.http.get(`${CALL_PATH}/${token}`);
1221
+ return response.data;
1222
+ }
1223
+ /**
1224
+ * Join a call
1225
+ *
1226
+ * @param token - Room token
1227
+ * @param options - Join options (flags, silent, etc.)
1228
+ *
1229
+ * @remarks
1230
+ * Default flags are IN_CALL | WITH_AUDIO | WITH_VIDEO (7).
1231
+ */
1232
+ async join(token, options = {}) {
1233
+ const flags = options.flags ?? 1 /* IN_CALL */ | 2 /* WITH_AUDIO */ | 4 /* WITH_VIDEO */;
1234
+ await this.http.post(`${CALL_PATH}/${token}`, {
1235
+ flags,
1236
+ silent: options.silent,
1237
+ recordingConsent: options.recordingConsent,
1238
+ silentFor: options.silentFor
1239
+ });
1240
+ }
1241
+ /**
1242
+ * Update call flags (audio/video status)
1243
+ *
1244
+ * @param token - Room token
1245
+ * @param flags - New in-call flags
1246
+ */
1247
+ async updateFlags(token, flags) {
1248
+ await this.http.put(`${CALL_PATH}/${token}`, { flags });
1249
+ }
1250
+ /**
1251
+ * Leave a call
1252
+ *
1253
+ * @param token - Room token
1254
+ * @param options - Leave options
1255
+ */
1256
+ async leave(token, options = {}) {
1257
+ await this.http.delete(`${CALL_PATH}/${token}`, { all: options.all });
1258
+ }
1259
+ /**
1260
+ * Ring a specific attendee
1261
+ *
1262
+ * @param token - Room token
1263
+ * @param attendeeId - Attendee ID to ring
1264
+ *
1265
+ * @remarks
1266
+ * Requires START_CALL permission.
1267
+ */
1268
+ async ringAttendee(token, attendeeId) {
1269
+ await this.http.post(`${CALL_PATH}/${token}/ring/${attendeeId}`);
1270
+ }
1271
+ /**
1272
+ * Initiate SIP dial-out to a phone participant
1273
+ *
1274
+ * @param token - Room token
1275
+ * @param attendeeId - Attendee ID to dial
1276
+ */
1277
+ async dialOut(token, attendeeId) {
1278
+ await this.http.post(`${CALL_PATH}/${token}/dialout/${attendeeId}`);
1279
+ }
1280
+ /**
1281
+ * Get signaling settings for WebRTC
1282
+ *
1283
+ * @param token - Room token
1284
+ * @returns Signaling configuration including STUN/TURN servers
1285
+ */
1286
+ async getSignalingSettings(token) {
1287
+ const response = await this.http.get(
1288
+ `${SIGNALING_PATH}/settings`,
1289
+ { token }
1290
+ );
1291
+ return response.data;
1292
+ }
1293
+ // Convenience methods for common flag operations
1294
+ /**
1295
+ * Enable audio in call
1296
+ *
1297
+ * @param token - Room token
1298
+ * @param currentFlags - Current in-call flags
1299
+ */
1300
+ async enableAudio(token, currentFlags) {
1301
+ await this.updateFlags(token, currentFlags | 2 /* WITH_AUDIO */);
1302
+ }
1303
+ /**
1304
+ * Disable audio in call
1305
+ *
1306
+ * @param token - Room token
1307
+ * @param currentFlags - Current in-call flags
1308
+ */
1309
+ async disableAudio(token, currentFlags) {
1310
+ await this.updateFlags(token, currentFlags & ~2 /* WITH_AUDIO */);
1311
+ }
1312
+ /**
1313
+ * Enable video in call
1314
+ *
1315
+ * @param token - Room token
1316
+ * @param currentFlags - Current in-call flags
1317
+ */
1318
+ async enableVideo(token, currentFlags) {
1319
+ await this.updateFlags(token, currentFlags | 4 /* WITH_VIDEO */);
1320
+ }
1321
+ /**
1322
+ * Disable video in call
1323
+ *
1324
+ * @param token - Room token
1325
+ * @param currentFlags - Current in-call flags
1326
+ */
1327
+ async disableVideo(token, currentFlags) {
1328
+ await this.updateFlags(token, currentFlags & ~4 /* WITH_VIDEO */);
1329
+ }
1330
+ };
1331
+
1332
+ // src/resources/poll-resource.ts
1333
+ var BASE_PATH4 = "/ocs/v2.php/apps/spreed/api/v1/poll";
1334
+ var PollResource = class {
1335
+ constructor(http) {
1336
+ this.http = http;
1337
+ }
1338
+ /**
1339
+ * Create a new poll
1340
+ *
1341
+ * @param token - Room token
1342
+ * @param options - Poll creation options
1343
+ * @returns Created poll
1344
+ */
1345
+ async create(token, options) {
1346
+ const response = await this.http.post(`${BASE_PATH4}/${token}`, {
1347
+ question: options.question,
1348
+ options: options.options,
1349
+ resultMode: options.resultMode ?? 0,
1350
+ maxVotes: options.maxVotes ?? 1,
1351
+ draft: options.draft,
1352
+ threadId: options.threadId
1353
+ });
1354
+ return response.data;
1355
+ }
1356
+ /**
1357
+ * Get a poll by ID
1358
+ *
1359
+ * @param token - Room token
1360
+ * @param pollId - Poll ID
1361
+ * @returns Poll data
1362
+ */
1363
+ async get(token, pollId) {
1364
+ const response = await this.http.get(`${BASE_PATH4}/${token}/${pollId}`);
1365
+ return response.data;
1366
+ }
1367
+ /**
1368
+ * Vote on a poll
1369
+ *
1370
+ * @param token - Room token
1371
+ * @param pollId - Poll ID
1372
+ * @param options - Vote options (option indices)
1373
+ * @returns Updated poll
1374
+ */
1375
+ async vote(token, pollId, options) {
1376
+ const response = await this.http.post(`${BASE_PATH4}/${token}/${pollId}`, {
1377
+ optionIds: options.optionIds
1378
+ });
1379
+ return response.data;
1380
+ }
1381
+ /**
1382
+ * Close or delete a poll
1383
+ *
1384
+ * @param token - Room token
1385
+ * @param pollId - Poll ID
1386
+ * @returns Closed poll
1387
+ */
1388
+ async close(token, pollId) {
1389
+ const response = await this.http.delete(`${BASE_PATH4}/${token}/${pollId}`);
1390
+ return response.data;
1391
+ }
1392
+ /**
1393
+ * Get poll drafts
1394
+ *
1395
+ * @param token - Room token
1396
+ * @returns Array of draft polls
1397
+ */
1398
+ async getDrafts(token) {
1399
+ const response = await this.http.get(`${BASE_PATH4}/${token}/drafts`);
1400
+ return response.data;
1401
+ }
1402
+ /**
1403
+ * Update a poll draft
1404
+ *
1405
+ * @param token - Room token
1406
+ * @param pollId - Poll draft ID
1407
+ * @param options - Updated poll options
1408
+ * @returns Updated draft
1409
+ */
1410
+ async updateDraft(token, pollId, options) {
1411
+ const response = await this.http.post(`${BASE_PATH4}/${token}/draft/${pollId}`, {
1412
+ question: options.question,
1413
+ options: options.options,
1414
+ resultMode: options.resultMode,
1415
+ maxVotes: options.maxVotes
1416
+ });
1417
+ return response.data;
1418
+ }
1419
+ };
1420
+
1421
+ // src/resources/reaction-resource.ts
1422
+ var BASE_PATH5 = "/ocs/v2.php/apps/spreed/api/v1/reaction";
1423
+ var ReactionResource = class {
1424
+ constructor(http) {
1425
+ this.http = http;
1426
+ }
1427
+ /**
1428
+ * Add a reaction to a message
1429
+ *
1430
+ * @param token - Room token
1431
+ * @param messageId - Message ID
1432
+ * @param reaction - Emoji reaction (e.g., "👍")
1433
+ * @returns Updated reactions map
1434
+ */
1435
+ async add(token, messageId, reaction) {
1436
+ const response = await this.http.post(
1437
+ `${BASE_PATH5}/${token}/${messageId}`,
1438
+ { reaction }
1439
+ );
1440
+ return response.data;
1441
+ }
1442
+ /**
1443
+ * Remove a reaction from a message
1444
+ *
1445
+ * @param token - Room token
1446
+ * @param messageId - Message ID
1447
+ * @param reaction - Emoji reaction to remove
1448
+ * @returns Updated reactions map
1449
+ */
1450
+ async remove(token, messageId, reaction) {
1451
+ const response = await this.http.delete(
1452
+ `${BASE_PATH5}/${token}/${messageId}`,
1453
+ { reaction }
1454
+ );
1455
+ return response.data;
1456
+ }
1457
+ /**
1458
+ * Get reactions for a message
1459
+ *
1460
+ * @param token - Room token
1461
+ * @param messageId - Message ID
1462
+ * @param reaction - Optional specific emoji to filter
1463
+ * @returns Reactions grouped by emoji
1464
+ */
1465
+ async get(token, messageId, reaction) {
1466
+ const response = await this.http.get(
1467
+ `${BASE_PATH5}/${token}/${messageId}`,
1468
+ { reaction }
1469
+ );
1470
+ return response.data;
1471
+ }
1472
+ };
1473
+
1474
+ // src/domain/room.ts
1475
+ var Room = class {
1476
+ /** Room token - primary API identifier */
1477
+ token;
1478
+ /** Room internal database ID */
1479
+ id;
1480
+ /** Conversation type */
1481
+ type;
1482
+ /** Room name */
1483
+ name;
1484
+ /** Computed display name */
1485
+ displayName;
1486
+ /** Room description */
1487
+ description;
1488
+ /** Current user's participant type/role */
1489
+ participantType;
1490
+ /** Current user's effective permissions */
1491
+ permissions;
1492
+ /** Whether room has a password */
1493
+ hasPassword;
1494
+ /** Whether there's an active call */
1495
+ hasCall;
1496
+ /** Read-only state */
1497
+ readOnly;
1498
+ /** Lobby state */
1499
+ lobbyState;
1500
+ /** Number of unread messages */
1501
+ unreadMessages;
1502
+ /** Whether there are unread mentions */
1503
+ unreadMention;
1504
+ /** Whether this is a favorite room */
1505
+ isFavorite;
1506
+ /** Whether this room is archived */
1507
+ isArchived;
1508
+ /** Last activity timestamp */
1509
+ lastActivity;
1510
+ /** Raw normalized data for advanced access */
1511
+ _data;
1512
+ resources;
1513
+ constructor(data, resources) {
1514
+ this._data = data;
1515
+ this.resources = resources;
1516
+ this.token = data.token;
1517
+ this.id = data.id;
1518
+ this.type = data.type;
1519
+ this.name = data.name;
1520
+ this.displayName = data.displayName;
1521
+ this.description = data.description;
1522
+ this.participantType = data.participantType;
1523
+ this.permissions = data.permissions;
1524
+ this.hasPassword = data.hasPassword;
1525
+ this.hasCall = data.hasCall;
1526
+ this.readOnly = data.readOnly;
1527
+ this.lobbyState = data.lobbyState;
1528
+ this.unreadMessages = data.unreadMessages;
1529
+ this.unreadMention = data.unreadMention;
1530
+ this.lastActivity = data.lastActivity;
1531
+ this.isFavorite = data.isFavorite;
1532
+ this.isArchived = data.isArchived;
1533
+ }
1534
+ // ==================== Chat Operations ====================
1535
+ /**
1536
+ * Send a message to this room
1537
+ *
1538
+ * @param message - Message content or full options
1539
+ * @returns Sent message
1540
+ */
1541
+ async sendMessage(message) {
1542
+ const options = typeof message === "string" ? { message } : message;
1543
+ return this.resources.chat.sendMessage(this.token, options);
1544
+ }
1545
+ /**
1546
+ * Get message history
1547
+ *
1548
+ * @param options - Optional limit and pagination
1549
+ * @returns Array of messages
1550
+ */
1551
+ async getHistory(options = {}) {
1552
+ return this.resources.chat.getHistory(this.token, options);
1553
+ }
1554
+ /**
1555
+ * Poll for new messages (long-polling)
1556
+ *
1557
+ * @param options - Poll options with lastKnownMessageId
1558
+ * @returns Poll result with messages and metadata
1559
+ */
1560
+ async pollMessages(options) {
1561
+ return this.resources.chat.pollMessages(this.token, options);
1562
+ }
1563
+ /**
1564
+ * Edit a message
1565
+ *
1566
+ * @param messageId - Message ID to edit
1567
+ * @param newContent - New message content
1568
+ * @returns Updated message
1569
+ */
1570
+ async editMessage(messageId, newContent) {
1571
+ return this.resources.chat.editMessage(this.token, messageId, newContent);
1572
+ }
1573
+ /**
1574
+ * Delete a message
1575
+ *
1576
+ * @param messageId - Message ID to delete
1577
+ * @returns Deleted message placeholder
1578
+ */
1579
+ async deleteMessage(messageId) {
1580
+ return this.resources.chat.deleteMessage(this.token, messageId);
1581
+ }
1582
+ /**
1583
+ * Set the read marker
1584
+ *
1585
+ * @param lastReadMessage - Message ID to mark as last read
1586
+ */
1587
+ async setReadMarker(lastReadMessage) {
1588
+ return this.resources.chat.setReadMarker(this.token, lastReadMessage);
1589
+ }
1590
+ // ==================== Participant Operations ====================
1591
+ /**
1592
+ * Get participants in this room
1593
+ *
1594
+ * @param includeStatus - Include user status information
1595
+ * @returns Array of participants
1596
+ */
1597
+ async getParticipants(includeStatus = false) {
1598
+ return this.resources.participants.list(this.token, includeStatus);
1599
+ }
1600
+ /**
1601
+ * Add a user to this room
1602
+ *
1603
+ * @param userId - User ID to add
1604
+ * @param source - Source type (default: 'users')
1605
+ */
1606
+ async addParticipant(userId, source = "users") {
1607
+ return this.resources.participants.add(this.token, {
1608
+ newParticipant: userId,
1609
+ source
1610
+ });
1611
+ }
1612
+ /**
1613
+ * Remove a participant from this room
1614
+ *
1615
+ * @param attendeeId - Attendee ID to remove
1616
+ */
1617
+ async removeParticipant(attendeeId) {
1618
+ return this.resources.participants.remove(this.token, attendeeId);
1619
+ }
1620
+ /**
1621
+ * Leave this room
1622
+ */
1623
+ async leave() {
1624
+ return this.resources.participants.removeSelf(this.token);
1625
+ }
1626
+ // ==================== Call Operations ====================
1627
+ /**
1628
+ * Get peers currently in the call
1629
+ *
1630
+ * @returns Array of call peers
1631
+ */
1632
+ async getCallPeers() {
1633
+ return this.resources.call.getPeers(this.token);
1634
+ }
1635
+ /**
1636
+ * Join the call
1637
+ *
1638
+ * @param options - Join options (flags, silent, etc.)
1639
+ */
1640
+ async joinCall(options = {}) {
1641
+ return this.resources.call.join(this.token, options);
1642
+ }
1643
+ /**
1644
+ * Leave the call
1645
+ *
1646
+ * @param endForAll - End call for everyone (moderator only)
1647
+ */
1648
+ async leaveCall(endForAll = false) {
1649
+ return this.resources.call.leave(this.token, { all: endForAll });
1650
+ }
1651
+ // ==================== Poll Operations ====================
1652
+ /**
1653
+ * Create a poll in this room
1654
+ *
1655
+ * @param options - Poll creation options
1656
+ * @returns Created poll
1657
+ */
1658
+ async createPoll(options) {
1659
+ return this.resources.poll.create(this.token, options);
1660
+ }
1661
+ // ==================== Reaction Operations ====================
1662
+ /**
1663
+ * Add a reaction to a message
1664
+ *
1665
+ * @param messageId - Message ID
1666
+ * @param reaction - Emoji reaction
1667
+ */
1668
+ async addReaction(messageId, reaction) {
1669
+ await this.resources.reaction.add(this.token, messageId, reaction);
1670
+ }
1671
+ /**
1672
+ * Remove a reaction from a message
1673
+ *
1674
+ * @param messageId - Message ID
1675
+ * @param reaction - Emoji reaction to remove
1676
+ */
1677
+ async removeReaction(messageId, reaction) {
1678
+ await this.resources.reaction.remove(this.token, messageId, reaction);
1679
+ }
1680
+ // ==================== Computed Properties ====================
1681
+ /** Whether the current user is a moderator or owner */
1682
+ get isModerator() {
1683
+ return this.participantType === 1 /* OWNER */ || this.participantType === 2 /* MODERATOR */ || this.participantType === 6 /* GUEST_MODERATOR */;
1684
+ }
1685
+ /** Whether this is a one-to-one conversation */
1686
+ get isOneToOne() {
1687
+ return this.type === 1 /* ONE_TO_ONE */;
1688
+ }
1689
+ /** Whether this is a group conversation */
1690
+ get isGroup() {
1691
+ return this.type === 2 /* GROUP */;
1692
+ }
1693
+ /** Whether this is a public (open) conversation */
1694
+ get isPublic() {
1695
+ return this.type === 3 /* PUBLIC */;
1696
+ }
1697
+ /** Whether the room is currently read-only */
1698
+ get isReadOnly() {
1699
+ return this.readOnly === 1 /* READ_ONLY */;
1700
+ }
1701
+ /** Whether the lobby is enabled */
1702
+ get hasLobby() {
1703
+ return this.lobbyState === 1 /* ENABLED */;
1704
+ }
1705
+ };
1706
+
1707
+ // src/client.ts
1708
+ var RoomsAccessor = class {
1709
+ constructor(roomResource, roomResources) {
1710
+ this.roomResource = roomResource;
1711
+ this.roomResources = roomResources;
1712
+ }
1713
+ /**
1714
+ * List all conversations the current user is part of
1715
+ *
1716
+ * @param options - List options
1717
+ * @returns Array of Room entities
1718
+ *
1719
+ * @example
1720
+ * ```ts
1721
+ * const rooms = await client.rooms.list();
1722
+ * const targetRoom = rooms.find(r => r.token === 'abcdefgh');
1723
+ * ```
1724
+ */
1725
+ async list(options = {}) {
1726
+ const normalized = await this.roomResource.list(options);
1727
+ return normalized.map((data) => new Room(data, this.roomResources));
1728
+ }
1729
+ /**
1730
+ * Get a single room by token
1731
+ *
1732
+ * @param token - Room token
1733
+ * @returns Room entity
1734
+ */
1735
+ async get(token) {
1736
+ const normalized = await this.roomResource.get(token);
1737
+ return new Room(normalized, this.roomResources);
1738
+ }
1739
+ /**
1740
+ * Create a new room
1741
+ *
1742
+ * @param options - Room creation options
1743
+ * @returns Created Room entity
1744
+ *
1745
+ * @example
1746
+ * ```ts
1747
+ * // Create a group room
1748
+ * const room = await client.rooms.create({
1749
+ * roomType: 2,
1750
+ * roomName: 'Team Chat',
1751
+ * });
1752
+ *
1753
+ * // Create a 1-1 chat
1754
+ * const dm = await client.rooms.create({
1755
+ * roomType: 1,
1756
+ * invite: 'other-user',
1757
+ * source: 'users',
1758
+ * });
1759
+ * ```
1760
+ */
1761
+ async create(options) {
1762
+ const normalized = await this.roomResource.create(options);
1763
+ return new Room(normalized, this.roomResources);
1764
+ }
1765
+ /**
1766
+ * Delete a room
1767
+ *
1768
+ * @param token - Room token
1769
+ */
1770
+ async delete(token) {
1771
+ await this.roomResource.delete(token);
1772
+ }
1773
+ /**
1774
+ * Rename a room
1775
+ *
1776
+ * @param token - Room token
1777
+ * @param name - New room name
1778
+ */
1779
+ async rename(token, name) {
1780
+ await this.roomResource.rename(token, name);
1781
+ }
1782
+ };
1783
+ var TalkClient = class {
1784
+ /** HTTP client for direct API access */
1785
+ http;
1786
+ /** Rooms accessor for room operations */
1787
+ rooms;
1788
+ /** Direct access to chat resource */
1789
+ chat;
1790
+ /** Direct access to participant resource */
1791
+ participants;
1792
+ /** Direct access to call resource */
1793
+ call;
1794
+ /** Direct access to poll resource */
1795
+ poll;
1796
+ /** Direct access to reaction resource */
1797
+ reaction;
1798
+ /** Direct access to room resource */
1799
+ roomResource;
1800
+ constructor(config) {
1801
+ this.http = new HttpClient({
1802
+ host: config.host,
1803
+ username: config.username,
1804
+ password: config.password,
1805
+ fetch: config.fetch
1806
+ });
1807
+ this.roomResource = new RoomResource(this.http);
1808
+ this.chat = new ChatResource(this.http);
1809
+ this.participants = new ParticipantResource(this.http);
1810
+ this.call = new CallResource(this.http);
1811
+ this.poll = new PollResource(this.http);
1812
+ this.reaction = new ReactionResource(this.http);
1813
+ const roomResources = {
1814
+ chat: this.chat,
1815
+ participants: this.participants,
1816
+ call: this.call,
1817
+ poll: this.poll,
1818
+ reaction: this.reaction
1819
+ };
1820
+ this.rooms = new RoomsAccessor(this.roomResource, roomResources);
1821
+ }
1822
+ /**
1823
+ * Get the base URL for this client
1824
+ */
1825
+ get host() {
1826
+ return this.http.host;
1827
+ }
1828
+ };
1829
+ // Annotate the CommonJS export names for ESM import in node:
1830
+ 0 && (module.exports = {
1831
+ ActorType,
1832
+ BreakoutRoomMode,
1833
+ CallResource,
1834
+ ChatResource,
1835
+ ConversationType,
1836
+ HttpClient,
1837
+ HttpClientError,
1838
+ InCallFlag,
1839
+ ListableScope,
1840
+ LobbyState,
1841
+ MessageType,
1842
+ NotificationLevel,
1843
+ ParticipantResource,
1844
+ ParticipantType,
1845
+ Permission,
1846
+ PollResource,
1847
+ PollResultMode,
1848
+ ReactionResource,
1849
+ ReadOnlyState,
1850
+ RecordingStatus,
1851
+ Room,
1852
+ RoomResource,
1853
+ RoomsAccessor,
1854
+ SIPState,
1855
+ SharedObjectType,
1856
+ TalkClient,
1857
+ normalizeMessage,
1858
+ normalizeMessageWithParent,
1859
+ normalizeMessages,
1860
+ normalizeParticipant,
1861
+ normalizeParticipants,
1862
+ normalizeRoom,
1863
+ normalizeRooms
1864
+ });