@cloudflare/sandbox 0.12.1 → 0.12.3

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.
@@ -1,6 +1,6 @@
1
1
  import "../dist-B_eXrP83.js";
2
- import "../errors-aRUdk9K8.js";
3
- import { S as validateTunnelName, r as getSandbox, w as streamFile, x as validatePort, y as SandboxSecurityError } from "../sandbox-DKG3H156.js";
2
+ import "../errors-CpkKPbWC.js";
3
+ import { S as validateTunnelName, r as getSandbox, w as streamFile, x as validatePort, y as SandboxSecurityError } from "../sandbox-DI6suZAc.js";
4
4
  import { DurableObject, env } from "cloudflare:workers";
5
5
  import { Hono } from "hono";
6
6
 
@@ -454,7 +454,7 @@ const OPENAPI_SCHEMA = {
454
454
  type: "string",
455
455
  pattern: "^[a-zA-Z0-9._-]{1,128}$"
456
456
  },
457
- description: "Scope this operation to a specific session. Uses the default session if omitted."
457
+ description: "Scope this operation to a specific session. If omitted, the operation runs without reusing shell state."
458
458
  }],
459
459
  requestBody: {
460
460
  required: true,
@@ -618,7 +618,7 @@ const OPENAPI_SCHEMA = {
618
618
  type: "string",
619
619
  pattern: "^[a-zA-Z0-9._-]{1,128}$"
620
620
  },
621
- description: "Scope this operation to a specific session. Uses the default session if omitted."
621
+ description: "Scope this operation to a specific session. If omitted, the operation runs without reusing shell state."
622
622
  }
623
623
  ],
624
624
  responses: {
@@ -694,7 +694,7 @@ const OPENAPI_SCHEMA = {
694
694
  type: "string",
695
695
  pattern: "^[a-zA-Z0-9._-]{1,128}$"
696
696
  },
697
- description: "Scope this operation to a specific session. Uses the default session if omitted."
697
+ description: "Scope this operation to a specific session. If omitted, the operation runs without reusing shell state."
698
698
  }
699
699
  ],
700
700
  requestBody: {
@@ -794,7 +794,7 @@ const OPENAPI_SCHEMA = {
794
794
  type: "string",
795
795
  pattern: "^[a-zA-Z0-9._-]{1,128}$"
796
796
  },
797
- description: "Scope this operation to a specific session. Uses the default session if omitted."
797
+ description: "Scope this PTY to a specific session."
798
798
  }
799
799
  ],
