@cloudflare/sandbox 0.10.2 → 0.11.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.
@@ -584,6 +584,12 @@ interface PortWatchRequest extends PortCheckRequest {
584
584
  interval?: number;
585
585
  }
586
586
  interface ProcessOptions extends BaseExecOptions {
587
+ /**
588
+ * Optional session ID to run the background process in.
589
+ *
590
+ * When omitted, the sandbox's default execution policy applies.
591
+ */
592
+ sessionId?: string;
587
593
  /**
588
594
  * Custom process ID for later reference
589
595
  * If not provided, a UUID will be generated
@@ -713,6 +719,12 @@ interface LogEvent {
713
719
  exitCode?: number;
714
720
  }
715
721
  interface StreamOptions extends BaseExecOptions {
722
+ /**
723
+ * Optional session ID to run the streaming command in.
724
+ *
725
+ * When omitted, the sandbox's default execution policy applies.
726
+ */
727
+ sessionId?: string;
716
728
  /**
717
729
  * Buffer size for streaming output
718
730
  */
@@ -771,6 +783,16 @@ interface SandboxOptions {
771
783
  * Default: false
772
784
  */
773
785
  keepAlive?: boolean;
786
+ /**
787
+ * When true (the default), implicit operations automatically create and reuse
788
+ * a persistent default shell session. Set to false to run implicit top-level
789
+ * operations sessionlessly, where each command spawns a fresh process with no
790
+ * shared shell state. Explicit per-call session IDs continue to work normally
791
+ * when this is false.
792
+ *
793
+ * Default: true
794
+ */
795
+ enableDefaultSession?: boolean;
774
796
  /**
775
797
  * Normalize sandbox ID to lowercase for preview URL compatibility
776
798
  *
@@ -965,6 +987,12 @@ interface FileInfo {
965
987
  interface ListFilesOptions {
966
988
  recursive?: boolean;
967
989
  includeHidden?: boolean;
990
+ /**
991
+ * Optional session ID used to resolve relative paths and execution context.
992
+ *
993
+ * When omitted, the sandbox's default execution policy applies.
994
+ */
995
+ sessionId?: string;
968
996
  }
969
997
  interface ListFilesResult {
970
998
  success: boolean;
@@ -1162,6 +1190,8 @@ interface ProcessLogsResult {
1162
1190
  }
1163
1191
  interface ProcessCleanupResult {
1164
1192
  success: boolean;
1193
+ message?: string;
1194
+ killedCount?: number;
1165
1195
  cleanedCount: number;
1166
1196
  timestamp: string;
1167
1197
  }
@@ -1170,34 +1200,14 @@ interface SessionDeleteResult {
1170
1200
  sessionId: string;
1171
1201
  timestamp: string;
1172
1202
  }
1173
- interface PortExposeResult {
1174
- success: boolean;
1175
- port: number;
1176
- url: string;
1177
- timestamp: string;
1178
- }
1179
- interface PortListResult {
1180
- success: boolean;
1181
- ports: Array<{
1182
- port: number;
1183
- url: string;
1184
- status: 'active' | 'inactive';
1185
- }>;
1186
- timestamp: string;
1187
- }
1188
- interface PortCloseResult {
1189
- success: boolean;
1190
- port: number;
1191
- timestamp: string;
1192
- }
1193
1203
  interface ExecutionSession {
1194
1204
  /** Unique session identifier */
1195
1205
  readonly id: string;
1196
1206
  exec(command: string, options?: ExecOptions): Promise<ExecResult>;
1197
1207
  execStream(command: string, options?: StreamOptions): Promise<ReadableStream<Uint8Array>>;
1198
1208
  startProcess(command: string, options?: ProcessOptions): Promise<Process>;
1199
- listProcesses(): Promise<Process[]>;
1200
- getProcess(id: string): Promise<Process | null>;
1209
+ listProcesses(sessionId?: string): Promise<Process[]>;
1210
+ getProcess(id: string, sessionId?: string): Promise<Process | null>;
1201
1211
  killProcess(id: string, signal?: string): Promise<void>;
1202
1212
  killAllProcesses(): Promise<number>;
1203
1213
  cleanupCompletedProcesses(): Promise<number>;
@@ -1375,10 +1385,10 @@ interface RemoteMountBucketOptions {
1375
1385
  /**
1376
1386
  * Optional prefix/subdirectory within the bucket to mount.
1377
1387
  *
1378
- * When specified, only the contents under this prefix will be visible
1379
- * at the mount point, enabling multi-tenant isolation within a single bucket.
1388
+ * When specified, only the contents under this prefix are visible at the
1389
+ * mount point, scoping the mount to a subdirectory of the bucket.
1380
1390
  *
1381
- * Must start with '/' (e.g., '/sessions/user123' or '/data/uploads/')
1391
+ * Must start with '/' (e.g., '/workspaces/project123' or '/data/uploads/')
1382
1392
  */
1383
1393
  prefix?: string;
1384
1394
  }
@@ -1441,8 +1451,8 @@ type MountBucketOptions = RemoteMountBucketOptions | LocalMountBucketOptions | R
1441
1451
  interface ISandbox {
1442
1452
  exec(command: string, options?: ExecOptions): Promise<ExecResult>;
1443
1453
  startProcess(command: string, options?: ProcessOptions): Promise<Process>;
1444
- listProcesses(): Promise<Process[]>;
1445
- getProcess(id: string): Promise<Process | null>;
1454
+ listProcesses(sessionId?: string): Promise<Process[]>;
1455
+ getProcess(id: string, sessionId?: string): Promise<Process | null>;
1446
1456
  killProcess(id: string, signal?: string): Promise<void>;
1447
1457
  killAllProcesses(): Promise<number>;
1448
1458
  execStream(command: string, options?: StreamOptions): Promise<ReadableStream<Uint8Array>>;
@@ -1541,13 +1551,6 @@ interface StartProcessRequest {
1541
1551
  autoCleanup?: boolean;
1542
1552
  origin?: 'user' | 'internal';
1543
1553
  }
1544
- /**
1545
- * Request to expose a port
1546
- */
1547
- interface ExposePortRequest {
1548
- port: number;
1549
- name?: string;
1550
- }
1551
1554
  /**
1552
1555
  * Request to create a backup archive from a directory.
1553
1556
  * The container creates a squashfs archive at archivePath.
@@ -1629,6 +1632,7 @@ interface SandboxCommandsAPI {
1629
1632
  timeoutMs?: number;
1630
1633
  env?: Record<string, string | undefined>;
1631
1634
  cwd?: string;
1635
+ origin?: 'user' | 'internal';
1632
1636
  }): Promise<{
1633
1637
  success: boolean;
1634
1638
  exitCode: number;
@@ -1641,6 +1645,7 @@ interface SandboxCommandsAPI {
1641
1645
  timeoutMs?: number;
1642
1646
  env?: Record<string, string | undefined>;
1643
1647
  cwd?: string;
1648
+ origin?: 'user' | 'internal';
1644
1649
  }): Promise<ReadableStream<Uint8Array>>;
1645
1650
  }
1646
1651
  interface SandboxFilesAPI {
@@ -1683,9 +1688,6 @@ interface SandboxProcessesAPI {
1683
1688
  streamProcessLogs(id: string): Promise<ReadableStream<Uint8Array>>;
1684
1689
  }
1685
1690
  interface SandboxPortsAPI {
1686
- exposePort(port: number, sessionId: string, name?: string): Promise<PortExposeResult>;
1687
- getExposedPorts(sessionId: string): Promise<PortListResult>;
1688
- unexposePort(port: number, sessionId: string): Promise<PortCloseResult>;
1689
1691
  watchPort(request: PortWatchRequest): Promise<ReadableStream<Uint8Array>>;
1690
1692
  }
1691
1693
  interface SandboxGitAPI {
@@ -1805,26 +1807,61 @@ interface SandboxWatchAPI {
1805
1807
  checkChanges(request: CheckChangesRequest): Promise<CheckChangesResult>;
1806
1808
  }
1807
1809
  /**
1808
- * Public-facing tunnel record.
1809
- *
1810
- * Today only quick tunnels (`*.trycloudflare.com`) are supported. Future
1811
- * PRs will add named tunnels, which will carry a `name: string` field;
1812
- * `TunnelInfo` will then become a discriminated union keyed on the
1813
- * presence of `name`. The quick variant declares `name?: never` so the
1814
- * narrowing works without a breaking change here.
1810
+ * Public-facing tunnel record. Discriminated on the presence of `name`:
1811
+ * quick tunnels (`*.trycloudflare.com`) omit it, named tunnels carry the
1812
+ * label that was passed to `get(port, { name })`.
1815
1813
  */
1816
- interface TunnelInfo {
1814
+ type TunnelInfo = QuickTunnelInfo | NamedTunnelInfo;
1815
+ interface QuickTunnelInfo {
1817
1816
  id: string;
1818
1817
  port: number;
1818
+ /** `https://<random>.trycloudflare.com`. */
1819
1819
  url: string;
1820
+ /** Hostname portion of `url`. */
1820
1821
  hostname: string;
1821
1822
  createdAt: string;
1822
- /** Reserved for the named-tunnel variant in a future PR. */
1823
+ /** Absent on quick tunnels; narrows the union. */
1823
1824
  name?: never;
1824
1825
  }
1826
+ interface NamedTunnelInfo {
1827
+ /** Cloudflare tunnel UUID (8-4-4-4-12). */
1828
+ id: string;
1829
+ port: number;
1830
+ /** `https://<hostname>`. */
1831
+ url: string;
1832
+ /** Full hostname bound to the tunnel (without scheme). */
1833
+ hostname: string;
1834
+ createdAt: string;
1835
+ /** Label originally passed via `TunnelOptions.name`. */
1836
+ name: string;
1837
+ }
1838
+ /**
1839
+ * Options accepted by `sandbox.tunnels.get(port, options)`. Omitting
1840
+ * `name` (or omitting the options object) selects the zero-config quick
1841
+ * tunnel; setting `name` selects the named-tunnel flow.
1842
+ */
1843
+ interface TunnelOptions {
1844
+ /**
1845
+ * Single DNS label under the configured zone. The full hostname is
1846
+ * `<name>.<zone-name>`. See `validateTunnelName` for the format rules.
1847
+ */
1848
+ name?: string;
1849
+ }
1825
1850
  interface SandboxTunnelsAPI {
1826
1851
  /** Spawn `cloudflared tunnel --url`. No credentials required. */
1827
1852
  runQuickTunnel(id: string, port: number): Promise<TunnelInfo>;
1853
+ /**
1854
+ * Spawn `cloudflared tunnel run --token <token> --url http://localhost:<port>`.
1855
+ *
1856
+ * The SDK is the source of truth for the hostname this tunnel binds to;
1857
+ * the container only sees the opaque token and the local port. The
1858
+ * returned `TunnelInfo` carries empty `url`/`hostname` fields — the SDK
1859
+ * enriches them with the values from the Cloudflare API before handing
1860
+ * the record to user code.
1861
+ *
1862
+ * The token must never be logged, persisted, or echoed back to callers.
1863
+ */
1864
+ runNamedTunnel(id: string, token: string, port: number): Promise<TunnelInfo>;
1828
1865
  /** Stop the cloudflared process for the given tunnel id. */
1829
1866
  destroyTunnel(id: string): Promise<{
1830
1867
  success: true;
@@ -2502,33 +2539,9 @@ declare class InterpreterClient extends BaseHttpClient implements SandboxInterpr
2502
2539
  //#endregion
2503
2540
  //#region src/clients/port-client.d.ts
2504
2541
  /**
2505
- * Request interface for unexposing ports
2506
- */
2507
- interface UnexposePortRequest {
2508
- port: number;
2509
- }
2510
- /**
2511
- * Client for port management and preview URL operations
2542
+ * Client for port readiness operations.
2512
2543
  */
2513
- declare class PortClient extends BaseHttpClient implements SandboxPortsAPI {
2514
- /**
2515
- * Expose a port and get a preview URL
2516
- * @param port - Port number to expose
2517
- * @param sessionId - The session ID for this operation
2518
- * @param name - Optional name for the port
2519
- */
2520
- exposePort(port: number, sessionId: string, name?: string): Promise<PortExposeResult>;
2521
- /**
2522
- * Unexpose a port and remove its preview URL
2523
- * @param port - Port number to unexpose
2524
- * @param sessionId - The session ID for this operation
2525
- */
2526
- unexposePort(port: number, sessionId: string): Promise<PortCloseResult>;
2527
- /**
2528
- * Get all currently exposed ports
2529
- * @param sessionId - The session ID for this operation
2530
- */
2531
- getExposedPorts(sessionId: string): Promise<PortListResult>;
2544
+ declare class PortClient extends BaseHttpClient {
2532
2545
  /**
2533
2546
  * Watch a port for readiness via SSE stream
2534
2547
  * @param request - Port watch configuration
@@ -2901,7 +2914,7 @@ declare class ContainerControlClient {
2901
2914
  //#endregion
2902
2915
  //#region src/tunnels/tunnels-handler.d.ts
2903
2916
  interface TunnelsHandler {
2904
- get(port: number): Promise<TunnelInfo>;
2917
+ get(port: number, options?: TunnelOptions): Promise<TunnelInfo>;
2905
2918
  list(): Promise<TunnelInfo[]>;
2906
2919
  destroy(portOrInfo: number | TunnelInfo): Promise<void>;
2907
2920
  }
@@ -2926,6 +2939,7 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
2926
2939
  private sandboxName;
2927
2940
  private tunnelsHandler;
2928
2941
  private tunnelExitHandler;
2942
+ private destroyAllTunnels;
2929
2943
  private readonly controlCallback;
2930
2944
  private normalizeId;
2931
2945
  private defaultSession;
@@ -2935,6 +2949,7 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
2935
2949
  private logger;
2936
2950
  private keepAliveEnabled;
2937
2951
  private activeMounts;
2952
+ private currentRuntime;
2938
2953
  private transport;
2939
2954
  /**
2940
2955
  * True once transport has been written to storage at least once (either
@@ -2960,7 +2975,22 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
2960
2975
  private r2SecretAccessKey;
2961
2976
  private r2AccountId;
2962
2977
  private backupBucketName;
2978
+ private backupBucketEndpoint;
2963
2979
  private r2Client;
2980
+ /**
2981
+ * Lazily-resolved Cloudflare account id for named-tunnel provisioning.
2982
+ * Resolved on first access via `tunnels/credentials.ts` and cached for
2983
+ * the lifetime of this DO instance. See the credentials helper for
2984
+ * the precedence chain.
2985
+ */
2986
+ private tunnelAccountIdPromise;
2987
+ /**
2988
+ * Lazily-resolved Cloudflare zone id for named-tunnel provisioning.
2989
+ * Falls back to the single zone the token can see under the resolved
2990
+ * account id when `CLOUDFLARE_ZONE_ID` is not set. Cached for the
2991
+ * lifetime of this DO instance.
2992
+ */
2993
+ private tunnelZoneIdPromise;
2964
2994
  /**
2965
2995
  * Default container startup timeouts (conservative for production)
2966
2996
  * Based on Cloudflare docs: "Containers take several minutes to provision"
@@ -3033,29 +3063,9 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3033
3063
  setSleepAfter(sleepAfter: string | number): Promise<void>;
3034
3064
  setKeepAlive(keepAlive: boolean): Promise<void>;
3035
3065
  setEnvVars(envVars: Record<string, string | undefined>): Promise<void>;
3036
- /**
3037
- * RPC method to configure container startup timeouts. Idempotent once
3038
- * the values have been persisted: re-applying the same timeout set is a
3039
- * no-op. The transport retry budget is recomputed only when at least
3040
- * one timeout actually changes. Storage is written before the in-memory
3041
- * mirror and derived state are updated.
3042
- */
3043
3066
  setContainerTimeouts(timeouts: NonNullable<SandboxOptions['containerTimeouts']>): Promise<void>;
3044
- /**
3045
- * RPC method to set the transport protocol. Idempotent once the value
3046
- * has been persisted: re-applying the same transport is a no-op.
3047
- * Storage is written before the in-memory state and client are updated.
3048
- */
3049
3067
  setTransport(transport: SandboxTransport): Promise<void>;
3050
- /**
3051
- * Validate a timeout value is within acceptable range
3052
- * Throws error if invalid - used for user-provided values
3053
- */
3054
3068
  private validateTimeout;
3055
- /**
3056
- * Get default timeouts with env var fallbacks and validation
3057
- * Precedence: SDK defaults < Env vars < User config
3058
- */
3059
3069
  private getDefaultTimeouts;
3060
3070
  /**
3061
3071
  * Mount an S3-compatible bucket as a local directory.
@@ -3145,18 +3155,7 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3145
3155
  destroy(): Promise<void>;
3146
3156
  private doDestroy;
3147
3157
  onStart(): Promise<void>;
3148
- /**
3149
- * Re-expose ports on the container runtime using tokens persisted in DO
3150
- * storage. Called from onStart() after a container (re)start.
3151
- *
3152
- * The DO storage holds the source of truth for which ports should be
3153
- * exposed, which tokens authorize them, and the friendly name (if any)
3154
- * that the caller set when first exposing the port. If a port is already
3155
- * exposed on the container this is a no-op for that port. Individual port
3156
- * failures are logged but do not abort the overall restore — a transient
3157
- * failure for one port must not prevent the others from being restored.
3158
- */
3159
- private restoreExposedPorts;
3158
+ stop(signal?: Parameters<Container<Env>['stop']>[0]): Promise<void>;
3160
3159
  /**
3161
3160
  * Read the `portTokens` map from DO storage, normalizing the legacy
3162
3161
  * string-valued format (just a token) to the current object format
@@ -3164,6 +3163,10 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3164
3163
  * can appear on any DO whose storage was written before that change.
3165
3164
  */
3166
3165
  private readPortTokens;
3166
+ private readActivePreviewPorts;
3167
+ private writeActivePreviewPorts;
3168
+ private readPreviewState;
3169
+ private clearActivePreviewPorts;
3167
3170
  /**
3168
3171
  * Check if the container version matches the SDK version
3169
3172
  * Logs a warning if there's a mismatch
@@ -3218,6 +3221,14 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3218
3221
  * When keepAlive is disabled, calls parent implementation which stops the container
3219
3222
  */
3220
3223
  onActivityExpired(): Promise<void>;
3224
+ private isPreviewProxyRequest;
3225
+ private invalidPreviewTokenResponse;
3226
+ private stalePreviewURLResponse;
3227
+ private getPreviewForwardingContainer;
3228
+ private beginPreviewForward;
3229
+ private fetchPreviewIfRunning;
3230
+ private buildPreviewProxyRequest;
3231
+ private proxyPreviewRequest;
3221
3232
  fetch(request: Request): Promise<Response>;
3222
3233
  wsConnect(request: Request, port: number): Promise<Response>;
3223
3234
  private determinePort;
@@ -3244,7 +3255,24 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3244
3255
  * yet observed."
3245
3256
  */
3246
3257
  private capturePlacementId;
3258
+ private resolveExecution;
3259
+ private validateExplicitSessionId;
3260
+ private serializeExecutionContext;
3261
+ private getPublicExecutionSessionId;
3262
+ /**
3263
+ * Resolves the session ID to annotate returned Process objects.
3264
+ *
3265
+ * Unlike `resolveExecution`, this is synchronous and never creates a
3266
+ * session. When the default session hasn't been established yet, it returns
3267
+ * `undefined` rather than triggering session creation. The resolved value is
3268
+ * only used to populate `Process.sessionId` on the returned object — it is
3269
+ * never sent to the container API.
3270
+ */
3271
+ private getProcessSessionBinding;
3272
+ private resolveExecutionEnv;
3273
+ private buildExecutionRequestOptions;
3247
3274
  exec(command: string, options?: ExecOptions): Promise<ExecResult>;
3275
+ execWithSessionToken(command: string, sessionId: string, options?: ExecOptions): Promise<ExecResult>;
3248
3276
  /**
3249
3277
  * Execute an infrastructure command (backup, mount, env setup, etc.)
3250
3278
  * tagged with origin: 'internal' so logging demotes it to debug level.
@@ -3309,6 +3337,7 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3309
3337
  processId: string;
3310
3338
  }>;
3311
3339
  execStream(command: string, options?: StreamOptions): Promise<ReadableStream<Uint8Array>>;
3340
+ execStreamWithSessionToken(command: string, sessionId: string, options?: StreamOptions): Promise<ReadableStream<Uint8Array>>;
3312
3341
  /**
3313
3342
  * Internal session-aware execStream implementation
3314
3343
  */
@@ -3371,10 +3400,7 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3371
3400
  readFileStream(path: string, options?: {
3372
3401
  sessionId?: string;
3373
3402
  }): Promise<ReadableStream<Uint8Array>>;
3374
- listFiles(path: string, options?: {
3375
- recursive?: boolean;
3376
- includeHidden?: boolean;
3377
- }): Promise<ListFilesResult>;
3403
+ listFiles(path: string, options?: ListFilesOptions): Promise<ListFilesResult>;
3378
3404
  exists(path: string, sessionId?: string): Promise<FileExistsResult>;
3379
3405
  /**
3380
3406
  * Get the noVNC preview URL for browser-based desktop viewing.
@@ -3421,11 +3447,10 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3421
3447
  /**
3422
3448
  * Expose a port and get a preview URL for accessing services running in the sandbox
3423
3449
  *
3424
- * Preview URLs survive transient container restarts: the token and any
3425
- * friendly name are persisted in Durable Object storage, and the port is
3426
- * automatically re-exposed on the container when it comes back up. Tokens
3427
- * are cleared only on explicit `unexposePort()` or full sandbox
3428
- * `destroy()`.
3450
+ * Preview URL authorization survives transient container restarts, but
3451
+ * forwarding is active only for the runtime where `exposePort()` was last
3452
+ * called. Call `exposePort()` again after a restart to reactivate an
3453
+ * existing URL for the current runtime.
3429
3454
  *
3430
3455
  * @param port - Port number to expose (1024-65535)
3431
3456
  * @param options - Configuration options
@@ -3457,11 +3482,22 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3457
3482
  port: number;
3458
3483
  name: string | undefined;
3459
3484
  }>;
3485
+ /**
3486
+ * Revoke preview URL authorization and current-runtime activation for a port.
3487
+ *
3488
+ * Revocation is idempotent: calling this for a port with no preview state is
3489
+ * still successful. The operation clears Durable Object-owned preview state
3490
+ * only and does not contact, probe, wake, or clean up the container runtime.
3491
+ */
3460
3492
  unexposePort(port: number): Promise<void>;
3493
+ /**
3494
+ * Returns preview URLs that are currently forwardable in the active runtime.
3495
+ * Durable authorization without current-runtime activation is omitted.
3496
+ */
3461
3497
  getExposedPorts(hostname: string): Promise<{
3462
3498
  url: string;
3463
3499
  port: number;
3464
- status: "active" | "inactive";
3500
+ status: "active";
3465
3501
  }[]>;
3466
3502
  /**
3467
3503
  * Namespaced tunnel API. Quick tunnels are zero-config preview URLs
@@ -3490,8 +3526,45 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3490
3526
  * fields.
3491
3527
  */
3492
3528
  private ensureTunnelsBuilt;
3529
+ /**
3530
+ * Resolve the Cloudflare account id used for named-tunnel provisioning.
3531
+ *
3532
+ * Memoised for the lifetime of this DO instance. The first call may hit
3533
+ * `GET /user/tokens/verify` to derive the account id from the configured
3534
+ * `CLOUDFLARE_API_TOKEN`; subsequent calls return the cached promise.
3535
+ *
3536
+ * Only successful resolutions are cached: a rejected lookup clears the
3537
+ * slot so the next caller retries. Otherwise a transient failure on
3538
+ * first use would permanently poison every later named-tunnel `get()`
3539
+ * on this DO instance.
3540
+ */
3541
+ private getTunnelAccountId;
3542
+ /**
3543
+ * Resolve the Cloudflare zone id used for named-tunnel provisioning.
3544
+ *
3545
+ * Memoised for the lifetime of this DO instance. Falls back to the
3546
+ * single zone the token can see under `accountId` via `GET /zones`
3547
+ * when `CLOUDFLARE_ZONE_ID` is not set. Failed lookups clear the cache
3548
+ * so the next caller retries — see `getTunnelAccountId` for the
3549
+ * rationale.
3550
+ */
3551
+ private getTunnelZoneId;
3552
+ /**
3553
+ * Returns whether a port is currently preview-forwardable.
3554
+ * This checks Durable Object-owned auth and runtime activation without
3555
+ * contacting or waking the container.
3556
+ */
3493
3557
  isPortExposed(port: number): Promise<boolean>;
3558
+ /**
3559
+ * Checks durable preview URL authorization for a port/token pair.
3560
+ *
3561
+ * This does not check whether the port is activated for the current runtime
3562
+ * and is not sufficient to decide whether preview traffic may forward.
3563
+ */
3494
3564
  validatePortToken(port: number, token: string): Promise<boolean>;
3565
+ private validatePreviewURLForRuntime;
3566
+ private getCurrentPreviewPorts;
3567
+ private previewTokensMatch;
3495
3568
  private validateCustomToken;
3496
3569
  private generatePortToken;
3497
3570
  private constructPreviewUrl;
@@ -3571,17 +3644,19 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3571
3644
  * Returns validated presigned URL configuration or throws if not configured.
3572
3645
  * All credential fields plus the R2 binding are required for backup to work.
3573
3646
  */
3574
- private requirePresignedUrlSupport;
3647
+ private requirePresignedURLSupport;
3648
+ private getBackupBucketEndpoint;
3649
+ private getBackupObjectURL;
3575
3650
  /**
3576
3651
  * Generate a presigned GET URL for downloading an object from R2.
3577
3652
  * The container can curl this URL directly without credentials.
3578
3653
  */
3579
- private generatePresignedGetUrl;
3654
+ private generatePresignedGetURL;
3580
3655
  /**
3581
3656
  * Generate a presigned PUT URL for uploading an object to R2.
3582
3657
  * The container can curl PUT to this URL directly without credentials.
3583
3658
  */
3584
- private generatePresignedPutUrl;
3659
+ private generatePresignedPutURL;
3585
3660
  /**
3586
3661
  * Upload a backup archive via presigned PUT URL.
3587
3662
  * The container curls the archive directly to R2, bypassing the DO.
@@ -3591,7 +3666,7 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3591
3666
  /**
3592
3667
  * Generate a presigned PUT URL for a single part in a multipart upload.
3593
3668
  */
3594
- private generatePresignedPartUrl;
3669
+ private generatePresignedPartURL;
3595
3670
  /**
3596
3671
  * Upload a backup archive to R2 using parallel multipart upload.
3597
3672
  * Uses the S3-compatible API exclusively for create/complete/abort so that
@@ -3685,5 +3760,5 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3685
3760
  private configureR2EgressOutbound;
3686
3761
  }
3687
3762
  //#endregion
3688
- export { StartProcessRequest as $, DesktopStopResponse as A, ProcessOptions as At, ExecuteResponse as B, WaitForPortOptions as Bt, ClickOptions as C, PortListResult as Ct, DesktopStartOptions as D, ProcessKillResult as Dt, DesktopClient as E, ProcessInfoResult as Et, ScreenshotRegion as F, SandboxOptions as Ft, HttpClientOptions as G, PtyOptions as Gt, BaseApiResponse as H, isExecResult as Ht, ScreenshotResponse as I, SandboxTransport as It, SessionRequest as J, Execution as Jt, RequestConfig as K, CodeContext as Kt, ScrollDirection as L, SessionOptions as Lt, ScreenSizeResponse as M, ProcessStatus as Mt, ScreenshotBytesResponse as N, RemoteMountBucketOptions as Nt, DesktopStartResponse as O, ProcessListResult as Ot, ScreenshotOptions as P, RestoreBackupResult as Pt, ExposePortRequest as Q, TypeOptions as R, StreamOptions as Rt, WriteFileRequest as S, PortExposeResult as St, Desktop as T, ProcessCleanupResult as Tt, ContainerStub as U, isProcess as Ut, BackupClient as V, WatchOptions as Vt, ErrorResponse as W, isProcessStatus as Wt, TunnelInfo as X, RunCodeOptions as Xt, SandboxInterpreterAPI as Y, ExecutionResult as Yt, ExecuteRequest as Z, GitClient as _, ListFilesOptions as _t, CreateSessionRequest as a, CheckChangesResult as at, MkdirRequest as b, MountBucketOptions as bt, DeleteSessionResponse as c, ExecOptions as ct, ProcessClient as d, FileChunk as dt, BackupOptions as et, PortClient as f, FileMetadata as ft, GitCheckoutRequest as g, ISandbox as gt, InterpreterClient as h, GitCheckoutResult as ht, CommandsResponse as i, CheckChangesOptions as it, KeyInput as j, ProcessStartResult as jt, DesktopStatusResponse as k, ProcessLogsResult as kt, PingResponse as l, ExecResult as lt, ExecutionCallbacks as m, FileWatchSSEEvent as mt, getSandbox as n, BucketCredentials as nt, CreateSessionResponse as o, DirectoryBackup as ot, UnexposePortRequest as p, FileStreamEvent as pt, ResponseHandler as q, CreateContextOptions as qt, SandboxClient as r, BucketProvider as rt, DeleteSessionRequest as s, ExecEvent as st, Sandbox as t, BaseExecOptions as tt, UtilityClient as u, ExecutionSession as ut, FileClient as v, LocalMountBucketOptions as vt, CursorPositionResponse as w, Process as wt, ReadFileRequest as x, PortCloseResult as xt, FileOperationRequest as y, LogEvent as yt, CommandClient as z, WaitForLogResult as zt };
3689
- //# sourceMappingURL=sandbox-KdzTTnWq.d.ts.map
3763
+ export { ExecuteRequest as $, KeyInput as A, ProcessStatus as At, BackupClient as B, isExecResult as Bt, CursorPositionResponse as C, ProcessCleanupResult as Ct, DesktopStartResponse as D, ProcessLogsResult as Dt, DesktopStartOptions as E, ProcessListResult as Et, ScreenshotResponse as F, SessionOptions as Ft, RequestConfig as G, CreateContextOptions as Gt, ContainerStub as H, isProcessStatus as Ht, ScrollDirection as I, StreamOptions as It, NamedTunnelInfo as J, RunCodeOptions as Jt, ResponseHandler as K, Execution as Kt, TypeOptions as L, WaitForLogResult as Lt, ScreenshotBytesResponse as M, RestoreBackupResult as Mt, ScreenshotOptions as N, SandboxOptions as Nt, DesktopStatusResponse as O, ProcessOptions as Ot, ScreenshotRegion as P, SandboxTransport as Pt, TunnelOptions as Q, CommandClient as R, WaitForPortOptions as Rt, ClickOptions as S, Process as St, DesktopClient as T, ProcessKillResult as Tt, ErrorResponse as U, PtyOptions as Ut, BaseApiResponse as V, isProcess as Vt, HttpClientOptions as W, CodeContext as Wt, SandboxInterpreterAPI as X, QuickTunnelInfo as Y, TunnelInfo as Z, FileClient as _, ISandbox as _t, CreateSessionRequest as a, CheckChangesOptions as at, ReadFileRequest as b, LogEvent as bt, DeleteSessionResponse as c, ExecEvent as ct, ProcessClient as d, ExecutionSession as dt, StartProcessRequest as et, PortClient as f, FileChunk as ft, GitClient as g, GitCheckoutResult as gt, GitCheckoutRequest as h, FileWatchSSEEvent as ht, CommandsResponse as i, BucketProvider as it, ScreenSizeResponse as j, RemoteMountBucketOptions as jt, DesktopStopResponse as k, ProcessStartResult as kt, PingResponse as l, ExecOptions as lt, InterpreterClient as m, FileStreamEvent as mt, getSandbox as n, BaseExecOptions as nt, CreateSessionResponse as o, CheckChangesResult as ot, ExecutionCallbacks as p, FileMetadata as pt, SessionRequest as q, ExecutionResult as qt, SandboxClient as r, BucketCredentials as rt, DeleteSessionRequest as s, DirectoryBackup as st, Sandbox as t, BackupOptions as tt, UtilityClient as u, ExecResult as ut, FileOperationRequest as v, ListFilesOptions as vt, Desktop as w, ProcessInfoResult as wt, WriteFileRequest as x, MountBucketOptions as xt, MkdirRequest as y, LocalMountBucketOptions as yt, ExecuteResponse as z, WatchOptions as zt };
3764
+ //# sourceMappingURL=sandbox-B9LOT0cg.d.ts.map