@bytecodealliance/preview2-shim 0.23.0 → 0.24.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/README.md +148 -7
- package/dist/browser/cli.d.ts +22 -1
- package/dist/browser/cli.js +66 -34
- package/dist/browser/clocks.js +24 -5
- package/dist/browser/common.d.ts +5 -0
- package/dist/browser/common.js +16 -0
- package/dist/browser/filesystem.d.ts +55 -97
- package/dist/browser/filesystem.js +106 -287
- package/dist/browser/http.d.ts +9 -0
- package/dist/browser/http.js +446 -136
- package/dist/browser/in-memory-filesystem.d.ts +22 -0
- package/dist/browser/in-memory-filesystem.js +530 -0
- package/dist/browser/in-memory-http.d.ts +8 -0
- package/dist/browser/in-memory-http.js +11 -0
- package/dist/browser/in-memory-sockets.d.ts +34 -0
- package/dist/browser/in-memory-sockets.js +294 -0
- package/dist/browser/io.d.ts +11 -2
- package/dist/browser/io.js +200 -39
- package/dist/browser/random.js +5 -3
- package/dist/browser/sockets.d.ts +2 -1
- package/dist/browser/sockets.js +75 -56
- package/dist/common/instantiation.d.ts +4 -1
- package/dist/common/instantiation.js +85 -49
- package/dist/io/worker-socket-tcp.js +3 -3
- package/dist/io/worker-socket-udp.js +3 -4
- package/dist/io/worker-sockets.d.ts +4 -4
- package/dist/io/worker-sockets.js +29 -9
- package/dist/io/worker-thread.bundle.js +22 -9
- package/dist/nodejs/filesystem.d.ts +7 -0
- package/dist/nodejs/filesystem.js +65 -22
- package/dist/nodejs/sockets.d.ts +13 -0
- package/dist/nodejs/sockets.js +20 -0
- package/package.json +1 -1
- package/types/instantiation.d.ts +64 -12
|
@@ -10,7 +10,7 @@ import { Server, Socket, isIP } from "node:net";
|
|
|
10
10
|
import { lookup } from "node:dns/promises";
|
|
11
11
|
import { createSocket } from "node:dgram";
|
|
12
12
|
import { ALL, BADFAMILY, CANCELLED, CONNREFUSED, NODATA, NOMEM, NONAME, NOTFOUND, REFUSED, SERVFAIL, TIMEOUT, V4MAPPED } from "node:dns";
|
|
13
|
-
import { EACCES, EADDRINUSE, EADDRNOTAVAIL, EALREADY, EBADF, ECONNABORTED, ECONNREFUSED, ECONNRESET, EINVAL, ENOBUFS, ENOMEM, ENOTCONN, ENOTSUP, EPERM, EWOULDBLOCK } from "node:constants";
|
|
13
|
+
import { EACCES, EADDRINUSE, EADDRNOTAVAIL, EALREADY, EBADF, ECONNABORTED, ECONNREFUSED, ECONNRESET, EHOSTUNREACH, EINVAL, EMFILE, EMSGSIZE, ENETDOWN, ENETUNREACH, ENFILE, ENOBUFS, ENOMEM, ENOTCONN, ENOTSUP, EPERM, EWOULDBLOCK } from "node:constants";
|
|
14
14
|
//#region \0rolldown/runtime.js
|
|
15
15
|
var __defProp = Object.defineProperty;
|
|
16
16
|
var __exportAll = (all, no_symbols) => {
|
|
@@ -611,11 +611,18 @@ function convertSocketError(err) {
|
|
|
611
611
|
case "ENOBUFS": return "out-of-memory";
|
|
612
612
|
case "EALREADY": return "concurrency-conflict";
|
|
613
613
|
case "EWOULDBLOCK": return "would-block";
|
|
614
|
+
case "EMFILE":
|
|
615
|
+
case "ENFILE": return "new-socket-limit";
|
|
614
616
|
case "EADDRNOTAVAIL": return "address-not-bindable";
|
|
615
617
|
case "EADDRINUSE": return "address-in-use";
|
|
618
|
+
case "EHOSTUNREACH":
|
|
619
|
+
case "EHOSTDOWN":
|
|
620
|
+
case "ENETUNREACH":
|
|
621
|
+
case "ENETDOWN": return "remote-unreachable";
|
|
616
622
|
case "ECONNREFUSED": return "connection-refused";
|
|
617
623
|
case "ECONNRESET": return "connection-reset";
|
|
618
624
|
case "ECONNABORTED": return "connection-aborted";
|
|
625
|
+
case "EMSGSIZE": return "datagram-too-large";
|
|
619
626
|
default: return "unknown";
|
|
620
627
|
}
|
|
621
628
|
}
|
|
@@ -633,13 +640,19 @@ function convertSocketErrorCode(code) {
|
|
|
633
640
|
case ENOBUFS: return "out-of-memory";
|
|
634
641
|
case EALREADY: return "concurrency-conflict";
|
|
635
642
|
case EWOULDBLOCK: return "would-block";
|
|
643
|
+
case EMFILE:
|
|
644
|
+
case ENFILE: return "new-socket-limit";
|
|
636
645
|
case 4090:
|
|
637
646
|
case EADDRNOTAVAIL: return "address-not-bindable";
|
|
638
647
|
case 4091:
|
|
639
648
|
case EADDRINUSE: return "address-in-use";
|
|
649
|
+
case EHOSTUNREACH:
|
|
650
|
+
case ENETUNREACH:
|
|
651
|
+
case ENETDOWN: return "remote-unreachable";
|
|
640
652
|
case ECONNREFUSED: return "connection-refused";
|
|
641
653
|
case ECONNRESET: return "connection-reset";
|
|
642
654
|
case ECONNABORTED: return "connection-aborted";
|
|
655
|
+
case EMSGSIZE: return "datagram-too-large";
|
|
643
656
|
default: return "unknown";
|
|
644
657
|
}
|
|
645
658
|
}
|
|
@@ -687,13 +700,14 @@ function ipv4ToTuple(ipv4) {
|
|
|
687
700
|
return ipv4.split(".").map((segment) => parseInt(segment, 10));
|
|
688
701
|
}
|
|
689
702
|
function ipSocketAddress(family, addr, port) {
|
|
690
|
-
if (family === "ipv4") return {
|
|
703
|
+
if (family === "ipv4" || family === "IPv4" || family === 4) return {
|
|
691
704
|
tag: "ipv4",
|
|
692
705
|
val: {
|
|
693
706
|
port,
|
|
694
707
|
address: ipv4ToTuple(addr)
|
|
695
708
|
}
|
|
696
709
|
};
|
|
710
|
+
if (family !== "ipv6" && family !== "IPv6" && family !== 6) throw "invalid-argument";
|
|
697
711
|
return {
|
|
698
712
|
tag: "ipv6",
|
|
699
713
|
val: {
|
|
@@ -789,7 +803,7 @@ function socketTcpBindStart(id, localAddress, family) {
|
|
|
789
803
|
reject("invalid-state");
|
|
790
804
|
return;
|
|
791
805
|
}
|
|
792
|
-
socket.localAddress = ipSocketAddress(boundAddress.family
|
|
806
|
+
socket.localAddress = ipSocketAddress(boundAddress.family, boundAddress.address, boundAddress.port);
|
|
793
807
|
resolve();
|
|
794
808
|
}
|
|
795
809
|
server.once("listening", handleListen);
|
|
@@ -915,14 +929,14 @@ function socketTcpSetListenBacklogSize(id, backlogSize) {
|
|
|
915
929
|
function socketTcpGetLocalAddress(id) {
|
|
916
930
|
const socket = tcpSockets.get(id);
|
|
917
931
|
const address = socket.tcpSocket?.address();
|
|
918
|
-
if (address && typeof address !== "string" && "family" in address) return ipSocketAddress(address.family
|
|
932
|
+
if (address && typeof address !== "string" && "family" in address) return ipSocketAddress(address.family, address.address, address.port);
|
|
919
933
|
if (socket.localAddress) return socket.localAddress;
|
|
920
934
|
throw "invalid-state";
|
|
921
935
|
}
|
|
922
936
|
function socketTcpGetRemoteAddress(id) {
|
|
923
937
|
const { tcpSocket } = tcpSockets.get(id);
|
|
924
938
|
if (!tcpSocket?.remoteFamily || !tcpSocket.remoteAddress || !tcpSocket.remotePort) throw "invalid-state";
|
|
925
|
-
return ipSocketAddress(tcpSocket.remoteFamily
|
|
939
|
+
return ipSocketAddress(tcpSocket.remoteFamily, tcpSocket.remoteAddress, tcpSocket.remotePort);
|
|
926
940
|
}
|
|
927
941
|
function socketTcpShutdown(id, _shutdownType) {
|
|
928
942
|
const socket = tcpSockets.get(id);
|
|
@@ -1000,10 +1014,9 @@ function createIncomingDatagramStream(socket) {
|
|
|
1000
1014
|
udpSocket.off("error", onError);
|
|
1001
1015
|
}
|
|
1002
1016
|
function onMessage(data, rinfo) {
|
|
1003
|
-
const family = rinfo.family.toLowerCase();
|
|
1004
1017
|
datagramStream.queue?.push({
|
|
1005
1018
|
data,
|
|
1006
|
-
remoteAddress: ipSocketAddress(family, rinfo.address, rinfo.port)
|
|
1019
|
+
remoteAddress: ipSocketAddress(rinfo.family, rinfo.address, rinfo.port)
|
|
1007
1020
|
});
|
|
1008
1021
|
if (!pollState.ready) pollStateReady(pollState);
|
|
1009
1022
|
}
|
|
@@ -1089,7 +1102,7 @@ function socketUdpGetLocalAddress(id) {
|
|
|
1089
1102
|
} catch (err) {
|
|
1090
1103
|
throw convertSocketError(err);
|
|
1091
1104
|
}
|
|
1092
|
-
return ipSocketAddress(family
|
|
1105
|
+
return ipSocketAddress(family, address, port);
|
|
1093
1106
|
}
|
|
1094
1107
|
/**
|
|
1095
1108
|
* @param {number} id
|
|
@@ -1103,7 +1116,7 @@ function socketUdpGetRemoteAddress(id) {
|
|
|
1103
1116
|
} catch (err) {
|
|
1104
1117
|
throw convertSocketError(err);
|
|
1105
1118
|
}
|
|
1106
|
-
return ipSocketAddress(family
|
|
1119
|
+
return ipSocketAddress(family, address, port);
|
|
1107
1120
|
}
|
|
1108
1121
|
function socketUdpStream(id, remoteAddress) {
|
|
1109
1122
|
const socket = udpSockets.get(id);
|
|
@@ -75,6 +75,13 @@ declare class Descriptor implements IDescriptor {
|
|
|
75
75
|
}
|
|
76
76
|
export declare const preopens: typeof PreopensNamespace;
|
|
77
77
|
export declare const types: typeof TypesNamespace;
|
|
78
|
+
/** Create isolated filesystem namespaces from Node.js host-path preopens. */
|
|
79
|
+
export declare function createFilesystem({ preopens }: {
|
|
80
|
+
preopens: Record<string, string>;
|
|
81
|
+
}): {
|
|
82
|
+
types: typeof TypesNamespace;
|
|
83
|
+
preopens: typeof PreopensNamespace;
|
|
84
|
+
};
|
|
78
85
|
/**
|
|
79
86
|
* Replace all preopens with the given set.
|
|
80
87
|
* @param {Record<string, string>} preopens - Map of virtual paths to host paths
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { earlyDispose, inputStreamCreate, ioCall, outputStreamCreate, registerDispose, } from "../io/worker-io.js";
|
|
2
2
|
import { FILE, FILESYSTEM_DESCRIPTOR_ADVISE, FILESYSTEM_DESCRIPTOR_CLOSE, FILESYSTEM_DESCRIPTOR_GET_TYPE, FILESYSTEM_DESCRIPTOR_METADATA_HASH, FILESYSTEM_DESCRIPTOR_OPEN, FILESYSTEM_DESCRIPTOR_READ, FILESYSTEM_DESCRIPTOR_SET_SIZE, FILESYSTEM_DESCRIPTOR_SET_TIMES, FILESYSTEM_DESCRIPTOR_STAT, FILESYSTEM_DESCRIPTOR_SYNC, FILESYSTEM_DESCRIPTOR_SYNC_DATA, FILESYSTEM_DESCRIPTOR_WRITE, INPUT_STREAM_CREATE, OUTPUT_STREAM_CREATE, } from "../io/calls.js";
|
|
3
|
-
import { constants, linkSync, lstatSync, lutimesSync, mkdirSync, opendirSync, readlinkSync, renameSync, rmdirSync, statSync, symlinkSync, unlinkSync, utimesSync, } from "node:fs";
|
|
3
|
+
import { constants, linkSync, lstatSync, lutimesSync, mkdirSync, opendirSync, readlinkSync, realpathSync, renameSync, rmdirSync, statSync, symlinkSync, unlinkSync, utimesSync, } from "node:fs";
|
|
4
4
|
import { platform } from "node:process";
|
|
5
5
|
const symbolDispose = Symbol.dispose || Symbol.for("dispose");
|
|
6
6
|
const isWindows = platform === "win32";
|
|
@@ -226,7 +226,7 @@ class Descriptor {
|
|
|
226
226
|
}
|
|
227
227
|
}
|
|
228
228
|
createDirectoryAt(path) {
|
|
229
|
-
const fullPath = this.#getFullPath(path
|
|
229
|
+
const fullPath = this.#getFullPath(path);
|
|
230
230
|
try {
|
|
231
231
|
mkdirSync(fullPath);
|
|
232
232
|
}
|
|
@@ -256,7 +256,7 @@ class Descriptor {
|
|
|
256
256
|
};
|
|
257
257
|
}
|
|
258
258
|
statAt(pathFlags, path) {
|
|
259
|
-
const fullPath = this.#getFullPath(path
|
|
259
|
+
const fullPath = this.#getFullPath(path);
|
|
260
260
|
let stats;
|
|
261
261
|
try {
|
|
262
262
|
stats = (pathFlags.symlinkFollow ? statSync : lstatSync)(fullPath, {
|
|
@@ -277,7 +277,7 @@ class Descriptor {
|
|
|
277
277
|
};
|
|
278
278
|
}
|
|
279
279
|
setTimesAt(pathFlags, path, dataAccessTimestamp, dataModificationTimestamp) {
|
|
280
|
-
const fullPath = this.#getFullPath(path
|
|
280
|
+
const fullPath = this.#getFullPath(path);
|
|
281
281
|
let stats;
|
|
282
282
|
if (dataAccessTimestamp.tag === "no-change" ||
|
|
283
283
|
dataModificationTimestamp.tag === "no-change") {
|
|
@@ -297,14 +297,32 @@ class Descriptor {
|
|
|
297
297
|
}
|
|
298
298
|
}
|
|
299
299
|
linkAt(oldPathFlags, oldPath, newDescriptor, newPath) {
|
|
300
|
-
const oldFullPath = this.#getFullPath(oldPath
|
|
301
|
-
const newFullPath = newDescriptor.#getFullPath(newPath
|
|
300
|
+
const oldFullPath = this.#getFullPath(oldPath);
|
|
301
|
+
const newFullPath = newDescriptor.#getFullPath(newPath);
|
|
302
302
|
// Windows doesn't automatically fail on trailing slashes
|
|
303
303
|
if (isWindows && newFullPath.endsWith("/")) {
|
|
304
304
|
throw "no-entry";
|
|
305
305
|
}
|
|
306
306
|
try {
|
|
307
|
-
|
|
307
|
+
// Unlike open/stat, Node's link does not follow the final symlink.
|
|
308
|
+
// Resolve only this operation's source, propagating resolution errors
|
|
309
|
+
// instead of silently hard-linking a dangling or cyclic symlink.
|
|
310
|
+
let source = oldFullPath;
|
|
311
|
+
if (oldPathFlags.symlinkFollow) {
|
|
312
|
+
source = realpathSync(source);
|
|
313
|
+
// realpath strips trailing slashes; keep the caller's directory
|
|
314
|
+
// requirement so a regular-file source ending in '/' still fails.
|
|
315
|
+
if (oldFullPath.endsWith("/")) {
|
|
316
|
+
// Windows may ignore a trailing slash even in linkSync.
|
|
317
|
+
if (!statSync(source).isDirectory()) {
|
|
318
|
+
throw "not-directory";
|
|
319
|
+
}
|
|
320
|
+
if (!source.endsWith("/")) {
|
|
321
|
+
source += "/";
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
linkSync(source, newFullPath);
|
|
308
326
|
}
|
|
309
327
|
catch (e) {
|
|
310
328
|
throw convertFsError(e);
|
|
@@ -314,7 +332,7 @@ class Descriptor {
|
|
|
314
332
|
if (preopenEntries.length === 0) {
|
|
315
333
|
throw "access";
|
|
316
334
|
}
|
|
317
|
-
const fullPath = this.#getFullPath(path
|
|
335
|
+
const fullPath = this.#getFullPath(path);
|
|
318
336
|
let fsOpenFlags = 0x0;
|
|
319
337
|
if (openFlags.create) {
|
|
320
338
|
fsOpenFlags |= constants.O_CREAT;
|
|
@@ -384,6 +402,15 @@ class Descriptor {
|
|
|
384
402
|
path: fullPath.endsWith("/") ? fullPath.slice(0, -1) : fullPath,
|
|
385
403
|
flags: fsOpenFlags,
|
|
386
404
|
});
|
|
405
|
+
// Wasmtime's updated path_open_preopen test requires ISDIR for a
|
|
406
|
+
// writable directory on every platform.
|
|
407
|
+
//
|
|
408
|
+
// Windows may still open it, so check the returned descriptor type.
|
|
409
|
+
if (type === "directory" && descriptorFlags.write) {
|
|
410
|
+
// Release the opened handle before reporting the error.
|
|
411
|
+
closeFileResource(id);
|
|
412
|
+
throw "is-directory";
|
|
413
|
+
}
|
|
387
414
|
const descriptor = descriptorCreate(id, descriptorFlags, fullPath);
|
|
388
415
|
if (fullPath.endsWith("/") && type !== "directory") {
|
|
389
416
|
descriptor[symbolDispose]();
|
|
@@ -399,7 +426,7 @@ class Descriptor {
|
|
|
399
426
|
}
|
|
400
427
|
}
|
|
401
428
|
readlinkAt(path) {
|
|
402
|
-
const fullPath = this.#getFullPath(path
|
|
429
|
+
const fullPath = this.#getFullPath(path);
|
|
403
430
|
try {
|
|
404
431
|
return readlinkSync(fullPath);
|
|
405
432
|
}
|
|
@@ -408,7 +435,7 @@ class Descriptor {
|
|
|
408
435
|
}
|
|
409
436
|
}
|
|
410
437
|
removeDirectoryAt(path) {
|
|
411
|
-
const fullPath = this.#getFullPath(path
|
|
438
|
+
const fullPath = this.#getFullPath(path);
|
|
412
439
|
try {
|
|
413
440
|
rmdirSync(fullPath);
|
|
414
441
|
}
|
|
@@ -420,8 +447,8 @@ class Descriptor {
|
|
|
420
447
|
}
|
|
421
448
|
}
|
|
422
449
|
renameAt(oldPath, newDescriptor, newPath) {
|
|
423
|
-
const oldFullPath = this.#getFullPath(oldPath
|
|
424
|
-
const newFullPath = newDescriptor.#getFullPath(newPath
|
|
450
|
+
const oldFullPath = this.#getFullPath(oldPath);
|
|
451
|
+
const newFullPath = newDescriptor.#getFullPath(newPath);
|
|
425
452
|
try {
|
|
426
453
|
renameSync(oldFullPath, newFullPath);
|
|
427
454
|
}
|
|
@@ -433,7 +460,7 @@ class Descriptor {
|
|
|
433
460
|
}
|
|
434
461
|
}
|
|
435
462
|
symlinkAt(target, path) {
|
|
436
|
-
const fullPath = this.#getFullPath(path
|
|
463
|
+
const fullPath = this.#getFullPath(path);
|
|
437
464
|
if (target.startsWith("/")) {
|
|
438
465
|
throw "not-permitted";
|
|
439
466
|
}
|
|
@@ -462,7 +489,7 @@ class Descriptor {
|
|
|
462
489
|
}
|
|
463
490
|
}
|
|
464
491
|
unlinkFileAt(path) {
|
|
465
|
-
const fullPath = this.#getFullPath(path
|
|
492
|
+
const fullPath = this.#getFullPath(path);
|
|
466
493
|
try {
|
|
467
494
|
if (fullPath.endsWith("/")) {
|
|
468
495
|
let isDir = false;
|
|
@@ -504,7 +531,7 @@ class Descriptor {
|
|
|
504
531
|
}
|
|
505
532
|
}
|
|
506
533
|
metadataHashAt(pathFlags, path) {
|
|
507
|
-
const fullPath = this.#getFullPath(path
|
|
534
|
+
const fullPath = this.#getFullPath(path);
|
|
508
535
|
try {
|
|
509
536
|
const stats = (pathFlags.symlinkFollow ? statSync : lstatSync)(fullPath, {
|
|
510
537
|
bigint: true,
|
|
@@ -515,8 +542,8 @@ class Descriptor {
|
|
|
515
542
|
throw convertFsError(e);
|
|
516
543
|
}
|
|
517
544
|
}
|
|
518
|
-
//
|
|
519
|
-
#getFullPath(subpath
|
|
545
|
+
// Join paths lexically; each operation supplies its own symlink semantics.
|
|
546
|
+
#getFullPath(subpath) {
|
|
520
547
|
let descriptor = this;
|
|
521
548
|
if (subpath.indexOf("\\") !== -1) {
|
|
522
549
|
subpath = subpath.replace(/\\/g, "/");
|
|
@@ -567,12 +594,18 @@ class Descriptor {
|
|
|
567
594
|
segments.push(subpath.slice(segmentIndex));
|
|
568
595
|
}
|
|
569
596
|
subpath = segments.join("");
|
|
570
|
-
|
|
571
|
-
|
|
597
|
+
// The default Windows preopen represents all drives.
|
|
598
|
+
//
|
|
599
|
+
// Convert drive paths to namespaced paths so joining them to the preopen
|
|
600
|
+
// does not produce an invalid UNC server name such as //C:/Users/...
|
|
601
|
+
if (isWindows && descriptor.#hostPreopen === "//" && /^[a-zA-Z]:\//.test(subpath)) {
|
|
602
|
+
return "//?/" + subpath;
|
|
603
|
+
}
|
|
604
|
+
return descriptor.#hostPreopen
|
|
605
|
+
? descriptor.#hostPreopen +
|
|
572
606
|
(descriptor.#hostPreopen.endsWith("/") ? "" : subpath.length > 0 ? "/" : "") +
|
|
573
|
-
subpath
|
|
574
|
-
|
|
575
|
-
return descriptor.#fullPath + (subpath.length > 0 ? "/" : "") + subpath;
|
|
607
|
+
subpath
|
|
608
|
+
: descriptor.#fullPath + (subpath.length > 0 ? "/" : "") + subpath;
|
|
576
609
|
}
|
|
577
610
|
}
|
|
578
611
|
const descriptorCreatePreopen = Descriptor._createPreopen;
|
|
@@ -629,6 +662,16 @@ export const types = {
|
|
|
629
662
|
return convertFsError(err.payload);
|
|
630
663
|
},
|
|
631
664
|
};
|
|
665
|
+
/** Create isolated filesystem namespaces from Node.js host-path preopens. */
|
|
666
|
+
export function createFilesystem({ preopens }) {
|
|
667
|
+
const entries = Object.entries(preopens).map(([virtualPath, hostPath]) => [descriptorCreatePreopen(hostPath), virtualPath]);
|
|
668
|
+
return {
|
|
669
|
+
types,
|
|
670
|
+
preopens: {
|
|
671
|
+
getDirectories: () => [...entries],
|
|
672
|
+
},
|
|
673
|
+
};
|
|
674
|
+
}
|
|
632
675
|
/**
|
|
633
676
|
* Replace all preopens with the given set.
|
|
634
677
|
* @param {Record<string, string>} preopens - Map of virtual paths to host paths
|
package/dist/nodejs/sockets.d.ts
CHANGED
|
@@ -18,4 +18,17 @@ export declare const tcpCreateSocket: typeof TcpCreateSocketNamespace;
|
|
|
18
18
|
export declare const tcp: typeof TcpNamespace;
|
|
19
19
|
export declare const udpCreateSocket: typeof UdpCreateSocketNamespace;
|
|
20
20
|
export declare const udp: typeof UdpNamespace;
|
|
21
|
+
export interface SocketsConfig {
|
|
22
|
+
enableNetwork?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/** Create socket namespaces with an instance-local network capability. */
|
|
25
|
+
export declare function createSockets(config?: SocketsConfig): {
|
|
26
|
+
instanceNetwork: typeof InstanceNetworkNamespace;
|
|
27
|
+
network: typeof NetworkNamespace;
|
|
28
|
+
ipNameLookup: typeof IpNameLookupNamespace;
|
|
29
|
+
tcpCreateSocket: typeof TcpCreateSocketNamespace;
|
|
30
|
+
tcp: typeof TcpNamespace;
|
|
31
|
+
udpCreateSocket: typeof UdpCreateSocketNamespace;
|
|
32
|
+
udp: typeof UdpNamespace;
|
|
33
|
+
};
|
|
21
34
|
export {};
|
package/dist/nodejs/sockets.js
CHANGED
|
@@ -480,3 +480,23 @@ export const udp = {
|
|
|
480
480
|
OutgoingDatagramStream,
|
|
481
481
|
IncomingDatagramStream,
|
|
482
482
|
};
|
|
483
|
+
/** Create socket namespaces with an instance-local network capability. */
|
|
484
|
+
export function createSockets(config = {}) {
|
|
485
|
+
const localNetwork = new Network();
|
|
486
|
+
if (config.enableNetwork === false) {
|
|
487
|
+
_denyDnsLookup(localNetwork);
|
|
488
|
+
_denyTcp(localNetwork);
|
|
489
|
+
_denyUdp(localNetwork);
|
|
490
|
+
}
|
|
491
|
+
return {
|
|
492
|
+
instanceNetwork: {
|
|
493
|
+
instanceNetwork: () => localNetwork,
|
|
494
|
+
},
|
|
495
|
+
network,
|
|
496
|
+
ipNameLookup,
|
|
497
|
+
tcpCreateSocket,
|
|
498
|
+
tcp,
|
|
499
|
+
udpCreateSocket,
|
|
500
|
+
udp,
|
|
501
|
+
};
|
|
502
|
+
}
|
package/package.json
CHANGED
package/types/instantiation.d.ts
CHANGED
|
@@ -43,6 +43,7 @@ type _WASIImportObject = {
|
|
|
43
43
|
'wasi:clocks/wall-clock': typeof import('./interfaces/wasi-clocks-wall-clock.d.ts');
|
|
44
44
|
|
|
45
45
|
'wasi:http/types': typeof import('./interfaces/wasi-http-types.d.ts');
|
|
46
|
+
'wasi:http/incoming-handler': typeof import('./interfaces/wasi-http-incoming-handler.d.ts');
|
|
46
47
|
'wasi:http/outgoing-handler': typeof import('./interfaces/wasi-http-outgoing-handler.d.ts');
|
|
47
48
|
};
|
|
48
49
|
|
|
@@ -53,10 +54,7 @@ type VersionedWASIImportObject<V extends string> = {
|
|
|
53
54
|
};
|
|
54
55
|
|
|
55
56
|
/** Used to append versions to generated WASI import objects */
|
|
56
|
-
type AppendVersion<
|
|
57
|
-
Key extends string | number | symbol,
|
|
58
|
-
Version extends string,
|
|
59
|
-
> = Version extends ''
|
|
57
|
+
type AppendVersion<Key extends string | number | symbol, Version extends string> = Version extends ''
|
|
60
58
|
? Key
|
|
61
59
|
: Version extends `${infer V}`
|
|
62
60
|
? Key extends `${infer K}`
|
|
@@ -68,8 +66,8 @@ type AppendVersion<
|
|
|
68
66
|
* Sandbox configuration options for WASIShim
|
|
69
67
|
*/
|
|
70
68
|
interface SandboxConfig {
|
|
71
|
-
/** Filesystem preopens mapping (virtual path -> host path) */
|
|
72
|
-
preopens?: Record<string,
|
|
69
|
+
/** Filesystem-specific preopens mapping (virtual path -> host path or capability). */
|
|
70
|
+
preopens?: Record<string, unknown>;
|
|
73
71
|
/** Environment variables visible to the guest */
|
|
74
72
|
env?: Record<string, string>;
|
|
75
73
|
/** Command-line arguments */
|
|
@@ -78,14 +76,49 @@ interface SandboxConfig {
|
|
|
78
76
|
enableNetwork?: boolean;
|
|
79
77
|
}
|
|
80
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Application-provided implementation of the two `wasi:filesystem` namespaces.
|
|
81
|
+
* Browser applications can use this boundary to select their own storage and
|
|
82
|
+
* permission model without the shim choosing a filesystem implementation.
|
|
83
|
+
*/
|
|
84
|
+
export interface FilesystemShim {
|
|
85
|
+
preopens: typeof import('./interfaces/wasi-filesystem-preopens.d.ts');
|
|
86
|
+
types: typeof import('./interfaces/wasi-filesystem-types.d.ts');
|
|
87
|
+
/** Interpret sandbox preopen properties and return this filesystem's preopens namespace. */
|
|
88
|
+
createPreopens?(
|
|
89
|
+
preopens: Record<string, unknown>,
|
|
90
|
+
): typeof import('./interfaces/wasi-filesystem-preopens.d.ts');
|
|
91
|
+
dispose?(): void;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Application-provided implementation of the WASI TCP namespaces. */
|
|
95
|
+
export interface TcpSocketsShim {
|
|
96
|
+
tcp: typeof import('./interfaces/wasi-sockets-tcp.d.ts');
|
|
97
|
+
tcpCreateSocket: typeof import('./interfaces/wasi-sockets-tcp-create-socket.d.ts');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Application-provided implementation of the WASI UDP namespaces. */
|
|
101
|
+
export interface UdpSocketsShim {
|
|
102
|
+
udp: typeof import('./interfaces/wasi-sockets-udp.d.ts');
|
|
103
|
+
udpCreateSocket: typeof import('./interfaces/wasi-sockets-udp-create-socket.d.ts');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Browser HTTP handler using standard Web Request and Response objects. */
|
|
107
|
+
export type WebIncomingHandler = (request: Request) => Response | Promise<Response>;
|
|
108
|
+
|
|
81
109
|
/**
|
|
82
110
|
* Configuration options for WASIShim
|
|
83
111
|
*/
|
|
84
112
|
interface WASIShimConfig {
|
|
85
113
|
/** Custom CLI shim */
|
|
86
114
|
cli?: object;
|
|
87
|
-
/**
|
|
88
|
-
filesystem?:
|
|
115
|
+
/** Application-provided filesystem namespaces. */
|
|
116
|
+
filesystem?: FilesystemShim;
|
|
117
|
+
/** Explicit ephemeral browser file-data adapter and guest-path mappings. */
|
|
118
|
+
browserFilesystem?: {
|
|
119
|
+
adapter: object;
|
|
120
|
+
preopens: Record<string, unknown>;
|
|
121
|
+
};
|
|
89
122
|
/** Custom I/O shim */
|
|
90
123
|
io?: object;
|
|
91
124
|
/** Custom random shim */
|
|
@@ -94,8 +127,26 @@ interface WASIShimConfig {
|
|
|
94
127
|
clocks?: object;
|
|
95
128
|
/** Custom sockets shim */
|
|
96
129
|
sockets?: object;
|
|
130
|
+
/** Custom TCP socket namespaces. */
|
|
131
|
+
tcpSockets?: TcpSocketsShim;
|
|
132
|
+
/** Custom UDP socket namespaces. */
|
|
133
|
+
udpSockets?: UdpSocketsShim;
|
|
97
134
|
/** Custom HTTP shim */
|
|
98
135
|
http?: object;
|
|
136
|
+
/** Browser incoming HTTP handler. */
|
|
137
|
+
incomingHandler?: WebIncomingHandler;
|
|
138
|
+
/** Browser-only isolated environment variables. */
|
|
139
|
+
environment?: Record<string, string>;
|
|
140
|
+
/** Browser-only isolated command-line arguments. */
|
|
141
|
+
arguments?: string[];
|
|
142
|
+
/** Browser-only initial working directory. */
|
|
143
|
+
initialCwd?: string;
|
|
144
|
+
/** Browser input stream handler. */
|
|
145
|
+
stdin?: object;
|
|
146
|
+
/** Browser output stream handler. */
|
|
147
|
+
stdout?: object;
|
|
148
|
+
/** Browser error stream handler. */
|
|
149
|
+
stderr?: object;
|
|
99
150
|
/** Sandbox configuration for restricting guest capabilities */
|
|
100
151
|
sandbox?: SandboxConfig;
|
|
101
152
|
}
|
|
@@ -160,7 +211,7 @@ interface WASIShimConfig {
|
|
|
160
211
|
* }
|
|
161
212
|
* });
|
|
162
213
|
*
|
|
163
|
-
* //
|
|
214
|
+
* // Node.js only: limited host filesystem access
|
|
164
215
|
* const limitedShim = new WASIShim({
|
|
165
216
|
* sandbox: {
|
|
166
217
|
* preopens: {
|
|
@@ -171,6 +222,9 @@ interface WASIShimConfig {
|
|
|
171
222
|
* });
|
|
172
223
|
* ```
|
|
173
224
|
*
|
|
225
|
+
* Browser applications should inject `filesystem` namespaces or explicitly
|
|
226
|
+
* configure `browserFilesystem`; browser preopens never interpret host paths.
|
|
227
|
+
*
|
|
174
228
|
* Note that this object is similar but not identical to the Node `WASI` object --
|
|
175
229
|
* it is solely concerned with shimming of preview2 when dealing with a WebAssembly
|
|
176
230
|
* component transpiled by Jco. While this object *does* work with Node (and the browser)
|
|
@@ -189,9 +243,7 @@ export class WASIShim {
|
|
|
189
243
|
* @param {options} [opt]
|
|
190
244
|
* @returns {object}
|
|
191
245
|
*/
|
|
192
|
-
getImportObject<V extends string = ''>(
|
|
193
|
-
opts?: GetImportObjectArgs
|
|
194
|
-
): VersionedWASIImportObject<V>;
|
|
246
|
+
getImportObject<V extends string = ''>(opts?: GetImportObjectArgs): VersionedWASIImportObject<V>;
|
|
195
247
|
}
|
|
196
248
|
|
|
197
249
|
interface GetImportObjectArgs {
|