@cloudflare/sandbox 0.0.8 → 0.1.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.
- package/CHANGELOG.md +16 -0
- package/Dockerfile +73 -9
- package/container_src/handler/exec.ts +337 -0
- package/container_src/handler/file.ts +844 -0
- package/container_src/handler/git.ts +182 -0
- package/container_src/handler/ports.ts +314 -0
- package/container_src/handler/process.ts +640 -0
- package/container_src/index.ts +102 -2647
- package/container_src/types.ts +103 -0
- package/dist/chunk-6THNBO4S.js +46 -0
- package/dist/chunk-6THNBO4S.js.map +1 -0
- package/dist/chunk-6UAWTJ5S.js +85 -0
- package/dist/chunk-6UAWTJ5S.js.map +1 -0
- package/dist/chunk-G4XT4SP7.js +638 -0
- package/dist/chunk-G4XT4SP7.js.map +1 -0
- package/dist/chunk-ISFOIYQC.js +585 -0
- package/dist/chunk-ISFOIYQC.js.map +1 -0
- package/dist/chunk-NNGBXDMY.js +89 -0
- package/dist/chunk-NNGBXDMY.js.map +1 -0
- package/dist/client-Da-mLX4p.d.ts +210 -0
- package/dist/client.d.ts +2 -1
- package/dist/client.js +3 -37
- package/dist/index.d.ts +5 -200
- package/dist/index.js +17 -106
- package/dist/index.js.map +1 -1
- package/dist/request-handler.d.ts +16 -0
- package/dist/request-handler.js +12 -0
- package/dist/request-handler.js.map +1 -0
- package/dist/sandbox.d.ts +3 -0
- package/dist/sandbox.js +12 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/security.d.ts +30 -0
- package/dist/security.js +13 -0
- package/dist/security.js.map +1 -0
- package/dist/sse-parser.d.ts +28 -0
- package/dist/sse-parser.js +11 -0
- package/dist/sse-parser.js.map +1 -0
- package/dist/types.d.ts +284 -0
- package/dist/types.js +19 -0
- package/dist/types.js.map +1 -0
- package/package.json +2 -7
- package/src/client.ts +320 -1242
- package/src/index.ts +20 -136
- package/src/request-handler.ts +144 -0
- package/src/sandbox.ts +645 -0
- package/src/security.ts +113 -0
- package/src/sse-parser.ts +147 -0
- package/src/types.ts +386 -0
- package/README.md +0 -65
- package/dist/chunk-7WZJ3TRE.js +0 -1364
- package/dist/chunk-7WZJ3TRE.js.map +0 -1
- package/tests/client.example.ts +0 -308
- package/tests/connection-test.ts +0 -81
- package/tests/simple-test.ts +0 -81
- package/tests/test1.ts +0 -281
- package/tests/test2.ts +0 -929
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sandbox.ts","../src/request-handler.ts"],"sourcesContent":["import { Container, getContainer } from \"@cloudflare/containers\";\nimport { HttpClient } from \"./client\";\nimport { isLocalhostPattern } from \"./request-handler\";\nimport {\n logSecurityEvent,\n SecurityError,\n sanitizeSandboxId,\n validatePort\n} from \"./security\";\nimport type {\n ExecOptions,\n ExecResult,\n ISandbox,\n Process,\n ProcessOptions,\n ProcessStatus,\n StreamOptions\n} from \"./types\";\nimport {\n ProcessNotFoundError,\n SandboxError\n} from \"./types\";\n\nexport function getSandbox(ns: DurableObjectNamespace<Sandbox>, id: string) {\n const stub = getContainer(ns, id);\n\n // Store the name on first access\n stub.setSandboxName?.(id);\n\n return stub;\n}\n\nexport class Sandbox<Env = unknown> extends Container<Env> implements ISandbox {\n sleepAfter = \"3m\"; // Sleep the sandbox if no requests are made in this timeframe\n client: HttpClient;\n private sandboxName: string | null = null;\n\n constructor(ctx: DurableObjectState, env: Env) {\n super(ctx, env);\n this.client = new HttpClient({\n onCommandComplete: (success, exitCode, _stdout, _stderr, command) => {\n console.log(\n `[Container] Command completed: ${command}, Success: ${success}, Exit code: ${exitCode}`\n );\n },\n onCommandStart: (command) => {\n console.log(\n `[Container] Command started: ${command}`\n );\n },\n onError: (error, _command) => {\n console.error(`[Container] Command error: ${error}`);\n },\n onOutput: (stream, data, _command) => {\n console.log(`[Container] [${stream}] ${data}`);\n },\n port: 3000, // Control plane port\n stub: this,\n });\n\n // Load the sandbox name from storage on initialization\n this.ctx.blockConcurrencyWhile(async () => {\n this.sandboxName = await this.ctx.storage.get<string>('sandboxName') || null;\n });\n }\n\n // RPC method to set the sandbox name\n async setSandboxName(name: string): Promise<void> {\n if (!this.sandboxName) {\n this.sandboxName = name;\n await this.ctx.storage.put('sandboxName', name);\n console.log(`[Sandbox] Stored sandbox name via RPC: ${name}`);\n }\n }\n\n // RPC method to set environment variables\n async setEnvVars(envVars: Record<string, string>): Promise<void> {\n this.envVars = { ...this.envVars, ...envVars };\n console.log(`[Sandbox] Updated environment variables`);\n }\n\n override onStart() {\n console.log(\"Sandbox successfully started\");\n }\n\n override onStop() {\n console.log(\"Sandbox successfully shut down\");\n if (this.client) {\n this.client.clearSession();\n }\n }\n\n override onError(error: unknown) {\n console.log(\"Sandbox error:\", error);\n }\n\n // Override fetch to route internal container requests to appropriate ports\n override async fetch(request: Request): Promise<Response> {\n const url = new URL(request.url);\n\n // Capture and store the sandbox name from the header if present\n if (!this.sandboxName && request.headers.has('X-Sandbox-Name')) {\n const name = request.headers.get('X-Sandbox-Name')!;\n this.sandboxName = name;\n await this.ctx.storage.put('sandboxName', name);\n console.log(`[Sandbox] Stored sandbox name: ${this.sandboxName}`);\n }\n\n // Determine which port to route to\n const port = this.determinePort(url);\n\n // Route to the appropriate port\n return await this.containerFetch(request, port);\n }\n\n private determinePort(url: URL): number {\n // Extract port from proxy requests (e.g., /proxy/8080/*)\n const proxyMatch = url.pathname.match(/^\\/proxy\\/(\\d+)/);\n if (proxyMatch) {\n return parseInt(proxyMatch[1]);\n }\n\n // All other requests go to control plane on port 3000\n // This includes /api/* endpoints and any other control requests\n return 3000;\n }\n\n // Enhanced exec method - always returns ExecResult with optional streaming\n // This replaces the old exec method to match ISandbox interface\n async exec(command: string, options?: ExecOptions): Promise<ExecResult> {\n const startTime = Date.now();\n const timestamp = new Date().toISOString();\n\n // Handle timeout\n let timeoutId: NodeJS.Timeout | undefined;\n\n try {\n // Handle cancellation\n if (options?.signal?.aborted) {\n throw new Error('Operation was aborted');\n }\n\n let result: ExecResult;\n\n if (options?.stream && options?.onOutput) {\n // Streaming with callbacks - we need to collect the final result\n result = await this.executeWithStreaming(command, options, startTime, timestamp);\n } else {\n // Regular execution\n const response = await this.client.execute(\n command,\n options?.sessionId\n );\n\n const duration = Date.now() - startTime;\n result = this.mapExecuteResponseToExecResult(response, duration, options?.sessionId);\n }\n\n // Call completion callback if provided\n if (options?.onComplete) {\n options.onComplete(result);\n }\n\n return result;\n } catch (error) {\n if (options?.onError && error instanceof Error) {\n options.onError(error);\n }\n throw error;\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n }\n\n private async executeWithStreaming(\n command: string,\n options: ExecOptions,\n startTime: number,\n timestamp: string\n ): Promise<ExecResult> {\n let stdout = '';\n let stderr = '';\n\n try {\n const stream = await this.client.executeCommandStream(command, options.sessionId);\n const { parseSSEStream } = await import('./sse-parser');\n\n for await (const event of parseSSEStream<import('./types').ExecEvent>(stream)) {\n // Check for cancellation\n if (options.signal?.aborted) {\n throw new Error('Operation was aborted');\n }\n\n switch (event.type) {\n case 'stdout':\n case 'stderr':\n if (event.data) {\n // Update accumulated output\n if (event.type === 'stdout') stdout += event.data;\n if (event.type === 'stderr') stderr += event.data;\n\n // Call user's callback\n if (options.onOutput) {\n options.onOutput(event.type, event.data);\n }\n }\n break;\n\n case 'complete': {\n // Use result from complete event if available\n const duration = Date.now() - startTime;\n return event.result || {\n success: event.exitCode === 0,\n exitCode: event.exitCode || 0,\n stdout,\n stderr,\n command,\n duration,\n timestamp,\n sessionId: options.sessionId\n };\n }\n\n case 'error':\n throw new Error(event.error || 'Command execution failed');\n }\n }\n\n // If we get here without a complete event, something went wrong\n throw new Error('Stream ended without completion event');\n\n } catch (error) {\n if (options.signal?.aborted) {\n throw new Error('Operation was aborted');\n }\n throw error;\n }\n }\n\n private mapExecuteResponseToExecResult(\n response: import('./client').ExecuteResponse,\n duration: number,\n sessionId?: string\n ): ExecResult {\n return {\n success: response.success,\n exitCode: response.exitCode,\n stdout: response.stdout,\n stderr: response.stderr,\n command: response.command,\n duration,\n timestamp: response.timestamp,\n sessionId\n };\n }\n\n\n // Background process management\n async startProcess(command: string, options?: ProcessOptions): Promise<Process> {\n // Use the new HttpClient method to start the process\n try {\n const response = await this.client.startProcess(command, {\n processId: options?.processId,\n sessionId: options?.sessionId,\n timeout: options?.timeout,\n env: options?.env,\n cwd: options?.cwd,\n encoding: options?.encoding,\n autoCleanup: options?.autoCleanup\n });\n\n const process = response.process;\n const processObj: Process = {\n id: process.id,\n pid: process.pid,\n command: process.command,\n status: process.status as ProcessStatus,\n startTime: new Date(process.startTime),\n endTime: undefined,\n exitCode: undefined,\n sessionId: process.sessionId,\n\n async kill(): Promise<void> {\n throw new Error('Method will be replaced');\n },\n async getStatus(): Promise<ProcessStatus> {\n throw new Error('Method will be replaced');\n },\n async getLogs(): Promise<{ stdout: string; stderr: string }> {\n throw new Error('Method will be replaced');\n }\n };\n\n // Bind context properly\n processObj.kill = async (signal?: string) => {\n await this.killProcess(process.id, signal);\n };\n\n processObj.getStatus = async () => {\n const current = await this.getProcess(process.id);\n return current?.status || 'error';\n };\n\n processObj.getLogs = async () => {\n const logs = await this.getProcessLogs(process.id);\n return { stdout: logs.stdout, stderr: logs.stderr };\n };\n\n // Call onStart callback if provided\n if (options?.onStart) {\n options.onStart(processObj);\n }\n\n return processObj;\n\n } catch (error) {\n if (options?.onError && error instanceof Error) {\n options.onError(error);\n }\n\n throw error;\n }\n }\n\n async listProcesses(): Promise<Process[]> {\n const response = await this.client.listProcesses();\n\n return response.processes.map(processData => ({\n id: processData.id,\n pid: processData.pid,\n command: processData.command,\n status: processData.status,\n startTime: new Date(processData.startTime),\n endTime: processData.endTime ? new Date(processData.endTime) : undefined,\n exitCode: processData.exitCode,\n sessionId: processData.sessionId,\n\n kill: async (signal?: string) => {\n await this.killProcess(processData.id, signal);\n },\n\n getStatus: async () => {\n const current = await this.getProcess(processData.id);\n return current?.status || 'error';\n },\n\n getLogs: async () => {\n const logs = await this.getProcessLogs(processData.id);\n return { stdout: logs.stdout, stderr: logs.stderr };\n }\n }));\n }\n\n async getProcess(id: string): Promise<Process | null> {\n const response = await this.client.getProcess(id);\n if (!response.process) {\n return null;\n }\n\n const processData = response.process;\n return {\n id: processData.id,\n pid: processData.pid,\n command: processData.command,\n status: processData.status,\n startTime: new Date(processData.startTime),\n endTime: processData.endTime ? new Date(processData.endTime) : undefined,\n exitCode: processData.exitCode,\n sessionId: processData.sessionId,\n\n kill: async (signal?: string) => {\n await this.killProcess(processData.id, signal);\n },\n\n getStatus: async () => {\n const current = await this.getProcess(processData.id);\n return current?.status || 'error';\n },\n\n getLogs: async () => {\n const logs = await this.getProcessLogs(processData.id);\n return { stdout: logs.stdout, stderr: logs.stderr };\n }\n };\n }\n\n async killProcess(id: string, _signal?: string): Promise<void> {\n try {\n // Note: signal parameter is not currently supported by the HttpClient implementation\n await this.client.killProcess(id);\n } catch (error) {\n if (error instanceof Error && error.message.includes('Process not found')) {\n throw new ProcessNotFoundError(id);\n }\n throw new SandboxError(\n `Failed to kill process ${id}: ${error instanceof Error ? error.message : 'Unknown error'}`,\n 'KILL_PROCESS_FAILED'\n );\n }\n }\n\n async killAllProcesses(): Promise<number> {\n const response = await this.client.killAllProcesses();\n return response.killedCount;\n }\n\n async cleanupCompletedProcesses(): Promise<number> {\n // For now, this would need to be implemented as a container endpoint\n // as we no longer maintain local process storage\n // We'll return 0 as a placeholder until the container endpoint is added\n return 0;\n }\n\n async getProcessLogs(id: string): Promise<{ stdout: string; stderr: string }> {\n try {\n const response = await this.client.getProcessLogs(id);\n return {\n stdout: response.stdout,\n stderr: response.stderr\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes('Process not found')) {\n throw new ProcessNotFoundError(id);\n }\n throw error;\n }\n }\n\n\n // Streaming methods - return ReadableStream for RPC compatibility\n async execStream(command: string, options?: StreamOptions): Promise<ReadableStream<Uint8Array>> {\n // Check for cancellation\n if (options?.signal?.aborted) {\n throw new Error('Operation was aborted');\n }\n\n // Get the stream from HttpClient (need to add this method)\n const stream = await this.client.executeCommandStream(command, options?.sessionId);\n\n // Return the ReadableStream directly - can be converted to AsyncIterable by consumers\n return stream;\n }\n\n async streamProcessLogs(processId: string, options?: { signal?: AbortSignal }): Promise<ReadableStream<Uint8Array>> {\n // Check for cancellation\n if (options?.signal?.aborted) {\n throw new Error('Operation was aborted');\n }\n\n // Get the stream from HttpClient\n const stream = await this.client.streamProcessLogs(processId);\n\n // Return the ReadableStream directly - can be converted to AsyncIterable by consumers\n return stream;\n }\n\n async gitCheckout(\n repoUrl: string,\n options: { branch?: string; targetDir?: string }\n ) {\n return this.client.gitCheckout(repoUrl, options.branch, options.targetDir);\n }\n\n async mkdir(\n path: string,\n options: { recursive?: boolean } = {}\n ) {\n return this.client.mkdir(path, options.recursive);\n }\n\n async writeFile(\n path: string,\n content: string,\n options: { encoding?: string } = {}\n ) {\n return this.client.writeFile(path, content, options.encoding);\n }\n\n async deleteFile(path: string) {\n return this.client.deleteFile(path);\n }\n\n async renameFile(\n oldPath: string,\n newPath: string\n ) {\n return this.client.renameFile(oldPath, newPath);\n }\n\n async moveFile(\n sourcePath: string,\n destinationPath: string\n ) {\n return this.client.moveFile(sourcePath, destinationPath);\n }\n\n async readFile(\n path: string,\n options: { encoding?: string } = {}\n ) {\n return this.client.readFile(path, options.encoding);\n }\n\n async exposePort(port: number, options: { name?: string; hostname: string }) {\n await this.client.exposePort(port, options?.name);\n\n // We need the sandbox name to construct preview URLs\n if (!this.sandboxName) {\n throw new Error('Sandbox name not available. Ensure sandbox is accessed through getSandbox()');\n }\n\n const url = this.constructPreviewUrl(port, this.sandboxName, options.hostname);\n\n return {\n url,\n port,\n name: options?.name,\n };\n }\n\n async unexposePort(port: number) {\n if (!validatePort(port)) {\n logSecurityEvent('INVALID_PORT_UNEXPOSE', {\n port\n }, 'high');\n throw new SecurityError(`Invalid port number: ${port}. Must be between 1024-65535 and not reserved.`);\n }\n\n await this.client.unexposePort(port);\n\n logSecurityEvent('PORT_UNEXPOSED', {\n port\n }, 'low');\n }\n\n async getExposedPorts(hostname: string) {\n const response = await this.client.getExposedPorts();\n\n // We need the sandbox name to construct preview URLs\n if (!this.sandboxName) {\n throw new Error('Sandbox name not available. Ensure sandbox is accessed through getSandbox()');\n }\n\n return response.ports.map(port => ({\n url: this.constructPreviewUrl(port.port, this.sandboxName!, hostname),\n port: port.port,\n name: port.name,\n exposedAt: port.exposedAt,\n }));\n }\n\n\n private constructPreviewUrl(port: number, sandboxId: string, hostname: string): string {\n if (!validatePort(port)) {\n logSecurityEvent('INVALID_PORT_REJECTED', {\n port,\n sandboxId,\n hostname\n }, 'high');\n throw new SecurityError(`Invalid port number: ${port}. Must be between 1024-65535 and not reserved.`);\n }\n\n let sanitizedSandboxId: string;\n try {\n sanitizedSandboxId = sanitizeSandboxId(sandboxId);\n } catch (error) {\n logSecurityEvent('INVALID_SANDBOX_ID_REJECTED', {\n sandboxId,\n port,\n hostname,\n error: error instanceof Error ? error.message : 'Unknown error'\n }, 'high');\n throw error;\n }\n\n const isLocalhost = isLocalhostPattern(hostname);\n\n if (isLocalhost) {\n // Unified subdomain approach for localhost (RFC 6761)\n const [host, portStr] = hostname.split(':');\n const mainPort = portStr || '80';\n\n // Use URL constructor for safe URL building\n try {\n const baseUrl = new URL(`http://${host}:${mainPort}`);\n // Construct subdomain safely\n const subdomainHost = `${port}-${sanitizedSandboxId}.${host}`;\n baseUrl.hostname = subdomainHost;\n\n const finalUrl = baseUrl.toString();\n\n logSecurityEvent('PREVIEW_URL_CONSTRUCTED', {\n port,\n sandboxId: sanitizedSandboxId,\n hostname,\n resultUrl: finalUrl,\n environment: 'localhost'\n }, 'low');\n\n return finalUrl;\n } catch (error) {\n logSecurityEvent('URL_CONSTRUCTION_FAILED', {\n port,\n sandboxId: sanitizedSandboxId,\n hostname,\n error: error instanceof Error ? error.message : 'Unknown error'\n }, 'high');\n throw new SecurityError(`Failed to construct preview URL: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n\n // Production subdomain logic - enforce HTTPS\n try {\n // Always use HTTPS for production (non-localhost)\n const protocol = \"https\";\n const baseUrl = new URL(`${protocol}://${hostname}`);\n\n // Construct subdomain safely\n const subdomainHost = `${port}-${sanitizedSandboxId}.${hostname}`;\n baseUrl.hostname = subdomainHost;\n\n const finalUrl = baseUrl.toString();\n\n logSecurityEvent('PREVIEW_URL_CONSTRUCTED', {\n port,\n sandboxId: sanitizedSandboxId,\n hostname,\n resultUrl: finalUrl,\n environment: 'production'\n }, 'low');\n\n return finalUrl;\n } catch (error) {\n logSecurityEvent('URL_CONSTRUCTION_FAILED', {\n port,\n sandboxId: sanitizedSandboxId,\n hostname,\n error: error instanceof Error ? error.message : 'Unknown error'\n }, 'high');\n throw new SecurityError(`Failed to construct preview URL: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n }\n}\n","import { getSandbox, type Sandbox } from \"./sandbox\";\nimport {\n logSecurityEvent,\n sanitizeSandboxId,\n validatePort\n} from \"./security\";\n\nexport interface SandboxEnv {\n Sandbox: DurableObjectNamespace<Sandbox>;\n}\n\nexport interface RouteInfo {\n port: number;\n sandboxId: string;\n path: string;\n}\n\nexport async function proxyToSandbox<E extends SandboxEnv>(\n request: Request,\n env: E\n): Promise<Response | null> {\n try {\n const url = new URL(request.url);\n const routeInfo = extractSandboxRoute(url);\n\n if (!routeInfo) {\n return null; // Not a request to an exposed container port\n }\n\n const { sandboxId, port, path } = routeInfo;\n const sandbox = getSandbox(env.Sandbox, sandboxId);\n\n // Build proxy request with proper headers\n let proxyUrl: string;\n\n // Route based on the target port\n if (port !== 3000) {\n // Route directly to user's service on the specified port\n proxyUrl = `http://localhost:${port}${path}${url.search}`;\n } else {\n // Port 3000 is our control plane - route normally\n proxyUrl = `http://localhost:3000${path}${url.search}`;\n }\n\n const proxyRequest = new Request(proxyUrl, {\n method: request.method,\n headers: {\n ...Object.fromEntries(request.headers),\n 'X-Original-URL': request.url,\n 'X-Forwarded-Host': url.hostname,\n 'X-Forwarded-Proto': url.protocol.replace(':', ''),\n 'X-Sandbox-Name': sandboxId, // Pass the friendly name\n },\n body: request.body,\n });\n\n return sandbox.containerFetch(proxyRequest, port);\n } catch (error) {\n console.error('[Sandbox] Proxy routing error:', error);\n return new Response('Proxy routing error', { status: 500 });\n }\n}\n\nfunction extractSandboxRoute(url: URL): RouteInfo | null {\n // Parse subdomain pattern: port-sandboxId.domain\n const subdomainMatch = url.hostname.match(/^(\\d{4,5})-([^.-][^.]*[^.-]|[^.-])\\.(.+)$/);\n\n if (!subdomainMatch) {\n // Log malformed subdomain attempts\n if (url.hostname.includes('-') && url.hostname.includes('.')) {\n logSecurityEvent('MALFORMED_SUBDOMAIN_ATTEMPT', {\n hostname: url.hostname,\n url: url.toString()\n }, 'medium');\n }\n return null;\n }\n\n const portStr = subdomainMatch[1];\n const sandboxId = subdomainMatch[2];\n const domain = subdomainMatch[3];\n\n const port = parseInt(portStr, 10);\n if (!validatePort(port)) {\n logSecurityEvent('INVALID_PORT_IN_SUBDOMAIN', {\n port,\n portStr,\n sandboxId,\n hostname: url.hostname,\n url: url.toString()\n }, 'high');\n return null;\n }\n\n let sanitizedSandboxId: string;\n try {\n sanitizedSandboxId = sanitizeSandboxId(sandboxId);\n } catch (error) {\n logSecurityEvent('INVALID_SANDBOX_ID_IN_SUBDOMAIN', {\n sandboxId,\n port,\n hostname: url.hostname,\n url: url.toString(),\n error: error instanceof Error ? error.message : 'Unknown error'\n }, 'high');\n return null;\n }\n\n // DNS subdomain length limit is 63 characters\n if (sandboxId.length > 63) {\n logSecurityEvent('SANDBOX_ID_LENGTH_VIOLATION', {\n sandboxId,\n length: sandboxId.length,\n port,\n hostname: url.hostname\n }, 'medium');\n return null;\n }\n\n logSecurityEvent('SANDBOX_ROUTE_EXTRACTED', {\n port,\n sandboxId: sanitizedSandboxId,\n domain,\n path: url.pathname || \"/\",\n hostname: url.hostname\n }, 'low');\n\n return {\n port,\n sandboxId: sanitizedSandboxId,\n path: url.pathname || \"/\",\n };\n}\n\nexport function isLocalhostPattern(hostname: string): boolean {\n const hostPart = hostname.split(\":\")[0];\n return (\n hostPart === \"localhost\" ||\n hostPart === \"127.0.0.1\" ||\n hostPart === \"::1\" ||\n hostPart === \"[::1]\" ||\n hostPart === \"0.0.0.0\"\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AAAA,SAAS,WAAW,oBAAoB;;;ACiBxC,eAAsB,eACpB,SACA,KAC0B;AAC1B,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAC/B,UAAM,YAAY,oBAAoB,GAAG;AAEzC,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AAEA,UAAM,EAAE,WAAW,MAAM,KAAK,IAAI;AAClC,UAAM,UAAU,WAAW,IAAI,SAAS,SAAS;AAGjD,QAAI;AAGJ,QAAI,SAAS,KAAM;AAEjB,iBAAW,oBAAoB,IAAI,GAAG,IAAI,GAAG,IAAI,MAAM;AAAA,IACzD,OAAO;AAEL,iBAAW,wBAAwB,IAAI,GAAG,IAAI,MAAM;AAAA,IACtD;AAEA,UAAM,eAAe,IAAI,QAAQ,UAAU;AAAA,MACzC,QAAQ,QAAQ;AAAA,MAChB,SAAS;AAAA,QACP,GAAG,OAAO,YAAY,QAAQ,OAAO;AAAA,QACrC,kBAAkB,QAAQ;AAAA,QAC1B,oBAAoB,IAAI;AAAA,QACxB,qBAAqB,IAAI,SAAS,QAAQ,KAAK,EAAE;AAAA,QACjD,kBAAkB;AAAA;AAAA,MACpB;AAAA,MACA,MAAM,QAAQ;AAAA,IAChB,CAAC;AAED,WAAO,QAAQ,eAAe,cAAc,IAAI;AAAA,EAClD,SAAS,OAAO;AACd,YAAQ,MAAM,kCAAkC,KAAK;AACrD,WAAO,IAAI,SAAS,uBAAuB,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC5D;AACF;AAEA,SAAS,oBAAoB,KAA4B;AAEvD,QAAM,iBAAiB,IAAI,SAAS,MAAM,2CAA2C;AAErF,MAAI,CAAC,gBAAgB;AAEnB,QAAI,IAAI,SAAS,SAAS,GAAG,KAAK,IAAI,SAAS,SAAS,GAAG,GAAG;AAC5D,uBAAiB,+BAA+B;AAAA,QAC9C,UAAU,IAAI;AAAA,QACd,KAAK,IAAI,SAAS;AAAA,MACpB,GAAG,QAAQ;AAAA,IACb;AACA,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,eAAe,CAAC;AAChC,QAAM,YAAY,eAAe,CAAC;AAClC,QAAM,SAAS,eAAe,CAAC;AAE/B,QAAM,OAAO,SAAS,SAAS,EAAE;AACjC,MAAI,CAAC,aAAa,IAAI,GAAG;AACvB,qBAAiB,6BAA6B;AAAA,MAC5C;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,IAAI;AAAA,MACd,KAAK,IAAI,SAAS;AAAA,IACpB,GAAG,MAAM;AACT,WAAO;AAAA,EACT;AAEA,MAAI;AACJ,MAAI;AACF,yBAAqB,kBAAkB,SAAS;AAAA,EAClD,SAAS,OAAO;AACd,qBAAiB,mCAAmC;AAAA,MAClD;AAAA,MACA;AAAA,MACA,UAAU,IAAI;AAAA,MACd,KAAK,IAAI,SAAS;AAAA,MAClB,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,IAClD,GAAG,MAAM;AACT,WAAO;AAAA,EACT;AAGA,MAAI,UAAU,SAAS,IAAI;AACzB,qBAAiB,+BAA+B;AAAA,MAC9C;AAAA,MACA,QAAQ,UAAU;AAAA,MAClB;AAAA,MACA,UAAU,IAAI;AAAA,IAChB,GAAG,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,mBAAiB,2BAA2B;AAAA,IAC1C;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA,MAAM,IAAI,YAAY;AAAA,IACtB,UAAU,IAAI;AAAA,EAChB,GAAG,KAAK;AAER,SAAO;AAAA,IACL;AAAA,IACA,WAAW;AAAA,IACX,MAAM,IAAI,YAAY;AAAA,EACxB;AACF;AAEO,SAAS,mBAAmB,UAA2B;AAC5D,QAAM,WAAW,SAAS,MAAM,GAAG,EAAE,CAAC;AACtC,SACE,aAAa,eACb,aAAa,eACb,aAAa,SACb,aAAa,WACb,aAAa;AAEjB;;;ADxHO,SAAS,WAAW,IAAqC,IAAY;AAC1E,QAAM,OAAO,aAAa,IAAI,EAAE;AAGhC,OAAK,iBAAiB,EAAE;AAExB,SAAO;AACT;AAEO,IAAM,UAAN,cAAqC,UAAmC;AAAA,EAC7E,aAAa;AAAA;AAAA,EACb;AAAA,EACQ,cAA6B;AAAA,EAErC,YAAY,KAAyB,KAAU;AAC7C,UAAM,KAAK,GAAG;AACd,SAAK,SAAS,IAAI,WAAW;AAAA,MAC3B,mBAAmB,CAAC,SAAS,UAAU,SAAS,SAAS,YAAY;AACnE,gBAAQ;AAAA,UACN,kCAAkC,OAAO,cAAc,OAAO,gBAAgB,QAAQ;AAAA,QACxF;AAAA,MACF;AAAA,MACA,gBAAgB,CAAC,YAAY;AAC3B,gBAAQ;AAAA,UACN,gCAAgC,OAAO;AAAA,QACzC;AAAA,MACF;AAAA,MACA,SAAS,CAAC,OAAO,aAAa;AAC5B,gBAAQ,MAAM,8BAA8B,KAAK,EAAE;AAAA,MACrD;AAAA,MACA,UAAU,CAAC,QAAQ,MAAM,aAAa;AACpC,gBAAQ,IAAI,gBAAgB,MAAM,KAAK,IAAI,EAAE;AAAA,MAC/C;AAAA,MACA,MAAM;AAAA;AAAA,MACN,MAAM;AAAA,IACR,CAAC;AAGD,SAAK,IAAI,sBAAsB,YAAY;AACzC,WAAK,cAAc,MAAM,KAAK,IAAI,QAAQ,IAAY,aAAa,KAAK;AAAA,IAC1E,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,eAAe,MAA6B;AAChD,QAAI,CAAC,KAAK,aAAa;AACrB,WAAK,cAAc;AACnB,YAAM,KAAK,IAAI,QAAQ,IAAI,eAAe,IAAI;AAC9C,cAAQ,IAAI,0CAA0C,IAAI,EAAE;AAAA,IAC9D;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,WAAW,SAAgD;AAC/D,SAAK,UAAU,EAAE,GAAG,KAAK,SAAS,GAAG,QAAQ;AAC7C,YAAQ,IAAI,yCAAyC;AAAA,EACvD;AAAA,EAES,UAAU;AACjB,YAAQ,IAAI,8BAA8B;AAAA,EAC5C;AAAA,EAES,SAAS;AAChB,YAAQ,IAAI,gCAAgC;AAC5C,QAAI,KAAK,QAAQ;AACf,WAAK,OAAO,aAAa;AAAA,IAC3B;AAAA,EACF;AAAA,EAES,QAAQ,OAAgB;AAC/B,YAAQ,IAAI,kBAAkB,KAAK;AAAA,EACrC;AAAA;AAAA,EAGA,MAAe,MAAM,SAAqC;AACxD,UAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAG/B,QAAI,CAAC,KAAK,eAAe,QAAQ,QAAQ,IAAI,gBAAgB,GAAG;AAC9D,YAAM,OAAO,QAAQ,QAAQ,IAAI,gBAAgB;AACjD,WAAK,cAAc;AACnB,YAAM,KAAK,IAAI,QAAQ,IAAI,eAAe,IAAI;AAC9C,cAAQ,IAAI,kCAAkC,KAAK,WAAW,EAAE;AAAA,IAClE;AAGA,UAAM,OAAO,KAAK,cAAc,GAAG;AAGnC,WAAO,MAAM,KAAK,eAAe,SAAS,IAAI;AAAA,EAChD;AAAA,EAEQ,cAAc,KAAkB;AAEtC,UAAM,aAAa,IAAI,SAAS,MAAM,iBAAiB;AACvD,QAAI,YAAY;AACd,aAAO,SAAS,WAAW,CAAC,CAAC;AAAA,IAC/B;AAIA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAIA,MAAM,KAAK,SAAiB,SAA4C;AACtE,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AAGzC,QAAI;AAEJ,QAAI;AAEF,UAAI,SAAS,QAAQ,SAAS;AAC5B,cAAM,IAAI,MAAM,uBAAuB;AAAA,MACzC;AAEA,UAAI;AAEJ,UAAI,SAAS,UAAU,SAAS,UAAU;AAExC,iBAAS,MAAM,KAAK,qBAAqB,SAAS,SAAS,WAAW,SAAS;AAAA,MACjF,OAAO;AAEL,cAAM,WAAW,MAAM,KAAK,OAAO;AAAA,UACjC;AAAA,UACA,SAAS;AAAA,QACX;AAEA,cAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,iBAAS,KAAK,+BAA+B,UAAU,UAAU,SAAS,SAAS;AAAA,MACrF;AAGA,UAAI,SAAS,YAAY;AACvB,gBAAQ,WAAW,MAAM;AAAA,MAC3B;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,UAAI,SAAS,WAAW,iBAAiB,OAAO;AAC9C,gBAAQ,QAAQ,KAAK;AAAA,MACvB;AACA,YAAM;AAAA,IACR,UAAE;AACA,UAAI,WAAW;AACb,qBAAa,SAAS;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,qBACZ,SACA,SACA,WACA,WACqB;AACrB,QAAI,SAAS;AACb,QAAI,SAAS;AAEb,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,OAAO,qBAAqB,SAAS,QAAQ,SAAS;AAChF,YAAM,EAAE,eAAe,IAAI,MAAM,OAAO,iBAAc;AAEtD,uBAAiB,SAAS,eAA4C,MAAM,GAAG;AAE7E,YAAI,QAAQ,QAAQ,SAAS;AAC3B,gBAAM,IAAI,MAAM,uBAAuB;AAAA,QACzC;AAEA,gBAAQ,MAAM,MAAM;AAAA,UAClB,KAAK;AAAA,UACL,KAAK;AACH,gBAAI,MAAM,MAAM;AAEd,kBAAI,MAAM,SAAS,SAAU,WAAU,MAAM;AAC7C,kBAAI,MAAM,SAAS,SAAU,WAAU,MAAM;AAG7C,kBAAI,QAAQ,UAAU;AACpB,wBAAQ,SAAS,MAAM,MAAM,MAAM,IAAI;AAAA,cACzC;AAAA,YACF;AACA;AAAA,UAEF,KAAK,YAAY;AAEf,kBAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,mBAAO,MAAM,UAAU;AAAA,cACrB,SAAS,MAAM,aAAa;AAAA,cAC5B,UAAU,MAAM,YAAY;AAAA,cAC5B;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA,WAAW,QAAQ;AAAA,YACrB;AAAA,UACF;AAAA,UAEA,KAAK;AACH,kBAAM,IAAI,MAAM,MAAM,SAAS,0BAA0B;AAAA,QAC7D;AAAA,MACF;AAGA,YAAM,IAAI,MAAM,uCAAuC;AAAA,IAEzD,SAAS,OAAO;AACd,UAAI,QAAQ,QAAQ,SAAS;AAC3B,cAAM,IAAI,MAAM,uBAAuB;AAAA,MACzC;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,+BACN,UACA,UACA,WACY;AACZ,WAAO;AAAA,MACL,SAAS,SAAS;AAAA,MAClB,UAAU,SAAS;AAAA,MACnB,QAAQ,SAAS;AAAA,MACjB,QAAQ,SAAS;AAAA,MACjB,SAAS,SAAS;AAAA,MAClB;AAAA,MACA,WAAW,SAAS;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIA,MAAM,aAAa,SAAiB,SAA4C;AAE9E,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,OAAO,aAAa,SAAS;AAAA,QACvD,WAAW,SAAS;AAAA,QACpB,WAAW,SAAS;AAAA,QACpB,SAAS,SAAS;AAAA,QAClB,KAAK,SAAS;AAAA,QACd,KAAK,SAAS;AAAA,QACd,UAAU,SAAS;AAAA,QACnB,aAAa,SAAS;AAAA,MACxB,CAAC;AAED,YAAM,UAAU,SAAS;AACzB,YAAM,aAAsB;AAAA,QAC1B,IAAI,QAAQ;AAAA,QACZ,KAAK,QAAQ;AAAA,QACb,SAAS,QAAQ;AAAA,QACjB,QAAQ,QAAQ;AAAA,QAChB,WAAW,IAAI,KAAK,QAAQ,SAAS;AAAA,QACrC,SAAS;AAAA,QACT,UAAU;AAAA,QACV,WAAW,QAAQ;AAAA,QAEnB,MAAM,OAAsB;AAC1B,gBAAM,IAAI,MAAM,yBAAyB;AAAA,QAC3C;AAAA,QACA,MAAM,YAAoC;AACxC,gBAAM,IAAI,MAAM,yBAAyB;AAAA,QAC3C;AAAA,QACA,MAAM,UAAuD;AAC3D,gBAAM,IAAI,MAAM,yBAAyB;AAAA,QAC3C;AAAA,MACF;AAGA,iBAAW,OAAO,OAAO,WAAoB;AAC3C,cAAM,KAAK,YAAY,QAAQ,IAAI,MAAM;AAAA,MAC3C;AAEA,iBAAW,YAAY,YAAY;AACjC,cAAM,UAAU,MAAM,KAAK,WAAW,QAAQ,EAAE;AAChD,eAAO,SAAS,UAAU;AAAA,MAC5B;AAEA,iBAAW,UAAU,YAAY;AAC/B,cAAM,OAAO,MAAM,KAAK,eAAe,QAAQ,EAAE;AACjD,eAAO,EAAE,QAAQ,KAAK,QAAQ,QAAQ,KAAK,OAAO;AAAA,MACpD;AAGA,UAAI,SAAS,SAAS;AACpB,gBAAQ,QAAQ,UAAU;AAAA,MAC5B;AAEA,aAAO;AAAA,IAET,SAAS,OAAO;AACd,UAAI,SAAS,WAAW,iBAAiB,OAAO;AAC9C,gBAAQ,QAAQ,KAAK;AAAA,MACvB;AAEA,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,gBAAoC;AACxC,UAAM,WAAW,MAAM,KAAK,OAAO,cAAc;AAEjD,WAAO,SAAS,UAAU,IAAI,kBAAgB;AAAA,MAC5C,IAAI,YAAY;AAAA,MAChB,KAAK,YAAY;AAAA,MACjB,SAAS,YAAY;AAAA,MACrB,QAAQ,YAAY;AAAA,MACpB,WAAW,IAAI,KAAK,YAAY,SAAS;AAAA,MACzC,SAAS,YAAY,UAAU,IAAI,KAAK,YAAY,OAAO,IAAI;AAAA,MAC/D,UAAU,YAAY;AAAA,MACtB,WAAW,YAAY;AAAA,MAEvB,MAAM,OAAO,WAAoB;AAC/B,cAAM,KAAK,YAAY,YAAY,IAAI,MAAM;AAAA,MAC/C;AAAA,MAEA,WAAW,YAAY;AACrB,cAAM,UAAU,MAAM,KAAK,WAAW,YAAY,EAAE;AACpD,eAAO,SAAS,UAAU;AAAA,MAC5B;AAAA,MAEA,SAAS,YAAY;AACnB,cAAM,OAAO,MAAM,KAAK,eAAe,YAAY,EAAE;AACrD,eAAO,EAAE,QAAQ,KAAK,QAAQ,QAAQ,KAAK,OAAO;AAAA,MACpD;AAAA,IACF,EAAE;AAAA,EACJ;AAAA,EAEA,MAAM,WAAW,IAAqC;AACpD,UAAM,WAAW,MAAM,KAAK,OAAO,WAAW,EAAE;AAChD,QAAI,CAAC,SAAS,SAAS;AACrB,aAAO;AAAA,IACT;AAEA,UAAM,cAAc,SAAS;AAC7B,WAAO;AAAA,MACL,IAAI,YAAY;AAAA,MAChB,KAAK,YAAY;AAAA,MACjB,SAAS,YAAY;AAAA,MACrB,QAAQ,YAAY;AAAA,MACpB,WAAW,IAAI,KAAK,YAAY,SAAS;AAAA,MACzC,SAAS,YAAY,UAAU,IAAI,KAAK,YAAY,OAAO,IAAI;AAAA,MAC/D,UAAU,YAAY;AAAA,MACtB,WAAW,YAAY;AAAA,MAEvB,MAAM,OAAO,WAAoB;AAC/B,cAAM,KAAK,YAAY,YAAY,IAAI,MAAM;AAAA,MAC/C;AAAA,MAEA,WAAW,YAAY;AACrB,cAAM,UAAU,MAAM,KAAK,WAAW,YAAY,EAAE;AACpD,eAAO,SAAS,UAAU;AAAA,MAC5B;AAAA,MAEA,SAAS,YAAY;AACnB,cAAM,OAAO,MAAM,KAAK,eAAe,YAAY,EAAE;AACrD,eAAO,EAAE,QAAQ,KAAK,QAAQ,QAAQ,KAAK,OAAO;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,IAAY,SAAiC;AAC7D,QAAI;AAEF,YAAM,KAAK,OAAO,YAAY,EAAE;AAAA,IAClC,SAAS,OAAO;AACd,UAAI,iBAAiB,SAAS,MAAM,QAAQ,SAAS,mBAAmB,GAAG;AACzE,cAAM,IAAI,qBAAqB,EAAE;AAAA,MACnC;AACA,YAAM,IAAI;AAAA,QACR,0BAA0B,EAAE,KAAK,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,QACzF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,mBAAoC;AACxC,UAAM,WAAW,MAAM,KAAK,OAAO,iBAAiB;AACpD,WAAO,SAAS;AAAA,EAClB;AAAA,EAEA,MAAM,4BAA6C;AAIjD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,eAAe,IAAyD;AAC5E,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,OAAO,eAAe,EAAE;AACpD,aAAO;AAAA,QACL,QAAQ,SAAS;AAAA,QACjB,QAAQ,SAAS;AAAA,MACnB;AAAA,IACF,SAAS,OAAO;AACd,UAAI,iBAAiB,SAAS,MAAM,QAAQ,SAAS,mBAAmB,GAAG;AACzE,cAAM,IAAI,qBAAqB,EAAE;AAAA,MACnC;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA,EAIA,MAAM,WAAW,SAAiB,SAA8D;AAE9F,QAAI,SAAS,QAAQ,SAAS;AAC5B,YAAM,IAAI,MAAM,uBAAuB;AAAA,IACzC;AAGA,UAAM,SAAS,MAAM,KAAK,OAAO,qBAAqB,SAAS,SAAS,SAAS;AAGjF,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,kBAAkB,WAAmB,SAAyE;AAElH,QAAI,SAAS,QAAQ,SAAS;AAC5B,YAAM,IAAI,MAAM,uBAAuB;AAAA,IACzC;AAGA,UAAM,SAAS,MAAM,KAAK,OAAO,kBAAkB,SAAS;AAG5D,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,YACJ,SACA,SACA;AACA,WAAO,KAAK,OAAO,YAAY,SAAS,QAAQ,QAAQ,QAAQ,SAAS;AAAA,EAC3E;AAAA,EAEA,MAAM,MACJ,MACA,UAAmC,CAAC,GACpC;AACA,WAAO,KAAK,OAAO,MAAM,MAAM,QAAQ,SAAS;AAAA,EAClD;AAAA,EAEA,MAAM,UACJ,MACA,SACA,UAAiC,CAAC,GAClC;AACA,WAAO,KAAK,OAAO,UAAU,MAAM,SAAS,QAAQ,QAAQ;AAAA,EAC9D;AAAA,EAEA,MAAM,WAAW,MAAc;AAC7B,WAAO,KAAK,OAAO,WAAW,IAAI;AAAA,EACpC;AAAA,EAEA,MAAM,WACJ,SACA,SACA;AACA,WAAO,KAAK,OAAO,WAAW,SAAS,OAAO;AAAA,EAChD;AAAA,EAEA,MAAM,SACJ,YACA,iBACA;AACA,WAAO,KAAK,OAAO,SAAS,YAAY,eAAe;AAAA,EACzD;AAAA,EAEA,MAAM,SACJ,MACA,UAAiC,CAAC,GAClC;AACA,WAAO,KAAK,OAAO,SAAS,MAAM,QAAQ,QAAQ;AAAA,EACpD;AAAA,EAEA,MAAM,WAAW,MAAc,SAA8C;AAC3E,UAAM,KAAK,OAAO,WAAW,MAAM,SAAS,IAAI;AAGhD,QAAI,CAAC,KAAK,aAAa;AACrB,YAAM,IAAI,MAAM,6EAA6E;AAAA,IAC/F;AAEA,UAAM,MAAM,KAAK,oBAAoB,MAAM,KAAK,aAAa,QAAQ,QAAQ;AAE7E,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,MAAM,SAAS;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,MAAM,aAAa,MAAc;AAC/B,QAAI,CAAC,aAAa,IAAI,GAAG;AACvB,uBAAiB,yBAAyB;AAAA,QACxC;AAAA,MACF,GAAG,MAAM;AACT,YAAM,IAAI,cAAc,wBAAwB,IAAI,gDAAgD;AAAA,IACtG;AAEA,UAAM,KAAK,OAAO,aAAa,IAAI;AAEnC,qBAAiB,kBAAkB;AAAA,MACjC;AAAA,IACF,GAAG,KAAK;AAAA,EACV;AAAA,EAEA,MAAM,gBAAgB,UAAkB;AACtC,UAAM,WAAW,MAAM,KAAK,OAAO,gBAAgB;AAGnD,QAAI,CAAC,KAAK,aAAa;AACrB,YAAM,IAAI,MAAM,6EAA6E;AAAA,IAC/F;AAEA,WAAO,SAAS,MAAM,IAAI,WAAS;AAAA,MACjC,KAAK,KAAK,oBAAoB,KAAK,MAAM,KAAK,aAAc,QAAQ;AAAA,MACpE,MAAM,KAAK;AAAA,MACX,MAAM,KAAK;AAAA,MACX,WAAW,KAAK;AAAA,IAClB,EAAE;AAAA,EACJ;AAAA,EAGQ,oBAAoB,MAAc,WAAmB,UAA0B;AACrF,QAAI,CAAC,aAAa,IAAI,GAAG;AACvB,uBAAiB,yBAAyB;AAAA,QACxC;AAAA,QACA;AAAA,QACA;AAAA,MACF,GAAG,MAAM;AACT,YAAM,IAAI,cAAc,wBAAwB,IAAI,gDAAgD;AAAA,IACtG;AAEA,QAAI;AACJ,QAAI;AACF,2BAAqB,kBAAkB,SAAS;AAAA,IAClD,SAAS,OAAO;AACd,uBAAiB,+BAA+B;AAAA,QAC9C;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAClD,GAAG,MAAM;AACT,YAAM;AAAA,IACR;AAEA,UAAM,cAAc,mBAAmB,QAAQ;AAE/C,QAAI,aAAa;AAEf,YAAM,CAAC,MAAM,OAAO,IAAI,SAAS,MAAM,GAAG;AAC1C,YAAM,WAAW,WAAW;AAG5B,UAAI;AACF,cAAM,UAAU,IAAI,IAAI,UAAU,IAAI,IAAI,QAAQ,EAAE;AAEpD,cAAM,gBAAgB,GAAG,IAAI,IAAI,kBAAkB,IAAI,IAAI;AAC3D,gBAAQ,WAAW;AAEnB,cAAM,WAAW,QAAQ,SAAS;AAElC,yBAAiB,2BAA2B;AAAA,UAC1C;AAAA,UACA,WAAW;AAAA,UACX;AAAA,UACA,WAAW;AAAA,UACX,aAAa;AAAA,QACf,GAAG,KAAK;AAER,eAAO;AAAA,MACT,SAAS,OAAO;AACd,yBAAiB,2BAA2B;AAAA,UAC1C;AAAA,UACA,WAAW;AAAA,UACX;AAAA,UACA,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,QAClD,GAAG,MAAM;AACT,cAAM,IAAI,cAAc,oCAAoC,iBAAiB,QAAQ,MAAM,UAAU,eAAe,EAAE;AAAA,MACxH;AAAA,IACF;AAGA,QAAI;AAEF,YAAM,WAAW;AACjB,YAAM,UAAU,IAAI,IAAI,GAAG,QAAQ,MAAM,QAAQ,EAAE;AAGnD,YAAM,gBAAgB,GAAG,IAAI,IAAI,kBAAkB,IAAI,QAAQ;AAC/D,cAAQ,WAAW;AAEnB,YAAM,WAAW,QAAQ,SAAS;AAElC,uBAAiB,2BAA2B;AAAA,QAC1C;AAAA,QACA,WAAW;AAAA,QACX;AAAA,QACA,WAAW;AAAA,QACX,aAAa;AAAA,MACf,GAAG,KAAK;AAER,aAAO;AAAA,IACT,SAAS,OAAO;AACd,uBAAiB,2BAA2B;AAAA,QAC1C;AAAA,QACA,WAAW;AAAA,QACX;AAAA,QACA,OAAO,iBAAiB,QAAQ,MAAM,UAAU;AAAA,MAClD,GAAG,MAAM;AACT,YAAM,IAAI,cAAc,oCAAoC,iBAAiB,QAAQ,MAAM,UAAU,eAAe,EAAE;AAAA,IACxH;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// src/sse-parser.ts
|
|
2
|
+
async function* parseSSEStream(stream, signal) {
|
|
3
|
+
const reader = stream.getReader();
|
|
4
|
+
const decoder = new TextDecoder();
|
|
5
|
+
let buffer = "";
|
|
6
|
+
try {
|
|
7
|
+
while (true) {
|
|
8
|
+
if (signal?.aborted) {
|
|
9
|
+
throw new Error("Operation was aborted");
|
|
10
|
+
}
|
|
11
|
+
const { done, value } = await reader.read();
|
|
12
|
+
if (done) break;
|
|
13
|
+
buffer += decoder.decode(value, { stream: true });
|
|
14
|
+
const lines = buffer.split("\n");
|
|
15
|
+
buffer = lines.pop() || "";
|
|
16
|
+
for (const line of lines) {
|
|
17
|
+
if (line.trim() === "") continue;
|
|
18
|
+
if (line.startsWith("data: ")) {
|
|
19
|
+
const data = line.substring(6);
|
|
20
|
+
if (data === "[DONE]" || data.trim() === "") continue;
|
|
21
|
+
try {
|
|
22
|
+
const event = JSON.parse(data);
|
|
23
|
+
yield event;
|
|
24
|
+
} catch (error) {
|
|
25
|
+
console.error("Failed to parse SSE event:", data, error);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (buffer.trim() && buffer.startsWith("data: ")) {
|
|
31
|
+
const data = buffer.substring(6);
|
|
32
|
+
if (data !== "[DONE]" && data.trim()) {
|
|
33
|
+
try {
|
|
34
|
+
const event = JSON.parse(data);
|
|
35
|
+
yield event;
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error("Failed to parse final SSE event:", data, error);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
} finally {
|
|
42
|
+
reader.releaseLock();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async function* responseToAsyncIterable(response, signal) {
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
throw new Error(`Response not ok: ${response.status} ${response.statusText}`);
|
|
48
|
+
}
|
|
49
|
+
if (!response.body) {
|
|
50
|
+
throw new Error("No response body");
|
|
51
|
+
}
|
|
52
|
+
yield* parseSSEStream(response.body, signal);
|
|
53
|
+
}
|
|
54
|
+
function asyncIterableToSSEStream(events, options) {
|
|
55
|
+
const encoder = new TextEncoder();
|
|
56
|
+
const serialize = options?.serialize || JSON.stringify;
|
|
57
|
+
return new ReadableStream({
|
|
58
|
+
async start(controller) {
|
|
59
|
+
try {
|
|
60
|
+
for await (const event of events) {
|
|
61
|
+
if (options?.signal?.aborted) {
|
|
62
|
+
controller.error(new Error("Operation was aborted"));
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
const data = serialize(event);
|
|
66
|
+
const sseEvent = `data: ${data}
|
|
67
|
+
|
|
68
|
+
`;
|
|
69
|
+
controller.enqueue(encoder.encode(sseEvent));
|
|
70
|
+
}
|
|
71
|
+
controller.enqueue(encoder.encode("data: [DONE]\n\n"));
|
|
72
|
+
} catch (error) {
|
|
73
|
+
controller.error(error);
|
|
74
|
+
} finally {
|
|
75
|
+
controller.close();
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
cancel() {
|
|
79
|
+
console.log("SSE stream cancelled");
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export {
|
|
85
|
+
parseSSEStream,
|
|
86
|
+
responseToAsyncIterable,
|
|
87
|
+
asyncIterableToSSEStream
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=chunk-NNGBXDMY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sse-parser.ts"],"sourcesContent":["/**\n * Server-Sent Events (SSE) parser for streaming responses\n * Converts ReadableStream<Uint8Array> to typed AsyncIterable<T>\n */\n\n/**\n * Parse a ReadableStream of SSE events into typed AsyncIterable\n * @param stream - The ReadableStream from fetch response\n * @param signal - Optional AbortSignal for cancellation\n */\nexport async function* parseSSEStream<T>(\n stream: ReadableStream<Uint8Array>,\n signal?: AbortSignal\n): AsyncIterable<T> {\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n while (true) {\n // Check for cancellation\n if (signal?.aborted) {\n throw new Error('Operation was aborted');\n }\n\n const { done, value } = await reader.read();\n if (done) break;\n\n // Decode chunk and add to buffer\n buffer += decoder.decode(value, { stream: true });\n\n // Process complete SSE events in buffer\n const lines = buffer.split('\\n');\n\n // Keep the last incomplete line in buffer\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n // Skip empty lines\n if (line.trim() === '') continue;\n\n // Process SSE data lines\n if (line.startsWith('data: ')) {\n const data = line.substring(6);\n\n // Skip [DONE] markers or empty data\n if (data === '[DONE]' || data.trim() === '') continue;\n\n try {\n const event = JSON.parse(data) as T;\n yield event;\n } catch (error) {\n // Log parsing errors but continue processing\n console.error('Failed to parse SSE event:', data, error);\n // Optionally yield an error event\n // yield { type: 'error', data: `Parse error: ${error.message}` } as T;\n }\n }\n // Handle other SSE fields if needed (event:, id:, retry:)\n // For now, we only care about data: lines\n }\n }\n\n // Process any remaining data in buffer\n if (buffer.trim() && buffer.startsWith('data: ')) {\n const data = buffer.substring(6);\n if (data !== '[DONE]' && data.trim()) {\n try {\n const event = JSON.parse(data) as T;\n yield event;\n } catch (error) {\n console.error('Failed to parse final SSE event:', data, error);\n }\n }\n }\n } finally {\n // Clean up resources\n reader.releaseLock();\n }\n}\n\n\n/**\n * Helper to convert a Response with SSE stream directly to AsyncIterable\n * @param response - Response object with SSE stream\n * @param signal - Optional AbortSignal for cancellation\n */\nexport async function* responseToAsyncIterable<T>(\n response: Response,\n signal?: AbortSignal\n): AsyncIterable<T> {\n if (!response.ok) {\n throw new Error(`Response not ok: ${response.status} ${response.statusText}`);\n }\n\n if (!response.body) {\n throw new Error('No response body');\n }\n\n yield* parseSSEStream<T>(response.body, signal);\n}\n\n/**\n * Create an SSE-formatted ReadableStream from an AsyncIterable\n * (Useful for Worker endpoints that need to forward AsyncIterable as SSE)\n * @param events - AsyncIterable of events\n * @param options - Stream options\n */\nexport function asyncIterableToSSEStream<T>(\n events: AsyncIterable<T>,\n options?: {\n signal?: AbortSignal;\n serialize?: (event: T) => string;\n }\n): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n const serialize = options?.serialize || JSON.stringify;\n\n return new ReadableStream({\n async start(controller) {\n try {\n for await (const event of events) {\n if (options?.signal?.aborted) {\n controller.error(new Error('Operation was aborted'));\n break;\n }\n\n const data = serialize(event);\n const sseEvent = `data: ${data}\\n\\n`;\n controller.enqueue(encoder.encode(sseEvent));\n }\n\n // Send completion marker\n controller.enqueue(encoder.encode('data: [DONE]\\n\\n'));\n } catch (error) {\n controller.error(error);\n } finally {\n controller.close();\n }\n },\n\n cancel() {\n // Handle stream cancellation\n console.log('SSE stream cancelled');\n }\n });\n}"],"mappings":";AAUA,gBAAuB,eACrB,QACA,QACkB;AAClB,QAAM,SAAS,OAAO,UAAU;AAChC,QAAM,UAAU,IAAI,YAAY;AAChC,MAAI,SAAS;AAEb,MAAI;AACF,WAAO,MAAM;AAEX,UAAI,QAAQ,SAAS;AACnB,cAAM,IAAI,MAAM,uBAAuB;AAAA,MACzC;AAEA,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AAGV,gBAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAGhD,YAAM,QAAQ,OAAO,MAAM,IAAI;AAG/B,eAAS,MAAM,IAAI,KAAK;AAExB,iBAAW,QAAQ,OAAO;AAExB,YAAI,KAAK,KAAK,MAAM,GAAI;AAGxB,YAAI,KAAK,WAAW,QAAQ,GAAG;AAC7B,gBAAM,OAAO,KAAK,UAAU,CAAC;AAG7B,cAAI,SAAS,YAAY,KAAK,KAAK,MAAM,GAAI;AAE7C,cAAI;AACF,kBAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,kBAAM;AAAA,UACR,SAAS,OAAO;AAEd,oBAAQ,MAAM,8BAA8B,MAAM,KAAK;AAAA,UAGzD;AAAA,QACF;AAAA,MAGF;AAAA,IACF;AAGA,QAAI,OAAO,KAAK,KAAK,OAAO,WAAW,QAAQ,GAAG;AAChD,YAAM,OAAO,OAAO,UAAU,CAAC;AAC/B,UAAI,SAAS,YAAY,KAAK,KAAK,GAAG;AACpC,YAAI;AACF,gBAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,gBAAM;AAAA,QACR,SAAS,OAAO;AACd,kBAAQ,MAAM,oCAAoC,MAAM,KAAK;AAAA,QAC/D;AAAA,MACF;AAAA,IACF;AAAA,EACF,UAAE;AAEA,WAAO,YAAY;AAAA,EACrB;AACF;AAQA,gBAAuB,wBACrB,UACA,QACkB;AAClB,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,oBAAoB,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,EAC9E;AAEA,MAAI,CAAC,SAAS,MAAM;AAClB,UAAM,IAAI,MAAM,kBAAkB;AAAA,EACpC;AAEA,SAAO,eAAkB,SAAS,MAAM,MAAM;AAChD;AAQO,SAAS,yBACd,QACA,SAI4B;AAC5B,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,YAAY,SAAS,aAAa,KAAK;AAE7C,SAAO,IAAI,eAAe;AAAA,IACxB,MAAM,MAAM,YAAY;AACtB,UAAI;AACF,yBAAiB,SAAS,QAAQ;AAChC,cAAI,SAAS,QAAQ,SAAS;AAC5B,uBAAW,MAAM,IAAI,MAAM,uBAAuB,CAAC;AACnD;AAAA,UACF;AAEA,gBAAM,OAAO,UAAU,KAAK;AAC5B,gBAAM,WAAW,SAAS,IAAI;AAAA;AAAA;AAC9B,qBAAW,QAAQ,QAAQ,OAAO,QAAQ,CAAC;AAAA,QAC7C;AAGA,mBAAW,QAAQ,QAAQ,OAAO,kBAAkB,CAAC;AAAA,MACvD,SAAS,OAAO;AACd,mBAAW,MAAM,KAAK;AAAA,MACxB,UAAE;AACA,mBAAW,MAAM;AAAA,MACnB;AAAA,IACF;AAAA,IAEA,SAAS;AAEP,cAAQ,IAAI,sBAAsB;AAAA,IACpC;AAAA,EACF,CAAC;AACH;","names":[]}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { Container } from '@cloudflare/containers';
|
|
2
|
+
import { ISandbox, ExecOptions, ExecResult, ProcessOptions, Process, StreamOptions, StartProcessResponse, ListProcessesResponse, GetProcessResponse, GetProcessLogsResponse } from './types.js';
|
|
3
|
+
|
|
4
|
+
declare function getSandbox(ns: DurableObjectNamespace<Sandbox>, id: string): DurableObjectStub<Sandbox<unknown>>;
|
|
5
|
+
declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox {
|
|
6
|
+
sleepAfter: string;
|
|
7
|
+
client: HttpClient;
|
|
8
|
+
private sandboxName;
|
|
9
|
+
constructor(ctx: DurableObjectState, env: Env);
|
|
10
|
+
setSandboxName(name: string): Promise<void>;
|
|
11
|
+
setEnvVars(envVars: Record<string, string>): Promise<void>;
|
|
12
|
+
onStart(): void;
|
|
13
|
+
onStop(): void;
|
|
14
|
+
onError(error: unknown): void;
|
|
15
|
+
fetch(request: Request): Promise<Response>;
|
|
16
|
+
private determinePort;
|
|
17
|
+
exec(command: string, options?: ExecOptions): Promise<ExecResult>;
|
|
18
|
+
private executeWithStreaming;
|
|
19
|
+
private mapExecuteResponseToExecResult;
|
|
20
|
+
startProcess(command: string, options?: ProcessOptions): Promise<Process>;
|
|
21
|
+
listProcesses(): Promise<Process[]>;
|
|
22
|
+
getProcess(id: string): Promise<Process | null>;
|
|
23
|
+
killProcess(id: string, _signal?: string): Promise<void>;
|
|
24
|
+
killAllProcesses(): Promise<number>;
|
|
25
|
+
cleanupCompletedProcesses(): Promise<number>;
|
|
26
|
+
getProcessLogs(id: string): Promise<{
|
|
27
|
+
stdout: string;
|
|
28
|
+
stderr: string;
|
|
29
|
+
}>;
|
|
30
|
+
execStream(command: string, options?: StreamOptions): Promise<ReadableStream<Uint8Array>>;
|
|
31
|
+
streamProcessLogs(processId: string, options?: {
|
|
32
|
+
signal?: AbortSignal;
|
|
33
|
+
}): Promise<ReadableStream<Uint8Array>>;
|
|
34
|
+
gitCheckout(repoUrl: string, options: {
|
|
35
|
+
branch?: string;
|
|
36
|
+
targetDir?: string;
|
|
37
|
+
}): Promise<GitCheckoutResponse>;
|
|
38
|
+
mkdir(path: string, options?: {
|
|
39
|
+
recursive?: boolean;
|
|
40
|
+
}): Promise<MkdirResponse>;
|
|
41
|
+
writeFile(path: string, content: string, options?: {
|
|
42
|
+
encoding?: string;
|
|
43
|
+
}): Promise<WriteFileResponse>;
|
|
44
|
+
deleteFile(path: string): Promise<DeleteFileResponse>;
|
|
45
|
+
renameFile(oldPath: string, newPath: string): Promise<RenameFileResponse>;
|
|
46
|
+
moveFile(sourcePath: string, destinationPath: string): Promise<MoveFileResponse>;
|
|
47
|
+
readFile(path: string, options?: {
|
|
48
|
+
encoding?: string;
|
|
49
|
+
}): Promise<ReadFileResponse>;
|
|
50
|
+
exposePort(port: number, options: {
|
|
51
|
+
name?: string;
|
|
52
|
+
hostname: string;
|
|
53
|
+
}): Promise<{
|
|
54
|
+
url: string;
|
|
55
|
+
port: number;
|
|
56
|
+
name: string | undefined;
|
|
57
|
+
}>;
|
|
58
|
+
unexposePort(port: number): Promise<void>;
|
|
59
|
+
getExposedPorts(hostname: string): Promise<{
|
|
60
|
+
url: string;
|
|
61
|
+
port: number;
|
|
62
|
+
name: string | undefined;
|
|
63
|
+
exposedAt: string;
|
|
64
|
+
}[]>;
|
|
65
|
+
private constructPreviewUrl;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
interface ExecuteResponse {
|
|
69
|
+
success: boolean;
|
|
70
|
+
stdout: string;
|
|
71
|
+
stderr: string;
|
|
72
|
+
exitCode: number;
|
|
73
|
+
command: string;
|
|
74
|
+
timestamp: string;
|
|
75
|
+
}
|
|
76
|
+
interface GitCheckoutResponse {
|
|
77
|
+
success: boolean;
|
|
78
|
+
stdout: string;
|
|
79
|
+
stderr: string;
|
|
80
|
+
exitCode: number;
|
|
81
|
+
repoUrl: string;
|
|
82
|
+
branch: string;
|
|
83
|
+
targetDir: string;
|
|
84
|
+
timestamp: string;
|
|
85
|
+
}
|
|
86
|
+
interface MkdirResponse {
|
|
87
|
+
success: boolean;
|
|
88
|
+
stdout: string;
|
|
89
|
+
stderr: string;
|
|
90
|
+
exitCode: number;
|
|
91
|
+
path: string;
|
|
92
|
+
recursive: boolean;
|
|
93
|
+
timestamp: string;
|
|
94
|
+
}
|
|
95
|
+
interface WriteFileResponse {
|
|
96
|
+
success: boolean;
|
|
97
|
+
exitCode: number;
|
|
98
|
+
path: string;
|
|
99
|
+
timestamp: string;
|
|
100
|
+
}
|
|
101
|
+
interface ReadFileResponse {
|
|
102
|
+
success: boolean;
|
|
103
|
+
exitCode: number;
|
|
104
|
+
path: string;
|
|
105
|
+
content: string;
|
|
106
|
+
timestamp: string;
|
|
107
|
+
}
|
|
108
|
+
interface DeleteFileResponse {
|
|
109
|
+
success: boolean;
|
|
110
|
+
exitCode: number;
|
|
111
|
+
path: string;
|
|
112
|
+
timestamp: string;
|
|
113
|
+
}
|
|
114
|
+
interface RenameFileResponse {
|
|
115
|
+
success: boolean;
|
|
116
|
+
exitCode: number;
|
|
117
|
+
oldPath: string;
|
|
118
|
+
newPath: string;
|
|
119
|
+
timestamp: string;
|
|
120
|
+
}
|
|
121
|
+
interface MoveFileResponse {
|
|
122
|
+
success: boolean;
|
|
123
|
+
exitCode: number;
|
|
124
|
+
sourcePath: string;
|
|
125
|
+
destinationPath: string;
|
|
126
|
+
timestamp: string;
|
|
127
|
+
}
|
|
128
|
+
interface PreviewInfo {
|
|
129
|
+
url: string;
|
|
130
|
+
port: number;
|
|
131
|
+
name?: string;
|
|
132
|
+
}
|
|
133
|
+
interface ExposedPort extends PreviewInfo {
|
|
134
|
+
exposedAt: string;
|
|
135
|
+
timestamp: string;
|
|
136
|
+
}
|
|
137
|
+
interface ExposePortResponse {
|
|
138
|
+
success: boolean;
|
|
139
|
+
port: number;
|
|
140
|
+
name?: string;
|
|
141
|
+
exposedAt: string;
|
|
142
|
+
timestamp: string;
|
|
143
|
+
}
|
|
144
|
+
interface UnexposePortResponse {
|
|
145
|
+
success: boolean;
|
|
146
|
+
port: number;
|
|
147
|
+
timestamp: string;
|
|
148
|
+
}
|
|
149
|
+
interface GetExposedPortsResponse {
|
|
150
|
+
ports: ExposedPort[];
|
|
151
|
+
count: number;
|
|
152
|
+
timestamp: string;
|
|
153
|
+
}
|
|
154
|
+
interface HttpClientOptions {
|
|
155
|
+
stub?: Sandbox;
|
|
156
|
+
baseUrl?: string;
|
|
157
|
+
port?: number;
|
|
158
|
+
onCommandStart?: (command: string) => void;
|
|
159
|
+
onOutput?: (stream: "stdout" | "stderr", data: string, command: string) => void;
|
|
160
|
+
onCommandComplete?: (success: boolean, exitCode: number, stdout: string, stderr: string, command: string) => void;
|
|
161
|
+
onError?: (error: string, command?: string) => void;
|
|
162
|
+
}
|
|
163
|
+
declare class HttpClient {
|
|
164
|
+
private baseUrl;
|
|
165
|
+
private options;
|
|
166
|
+
private sessionId;
|
|
167
|
+
constructor(options?: HttpClientOptions);
|
|
168
|
+
private doFetch;
|
|
169
|
+
execute(command: string, sessionId?: string): Promise<ExecuteResponse>;
|
|
170
|
+
executeCommandStream(command: string, sessionId?: string): Promise<ReadableStream<Uint8Array>>;
|
|
171
|
+
gitCheckout(repoUrl: string, branch?: string, targetDir?: string, sessionId?: string): Promise<GitCheckoutResponse>;
|
|
172
|
+
mkdir(path: string, recursive?: boolean, sessionId?: string): Promise<MkdirResponse>;
|
|
173
|
+
writeFile(path: string, content: string, encoding?: string, sessionId?: string): Promise<WriteFileResponse>;
|
|
174
|
+
readFile(path: string, encoding?: string, sessionId?: string): Promise<ReadFileResponse>;
|
|
175
|
+
deleteFile(path: string, sessionId?: string): Promise<DeleteFileResponse>;
|
|
176
|
+
renameFile(oldPath: string, newPath: string, sessionId?: string): Promise<RenameFileResponse>;
|
|
177
|
+
moveFile(sourcePath: string, destinationPath: string, sessionId?: string): Promise<MoveFileResponse>;
|
|
178
|
+
exposePort(port: number, name?: string): Promise<ExposePortResponse>;
|
|
179
|
+
unexposePort(port: number): Promise<UnexposePortResponse>;
|
|
180
|
+
getExposedPorts(): Promise<GetExposedPortsResponse>;
|
|
181
|
+
ping(): Promise<string>;
|
|
182
|
+
getCommands(): Promise<string[]>;
|
|
183
|
+
getSessionId(): string | null;
|
|
184
|
+
setSessionId(sessionId: string): void;
|
|
185
|
+
clearSession(): void;
|
|
186
|
+
startProcess(command: string, options?: {
|
|
187
|
+
processId?: string;
|
|
188
|
+
sessionId?: string;
|
|
189
|
+
timeout?: number;
|
|
190
|
+
env?: Record<string, string>;
|
|
191
|
+
cwd?: string;
|
|
192
|
+
encoding?: string;
|
|
193
|
+
autoCleanup?: boolean;
|
|
194
|
+
}): Promise<StartProcessResponse>;
|
|
195
|
+
listProcesses(): Promise<ListProcessesResponse>;
|
|
196
|
+
getProcess(processId: string): Promise<GetProcessResponse>;
|
|
197
|
+
killProcess(processId: string): Promise<{
|
|
198
|
+
success: boolean;
|
|
199
|
+
message: string;
|
|
200
|
+
}>;
|
|
201
|
+
killAllProcesses(): Promise<{
|
|
202
|
+
success: boolean;
|
|
203
|
+
killedCount: number;
|
|
204
|
+
message: string;
|
|
205
|
+
}>;
|
|
206
|
+
getProcessLogs(processId: string): Promise<GetProcessLogsResponse>;
|
|
207
|
+
streamProcessLogs(processId: string): Promise<ReadableStream<Uint8Array>>;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export { type DeleteFileResponse as D, type ExecuteResponse as E, type GitCheckoutResponse as G, HttpClient as H, type MkdirResponse as M, type ReadFileResponse as R, Sandbox as S, type WriteFileResponse as W, type MoveFileResponse as a, type RenameFileResponse as b, getSandbox as g };
|
package/dist/client.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export { D as DeleteFileResponse, E as ExecuteResponse, G as GitCheckoutResponse, H as HttpClient, M as MkdirResponse,
|
|
1
|
+
export { D as DeleteFileResponse, E as ExecuteResponse, G as GitCheckoutResponse, H as HttpClient, M as MkdirResponse, a as MoveFileResponse, R as ReadFileResponse, b as RenameFileResponse, W as WriteFileResponse } from './client-Da-mLX4p.js';
|
|
2
|
+
import './types.js';
|
|
2
3
|
import '@cloudflare/containers';
|
package/dist/client.js
CHANGED
|
@@ -1,41 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
HttpClient
|
|
3
|
-
|
|
4
|
-
quickDeleteFile,
|
|
5
|
-
quickDeleteFileStream,
|
|
6
|
-
quickExecute,
|
|
7
|
-
quickExecuteStream,
|
|
8
|
-
quickGitCheckout,
|
|
9
|
-
quickGitCheckoutStream,
|
|
10
|
-
quickMkdir,
|
|
11
|
-
quickMkdirStream,
|
|
12
|
-
quickMoveFile,
|
|
13
|
-
quickMoveFileStream,
|
|
14
|
-
quickReadFile,
|
|
15
|
-
quickReadFileStream,
|
|
16
|
-
quickRenameFile,
|
|
17
|
-
quickRenameFileStream,
|
|
18
|
-
quickWriteFile,
|
|
19
|
-
quickWriteFileStream
|
|
20
|
-
} from "./chunk-7WZJ3TRE.js";
|
|
2
|
+
HttpClient
|
|
3
|
+
} from "./chunk-G4XT4SP7.js";
|
|
21
4
|
export {
|
|
22
|
-
HttpClient
|
|
23
|
-
createClient,
|
|
24
|
-
quickDeleteFile,
|
|
25
|
-
quickDeleteFileStream,
|
|
26
|
-
quickExecute,
|
|
27
|
-
quickExecuteStream,
|
|
28
|
-
quickGitCheckout,
|
|
29
|
-
quickGitCheckoutStream,
|
|
30
|
-
quickMkdir,
|
|
31
|
-
quickMkdirStream,
|
|
32
|
-
quickMoveFile,
|
|
33
|
-
quickMoveFileStream,
|
|
34
|
-
quickReadFile,
|
|
35
|
-
quickReadFileStream,
|
|
36
|
-
quickRenameFile,
|
|
37
|
-
quickRenameFileStream,
|
|
38
|
-
quickWriteFile,
|
|
39
|
-
quickWriteFileStream
|
|
5
|
+
HttpClient
|
|
40
6
|
};
|
|
41
7
|
//# sourceMappingURL=client.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,200 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
sleepAfter: string;
|
|
7
|
-
client: HttpClient;
|
|
8
|
-
constructor(ctx: DurableObjectState, env: Env);
|
|
9
|
-
envVars: {
|
|
10
|
-
MESSAGE: string;
|
|
11
|
-
};
|
|
12
|
-
onStart(): void;
|
|
13
|
-
onStop(): void;
|
|
14
|
-
onError(error: unknown): void;
|
|
15
|
-
exec(command: string, args: string[], options?: {
|
|
16
|
-
stream?: boolean;
|
|
17
|
-
}): Promise<void | ExecuteResponse>;
|
|
18
|
-
gitCheckout(repoUrl: string, options: {
|
|
19
|
-
branch?: string;
|
|
20
|
-
targetDir?: string;
|
|
21
|
-
stream?: boolean;
|
|
22
|
-
}): Promise<void | GitCheckoutResponse>;
|
|
23
|
-
mkdir(path: string, options?: {
|
|
24
|
-
recursive?: boolean;
|
|
25
|
-
stream?: boolean;
|
|
26
|
-
}): Promise<void | MkdirResponse>;
|
|
27
|
-
writeFile(path: string, content: string, options?: {
|
|
28
|
-
encoding?: string;
|
|
29
|
-
stream?: boolean;
|
|
30
|
-
}): Promise<void | WriteFileResponse>;
|
|
31
|
-
deleteFile(path: string, options?: {
|
|
32
|
-
stream?: boolean;
|
|
33
|
-
}): Promise<void | DeleteFileResponse>;
|
|
34
|
-
renameFile(oldPath: string, newPath: string, options?: {
|
|
35
|
-
stream?: boolean;
|
|
36
|
-
}): Promise<void | RenameFileResponse>;
|
|
37
|
-
moveFile(sourcePath: string, destinationPath: string, options?: {
|
|
38
|
-
stream?: boolean;
|
|
39
|
-
}): Promise<void | MoveFileResponse>;
|
|
40
|
-
readFile(path: string, options?: {
|
|
41
|
-
encoding?: string;
|
|
42
|
-
stream?: boolean;
|
|
43
|
-
}): Promise<void | ReadFileResponse>;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
interface ExecuteResponse {
|
|
47
|
-
success: boolean;
|
|
48
|
-
stdout: string;
|
|
49
|
-
stderr: string;
|
|
50
|
-
exitCode: number;
|
|
51
|
-
command: string;
|
|
52
|
-
args: string[];
|
|
53
|
-
timestamp: string;
|
|
54
|
-
}
|
|
55
|
-
interface SessionListResponse {
|
|
56
|
-
sessions: Array<{
|
|
57
|
-
sessionId: string;
|
|
58
|
-
hasActiveProcess: boolean;
|
|
59
|
-
createdAt: string;
|
|
60
|
-
}>;
|
|
61
|
-
count: number;
|
|
62
|
-
timestamp: string;
|
|
63
|
-
}
|
|
64
|
-
interface GitCheckoutResponse {
|
|
65
|
-
success: boolean;
|
|
66
|
-
stdout: string;
|
|
67
|
-
stderr: string;
|
|
68
|
-
exitCode: number;
|
|
69
|
-
repoUrl: string;
|
|
70
|
-
branch: string;
|
|
71
|
-
targetDir: string;
|
|
72
|
-
timestamp: string;
|
|
73
|
-
}
|
|
74
|
-
interface MkdirResponse {
|
|
75
|
-
success: boolean;
|
|
76
|
-
stdout: string;
|
|
77
|
-
stderr: string;
|
|
78
|
-
exitCode: number;
|
|
79
|
-
path: string;
|
|
80
|
-
recursive: boolean;
|
|
81
|
-
timestamp: string;
|
|
82
|
-
}
|
|
83
|
-
interface WriteFileResponse {
|
|
84
|
-
success: boolean;
|
|
85
|
-
exitCode: number;
|
|
86
|
-
path: string;
|
|
87
|
-
timestamp: string;
|
|
88
|
-
}
|
|
89
|
-
interface ReadFileResponse {
|
|
90
|
-
success: boolean;
|
|
91
|
-
exitCode: number;
|
|
92
|
-
path: string;
|
|
93
|
-
content: string;
|
|
94
|
-
timestamp: string;
|
|
95
|
-
}
|
|
96
|
-
interface DeleteFileResponse {
|
|
97
|
-
success: boolean;
|
|
98
|
-
exitCode: number;
|
|
99
|
-
path: string;
|
|
100
|
-
timestamp: string;
|
|
101
|
-
}
|
|
102
|
-
interface RenameFileResponse {
|
|
103
|
-
success: boolean;
|
|
104
|
-
exitCode: number;
|
|
105
|
-
oldPath: string;
|
|
106
|
-
newPath: string;
|
|
107
|
-
timestamp: string;
|
|
108
|
-
}
|
|
109
|
-
interface MoveFileResponse {
|
|
110
|
-
success: boolean;
|
|
111
|
-
exitCode: number;
|
|
112
|
-
sourcePath: string;
|
|
113
|
-
destinationPath: string;
|
|
114
|
-
timestamp: string;
|
|
115
|
-
}
|
|
116
|
-
interface StreamEvent {
|
|
117
|
-
type: "command_start" | "output" | "command_complete" | "error";
|
|
118
|
-
command?: string;
|
|
119
|
-
args?: string[];
|
|
120
|
-
stream?: "stdout" | "stderr";
|
|
121
|
-
data?: string;
|
|
122
|
-
message?: string;
|
|
123
|
-
path?: string;
|
|
124
|
-
oldPath?: string;
|
|
125
|
-
newPath?: string;
|
|
126
|
-
sourcePath?: string;
|
|
127
|
-
destinationPath?: string;
|
|
128
|
-
content?: string;
|
|
129
|
-
success?: boolean;
|
|
130
|
-
exitCode?: number;
|
|
131
|
-
stdout?: string;
|
|
132
|
-
stderr?: string;
|
|
133
|
-
error?: string;
|
|
134
|
-
timestamp?: string;
|
|
135
|
-
}
|
|
136
|
-
interface HttpClientOptions {
|
|
137
|
-
stub?: Sandbox;
|
|
138
|
-
baseUrl?: string;
|
|
139
|
-
port?: number;
|
|
140
|
-
onCommandStart?: (command: string, args: string[]) => void;
|
|
141
|
-
onOutput?: (stream: "stdout" | "stderr", data: string, command: string) => void;
|
|
142
|
-
onCommandComplete?: (success: boolean, exitCode: number, stdout: string, stderr: string, command: string, args: string[]) => void;
|
|
143
|
-
onError?: (error: string, command?: string, args?: string[]) => void;
|
|
144
|
-
onStreamEvent?: (event: StreamEvent) => void;
|
|
145
|
-
}
|
|
146
|
-
declare class HttpClient {
|
|
147
|
-
private baseUrl;
|
|
148
|
-
private options;
|
|
149
|
-
private sessionId;
|
|
150
|
-
constructor(options?: HttpClientOptions);
|
|
151
|
-
private doFetch;
|
|
152
|
-
setOnOutput(handler: (stream: "stdout" | "stderr", data: string, command: string) => void): void;
|
|
153
|
-
setOnCommandComplete(handler: (success: boolean, exitCode: number, stdout: string, stderr: string, command: string, args: string[]) => void): void;
|
|
154
|
-
setOnStreamEvent(handler: (event: StreamEvent) => void): void;
|
|
155
|
-
getOnOutput(): ((stream: "stdout" | "stderr", data: string, command: string) => void) | undefined;
|
|
156
|
-
getOnCommandComplete(): ((success: boolean, exitCode: number, stdout: string, stderr: string, command: string, args: string[]) => void) | undefined;
|
|
157
|
-
getOnStreamEvent(): ((event: StreamEvent) => void) | undefined;
|
|
158
|
-
createSession(): Promise<string>;
|
|
159
|
-
listSessions(): Promise<SessionListResponse>;
|
|
160
|
-
execute(command: string, args?: string[], sessionId?: string): Promise<ExecuteResponse>;
|
|
161
|
-
executeStream(command: string, args?: string[], sessionId?: string): Promise<void>;
|
|
162
|
-
gitCheckout(repoUrl: string, branch?: string, targetDir?: string, sessionId?: string): Promise<GitCheckoutResponse>;
|
|
163
|
-
gitCheckoutStream(repoUrl: string, branch?: string, targetDir?: string, sessionId?: string): Promise<void>;
|
|
164
|
-
mkdir(path: string, recursive?: boolean, sessionId?: string): Promise<MkdirResponse>;
|
|
165
|
-
mkdirStream(path: string, recursive?: boolean, sessionId?: string): Promise<void>;
|
|
166
|
-
writeFile(path: string, content: string, encoding?: string, sessionId?: string): Promise<WriteFileResponse>;
|
|
167
|
-
writeFileStream(path: string, content: string, encoding?: string, sessionId?: string): Promise<void>;
|
|
168
|
-
readFile(path: string, encoding?: string, sessionId?: string): Promise<ReadFileResponse>;
|
|
169
|
-
readFileStream(path: string, encoding?: string, sessionId?: string): Promise<void>;
|
|
170
|
-
deleteFile(path: string, sessionId?: string): Promise<DeleteFileResponse>;
|
|
171
|
-
deleteFileStream(path: string, sessionId?: string): Promise<void>;
|
|
172
|
-
renameFile(oldPath: string, newPath: string, sessionId?: string): Promise<RenameFileResponse>;
|
|
173
|
-
renameFileStream(oldPath: string, newPath: string, sessionId?: string): Promise<void>;
|
|
174
|
-
moveFile(sourcePath: string, destinationPath: string, sessionId?: string): Promise<MoveFileResponse>;
|
|
175
|
-
moveFileStream(sourcePath: string, destinationPath: string, sessionId?: string): Promise<void>;
|
|
176
|
-
ping(): Promise<string>;
|
|
177
|
-
getCommands(): Promise<string[]>;
|
|
178
|
-
getSessionId(): string | null;
|
|
179
|
-
setSessionId(sessionId: string): void;
|
|
180
|
-
clearSession(): void;
|
|
181
|
-
}
|
|
182
|
-
declare function createClient(options?: HttpClientOptions): HttpClient;
|
|
183
|
-
declare function quickExecute(command: string, args?: string[], options?: HttpClientOptions): Promise<ExecuteResponse>;
|
|
184
|
-
declare function quickExecuteStream(command: string, args?: string[], options?: HttpClientOptions): Promise<void>;
|
|
185
|
-
declare function quickGitCheckout(repoUrl: string, branch?: string, targetDir?: string, options?: HttpClientOptions): Promise<GitCheckoutResponse>;
|
|
186
|
-
declare function quickMkdir(path: string, recursive?: boolean, options?: HttpClientOptions): Promise<MkdirResponse>;
|
|
187
|
-
declare function quickGitCheckoutStream(repoUrl: string, branch?: string, targetDir?: string, options?: HttpClientOptions): Promise<void>;
|
|
188
|
-
declare function quickMkdirStream(path: string, recursive?: boolean, options?: HttpClientOptions): Promise<void>;
|
|
189
|
-
declare function quickWriteFile(path: string, content: string, encoding?: string, options?: HttpClientOptions): Promise<WriteFileResponse>;
|
|
190
|
-
declare function quickWriteFileStream(path: string, content: string, encoding?: string, options?: HttpClientOptions): Promise<void>;
|
|
191
|
-
declare function quickReadFile(path: string, encoding?: string, options?: HttpClientOptions): Promise<ReadFileResponse>;
|
|
192
|
-
declare function quickReadFileStream(path: string, encoding?: string, options?: HttpClientOptions): Promise<void>;
|
|
193
|
-
declare function quickDeleteFile(path: string, options?: HttpClientOptions): Promise<DeleteFileResponse>;
|
|
194
|
-
declare function quickDeleteFileStream(path: string, options?: HttpClientOptions): Promise<void>;
|
|
195
|
-
declare function quickRenameFile(oldPath: string, newPath: string, options?: HttpClientOptions): Promise<RenameFileResponse>;
|
|
196
|
-
declare function quickRenameFileStream(oldPath: string, newPath: string, options?: HttpClientOptions): Promise<void>;
|
|
197
|
-
declare function quickMoveFile(sourcePath: string, destinationPath: string, options?: HttpClientOptions): Promise<MoveFileResponse>;
|
|
198
|
-
declare function quickMoveFileStream(sourcePath: string, destinationPath: string, options?: HttpClientOptions): Promise<void>;
|
|
199
|
-
|
|
200
|
-
export { type DeleteFileResponse as D, type ExecuteResponse as E, type GitCheckoutResponse as G, HttpClient as H, type MkdirResponse as M, type ReadFileResponse as R, Sandbox, type WriteFileResponse as W, type RenameFileResponse as a, type MoveFileResponse as b, createClient as c, quickExecuteStream as d, quickGitCheckout as e, quickMkdir as f, quickGitCheckoutStream as g, getSandbox, quickMkdirStream as h, quickWriteFile as i, quickWriteFileStream as j, quickReadFile as k, quickReadFileStream as l, quickDeleteFile as m, quickDeleteFileStream as n, quickRenameFile as o, quickRenameFileStream as p, quickExecute as q, quickMoveFile as r, quickMoveFileStream as s };
|
|
1
|
+
export { D as DeleteFileResponse, E as ExecuteResponse, G as GitCheckoutResponse, M as MkdirResponse, a as MoveFileResponse, R as ReadFileResponse, b as RenameFileResponse, S as Sandbox, W as WriteFileResponse, g as getSandbox } from './client-Da-mLX4p.js';
|
|
2
|
+
export { RouteInfo, SandboxEnv, proxyToSandbox } from './request-handler.js';
|
|
3
|
+
export { asyncIterableToSSEStream, parseSSEStream, responseToAsyncIterable } from './sse-parser.js';
|
|
4
|
+
export { ExecEvent, LogEvent } from './types.js';
|
|
5
|
+
import '@cloudflare/containers';
|