@liveblocks/node 3.14.0-types2 → 3.14.0

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 CHANGED
@@ -3,7 +3,7 @@ import { detectDupes } from "@liveblocks/core";
3
3
 
4
4
  // src/version.ts
5
5
  var PKG_NAME = "@liveblocks/node";
6
- var PKG_VERSION = "3.14.0-types2";
6
+ var PKG_VERSION = "3.14.0";
7
7
  var PKG_FORMAT = "esm";
8
8
 
9
9
  // src/client.ts
@@ -92,6 +92,19 @@ var NdJsonStream = class extends TransformStream {
92
92
  }
93
93
  };
94
94
 
95
+ // src/lib/xwarn.ts
96
+ function xwarn(resp, method, path) {
97
+ const message = resp.headers.get("X-LB-Warn");
98
+ if (message) {
99
+ const msg = ` \u26A0 [Liveblocks] ${message} (${method} ${path})`;
100
+ if (resp.ok) {
101
+ console.warn(msg);
102
+ } else {
103
+ console.error(msg);
104
+ }
105
+ }
106
+ }
107
+
95
108
  // src/Session.ts
96
109
  import { url } from "@liveblocks/core";
97
110
 
@@ -171,16 +184,19 @@ var Session = class {
171
184
  #postFn;
172
185
  #userId;
173
186
  #userInfo;
174
- #tenantId;
187
+ #organizationId;
188
+ /** Only used as a hint to produce better error messages. */
189
+ #localDev;
175
190
  #sealed = false;
176
191
  #permissions = /* @__PURE__ */ new Map();
177
192
  /** @internal */
178
- constructor(postFn, userId, userInfo, tenantId) {
193
+ constructor(postFn, userId, userInfo, organizationId, localDev) {
179
194
  assertNonEmpty(userId, "userId");
180
195
  this.#postFn = postFn;
181
196
  this.#userId = userId;
182
197
  this.#userInfo = userInfo;
183
- this.#tenantId = tenantId;
198
+ this.#organizationId = organizationId;
199
+ this.#localDev = localDev ?? false;
184
200
  }
185
201
  #getOrCreate(roomId) {
186
202
  if (this.#sealed) {
@@ -254,14 +270,17 @@ var Session = class {
254
270
  );
255
271
  }
256
272
  try {
257
- const resp = await this.#postFn(url`/v2/authorize-user`, {
273
+ const body = {
258
274
  // Required
259
275
  userId: this.#userId,
260
276
  permissions: this.serializePermissions(),
261
277
  // Optional metadata
262
- userInfo: this.#userInfo,
263
- tenantId: this.#tenantId
264
- });
278
+ userInfo: this.#userInfo
279
+ };
280
+ if (this.#organizationId !== void 0) {
281
+ body.organizationId = this.#organizationId;
282
+ }
283
+ const resp = await this.#postFn(url`/v2/authorize-user`, body);
265
284
  return {
266
285
  status: normalizeStatusCode(resp.status),
267
286
  body: await resp.text()
@@ -269,7 +288,7 @@ var Session = class {
269
288
  } catch (er) {
270
289
  return {
271
290
  status: 503,
272
- body: 'Call to /v2/authorize-user failed. See "error" for more information.',
291
+ body: this.#localDev ? "Could not connect to your Liveblocks dev server. Is it running?" : 'Call to /v2/authorize-user failed. See "error" for more information.',
273
292
  error: er
274
293
  };
275
294
  }
@@ -312,6 +331,8 @@ function inflateWebKnowledgeSourceLink(link) {
312
331
  var Liveblocks = class {
313
332
  #secret;
314
333
  #baseUrl;
334
+ /** Only used as a hint to produce better error messages. */
335
+ #localDev;
315
336
  /**
316
337
  * Interact with the Liveblocks API from your Node.js backend.
317
338
  */
@@ -321,6 +342,7 @@ var Liveblocks = class {
321
342
  assertSecretKey(secret, "secret");
322
343
  this.#secret = secret;
323
344
  this.#baseUrl = new URL(getBaseUrl(options.baseUrl));
345
+ this.#localDev = !!options.baseUrl && /^https?:\/\/localhost[:/]/.test(options.baseUrl);
324
346
  }
325
347
  async #post(path, json, options) {
326
348
  const url3 = urljoin(this.#baseUrl, path);
@@ -335,6 +357,7 @@ var Liveblocks = class {
335
357
  body: JSON.stringify(json),
336
358
  signal: options?.signal
337
359
  });
360
+ xwarn(res, "POST", path);
338
361
  return res;
339
362
  }
340
363
  async #putBinary(path, body, params, options) {
@@ -344,12 +367,14 @@ var Liveblocks = class {
344
367
  "Content-Type": "application/octet-stream"
345
368
  };
346
369
  const fetch = await fetchPolyfill();
347
- return await fetch(url3, {
370
+ const res = await fetch(url3, {
348
371
  method: "PUT",
349
372
  headers,
350
373
  body,
351
374
  signal: options?.signal
352
375
  });
376
+ xwarn(res, "PUT", path);
377
+ return res;
353
378
  }
354
379
  async #delete(path, params, options) {
355
380
  const url3 = urljoin(this.#baseUrl, path, params);
@@ -362,6 +387,7 @@ var Liveblocks = class {
362
387
  headers,
363
388
  signal: options?.signal
364
389
  });
390
+ xwarn(res, "DELETE", path);
365
391
  return res;
366
392
  }
367
393
  async #get(path, params, options) {
@@ -375,6 +401,7 @@ var Liveblocks = class {
375
401
  headers,
376
402
  signal: options?.signal
377
403
  });
404
+ xwarn(res, "GET", path);
378
405
  return res;
379
406
  }
380
407
  /* -------------------------------------------------------------------------------------------------
@@ -391,7 +418,7 @@ var Liveblocks = class {
391
418
  * uniquely identify the user account in your system. The uniqueness of this
392
419
  * value will determine how many MAUs will be counted/billed.
393
420
  *
394
- * @param tenantId (optional) The tenant ID to authorize the user for.
421
+ * @param options.organizationId (optional) The organization ID to authorize the user for.
395
422
  *
396
423
  * @param options.userInfo Custom metadata to attach to this user. Data you
397
424
  * add here will be visible to all other clients in the room, through the
@@ -404,7 +431,8 @@ var Liveblocks = class {
404
431
  this.#post.bind(this),
405
432
  userId,
406
433
  options?.userInfo,
407
- options?.tenantId
434
+ options?.organizationId ?? options?.tenantId,
435
+ this.#localDev
408
436
  );
409
437
  }
410
438
  /**
@@ -443,14 +471,23 @@ var Liveblocks = class {
443
471
  async identifyUser(identity, ...rest) {
444
472
  const options = rest[0];
445
473
  const path = url2`/v2/identify-user`;
446
- const { userId, groupIds, tenantId } = typeof identity === "string" ? { userId: identity, groupIds: void 0, tenantId: void 0 } : identity;
474
+ const { userId, groupIds, tenantId, organizationId } = typeof identity === "string" ? {
475
+ userId: identity,
476
+ groupIds: void 0,
477
+ tenantId: void 0,
478
+ organizationId: void 0
479
+ } : identity;
447
480
  assertNonEmpty(userId, "userId");
448
481
  const body = {
449
482
  userId,
450
483
  groupIds,
451
- tenantId,
452
484
  userInfo: options?.userInfo
453
485
  };
486
+ if (organizationId !== void 0) {
487
+ body.organizationId = organizationId;
488
+ } else if (tenantId !== void 0) {
489
+ body.organizationId = tenantId;
490
+ }
454
491
  try {
455
492
  const resp = await this.#post(path, body);
456
493
  return {
@@ -460,7 +497,7 @@ var Liveblocks = class {
460
497
  } catch (er) {
461
498
  return {
462
499
  status: 503,
463
- body: `Call to ${urljoin(
500
+ body: this.#localDev ? "Could not connect to your Liveblocks dev server. Is it running?" : `Call to ${urljoin(
464
501
  this.#baseUrl,
465
502
  path
466
503
  )} failed. See "error" for more information.`,
@@ -478,7 +515,7 @@ var Liveblocks = class {
478
515
  * @param params.userId (optional) A filter on users accesses.
479
516
  * @param params.metadata (optional) A filter on metadata. Multiple metadata keys can be used to filter rooms.
480
517
  * @param params.groupIds (optional) A filter on groups accesses. Multiple groups can be used.
481
- * @param params.tenantId (optional) A filter on tenant ID.
518
+ * @param params.organizationId (optional) A filter on organization ID.
482
519
  * @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.
483
520
  * @param options.signal (optional) An abort signal to cancel the request.
484
521
  * @returns A list of rooms.
@@ -495,10 +532,14 @@ var Liveblocks = class {
495
532
  limit: params.limit,
496
533
  startingAfter: params.startingAfter,
497
534
  userId: params.userId,
498
- tenantId: params.tenantId,
499
535
  groupIds: params.groupIds ? params.groupIds.join(",") : void 0,
500
536
  query
501
537
  };
538
+ if (params.organizationId !== void 0) {
539
+ queryParams.organizationId = params.organizationId;
540
+ } else if (params.tenantId !== void 0) {
541
+ queryParams.organizationId = params.tenantId;
542
+ }
502
543
  const res = await this.#get(path, queryParams, options);
503
544
  if (!res.ok) {
504
545
  throw await LiveblocksError.from(res);
@@ -549,7 +590,7 @@ var Liveblocks = class {
549
590
  * @param params.groupsAccesses (optional) The group accesses for the room. Can contain a maximum of 100 entries. Key length has a limit of 40 characters.
550
591
  * @param params.usersAccesses (optional) The user accesses for the room. Can contain a maximum of 100 entries. Key length has a limit of 40 characters.
551
592
  * @param params.metadata (optional) The metadata for the room. Supports upto a maximum of 50 entries. Key length has a limit of 40 characters. Value length has a limit of 256 characters.
552
- * @param params.tenantId (optional) The tenant ID to create the room for.
593
+ * @param params.organizationId (optional) The organization ID to create the room for.
553
594
  * @param options.signal (optional) An abort signal to cancel the request.
554
595
  * @returns The created room.
555
596
  */
@@ -560,19 +601,25 @@ var Liveblocks = class {
560
601
  usersAccesses,
561
602
  metadata,
562
603
  tenantId,
604
+ organizationId,
563
605
  engine
564
606
  } = params;
607
+ const body = {
608
+ id: roomId,
609
+ defaultAccesses,
610
+ groupsAccesses,
611
+ usersAccesses,
612
+ metadata,
613
+ engine
614
+ };
615
+ if (organizationId !== void 0) {
616
+ body.organizationId = organizationId;
617
+ } else if (tenantId !== void 0) {
618
+ body.organizationId = tenantId;
619
+ }
565
620
  const res = await this.#post(
566
621
  options?.idempotent ? url2`/v2/rooms?idempotent` : url2`/v2/rooms`,
567
- {
568
- id: roomId,
569
- defaultAccesses,
570
- groupsAccesses,
571
- usersAccesses,
572
- tenantId,
573
- metadata,
574
- engine
575
- },
622
+ body,
576
623
  options
577
624
  );
