@liveblocks/node 1.19.0-test1 → 2.0.0-alpha1
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.d.mts +171 -111
- package/dist/index.d.ts +171 -111
- package/dist/index.js +182 -88
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +182 -88
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -3
package/dist/index.mjs
CHANGED
|
@@ -3,11 +3,27 @@ import { detectDupes } from "@liveblocks/core";
|
|
|
3
3
|
|
|
4
4
|
// src/version.ts
|
|
5
5
|
var PKG_NAME = "@liveblocks/node";
|
|
6
|
-
var PKG_VERSION = "
|
|
6
|
+
var PKG_VERSION = "2.0.0-alpha1";
|
|
7
7
|
var PKG_FORMAT = "esm";
|
|
8
8
|
|
|
9
|
+
// src/client.ts
|
|
10
|
+
import {
|
|
11
|
+
convertToCommentData,
|
|
12
|
+
convertToCommentUserReaction,
|
|
13
|
+
convertToInboxNotificationData,
|
|
14
|
+
convertToThreadData,
|
|
15
|
+
objectToQuery
|
|
16
|
+
} from "@liveblocks/core";
|
|
17
|
+
|
|
9
18
|
// src/utils.ts
|
|
10
19
|
var DEFAULT_BASE_URL = "https://api.liveblocks.io";
|
|
20
|
+
function getBaseUrl(baseUrl) {
|
|
21
|
+
if (typeof baseUrl === "string" && baseUrl.startsWith("http")) {
|
|
22
|
+
return baseUrl;
|
|
23
|
+
} else {
|
|
24
|
+
return DEFAULT_BASE_URL;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
11
27
|
async function fetchPolyfill() {
|
|
12
28
|
return typeof globalThis.fetch !== "undefined" ? globalThis.fetch : (await import("node-fetch")).default;
|
|
13
29
|
}
|
|
@@ -59,55 +75,6 @@ function url(strings, ...values) {
|
|
|
59
75
|
);
|
|
60
76
|
}
|
|
61
77
|
|
|
62
|
-
// src/authorize.ts
|
|
63
|
-
async function authorize(options) {
|
|
64
|
-
let url2 = null;
|
|
65
|
-
try {
|
|
66
|
-
const { room, secret, userId, userInfo, groupIds } = (
|
|
67
|
-
// Ensure we'll validate inputs at runtime
|
|
68
|
-
options
|
|
69
|
-
);
|
|
70
|
-
assertNonEmpty(secret, "secret");
|
|
71
|
-
assertNonEmpty(room, "room");
|
|
72
|
-
assertNonEmpty(userId, "userId");
|
|
73
|
-
url2 = buildLiveblocksAuthorizeEndpoint(options, room);
|
|
74
|
-
const fetch = await fetchPolyfill();
|
|
75
|
-
const resp = await fetch(buildLiveblocksAuthorizeEndpoint(options, room), {
|
|
76
|
-
method: "POST",
|
|
77
|
-
headers: {
|
|
78
|
-
Authorization: `Bearer ${secret}`,
|
|
79
|
-
"Content-Type": "application/json"
|
|
80
|
-
},
|
|
81
|
-
body: JSON.stringify({
|
|
82
|
-
userId,
|
|
83
|
-
userInfo,
|
|
84
|
-
groupIds
|
|
85
|
-
})
|
|
86
|
-
});
|
|
87
|
-
return {
|
|
88
|
-
status: normalizeStatusCode(resp.status),
|
|
89
|
-
body: await resp.text()
|
|
90
|
-
};
|
|
91
|
-
} catch (er) {
|
|
92
|
-
return {
|
|
93
|
-
status: 503,
|
|
94
|
-
body: (url2 ? `Call to "${url2}" failed.` : "Invalid authorize request.") + ' See "error" for more information.',
|
|
95
|
-
error: er
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
function buildLiveblocksAuthorizeEndpoint(options, roomId) {
|
|
100
|
-
const path = `/v2/rooms/${encodeURIComponent(roomId)}/authorize`;
|
|
101
|
-
return urljoin(options.baseUrl || DEFAULT_BASE_URL, path);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// src/client.ts
|
|
105
|
-
import {
|
|
106
|
-
convertToCommentData,
|
|
107
|
-
convertToCommentUserReaction,
|
|
108
|
-
convertToThreadData
|
|
109
|
-
} from "@liveblocks/core";
|
|
110
|
-
|
|
111
78
|
// src/Session.ts
|
|
112
79
|
var ALL_PERMISSIONS = Object.freeze([
|
|
113
80
|
"room:write",
|
|
@@ -126,7 +93,7 @@ var READ_ACCESS = Object.freeze([
|
|
|
126
93
|
"comments:read"
|
|
127
94
|
]);
|
|
128
95
|
var FULL_ACCESS = Object.freeze(["room:write", "comments:write"]);
|
|
129
|
-
var roomPatternRegex = /^[^*]{1,128}[*]
|
|
96
|
+
var roomPatternRegex = /^([*]|[^*]{1,128}[*]?)$/;
|
|
130
97
|
var Session = class {
|
|
131
98
|
/** @internal */
|
|
132
99
|
constructor(postFn, userId, userInfo) {
|
|
@@ -161,6 +128,9 @@ var Session = class {
|
|
|
161
128
|
}
|
|
162
129
|
}
|
|
163
130
|
allow(roomIdOrPattern, newPerms) {
|
|
131
|
+
if (typeof roomIdOrPattern !== "string") {
|
|
132
|
+
throw new Error("Room name or pattern must be a string");
|
|
133
|
+
}
|
|
164
134
|
if (!roomPatternRegex.test(roomIdOrPattern)) {
|
|
165
135
|
throw new Error("Invalid room name or pattern");
|
|
166
136
|
}
|
|
@@ -206,10 +176,9 @@ var Session = class {
|
|
|
206
176
|
async authorize() {
|
|
207
177
|
this.seal();
|
|
208
178
|
if (!this.hasPermissions()) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
};
|
|
179
|
+
console.warn(
|
|
180
|
+
"Access tokens without any permission will not be supported soon, you should use wildcards when the client requests a token for resources outside a room. See https://liveblocks.io/docs/errors/liveblocks-client/access-tokens-not-enough-permissions"
|
|
181
|
+
);
|
|
213
182
|
}
|
|
214
183
|
try {
|
|
215
184
|
const resp = await this._postFn(url`/v2/authorize-user`, {
|
|
@@ -243,7 +212,7 @@ var Liveblocks = class {
|
|
|
243
212
|
const secret = options_.secret;
|
|
244
213
|
assertSecretKey(secret, "secret");
|
|
245
214
|
this._secret = secret;
|
|
246
|
-
this._baseUrl = new URL(options.baseUrl
|
|
215
|
+
this._baseUrl = new URL(getBaseUrl(options.baseUrl));
|
|
247
216
|
}
|
|
248
217
|
/** @internal */
|
|
249
218
|
async post(path, json) {
|
|
@@ -268,12 +237,21 @@ var Liveblocks = class {
|
|
|
268
237
|
"Content-Type": "application/json"
|
|
269
238
|
};
|
|
270
239
|
const fetch = await fetchPolyfill();
|
|
271
|
-
|
|
240
|
+
return await fetch(url2, {
|
|
272
241
|
method: "PUT",
|
|
273
242
|
headers,
|
|
274
243
|
body: JSON.stringify(json)
|
|
275
244
|
});
|
|
276
|
-
|
|
245
|
+
}
|
|
246
|
+
/** @internal */
|
|
247
|
+
async putBinary(path, body, params) {
|
|
248
|
+
const url2 = urljoin(this._baseUrl, path, params);
|
|
249
|
+
const headers = {
|
|
250
|
+
Authorization: `Bearer ${this._secret}`,
|
|
251
|
+
"Content-Type": "application/octet-stream"
|
|
252
|
+
};
|
|
253
|
+
const fetch = await fetchPolyfill();
|
|
254
|
+
return await fetch(url2, { method: "PUT", headers, body });
|
|
277
255
|
}
|
|
278
256
|
/** @internal */
|
|
279
257
|
async delete(path) {
|
|
@@ -288,7 +266,6 @@ var Liveblocks = class {
|
|
|
288
266
|
/** @internal */
|
|
289
267
|
async get(path, params) {
|
|
290
268
|
const url2 = urljoin(this._baseUrl, path, params);
|
|
291
|
-
console.log("url", url2);
|
|
292
269
|
const headers = {
|
|
293
270
|
Authorization: `Bearer ${this._secret}`
|
|
294
271
|
};
|
|
@@ -388,10 +365,17 @@ var Liveblocks = class {
|
|
|
388
365
|
* @param params.userId (optional) A filter on users accesses.
|
|
389
366
|
* @param params.metadata (optional) A filter on metadata. Multiple metadata keys can be used to filter rooms.
|
|
390
367
|
* @param params.groupIds (optional) A filter on groups accesses. Multiple groups can be used.
|
|
368
|
+
* @param params.query (optional) A query to filter rooms by. It is based on our query language. You can filter by metadata and room ID.
|
|
391
369
|
* @returns A list of rooms.
|
|
392
370
|
*/
|
|
393
371
|
async getRooms(params = {}) {
|
|
394
372
|
const path = url`/v2/rooms`;
|
|
373
|
+
let query;
|
|
374
|
+
if (typeof params.query === "string") {
|
|
375
|
+
query = params.query;
|
|
376
|
+
} else if (typeof params.query === "object") {
|
|
377
|
+
query = objectToQuery(params.query);
|
|
378
|
+
}
|
|
395
379
|
const queryParams = {
|
|
396
380
|
limit: params.limit,
|
|
397
381
|
startingAfter: params.startingAfter,
|
|
@@ -399,21 +383,26 @@ var Liveblocks = class {
|
|
|
399
383
|
groupIds: params.groupIds ? params.groupIds.join(",") : void 0,
|
|
400
384
|
// "Flatten" {metadata: {foo: "bar"}} to {"metadata.foo": "bar"}
|
|
401
385
|
...Object.fromEntries(
|
|
402
|
-
Object.entries(params.metadata ?? {}).map(([key, val]) =>
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
)
|
|
386
|
+
Object.entries(params.metadata ?? {}).map(([key, val]) => [
|
|
387
|
+
`metadata.${key}`,
|
|
388
|
+
val
|
|
389
|
+
])
|
|
390
|
+
),
|
|
391
|
+
query
|
|
407
392
|
};
|
|
408
393
|
const res = await this.get(path, queryParams);
|
|
394
|
+
if (!res.ok) {
|
|
395
|
+
const text = await res.text();
|
|
396
|
+
throw new LiveblocksError(res.status, text);
|
|
397
|
+
}
|
|
409
398
|
const data = await res.json();
|
|
410
399
|
const rooms = data.data.map((room) => {
|
|
411
400
|
const lastConnectionAt = room.lastConnectionAt ? new Date(room.lastConnectionAt) : void 0;
|
|
412
|
-
const createdAt =
|
|
401
|
+
const createdAt = new Date(room.createdAt);
|
|
413
402
|
return {
|
|
414
403
|
...room,
|
|
415
|
-
|
|
416
|
-
|
|
404
|
+
createdAt,
|
|
405
|
+
lastConnectionAt
|
|
417
406
|
};
|
|
418
407
|
});
|
|
419
408
|
return {
|
|
@@ -445,7 +434,7 @@ var Liveblocks = class {
|
|
|
445
434
|
}
|
|
446
435
|
const data = await res.json();
|
|
447
436
|
const lastConnectionAt = data.lastConnectionAt ? new Date(data.lastConnectionAt) : void 0;
|
|
448
|
-
const createdAt =
|
|
437
|
+
const createdAt = new Date(data.createdAt);
|
|
449
438
|
return {
|
|
450
439
|
...data,
|
|
451
440
|
lastConnectionAt,
|
|
@@ -465,11 +454,11 @@ var Liveblocks = class {
|
|
|
465
454
|
}
|
|
466
455
|
const data = await res.json();
|
|
467
456
|
const lastConnectionAt = data.lastConnectionAt ? new Date(data.lastConnectionAt) : void 0;
|
|
468
|
-
const createdAt =
|
|
457
|
+
const createdAt = new Date(data.createdAt);
|
|
469
458
|
return {
|
|
470
459
|
...data,
|
|
471
|
-
|
|
472
|
-
|
|
460
|
+
createdAt,
|
|
461
|
+
lastConnectionAt
|
|
473
462
|
};
|
|
474
463
|
}
|
|
475
464
|
/**
|
|
@@ -496,7 +485,7 @@ var Liveblocks = class {
|
|
|
496
485
|
}
|
|
497
486
|
const data = await res.json();
|
|
498
487
|
const lastConnectionAt = data.lastConnectionAt ? new Date(data.lastConnectionAt) : void 0;
|
|
499
|
-
const createdAt =
|
|
488
|
+
const createdAt = new Date(data.createdAt);
|
|
500
489
|
return {
|
|
501
490
|
...data,
|
|
502
491
|
lastConnectionAt,
|
|
@@ -605,12 +594,12 @@ var Liveblocks = class {
|
|
|
605
594
|
/**
|
|
606
595
|
* Send a Yjs binary update to the room’s Yjs document. You can use this endpoint to initialize Yjs data for the room or to update the room’s Yjs document.
|
|
607
596
|
* @param roomId The id of the room to send the Yjs binary update to.
|
|
608
|
-
* @param
|
|
597
|
+
* @param update The Yjs update to send. Typically the result of calling `Yjs.encodeStateAsUpdate(doc)`. Read the [Yjs documentation](https://docs.yjs.dev/api/document-updates) to learn how to create a binary update.
|
|
598
|
+
* @param params.guid (optional) If provided, the binary update will be applied to the Yjs subdocument with the given guid. If not provided, the binary update will be applied to the root Yjs document.
|
|
609
599
|
*/
|
|
610
|
-
async sendYjsBinaryUpdate(roomId, params) {
|
|
611
|
-
const
|
|
612
|
-
|
|
613
|
-
update
|
|
600
|
+
async sendYjsBinaryUpdate(roomId, update, params = {}) {
|
|
601
|
+
const res = await this.putBinary(url`/v2/rooms/${roomId}/ydoc`, update, {
|
|
602
|
+
guid: params.guid
|
|
614
603
|
});
|
|
615
604
|
if (!res.ok) {
|
|
616
605
|
const text = await res.text();
|
|
@@ -621,10 +610,13 @@ var Liveblocks = class {
|
|
|
621
610
|
* Returns the room’s Yjs document encoded as a single binary update. This can be used by Y.applyUpdate(responseBody) to get a copy of the document in your backend.
|
|
622
611
|
* See [Yjs documentation](https://docs.yjs.dev/api/document-updates) for more information on working with updates.
|
|
623
612
|
* @param roomId The id of the room to get the Yjs document from.
|
|
613
|
+
* @param params.guid (optional) If provided, returns the binary update of the Yjs subdocument with the given guid. If not provided, returns the binary update of the root Yjs document.
|
|
624
614
|
* @returns The room’s Yjs document encoded as a single binary update.
|
|
625
615
|
*/
|
|
626
|
-
async getYjsDocumentAsBinaryUpdate(roomId) {
|
|
627
|
-
const res = await this.get(url`/v2/rooms/${roomId}/ydoc-binary
|
|
616
|
+
async getYjsDocumentAsBinaryUpdate(roomId, params = {}) {
|
|
617
|
+
const res = await this.get(url`/v2/rooms/${roomId}/ydoc-binary`, {
|
|
618
|
+
guid: params.guid
|
|
619
|
+
});
|
|
628
620
|
if (!res.ok) {
|
|
629
621
|
const text = await res.text();
|
|
630
622
|
throw new LiveblocksError(res.status, text);
|
|
@@ -767,12 +759,19 @@ var Liveblocks = class {
|
|
|
767
759
|
* Gets all the threads in a room.
|
|
768
760
|
*
|
|
769
761
|
* @param params.roomId The room ID to get the threads from.
|
|
762
|
+
* @param params.query The query to filter threads by. It is based on our query language and can filter by metadata.
|
|
770
763
|
* @returns A list of threads.
|
|
771
764
|
*/
|
|
772
765
|
async getThreads(params) {
|
|
773
766
|
const { roomId } = params;
|
|
767
|
+
let query;
|
|
768
|
+
if (typeof params.query === "string") {
|
|
769
|
+
query = params.query;
|
|
770
|
+
} else if (typeof params.query === "object") {
|
|
771
|
+
query = objectToQuery(params.query);
|
|
772
|
+
}
|
|
774
773
|
const res = await this.get(url`/v2/rooms/${roomId}/threads`, {
|
|
775
|
-
|
|
774
|
+
query
|
|
776
775
|
});
|
|
777
776
|
if (!res.ok) {
|
|
778
777
|
const text = await res.text();
|
|
@@ -797,9 +796,7 @@ var Liveblocks = class {
|
|
|
797
796
|
const text = await res.text();
|
|
798
797
|
throw new LiveblocksError(res.status, text);
|
|
799
798
|
}
|
|
800
|
-
return convertToThreadData(
|
|
801
|
-
await res.json()
|
|
802
|
-
);
|
|
799
|
+
return convertToThreadData(await res.json());
|
|
803
800
|
}
|
|
804
801
|
/**
|
|
805
802
|
* Gets a thread's participants.
|
|
@@ -929,9 +926,7 @@ var Liveblocks = class {
|
|
|
929
926
|
const text = await res.text();
|
|
930
927
|
throw new LiveblocksError(res.status, text);
|
|
931
928
|
}
|
|
932
|
-
return convertToThreadData(
|
|
933
|
-
await res.json()
|
|
934
|
-
);
|
|
929
|
+
return convertToThreadData(await res.json());
|
|
935
930
|
}
|
|
936
931
|
/**
|
|
937
932
|
* Updates the metadata of the specified thread in a room.
|
|
@@ -1006,6 +1001,104 @@ var Liveblocks = class {
|
|
|
1006
1001
|
throw new LiveblocksError(res.status, text);
|
|
1007
1002
|
}
|
|
1008
1003
|
}
|
|
1004
|
+
/**
|
|
1005
|
+
* Returns the inbox notifications for a user.
|
|
1006
|
+
* @param params.userId The user ID to get the inbox notifications from.
|
|
1007
|
+
* @param params.inboxNotificationId The ID of the inbox notification to get.
|
|
1008
|
+
*/
|
|
1009
|
+
async getInboxNotification(params) {
|
|
1010
|
+
const { userId, inboxNotificationId } = params;
|
|
1011
|
+
const res = await this.get(
|
|
1012
|
+
url`/v2/users/${userId}/inbox-notifications/${inboxNotificationId}`
|
|
1013
|
+
);
|
|
1014
|
+
if (!res.ok) {
|
|
1015
|
+
const text = await res.text();
|
|
1016
|
+
throw new LiveblocksError(res.status, text);
|
|
1017
|
+
}
|
|
1018
|
+
return convertToInboxNotificationData(
|
|
1019
|
+
await res.json()
|
|
1020
|
+
);
|
|
1021
|
+
}
|
|
1022
|
+
/**
|
|
1023
|
+
* Gets the user's room notification settings.
|
|
1024
|
+
* @param params.userId The user ID to get the room notifications from.
|
|
1025
|
+
* @param params.roomId The room ID to get the room notification settings from.
|
|
1026
|
+
*/
|
|
1027
|
+
async getRoomNotificationSettings(params) {
|
|
1028
|
+
const { userId, roomId } = params;
|
|
1029
|
+
const res = await this.get(
|
|
1030
|
+
url`/v2/rooms/${roomId}/users/${userId}/notification-settings`
|
|
1031
|
+
);
|
|
1032
|
+
if (!res.ok) {
|
|
1033
|
+
const text = await res.text();
|
|
1034
|
+
throw new LiveblocksError(res.status, text);
|
|
1035
|
+
}
|
|
1036
|
+
return await res.json();
|
|
1037
|
+
}
|
|
1038
|
+
/**
|
|
1039
|
+
* Updates the user's room notification settings.
|
|
1040
|
+
* @param params.userId The user ID to update the room notification settings for.
|
|
1041
|
+
* @param params.roomId The room ID to update the room notification settings for.
|
|
1042
|
+
* @param params.data The new room notification settings for the user.
|
|
1043
|
+
*/
|
|
1044
|
+
async updateRoomNotificationSettings(params) {
|
|
1045
|
+
const { userId, roomId, data } = params;
|
|
1046
|
+
const res = await this.post(
|
|
1047
|
+
url`/v2/rooms/${roomId}/users/${userId}/notification-settings`,
|
|
1048
|
+
data
|
|
1049
|
+
);
|
|
1050
|
+
if (!res.ok) {
|
|
1051
|
+
const text = await res.text();
|
|
1052
|
+
throw new LiveblocksError(res.status, text);
|
|
1053
|
+
}
|
|
1054
|
+
return await res.json();
|
|
1055
|
+
}
|
|
1056
|
+
/**
|
|
1057
|
+
* Delete the user's room notification settings.
|
|
1058
|
+
* @param params.userId The user ID to delete the room notification settings from.
|
|
1059
|
+
* @param params.roomId The room ID to delete the room notification settings from.
|
|
1060
|
+
*/
|
|
1061
|
+
async deleteRoomNotificationSettings(params) {
|
|
1062
|
+
const { userId, roomId } = params;
|
|
1063
|
+
const res = await this.delete(
|
|
1064
|
+
url`/v2/rooms/${roomId}/users/${userId}/notification-settings`
|
|
1065
|
+
);
|
|
1066
|
+
if (!res.ok) {
|
|
1067
|
+
const text = await res.text();
|
|
1068
|
+
throw new LiveblocksError(res.status, text);
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
/**
|
|
1072
|
+
* Update a room ID.
|
|
1073
|
+
* @param params.roomId The current ID of the room.
|
|
1074
|
+
* @param params.newRoomId The new room ID.
|
|
1075
|
+
*/
|
|
1076
|
+
async updateRoomId(params) {
|
|
1077
|
+
const { currentRoomId, newRoomId } = params;
|
|
1078
|
+
const res = await this.post(
|
|
1079
|
+
url`/v2/rooms/${currentRoomId}/update-room-id`,
|
|
1080
|
+
{
|
|
1081
|
+
newRoomId
|
|
1082
|
+
}
|
|
1083
|
+
);
|
|
1084
|
+
if (!res.ok) {
|
|
1085
|
+
const text = await res.text();
|
|
1086
|
+
throw new LiveblocksError(res.status, text);
|
|
1087
|
+
}
|
|
1088
|
+
const data = await res.json();
|
|
1089
|
+
return {
|
|
1090
|
+
...data,
|
|
1091
|
+
createdAt: new Date(data.createdAt),
|
|
1092
|
+
lastConnectionAt: data.lastConnectionAt ? new Date(data.lastConnectionAt) : void 0
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
async triggerInboxNotification(params) {
|
|
1096
|
+
const res = await this.post(url`/v2/inbox-notifications/trigger`, params);
|
|
1097
|
+
if (!res.ok) {
|
|
1098
|
+
const text = await res.text();
|
|
1099
|
+
throw new LiveblocksError(res.status, text);
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1009
1102
|
};
|
|
1010
1103
|
var LiveblocksError = class extends Error {
|
|
1011
1104
|
constructor(status, message = "") {
|
|
@@ -1121,7 +1214,8 @@ var _WebhookHandler = class _WebhookHandler {
|
|
|
1121
1214
|
"commentReactionRemoved",
|
|
1122
1215
|
"threadMetadataUpdated",
|
|
1123
1216
|
"threadCreated",
|
|
1124
|
-
"ydocUpdated"
|
|
1217
|
+
"ydocUpdated",
|
|
1218
|
+
"notification"
|
|
1125
1219
|
].includes(event.type))
|
|
1126
1220
|
return;
|
|
1127
1221
|
throw new Error(
|
|
@@ -1142,8 +1236,8 @@ import {
|
|
|
1142
1236
|
detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
|
|
1143
1237
|
export {
|
|
1144
1238
|
Liveblocks,
|
|
1239
|
+
LiveblocksError,
|
|
1145
1240
|
WebhookHandler,
|
|
1146
|
-
authorize,
|
|
1147
1241
|
getMentionedIdsFromCommentBody,
|
|
1148
1242
|
stringifyCommentBody
|
|
1149
1243
|
};
|