800
800
  responses: {
@@ -1767,6 +1767,10 @@ function esc(s) {
1767
1767
  function getSandbox$1(ns, containerUUID) {
1768
1768
  return getSandbox(ns, containerUUID);
1769
1769
  }
1770
+ /** Bridge routes should not implicitly reuse the SDK's default shell session. */
1771
+ function getSandboxWithoutDefaultSession(ns, containerUUID) {
1772
+ return getSandbox(ns, containerUUID, { enableDefaultSession: false });
1773
+ }
1770
1774
  function hasEndpoint(options) {
1771
1775
  return "endpoint" in options && typeof options.endpoint === "string";
1772
1776
  }
@@ -1910,7 +1914,7 @@ function createBridgeApp(config) {
1910
1914
  return errorJson("Invalid JSON body", "invalid_request", 400);
1911
1915
  }
1912
1916
  if (!Array.isArray(body.argv) || body.argv.length === 0) return errorJson("argv must be a non-empty array", "invalid_request", 400);
1913
- const sandbox = getSandbox$1(getSandboxNs(c.env), c.get("containerUUID"));
1917
+ const sandbox = getSandboxWithoutDefaultSession(getSandboxNs(c.env), c.get("containerUUID"));
1914
1918
  const rawSessionId = c.req.header("Session-Id");
1915
1919
  let executor = sandbox;
1916
1920
  if (rawSessionId) {
@@ -1983,7 +1987,7 @@ function createBridgeApp(config) {
1983
1987
  if (!relativePath) return errorJson("file path must not be empty", "invalid_request", 400);
1984
1988
  const resolvedPath = resolveWorkspacePath(`/${relativePath}`);
1985
1989
  if (!resolvedPath) return errorJson("path must resolve to a location within /workspace", "invalid_request", 403);
1986
- const sandbox = getSandbox$1(getSandboxNs(c.env), c.get("containerUUID"));
1990
+ const sandbox = getSandboxWithoutDefaultSession(getSandboxNs(c.env), c.get("containerUUID"));
1987
1991
  const rawSessionId = c.req.header("Session-Id");
1988
1992
  let executor = sandbox;
1989
1993
  if (rawSessionId) {
@@ -2010,7 +2014,7 @@ function createBridgeApp(config) {
2010
2014
  if (!relativePath) return errorJson("file path must not be empty", "invalid_request", 400);
2011
2015
  const resolvedPath = resolveWorkspacePath(`/${relativePath}`);
2012
2016
  if (!resolvedPath) return errorJson("path must resolve to a location within /workspace", "invalid_request", 403);
2013
- const sandbox = getSandbox$1(getSandboxNs(c.env), c.get("containerUUID"));
2017
+ const sandbox = getSandboxWithoutDefaultSession(getSandboxNs(c.env), c.get("containerUUID"));
2014
2018
  const rawSessionId = c.req.header("Session-Id");
2015
2019
  let executor = sandbox;
2016
2020
  if (rawSessionId) {
@@ -2037,7 +2041,7 @@ function createBridgeApp(config) {
2037
2041
  if (!validatePort(port)) return errorJson("Invalid port", "invalid_request", 400);
2038
2042
  const options = parseTunnelOptions(await c.req.text());
2039
2043
  if (options instanceof Response) return options;
2040
- const sandbox = getSandbox$1(getSandboxNs(c.env), c.get("containerUUID"));
2044
+ const sandbox = getSandboxWithoutDefaultSession(getSandboxNs(c.env), c.get("containerUUID"));
2041
2045
  try {
2042
2046
  const tunnel = await sandbox.tunnels.get(port, options);
2043
2047
  return c.json(tunnel);
@@ -2048,7 +2052,7 @@ function createBridgeApp(config) {
2048
2052
  app.delete(`${apiPrefix}/sandbox/:id/tunnel/:port`, async (c) => {
2049
2053
  const port = Number(c.req.param("port"));
2050
2054
  if (!validatePort(port)) return errorJson("Invalid port", "invalid_request", 400);
2051
- const sandbox = getSandbox$1(getSandboxNs(c.env), c.get("containerUUID"));
2055
+ const sandbox = getSandboxWithoutDefaultSession(getSandboxNs(c.env), c.get("containerUUID"));
2052
2056
  try {
2053
2057
  await sandbox.tunnels.destroy(port);
2054
2058
  return c.body(null, 204);
@@ -2057,7 +2061,7 @@ function createBridgeApp(config) {
2057
2061
  }
2058
2062
  });
2059
2063
  app.get(`${apiPrefix}/sandbox/:id/running`, async (c) => {
2060
- const sandbox = getSandbox$1(getSandboxNs(c.env), c.get("containerUUID"));
2064
+ const sandbox = getSandboxWithoutDefaultSession(getSandboxNs(c.env), c.get("containerUUID"));
2061
2065
  try {
2062
2066
  await sandbox.exec("true");
2063
2067
  return c.json({ running: true });
@@ -2068,7 +2072,7 @@ function createBridgeApp(config) {
2068
2072
  app.get(`${apiPrefix}/sandbox/:id/pty`, async (c) => {
2069
2073
  const upgrade = c.req.header("Upgrade");
2070
2074
  if (!upgrade || upgrade.toLowerCase() !== "websocket") return errorJson("WebSocket upgrade required", "invalid_request", 400);
2071
- const sandbox = getSandbox$1(getSandboxNs(c.env), c.get("containerUUID"));
2075
+ const sandbox = getSandboxWithoutDefaultSession(getSandboxNs(c.env), c.get("containerUUID"));
2072
2076
  const colsParam = c.req.query("cols");
2073
2077
  const rowsParam = c.req.query("rows");
2074
2078
  const shell = c.req.query("shell");
@@ -2097,7 +2101,7 @@ function createBridgeApp(config) {
2097
2101
  const excludesParam = c.req.query("excludes") ?? "";
2098
2102
  const excludes = excludesParam ? excludesParam.split(",").filter((s) => s.length > 0) : [];
2099
2103
  for (const ex of excludes) if (ex.includes("..")) return errorJson("exclude paths must not contain \"..\"", "invalid_request", 400);
2100
- const sandbox = getSandbox$1(getSandboxNs(c.env), c.get("containerUUID"));
2104
+ const sandbox = getSandboxWithoutDefaultSession(getSandboxNs(c.env), c.get("containerUUID"));
2101
2105
  const tmpPath = `/tmp/sandbox-persist-${Date.now()}.tar`;
2102
2106
  const excludeArgs = excludes.map((rel) => `--exclude ${shellQuote(`./${rel.replace(/^\.\//, "")}`)}`).join(" ");
2103
2107
  const tarCmd = excludeArgs ? `tar cf ${shellQuote(tmpPath)} ${excludeArgs} -C ${shellQuote(root)} .` : `tar cf ${shellQuote(tmpPath)} -C ${shellQuote(root)} .`;
@@ -2116,7 +2120,7 @@ function createBridgeApp(config) {
2116
2120
  });
2117
2121
  app.post(`${apiPrefix}/sandbox/:id/hydrate`, async (c) => {
2118
2122
  const root = "/workspace";
2119
- const sandbox = getSandbox$1(getSandboxNs(c.env), c.get("containerUUID"));
2123
+ const sandbox = getSandboxWithoutDefaultSession(getSandboxNs(c.env), c.get("containerUUID"));
2120
2124
  let tarBytes;
2121
2125
  try {
2122
2126
  const buffer = await c.req.arrayBuffer();
@@ -2156,7 +2160,7 @@ function createBridgeApp(config) {
2156
2160
  if (optionsError) return optionsError;
2157
2161
  const bucketName = resolveMountBucketName(body);
2158
2162
  if (bucketName instanceof Response) return bucketName;
2159
- const sandbox = getSandbox$1(getSandboxNs(c.env), c.get("containerUUID"));
2163
+ const sandbox = getSandboxWithoutDefaultSession(getSandboxNs(c.env), c.get("containerUUID"));
2160
2164
  const sdkOptions = toSDKMountOptions(body.options);
2161
2165
  try {
2162
2166
  await sandbox.mountBucket(bucketName, body.mountPath, sdkOptions);
@@ -2176,7 +2180,7 @@ function createBridgeApp(config) {
2176
2180
  if (!body.mountPath.startsWith("/")) return errorJson("mountPath must be an absolute path (start with /)", "invalid_request", 400);
2177
2181
  const normalizedPath = new URL(body.mountPath, "file:///").pathname;
2178
2182
  if (normalizedPath === "/") return errorJson("mountPath must not resolve to / (filesystem root)", "invalid_request", 400);
2179
- const sandbox = getSandbox$1(getSandboxNs(c.env), c.get("containerUUID"));
2183
+ const sandbox = getSandboxWithoutDefaultSession(getSandboxNs(c.env), c.get("containerUUID"));
2180
2184
  try {
2181
2185
  await sandbox.unmountBucket(normalizedPath);
2182
2186
  const quoted = shellQuote(normalizedPath);
@@ -2213,7 +2217,7 @@ function createBridgeApp(config) {
2213
2217
  });
2214
2218
  app.delete(`${apiPrefix}/sandbox/:id`, async (c) => {
2215
2219
  const containerUUID = c.get("containerUUID");
2216
- const sandbox = getSandbox$1(getSandboxNs(c.env), containerUUID);
2220
+ const sandbox = getSandboxWithoutDefaultSession(getSandboxNs(c.env), containerUUID);
2217
2221
  try {
2218
2222
  await sandbox.destroy();
2219
2223
  } catch {}