@cloudflare/sandbox 0.0.0-104f455 → 0.0.0-153e416
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/CHANGELOG.md +53 -0
- package/Dockerfile +6 -0
- package/dist/chunk-FE4PJSRB.js +7 -0
- package/dist/chunk-FE4PJSRB.js.map +1 -0
- package/dist/{chunk-2P3MDMNJ.js → chunk-SVWLTRHD.js} +94 -5
- package/dist/chunk-SVWLTRHD.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/interpreter.d.ts +1 -1
- package/dist/request-handler.d.ts +1 -1
- package/dist/request-handler.js +2 -1
- package/dist/{sandbox-CZTMzV2R.d.ts → sandbox-DWQVgVTY.d.ts} +21 -5
- package/dist/sandbox.d.ts +1 -1
- package/dist/sandbox.js +2 -1
- package/dist/version.d.ts +8 -0
- package/dist/version.js +7 -0
- package/dist/version.js.map +1 -0
- package/package.json +6 -6
- package/src/clients/file-client.ts +26 -0
- package/src/clients/index.ts +1 -0
- package/src/clients/utility-client.ts +25 -0
- package/src/request-handler.ts +12 -2
- package/src/sandbox.ts +84 -7
- package/src/version.ts +6 -0
- package/tests/file-client.test.ts +76 -0
- package/tests/get-sandbox.test.ts +110 -0
- package/tests/request-handler.test.ts +240 -0
- package/tests/sandbox.test.ts +94 -5
- package/tests/utility-client.test.ts +67 -1
- package/tests/version.test.ts +16 -0
- package/dist/chunk-2P3MDMNJ.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
# @cloudflare/sandbox
|
|
2
2
|
|
|
3
|
+
## 0.4.11
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#159](https://github.com/cloudflare/sandbox-sdk/pull/159) [`e16659a`](https://github.com/cloudflare/sandbox-sdk/commit/e16659a1815923f1cd1176f51a052725d820ee16) Thanks [@ghostwriternr](https://github.com/ghostwriternr)! - Use latest containers package version
|
|
8
|
+
|
|
9
|
+
## 0.4.10
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#156](https://github.com/cloudflare/sandbox-sdk/pull/156) [`b61841c`](https://github.com/cloudflare/sandbox-sdk/commit/b61841cfb3248022ee8136311e54955ed9faa1ee) Thanks [@ghostwriternr](https://github.com/ghostwriternr)! - Fix WebSocket upgrade requests through exposed ports
|
|
14
|
+
|
|
15
|
+
## 0.4.9
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- [#152](https://github.com/cloudflare/sandbox-sdk/pull/152) [`8e7773e`](https://github.com/cloudflare/sandbox-sdk/commit/8e7773ec9571a5f968cbbc5f48e38e01d7d13b77) Thanks [@ghostwriternr](https://github.com/ghostwriternr)! - Add exists() method to check if a file or directory exists
|
|
20
|
+
|
|
21
|
+
This adds a new `exists()` method to the SDK that checks whether a file or directory exists at a given path. The method returns a boolean indicating existence, similar to Python's `os.path.exists()` and JavaScript's `fs.existsSync()`.
|
|
22
|
+
|
|
23
|
+
The implementation is end-to-end:
|
|
24
|
+
|
|
25
|
+
- New `FileExistsResult` and `FileExistsRequest` types in shared package
|
|
26
|
+
- Handler endpoint at `/api/exists` in container layer
|
|
27
|
+
- Client method in `FileClient` and `Sandbox` classes
|
|
28
|
+
- Full test coverage (unit tests and E2E tests)
|
|
29
|
+
|
|
30
|
+
## 0.4.8
|
|
31
|
+
|
|
32
|
+
### Patch Changes
|
|
33
|
+
|
|
34
|
+
- [#153](https://github.com/cloudflare/sandbox-sdk/pull/153) [`f6a5c3e`](https://github.com/cloudflare/sandbox-sdk/commit/f6a5c3e1607fce5fc26f816e9206ae437898d5af) Thanks [@ghostwriternr](https://github.com/ghostwriternr)! - Fix token extraction regex causing Invalid token errors
|
|
35
|
+
|
|
36
|
+
## 0.4.7
|
|
37
|
+
|
|
38
|
+
### Patch Changes
|
|
39
|
+
|
|
40
|
+
- [#141](https://github.com/cloudflare/sandbox-sdk/pull/141) [`c39674b`](https://github.com/cloudflare/sandbox-sdk/commit/c39674b8fe2e986e59a794b6bb3a5f51a87bae89) Thanks [@ghostwriternr](https://github.com/ghostwriternr)! - Fix commands hanging when reading stdin by redirecting stdin to /dev/null
|
|
41
|
+
|
|
42
|
+
- [#143](https://github.com/cloudflare/sandbox-sdk/pull/143) [`276efc0`](https://github.com/cloudflare/sandbox-sdk/commit/276efc0ca8776bcc8de79e7e58dd24d9f418cc5c) Thanks [@ghostwriternr](https://github.com/ghostwriternr)! - Remove unnecessary existing session check
|
|
43
|
+
|
|
44
|
+
## 0.4.6
|
|
45
|
+
|
|
46
|
+
### Patch Changes
|
|
47
|
+
|
|
48
|
+
- [#133](https://github.com/cloudflare/sandbox-sdk/pull/133) [`da2cfb8`](https://github.com/cloudflare/sandbox-sdk/commit/da2cfb876675eb3445970c90b4d70d00288a7c74) Thanks [@ghostwriternr](https://github.com/ghostwriternr)! - feat: Add version sync detection between npm package and Docker image
|
|
49
|
+
|
|
50
|
+
## 0.4.5
|
|
51
|
+
|
|
52
|
+
### Patch Changes
|
|
53
|
+
|
|
54
|
+
- [#127](https://github.com/cloudflare/sandbox-sdk/pull/127) [`e79ac80`](https://github.com/cloudflare/sandbox-sdk/commit/e79ac80bc855a3ec527d44cc14585794b23cb129) Thanks [@whoiskatrin](https://github.com/whoiskatrin)! - configurable sleepAfter
|
|
55
|
+
|
|
3
56
|
## 0.4.4
|
|
4
57
|
|
|
5
58
|
### Patch Changes
|
package/Dockerfile
CHANGED
|
@@ -60,9 +60,15 @@ RUN npm ci --production
|
|
|
60
60
|
# ============================================================================
|
|
61
61
|
FROM ubuntu:22.04 AS runtime
|
|
62
62
|
|
|
63
|
+
# Accept version as build argument (passed from npm_package_version)
|
|
64
|
+
ARG SANDBOX_VERSION=unknown
|
|
65
|
+
|
|
63
66
|
# Prevent interactive prompts during package installation
|
|
64
67
|
ENV DEBIAN_FRONTEND=noninteractive
|
|
65
68
|
|
|
69
|
+
# Set the sandbox version as an environment variable for version checking
|
|
70
|
+
ENV SANDBOX_VERSION=${SANDBOX_VERSION}
|
|
71
|
+
|
|
66
72
|
# Install essential runtime packages
|
|
67
73
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
68
74
|
curl \
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["/**\n * SDK version - automatically synchronized with package.json by Changesets\n * This file is auto-updated by .github/changeset-version.ts during releases\n * DO NOT EDIT MANUALLY - Changes will be overwritten on the next version bump\n */\nexport const SDK_VERSION = '0.4.11';\n"],"mappings":";AAKO,IAAM,cAAc;","names":[]}
|
|
@@ -14,6 +14,12 @@ import {
|
|
|
14
14
|
import {
|
|
15
15
|
parseSSEStream
|
|
16
16
|
} from "./chunk-EKSWCBCA.js";
|
|
17
|
+
import {
|
|
18
|
+
SDK_VERSION
|
|
19
|
+
} from "./chunk-FE4PJSRB.js";
|
|
20
|
+
|
|
21
|
+
// src/request-handler.ts
|
|
22
|
+
import { switchPort } from "@cloudflare/containers";
|
|
17
23
|
|
|
18
24
|
// src/sandbox.ts
|
|
19
25
|
import { Container, getContainer } from "@cloudflare/containers";
|
|
@@ -1057,6 +1063,25 @@ var FileClient = class extends BaseHttpClient {
|
|
|
1057
1063
|
throw error;
|
|
1058
1064
|
}
|
|
1059
1065
|
}
|
|
1066
|
+
/**
|
|
1067
|
+
* Check if a file or directory exists
|
|
1068
|
+
* @param path - Path to check
|
|
1069
|
+
* @param sessionId - The session ID for this operation
|
|
1070
|
+
*/
|
|
1071
|
+
async exists(path, sessionId) {
|
|
1072
|
+
try {
|
|
1073
|
+
const data = {
|
|
1074
|
+
path,
|
|
1075
|
+
sessionId
|
|
1076
|
+
};
|
|
1077
|
+
const response = await this.post("/api/exists", data);
|
|
1078
|
+
this.logSuccess("Path existence checked", `${path} (exists: ${response.exists})`);
|
|
1079
|
+
return response;
|
|
1080
|
+
} catch (error) {
|
|
1081
|
+
this.logError("exists", error);
|
|
1082
|
+
throw error;
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1060
1085
|
};
|
|
1061
1086
|
|
|
1062
1087
|
// src/clients/git-client.ts
|
|
@@ -1562,6 +1587,20 @@ var UtilityClient = class extends BaseHttpClient {
|
|
|
1562
1587
|
throw error;
|
|
1563
1588
|
}
|
|
1564
1589
|
}
|
|
1590
|
+
/**
|
|
1591
|
+
* Get the container version
|
|
1592
|
+
* Returns the version embedded in the Docker image during build
|
|
1593
|
+
*/
|
|
1594
|
+
async getVersion() {
|
|
1595
|
+
try {
|
|
1596
|
+
const response = await this.get("/api/version");
|
|
1597
|
+
this.logSuccess("Version retrieved", response.version);
|
|
1598
|
+
return response.version;
|
|
1599
|
+
} catch (error) {
|
|
1600
|
+
this.logger.debug("Failed to get container version (may be old container)", { error });
|
|
1601
|
+
return "unknown";
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1565
1604
|
};
|
|
1566
1605
|
|
|
1567
1606
|
// src/clients/sandbox-client.ts
|
|
@@ -1595,12 +1634,15 @@ function getSandbox(ns, id, options) {
|
|
|
1595
1634
|
if (options?.baseUrl) {
|
|
1596
1635
|
stub.setBaseUrl(options.baseUrl);
|
|
1597
1636
|
}
|
|
1637
|
+
if (options?.sleepAfter !== void 0) {
|
|
1638
|
+
stub.setSleepAfter(options.sleepAfter);
|
|
1639
|
+
}
|
|
1598
1640
|
return stub;
|
|
1599
1641
|
}
|
|
1600
1642
|
var Sandbox = class extends Container {
|
|
1601
1643
|
defaultPort = 3e3;
|
|
1602
1644
|
// Default port for the container's Bun server
|
|
1603
|
-
sleepAfter = "
|
|
1645
|
+
sleepAfter = "10m";
|
|
1604
1646
|
// Sleep the sandbox if no requests are made in this timeframe
|
|
1605
1647
|
client;
|
|
1606
1648
|
codeInterpreter;
|
|
@@ -1658,6 +1700,10 @@ var Sandbox = class extends Container {
|
|
|
1658
1700
|
}
|
|
1659
1701
|
}
|
|
1660
1702
|
}
|
|
1703
|
+
// RPC method to set the sleep timeout
|
|
1704
|
+
async setSleepAfter(sleepAfter) {
|
|
1705
|
+
this.sleepAfter = sleepAfter;
|
|
1706
|
+
}
|
|
1661
1707
|
// RPC method to set environment variables
|
|
1662
1708
|
async setEnvVars(envVars) {
|
|
1663
1709
|
this.envVars = { ...this.envVars, ...envVars };
|
|
@@ -1681,6 +1727,35 @@ var Sandbox = class extends Container {
|
|
|
1681
1727
|
}
|
|
1682
1728
|
onStart() {
|
|
1683
1729
|
this.logger.debug("Sandbox started");
|
|
1730
|
+
this.checkVersionCompatibility().catch((error) => {
|
|
1731
|
+
this.logger.error("Version compatibility check failed", error instanceof Error ? error : new Error(String(error)));
|
|
1732
|
+
});
|
|
1733
|
+
}
|
|
1734
|
+
/**
|
|
1735
|
+
* Check if the container version matches the SDK version
|
|
1736
|
+
* Logs a warning if there's a mismatch
|
|
1737
|
+
*/
|
|
1738
|
+
async checkVersionCompatibility() {
|
|
1739
|
+
try {
|
|
1740
|
+
const sdkVersion = SDK_VERSION;
|
|
1741
|
+
const containerVersion = await this.client.utils.getVersion();
|
|
1742
|
+
if (containerVersion === "unknown") {
|
|
1743
|
+
this.logger.warn(
|
|
1744
|
+
"Container version check: Container version could not be determined. This may indicate an outdated container image. Please update your container to match SDK version " + sdkVersion
|
|
1745
|
+
);
|
|
1746
|
+
return;
|
|
1747
|
+
}
|
|
1748
|
+
if (containerVersion !== sdkVersion) {
|
|
1749
|
+
const message = `Version mismatch detected! SDK version (${sdkVersion}) does not match container version (${containerVersion}). This may cause compatibility issues. Please update your container image to version ${sdkVersion}`;
|
|
1750
|
+
this.logger.warn(message);
|
|
1751
|
+
} else {
|
|
1752
|
+
this.logger.debug("Version check passed", { sdkVersion, containerVersion });
|
|
1753
|
+
}
|
|
1754
|
+
} catch (error) {
|
|
1755
|
+
this.logger.debug("Version compatibility check encountered an error", {
|
|
1756
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1757
|
+
});
|
|
1758
|
+
}
|
|
1684
1759
|
}
|
|
1685
1760
|
onStop() {
|
|
1686
1761
|
this.logger.debug("Sandbox stopped");
|
|
@@ -1699,6 +1774,11 @@ var Sandbox = class extends Container {
|
|
|
1699
1774
|
this.sandboxName = name;
|
|
1700
1775
|
await this.ctx.storage.put("sandboxName", name);
|
|
1701
1776
|
}
|
|
1777
|
+
const upgradeHeader = request.headers.get("Upgrade");
|
|
1778
|
+
const isWebSocket = upgradeHeader?.toLowerCase() === "websocket";
|
|
1779
|
+
if (isWebSocket) {
|
|
1780
|
+
return await super.fetch(request);
|
|
1781
|
+
}
|
|
1702
1782
|
const port = this.determinePort(url);
|
|
1703
1783
|
return await this.containerFetch(request, port);
|
|
1704
1784
|
});
|
|
@@ -1731,7 +1811,7 @@ var Sandbox = class extends Container {
|
|
|
1731
1811
|
await this.ctx.storage.put("defaultSession", sessionId);
|
|
1732
1812
|
this.logger.debug("Default session initialized", { sessionId });
|
|
1733
1813
|
} catch (error) {
|
|
1734
|
-
if (error?.message?.includes("already exists")
|
|
1814
|
+
if (error?.message?.includes("already exists")) {
|
|
1735
1815
|
this.logger.debug("Reusing existing session after reload", { sessionId });
|
|
1736
1816
|
this.defaultSession = sessionId;
|
|
1737
1817
|
await this.ctx.storage.put("defaultSession", sessionId);
|
|
@@ -2013,6 +2093,10 @@ var Sandbox = class extends Container {
|
|
|
2013
2093
|
const session = await this.ensureDefaultSession();
|
|
2014
2094
|
return this.client.files.listFiles(path, session, options);
|
|
2015
2095
|
}
|
|
2096
|
+
async exists(path, sessionId) {
|
|
2097
|
+
const session = sessionId ?? await this.ensureDefaultSession();
|
|
2098
|
+
return this.client.files.exists(path, session);
|
|
2099
|
+
}
|
|
2016
2100
|
async exposePort(port, options) {
|
|
2017
2101
|
if (options.hostname.endsWith(".workers.dev")) {
|
|
2018
2102
|
const errorResponse = {
|
|
@@ -2188,6 +2272,7 @@ var Sandbox = class extends Container {
|
|
|
2188
2272
|
renameFile: (oldPath, newPath) => this.renameFile(oldPath, newPath, sessionId),
|
|
2189
2273
|
moveFile: (sourcePath, destPath) => this.moveFile(sourcePath, destPath, sessionId),
|
|
2190
2274
|
listFiles: (path, options) => this.client.files.listFiles(path, sessionId, options),
|
|
2275
|
+
exists: (path) => this.exists(path, sessionId),
|
|
2191
2276
|
// Git operations
|
|
2192
2277
|
gitCheckout: (repoUrl, options) => this.gitCheckout(repoUrl, { ...options, sessionId }),
|
|
2193
2278
|
// Environment management - needs special handling
|
|
@@ -2280,6 +2365,10 @@ async function proxyToSandbox(request, env) {
|
|
|
2280
2365
|
);
|
|
2281
2366
|
}
|
|
2282
2367
|
}
|
|
2368
|
+
const upgradeHeader = request.headers.get("Upgrade");
|
|
2369
|
+
if (upgradeHeader?.toLowerCase() === "websocket") {
|
|
2370
|
+
return await sandbox.fetch(switchPort(request, port));
|
|
2371
|
+
}
|
|
2283
2372
|
let proxyUrl;
|
|
2284
2373
|
if (port !== 3e3) {
|
|
2285
2374
|
proxyUrl = `http://localhost:${port}${path}${url.search}`;
|
|
@@ -2300,14 +2389,14 @@ async function proxyToSandbox(request, env) {
|
|
|
2300
2389
|
// @ts-expect-error - duplex required for body streaming in modern runtimes
|
|
2301
2390
|
duplex: "half"
|
|
2302
2391
|
});
|
|
2303
|
-
return sandbox.containerFetch(proxyRequest, port);
|
|
2392
|
+
return await sandbox.containerFetch(proxyRequest, port);
|
|
2304
2393
|
} catch (error) {
|
|
2305
2394
|
logger.error("Proxy routing error", error instanceof Error ? error : new Error(String(error)));
|
|
2306
2395
|
return new Response("Proxy routing error", { status: 500 });
|
|
2307
2396
|
}
|
|
2308
2397
|
}
|
|
2309
2398
|
function extractSandboxRoute(url) {
|
|
2310
|
-
const subdomainMatch = url.hostname.match(/^(\d{4,5})-([^.-][^.]
|
|
2399
|
+
const subdomainMatch = url.hostname.match(/^(\d{4,5})-([^.-][^.]*?[^.-]|[^.-])-([a-z0-9_-]{16})\.(.+)$/);
|
|
2311
2400
|
if (!subdomainMatch) {
|
|
2312
2401
|
return null;
|
|
2313
2402
|
}
|
|
@@ -2364,4 +2453,4 @@ export {
|
|
|
2364
2453
|
getSandbox,
|
|
2365
2454
|
Sandbox
|
|
2366
2455
|
};
|
|
2367
|
-
//# sourceMappingURL=chunk-
|
|
2456
|
+
//# sourceMappingURL=chunk-SVWLTRHD.js.map
|