ring-client-api 13.1.0 → 13.2.0-beta.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/lib/api.js CHANGED
@@ -18,6 +18,9 @@ const push_receiver_1 = __importDefault(require("@eneris/push-receiver"));
18
18
  const ring_intercom_1 = require("./ring-intercom");
19
19
  const json_bigint_1 = __importDefault(require("json-bigint"));
20
20
  class RingApi extends subscribed_1.Subscribed {
21
+ options;
22
+ restClient;
23
+ onRefreshTokenUpdated;
21
24
  constructor(options) {
22
25
  super();
23
26
  this.options = options;
@@ -273,6 +276,7 @@ class RingApi extends subscribed_1.Subscribed {
273
276
  });
274
277
  return locations;
275
278
  }
279
+ locationsPromise;
276
280
  getLocations() {
277
281
  if (!this.locationsPromise) {
278
282
  this.locationsPromise = this.fetchAndBuildLocations();
package/lib/location.js CHANGED
@@ -15,6 +15,51 @@ function flattenDeviceData(data) {
15
15
  return Object.assign({}, data.general && data.general.v2, data.device && data.device.v1);
16
16
  }
17
17
  class Location extends subscribed_1.Subscribed {
18
+ locationDetails;
19
+ cameras;
20
+ chimes;
21
+ intercoms;
22
+ options;
23
+ restClient;
24
+ seq = 1;
25
+ onMessage = new rxjs_1.Subject();
26
+ onDataUpdate = new rxjs_1.Subject();
27
+ onDeviceDataUpdate = this.onDataUpdate.pipe((0, operators_1.filter)((message) => {
28
+ return message.datatype === 'DeviceInfoDocType' && Boolean(message.body);
29
+ }), (0, operators_1.concatMap)((message) => message.body), (0, operators_1.map)(flattenDeviceData));
30
+ onDeviceList = this.onMessage.pipe((0, operators_1.filter)((m) => m.msg === deviceListMessageType));
31
+ onDevices = this.onDeviceList.pipe((0, operators_1.scan)((devices, { body: deviceList, src }) => {
32
+ if (!deviceList) {
33
+ return devices;
34
+ }
35
+ if (!this.receivedAssetDeviceLists.includes(src)) {
36
+ this.receivedAssetDeviceLists.push(src);
37
+ }
38
+ return deviceList.reduce((updatedDevices, data) => {
39
+ const flatData = flattenDeviceData(data), existingDevice = updatedDevices.find((x) => x.zid === flatData.zid);
40
+ if (existingDevice) {
41
+ existingDevice.updateData(flatData);
42
+ return updatedDevices;
43
+ }
44
+ return [...updatedDevices, new ring_device_1.RingDevice(flatData, this, src)];
45
+ }, devices);
46
+ }, []), (0, operators_1.distinctUntilChanged)((a, b) => a.length === b.length), (0, operators_1.filter)(() => {
47
+ return Boolean(this.assets &&
48
+ this.assets.every((asset) => this.receivedAssetDeviceLists.includes(asset.uuid)));
49
+ }), (0, operators_1.shareReplay)(1));
50
+ onSessionInfo = this.onDataUpdate.pipe((0, operators_1.filter)((m) => m.msg === 'SessionInfo'), (0, operators_1.map)((m) => m.body));
51
+ onConnected = new rxjs_1.BehaviorSubject(false);
52
+ onLocationMode = new rxjs_1.ReplaySubject(1);
53
+ onLocationModeRequested = new rxjs_1.Subject();
54
+ reconnecting = false;
55
+ disconnected = false;
56
+ connectionPromise;
57
+ securityPanel;
58
+ assets;
59
+ receivedAssetDeviceLists = [];
60
+ offlineAssets = [];
61
+ hasHubs;
62
+ hasAlarmBaseStation;
18
63
  constructor(locationDetails, cameras, chimes, intercoms, options, restClient) {
19
64
  super();
20
65
  this.locationDetails = locationDetails;
@@ -23,40 +68,6 @@ class Location extends subscribed_1.Subscribed {
23
68
  this.intercoms = intercoms;
24
69
  this.options = options;
25
70
  this.restClient = restClient;
26
- this.seq = 1;
27
- this.onMessage = new rxjs_1.Subject();
28
- this.onDataUpdate = new rxjs_1.Subject();
29
- this.onDeviceDataUpdate = this.onDataUpdate.pipe((0, operators_1.filter)((message) => {
30
- return message.datatype === 'DeviceInfoDocType' && Boolean(message.body);
31
- }), (0, operators_1.concatMap)((message) => message.body), (0, operators_1.map)(flattenDeviceData));
32
- this.onDeviceList = this.onMessage.pipe((0, operators_1.filter)((m) => m.msg === deviceListMessageType));
33
- this.onDevices = this.onDeviceList.pipe((0, operators_1.scan)((devices, { body: deviceList, src }) => {
34
- if (!deviceList) {
35
- return devices;
36
- }
37
- if (!this.receivedAssetDeviceLists.includes(src)) {
38
- this.receivedAssetDeviceLists.push(src);
39
- }
40
- return deviceList.reduce((updatedDevices, data) => {
41
- const flatData = flattenDeviceData(data), existingDevice = updatedDevices.find((x) => x.zid === flatData.zid);
42
- if (existingDevice) {
43
- existingDevice.updateData(flatData);
44
- return updatedDevices;
45
- }
46
- return [...updatedDevices, new ring_device_1.RingDevice(flatData, this, src)];
47
- }, devices);
48
- }, []), (0, operators_1.distinctUntilChanged)((a, b) => a.length === b.length), (0, operators_1.filter)(() => {
49
- return Boolean(this.assets &&
50
- this.assets.every((asset) => this.receivedAssetDeviceLists.includes(asset.uuid)));
51
- }), (0, operators_1.shareReplay)(1));
52
- this.onSessionInfo = this.onDataUpdate.pipe((0, operators_1.filter)((m) => m.msg === 'SessionInfo'), (0, operators_1.map)((m) => m.body));
53
- this.onConnected = new rxjs_1.BehaviorSubject(false);
54
- this.onLocationMode = new rxjs_1.ReplaySubject(1);
55
- this.onLocationModeRequested = new rxjs_1.Subject();
56
- this.reconnecting = false;
57
- this.disconnected = false;
58
- this.receivedAssetDeviceLists = [];
59
- this.offlineAssets = [];
60
71
  this.hasHubs = this.options.hasHubs;
61
72
  this.hasAlarmBaseStation = this.options.hasAlarmBaseStation;
62
73
  this.addSubscriptions(
@@ -138,6 +138,12 @@ function parseAuthConfig(rawRefreshToken) {
138
138
  }
139
139
  }
140
140
  class RingRestClient {
141
+ authOptions;
142
+ refreshToken;
143
+ authConfig;
144
+ hardwareIdPromise;
145
+ _authPromise;
146
+ timeouts = [];
141
147
  clearPreviousAuth() {
142
148
  this._authPromise = undefined;
143
149
  }
@@ -161,21 +167,22 @@ class RingRestClient {
161
167
  }
162
168
  return this._authPromise;
163
169
  }
170
+ sessionPromise = undefined;
171
+ using2fa = false;
172
+ promptFor2fa;
173
+ onRefreshTokenUpdated = new rxjs_1.ReplaySubject(1);
174
+ onSession = new rxjs_1.ReplaySubject(1);
175
+ baseSessionMetadata;
164
176
  constructor(authOptions) {
165
177
  this.authOptions = authOptions;
166
- this.refreshToken = 'refreshToken' in this.authOptions
167
- ? this.authOptions.refreshToken
168
- : undefined;
178
+ this.refreshToken =
179
+ 'refreshToken' in authOptions ? authOptions.refreshToken : undefined;
169
180
  this.authConfig = parseAuthConfig(this.refreshToken);
170
- this.hardwareIdPromise = this.authConfig?.hid || (0, util_1.getHardwareId)(this.authOptions.systemId);
171
- this.timeouts = [];
172
- this.sessionPromise = undefined;
173
- this.using2fa = false;
174
- this.onRefreshTokenUpdated = new rxjs_1.ReplaySubject(1);
175
- this.onSession = new rxjs_1.ReplaySubject(1);
181
+ this.hardwareIdPromise =
182
+ this.authConfig?.hid || (0, util_1.getHardwareId)(authOptions.systemId);
176
183
  this.baseSessionMetadata = {
177
184
  api_version: apiVersion,
178
- device_model: this.authOptions.controlCenterDisplayName ?? 'ring-client-api',
185
+ device_model: authOptions.controlCenterDisplayName ?? 'ring-client-api',
179
186
  };
180
187
  }
181
188
  getGrantData(twoFactorAuthCode) {
@@ -68,28 +68,37 @@ function cleanSnapshotUuid(uuid) {
68
68
  return uuid.replace(/:.*$/, '');
69
69
  }
70
70
  class RingCamera extends subscribed_1.Subscribed {
71
+ initialData;
72
+ isDoorbot;
73
+ restClient;
74
+ avoidSnapshotBatteryDrain;
75
+ id;
76
+ deviceType;
77
+ model;
78
+ onData;
79
+ hasLight;
80
+ hasSiren;
81
+ onRequestUpdate = new rxjs_1.Subject();
82
+ onNewNotification = new rxjs_1.Subject();
83
+ onActiveNotifications = new rxjs_1.BehaviorSubject([]);
84
+ onDoorbellPressed = this.onNewNotification.pipe((0, operators_1.filter)((notification) => notification.android_config.category === ring_types_1.PushNotificationAction.Ding), (0, operators_1.share)());
85
+ onMotionDetected = this.onActiveNotifications.pipe((0, operators_1.map)((notifications) => notifications.some((notification) => notification.android_config.category ===
86
+ ring_types_1.PushNotificationAction.Motion)), (0, operators_1.distinctUntilChanged)(), (0, operators_1.share)({
87
+ connector: () => new rxjs_1.ReplaySubject(1),
88
+ resetOnError: false,
89
+ resetOnComplete: false,
90
+ resetOnRefCountZero: false,
91
+ }));
92
+ onMotionStarted = this.onMotionDetected.pipe((0, operators_1.filter)((currentlyDetected) => currentlyDetected), (0, operators_1.map)(() => null), // no value needed, event is what matters
93
+ (0, operators_1.share)());
94
+ onBatteryLevel;
95
+ onInHomeDoorbellStatus;
71
96
  constructor(initialData, isDoorbot, restClient, avoidSnapshotBatteryDrain) {
72
97
  super();
73
98
  this.initialData = initialData;
74
99
  this.isDoorbot = isDoorbot;
75
100
  this.restClient = restClient;
76
101
  this.avoidSnapshotBatteryDrain = avoidSnapshotBatteryDrain;
77
- this.onRequestUpdate = new rxjs_1.Subject();
78
- this.onNewNotification = new rxjs_1.Subject();
79
- this.onActiveNotifications = new rxjs_1.BehaviorSubject([]);
80
- this.onDoorbellPressed = this.onNewNotification.pipe((0, operators_1.filter)((notification) => notification.android_config.category === ring_types_1.PushNotificationAction.Ding), (0, operators_1.share)());
81
- this.onMotionDetected = this.onActiveNotifications.pipe((0, operators_1.map)((notifications) => notifications.some((notification) => notification.android_config.category ===
82
- ring_types_1.PushNotificationAction.Motion)), (0, operators_1.distinctUntilChanged)(), (0, operators_1.share)({
83
- connector: () => new rxjs_1.ReplaySubject(1),
84
- resetOnError: false,
85
- resetOnComplete: false,
86
- resetOnRefCountZero: false,
87
- }));
88
- this.onMotionStarted = this.onMotionDetected.pipe((0, operators_1.filter)((currentlyDetected) => currentlyDetected), (0, operators_1.map)(() => null), // no value needed, event is what matters
89
- (0, operators_1.share)());
90
- this.lastSnapshotTimestamp = 0;
91
- this.lastSnapshotTimestampLocal = 0;
92
- this.fetchingSnapshot = false;
93
102
  this.id = this.initialData.id;
94
103
  this.deviceType = this.initialData.kind;
95
104
  this.model =
@@ -324,6 +333,9 @@ class RingCamera extends subscribed_1.Subscribed {
324
333
  ? 600 * 1000 // battery cams only refresh timestamp every 10 minutes
325
334
  : 10 * 1000; // snapshot updates will be forced. Limit to 10s lifetime
326
335
  }
336
+ lastSnapshotTimestamp = 0;
337
+ lastSnapshotTimestampLocal = 0;
338
+ lastSnapshotPromise;
327
339
  get currentTimestampAge() {
328
340
  return Date.now() - this.lastSnapshotTimestampLocal;
329
341
  }
@@ -352,6 +364,7 @@ class RingCamera extends subscribed_1.Subscribed {
352
364
  return false;
353
365
  }
354
366
  }
367
+ fetchingSnapshot = false;
355
368
  async getSnapshot({ uuid } = {}) {
356
369
  if (this.lastSnapshotPromise && this.shouldUseExistingSnapshotPromise()) {
357
370
  return this.lastSnapshotPromise;
package/lib/ring-chime.js CHANGED
@@ -11,10 +11,16 @@ const settingsWhichRequireReboot = [
11
11
  'motion_audio_user_id',
12
12
  ];
13
13
  class RingChime {
14
+ initialData;
15
+ restClient;
16
+ id;
17
+ deviceType;
18
+ model;
19
+ onData;
20
+ onRequestUpdate = new rxjs_1.Subject();
14
21
  constructor(initialData, restClient) {
15
22
  this.initialData = initialData;
16
23
  this.restClient = restClient;
17
- this.onRequestUpdate = new rxjs_1.Subject();
18
24
  this.id = this.initialData.id;
19
25
  this.deviceType = this.initialData.kind;
20
26
  this.model = ring_types_1.ChimeModel[this.deviceType] || 'Chime';
@@ -7,6 +7,15 @@ const operators_1 = require("rxjs/operators");
7
7
  const subscribed_1 = require("./subscribed");
8
8
  const util_1 = require("./util");
9
9
  class RingDevice extends subscribed_1.Subscribed {
10
+ initialData;
11
+ location;
12
+ assetId;
13
+ onData;
14
+ zid;
15
+ id;
16
+ deviceType;
17
+ categoryId;
18
+ onComponentDevices;
10
19
  constructor(initialData, location, assetId) {
11
20
  super();
12
21
  this.initialData = initialData;
@@ -8,12 +8,18 @@ const operators_1 = require("rxjs/operators");
8
8
  const ring_camera_1 = require("./ring-camera");
9
9
  const util_1 = require("./util");
10
10
  class RingIntercom {
11
+ initialData;
12
+ restClient;
13
+ id;
14
+ deviceType;
15
+ onData;
16
+ onRequestUpdate = new rxjs_1.Subject();
17
+ onBatteryLevel;
18
+ onDing = new rxjs_1.Subject();
19
+ onUnlocked = new rxjs_1.Subject();
11
20
  constructor(initialData, restClient) {
12
21
  this.initialData = initialData;
13
22
  this.restClient = restClient;
14
- this.onRequestUpdate = new rxjs_1.Subject();
15
- this.onDing = new rxjs_1.Subject();
16
- this.onUnlocked = new rxjs_1.Subject();
17
23
  this.id = this.initialData.id;
18
24
  this.deviceType = this.initialData.kind;
19
25
  this.onData = new rxjs_1.BehaviorSubject(this.initialData);
@@ -17,16 +17,17 @@ const ringIceServers = [
17
17
  'stun:stun4.l.google.com:19302',
18
18
  ];
19
19
  class WeriftPeerConnection extends subscribed_1.Subscribed {
20
+ pc;
21
+ onAudioRtp = new rxjs_1.Subject();
22
+ onAudioRtcp = new rxjs_1.Subject();
23
+ onVideoRtp = new rxjs_1.Subject();
24
+ onVideoRtcp = new rxjs_1.Subject();
25
+ onIceCandidate = new rxjs_1.Subject();
26
+ onConnectionState = new rxjs_1.ReplaySubject(1);
27
+ returnAudioTrack = new werift_1.MediaStreamTrack({ kind: 'audio' });
28
+ onRequestKeyFrame = new rxjs_1.Subject();
20
29
  constructor() {
21
30
  super();
22
- this.onAudioRtp = new rxjs_1.Subject();
23
- this.onAudioRtcp = new rxjs_1.Subject();
24
- this.onVideoRtp = new rxjs_1.Subject();
25
- this.onVideoRtcp = new rxjs_1.Subject();
26
- this.onIceCandidate = new rxjs_1.Subject();
27
- this.onConnectionState = new rxjs_1.ReplaySubject(1);
28
- this.returnAudioTrack = new werift_1.MediaStreamTrack({ kind: 'audio' });
29
- this.onRequestKeyFrame = new rxjs_1.Subject();
30
31
  const pc = (this.pc = new werift_1.RTCPeerConnection({
31
32
  codecs: {
32
33
  audio: [
@@ -6,10 +6,12 @@ function liveViewUrl(path) {
6
6
  return `https://api.ring.com/integrations/v1/liveview/${path}`;
7
7
  }
8
8
  class SimpleWebRtcSession {
9
+ camera;
10
+ restClient;
11
+ sessionId = (0, util_1.generateUuid)();
9
12
  constructor(camera, restClient) {
10
13
  this.camera = camera;
11
14
  this.restClient = restClient;
12
- this.sessionId = (0, util_1.generateUuid)();
13
15
  }
14
16
  async start(sdp) {
15
17
  const response = await this.restClient.request({
@@ -17,19 +17,19 @@ function getCleanSdp(sdp, includeVideo) {
17
17
  .join('\n');
18
18
  }
19
19
  class StreamingSession extends subscribed_1.Subscribed {
20
+ camera;
21
+ connection;
22
+ onCallEnded = new rxjs_1.ReplaySubject(1);
23
+ onUsingOpus = new rxjs_1.ReplaySubject(1);
24
+ onVideoRtp = new rxjs_1.Subject();
25
+ onAudioRtp = new rxjs_1.Subject();
26
+ audioSplitter = new camera_utils_1.RtpSplitter();
27
+ videoSplitter = new camera_utils_1.RtpSplitter();
28
+ returnAudioSplitter = new camera_utils_1.RtpSplitter();
20
29
  constructor(camera, connection) {
21
30
  super();
22
31
  this.camera = camera;
23
32
  this.connection = connection;
24
- this.onCallEnded = new rxjs_1.ReplaySubject(1);
25
- this.onUsingOpus = new rxjs_1.ReplaySubject(1);
26
- this.onVideoRtp = new rxjs_1.Subject();
27
- this.onAudioRtp = new rxjs_1.Subject();
28
- this.audioSplitter = new camera_utils_1.RtpSplitter();
29
- this.videoSplitter = new camera_utils_1.RtpSplitter();
30
- this.returnAudioSplitter = new camera_utils_1.RtpSplitter();
31
- this.cameraSpeakerActivated = false;
32
- this.hasEnded = false;
33
33
  this.bindToConnection(connection);
34
34
  }
35
35
  bindToConnection(connection) {
@@ -44,6 +44,7 @@ class StreamingSession extends subscribed_1.Subscribed {
44
44
  activate() {
45
45
  this.requestKeyFrame();
46
46
  }
47
+ cameraSpeakerActivated = false;
47
48
  activateCameraSpeaker() {
48
49
  if (this.cameraSpeakerActivated || this.hasEnded) {
49
50
  return;
@@ -155,6 +156,7 @@ class StreamingSession extends subscribed_1.Subscribed {
155
156
  });
156
157
  this.onCallEnded.pipe((0, operators_1.take)(1)).subscribe(() => ff.stop());
157
158
  }
159
+ hasEnded = false;
158
160
  callEnded() {
159
161
  if (this.hasEnded) {
160
162
  return;
@@ -8,19 +8,23 @@ const util_1 = require("../util");
8
8
  const peer_connection_1 = require("./peer-connection");
9
9
  const subscribed_1 = require("../subscribed");
10
10
  class WebrtcConnection extends subscribed_1.Subscribed {
11
+ camera;
12
+ onSessionId = new rxjs_1.ReplaySubject(1);
13
+ onOfferSent = new rxjs_1.ReplaySubject(1);
14
+ dialogId = (0, util_1.generateUuid)();
15
+ onCameraConnected = new rxjs_1.ReplaySubject(1);
16
+ onCallAnswered = new rxjs_1.ReplaySubject(1);
17
+ onCallEnded = new rxjs_1.ReplaySubject(1);
18
+ onError = new rxjs_1.ReplaySubject(1);
19
+ onMessage = new rxjs_1.ReplaySubject();
20
+ onWsOpen;
21
+ onAudioRtp;
22
+ onVideoRtp;
23
+ pc;
24
+ ws;
11
25
  constructor(ticket, camera, options) {
12
26
  super();
13
27
  this.camera = camera;
14
- this.onSessionId = new rxjs_1.ReplaySubject(1);
15
- this.onOfferSent = new rxjs_1.ReplaySubject(1);
16
- this.dialogId = (0, util_1.generateUuid)();
17
- this.onCameraConnected = new rxjs_1.ReplaySubject(1);
18
- this.onCallAnswered = new rxjs_1.ReplaySubject(1);
19
- this.onCallEnded = new rxjs_1.ReplaySubject(1);
20
- this.onError = new rxjs_1.ReplaySubject(1);
21
- this.onMessage = new rxjs_1.ReplaySubject();
22
- this.sessionId = null;
23
- this.hasEnded = false;
24
28
  this.ws = new ws_1.WebSocket(`wss://api.prod.signalling.ring.devices.a2z.com:443/ws?api_version=4.0&auth_type=ring_solutions&client_id=ring_site-${(0, util_1.generateUuid)()}&token=${ticket}`, {
25
29
  headers: {
26
30
  // This must exist or the socket will close immediately but content does not seem to matter
@@ -110,6 +114,7 @@ class WebrtcConnection extends subscribed_1.Subscribed {
110
114
  });
111
115
  this.onOfferSent.next();
112
116
  }
117
+ sessionId = null;
113
118
  async handleMessage(message) {
114
119
  if (message.body.doorbot_id !== this.camera.id) {
115
120
  // ignore messages for other cameras
@@ -220,6 +225,7 @@ class WebrtcConnection extends subscribed_1.Subscribed {
220
225
  });
221
226
  }));
222
227
  }
228
+ hasEnded = false;
223
229
  callEnded() {
224
230
  if (this.hasEnded) {
225
231
  return;
package/lib/subscribed.js CHANGED
@@ -2,9 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Subscribed = void 0;
4
4
  class Subscribed {
5
- constructor() {
6
- this.subscriptions = [];
7
- }
5
+ subscriptions = [];
8
6
  addSubscriptions(...subscriptions) {
9
7
  this.subscriptions.push(...subscriptions);
10
8
  }
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "ring-client-api",
3
- "version": "13.1.0",
3
+ "version": "13.2.0-beta.0",
4
4
  "description": "Unofficial API for Ring doorbells, cameras, security alarm system and smart lighting",
5
5
  "main": "lib/index.js",
6
6
  "exports": {
7
7
  ".": "./lib/index.js",
8
8
  "./ffmpeg": "./lib/ffmpeg.js",
9
9
  "./util": "./lib/util.js",
10
- "./rest-client": "./lib/rest-client.js"
10
+ "./rest-client": "./lib/rest-client.js",
11
+ "./streaming/streaming-session": "./lib/streaming/streaming-session.js"
11
12
  },
12
13
  "scripts": {
13
14
  "build": "rm -rf lib && tsc --declaration && chmod +x ./lib/ring-*-cli.js",
@@ -17,35 +18,35 @@
17
18
  "test:watch": "jest --watch"
18
19
  },
19
20
  "dependencies": {
20
- "@eneris/push-receiver": "4.1.6",
21
+ "@eneris/push-receiver": "4.2.0",
21
22
  "@homebridge/camera-utils": "^2.2.6",
22
- "@types/socket.io-client": "1.4.36",
23
23
  "colors": "1.4.0",
24
- "debug": "^4.3.6",
24
+ "debug": "^4.3.7",
25
25
  "json-bigint": "^1.0.0",
26
26
  "rxjs": "^7.8.1",
27
27
  "socket.io-client": "^2.5.0",
28
- "systeminformation": "^5.23.4",
28
+ "systeminformation": "^5.23.5",
29
29
  "uuid": "^10.0.0",
30
30
  "werift": "0.19.4",
31
31
  "ws": "^8.18.0"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/debug": "4.1.12",
35
- "@types/jest": "29.5.12",
35
+ "@types/jest": "29.5.13",
36
36
  "@types/json-bigint": "^1.0.4",
37
- "@types/node": "22.1.0",
37
+ "@types/node": "22.7.5",
38
+ "@types/socket.io-client": "1.4.36",
38
39
  "@types/uuid": "10.0.0",
39
40
  "@types/ws": "^8.5.12",
40
41
  "eslint-config-shared": "*",
41
42
  "jest": "29.7.0",
42
- "msw": "^2.3.5",
43
- "ts-jest": "29.2.4",
43
+ "msw": "^2.4.10",
44
+ "ts-jest": "29.2.5",
44
45
  "tsconfig": "*",
45
- "typescript": "5.5.4"
46
+ "typescript": "5.6.3"
46
47
  },
47
48
  "engines": {
48
- "node": "^18 || ^20"
49
+ "node": "^18 || ^20 || ^22"
49
50
  },
50
51
  "repository": {
51
52
  "type": "git",