sandboxedjs 0.1.97 → 0.1.99
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.cjs +19 -16
- package/dist/index.d.cts +36 -12
- package/dist/index.d.ts +36 -12
- package/dist/index.js +19 -16
- package/dist/python-worker.js +2 -1
- package/dist/service-worker.js +21 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4273,7 +4273,8 @@ function md5Hex(input) {
|
|
|
4273
4273
|
var isNode, zlibPromise, cryptoPromise, SUBTLE_NAMES, UnsupportedAlgorithmError;
|
|
4274
4274
|
var init_binary = __esm({
|
|
4275
4275
|
"src/util/binary.ts"() {
|
|
4276
|
-
isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null
|
|
4276
|
+
isNode = typeof window === "undefined" && typeof document === "undefined" && typeof process !== "undefined" && process.versions != null && process.versions.node != null && /* A shim has no `release.name`, and Node's has said "node" since v3. */
|
|
4277
|
+
process.release?.name === "node";
|
|
4277
4278
|
zlibPromise = null;
|
|
4278
4279
|
cryptoPromise = null;
|
|
4279
4280
|
SUBTLE_NAMES = {
|
|
@@ -20958,7 +20959,7 @@ var wheels_default = {
|
|
|
20958
20959
|
|
|
20959
20960
|
// package.json
|
|
20960
20961
|
var package_default = {
|
|
20961
|
-
version: "0.1.
|
|
20962
|
+
version: "0.1.99"};
|
|
20962
20963
|
|
|
20963
20964
|
// src/python/extension-abi.ts
|
|
20964
20965
|
var EXTENSION_ABI = {
|
|
@@ -38658,6 +38659,22 @@ var WS_DATA = "sandboxedjs:ws-data";
|
|
|
38658
38659
|
var WS_CLOSE = "sandboxedjs:ws-close";
|
|
38659
38660
|
var WS_ERROR = "sandboxedjs:ws-error";
|
|
38660
38661
|
|
|
38662
|
+
// src/preview/router.ts
|
|
38663
|
+
var LOOPBACK_HOST = /^(?:localhost|127(?:\.\d{1,3}){3}|0\.0\.0\.0|\[?::1\]?)$/i;
|
|
38664
|
+
function containerTarget(value) {
|
|
38665
|
+
let url;
|
|
38666
|
+
try {
|
|
38667
|
+
url = new URL(value.trim());
|
|
38668
|
+
} catch {
|
|
38669
|
+
return null;
|
|
38670
|
+
}
|
|
38671
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") return null;
|
|
38672
|
+
if (!LOOPBACK_HOST.test(url.hostname)) return null;
|
|
38673
|
+
const port = Number(url.port || (url.protocol === "https:" ? 443 : 80));
|
|
38674
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) return null;
|
|
38675
|
+
return { port, path: `${url.pathname}${url.search}` };
|
|
38676
|
+
}
|
|
38677
|
+
|
|
38661
38678
|
// src/preview/register.ts
|
|
38662
38679
|
function serveContainerOn(port, box) {
|
|
38663
38680
|
port.onmessage = async (event) => {
|
|
@@ -38692,20 +38709,6 @@ function serveContainerOn(port, box) {
|
|
|
38692
38709
|
};
|
|
38693
38710
|
port.start?.();
|
|
38694
38711
|
}
|
|
38695
|
-
var LOOPBACK_HOST = /^(?:localhost|127(?:\.\d{1,3}){3}|0\.0\.0\.0|\[?::1\]?)$/i;
|
|
38696
|
-
function containerTarget(value) {
|
|
38697
|
-
let url;
|
|
38698
|
-
try {
|
|
38699
|
-
url = new URL(value.trim());
|
|
38700
|
-
} catch {
|
|
38701
|
-
return null;
|
|
38702
|
-
}
|
|
38703
|
-
if (url.protocol !== "http:" && url.protocol !== "https:") return null;
|
|
38704
|
-
if (!LOOPBACK_HOST.test(url.hostname)) return null;
|
|
38705
|
-
const port = Number(url.port || (url.protocol === "https:" ? 443 : 80));
|
|
38706
|
-
if (!Number.isInteger(port) || port < 1 || port > 65535) return null;
|
|
38707
|
-
return { port, path: `${url.pathname}${url.search}` };
|
|
38708
|
-
}
|
|
38709
38712
|
async function createPreview(box, options = {}) {
|
|
38710
38713
|
if (typeof navigator === "undefined" || !("serviceWorker" in navigator)) return null;
|
|
38711
38714
|
const scriptUrl = options.scriptUrl ?? new URL("./service-worker.js?no-inline", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
|
package/dist/index.d.cts
CHANGED
|
@@ -1590,19 +1590,22 @@ declare function startRuntimeWorker(options?: {
|
|
|
1590
1590
|
declare function syncChannelSupported(): boolean;
|
|
1591
1591
|
|
|
1592
1592
|
/**
|
|
1593
|
-
*
|
|
1593
|
+
* The routing a preview service worker does, separated from the worker itself.
|
|
1594
1594
|
*
|
|
1595
|
-
*
|
|
1596
|
-
*
|
|
1595
|
+
* A service worker is awkward to test — it needs a browser, a registration and
|
|
1596
|
+
* a secure context — but almost none of what makes this correct is about being
|
|
1597
|
+
* a service worker. The interesting part is the bookkeeping: which client is
|
|
1598
|
+
* previewing which port, which requests belong to a preview at all, and how a
|
|
1599
|
+
* response is rebuilt on the way back. That lives here, where it can be
|
|
1600
|
+
* exercised directly.
|
|
1597
1601
|
*
|
|
1598
|
-
*
|
|
1599
|
-
*
|
|
1600
|
-
*
|
|
1601
|
-
*
|
|
1602
|
-
*
|
|
1603
|
-
*
|
|
1602
|
+
* The rule this implements, and the reason it exists: requests are routed by
|
|
1603
|
+
* **who is asking**, not by what the path looks like. An iframe navigates once
|
|
1604
|
+
* to `/__sbx__/<port>/`; every later request from that client — however
|
|
1605
|
+
* absolute its path — is recognised by its client id. Nothing has to rewrite
|
|
1606
|
+
* `/src/main.js` or `/@vite/client`, which is what makes a real dev server
|
|
1607
|
+
* work rather than only a single page.
|
|
1604
1608
|
*/
|
|
1605
|
-
|
|
1606
1609
|
/** A container-local server, named by port rather than by an address. */
|
|
1607
1610
|
interface ContainerTarget {
|
|
1608
1611
|
port: number;
|
|
@@ -1618,10 +1621,31 @@ interface ContainerTarget {
|
|
|
1618
1621
|
* is listening, so a frame pointed at it fails with "refused to connect"
|
|
1619
1622
|
* rather than failing visibly as a routing mistake.
|
|
1620
1623
|
*
|
|
1621
|
-
*
|
|
1622
|
-
*
|
|
1624
|
+
* The same translation serves two callers. A host reading an address out of a
|
|
1625
|
+
* build log needs it to point a frame somewhere (`Preview.resolve`), and the
|
|
1626
|
+
* service worker needs it for the other direction: a page *inside* a preview
|
|
1627
|
+
* asking its own backend for `http://localhost:8000/api` means the container's
|
|
1628
|
+
* port 8000, not the reader's machine.
|
|
1629
|
+
*
|
|
1630
|
+
* Kept pure, and kept here rather than beside the host half, because the
|
|
1631
|
+
* worker bundles this module and not that one.
|
|
1623
1632
|
*/
|
|
1624
1633
|
declare function containerTarget(value: string): ContainerTarget | null;
|
|
1634
|
+
|
|
1635
|
+
/**
|
|
1636
|
+
* Wiring a container's HTTP servers up to real URLs in the page.
|
|
1637
|
+
*
|
|
1638
|
+
* The service worker does the routing; this is the half that lives in the page
|
|
1639
|
+
* and actually knows about the container.
|
|
1640
|
+
*
|
|
1641
|
+
* **Read the origin note before using this.** A preview served this way runs on
|
|
1642
|
+
* *your* origin, so scripts inside it can reach `window.parent`, your cookies
|
|
1643
|
+
* and your `localStorage` — the sandbox contains the program's *filesystem and
|
|
1644
|
+
* process table*, not the page it serves. For code you did not write, either
|
|
1645
|
+
* host the preview on a separate origin, or use {@link renderInto}, which puts
|
|
1646
|
+
* the response in an iframe with no origin at all.
|
|
1647
|
+
*/
|
|
1648
|
+
|
|
1625
1649
|
interface PreviewOptions {
|
|
1626
1650
|
/** Where the worker script lives; defaults to the copy shipped beside the bundle. */
|
|
1627
1651
|
scriptUrl?: string | URL;
|
package/dist/index.d.ts
CHANGED
|
@@ -1590,19 +1590,22 @@ declare function startRuntimeWorker(options?: {
|
|
|
1590
1590
|
declare function syncChannelSupported(): boolean;
|
|
1591
1591
|
|
|
1592
1592
|
/**
|
|
1593
|
-
*
|
|
1593
|
+
* The routing a preview service worker does, separated from the worker itself.
|
|
1594
1594
|
*
|
|
1595
|
-
*
|
|
1596
|
-
*
|
|
1595
|
+
* A service worker is awkward to test — it needs a browser, a registration and
|
|
1596
|
+
* a secure context — but almost none of what makes this correct is about being
|
|
1597
|
+
* a service worker. The interesting part is the bookkeeping: which client is
|
|
1598
|
+
* previewing which port, which requests belong to a preview at all, and how a
|
|
1599
|
+
* response is rebuilt on the way back. That lives here, where it can be
|
|
1600
|
+
* exercised directly.
|
|
1597
1601
|
*
|
|
1598
|
-
*
|
|
1599
|
-
*
|
|
1600
|
-
*
|
|
1601
|
-
*
|
|
1602
|
-
*
|
|
1603
|
-
*
|
|
1602
|
+
* The rule this implements, and the reason it exists: requests are routed by
|
|
1603
|
+
* **who is asking**, not by what the path looks like. An iframe navigates once
|
|
1604
|
+
* to `/__sbx__/<port>/`; every later request from that client — however
|
|
1605
|
+
* absolute its path — is recognised by its client id. Nothing has to rewrite
|
|
1606
|
+
* `/src/main.js` or `/@vite/client`, which is what makes a real dev server
|
|
1607
|
+
* work rather than only a single page.
|
|
1604
1608
|
*/
|
|
1605
|
-
|
|
1606
1609
|
/** A container-local server, named by port rather than by an address. */
|
|
1607
1610
|
interface ContainerTarget {
|
|
1608
1611
|
port: number;
|
|
@@ -1618,10 +1621,31 @@ interface ContainerTarget {
|
|
|
1618
1621
|
* is listening, so a frame pointed at it fails with "refused to connect"
|
|
1619
1622
|
* rather than failing visibly as a routing mistake.
|
|
1620
1623
|
*
|
|
1621
|
-
*
|
|
1622
|
-
*
|
|
1624
|
+
* The same translation serves two callers. A host reading an address out of a
|
|
1625
|
+
* build log needs it to point a frame somewhere (`Preview.resolve`), and the
|
|
1626
|
+
* service worker needs it for the other direction: a page *inside* a preview
|
|
1627
|
+
* asking its own backend for `http://localhost:8000/api` means the container's
|
|
1628
|
+
* port 8000, not the reader's machine.
|
|
1629
|
+
*
|
|
1630
|
+
* Kept pure, and kept here rather than beside the host half, because the
|
|
1631
|
+
* worker bundles this module and not that one.
|
|
1623
1632
|
*/
|
|
1624
1633
|
declare function containerTarget(value: string): ContainerTarget | null;
|
|
1634
|
+
|
|
1635
|
+
/**
|
|
1636
|
+
* Wiring a container's HTTP servers up to real URLs in the page.
|
|
1637
|
+
*
|
|
1638
|
+
* The service worker does the routing; this is the half that lives in the page
|
|
1639
|
+
* and actually knows about the container.
|
|
1640
|
+
*
|
|
1641
|
+
* **Read the origin note before using this.** A preview served this way runs on
|
|
1642
|
+
* *your* origin, so scripts inside it can reach `window.parent`, your cookies
|
|
1643
|
+
* and your `localStorage` — the sandbox contains the program's *filesystem and
|
|
1644
|
+
* process table*, not the page it serves. For code you did not write, either
|
|
1645
|
+
* host the preview on a separate origin, or use {@link renderInto}, which puts
|
|
1646
|
+
* the response in an iframe with no origin at all.
|
|
1647
|
+
*/
|
|
1648
|
+
|
|
1625
1649
|
interface PreviewOptions {
|
|
1626
1650
|
/** Where the worker script lives; defaults to the copy shipped beside the bundle. */
|
|
1627
1651
|
scriptUrl?: string | URL;
|
package/dist/index.js
CHANGED
|
@@ -4256,7 +4256,8 @@ function md5Hex(input) {
|
|
|
4256
4256
|
var isNode, zlibPromise, cryptoPromise, SUBTLE_NAMES, UnsupportedAlgorithmError;
|
|
4257
4257
|
var init_binary = __esm({
|
|
4258
4258
|
"src/util/binary.ts"() {
|
|
4259
|
-
isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null
|
|
4259
|
+
isNode = typeof window === "undefined" && typeof document === "undefined" && typeof process !== "undefined" && process.versions != null && process.versions.node != null && /* A shim has no `release.name`, and Node's has said "node" since v3. */
|
|
4260
|
+
process.release?.name === "node";
|
|
4260
4261
|
zlibPromise = null;
|
|
4261
4262
|
cryptoPromise = null;
|
|
4262
4263
|
SUBTLE_NAMES = {
|
|
@@ -20941,7 +20942,7 @@ var wheels_default = {
|
|
|
20941
20942
|
|
|
20942
20943
|
// package.json
|
|
20943
20944
|
var package_default = {
|
|
20944
|
-
version: "0.1.
|
|
20945
|
+
version: "0.1.99"};
|
|
20945
20946
|
|
|
20946
20947
|
// src/python/extension-abi.ts
|
|
20947
20948
|
var EXTENSION_ABI = {
|
|
@@ -38641,6 +38642,22 @@ var WS_DATA = "sandboxedjs:ws-data";
|
|
|
38641
38642
|
var WS_CLOSE = "sandboxedjs:ws-close";
|
|
38642
38643
|
var WS_ERROR = "sandboxedjs:ws-error";
|
|
38643
38644
|
|
|
38645
|
+
// src/preview/router.ts
|
|
38646
|
+
var LOOPBACK_HOST = /^(?:localhost|127(?:\.\d{1,3}){3}|0\.0\.0\.0|\[?::1\]?)$/i;
|
|
38647
|
+
function containerTarget(value) {
|
|
38648
|
+
let url;
|
|
38649
|
+
try {
|
|
38650
|
+
url = new URL(value.trim());
|
|
38651
|
+
} catch {
|
|
38652
|
+
return null;
|
|
38653
|
+
}
|
|
38654
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") return null;
|
|
38655
|
+
if (!LOOPBACK_HOST.test(url.hostname)) return null;
|
|
38656
|
+
const port = Number(url.port || (url.protocol === "https:" ? 443 : 80));
|
|
38657
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) return null;
|
|
38658
|
+
return { port, path: `${url.pathname}${url.search}` };
|
|
38659
|
+
}
|
|
38660
|
+
|
|
38644
38661
|
// src/preview/register.ts
|
|
38645
38662
|
function serveContainerOn(port, box) {
|
|
38646
38663
|
port.onmessage = async (event) => {
|
|
@@ -38675,20 +38692,6 @@ function serveContainerOn(port, box) {
|
|
|
38675
38692
|
};
|
|
38676
38693
|
port.start?.();
|
|
38677
38694
|
}
|
|
38678
|
-
var LOOPBACK_HOST = /^(?:localhost|127(?:\.\d{1,3}){3}|0\.0\.0\.0|\[?::1\]?)$/i;
|
|
38679
|
-
function containerTarget(value) {
|
|
38680
|
-
let url;
|
|
38681
|
-
try {
|
|
38682
|
-
url = new URL(value.trim());
|
|
38683
|
-
} catch {
|
|
38684
|
-
return null;
|
|
38685
|
-
}
|
|
38686
|
-
if (url.protocol !== "http:" && url.protocol !== "https:") return null;
|
|
38687
|
-
if (!LOOPBACK_HOST.test(url.hostname)) return null;
|
|
38688
|
-
const port = Number(url.port || (url.protocol === "https:" ? 443 : 80));
|
|
38689
|
-
if (!Number.isInteger(port) || port < 1 || port > 65535) return null;
|
|
38690
|
-
return { port, path: `${url.pathname}${url.search}` };
|
|
38691
|
-
}
|
|
38692
38695
|
async function createPreview(box, options = {}) {
|
|
38693
38696
|
if (typeof navigator === "undefined" || !("serviceWorker" in navigator)) return null;
|
|
38694
38697
|
const scriptUrl = options.scriptUrl ?? new URL("./service-worker.js?no-inline", import.meta.url);
|
package/dist/python-worker.js
CHANGED
|
@@ -772,7 +772,8 @@ function createSbxFs(FS, client, errnoCodes) {
|
|
|
772
772
|
}
|
|
773
773
|
|
|
774
774
|
// src/util/binary.ts
|
|
775
|
-
typeof process !== "undefined" && process.versions != null && process.versions.node != null
|
|
775
|
+
typeof window === "undefined" && typeof document === "undefined" && typeof process !== "undefined" && process.versions != null && process.versions.node != null && /* A shim has no `release.name`, and Node's has said "node" since v3. */
|
|
776
|
+
process.release?.name === "node";
|
|
776
777
|
async function nodeBuiltin(name) {
|
|
777
778
|
const specifier = `node:${name}`;
|
|
778
779
|
return await import(
|
package/dist/service-worker.js
CHANGED
|
@@ -349,6 +349,20 @@ function previewSocketSource() {
|
|
|
349
349
|
|
|
350
350
|
// src/preview/router.ts
|
|
351
351
|
var CLAIM = /(?:^|\/)__sbx__\/(\d+)(?:\/|$)/;
|
|
352
|
+
var LOOPBACK_HOST = /^(?:localhost|127(?:\.\d{1,3}){3}|0\.0\.0\.0|\[?::1\]?)$/i;
|
|
353
|
+
function containerTarget(value) {
|
|
354
|
+
let url;
|
|
355
|
+
try {
|
|
356
|
+
url = new URL(value.trim());
|
|
357
|
+
} catch {
|
|
358
|
+
return null;
|
|
359
|
+
}
|
|
360
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") return null;
|
|
361
|
+
if (!LOOPBACK_HOST.test(url.hostname)) return null;
|
|
362
|
+
const port = Number(url.port || (url.protocol === "https:" ? 443 : 80));
|
|
363
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) return null;
|
|
364
|
+
return { port, path: `${url.pathname}${url.search}` };
|
|
365
|
+
}
|
|
352
366
|
var OUTDATED = /outdated optimize dep/i;
|
|
353
367
|
var NOT_CONNECTED = 503;
|
|
354
368
|
var PreviewRouter = class {
|
|
@@ -549,7 +563,13 @@ worker.addEventListener("message", (event) => {
|
|
|
549
563
|
});
|
|
550
564
|
worker.addEventListener("fetch", (event) => {
|
|
551
565
|
const url = new URL(event.request.url);
|
|
552
|
-
if (url.origin !== worker.location.origin)
|
|
566
|
+
if (url.origin !== worker.location.origin) {
|
|
567
|
+
const port2 = router.portFor(event.clientId);
|
|
568
|
+
const target = port2 === void 0 ? null : containerTarget(url.href);
|
|
569
|
+
if (!target) return;
|
|
570
|
+
event.respondWith(router.fetch(target.port, target.path, event.request, event.clientId));
|
|
571
|
+
return;
|
|
572
|
+
}
|
|
553
573
|
const claimed = router.claimedPort(url.pathname);
|
|
554
574
|
if (claimed !== null && event.request.mode === "navigate") {
|
|
555
575
|
router.bind(event.resultingClientId || event.clientId, claimed);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sandboxedjs",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.99",
|
|
4
4
|
"description": "A Linux-like container that runs entirely inside Node.js — POSIX shell, ~140 coreutils, Node.js and Python runtimes, virtual filesystem and networking. No Docker, no VM, no native modules.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|