@cloudflare/sandbox
Advanced tools
| // src/client.ts | ||
| var HttpClient = class { | ||
| baseUrl; | ||
| options; | ||
| sessionId = null; | ||
| constructor(options = {}) { | ||
| this.options = { | ||
| ...options | ||
| }; | ||
| this.baseUrl = this.options.baseUrl; | ||
| } | ||
| async doFetch(path, options) { | ||
| if (this.options.stub) { | ||
| return this.options.stub.containerFetch(path, options, this.options.port); | ||
| } | ||
| return fetch(this.baseUrl + path, options); | ||
| } | ||
| // Public methods to set event handlers | ||
| setOnOutput(handler) { | ||
| this.options.onOutput = handler; | ||
| } | ||
| setOnCommandComplete(handler) { | ||
| this.options.onCommandComplete = handler; | ||
| } | ||
| setOnStreamEvent(handler) { | ||
| this.options.onStreamEvent = handler; | ||
| } | ||
| // Public getter methods | ||
| getOnOutput() { | ||
| return this.options.onOutput; | ||
| } | ||
| getOnCommandComplete() { | ||
| return this.options.onCommandComplete; | ||
| } | ||
| getOnStreamEvent() { | ||
| return this.options.onStreamEvent; | ||
| } | ||
| async createSession() { | ||
| try { | ||
| const response = await this.doFetch(`/api/session/create`, { | ||
| headers: { | ||
| "Content-Type": "application/json" | ||
| }, | ||
| method: "POST" | ||
| }); | ||
| if (!response.ok) { | ||
| throw new Error(`HTTP error! status: ${response.status}`); | ||
| } | ||
| const data = await response.json(); | ||
| this.sessionId = data.sessionId; | ||
| console.log(`[HTTP Client] Created session: ${this.sessionId}`); | ||
| return this.sessionId; | ||
| } catch (error) { | ||
| console.error("[HTTP Client] Error creating session:", error); | ||
| throw error; | ||
| } | ||
| } | ||
| async listSessions() { | ||
| try { | ||
| const response = await this.doFetch(`/api/session/list`, { | ||
| headers: { | ||
| "Content-Type": "application/json" | ||
| }, | ||
| method: "GET" | ||
| }); | ||
| if (!response.ok) { | ||
| throw new Error(`HTTP error! status: ${response.status}`); | ||
| } | ||
| const data = await response.json(); | ||
| console.log(`[HTTP Client] Listed ${data.count} sessions`); | ||
| return data; | ||
| } catch (error) { | ||
| console.error("[HTTP Client] Error listing sessions:", error); | ||
| throw error; | ||
| } | ||
| } | ||
| async execute(command, args = [], sessionId) { | ||
| try { | ||
| const targetSessionId = sessionId || this.sessionId; | ||
| const response = await this.doFetch(`/api/execute`, { | ||
| body: JSON.stringify({ | ||
| args, | ||
| command, | ||
| sessionId: targetSessionId | ||
| }), | ||
| headers: { | ||
| "Content-Type": "application/json" | ||
| }, | ||
| method: "POST" | ||
| }); | ||
| if (!response.ok) { | ||
| const errorData = await response.json().catch(() => ({})); | ||
| throw new Error( | ||
| errorData.error || `HTTP error! status: ${response.status}` | ||
| ); | ||
| } | ||
| const data = await response.json(); | ||
| console.log( | ||
| `[HTTP Client] Command executed: ${command}, Success: ${data.success}` | ||
| ); | ||
| this.options.onCommandComplete?.( | ||
| data.success, | ||
| data.exitCode, | ||
| data.stdout, | ||
| data.stderr, | ||
| data.command, | ||
| data.args | ||
| ); | ||
| return data; | ||
| } catch (error) { | ||
| console.error("[HTTP Client] Error executing command:", error); | ||
| this.options.onError?.( | ||
| error instanceof Error ? error.message : "Unknown error", | ||
| command, | ||
| args | ||
| ); | ||
| throw error; | ||
| } | ||
| } | ||
| async executeStream(command, args = [], sessionId) { | ||
| try { | ||
| const targetSessionId = sessionId || this.sessionId; | ||
| const response = await this.doFetch(`/api/execute/stream`, { | ||
| body: JSON.stringify({ | ||
| args, | ||
| command, | ||
| sessionId: targetSessionId | ||
| }), | ||
| headers: { | ||
| "Content-Type": "application/json" | ||
| }, | ||
| method: "POST" | ||
| }); | ||
| if (!response.ok) { | ||
| const errorData = await response.json().catch(() => ({})); | ||
| throw new Error( | ||
| errorData.error || `HTTP error! status: ${response.status}` | ||
| ); | ||
| } | ||
| if (!response.body) { | ||
| throw new Error("No response body for streaming request"); | ||
| } | ||
| const reader = response.body.getReader(); | ||
| const decoder = new TextDecoder(); | ||
| try { | ||
| while (true) { | ||
| const { done, value } = await reader.read(); | ||
| if (done) { | ||
| break; | ||
| } | ||
| const chunk = decoder.decode(value, { stream: true }); | ||
| const lines = chunk.split("\n"); | ||
| for (const line of lines) { | ||
| if (line.startsWith("data: ")) { | ||
| try { | ||
| const eventData = line.slice(6); | ||
| const event = JSON.parse(eventData); | ||
| console.log(`[HTTP Client] Stream event: ${event.type}`); | ||
| this.options.onStreamEvent?.(event); | ||
| switch (event.type) { | ||
| case "command_start": | ||
| console.log( | ||
| `[HTTP Client] Command started: ${event.command} ${event.args?.join(" ")}` | ||
| ); | ||
| this.options.onCommandStart?.( | ||
| event.command, | ||
| event.args || [] | ||
| ); | ||
| break; | ||
| case "output": | ||
| console.log(`[${event.stream}] ${event.data}`); | ||
| this.options.onOutput?.( | ||
| event.stream, | ||
| event.data, | ||
| event.command | ||
| ); | ||
| break; | ||
| case "command_complete": | ||
| console.log( | ||
| `[HTTP Client] Command completed: ${event.command}, Success: ${event.success}, Exit code: ${event.exitCode}` | ||
| ); | ||
| this.options.onCommandComplete?.( | ||
| event.success, | ||
| event.exitCode, | ||
| event.stdout, | ||
| event.stderr, | ||
| event.command, | ||
| event.args || [] | ||
| ); | ||
| break; | ||
| case "error": | ||
| console.error( | ||
| `[HTTP Client] Command error: ${event.error}` | ||
| ); | ||
| this.options.onError?.( | ||
| event.error, | ||
| event.command, | ||
| event.args | ||
| ); | ||
| break; | ||
| } | ||
| } catch (parseError) { | ||
| console.warn( | ||
| "[HTTP Client] Failed to parse stream event:", | ||
| parseError | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } finally { | ||
| reader.releaseLock(); | ||
| } | ||
| } catch (error) { | ||
| console.error("[HTTP Client] Error in streaming execution:", error); | ||
| this.options.onError?.( | ||
| error instanceof Error ? error.message : "Unknown error", | ||
| command, | ||
| args | ||
| ); | ||
| throw error; | ||
| } | ||
| } | ||
| async gitCheckout(repoUrl, branch = "main", targetDir, sessionId) { | ||
| try { | ||
| const targetSessionId = sessionId || this.sessionId; | ||
| const response = await this.doFetch(`/api/git/checkout`, { | ||
| body: JSON.stringify({ | ||
| branch, | ||
| repoUrl, | ||
| sessionId: targetSessionId, | ||
| targetDir | ||
| }), | ||
| headers: { | ||
| "Content-Type": "application/json" | ||
| }, | ||
| method: "POST" | ||
| }); | ||
| if (!response.ok) { | ||
| const errorData = await response.json().catch(() => ({})); | ||
| throw new Error( | ||
| errorData.error || `HTTP error! status: ${response.status}` | ||
| ); | ||
| } | ||
| const data = await response.json(); | ||
| console.log( | ||
| `[HTTP Client] Git checkout completed: ${repoUrl}, Success: ${data.success}, Target: ${data.targetDir}` | ||
| ); | ||
| return data; | ||
| } catch (error) { | ||
| console.error("[HTTP Client] Error in git checkout:", error); | ||
| throw error; | ||
| } | ||
| } | ||
| async gitCheckoutStream(repoUrl, branch = "main", targetDir, sessionId) { | ||
| try { | ||
| const targetSessionId = sessionId || this.sessionId; | ||
| const response = await this.doFetch(`/api/git/checkout/stream`, { | ||
| body: JSON.stringify({ | ||
| branch, | ||
| repoUrl, | ||
| sessionId: targetSessionId, | ||
| targetDir | ||
| }), | ||
| headers: { | ||
| "Content-Type": "application/json" | ||
| }, | ||
| method: "POST" | ||
| }); | ||
| if (!response.ok) { | ||
| const errorData = await response.json().catch(() => ({})); | ||
| throw new Error( | ||
| errorData.error || `HTTP error! status: ${response.status}` | ||
| ); | ||
| } | ||
| if (!response.body) { | ||
| throw new Error("No response body for streaming request"); | ||
| } | ||
| const reader = response.body.getReader(); | ||
| const decoder = new TextDecoder(); | ||
| try { | ||
| while (true) { | ||
| const { done, value } = await reader.read(); | ||
| if (done) { | ||
| break; | ||
| } | ||
| const chunk = decoder.decode(value, { stream: true }); | ||
| const lines = chunk.split("\n"); | ||
| for (const line of lines) { | ||
| if (line.startsWith("data: ")) { | ||
| try { | ||
| const eventData = line.slice(6); | ||
| const event = JSON.parse(eventData); | ||
| console.log( | ||
| `[HTTP Client] Git checkout stream event: ${event.type}` | ||
| ); | ||
| this.options.onStreamEvent?.(event); | ||
| switch (event.type) { | ||
| case "command_start": | ||
| console.log( | ||
| `[HTTP Client] Git checkout started: ${event.command} ${event.args?.join(" ")}` | ||
| ); | ||
| this.options.onCommandStart?.( | ||
| event.command, | ||
| event.args || [] | ||
| ); | ||
| break; | ||
| case "output": | ||
| console.log(`[${event.stream}] ${event.data}`); | ||
| this.options.onOutput?.( | ||
| event.stream, | ||
| event.data, | ||
| event.command | ||
| ); | ||
| break; | ||
| case "command_complete": | ||
| console.log( | ||
| `[HTTP Client] Git checkout completed: ${event.command}, Success: ${event.success}, Exit code: ${event.exitCode}` | ||
| ); | ||
| this.options.onCommandComplete?.( | ||
| event.success, | ||
| event.exitCode, | ||
| event.stdout, | ||
| event.stderr, | ||
| event.command, | ||
| event.args || [] | ||
| ); | ||
| break; | ||
| case "error": | ||
| console.error( | ||
| `[HTTP Client] Git checkout error: ${event.error}` | ||
| ); | ||
| this.options.onError?.( | ||
| event.error, | ||
| event.command, | ||
| event.args | ||
| ); | ||
| break; | ||
| } | ||
| } catch (parseError) { | ||
| console.warn( | ||
| "[HTTP Client] Failed to parse git checkout stream event:", | ||
| parseError | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } finally { | ||
| reader.releaseLock(); | ||
| } | ||
| } catch (error) { | ||
| console.error("[HTTP Client] Error in streaming git checkout:", error); | ||
| this.options.onError?.( | ||
| error instanceof Error ? error.message : "Unknown error", | ||
| "git clone", | ||
| [branch, repoUrl, targetDir || ""] | ||
| ); | ||
| throw error; | ||
| } | ||
| } | ||
| async mkdir(path, recursive = false, sessionId) { | ||
| try { | ||
| const targetSessionId = sessionId || this.sessionId; | ||
| const response = await this.doFetch(`/api/mkdir`, { | ||
| body: JSON.stringify({ | ||
| path, | ||
| recursive, | ||
| sessionId: targetSessionId | ||
| }), | ||
| headers: { | ||
| "Content-Type": "application/json" | ||
| }, | ||
| method: "POST" | ||
| }); | ||
| if (!response.ok) { | ||
| const errorData = await response.json().catch(() => ({})); | ||
| throw new Error( | ||
| errorData.error || `HTTP error! status: ${response.status}` | ||
| ); | ||
| } | ||
| const data = await response.json(); | ||
| console.log( | ||
| `[HTTP Client] Directory created: ${path}, Success: ${data.success}, Recursive: ${data.recursive}` | ||
| ); | ||
| return data; | ||
| } catch (error) { | ||
| console.error("[HTTP Client] Error creating directory:", error); | ||
| throw error; | ||
| } | ||
| } | ||
| async mkdirStream(path, recursive = false, sessionId) { | ||
| try { | ||
| const targetSessionId = sessionId || this.sessionId; | ||
| const response = await this.doFetch(`/api/mkdir/stream`, { | ||
| body: JSON.stringify({ | ||
| path, | ||
| recursive, | ||
| sessionId: targetSessionId | ||
| }), | ||
| headers: { | ||
| "Content-Type": "application/json" | ||
| }, | ||
| method: "POST" | ||
| }); | ||
| if (!response.ok) { | ||
| const errorData = await response.json().catch(() => ({})); | ||
| throw new Error( | ||
| errorData.error || `HTTP error! status: ${response.status}` | ||
| ); | ||
| } | ||
| if (!response.body) { | ||
| throw new Error("No response body for streaming request"); | ||
| } | ||
| const reader = response.body.getReader(); | ||
| const decoder = new TextDecoder(); | ||
| try { | ||
| while (true) { | ||
| const { done, value } = await reader.read(); | ||
| if (done) { | ||
| break; | ||
| } | ||
| const chunk = decoder.decode(value, { stream: true }); | ||
| const lines = chunk.split("\n"); | ||
| for (const line of lines) { | ||
| if (line.startsWith("data: ")) { | ||
| try { | ||
| const eventData = line.slice(6); | ||
| const event = JSON.parse(eventData); | ||
| console.log(`[HTTP Client] Mkdir stream event: ${event.type}`); | ||
| this.options.onStreamEvent?.(event); | ||
| switch (event.type) { | ||
| case "command_start": | ||
| console.log( | ||
| `[HTTP Client] Mkdir started: ${event.command} ${event.args?.join(" ")}` | ||
| ); | ||
| this.options.onCommandStart?.( | ||
| event.command, | ||
| event.args || [] | ||
| ); | ||
| break; | ||
| case "output": | ||
| console.log(`[${event.stream}] ${event.data}`); | ||
| this.options.onOutput?.( | ||
| event.stream, | ||
| event.data, | ||
| event.command | ||
| ); | ||
| break; | ||
| case "command_complete": | ||
| console.log( | ||
| `[HTTP Client] Mkdir completed: ${event.command}, Success: ${event.success}, Exit code: ${event.exitCode}` | ||
| ); | ||
| this.options.onCommandComplete?.( | ||
| event.success, | ||
| event.exitCode, | ||
| event.stdout, | ||
| event.stderr, | ||
| event.command, | ||
| event.args || [] | ||
| ); | ||
| break; | ||
| case "error": | ||
| console.error(`[HTTP Client] Mkdir error: ${event.error}`); | ||
| this.options.onError?.( | ||
| event.error, | ||
| event.command, | ||
| event.args | ||
| ); | ||
| break; | ||
| } | ||
| } catch (parseError) { | ||
| console.warn( | ||
| "[HTTP Client] Failed to parse mkdir stream event:", | ||
| parseError | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } finally { | ||
| reader.releaseLock(); | ||
| } | ||
| } catch (error) { | ||
| console.error("[HTTP Client] Error in streaming mkdir:", error); | ||
| this.options.onError?.( | ||
| error instanceof Error ? error.message : "Unknown error", | ||
| "mkdir", | ||
| recursive ? ["-p", path] : [path] | ||
| ); | ||
| throw error; | ||
| } | ||
| } | ||
| async writeFile(path, content, encoding = "utf-8", sessionId) { | ||
| try { | ||
| const targetSessionId = sessionId || this.sessionId; | ||
| const response = await this.doFetch(`/api/write`, { | ||
| body: JSON.stringify({ | ||
| content, | ||
| encoding, | ||
| path, | ||
| sessionId: targetSessionId | ||
| }), | ||
| headers: { | ||
| "Content-Type": "application/json" | ||
| }, | ||
| method: "POST" | ||
| }); | ||
| if (!response.ok) { | ||
| const errorData = await response.json().catch(() => ({})); | ||
| throw new Error( | ||
| errorData.error || `HTTP error! status: ${response.status}` | ||
| ); | ||
| } | ||
| const data = await response.json(); | ||
| console.log( | ||
| `[HTTP Client] File written: ${path}, Success: ${data.success}` | ||
| ); | ||
| return data; | ||
| } catch (error) { | ||
| console.error("[HTTP Client] Error writing file:", error); | ||
| throw error; | ||
| } | ||
| } | ||
| async writeFileStream(path, content, encoding = "utf-8", sessionId) { | ||
| try { | ||
| const targetSessionId = sessionId || this.sessionId; | ||
| const response = await this.doFetch(`/api/write/stream`, { | ||
| body: JSON.stringify({ | ||
| content, | ||
| encoding, | ||
| path, | ||
| sessionId: targetSessionId | ||
| }), | ||
| headers: { | ||
| "Content-Type": "application/json" | ||
| }, | ||
| method: "POST" | ||
| }); | ||
| if (!response.ok) { | ||
| const errorData = await response.json().catch(() => ({})); | ||
| throw new Error( | ||
| errorData.error || `HTTP error! status: ${response.status}` | ||
| ); | ||
| } | ||
| if (!response.body) { | ||
| throw new Error("No response body for streaming request"); | ||
| } | ||
| const reader = response.body.getReader(); | ||
| const decoder = new TextDecoder(); | ||
| try { | ||
| while (true) { | ||
| const { done, value } = await reader.read(); | ||
| if (done) { | ||
| break; | ||
| } | ||
| const chunk = decoder.decode(value, { stream: true }); | ||
| const lines = chunk.split("\n"); | ||
| for (const line of lines) { | ||
| if (line.startsWith("data: ")) { | ||
| try { | ||
| const eventData = line.slice(6); | ||
| const event = JSON.parse(eventData); | ||
| console.log( | ||
| `[HTTP Client] Write file stream event: ${event.type}` | ||
| ); | ||
| this.options.onStreamEvent?.(event); | ||
| switch (event.type) { | ||
| case "command_start": | ||
| console.log( | ||
| `[HTTP Client] Write file started: ${event.path}` | ||
| ); | ||
| this.options.onCommandStart?.("write", [ | ||
| path, | ||
| content, | ||
| encoding | ||
| ]); | ||
| break; | ||
| case "output": | ||
| console.log(`[output] ${event.message}`); | ||
| this.options.onOutput?.("stdout", event.message, "write"); | ||
| break; | ||
| case "command_complete": | ||
| console.log( | ||
| `[HTTP Client] Write file completed: ${event.path}, Success: ${event.success}` | ||
| ); | ||
| this.options.onCommandComplete?.( | ||
| event.success, | ||
| 0, | ||
| "", | ||
| "", | ||
| "write", | ||
| [path, content, encoding] | ||
| ); | ||
| break; | ||
| case "error": | ||
| console.error( | ||
| `[HTTP Client] Write file error: ${event.error}` | ||
| ); | ||
| this.options.onError?.(event.error, "write", [ | ||
| path, | ||
| content, | ||
| encoding | ||
| ]); | ||
| break; | ||
| } | ||
| } catch (parseError) { | ||
| console.warn( | ||
| "[HTTP Client] Failed to parse write file stream event:", | ||
| parseError | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } finally { | ||
| reader.releaseLock(); | ||
| } | ||
| } catch (error) { | ||
| console.error("[HTTP Client] Error in streaming write file:", error); | ||
| this.options.onError?.( | ||
| error instanceof Error ? error.message : "Unknown error", | ||
| "write", | ||
| [path, content, encoding] | ||
| ); | ||
| throw error; | ||
| } | ||
| } | ||
| async deleteFile(path, sessionId) { | ||
| try { | ||
| const targetSessionId = sessionId || this.sessionId; | ||
| const response = await this.doFetch(`/api/delete`, { | ||
| body: JSON.stringify({ | ||
| path, | ||
| sessionId: targetSessionId | ||
| }), | ||
| headers: { | ||
| "Content-Type": "application/json" | ||
| }, | ||
| method: "POST" | ||
| }); | ||
| if (!response.ok) { | ||
| const errorData = await response.json().catch(() => ({})); | ||
| throw new Error( | ||
| errorData.error || `HTTP error! status: ${response.status}` | ||
| ); | ||
| } | ||
| const data = await response.json(); | ||
| console.log( | ||
| `[HTTP Client] File deleted: ${path}, Success: ${data.success}` | ||
| ); | ||
| return data; | ||
| } catch (error) { | ||
| console.error("[HTTP Client] Error deleting file:", error); | ||
| throw error; | ||
| } | ||
| } | ||
| async deleteFileStream(path, sessionId) { | ||
| try { | ||
| const targetSessionId = sessionId || this.sessionId; | ||
| const response = await this.doFetch(`/api/delete/stream`, { | ||
| body: JSON.stringify({ | ||
| path, | ||
| sessionId: targetSessionId | ||
| }), | ||
| headers: { | ||
| "Content-Type": "application/json" | ||
| }, | ||
| method: "POST" | ||
| }); | ||
| if (!response.ok) { | ||
| const errorData = await response.json().catch(() => ({})); | ||
| throw new Error( | ||
| errorData.error || `HTTP error! status: ${response.status}` | ||
| ); | ||
| } | ||
| if (!response.body) { | ||
| throw new Error("No response body for streaming request"); | ||
| } | ||
| const reader = response.body.getReader(); | ||
| const decoder = new TextDecoder(); | ||
| try { | ||
| while (true) { | ||
| const { done, value } = await reader.read(); | ||
| if (done) { | ||
| break; | ||
| } | ||
| const chunk = decoder.decode(value, { stream: true }); | ||
| const lines = chunk.split("\n"); | ||
| for (const line of lines) { | ||
| if (line.startsWith("data: ")) { | ||
| try { | ||
| const eventData = line.slice(6); | ||
| const event = JSON.parse(eventData); | ||
| console.log( | ||
| `[HTTP Client] Delete file stream event: ${event.type}` | ||
| ); | ||
| this.options.onStreamEvent?.(event); | ||
| switch (event.type) { | ||
| case "command_start": | ||
| console.log( | ||
| `[HTTP Client] Delete file started: ${event.path}` | ||
| ); | ||
| this.options.onCommandStart?.("delete", [path]); | ||
| break; | ||
| case "command_complete": | ||
| console.log( | ||
| `[HTTP Client] Delete file completed: ${event.path}, Success: ${event.success}` | ||
| ); | ||
| this.options.onCommandComplete?.( | ||
| event.success, | ||
| 0, | ||
| "", | ||
| "", | ||
| "delete", | ||
| [path] | ||
| ); | ||
| break; | ||
| case "error": | ||
| console.error( | ||
| `[HTTP Client] Delete file error: ${event.error}` | ||
| ); | ||
| this.options.onError?.(event.error, "delete", [path]); | ||
| break; | ||
| } | ||
| } catch (parseError) { | ||
| console.warn( | ||
| "[HTTP Client] Failed to parse delete file stream event:", | ||
| parseError | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } finally { | ||
| reader.releaseLock(); | ||
| } | ||
| } catch (error) { | ||
| console.error("[HTTP Client] Error in streaming delete file:", error); | ||
| this.options.onError?.( | ||
| error instanceof Error ? error.message : "Unknown error", | ||
| "delete", | ||
| [path] | ||
| ); | ||
| throw error; | ||
| } | ||
| } | ||
| async renameFile(oldPath, newPath, sessionId) { | ||
| try { | ||
| const targetSessionId = sessionId || this.sessionId; | ||
| const response = await this.doFetch(`/api/rename`, { | ||
| body: JSON.stringify({ | ||
| newPath, | ||
| oldPath, | ||
| sessionId: targetSessionId | ||
| }), | ||
| headers: { | ||
| "Content-Type": "application/json" | ||
| }, | ||
| method: "POST" | ||
| }); | ||
| if (!response.ok) { | ||
| const errorData = await response.json().catch(() => ({})); | ||
| throw new Error( | ||
| errorData.error || `HTTP error! status: ${response.status}` | ||
| ); | ||
| } | ||
| const data = await response.json(); | ||
| console.log( | ||
| `[HTTP Client] File renamed: ${oldPath} -> ${newPath}, Success: ${data.success}` | ||
| ); | ||
| return data; | ||
| } catch (error) { | ||
| console.error("[HTTP Client] Error renaming file:", error); | ||
| throw error; | ||
| } | ||
| } | ||
| async renameFileStream(oldPath, newPath, sessionId) { | ||
| try { | ||
| const targetSessionId = sessionId || this.sessionId; | ||
| const response = await this.doFetch(`/api/rename/stream`, { | ||
| body: JSON.stringify({ | ||
| newPath, | ||
| oldPath, | ||
| sessionId: targetSessionId | ||
| }), | ||
| headers: { | ||
| "Content-Type": "application/json" | ||
| }, | ||
| method: "POST" | ||
| }); | ||
| if (!response.ok) { | ||
| const errorData = await response.json().catch(() => ({})); | ||
| throw new Error( | ||
| errorData.error || `HTTP error! status: ${response.status}` | ||
| ); | ||
| } | ||
| if (!response.body) { | ||
| throw new Error("No response body for streaming request"); | ||
| } | ||
| const reader = response.body.getReader(); | ||
| const decoder = new TextDecoder(); | ||
| try { | ||
| while (true) { | ||
| const { done, value } = await reader.read(); | ||
| if (done) { | ||
| break; | ||
| } | ||
| const chunk = decoder.decode(value, { stream: true }); | ||
| const lines = chunk.split("\n"); | ||
| for (const line of lines) { | ||
| if (line.startsWith("data: ")) { | ||
| try { | ||
| const eventData = line.slice(6); | ||
| const event = JSON.parse(eventData); | ||
| console.log( | ||
| `[HTTP Client] Rename file stream event: ${event.type}` | ||
| ); | ||
| this.options.onStreamEvent?.(event); | ||
| switch (event.type) { | ||
| case "command_start": | ||
| console.log( | ||
| `[HTTP Client] Rename file started: ${event.oldPath} -> ${event.newPath}` | ||
| ); | ||
| this.options.onCommandStart?.("rename", [oldPath, newPath]); | ||
| break; | ||
| case "command_complete": | ||
| console.log( | ||
| `[HTTP Client] Rename file completed: ${event.oldPath} -> ${event.newPath}, Success: ${event.success}` | ||
| ); | ||
| this.options.onCommandComplete?.( | ||
| event.success, | ||
| 0, | ||
| "", | ||
| "", | ||
| "rename", | ||
| [oldPath, newPath] | ||
| ); | ||
| break; | ||
| case "error": | ||
| console.error( | ||
| `[HTTP Client] Rename file error: ${event.error}` | ||
| ); | ||
| this.options.onError?.(event.error, "rename", [ | ||
| oldPath, | ||
| newPath | ||
| ]); | ||
| break; | ||
| } | ||
| } catch (parseError) { | ||
| console.warn( | ||
| "[HTTP Client] Failed to parse rename file stream event:", | ||
| parseError | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } finally { | ||
| reader.releaseLock(); | ||
| } | ||
| } catch (error) { | ||
| console.error("[HTTP Client] Error in streaming rename file:", error); | ||
| this.options.onError?.( | ||
| error instanceof Error ? error.message : "Unknown error", | ||
| "rename", | ||
| [oldPath, newPath] | ||
| ); | ||
| throw error; | ||
| } | ||
| } | ||
| async moveFile(sourcePath, destinationPath, sessionId) { | ||
| try { | ||
| const targetSessionId = sessionId || this.sessionId; | ||
| const response = await this.doFetch(`/api/move`, { | ||
| body: JSON.stringify({ | ||
| destinationPath, | ||
| sessionId: targetSessionId, | ||
| sourcePath | ||
| }), | ||
| headers: { | ||
| "Content-Type": "application/json" | ||
| }, | ||
| method: "POST" | ||
| }); | ||
| if (!response.ok) { | ||
| const errorData = await response.json().catch(() => ({})); | ||
| throw new Error( | ||
| errorData.error || `HTTP error! status: ${response.status}` | ||
| ); | ||
| } | ||
| const data = await response.json(); | ||
| console.log( | ||
| `[HTTP Client] File moved: ${sourcePath} -> ${destinationPath}, Success: ${data.success}` | ||
| ); | ||
| return data; | ||
| } catch (error) { | ||
| console.error("[HTTP Client] Error moving file:", error); | ||
| throw error; | ||
| } | ||
| } | ||
| async moveFileStream(sourcePath, destinationPath, sessionId) { | ||
| try { | ||
| const targetSessionId = sessionId || this.sessionId; | ||
| const response = await this.doFetch(`/api/move/stream`, { | ||
| body: JSON.stringify({ | ||
| destinationPath, | ||
| sessionId: targetSessionId, | ||
| sourcePath | ||
| }), | ||
| headers: { | ||
| "Content-Type": "application/json" | ||
| }, | ||
| method: "POST" | ||
| }); | ||
| if (!response.ok) { | ||
| const errorData = await response.json().catch(() => ({})); | ||
| throw new Error( | ||
| errorData.error || `HTTP error! status: ${response.status}` | ||
| ); | ||
| } | ||
| if (!response.body) { | ||
| throw new Error("No response body for streaming request"); | ||
| } | ||
| const reader = response.body.getReader(); | ||
| const decoder = new TextDecoder(); | ||
| try { | ||
| while (true) { | ||
| const { done, value } = await reader.read(); | ||
| if (done) { | ||
| break; | ||
| } | ||
| const chunk = decoder.decode(value, { stream: true }); | ||
| const lines = chunk.split("\n"); | ||
| for (const line of lines) { | ||
| if (line.startsWith("data: ")) { | ||
| try { | ||
| const eventData = line.slice(6); | ||
| const event = JSON.parse(eventData); | ||
| console.log( | ||
| `[HTTP Client] Move file stream event: ${event.type}` | ||
| ); | ||
| this.options.onStreamEvent?.(event); | ||
| switch (event.type) { | ||
| case "command_start": | ||
| console.log( | ||
| `[HTTP Client] Move file started: ${event.sourcePath} -> ${event.destinationPath}` | ||
| ); | ||
| this.options.onCommandStart?.("move", [ | ||
| sourcePath, | ||
| destinationPath | ||
| ]); | ||
| break; | ||
| case "command_complete": | ||
| console.log( | ||
| `[HTTP Client] Move file completed: ${event.sourcePath} -> ${event.destinationPath}, Success: ${event.success}` | ||
| ); | ||
| this.options.onCommandComplete?.( | ||
| event.success, | ||
| 0, | ||
| "", | ||
| "", | ||
| "move", | ||
| [sourcePath, destinationPath] | ||
| ); | ||
| break; | ||
| case "error": | ||
| console.error( | ||
| `[HTTP Client] Move file error: ${event.error}` | ||
| ); | ||
| this.options.onError?.(event.error, "move", [ | ||
| sourcePath, | ||
| destinationPath | ||
| ]); | ||
| break; | ||
| } | ||
| } catch (parseError) { | ||
| console.warn( | ||
| "[HTTP Client] Failed to parse move file stream event:", | ||
| parseError | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } finally { | ||
| reader.releaseLock(); | ||
| } | ||
| } catch (error) { | ||
| console.error("[HTTP Client] Error in streaming move file:", error); | ||
| this.options.onError?.( | ||
| error instanceof Error ? error.message : "Unknown error", | ||
| "move", | ||
| [sourcePath, destinationPath] | ||
| ); | ||
| throw error; | ||
| } | ||
| } | ||
| async ping() { | ||
| try { | ||
| const response = await this.doFetch(`/api/ping`, { | ||
| headers: { | ||
| "Content-Type": "application/json" | ||
| }, | ||
| method: "GET" | ||
| }); | ||
| if (!response.ok) { | ||
| throw new Error(`HTTP error! status: ${response.status}`); | ||
| } | ||
| const data = await response.json(); | ||
| console.log(`[HTTP Client] Ping response: ${data.message}`); | ||
| return data.timestamp; | ||
| } catch (error) { | ||
| console.error("[HTTP Client] Error pinging server:", error); | ||
| throw error; | ||
| } | ||
| } | ||
| async getCommands() { | ||
| try { | ||
| const response = await fetch(`${this.baseUrl}/api/commands`, { | ||
| headers: { | ||
| "Content-Type": "application/json" | ||
| }, | ||
| method: "GET" | ||
| }); | ||
| if (!response.ok) { | ||
| throw new Error(`HTTP error! status: ${response.status}`); | ||
| } | ||
| const data = await response.json(); | ||
| console.log( | ||
| `[HTTP Client] Available commands: ${data.availableCommands.length}` | ||
| ); | ||
| return data.availableCommands; | ||
| } catch (error) { | ||
| console.error("[HTTP Client] Error getting commands:", error); | ||
| throw error; | ||
| } | ||
| } | ||
| getSessionId() { | ||
| return this.sessionId; | ||
| } | ||
| setSessionId(sessionId) { | ||
| this.sessionId = sessionId; | ||
| } | ||
| clearSession() { | ||
| this.sessionId = null; | ||
| } | ||
| }; | ||
| function createClient(options) { | ||
| return new HttpClient(options); | ||
| } | ||
| async function quickExecute(command, args = [], options) { | ||
| const client = createClient(options); | ||
| await client.createSession(); | ||
| try { | ||
| return await client.execute(command, args); | ||
| } finally { | ||
| client.clearSession(); | ||
| } | ||
| } | ||
| async function quickExecuteStream(command, args = [], options) { | ||
| const client = createClient(options); | ||
| await client.createSession(); | ||
| try { | ||
| await client.executeStream(command, args); | ||
| } finally { | ||
| client.clearSession(); | ||
| } | ||
| } | ||
| async function quickGitCheckout(repoUrl, branch = "main", targetDir, options) { | ||
| const client = createClient(options); | ||
| await client.createSession(); | ||
| try { | ||
| return await client.gitCheckout(repoUrl, branch, targetDir); | ||
| } finally { | ||
| client.clearSession(); | ||
| } | ||
| } | ||
| async function quickMkdir(path, recursive = false, options) { | ||
| const client = createClient(options); | ||
| await client.createSession(); | ||
| try { | ||
| return await client.mkdir(path, recursive); | ||
| } finally { | ||
| client.clearSession(); | ||
| } | ||
| } | ||
| async function quickGitCheckoutStream(repoUrl, branch = "main", targetDir, options) { | ||
| const client = createClient(options); | ||
| await client.createSession(); | ||
| try { | ||
| await client.gitCheckoutStream(repoUrl, branch, targetDir); | ||
| } finally { | ||
| client.clearSession(); | ||
| } | ||
| } | ||
| async function quickMkdirStream(path, recursive = false, options) { | ||
| const client = createClient(options); | ||
| await client.createSession(); | ||
| try { | ||
| await client.mkdirStream(path, recursive); | ||
| } finally { | ||
| client.clearSession(); | ||
| } | ||
| } | ||
| async function quickWriteFile(path, content, encoding = "utf-8", options) { | ||
| const client = createClient(options); | ||
| await client.createSession(); | ||
| try { | ||
| return await client.writeFile(path, content, encoding); | ||
| } finally { | ||
| client.clearSession(); | ||
| } | ||
| } | ||
| async function quickWriteFileStream(path, content, encoding = "utf-8", options) { | ||
| const client = createClient(options); | ||
| await client.createSession(); | ||
| try { | ||
| await client.writeFileStream(path, content, encoding); | ||
| } finally { | ||
| client.clearSession(); | ||
| } | ||
| } | ||
| async function quickDeleteFile(path, options) { | ||
| const client = createClient(options); | ||
| await client.createSession(); | ||
| try { | ||
| return await client.deleteFile(path); | ||
| } finally { | ||
| client.clearSession(); | ||
| } | ||
| } | ||
| async function quickDeleteFileStream(path, options) { | ||
| const client = createClient(options); | ||
| await client.createSession(); | ||
| try { | ||
| await client.deleteFileStream(path); | ||
| } finally { | ||
| client.clearSession(); | ||
| } | ||
| } | ||
| async function quickRenameFile(oldPath, newPath, options) { | ||
| const client = createClient(options); | ||
| await client.createSession(); | ||
| try { | ||
| return await client.renameFile(oldPath, newPath); | ||
| } finally { | ||
| client.clearSession(); | ||
| } | ||
| } | ||
| async function quickRenameFileStream(oldPath, newPath, options) { | ||
| const client = createClient(options); | ||
| await client.createSession(); | ||
| try { | ||
| await client.renameFileStream(oldPath, newPath); | ||
| } finally { | ||
| client.clearSession(); | ||
| } | ||
| } | ||
| async function quickMoveFile(sourcePath, destinationPath, options) { | ||
| const client = createClient(options); | ||
| await client.createSession(); | ||
| try { | ||
| return await client.moveFile(sourcePath, destinationPath); | ||
| } finally { | ||
| client.clearSession(); | ||
| } | ||
| } | ||
| async function quickMoveFileStream(sourcePath, destinationPath, options) { | ||
| const client = createClient(options); | ||
| await client.createSession(); | ||
| try { | ||
| await client.moveFileStream(sourcePath, destinationPath); | ||
| } finally { | ||
| client.clearSession(); | ||
| } | ||
| } | ||
| export { | ||
| HttpClient, | ||
| createClient, | ||
| quickExecute, | ||
| quickExecuteStream, | ||
| quickGitCheckout, | ||
| quickMkdir, | ||
| quickGitCheckoutStream, | ||
| quickMkdirStream, | ||
| quickWriteFile, | ||
| quickWriteFileStream, | ||
| quickDeleteFile, | ||
| quickDeleteFileStream, | ||
| quickRenameFile, | ||
| quickRenameFileStream, | ||
| quickMoveFile, | ||
| quickMoveFileStream | ||
| }; | ||
| //# sourceMappingURL=chunk-GYEDSCAB.js.map |
Sorry, the diff of this file is too big to display
| export { D as DeleteFileResponse, E as ExecuteResponse, G as GitCheckoutResponse, H as HttpClient, M as MkdirResponse, a as MoveFileResponse, R as RenameFileResponse, W as WriteFileResponse, c as createClient, j as quickDeleteFile, k as quickDeleteFileStream, q as quickExecute, b as quickExecuteStream, d as quickGitCheckout, f as quickGitCheckoutStream, e as quickMkdir, g as quickMkdirStream, n as quickMoveFile, o as quickMoveFileStream, l as quickRenameFile, m as quickRenameFileStream, h as quickWriteFile, i as quickWriteFileStream } from './index.js'; | ||
| import '@cloudflare/containers'; |
| import { | ||
| HttpClient, | ||
| createClient, | ||
| quickDeleteFile, | ||
| quickDeleteFileStream, | ||
| quickExecute, | ||
| quickExecuteStream, | ||
| quickGitCheckout, | ||
| quickGitCheckoutStream, | ||
| quickMkdir, | ||
| quickMkdirStream, | ||
| quickMoveFile, | ||
| quickMoveFileStream, | ||
| quickRenameFile, | ||
| quickRenameFileStream, | ||
| quickWriteFile, | ||
| quickWriteFileStream | ||
| } from "./chunk-GYEDSCAB.js"; | ||
| export { | ||
| HttpClient, | ||
| createClient, | ||
| quickDeleteFile, | ||
| quickDeleteFileStream, | ||
| quickExecute, | ||
| quickExecuteStream, | ||
| quickGitCheckout, | ||
| quickGitCheckoutStream, | ||
| quickMkdir, | ||
| quickMkdirStream, | ||
| quickMoveFile, | ||
| quickMoveFileStream, | ||
| quickRenameFile, | ||
| quickRenameFileStream, | ||
| quickWriteFile, | ||
| quickWriteFileStream | ||
| }; | ||
| //# sourceMappingURL=client.js.map |
| {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]} |
+170
| import { Container } from '@cloudflare/containers'; | ||
| declare function getSandbox(ns: DurableObjectNamespace<Sandbox>, id: string): DurableObjectStub<Sandbox<unknown>>; | ||
| declare class Sandbox<Env = unknown> extends Container<Env> { | ||
| defaultPort: number; | ||
| sleepAfter: string; | ||
| client: HttpClient; | ||
| envVars: { | ||
| MESSAGE: string; | ||
| }; | ||
| onStart(): void; | ||
| onStop(): void; | ||
| onError(error: unknown): void; | ||
| exec(command: string, args: string[], options?: { | ||
| stream?: boolean; | ||
| }): Promise<void | ExecuteResponse>; | ||
| gitCheckout(repoUrl: string, options: { | ||
| branch?: string; | ||
| targetDir?: string; | ||
| stream?: boolean; | ||
| }): Promise<void | GitCheckoutResponse>; | ||
| mkdir(path: string, options: { | ||
| recursive?: boolean; | ||
| stream?: boolean; | ||
| }): Promise<void | MkdirResponse>; | ||
| } | ||
| interface ExecuteResponse { | ||
| success: boolean; | ||
| stdout: string; | ||
| stderr: string; | ||
| exitCode: number; | ||
| command: string; | ||
| args: string[]; | ||
| timestamp: string; | ||
| } | ||
| interface SessionListResponse { | ||
| sessions: Array<{ | ||
| sessionId: string; | ||
| hasActiveProcess: boolean; | ||
| createdAt: string; | ||
| }>; | ||
| count: number; | ||
| timestamp: string; | ||
| } | ||
| interface GitCheckoutResponse { | ||
| success: boolean; | ||
| stdout: string; | ||
| stderr: string; | ||
| exitCode: number; | ||
| repoUrl: string; | ||
| branch: string; | ||
| targetDir: string; | ||
| timestamp: string; | ||
| } | ||
| interface MkdirResponse { | ||
| success: boolean; | ||
| stdout: string; | ||
| stderr: string; | ||
| exitCode: number; | ||
| path: string; | ||
| recursive: boolean; | ||
| timestamp: string; | ||
| } | ||
| interface WriteFileResponse { | ||
| success: boolean; | ||
| exitCode: number; | ||
| path: string; | ||
| timestamp: string; | ||
| } | ||
| interface DeleteFileResponse { | ||
| success: boolean; | ||
| exitCode: number; | ||
| path: string; | ||
| timestamp: string; | ||
| } | ||
| interface RenameFileResponse { | ||
| success: boolean; | ||
| exitCode: number; | ||
| oldPath: string; | ||
| newPath: string; | ||
| timestamp: string; | ||
| } | ||
| interface MoveFileResponse { | ||
| success: boolean; | ||
| exitCode: number; | ||
| sourcePath: string; | ||
| destinationPath: string; | ||
| timestamp: string; | ||
| } | ||
| interface StreamEvent { | ||
| type: "command_start" | "output" | "command_complete" | "error"; | ||
| command?: string; | ||
| args?: string[]; | ||
| stream?: "stdout" | "stderr"; | ||
| data?: string; | ||
| message?: string; | ||
| path?: string; | ||
| oldPath?: string; | ||
| newPath?: string; | ||
| sourcePath?: string; | ||
| destinationPath?: string; | ||
| success?: boolean; | ||
| exitCode?: number; | ||
| stdout?: string; | ||
| stderr?: string; | ||
| error?: string; | ||
| timestamp?: string; | ||
| } | ||
| interface HttpClientOptions { | ||
| stub?: Sandbox; | ||
| baseUrl?: string; | ||
| port?: number; | ||
| onCommandStart?: (command: string, args: string[]) => void; | ||
| onOutput?: (stream: "stdout" | "stderr", data: string, command: string) => void; | ||
| onCommandComplete?: (success: boolean, exitCode: number, stdout: string, stderr: string, command: string, args: string[]) => void; | ||
| onError?: (error: string, command?: string, args?: string[]) => void; | ||
| onStreamEvent?: (event: StreamEvent) => void; | ||
| } | ||
| declare class HttpClient { | ||
| private baseUrl; | ||
| private options; | ||
| private sessionId; | ||
| constructor(options?: HttpClientOptions); | ||
| private doFetch; | ||
| setOnOutput(handler: (stream: "stdout" | "stderr", data: string, command: string) => void): void; | ||
| setOnCommandComplete(handler: (success: boolean, exitCode: number, stdout: string, stderr: string, command: string, args: string[]) => void): void; | ||
| setOnStreamEvent(handler: (event: StreamEvent) => void): void; | ||
| getOnOutput(): ((stream: "stdout" | "stderr", data: string, command: string) => void) | undefined; | ||
| getOnCommandComplete(): ((success: boolean, exitCode: number, stdout: string, stderr: string, command: string, args: string[]) => void) | undefined; | ||
| getOnStreamEvent(): ((event: StreamEvent) => void) | undefined; | ||
| createSession(): Promise<string>; | ||
| listSessions(): Promise<SessionListResponse>; | ||
| execute(command: string, args?: string[], sessionId?: string): Promise<ExecuteResponse>; | ||
| executeStream(command: string, args?: string[], sessionId?: string): Promise<void>; | ||
| gitCheckout(repoUrl: string, branch?: string, targetDir?: string, sessionId?: string): Promise<GitCheckoutResponse>; | ||
| gitCheckoutStream(repoUrl: string, branch?: string, targetDir?: string, sessionId?: string): Promise<void>; | ||
| mkdir(path: string, recursive?: boolean, sessionId?: string): Promise<MkdirResponse>; | ||
| mkdirStream(path: string, recursive?: boolean, sessionId?: string): Promise<void>; | ||
| writeFile(path: string, content: string, encoding?: string, sessionId?: string): Promise<WriteFileResponse>; | ||
| writeFileStream(path: string, content: string, encoding?: string, sessionId?: string): Promise<void>; | ||
| deleteFile(path: string, sessionId?: string): Promise<DeleteFileResponse>; | ||
| deleteFileStream(path: string, sessionId?: string): Promise<void>; | ||
| renameFile(oldPath: string, newPath: string, sessionId?: string): Promise<RenameFileResponse>; | ||
| renameFileStream(oldPath: string, newPath: string, sessionId?: string): Promise<void>; | ||
| moveFile(sourcePath: string, destinationPath: string, sessionId?: string): Promise<MoveFileResponse>; | ||
| moveFileStream(sourcePath: string, destinationPath: string, sessionId?: string): Promise<void>; | ||
| ping(): Promise<string>; | ||
| getCommands(): Promise<string[]>; | ||
| getSessionId(): string | null; | ||
| setSessionId(sessionId: string): void; | ||
| clearSession(): void; | ||
| } | ||
| declare function createClient(options?: HttpClientOptions): HttpClient; | ||
| declare function quickExecute(command: string, args?: string[], options?: HttpClientOptions): Promise<ExecuteResponse>; | ||
| declare function quickExecuteStream(command: string, args?: string[], options?: HttpClientOptions): Promise<void>; | ||
| declare function quickGitCheckout(repoUrl: string, branch?: string, targetDir?: string, options?: HttpClientOptions): Promise<GitCheckoutResponse>; | ||
| declare function quickMkdir(path: string, recursive?: boolean, options?: HttpClientOptions): Promise<MkdirResponse>; | ||
| declare function quickGitCheckoutStream(repoUrl: string, branch?: string, targetDir?: string, options?: HttpClientOptions): Promise<void>; | ||
| declare function quickMkdirStream(path: string, recursive?: boolean, options?: HttpClientOptions): Promise<void>; | ||
| declare function quickWriteFile(path: string, content: string, encoding?: string, options?: HttpClientOptions): Promise<WriteFileResponse>; | ||
| declare function quickWriteFileStream(path: string, content: string, encoding?: string, options?: HttpClientOptions): Promise<void>; | ||
| declare function quickDeleteFile(path: string, options?: HttpClientOptions): Promise<DeleteFileResponse>; | ||
| declare function quickDeleteFileStream(path: string, options?: HttpClientOptions): Promise<void>; | ||
| declare function quickRenameFile(oldPath: string, newPath: string, options?: HttpClientOptions): Promise<RenameFileResponse>; | ||
| declare function quickRenameFileStream(oldPath: string, newPath: string, options?: HttpClientOptions): Promise<void>; | ||
| declare function quickMoveFile(sourcePath: string, destinationPath: string, options?: HttpClientOptions): Promise<MoveFileResponse>; | ||
| declare function quickMoveFileStream(sourcePath: string, destinationPath: string, options?: HttpClientOptions): Promise<void>; | ||
| export { type DeleteFileResponse as D, type ExecuteResponse as E, type GitCheckoutResponse as G, HttpClient as H, type MkdirResponse as M, type RenameFileResponse as R, Sandbox, type WriteFileResponse as W, type MoveFileResponse as a, quickExecuteStream as b, createClient as c, quickGitCheckout as d, quickMkdir as e, quickGitCheckoutStream as f, quickMkdirStream as g, getSandbox, quickWriteFile as h, quickWriteFileStream as i, quickDeleteFile as j, quickDeleteFileStream as k, quickRenameFile as l, quickRenameFileStream as m, quickMoveFile as n, quickMoveFileStream as o, quickExecute as q }; |
| import { | ||
| HttpClient | ||
| } from "./chunk-GYEDSCAB.js"; | ||
| // src/index.ts | ||
| import { Container, getContainer } from "@cloudflare/containers"; | ||
| function getSandbox(ns, id) { | ||
| return getContainer(ns, id); | ||
| } | ||
| var Sandbox = class extends Container { | ||
| defaultPort = 3e3; | ||
| // The default port for the container to listen on | ||
| sleepAfter = "3m"; | ||
| // Sleep the sandbox if no requests are made in this timeframe | ||
| client = new HttpClient({ | ||
| onCommandComplete: (success, exitCode, stdout, stderr, command, args) => { | ||
| console.log( | ||
| `[Container] Command completed: ${command}, Success: ${success}, Exit code: ${exitCode}` | ||
| ); | ||
| }, | ||
| onCommandStart: (command, args) => { | ||
| console.log(`[Container] Command started: ${command} ${args.join(" ")}`); | ||
| }, | ||
| onError: (error, command, args) => { | ||
| console.error(`[Container] Command error: ${error}`); | ||
| }, | ||
| onOutput: (stream, data, command) => { | ||
| console.log(`[Container] [${stream}] ${data}`); | ||
| }, | ||
| port: this.defaultPort | ||
| }); | ||
| envVars = { | ||
| MESSAGE: "I was passed in via the Sandbox class!" | ||
| }; | ||
| onStart() { | ||
| console.log("Sandbox successfully started"); | ||
| } | ||
| onStop() { | ||
| console.log("Sandbox successfully shut down"); | ||
| if (this.client) { | ||
| this.client.clearSession(); | ||
| } | ||
| } | ||
| onError(error) { | ||
| console.log("Sandbox error:", error); | ||
| } | ||
| async exec(command, args, options) { | ||
| if (options?.stream) { | ||
| return this.client.executeStream(command, args); | ||
| } | ||
| return this.client.execute(command, args); | ||
| } | ||
| async gitCheckout(repoUrl, options) { | ||
| if (options?.stream) { | ||
| return this.client.gitCheckoutStream( | ||
| repoUrl, | ||
| options.branch, | ||
| options.targetDir | ||
| ); | ||
| } | ||
| return this.client.gitCheckout(repoUrl, options.branch, options.targetDir); | ||
| } | ||
| async mkdir(path, options) { | ||
| if (options?.stream) { | ||
| return this.client.mkdirStream(path, options.recursive); | ||
| } | ||
| return this.client.mkdir(path, options.recursive); | ||
| } | ||
| }; | ||
| export { | ||
| Sandbox, | ||
| getSandbox | ||
| }; | ||
| //# sourceMappingURL=index.js.map |
| {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Container, getContainer } from \"@cloudflare/containers\";\nimport { HttpClient } from \"./client\";\n\nexport function getSandbox(ns: DurableObjectNamespace<Sandbox>, id: string) {\n return getContainer(ns, id);\n}\n\nexport class Sandbox<Env = unknown> extends Container<Env> {\n defaultPort = 3000; // The default port for the container to listen on\n sleepAfter = \"3m\"; // Sleep the sandbox if no requests are made in this timeframe\n\n client: HttpClient = new HttpClient({\n onCommandComplete: (success, exitCode, stdout, stderr, command, args) => {\n console.log(\n `[Container] Command completed: ${command}, Success: ${success}, Exit code: ${exitCode}`\n );\n },\n onCommandStart: (command, args) => {\n console.log(`[Container] Command started: ${command} ${args.join(\" \")}`);\n },\n onError: (error, command, args) => {\n console.error(`[Container] Command error: ${error}`);\n },\n onOutput: (stream, data, command) => {\n console.log(`[Container] [${stream}] ${data}`);\n },\n port: this.defaultPort,\n });\n\n envVars = {\n MESSAGE: \"I was passed in via the Sandbox class!\",\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 async exec(command: string, args: string[], options?: { stream?: boolean }) {\n if (options?.stream) {\n return this.client.executeStream(command, args);\n }\n return this.client.execute(command, args);\n }\n\n async gitCheckout(\n repoUrl: string,\n options: { branch?: string; targetDir?: string; stream?: boolean }\n ) {\n if (options?.stream) {\n return this.client.gitCheckoutStream(\n repoUrl,\n options.branch,\n options.targetDir\n );\n }\n return this.client.gitCheckout(repoUrl, options.branch, options.targetDir);\n }\n\n async mkdir(\n path: string,\n options: { recursive?: boolean; stream?: boolean }\n ) {\n if (options?.stream) {\n return this.client.mkdirStream(path, options.recursive);\n }\n return this.client.mkdir(path, options.recursive);\n }\n}\n"],"mappings":";;;;;AAAA,SAAS,WAAW,oBAAoB;AAGjC,SAAS,WAAW,IAAqC,IAAY;AAC1E,SAAO,aAAa,IAAI,EAAE;AAC5B;AAEO,IAAM,UAAN,cAAqC,UAAe;AAAA,EACzD,cAAc;AAAA;AAAA,EACd,aAAa;AAAA;AAAA,EAEb,SAAqB,IAAI,WAAW;AAAA,IAClC,mBAAmB,CAAC,SAAS,UAAU,QAAQ,QAAQ,SAAS,SAAS;AACvE,cAAQ;AAAA,QACN,kCAAkC,OAAO,cAAc,OAAO,gBAAgB,QAAQ;AAAA,MACxF;AAAA,IACF;AAAA,IACA,gBAAgB,CAAC,SAAS,SAAS;AACjC,cAAQ,IAAI,gCAAgC,OAAO,IAAI,KAAK,KAAK,GAAG,CAAC,EAAE;AAAA,IACzE;AAAA,IACA,SAAS,CAAC,OAAO,SAAS,SAAS;AACjC,cAAQ,MAAM,8BAA8B,KAAK,EAAE;AAAA,IACrD;AAAA,IACA,UAAU,CAAC,QAAQ,MAAM,YAAY;AACnC,cAAQ,IAAI,gBAAgB,MAAM,KAAK,IAAI,EAAE;AAAA,IAC/C;AAAA,IACA,MAAM,KAAK;AAAA,EACb,CAAC;AAAA,EAED,UAAU;AAAA,IACR,SAAS;AAAA,EACX;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,EAEA,MAAM,KAAK,SAAiB,MAAgB,SAAgC;AAC1E,QAAI,SAAS,QAAQ;AACnB,aAAO,KAAK,OAAO,cAAc,SAAS,IAAI;AAAA,IAChD;AACA,WAAO,KAAK,OAAO,QAAQ,SAAS,IAAI;AAAA,EAC1C;AAAA,EAEA,MAAM,YACJ,SACA,SACA;AACA,QAAI,SAAS,QAAQ;AACnB,aAAO,KAAK,OAAO;AAAA,QACjB;AAAA,QACA,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,IACF;AACA,WAAO,KAAK,OAAO,YAAY,SAAS,QAAQ,QAAQ,QAAQ,SAAS;AAAA,EAC3E;AAAA,EAEA,MAAM,MACJ,MACA,SACA;AACA,QAAI,SAAS,QAAQ;AACnB,aAAO,KAAK,OAAO,YAAY,MAAM,QAAQ,SAAS;AAAA,IACxD;AACA,WAAO,KAAK,OAAO,MAAM,MAAM,QAAQ,SAAS;AAAA,EAClD;AACF;","names":[]} |
+1
-1
| { | ||
| "name": "@cloudflare/sandbox", | ||
| "version": "0.0.0-1c0902c", | ||
| "version": "0.0.0", | ||
| "description": "A sandboxed environment for running commands", | ||
@@ -5,0 +5,0 @@ "dependencies": { |
AI-detected potential malware
Supply chain riskAI has identified this package as malware. This is a strong signal that the package may be malicious.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
AI-detected potential malware
Supply chain riskAI has identified this package as malware. This is a strong signal that the package may be malicious.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
289408
75.22%21
61.54%6711
28.17%5
66.67%