578
625
  if (!res.ok) {
@@ -590,7 +637,7 @@ var Liveblocks = class {
590
637
  * @param params.groupsAccesses (optional) The group accesses for the room if the room will be created. Can contain a maximum of 100 entries. Key length has a limit of 40 characters.
591
638
  * @param params.usersAccesses (optional) The user accesses for the room if the room will be created. Can contain a maximum of 100 entries. Key length has a limit of 40 characters.
592
639
  * @param params.metadata (optional) The metadata for the room if the room will be created. Supports upto a maximum of 50 entries. Key length has a limit of 40 characters. Value length has a limit of 256 characters.
593
- * @param params.tenantId (optional) The tenant ID to create the room for.
640
+ * @param params.organizationId (optional) The organization ID to create the room for.
594
641
  * @param options.signal (optional) An abort signal to cancel the request.
595
642
  * @returns The room.
596
643
  */
@@ -727,6 +774,33 @@ var Liveblocks = class {
727
774
  throw await LiveblocksError.from(res);
728
775
  }
729
776
  }
777
+ /**
778
+ * Sets ephemeral presence for a user in a room without requiring a WebSocket connection.
779
+ * The presence data will automatically expire after the specified TTL.
780
+ * This is useful for scenarios like showing an AI agent's presence in a room.
781
+ *
782
+ * @param roomId The id of the room to set presence in.
783
+ * @param params.userId The ID of the user to set presence for.
784
+ * @param params.data The presence data as a JSON object.
785
+ * @param params.userInfo (optional) Metadata about the user or agent
786
+ * @param params.ttl (optional) Time-to-live in seconds. If not specified, the default TTL is 60 seconds. (minimum: 2, maximum: 3599).
787
+ * @param options.signal (optional) An abort signal to cancel the request.
788
+ */
789
+ async setPresence(roomId, params, options) {
790
+ const res = await this.#post(
791
+ url2`/v2/rooms/${roomId}/presence`,
792
+ {
793
+ userId: params.userId,
794
+ data: params.data,
795
+ userInfo: params.userInfo,
796
+ ttl: params.ttl
797
+ },
798
+ options
799
+ );
800
+ if (!res.ok) {
801
+ throw await LiveblocksError.from(res);
802
+ }
803
+ }
730
804
  async getStorageDocument(roomId, format = "plain-lson", options) {
731
805
  const res = await this.#get(
732
806
  url2`/v2/rooms/${roomId}/storage`,
@@ -1307,25 +1381,30 @@ var Liveblocks = class {
1307
1381
  * Returns the inbox notifications for a user.
1308
1382
  * @param params.userId The user ID to get the inbox notifications from.
1309
1383
  * @param params.query The query to filter inbox notifications by. It is based on our query language and can filter by unread.
1310
- * @param params.tenantId (optional) The tenant ID to get the inbox notifications for.
1384
+ * @param params.organizationId (optional) The organization ID to get the inbox notifications for.
1311
1385
  * @param options.signal (optional) An abort signal to cancel the request.
1312
1386
  */
1313
1387
  async getInboxNotifications(params, options) {
1314
- const { userId, tenantId, limit, startingAfter } = params;
1388
+ const { userId, tenantId, organizationId, limit, startingAfter } = params;
1315
1389
  let query;
1316
1390
  if (typeof params.query === "string") {
1317
1391
  query = params.query;
1318
1392
  } else if (typeof params.query === "object") {
1319
1393
  query = objectToQuery(params.query);
1320
1394
  }
1395
+ const queryParams = {
1396
+ query,
1397
+ limit,
1398
+ startingAfter
1399
+ };
1400
+ if (organizationId !== void 0) {
1401
+ queryParams.organizationId = organizationId;
1402
+ } else if (tenantId !== void 0) {
1403
+ queryParams.organizationId = tenantId;
1404
+ }
1321
1405
  const res = await this.#get(
1322
1406
  url2`/v2/users/${userId}/inbox-notifications`,
1323
- {
1324
- query,
1325
- limit,
1326
- startingAfter,
1327
- tenantId
1328
- },
1407
+ queryParams,
1329
1408
  options
1330
1409
  );
1331
1410
  if (!res.ok) {
@@ -1345,7 +1424,7 @@ var Liveblocks = class {
1345
1424
  *
1346
1425
  * @param criteria.userId The user ID to get the inbox notifications from.
1347
1426
  * @param criteria.query The query to filter inbox notifications by. It is based on our query language and can filter by unread.
1348
- * @param criteria.tenantId (optional) The tenant ID to get the inbox notifications for.
1427
+ * @param criteria.organizationId (optional) The organization ID to get the inbox notifications for.
1349
1428
  * @param options.pageSize (optional) The page size to use for each request.
1350
1429
  * @param options.signal (optional) An abort signal to cancel the request.
1351
1430
  */
@@ -1370,20 +1449,25 @@ var Liveblocks = class {
1370
1449
  /**
1371
1450
  * Returns all room subscription settings for a user.
1372
1451
  * @param params.userId The user ID to get the room subscription settings from.
1373
- * @param params.tenantId (optional) The tenant ID to get the room subscription settings for.
1452
+ * @param params.organizationId (optional) The organization ID to get the room subscription settings for.
1374
1453
  * @param params.startingAfter (optional) The cursor to start the pagination from.
1375
1454
  * @param params.limit (optional) The number of items to return.
1376
1455
  * @param options.signal (optional) An abort signal to cancel the request.
1377
1456
  */
1378
1457
  async getUserRoomSubscriptionSettings(params, options) {
1379
- const { userId, tenantId, startingAfter, limit } = params;
1458
+ const { userId, tenantId, organizationId, startingAfter, limit } = params;
1459
+ const queryParams = {
1460
+ startingAfter,
1461
+ limit
1462
+ };
1463
+ if (organizationId !== void 0) {
1464
+ queryParams.organizationId = organizationId;
1465
+ } else if (tenantId !== void 0) {
1466
+ queryParams.organizationId = tenantId;
1467
+ }
1380
1468
  const res = await this.#get(
1381
1469
  url2`/v2/users/${userId}/room-subscription-settings`,
1382
- {
1383
- tenantId,
1384
- startingAfter,
1385
- limit
1386
- },
1470
+ queryParams,
1387
1471
  options
1388
1472
  );
1389
1473
  if (!res.ok) {
@@ -1471,13 +1555,22 @@ var Liveblocks = class {
1471
1555
  * @param params.subjectId The subject ID of the triggered inbox notification.
1472
1556
  * @param params.activityData The activity data of the triggered inbox notification.
1473
1557
  * @param params.roomId (optional) The room ID to trigger the inbox notification for.
1474
- * @param params.tenantId (optional) The tenant ID to trigger the inbox notification for.
1558
+ * @param params.organizationId (optional) The organization ID to trigger the inbox notification for.
1475
1559
  * @param options.signal (optional) An abort signal to cancel the request.
1476
1560
  */
1477
1561
  async triggerInboxNotification(params, options) {
1562
+ const { tenantId, organizationId, ...restParams } = params;
1563
+ const body = {
1564
+ ...restParams
1565
+ };
1566
+ if (organizationId !== void 0) {
1567
+ body.organizationId = organizationId;
1568
+ } else if (tenantId !== void 0) {
1569
+ body.organizationId = tenantId;
1570
+ }
1478
1571
  const res = await this.#post(
1479
1572
  url2`/v2/inbox-notifications/trigger`,
1480
- params,
1573
+ body,
1481
1574
  options
1482
1575
  );
1483
1576
  if (!res.ok) {
@@ -1504,14 +1597,20 @@ var Liveblocks = class {
1504
1597
  /**
1505
1598
  * Deletes all inbox notifications for a user.
1506
1599
  * @param params.userId The user ID for which to delete all the inbox notifications.
1507
- * @param params.tenantId (optional) The tenant ID to delete the inbox notifications for.
1600
+ * @param params.organizationId (optional) The organization ID to delete the inbox notifications for.
1508
1601
  * @param options.signal (optional) An abort signal to cancel the request.
1509
1602
  */
1510
1603
  async deleteAllInboxNotifications(params, options) {
1511
- const { userId, tenantId } = params;
1604
+ const { userId, tenantId, organizationId } = params;
1605
+ const queryParams = {};
1606
+ if (organizationId !== void 0) {
1607
+ queryParams.organizationId = organizationId;
1608
+ } else if (tenantId !== void 0) {
1609
+ queryParams.organizationId = tenantId;
1610
+ }
1512
1611
  const res = await this.#delete(
1513
1612
  url2`/v2/users/${userId}/inbox-notifications`,
1514
- { tenantId },
1613
+ queryParams,
1515
1614
  options
1516
1615
  );
1517
1616
  if (!res.ok) {
@@ -1577,21 +1676,24 @@ var Liveblocks = class {
1577
1676
  * Create a group
1578
1677
  * @param params.groupId The ID of the group to create.
1579
1678
  * @param params.memberIds The IDs of the members to add to the group.
1580
- * @param params.tenantId (optional) The tenant ID to create the group for.
1679
+ * @param params.organizationId (optional) The organization ID to create the group for.
1581
1680
  * @param params.scopes (optional) The scopes to grant to the group. The default is `{ mention: true }`.
1582
1681
  * @param options.signal (optional) An abort signal to cancel the request.
1583
1682
  */
1584
1683
  async createGroup(params, options) {
1585
- const res = await this.#post(
1586
- url2`/v2/groups`,
1587
- {
1588
- ...params,
1589
- // The REST API uses `id` since a group is a resource,
1590
- // but we use `groupId` here for consistency with the other methods.
1591
- id: params.groupId
1592
- },
1593
- options
1594
- );
1684
+ const { tenantId, organizationId, ...restParams } = params;
1685
+ const body = {
1686
+ ...restParams,
1687
+ // The REST API uses `id` since a group is a resource,
1688
+ // but we use `groupId` here for consistency with the other methods.
1689
+ id: params.groupId
1690
+ };
1691
+ if (organizationId !== void 0) {
1692
+ body.organizationId = organizationId;
1693
+ } else if (tenantId !== void 0) {
1694
+ body.organizationId = tenantId;
1695
+ }
1696
+ const res = await this.#post(url2`/v2/groups`, body, options);
1595
1697
  if (!res.ok) {
1596
1698
  throw await LiveblocksError.from(res);
1597
1699
  }