@e-mc/watch 0.5.3 → 0.5.5
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/LICENSE +7 -11
- package/README.md +5 -3
- package/filegroup/index.d.ts +5 -5
- package/filegroup/index.js +4 -4
- package/index.d.ts +4 -4
- package/index.js +61 -59
- package/package.json +7 -7
package/LICENSE
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
Copyright 2023
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
10
|
-
|
|
11
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
1
|
+
Copyright 2023 Anya Forger
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
package/filegroup/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { FileGroupConstructor } from '../../types/lib/watch';
|
|
2
|
-
import type { ExternalAsset } from '../../types/lib/asset';
|
|
3
|
-
|
|
4
|
-
declare const FileGroup: FileGroupConstructor<ExternalAsset>;
|
|
5
|
-
|
|
1
|
+
import type { FileGroupConstructor } from '../../types/lib/watch';
|
|
2
|
+
import type { ExternalAsset } from '../../types/lib/asset';
|
|
3
|
+
|
|
4
|
+
declare const FileGroup: FileGroupConstructor<ExternalAsset>;
|
|
5
|
+
|
|
6
6
|
export = FileGroup;
|
package/filegroup/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var _a, _b, _c, _d, _e;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
const types_1 = require("
|
|
5
|
-
const core_1 = require("
|
|
4
|
+
const types_1 = require("@e-mc/types");
|
|
5
|
+
const core_1 = require("@e-mc/core");
|
|
6
6
|
const kPaused = Symbol('paused');
|
|
7
7
|
const kServer = Symbol('server');
|
|
8
8
|
const kAssets = Symbol('assets');
|
|
@@ -132,7 +132,7 @@ class FileGroup extends core_1.AbortComponent {
|
|
|
132
132
|
set related(value) {
|
|
133
133
|
this._related = value.map(item => {
|
|
134
134
|
item = FileGroup.cloneAsset(item);
|
|
135
|
-
item.flags = 1
|
|
135
|
+
item.flags = 1;
|
|
136
136
|
return item;
|
|
137
137
|
});
|
|
138
138
|
}
|
|
@@ -187,7 +187,7 @@ class FileGroup extends core_1.AbortComponent {
|
|
|
187
187
|
}
|
|
188
188
|
}
|
|
189
189
|
_a = kServer, _b = kPaused, _c = kEtag, _d = kLastModified, _e = kSockets;
|
|
190
|
-
FileGroup.CONNECTION_TIMEOUT = 10 * 60000
|
|
190
|
+
FileGroup.CONNECTION_TIMEOUT = 10 * 60000;
|
|
191
191
|
FileGroup.CLIENT_SESSION = new Map();
|
|
192
192
|
exports.default = FileGroup;
|
|
193
193
|
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { IFileManager, WatchConstructor } from '../types/lib';
|
|
2
|
-
|
|
3
|
-
declare const Watch: WatchConstructor<IFileManager>;
|
|
4
|
-
|
|
1
|
+
import type { IFileManager, WatchConstructor } from '../types/lib';
|
|
2
|
+
|
|
3
|
+
declare const Watch: WatchConstructor<IFileManager>;
|
|
4
|
+
|
|
5
5
|
export = Watch;
|
package/index.js
CHANGED
|
@@ -6,11 +6,11 @@ const fs = require("fs");
|
|
|
6
6
|
const https = require("https");
|
|
7
7
|
const ws = require("ws");
|
|
8
8
|
const pm = require("picomatch");
|
|
9
|
-
const util_1 = require("
|
|
10
|
-
const types_1 = require("
|
|
11
|
-
const core_1 = require("
|
|
12
|
-
const request_1 = require("
|
|
13
|
-
const filegroup_1 = require("
|
|
9
|
+
const util_1 = require("@e-mc/request/util");
|
|
10
|
+
const types_1 = require("@e-mc/types");
|
|
11
|
+
const core_1 = require("@e-mc/core");
|
|
12
|
+
const request_1 = require("@e-mc/request");
|
|
13
|
+
const filegroup_1 = require("@e-mc/watch/filegroup");
|
|
14
14
|
const kInterval = Symbol('interval');
|
|
15
15
|
const kPort = Symbol('port');
|
|
16
16
|
const kSecurePort = Symbol('securePort');
|
|
@@ -53,43 +53,45 @@ class Watch extends core_1.Client {
|
|
|
53
53
|
let wss;
|
|
54
54
|
try {
|
|
55
55
|
if ((0, types_1.isPlainObject)(secure)) {
|
|
56
|
-
if (wss = SECURE_MAP[port]) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
56
|
+
if (!(wss = SECURE_MAP[port])) {
|
|
57
|
+
const { ca, passphrase, version, config } = secure;
|
|
58
|
+
let { key, cert } = secure;
|
|
59
|
+
if (key && cert && (key = request_1.default.readTLSKey(key, true)) && (cert = request_1.default.readTLSKey(cert, true))) {
|
|
60
|
+
const server = https.createServer({
|
|
61
|
+
...config,
|
|
62
|
+
ca: ca && request_1.default.readCACert(ca, true) || undefined,
|
|
63
|
+
key: passphrase ? [{ pem: key, passphrase }] : key,
|
|
64
|
+
cert,
|
|
65
|
+
minVersion: version || config?.minVersion
|
|
66
|
+
});
|
|
67
|
+
server.listen(port);
|
|
68
|
+
wss = new ws.Server({ server });
|
|
69
|
+
SECURE_MAP[port] = wss;
|
|
70
|
+
if (active) {
|
|
71
|
+
STATE_MAP.add(wss);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
this.writeFail('TLS/SSL key and cert not found', (0, types_1.errorMessage)('ws', 'Missing TLS/SSL credentials'));
|
|
74
76
|
}
|
|
75
77
|
}
|
|
76
78
|
else {
|
|
77
|
-
|
|
79
|
+
return wss;
|
|
78
80
|
}
|
|
79
81
|
}
|
|
80
|
-
else if (wss = PORT_MAP[port]) {
|
|
81
|
-
return wss;
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
82
|
+
else if (!(wss = PORT_MAP[port])) {
|
|
84
83
|
wss = new ws.Server({ port });
|
|
85
84
|
PORT_MAP[port] = wss;
|
|
86
85
|
if (active) {
|
|
87
86
|
STATE_MAP.add(wss);
|
|
88
87
|
}
|
|
89
88
|
}
|
|
89
|
+
else {
|
|
90
|
+
return wss;
|
|
91
|
+
}
|
|
90
92
|
}
|
|
91
93
|
catch (err) {
|
|
92
|
-
this.writeFail("Unknown"
|
|
94
|
+
this.writeFail("Unknown", err);
|
|
93
95
|
}
|
|
94
96
|
if (wss) {
|
|
95
97
|
wss.on('connection', function (socket) {
|
|
@@ -147,8 +149,8 @@ class Watch extends core_1.Client {
|
|
|
147
149
|
this._extensions = [];
|
|
148
150
|
this._hostEvents = [];
|
|
149
151
|
this[_a] = types_1.THRESHOLD.WATCH_INTERVAL;
|
|
150
|
-
this[_b] = 80
|
|
151
|
-
this[_c] = 443
|
|
152
|
+
this[_b] = 80;
|
|
153
|
+
this[_c] = 443;
|
|
152
154
|
this[_d] = '';
|
|
153
155
|
this[_e] = '';
|
|
154
156
|
this[_f] = '';
|
|
@@ -202,7 +204,7 @@ class Watch extends core_1.Client {
|
|
|
202
204
|
continue;
|
|
203
205
|
}
|
|
204
206
|
let watchInterval, bundleMain;
|
|
205
|
-
if (dest
|
|
207
|
+
if (dest.startsWith(':')) {
|
|
206
208
|
items.sort((a, b) => a.bundleIndex - b.bundleIndex);
|
|
207
209
|
bundleMain = items[0];
|
|
208
210
|
dest = bundleMain.localUri;
|
|
@@ -224,7 +226,7 @@ class Watch extends core_1.Client {
|
|
|
224
226
|
other = filegroup_1.default.cloneAsset(other);
|
|
225
227
|
other.watch = { ...watch };
|
|
226
228
|
}
|
|
227
|
-
other.flags &= ~1
|
|
229
|
+
other.flags &= ~1;
|
|
228
230
|
other.invalid = undefined;
|
|
229
231
|
items.push(other);
|
|
230
232
|
}
|
|
@@ -241,10 +243,10 @@ class Watch extends core_1.Client {
|
|
|
241
243
|
const uri = target.value.uri;
|
|
242
244
|
delete map[uri];
|
|
243
245
|
abortTimeout(target);
|
|
244
|
-
this.writeFail(["Unable to watch file"
|
|
246
|
+
this.writeFail(["Unable to watch file", uri], err, 16);
|
|
245
247
|
};
|
|
246
248
|
const watchExpired = (map, target, message = 'Expired') => {
|
|
247
|
-
this.formatMessage(16
|
|
249
|
+
this.formatMessage(16, 'WATCH', [message, target.startTime ? 'since ' + formatDate(target.startTime) : ''], target.uri, { titleColor: 'grey' });
|
|
248
250
|
const data = map[target.uri];
|
|
249
251
|
if (!data || data.size === 0) {
|
|
250
252
|
delete map[target.uri];
|
|
@@ -301,7 +303,7 @@ class Watch extends core_1.Client {
|
|
|
301
303
|
wss = Watch.createServer(port || (port = this.port));
|
|
302
304
|
}
|
|
303
305
|
if (!wss) {
|
|
304
|
-
this.writeFail('Unable to create WebSocket server', (0, types_1.errorMessage)(secure ? 'wss' : 'ws', "Invalid parameters"
|
|
306
|
+
this.writeFail('Unable to create WebSocket server', (0, types_1.errorMessage)(secure ? 'wss' : 'ws', "Invalid parameters", 'port: ' + (port || "Unknown")), 16);
|
|
305
307
|
socketId = undefined;
|
|
306
308
|
port = undefined;
|
|
307
309
|
secure = undefined;
|
|
@@ -313,7 +315,7 @@ class Watch extends core_1.Client {
|
|
|
313
315
|
}
|
|
314
316
|
const interval = getInterval(item) || watchInterval || this.interval;
|
|
315
317
|
const watching = (uri, esm) => {
|
|
316
|
-
const group = new filegroup_1.default(uri, main ? assets : items, startTime, this.willAbort("(watch)"
|
|
318
|
+
const group = new filegroup_1.default(uri, main ? assets : items, startTime, this.willAbort("(watch)"));
|
|
317
319
|
group.add(expires, socketId, id);
|
|
318
320
|
if (main) {
|
|
319
321
|
group.main = main;
|
|
@@ -386,7 +388,7 @@ class Watch extends core_1.Client {
|
|
|
386
388
|
wss.close();
|
|
387
389
|
}
|
|
388
390
|
message = 'Destination already watched @ ' + (current.secure ? 'wss' : 'ws') + '://hostname:' + current.port;
|
|
389
|
-
return 3
|
|
391
|
+
return 3;
|
|
390
392
|
}
|
|
391
393
|
}
|
|
392
394
|
const socket = socketId && current.find(socketId);
|
|
@@ -396,18 +398,18 @@ class Watch extends core_1.Client {
|
|
|
396
398
|
else {
|
|
397
399
|
current.add(expires, socketId, id);
|
|
398
400
|
}
|
|
399
|
-
return 0
|
|
401
|
+
return 0;
|
|
400
402
|
}
|
|
401
403
|
}
|
|
402
404
|
data.set(dest, target);
|
|
403
|
-
return 0
|
|
405
|
+
return 0;
|
|
404
406
|
};
|
|
405
407
|
if (core_1.Client.isFile(uri, 'http/s')) {
|
|
406
408
|
group.url = item.url;
|
|
407
409
|
group.etag = item.etag;
|
|
408
410
|
group.lastModified = item.lastModified;
|
|
409
411
|
if (!group.etag && !group.lastModified) {
|
|
410
|
-
return 1
|
|
412
|
+
return 1;
|
|
411
413
|
}
|
|
412
414
|
if ((status = checkPreceding(HTTP_MAP)) !== undefined) {
|
|
413
415
|
return status;
|
|
@@ -429,7 +431,7 @@ class Watch extends core_1.Client {
|
|
|
429
431
|
return;
|
|
430
432
|
}
|
|
431
433
|
const statusCode = res.statusCode;
|
|
432
|
-
const valid = statusCode >= 200
|
|
434
|
+
const valid = statusCode >= 200 && statusCode < 300;
|
|
433
435
|
const map = HTTP_MAP[uri];
|
|
434
436
|
const etag = res.headers.etag;
|
|
435
437
|
const lastModified = res.headers['last-modified'];
|
|
@@ -481,15 +483,15 @@ class Watch extends core_1.Client {
|
|
|
481
483
|
resolve();
|
|
482
484
|
})
|
|
483
485
|
.on('error', err => {
|
|
484
|
-
if (!timeout.aborted && !(isConnectionTimeout(err) && ++timeout.retries <= 10
|
|
486
|
+
if (!timeout.aborted && !(isConnectionTimeout(err) && ++timeout.retries <= 10)) {
|
|
485
487
|
reject(err);
|
|
486
488
|
return;
|
|
487
489
|
}
|
|
488
490
|
resolve();
|
|
489
491
|
})
|
|
490
492
|
.on('timeout', () => {
|
|
491
|
-
if (!timeout.aborted && ++timeout.retries > 10
|
|
492
|
-
reject((0, types_1.errorMessage)(408
|
|
493
|
+
if (!timeout.aborted && ++timeout.retries > 10) {
|
|
494
|
+
reject((0, types_1.errorMessage)(408, 'HTTP request timeout'));
|
|
493
495
|
return;
|
|
494
496
|
}
|
|
495
497
|
resolve();
|
|
@@ -559,7 +561,7 @@ class Watch extends core_1.Client {
|
|
|
559
561
|
break;
|
|
560
562
|
}
|
|
561
563
|
catch (err) {
|
|
562
|
-
this.writeFail(["Unable to read file"
|
|
564
|
+
this.writeFail(["Unable to read file", path.basename(uri)], err, { type: 32, fatal: false });
|
|
563
565
|
}
|
|
564
566
|
}
|
|
565
567
|
}
|
|
@@ -575,9 +577,9 @@ class Watch extends core_1.Client {
|
|
|
575
577
|
DISK_MAP[uri] = new Map([[dest, target]]);
|
|
576
578
|
}
|
|
577
579
|
else {
|
|
578
|
-
return 2
|
|
580
|
+
return 2;
|
|
579
581
|
}
|
|
580
|
-
return 0
|
|
582
|
+
return 0;
|
|
581
583
|
};
|
|
582
584
|
if ((0, types_1.isArray)(sourceFiles) && sourceFiles.some(file => this.canRead(file, { hostPermissionOnly: !!this.host }))) {
|
|
583
585
|
let index = 0;
|
|
@@ -599,34 +601,34 @@ class Watch extends core_1.Client {
|
|
|
599
601
|
if (status > 0) {
|
|
600
602
|
if (!message) {
|
|
601
603
|
switch (status) {
|
|
602
|
-
case 1
|
|
604
|
+
case 1:
|
|
603
605
|
if ((0, types_1.existsFlag)(item.flags)) {
|
|
604
606
|
continue;
|
|
605
607
|
}
|
|
606
608
|
message = 'ETag unavailable';
|
|
607
609
|
break;
|
|
608
|
-
case 2
|
|
610
|
+
case 2:
|
|
609
611
|
message = 'No read permission';
|
|
610
612
|
break;
|
|
611
|
-
case 3
|
|
613
|
+
case 3:
|
|
612
614
|
message = 'Server already in use';
|
|
613
615
|
break;
|
|
614
616
|
default:
|
|
615
|
-
message = "Unknown"
|
|
617
|
+
message = "Unknown";
|
|
616
618
|
break;
|
|
617
619
|
}
|
|
618
620
|
}
|
|
619
|
-
this.formatFail((16
|
|
621
|
+
this.formatFail((16 | (status === 2 ? 8192 : 0)), 'WATCH', ["Unable to watch file", watched && path.basename(watched)], (0, types_1.errorValue)(message, watched));
|
|
620
622
|
}
|
|
621
623
|
else {
|
|
622
|
-
this.formatMessage(16
|
|
624
|
+
this.formatMessage(16, 'WATCH', ['Start', interval + 'ms ' + (expires ? formatDate(expires) : 'never')], watched, { titleColor: 'blue' });
|
|
623
625
|
}
|
|
624
626
|
}
|
|
625
627
|
}
|
|
626
628
|
}
|
|
627
629
|
}
|
|
628
630
|
async modified(watch) {
|
|
629
|
-
this.formatMessage(16
|
|
631
|
+
this.formatMessage(16, 'WATCH', 'File modified', watch.uri, { ...core_1.Client.LOG_STYLE_WARN });
|
|
630
632
|
const { host, assets } = this;
|
|
631
633
|
let items, sanitize = false;
|
|
632
634
|
if (watch.main) {
|
|
@@ -656,7 +658,7 @@ class Watch extends core_1.Client {
|
|
|
656
658
|
}
|
|
657
659
|
}
|
|
658
660
|
if (!sanitize) {
|
|
659
|
-
items.forEach(item => item.flags |= 2
|
|
661
|
+
items.forEach(item => item.flags |= 2);
|
|
660
662
|
}
|
|
661
663
|
watch.captured = false;
|
|
662
664
|
try {
|
|
@@ -703,7 +705,7 @@ class Watch extends core_1.Client {
|
|
|
703
705
|
}
|
|
704
706
|
}
|
|
705
707
|
catch (err) {
|
|
706
|
-
this.writeFail(["Unknown"
|
|
708
|
+
this.writeFail(["Unknown", watch.url?.pathname || path.basename(watch.uri)], err);
|
|
707
709
|
}
|
|
708
710
|
}
|
|
709
711
|
configureServer({ ca, key, cert, passphrase, version, config }) {
|
|
@@ -762,7 +764,7 @@ class Watch extends core_1.Client {
|
|
|
762
764
|
return !!this[kTlsKey] && !!this[kTlsCert];
|
|
763
765
|
}
|
|
764
766
|
willAbort(value) {
|
|
765
|
-
return this.host ? this.host.willAbort(value) : value === "(watch)"
|
|
767
|
+
return this.host ? this.host.willAbort(value) : value === "(watch)";
|
|
766
768
|
}
|
|
767
769
|
set host(value) {
|
|
768
770
|
super.host = value;
|
|
@@ -810,7 +812,7 @@ class Watch extends core_1.Client {
|
|
|
810
812
|
}
|
|
811
813
|
}
|
|
812
814
|
_a = kInterval, _b = kPort, _c = kSecurePort, _d = kCa, _e = kTlsKey, _f = kTlsCert, _g = kTlsPassphrase, _h = kTlsVersion, _j = kTlsConfig;
|
|
813
|
-
Watch.PROCESS_TIMEOUT = 5 * 1000
|
|
815
|
+
Watch.PROCESS_TIMEOUT = 5 * 1000;
|
|
814
816
|
exports.default = Watch;
|
|
815
817
|
|
|
816
818
|
if (exports.default) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@e-mc/watch",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.5",
|
|
4
4
|
"description": "Watch constructor for E-mc.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
|
-
"url": "https://github.com/anpham6/e-mc.git",
|
|
12
|
+
"url": "git+https://github.com/anpham6/e-mc.git",
|
|
13
13
|
"directory": "src/watch"
|
|
14
14
|
},
|
|
15
15
|
"keywords": [
|
|
@@ -17,13 +17,13 @@
|
|
|
17
17
|
"squared-functions"
|
|
18
18
|
],
|
|
19
19
|
"author": "An Pham <anpham6@gmail.com>",
|
|
20
|
-
"license": "
|
|
20
|
+
"license": "MIT",
|
|
21
21
|
"homepage": "https://github.com/anpham6/e-mc#readme",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@e-mc/core": "0.5.
|
|
24
|
-
"@e-mc/request": "0.5.
|
|
25
|
-
"@e-mc/types": "0.5.
|
|
23
|
+
"@e-mc/core": "0.5.5",
|
|
24
|
+
"@e-mc/request": "0.5.5",
|
|
25
|
+
"@e-mc/types": "0.5.5",
|
|
26
26
|
"picomatch": "^2.3.1",
|
|
27
|
-
"ws": "^8.
|
|
27
|
+
"ws": "^8.16.0"
|
|
28
28
|
}
|
|
29
29
|
}
|