@cloudflare/sandbox 0.5.1 → 0.5.2

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.js CHANGED
@@ -1,667 +1,6 @@
1
- import { AsyncLocalStorage } from "node:async_hooks";
1
+ import { a as createLogger, c as Execution, d as getEnvString, i as shellEscape, l as ResultImpl, n as isProcess, o as createNoOpLogger, r as isProcessStatus, s as TraceContext, t as isExecResult, u as GitLogger } from "./dist-gVyG2H2h.js";
2
2
  import { Container, getContainer, switchPort } from "@cloudflare/containers";
3
3
 
4
- //#region ../shared/dist/env.js
5
- /**
6
- * Safely extract a string value from an environment object
7
- *
8
- * @param env - Environment object with dynamic keys
9
- * @param key - The environment variable key to access
10
- * @returns The string value if present and is a string, undefined otherwise
11
- */
12
- function getEnvString(env, key) {
13
- const value = env?.[key];
14
- return typeof value === "string" ? value : void 0;
15
- }
16
-
17
- //#endregion
18
- //#region ../shared/dist/git.js
19
- /**
20
- * Redact credentials from URLs for secure logging
21
- *
22
- * Replaces any credentials (username:password, tokens, etc.) embedded
23
- * in URLs with ****** to prevent sensitive data exposure in logs.
24
- * Works with URLs embedded in text (e.g., "Error: https://token@github.com/repo.git failed")
25
- *
26
- * @param text - String that may contain URLs with credentials
27
- * @returns String with credentials redacted from any URLs
28
- */
29
- function redactCredentials(text) {
30
- let result = text;
31
- let pos = 0;
32
- while (pos < result.length) {
33
- const httpPos = result.indexOf("http://", pos);
34
- const httpsPos = result.indexOf("https://", pos);
35
- let protocolPos = -1;
36
- let protocolLen = 0;
37
- if (httpPos === -1 && httpsPos === -1) break;
38
- if (httpPos !== -1 && (httpsPos === -1 || httpPos < httpsPos)) {
39
- protocolPos = httpPos;
40
- protocolLen = 7;
41
- } else {
42
- protocolPos = httpsPos;
43
- protocolLen = 8;
44
- }
45
- const searchStart = protocolPos + protocolLen;
46
- const atPos = result.indexOf("@", searchStart);
47
- let urlEnd = searchStart;
48
- while (urlEnd < result.length) {
49
- const char = result[urlEnd];
50
- if (/[\s"'`<>,;{}[\]]/.test(char)) break;
51
- urlEnd++;
52
- }
53
- if (atPos !== -1 && atPos < urlEnd) {
54
- result = `${result.substring(0, searchStart)}******${result.substring(atPos)}`;
55
- pos = searchStart + 6;
56
- } else pos = protocolPos + protocolLen;
57
- }
58
- return result;
59
- }
60
- /**
61
- * Sanitize data by redacting credentials from any strings
62
- * Recursively processes objects and arrays to ensure credentials are never leaked
63
- */
64
- function sanitizeGitData(data) {
65
- if (typeof data === "string") return redactCredentials(data);
66
- if (data === null || data === void 0) return data;
67
- if (Array.isArray(data)) return data.map((item) => sanitizeGitData(item));
68
- if (typeof data === "object") {
69
- const result = {};
70
- for (const [key, value] of Object.entries(data)) result[key] = sanitizeGitData(value);
71
- return result;
72
- }
73
- return data;
74
- }
75
- /**
76
- * Logger wrapper that automatically sanitizes git credentials
77
- */
78
- var GitLogger = class GitLogger {
79
- baseLogger;
80
- constructor(baseLogger) {
81
- this.baseLogger = baseLogger;
82
- }
83
- sanitizeContext(context) {
84
- return context ? sanitizeGitData(context) : context;
85
- }
86
- sanitizeError(error) {
87
- if (!error) return error;
88
- const sanitized = new Error(redactCredentials(error.message));
89
- sanitized.name = error.name;
90
- if (error.stack) sanitized.stack = redactCredentials(error.stack);
91
- const sanitizedRecord = sanitized;
92
- const errorRecord = error;
93
- for (const key of Object.keys(error)) if (key !== "message" && key !== "stack" && key !== "name") sanitizedRecord[key] = sanitizeGitData(errorRecord[key]);
94
- return sanitized;
95
- }
96
- debug(message, context) {
97
- this.baseLogger.debug(message, this.sanitizeContext(context));
98
- }
99
- info(message, context) {
100
- this.baseLogger.info(message, this.sanitizeContext(context));
101
- }
102
- warn(message, context) {
103
- this.baseLogger.warn(message, this.sanitizeContext(context));
104
- }
105
- error(message, error, context) {
106
- this.baseLogger.error(message, this.sanitizeError(error), this.sanitizeContext(context));
107
- }
108
- child(context) {
109
- const sanitized = sanitizeGitData(context);
110
- return new GitLogger(this.baseLogger.child(sanitized));
111
- }
112
- };
113
-
114
- //#endregion
115
- //#region ../shared/dist/interpreter-types.js
116
- var Execution = class {
117
- code;
118
- context;
119
- /**
120
- * All results from the execution
121
- */
122
- results = [];
123
- /**
124
- * Accumulated stdout and stderr
125
- */
126
- logs = {
127
- stdout: [],
128
- stderr: []
129
- };
130
- /**
131
- * Execution error if any
132
- */
133
- error;
134
- /**
135
- * Execution count (for interpreter)
136
- */
137
- executionCount;
138
- constructor(code, context) {
139
- this.code = code;
140
- this.context = context;
141
- }
142
- /**
143
- * Convert to a plain object for serialization
144
- */
145
- toJSON() {
146
- return {
147
- code: this.code,
148
- logs: this.logs,
149
- error: this.error,
150
- executionCount: this.executionCount,
151
- results: this.results.map((result) => ({
152
- text: result.text,
153
- html: result.html,
154
- png: result.png,
155
- jpeg: result.jpeg,
156
- svg: result.svg,
157
- latex: result.latex,
158
- markdown: result.markdown,
159
- javascript: result.javascript,
160
- json: result.json,
161
- chart: result.chart,
162
- data: result.data
163
- }))
164
- };
165
- }
166
- };
167
- var ResultImpl = class {
168
- raw;
169
- constructor(raw) {
170
- this.raw = raw;
171
- }
172
- get text() {
173
- return this.raw.text || this.raw.data?.["text/plain"];
174
- }
175
- get html() {
176
- return this.raw.html || this.raw.data?.["text/html"];
177
- }
178
- get png() {
179
- return this.raw.png || this.raw.data?.["image/png"];
180
- }
181
- get jpeg() {
182
- return this.raw.jpeg || this.raw.data?.["image/jpeg"];
183
- }
184
- get svg() {
185
- return this.raw.svg || this.raw.data?.["image/svg+xml"];
186
- }
187
- get latex() {
188
- return this.raw.latex || this.raw.data?.["text/latex"];
189
- }
190
- get markdown() {
191
- return this.raw.markdown || this.raw.data?.["text/markdown"];
192
- }
193
- get javascript() {
194
- return this.raw.javascript || this.raw.data?.["application/javascript"];
195
- }
196
- get json() {
197
- return this.raw.json || this.raw.data?.["application/json"];
198
- }
199
- get chart() {
200
- return this.raw.chart;
201
- }
202
- get data() {
203
- return this.raw.data;
204
- }
205
- formats() {
206
- const formats = [];
207
- if (this.text) formats.push("text");
208
- if (this.html) formats.push("html");
209
- if (this.png) formats.push("png");
210
- if (this.jpeg) formats.push("jpeg");
211
- if (this.svg) formats.push("svg");
212
- if (this.latex) formats.push("latex");
213
- if (this.markdown) formats.push("markdown");
214
- if (this.javascript) formats.push("javascript");
215
- if (this.json) formats.push("json");
216
- if (this.chart) formats.push("chart");
217
- return formats;
218
- }
219
- };
220
-
221
- //#endregion
222
- //#region ../shared/dist/logger/types.js
223
- /**
224
- * Logger types for Cloudflare Sandbox SDK
225
- *
226
- * Provides structured, trace-aware logging across Worker, Durable Object, and Container.
227
- */
228
- /**
229
- * Log levels (from most to least verbose)
230
- */
231
- var LogLevel;
232
- (function(LogLevel$1) {
233
- LogLevel$1[LogLevel$1["DEBUG"] = 0] = "DEBUG";
234
- LogLevel$1[LogLevel$1["INFO"] = 1] = "INFO";
235
- LogLevel$1[LogLevel$1["WARN"] = 2] = "WARN";
236
- LogLevel$1[LogLevel$1["ERROR"] = 3] = "ERROR";
237
- })(LogLevel || (LogLevel = {}));
238
-
239
- //#endregion
240
- //#region ../shared/dist/logger/logger.js
241
- /**
242
- * Logger implementation
243
- */
244
- /**
245
- * ANSI color codes for terminal output
246
- */
247
- const COLORS = {
248
- reset: "\x1B[0m",
249
- debug: "\x1B[36m",
250
- info: "\x1B[32m",
251
- warn: "\x1B[33m",
252
- error: "\x1B[31m",
253
- dim: "\x1B[2m"
254
- };
255
- /**
256
- * CloudflareLogger implements structured logging with support for
257
- * both JSON output (production) and pretty printing (development).
258
- */
259
- var CloudflareLogger = class CloudflareLogger {
260
- baseContext;
261
- minLevel;
262
- pretty;
263
- /**
264
- * Create a new CloudflareLogger
265
- *
266
- * @param baseContext Base context included in all log entries
267
- * @param minLevel Minimum log level to output (default: INFO)
268
- * @param pretty Enable pretty printing for human-readable output (default: false)
269
- */
270
- constructor(baseContext, minLevel = LogLevel.INFO, pretty = false) {
271
- this.baseContext = baseContext;
272
- this.minLevel = minLevel;
273
- this.pretty = pretty;
274
- }
275
- /**
276
- * Log debug-level message
277
- */
278
- debug(message, context) {
279
- if (this.shouldLog(LogLevel.DEBUG)) {
280
- const logData = this.buildLogData("debug", message, context);
281
- this.output(console.log, logData);
282
- }
283
- }
284
- /**
285
- * Log info-level message
286
- */
287
- info(message, context) {
288
- if (this.shouldLog(LogLevel.INFO)) {
289
- const logData = this.buildLogData("info", message, context);
290
- this.output(console.log, logData);
291
- }
292
- }
293
- /**
294
- * Log warning-level message
295
- */
296
- warn(message, context) {
297
- if (this.shouldLog(LogLevel.WARN)) {
298
- const logData = this.buildLogData("warn", message, context);
299
- this.output(console.warn, logData);
300
- }
301
- }
302
- /**
303
- * Log error-level message
304
- */
305
- error(message, error, context) {
306
- if (this.shouldLog(LogLevel.ERROR)) {
307
- const logData = this.buildLogData("error", message, context, error);
308
- this.output(console.error, logData);
309
- }
310
- }
311
- /**
312
- * Create a child logger with additional context
313
- */
314
- child(context) {
315
- return new CloudflareLogger({
316
- ...this.baseContext,
317
- ...context
318
- }, this.minLevel, this.pretty);
319
- }
320
- /**
321
- * Check if a log level should be output
322
- */
323
- shouldLog(level) {
324
- return level >= this.minLevel;
325
- }
326
- /**
327
- * Build log data object
328
- */
329
- buildLogData(level, message, context, error) {
330
- const logData = {
331
- level,
332
- msg: message,
333
- ...this.baseContext,
334
- ...context,
335
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
336
- };
337
- if (error) logData.error = {
338
- message: error.message,
339
- stack: error.stack,
340
- name: error.name
341
- };
342
- return logData;
343
- }
344
- /**
345
- * Output log data to console (pretty or JSON)
346
- */
347
- output(consoleFn, data) {
348
- if (this.pretty) this.outputPretty(consoleFn, data);
349
- else this.outputJson(consoleFn, data);
350
- }
351
- /**
352
- * Output as JSON (production)
353
- */
354
- outputJson(consoleFn, data) {
355
- consoleFn(JSON.stringify(data));
356
- }
357
- /**
358
- * Output as pretty-printed, colored text (development)
359
- *
360
- * Format: LEVEL [component] message (trace: tr_...) {context}
361
- * Example: INFO [sandbox-do] Command started (trace: tr_7f3a9b2c) {commandId: "cmd-123"}
362
- */
363
- outputPretty(consoleFn, data) {
364
- const { level, msg, timestamp, traceId, component, sandboxId, sessionId, processId, commandId, operation, duration, error, ...rest } = data;
365
- const levelStr = String(level || "INFO").toUpperCase();
366
- const levelColor = this.getLevelColor(levelStr);
367
- const componentBadge = component ? `[${component}]` : "";
368
- const traceIdShort = traceId ? String(traceId).substring(0, 12) : "";
369
- let logLine = `${levelColor}${levelStr.padEnd(5)}${COLORS.reset} ${componentBadge} ${msg}`;
370
- if (traceIdShort) logLine += ` ${COLORS.dim}(trace: ${traceIdShort})${COLORS.reset}`;
371
- const contextFields = [];
372
- if (operation) contextFields.push(`operation: ${operation}`);
373
- if (commandId) contextFields.push(`commandId: ${String(commandId).substring(0, 12)}`);
374
- if (sandboxId) contextFields.push(`sandboxId: ${sandboxId}`);
375
- if (sessionId) contextFields.push(`sessionId: ${String(sessionId).substring(0, 12)}`);
376
- if (processId) contextFields.push(`processId: ${processId}`);
377
- if (duration !== void 0) contextFields.push(`duration: ${duration}ms`);
378
- if (contextFields.length > 0) logLine += ` ${COLORS.dim}{${contextFields.join(", ")}}${COLORS.reset}`;
379
- consoleFn(logLine);
380
- if (error && typeof error === "object") {
381
- const errorObj = error;
382
- if (errorObj.message) consoleFn(` ${COLORS.error}Error: ${errorObj.message}${COLORS.reset}`);
383
- if (errorObj.stack) consoleFn(` ${COLORS.dim}${errorObj.stack}${COLORS.reset}`);
384
- }
385
- if (Object.keys(rest).length > 0) consoleFn(` ${COLORS.dim}${JSON.stringify(rest, null, 2)}${COLORS.reset}`);
386
- }
387
- /**
388
- * Get ANSI color code for log level
389
- */
390
- getLevelColor(level) {
391
- switch (level.toLowerCase()) {
392
- case "debug": return COLORS.debug;
393
- case "info": return COLORS.info;
394
- case "warn": return COLORS.warn;
395
- case "error": return COLORS.error;
396
- default: return COLORS.reset;
397
- }
398
- }
399
- };
400
-
401
- //#endregion
402
- //#region ../shared/dist/logger/trace-context.js
403
- /**
404
- * Trace context utilities for request correlation
405
- *
406
- * Trace IDs enable correlating logs across distributed components:
407
- * Worker → Durable Object → Container → back
408
- *
409
- * The trace ID is propagated via the X-Trace-Id HTTP header.
410
- */
411
- /**
412
- * Utility for managing trace context across distributed components
413
- */
414
- var TraceContext = class TraceContext {
415
- /**
416
- * HTTP header name for trace ID propagation
417
- */
418
- static TRACE_HEADER = "X-Trace-Id";
419
- /**
420
- * Generate a new trace ID
421
- *
422
- * Format: "tr_" + 16 random hex characters
423
- * Example: "tr_7f3a9b2c4e5d6f1a"
424
- *
425
- * @returns Newly generated trace ID
426
- */
427
- static generate() {
428
- return `tr_${crypto.randomUUID().replace(/-/g, "").substring(0, 16)}`;
429
- }
430
- /**
431
- * Extract trace ID from HTTP request headers
432
- *
433
- * @param headers Request headers
434
- * @returns Trace ID if present, null otherwise
435
- */
436
- static fromHeaders(headers) {
437
- return headers.get(TraceContext.TRACE_HEADER);
438
- }
439
- /**
440
- * Create headers object with trace ID for outgoing requests
441
- *
442
- * @param traceId Trace ID to include
443
- * @returns Headers object with X-Trace-Id set
444
- */
445
- static toHeaders(traceId) {
446
- return { [TraceContext.TRACE_HEADER]: traceId };
447
- }
448
- /**
449
- * Get the header name used for trace ID propagation
450
- *
451
- * @returns Header name ("X-Trace-Id")
452
- */
453
- static getHeaderName() {
454
- return TraceContext.TRACE_HEADER;
455
- }
456
- };
457
-
458
- //#endregion
459
- //#region ../shared/dist/logger/index.js
460
- /**
461
- * Logger module
462
- *
463
- * Provides structured, trace-aware logging with:
464
- * - AsyncLocalStorage for implicit context propagation
465
- * - Pretty printing for local development
466
- * - JSON output for production
467
- * - Environment auto-detection
468
- * - Log level configuration
469
- *
470
- * Usage:
471
- *
472
- * ```typescript
473
- * // Create a logger at entry point
474
- * const logger = createLogger({ component: 'sandbox-do', traceId: 'tr_abc123' });
475
- *
476
- * // Store in AsyncLocalStorage for entire request
477
- * await runWithLogger(logger, async () => {
478
- * await handleRequest();
479
- * });
480
- *
481
- * // Retrieve logger anywhere in call stack
482
- * const logger = getLogger();
483
- * logger.info('Operation started');
484
- *
485
- * // Add operation-specific context
486
- * const execLogger = logger.child({ operation: 'exec', commandId: 'cmd-456' });
487
- * await runWithLogger(execLogger, async () => {
488
- * // All nested calls automatically get execLogger
489
- * await executeCommand();
490
- * });
491
- * ```
492
- */
493
- /**
494
- * Create a no-op logger for testing
495
- *
496
- * Returns a logger that implements the Logger interface but does nothing.
497
- * Useful for tests that don't need actual logging output.
498
- *
499
- * @returns No-op logger instance
500
- *
501
- * @example
502
- * ```typescript
503
- * // In tests
504
- * const client = new HttpClient({
505
- * baseUrl: 'http://test.com',
506
- * logger: createNoOpLogger() // Optional - tests can enable real logging if needed
507
- * });
508
- * ```
509
- */
510
- function createNoOpLogger() {
511
- return {
512
- debug: () => {},
513
- info: () => {},
514
- warn: () => {},
515
- error: () => {},
516
- child: () => createNoOpLogger()
517
- };
518
- }
519
- /**
520
- * AsyncLocalStorage for logger context
521
- *
522
- * Enables implicit logger propagation throughout the call stack without
523
- * explicit parameter passing. The logger is stored per async context.
524
- */
525
- const loggerStorage = new AsyncLocalStorage();
526
- /**
527
- * Run a function with a logger stored in AsyncLocalStorage
528
- *
529
- * The logger is available to all code within the function via getLogger().
530
- * This is typically called at request entry points (fetch handler) and when
531
- * creating child loggers with additional context.
532
- *
533
- * @param logger Logger instance to store in context
534
- * @param fn Function to execute with logger context
535
- * @returns Result of the function
536
- *
537
- * @example
538
- * ```typescript
539
- * // At request entry point
540
- * async fetch(request: Request): Promise<Response> {
541
- * const logger = createLogger({ component: 'sandbox-do', traceId: 'tr_abc' });
542
- * return runWithLogger(logger, async () => {
543
- * return await this.handleRequest(request);
544
- * });
545
- * }
546
- *
547
- * // When adding operation context
548
- * async exec(command: string) {
549
- * const logger = getLogger().child({ operation: 'exec', commandId: 'cmd-123' });
550
- * return runWithLogger(logger, async () => {
551
- * logger.info('Command started');
552
- * await this.executeCommand(command); // Nested calls get the child logger
553
- * logger.info('Command completed');
554
- * });
555
- * }
556
- * ```
557
- */
558
- function runWithLogger(logger, fn) {
559
- return loggerStorage.run(logger, fn);
560
- }
561
- /**
562
- * Create a new logger instance
563
- *
564
- * @param context Base context for the logger. Must include 'component'.
565
- * TraceId will be auto-generated if not provided.
566
- * @returns New logger instance
567
- *
568
- * @example
569
- * ```typescript
570
- * // In Durable Object
571
- * const logger = createLogger({
572
- * component: 'sandbox-do',
573
- * traceId: TraceContext.fromHeaders(request.headers) || TraceContext.generate(),
574
- * sandboxId: this.id
575
- * });
576
- *
577
- * // In Container
578
- * const logger = createLogger({
579
- * component: 'container',
580
- * traceId: TraceContext.fromHeaders(request.headers)!,
581
- * sessionId: this.id
582
- * });
583
- * ```
584
- */
585
- function createLogger(context) {
586
- const minLevel = getLogLevelFromEnv();
587
- const pretty = isPrettyPrintEnabled();
588
- return new CloudflareLogger({
589
- ...context,
590
- traceId: context.traceId || TraceContext.generate(),
591
- component: context.component
592
- }, minLevel, pretty);
593
- }
594
- /**
595
- * Get log level from environment variable
596
- *
597
- * Checks SANDBOX_LOG_LEVEL env var, falls back to default based on environment.
598
- * Default: 'debug' for development, 'info' for production
599
- */
600
- function getLogLevelFromEnv() {
601
- switch ((getEnvVar("SANDBOX_LOG_LEVEL") || "info").toLowerCase()) {
602
- case "debug": return LogLevel.DEBUG;
603
- case "info": return LogLevel.INFO;
604
- case "warn": return LogLevel.WARN;
605
- case "error": return LogLevel.ERROR;
606
- default: return LogLevel.INFO;
607
- }
608
- }
609
- /**
610
- * Check if pretty printing should be enabled
611
- *
612
- * Checks SANDBOX_LOG_FORMAT env var, falls back to auto-detection:
613
- * - Local development: pretty (colored, human-readable)
614
- * - Production: json (structured)
615
- */
616
- function isPrettyPrintEnabled() {
617
- const format = getEnvVar("SANDBOX_LOG_FORMAT");
618
- if (format) return format.toLowerCase() === "pretty";
619
- return false;
620
- }
621
- /**
622
- * Get environment variable value
623
- *
624
- * Supports both Node.js (process.env) and Bun (Bun.env)
625
- */
626
- function getEnvVar(name) {
627
- if (typeof process !== "undefined" && process.env) return process.env[name];
628
- if (typeof Bun !== "undefined") {
629
- const bunEnv = Bun.env;
630
- if (bunEnv) return bunEnv[name];
631
- }
632
- }
633
-
634
- //#endregion
635
- //#region ../shared/dist/shell-escape.js
636
- /**
637
- * Escapes a string for safe use in shell commands using POSIX single-quote escaping.
638
- * Prevents command injection by wrapping the string in single quotes and escaping
639
- * any single quotes within the string.
640
- */
641
- function shellEscape(str) {
642
- return `'${str.replace(/'/g, "'\\''")}'`;
643
- }
644
-
645
- //#endregion
646
- //#region ../shared/dist/types.js
647
- function isExecResult(value) {
648
- return value && typeof value.success === "boolean" && typeof value.exitCode === "number" && typeof value.stdout === "string" && typeof value.stderr === "string";
649
- }
650
- function isProcess(value) {
651
- return value && typeof value.id === "string" && typeof value.command === "string" && typeof value.status === "string";
652
- }
653
- function isProcessStatus(value) {
654
- return [
655
- "starting",
656
- "running",
657
- "completed",
658
- "failed",
659
- "killed",
660
- "error"
661
- ].includes(value);
662
- }
663
-
664
- //#endregion
665
4
  //#region ../shared/dist/errors/codes.js
666
5
  /**
667
6
  * Centralized error code registry
@@ -2703,7 +2042,7 @@ function resolveS3fsOptions(provider, userOptions) {
2703
2042
  * This file is auto-updated by .github/changeset-version.ts during releases
2704
2043
  * DO NOT EDIT MANUALLY - Changes will be overwritten on the next version bump
2705
2044
  */
2706
- const SDK_VERSION = "0.5.1";
2045
+ const SDK_VERSION = "0.5.2";
2707
2046
 
2708
2047
  //#endregion
2709
2048
  //#region src/sandbox.ts
@@ -3028,8 +2367,12 @@ var Sandbox = class extends Container {
3028
2367
  this.logger.debug("Version compatibility check encountered an error", { error: error instanceof Error ? error.message : String(error) });
3029
2368
  }
3030
2369
  }
3031
- onStop() {
2370
+ async onStop() {
3032
2371
  this.logger.debug("Sandbox stopped");
2372
+ this.portTokens.clear();
2373
+ this.defaultSession = null;
2374
+ this.activeMounts.clear();
2375
+ await Promise.all([this.ctx.storage.delete("portTokens"), this.ctx.storage.delete("defaultSession")]);
3033
2376
  }
3034
2377
  onError(error) {
3035
2378
  this.logger.error("Sandbox error", error instanceof Error ? error : new Error(String(error)));
@@ -3109,28 +2452,26 @@ var Sandbox = class extends Container {
3109
2452
  traceId,
3110
2453
  operation: "fetch"
3111
2454
  });
3112
- return await runWithLogger(requestLogger, async () => {
3113
- const url = new URL(request.url);
3114
- if (!this.sandboxName && request.headers.has("X-Sandbox-Name")) {
3115
- const name = request.headers.get("X-Sandbox-Name");
3116
- this.sandboxName = name;
3117
- await this.ctx.storage.put("sandboxName", name);
3118
- }
3119
- const upgradeHeader = request.headers.get("Upgrade");
3120
- const connectionHeader = request.headers.get("Connection");
3121
- if (upgradeHeader?.toLowerCase() === "websocket" && connectionHeader?.toLowerCase().includes("upgrade")) try {
3122
- requestLogger.debug("WebSocket upgrade requested", {
3123
- path: url.pathname,
3124
- port: this.determinePort(url)
3125
- });
3126
- return await super.fetch(request);
3127
- } catch (error) {
3128
- requestLogger.error("WebSocket connection failed", error instanceof Error ? error : new Error(String(error)), { path: url.pathname });
3129
- throw error;
3130
- }
3131
- const port = this.determinePort(url);
3132
- return await this.containerFetch(request, port);
3133
- });
2455
+ const url = new URL(request.url);
2456
+ if (!this.sandboxName && request.headers.has("X-Sandbox-Name")) {
2457
+ const name = request.headers.get("X-Sandbox-Name");
2458
+ this.sandboxName = name;
2459
+ await this.ctx.storage.put("sandboxName", name);
2460
+ }
2461
+ const upgradeHeader = request.headers.get("Upgrade");
2462
+ const connectionHeader = request.headers.get("Connection");
2463
+ if (upgradeHeader?.toLowerCase() === "websocket" && connectionHeader?.toLowerCase().includes("upgrade")) try {
2464
+ requestLogger.debug("WebSocket upgrade requested", {
2465
+ path: url.pathname,
2466
+ port: this.determinePort(url)
2467
+ });
2468
+ return await super.fetch(request);
2469
+ } catch (error) {
2470
+ requestLogger.error("WebSocket connection failed", error instanceof Error ? error : new Error(String(error)), { path: url.pathname });
2471
+ throw error;
2472
+ }
2473
+ const port = this.determinePort(url);
2474
+ return await this.containerFetch(request, port);
3134
2475
  }
3135
2476
  wsConnect(request, port) {
3136
2477
  throw new Error("Not implemented here to avoid RPC serialization issues");