@cloudflare/sandbox 0.0.8 → 0.0.9
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 +6 -0
- package/Dockerfile +86 -9
- package/container_src/index.ts +428 -82
- package/dist/{chunk-7WZJ3TRE.js → chunk-4J5LQCCN.js} +85 -3
- package/dist/chunk-4J5LQCCN.js.map +1 -0
- package/dist/chunk-5SZ3RVJZ.js +250 -0
- package/dist/chunk-5SZ3RVJZ.js.map +1 -0
- package/dist/client-BuVjqV00.d.ts +247 -0
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/index.d.ts +3 -200
- package/dist/index.js +7 -106
- package/dist/index.js.map +1 -1
- package/dist/request-handler.d.ts +15 -0
- package/dist/request-handler.js +10 -0
- package/dist/request-handler.js.map +1 -0
- package/dist/sandbox.d.ts +2 -0
- package/dist/sandbox.js +10 -0
- package/dist/sandbox.js.map +1 -0
- package/package.json +2 -2
- package/src/client.ts +163 -34
- package/src/index.ts +14 -136
- package/src/request-handler.ts +95 -0
- package/src/sandbox.ts +252 -0
- package/dist/chunk-7WZJ3TRE.js.map +0 -1
|
@@ -97,13 +97,14 @@ var HttpClient = class {
|
|
|
97
97
|
throw error;
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
|
-
async execute(command, args = [], sessionId) {
|
|
100
|
+
async execute(command, args = [], sessionId, background = false) {
|
|
101
101
|
try {
|
|
102
102
|
const targetSessionId = sessionId || this.sessionId;
|
|
103
103
|
const response = await this.doFetch(`/api/execute`, {
|
|
104
104
|
body: JSON.stringify({
|
|
105
105
|
args,
|
|
106
106
|
command,
|
|
107
|
+
background,
|
|
107
108
|
sessionId: targetSessionId
|
|
108
109
|
}),
|
|
109
110
|
headers: {
|
|
@@ -140,13 +141,14 @@ var HttpClient = class {
|
|
|
140
141
|
throw error;
|
|
141
142
|
}
|
|
142
143
|
}
|
|
143
|
-
async executeStream(command, args = [], sessionId) {
|
|
144
|
+
async executeStream(command, args = [], sessionId, background = false) {
|
|
144
145
|
try {
|
|
145
146
|
const targetSessionId = sessionId || this.sessionId;
|
|
146
147
|
const response = await this.doFetch(`/api/execute/stream`, {
|
|
147
148
|
body: JSON.stringify({
|
|
148
149
|
args,
|
|
149
150
|
command,
|
|
151
|
+
background,
|
|
150
152
|
sessionId: targetSessionId
|
|
151
153
|
}),
|
|
152
154
|
headers: {
|
|
@@ -1143,6 +1145,86 @@ var HttpClient = class {
|
|
|
1143
1145
|
throw error;
|
|
1144
1146
|
}
|
|
1145
1147
|
}
|
|
1148
|
+
async exposePort(port, name) {
|
|
1149
|
+
try {
|
|
1150
|
+
const response = await this.doFetch(`/api/expose-port`, {
|
|
1151
|
+
body: JSON.stringify({
|
|
1152
|
+
port,
|
|
1153
|
+
name
|
|
1154
|
+
}),
|
|
1155
|
+
headers: {
|
|
1156
|
+
"Content-Type": "application/json"
|
|
1157
|
+
},
|
|
1158
|
+
method: "POST"
|
|
1159
|
+
});
|
|
1160
|
+
if (!response.ok) {
|
|
1161
|
+
const errorData = await response.json().catch(() => ({}));
|
|
1162
|
+
console.log(errorData);
|
|
1163
|
+
throw new Error(
|
|
1164
|
+
errorData.error || `HTTP error! status: ${response.status}`
|
|
1165
|
+
);
|
|
1166
|
+
}
|
|
1167
|
+
const data = await response.json();
|
|
1168
|
+
console.log(
|
|
1169
|
+
`[HTTP Client] Port exposed: ${port}${name ? ` (${name})` : ""}, Success: ${data.success}`
|
|
1170
|
+
);
|
|
1171
|
+
return data;
|
|
1172
|
+
} catch (error) {
|
|
1173
|
+
console.error("[HTTP Client] Error exposing port:", error);
|
|
1174
|
+
throw error;
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
async unexposePort(port) {
|
|
1178
|
+
try {
|
|
1179
|
+
const response = await this.doFetch(`/api/unexpose-port`, {
|
|
1180
|
+
body: JSON.stringify({
|
|
1181
|
+
port
|
|
1182
|
+
}),
|
|
1183
|
+
headers: {
|
|
1184
|
+
"Content-Type": "application/json"
|
|
1185
|
+
},
|
|
1186
|
+
method: "DELETE"
|
|
1187
|
+
});
|
|
1188
|
+
if (!response.ok) {
|
|
1189
|
+
const errorData = await response.json().catch(() => ({}));
|
|
1190
|
+
throw new Error(
|
|
1191
|
+
errorData.error || `HTTP error! status: ${response.status}`
|
|
1192
|
+
);
|
|
1193
|
+
}
|
|
1194
|
+
const data = await response.json();
|
|
1195
|
+
console.log(
|
|
1196
|
+
`[HTTP Client] Port unexposed: ${port}, Success: ${data.success}`
|
|
1197
|
+
);
|
|
1198
|
+
return data;
|
|
1199
|
+
} catch (error) {
|
|
1200
|
+
console.error("[HTTP Client] Error unexposing port:", error);
|
|
1201
|
+
throw error;
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
async getExposedPorts() {
|
|
1205
|
+
try {
|
|
1206
|
+
const response = await this.doFetch(`/api/exposed-ports`, {
|
|
1207
|
+
headers: {
|
|
1208
|
+
"Content-Type": "application/json"
|
|
1209
|
+
},
|
|
1210
|
+
method: "GET"
|
|
1211
|
+
});
|
|
1212
|
+
if (!response.ok) {
|
|
1213
|
+
const errorData = await response.json().catch(() => ({}));
|
|
1214
|
+
throw new Error(
|
|
1215
|
+
errorData.error || `HTTP error! status: ${response.status}`
|
|
1216
|
+
);
|
|
1217
|
+
}
|
|
1218
|
+
const data = await response.json();
|
|
1219
|
+
console.log(
|
|
1220
|
+
`[HTTP Client] Got ${data.count} exposed ports`
|
|
1221
|
+
);
|
|
1222
|
+
return data;
|
|
1223
|
+
} catch (error) {
|
|
1224
|
+
console.error("[HTTP Client] Error getting exposed ports:", error);
|
|
1225
|
+
throw error;
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1146
1228
|
async ping() {
|
|
1147
1229
|
try {
|
|
1148
1230
|
const response = await this.doFetch(`/api/ping`, {
|
|
@@ -1361,4 +1443,4 @@ export {
|
|
|
1361
1443
|
quickMoveFile,
|
|
1362
1444
|
quickMoveFileStream
|
|
1363
1445
|
};
|
|
1364
|
-
//# sourceMappingURL=chunk-
|
|
1446
|
+
//# sourceMappingURL=chunk-4J5LQCCN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"sourcesContent":["import type { Sandbox } from \"./index\";\n\ninterface ExecuteRequest {\n command: string;\n args?: string[];\n sessionId?: string;\n background?: boolean;\n}\n\nexport interface ExecuteResponse {\n success: boolean;\n stdout: string;\n stderr: string;\n exitCode: number;\n command: string;\n args: string[];\n timestamp: string;\n}\n\ninterface SessionResponse {\n sessionId: string;\n message: string;\n timestamp: string;\n}\n\ninterface SessionListResponse {\n sessions: Array<{\n sessionId: string;\n hasActiveProcess: boolean;\n createdAt: string;\n }>;\n count: number;\n timestamp: string;\n}\n\ninterface CommandsResponse {\n availableCommands: string[];\n timestamp: string;\n}\n\ninterface GitCheckoutRequest {\n repoUrl: string;\n branch?: string;\n targetDir?: string;\n sessionId?: string;\n}\n\nexport interface GitCheckoutResponse {\n success: boolean;\n stdout: string;\n stderr: string;\n exitCode: number;\n repoUrl: string;\n branch: string;\n targetDir: string;\n timestamp: string;\n}\n\ninterface MkdirRequest {\n path: string;\n recursive?: boolean;\n sessionId?: string;\n}\n\nexport interface MkdirResponse {\n success: boolean;\n stdout: string;\n stderr: string;\n exitCode: number;\n path: string;\n recursive: boolean;\n timestamp: string;\n}\n\ninterface WriteFileRequest {\n path: string;\n content: string;\n encoding?: string;\n sessionId?: string;\n}\n\nexport interface WriteFileResponse {\n success: boolean;\n exitCode: number;\n path: string;\n timestamp: string;\n}\n\ninterface ReadFileRequest {\n path: string;\n encoding?: string;\n sessionId?: string;\n}\n\nexport interface ReadFileResponse {\n success: boolean;\n exitCode: number;\n path: string;\n content: string;\n timestamp: string;\n}\n\ninterface DeleteFileRequest {\n path: string;\n sessionId?: string;\n}\n\nexport interface DeleteFileResponse {\n success: boolean;\n exitCode: number;\n path: string;\n timestamp: string;\n}\n\ninterface RenameFileRequest {\n oldPath: string;\n newPath: string;\n sessionId?: string;\n}\n\nexport interface RenameFileResponse {\n success: boolean;\n exitCode: number;\n oldPath: string;\n newPath: string;\n timestamp: string;\n}\n\ninterface MoveFileRequest {\n sourcePath: string;\n destinationPath: string;\n sessionId?: string;\n}\n\nexport interface MoveFileResponse {\n success: boolean;\n exitCode: number;\n sourcePath: string;\n destinationPath: string;\n timestamp: string;\n}\n\ninterface PreviewInfo {\n url: string;\n port: number;\n name?: string;\n}\n\ninterface ExposedPort extends PreviewInfo {\n exposedAt: string;\n timestamp: string;\n}\n\ninterface ExposePortResponse {\n success: boolean;\n port: number;\n name?: string;\n exposedAt: string;\n timestamp: string;\n}\n\ninterface UnexposePortResponse {\n success: boolean;\n port: number;\n timestamp: string;\n}\n\ninterface GetExposedPortsResponse {\n ports: ExposedPort[];\n count: number;\n timestamp: string;\n}\n\ninterface PingResponse {\n message: string;\n timestamp: string;\n}\n\ninterface StreamEvent {\n type: \"command_start\" | \"output\" | \"command_complete\" | \"error\";\n command?: string;\n args?: string[];\n stream?: \"stdout\" | \"stderr\";\n data?: string;\n message?: string;\n path?: string;\n oldPath?: string;\n newPath?: string;\n sourcePath?: string;\n destinationPath?: string;\n content?: string;\n success?: boolean;\n exitCode?: number;\n stdout?: string;\n stderr?: string;\n error?: string;\n timestamp?: string;\n}\n\ninterface HttpClientOptions {\n stub?: Sandbox;\n baseUrl?: string;\n port?: number;\n onCommandStart?: (command: string, args: string[]) => void;\n onOutput?: (\n stream: \"stdout\" | \"stderr\",\n data: string,\n command: string\n ) => void;\n onCommandComplete?: (\n success: boolean,\n exitCode: number,\n stdout: string,\n stderr: string,\n command: string,\n args: string[]\n ) => void;\n onError?: (error: string, command?: string, args?: string[]) => void;\n onStreamEvent?: (event: StreamEvent) => void;\n}\n\nexport class HttpClient {\n private baseUrl: string;\n private options: HttpClientOptions;\n private sessionId: string | null = null;\n\n constructor(options: HttpClientOptions = {}) {\n this.options = {\n ...options,\n };\n this.baseUrl = this.options.baseUrl!;\n }\n\n private async doFetch(\n path: string,\n options?: RequestInit\n ): Promise<Response> {\n const url = this.options.stub\n ? `http://localhost:${this.options.port}${path}`\n : `${this.baseUrl}${path}`;\n const method = options?.method || \"GET\";\n\n console.log(`[HTTP Client] Making ${method} request to ${url}`);\n\n try {\n let response: Response;\n\n if (this.options.stub) {\n response = await this.options.stub.containerFetch(\n url,\n options,\n this.options.port\n );\n } else {\n response = await fetch(url, options);\n }\n\n console.log(\n `[HTTP Client] Response: ${response.status} ${response.statusText}`\n );\n\n if (!response.ok) {\n console.error(\n `[HTTP Client] Request failed: ${method} ${url} - ${response.status} ${response.statusText}`\n );\n }\n\n return response;\n } catch (error) {\n console.error(`[HTTP Client] Request error: ${method} ${url}`, error);\n throw error;\n }\n }\n // Public methods to set event handlers\n setOnOutput(\n handler: (\n stream: \"stdout\" | \"stderr\",\n data: string,\n command: string\n ) => void\n ): void {\n this.options.onOutput = handler;\n }\n\n setOnCommandComplete(\n handler: (\n success: boolean,\n exitCode: number,\n stdout: string,\n stderr: string,\n command: string,\n args: string[]\n ) => void\n ): void {\n this.options.onCommandComplete = handler;\n }\n\n setOnStreamEvent(handler: (event: StreamEvent) => void): void {\n this.options.onStreamEvent = handler;\n }\n\n // Public getter methods\n getOnOutput():\n | ((stream: \"stdout\" | \"stderr\", data: string, command: string) => void)\n | undefined {\n return this.options.onOutput;\n }\n\n getOnCommandComplete():\n | ((\n success: boolean,\n exitCode: number,\n stdout: string,\n stderr: string,\n command: string,\n args: string[]\n ) => void)\n | undefined {\n return this.options.onCommandComplete;\n }\n\n getOnStreamEvent(): ((event: StreamEvent) => void) | undefined {\n return this.options.onStreamEvent;\n }\n\n async createSession(): Promise<string> {\n try {\n const response = await this.doFetch(`/api/session/create`, {\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const data: SessionResponse = await response.json();\n this.sessionId = data.sessionId;\n console.log(`[HTTP Client] Created session: ${this.sessionId}`);\n return this.sessionId;\n } catch (error) {\n console.error(\"[HTTP Client] Error creating session:\", error);\n throw error;\n }\n }\n\n async listSessions(): Promise<SessionListResponse> {\n try {\n const response = await this.doFetch(`/api/session/list`, {\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"GET\",\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const data: SessionListResponse = await response.json();\n console.log(`[HTTP Client] Listed ${data.count} sessions`);\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error listing sessions:\", error);\n throw error;\n }\n }\n\n async execute(\n command: string,\n args: string[] = [],\n sessionId?: string,\n background: boolean = false,\n ): Promise<ExecuteResponse> {\n try {\n const targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/execute`, {\n body: JSON.stringify({\n args,\n command,\n background,\n sessionId: targetSessionId,\n } as ExecuteRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: ExecuteResponse = await response.json();\n console.log(\n `[HTTP Client] Command executed: ${command}, Success: ${data.success}`\n );\n\n // Call the callback if provided\n this.options.onCommandComplete?.(\n data.success,\n data.exitCode,\n data.stdout,\n data.stderr,\n data.command,\n data.args\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error executing command:\", error);\n this.options.onError?.(\n error instanceof Error ? error.message : \"Unknown error\",\n command,\n args\n );\n throw error;\n }\n }\n\n async executeStream(\n command: string,\n args: string[] = [],\n sessionId?: string,\n background: boolean = false\n ): Promise<void> {\n try {\n const targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/execute/stream`, {\n body: JSON.stringify({\n args,\n command,\n background,\n sessionId: targetSessionId,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n if (!response.body) {\n throw new Error(\"No response body for streaming request\");\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n const chunk = decoder.decode(value, { stream: true });\n const lines = chunk.split(\"\\n\");\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n try {\n const eventData = line.slice(6); // Remove 'data: ' prefix\n const event: StreamEvent = JSON.parse(eventData);\n\n console.log(`[HTTP Client] Stream event: ${event.type}`);\n this.options.onStreamEvent?.(event);\n\n switch (event.type) {\n case \"command_start\":\n console.log(\n `[HTTP Client] Command started: ${event.command\n } ${event.args?.join(\" \")}`\n );\n this.options.onCommandStart?.(\n event.command!,\n event.args || []\n );\n break;\n\n case \"output\":\n console.log(`[${event.stream}] ${event.data}`);\n this.options.onOutput?.(\n event.stream!,\n event.data!,\n event.command!\n );\n break;\n\n case \"command_complete\":\n console.log(\n `[HTTP Client] Command completed: ${event.command}, Success: ${event.success}, Exit code: ${event.exitCode}`\n );\n this.options.onCommandComplete?.(\n event.success!,\n event.exitCode!,\n event.stdout!,\n event.stderr!,\n event.command!,\n event.args || []\n );\n break;\n\n case \"error\":\n console.error(\n `[HTTP Client] Command error: ${event.error}`\n );\n this.options.onError?.(\n event.error!,\n event.command,\n event.args\n );\n break;\n }\n } catch (parseError) {\n console.warn(\n \"[HTTP Client] Failed to parse stream event:\",\n parseError\n );\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n } catch (error) {\n console.error(\"[HTTP Client] Error in streaming execution:\", error);\n this.options.onError?.(\n error instanceof Error ? error.message : \"Unknown error\",\n command,\n args\n );\n throw error;\n }\n }\n\n async gitCheckout(\n repoUrl: string,\n branch: string = \"main\",\n targetDir?: string,\n sessionId?: string\n ): Promise<GitCheckoutResponse> {\n try {\n const targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/git/checkout`, {\n body: JSON.stringify({\n branch,\n repoUrl,\n sessionId: targetSessionId,\n targetDir,\n } as GitCheckoutRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: GitCheckoutResponse = await response.json();\n console.log(\n `[HTTP Client] Git checkout completed: ${repoUrl}, Success: ${data.success}, Target: ${data.targetDir}`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error in git checkout:\", error);\n throw error;\n }\n }\n\n async gitCheckoutStream(\n repoUrl: string,\n branch: string = \"main\",\n targetDir?: string,\n sessionId?: string\n ): Promise<void> {\n try {\n const targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/git/checkout/stream`, {\n body: JSON.stringify({\n branch,\n repoUrl,\n sessionId: targetSessionId,\n targetDir,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n if (!response.body) {\n throw new Error(\"No response body for streaming request\");\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n const chunk = decoder.decode(value, { stream: true });\n const lines = chunk.split(\"\\n\");\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n try {\n const eventData = line.slice(6); // Remove 'data: ' prefix\n const event: StreamEvent = JSON.parse(eventData);\n\n console.log(\n `[HTTP Client] Git checkout stream event: ${event.type}`\n );\n this.options.onStreamEvent?.(event);\n\n switch (event.type) {\n case \"command_start\":\n console.log(\n `[HTTP Client] Git checkout started: ${event.command\n } ${event.args?.join(\" \")}`\n );\n this.options.onCommandStart?.(\n event.command!,\n event.args || []\n );\n break;\n\n case \"output\":\n console.log(`[${event.stream}] ${event.data}`);\n this.options.onOutput?.(\n event.stream!,\n event.data!,\n event.command!\n );\n break;\n\n case \"command_complete\":\n console.log(\n `[HTTP Client] Git checkout completed: ${event.command}, Success: ${event.success}, Exit code: ${event.exitCode}`\n );\n this.options.onCommandComplete?.(\n event.success!,\n event.exitCode!,\n event.stdout!,\n event.stderr!,\n event.command!,\n event.args || []\n );\n break;\n\n case \"error\":\n console.error(\n `[HTTP Client] Git checkout error: ${event.error}`\n );\n this.options.onError?.(\n event.error!,\n event.command,\n event.args\n );\n break;\n }\n } catch (parseError) {\n console.warn(\n \"[HTTP Client] Failed to parse git checkout stream event:\",\n parseError\n );\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n } catch (error) {\n console.error(\"[HTTP Client] Error in streaming git checkout:\", error);\n this.options.onError?.(\n error instanceof Error ? error.message : \"Unknown error\",\n \"git clone\",\n [branch, repoUrl, targetDir || \"\"]\n );\n throw error;\n }\n }\n\n async mkdir(\n path: string,\n recursive: boolean = false,\n sessionId?: string\n ): Promise<MkdirResponse> {\n try {\n const targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/mkdir`, {\n body: JSON.stringify({\n path,\n recursive,\n sessionId: targetSessionId,\n } as MkdirRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: MkdirResponse = await response.json();\n console.log(\n `[HTTP Client] Directory created: ${path}, Success: ${data.success}, Recursive: ${data.recursive}`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error creating directory:\", error);\n throw error;\n }\n }\n\n async mkdirStream(\n path: string,\n recursive: boolean = false,\n sessionId?: string\n ): Promise<void> {\n try {\n const targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/mkdir/stream`, {\n body: JSON.stringify({\n path,\n recursive,\n sessionId: targetSessionId,\n } as MkdirRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n if (!response.body) {\n throw new Error(\"No response body for streaming request\");\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n const chunk = decoder.decode(value, { stream: true });\n const lines = chunk.split(\"\\n\");\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n try {\n const eventData = line.slice(6); // Remove 'data: ' prefix\n const event: StreamEvent = JSON.parse(eventData);\n\n console.log(`[HTTP Client] Mkdir stream event: ${event.type}`);\n this.options.onStreamEvent?.(event);\n\n switch (event.type) {\n case \"command_start\":\n console.log(\n `[HTTP Client] Mkdir started: ${event.command\n } ${event.args?.join(\" \")}`\n );\n this.options.onCommandStart?.(\n event.command!,\n event.args || []\n );\n break;\n\n case \"output\":\n console.log(`[${event.stream}] ${event.data}`);\n this.options.onOutput?.(\n event.stream!,\n event.data!,\n event.command!\n );\n break;\n\n case \"command_complete\":\n console.log(\n `[HTTP Client] Mkdir completed: ${event.command}, Success: ${event.success}, Exit code: ${event.exitCode}`\n );\n this.options.onCommandComplete?.(\n event.success!,\n event.exitCode!,\n event.stdout!,\n event.stderr!,\n event.command!,\n event.args || []\n );\n break;\n\n case \"error\":\n console.error(`[HTTP Client] Mkdir error: ${event.error}`);\n this.options.onError?.(\n event.error!,\n event.command,\n event.args\n );\n break;\n }\n } catch (parseError) {\n console.warn(\n \"[HTTP Client] Failed to parse mkdir stream event:\",\n parseError\n );\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n } catch (error) {\n console.error(\"[HTTP Client] Error in streaming mkdir:\", error);\n this.options.onError?.(\n error instanceof Error ? error.message : \"Unknown error\",\n \"mkdir\",\n recursive ? [\"-p\", path] : [path]\n );\n throw error;\n }\n }\n\n async writeFile(\n path: string,\n content: string,\n encoding: string = \"utf-8\",\n sessionId?: string\n ): Promise<WriteFileResponse> {\n try {\n const targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/write`, {\n body: JSON.stringify({\n content,\n encoding,\n path,\n sessionId: targetSessionId,\n } as WriteFileRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: WriteFileResponse = await response.json();\n console.log(\n `[HTTP Client] File written: ${path}, Success: ${data.success}`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error writing file:\", error);\n throw error;\n }\n }\n\n async writeFileStream(\n path: string,\n content: string,\n encoding: string = \"utf-8\",\n sessionId?: string\n ): Promise<void> {\n try {\n const targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/write/stream`, {\n body: JSON.stringify({\n content,\n encoding,\n path,\n sessionId: targetSessionId,\n } as WriteFileRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n if (!response.body) {\n throw new Error(\"No response body for streaming request\");\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n const chunk = decoder.decode(value, { stream: true });\n const lines = chunk.split(\"\\n\");\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n try {\n const eventData = line.slice(6); // Remove 'data: ' prefix\n const event: StreamEvent = JSON.parse(eventData);\n\n console.log(\n `[HTTP Client] Write file stream event: ${event.type}`\n );\n this.options.onStreamEvent?.(event);\n\n switch (event.type) {\n case \"command_start\":\n console.log(\n `[HTTP Client] Write file started: ${event.path}`\n );\n this.options.onCommandStart?.(\"write\", [\n path,\n content,\n encoding,\n ]);\n break;\n\n case \"output\":\n console.log(`[output] ${event.message}`);\n this.options.onOutput?.(\"stdout\", event.message!, \"write\");\n break;\n\n case \"command_complete\":\n console.log(\n `[HTTP Client] Write file completed: ${event.path}, Success: ${event.success}`\n );\n this.options.onCommandComplete?.(\n event.success!,\n 0,\n \"\",\n \"\",\n \"write\",\n [path, content, encoding]\n );\n break;\n\n case \"error\":\n console.error(\n `[HTTP Client] Write file error: ${event.error}`\n );\n this.options.onError?.(event.error!, \"write\", [\n path,\n content,\n encoding,\n ]);\n break;\n }\n } catch (parseError) {\n console.warn(\n \"[HTTP Client] Failed to parse write file stream event:\",\n parseError\n );\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n } catch (error) {\n console.error(\"[HTTP Client] Error in streaming write file:\", error);\n this.options.onError?.(\n error instanceof Error ? error.message : \"Unknown error\",\n \"write\",\n [path, content, encoding]\n );\n throw error;\n }\n }\n\n async readFile(\n path: string,\n encoding: string = \"utf-8\",\n sessionId?: string\n ): Promise<ReadFileResponse> {\n try {\n const targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/read`, {\n body: JSON.stringify({\n encoding,\n path,\n sessionId: targetSessionId,\n } as ReadFileRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: ReadFileResponse = await response.json();\n console.log(\n `[HTTP Client] File read: ${path}, Success: ${data.success}, Content length: ${data.content.length}`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error reading file:\", error);\n throw error;\n }\n }\n\n async readFileStream(\n path: string,\n encoding: string = \"utf-8\",\n sessionId?: string\n ): Promise<void> {\n try {\n const targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/read/stream`, {\n body: JSON.stringify({\n encoding,\n path,\n sessionId: targetSessionId,\n } as ReadFileRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n if (!response.body) {\n throw new Error(\"No response body for streaming request\");\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n const chunk = decoder.decode(value, { stream: true });\n const lines = chunk.split(\"\\n\");\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n try {\n const eventData = line.slice(6); // Remove 'data: ' prefix\n const event: StreamEvent = JSON.parse(eventData);\n\n console.log(\n `[HTTP Client] Read file stream event: ${event.type}`\n );\n this.options.onStreamEvent?.(event);\n\n switch (event.type) {\n case \"command_start\":\n console.log(\n `[HTTP Client] Read file started: ${event.path}`\n );\n this.options.onCommandStart?.(\"read\", [path, encoding]);\n break;\n\n case \"command_complete\":\n console.log(\n `[HTTP Client] Read file completed: ${event.path\n }, Success: ${event.success}, Content length: ${event.content?.length || 0\n }`\n );\n this.options.onCommandComplete?.(\n event.success!,\n 0,\n event.content || \"\",\n \"\",\n \"read\",\n [path, encoding]\n );\n break;\n\n case \"error\":\n console.error(\n `[HTTP Client] Read file error: ${event.error}`\n );\n this.options.onError?.(event.error!, \"read\", [\n path,\n encoding,\n ]);\n break;\n }\n } catch (parseError) {\n console.warn(\n \"[HTTP Client] Failed to parse read file stream event:\",\n parseError\n );\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n } catch (error) {\n console.error(\"[HTTP Client] Error in streaming read file:\", error);\n this.options.onError?.(\n error instanceof Error ? error.message : \"Unknown error\",\n \"read\",\n [path, encoding]\n );\n throw error;\n }\n }\n\n async deleteFile(\n path: string,\n sessionId?: string\n ): Promise<DeleteFileResponse> {\n try {\n const targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/delete`, {\n body: JSON.stringify({\n path,\n sessionId: targetSessionId,\n } as DeleteFileRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: DeleteFileResponse = await response.json();\n console.log(\n `[HTTP Client] File deleted: ${path}, Success: ${data.success}`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error deleting file:\", error);\n throw error;\n }\n }\n\n async deleteFileStream(path: string, sessionId?: string): Promise<void> {\n try {\n const targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/delete/stream`, {\n body: JSON.stringify({\n path,\n sessionId: targetSessionId,\n } as DeleteFileRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n if (!response.body) {\n throw new Error(\"No response body for streaming request\");\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n const chunk = decoder.decode(value, { stream: true });\n const lines = chunk.split(\"\\n\");\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n try {\n const eventData = line.slice(6); // Remove 'data: ' prefix\n const event: StreamEvent = JSON.parse(eventData);\n\n console.log(\n `[HTTP Client] Delete file stream event: ${event.type}`\n );\n this.options.onStreamEvent?.(event);\n\n switch (event.type) {\n case \"command_start\":\n console.log(\n `[HTTP Client] Delete file started: ${event.path}`\n );\n this.options.onCommandStart?.(\"delete\", [path]);\n break;\n\n case \"command_complete\":\n console.log(\n `[HTTP Client] Delete file completed: ${event.path}, Success: ${event.success}`\n );\n this.options.onCommandComplete?.(\n event.success!,\n 0,\n \"\",\n \"\",\n \"delete\",\n [path]\n );\n break;\n\n case \"error\":\n console.error(\n `[HTTP Client] Delete file error: ${event.error}`\n );\n this.options.onError?.(event.error!, \"delete\", [path]);\n break;\n }\n } catch (parseError) {\n console.warn(\n \"[HTTP Client] Failed to parse delete file stream event:\",\n parseError\n );\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n } catch (error) {\n console.error(\"[HTTP Client] Error in streaming delete file:\", error);\n this.options.onError?.(\n error instanceof Error ? error.message : \"Unknown error\",\n \"delete\",\n [path]\n );\n throw error;\n }\n }\n\n async renameFile(\n oldPath: string,\n newPath: string,\n sessionId?: string\n ): Promise<RenameFileResponse> {\n try {\n const targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/rename`, {\n body: JSON.stringify({\n newPath,\n oldPath,\n sessionId: targetSessionId,\n } as RenameFileRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: RenameFileResponse = await response.json();\n console.log(\n `[HTTP Client] File renamed: ${oldPath} -> ${newPath}, Success: ${data.success}`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error renaming file:\", error);\n throw error;\n }\n }\n\n async renameFileStream(\n oldPath: string,\n newPath: string,\n sessionId?: string\n ): Promise<void> {\n try {\n const targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/rename/stream`, {\n body: JSON.stringify({\n newPath,\n oldPath,\n sessionId: targetSessionId,\n } as RenameFileRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n if (!response.body) {\n throw new Error(\"No response body for streaming request\");\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n const chunk = decoder.decode(value, { stream: true });\n const lines = chunk.split(\"\\n\");\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n try {\n const eventData = line.slice(6); // Remove 'data: ' prefix\n const event: StreamEvent = JSON.parse(eventData);\n\n console.log(\n `[HTTP Client] Rename file stream event: ${event.type}`\n );\n this.options.onStreamEvent?.(event);\n\n switch (event.type) {\n case \"command_start\":\n console.log(\n `[HTTP Client] Rename file started: ${event.oldPath} -> ${event.newPath}`\n );\n this.options.onCommandStart?.(\"rename\", [oldPath, newPath]);\n break;\n\n case \"command_complete\":\n console.log(\n `[HTTP Client] Rename file completed: ${event.oldPath} -> ${event.newPath}, Success: ${event.success}`\n );\n this.options.onCommandComplete?.(\n event.success!,\n 0,\n \"\",\n \"\",\n \"rename\",\n [oldPath, newPath]\n );\n break;\n\n case \"error\":\n console.error(\n `[HTTP Client] Rename file error: ${event.error}`\n );\n this.options.onError?.(event.error!, \"rename\", [\n oldPath,\n newPath,\n ]);\n break;\n }\n } catch (parseError) {\n console.warn(\n \"[HTTP Client] Failed to parse rename file stream event:\",\n parseError\n );\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n } catch (error) {\n console.error(\"[HTTP Client] Error in streaming rename file:\", error);\n this.options.onError?.(\n error instanceof Error ? error.message : \"Unknown error\",\n \"rename\",\n [oldPath, newPath]\n );\n throw error;\n }\n }\n\n async moveFile(\n sourcePath: string,\n destinationPath: string,\n sessionId?: string\n ): Promise<MoveFileResponse> {\n try {\n const targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/move`, {\n body: JSON.stringify({\n destinationPath,\n sessionId: targetSessionId,\n sourcePath,\n } as MoveFileRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: MoveFileResponse = await response.json();\n console.log(\n `[HTTP Client] File moved: ${sourcePath} -> ${destinationPath}, Success: ${data.success}`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error moving file:\", error);\n throw error;\n }\n }\n\n async moveFileStream(\n sourcePath: string,\n destinationPath: string,\n sessionId?: string\n ): Promise<void> {\n try {\n const targetSessionId = sessionId || this.sessionId;\n\n const response = await this.doFetch(`/api/move/stream`, {\n body: JSON.stringify({\n destinationPath,\n sessionId: targetSessionId,\n sourcePath,\n } as MoveFileRequest),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n if (!response.body) {\n throw new Error(\"No response body for streaming request\");\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n const chunk = decoder.decode(value, { stream: true });\n const lines = chunk.split(\"\\n\");\n\n for (const line of lines) {\n if (line.startsWith(\"data: \")) {\n try {\n const eventData = line.slice(6); // Remove 'data: ' prefix\n const event: StreamEvent = JSON.parse(eventData);\n\n console.log(\n `[HTTP Client] Move file stream event: ${event.type}`\n );\n this.options.onStreamEvent?.(event);\n\n switch (event.type) {\n case \"command_start\":\n console.log(\n `[HTTP Client] Move file started: ${event.sourcePath} -> ${event.destinationPath}`\n );\n this.options.onCommandStart?.(\"move\", [\n sourcePath,\n destinationPath,\n ]);\n break;\n\n case \"command_complete\":\n console.log(\n `[HTTP Client] Move file completed: ${event.sourcePath} -> ${event.destinationPath}, Success: ${event.success}`\n );\n this.options.onCommandComplete?.(\n event.success!,\n 0,\n \"\",\n \"\",\n \"move\",\n [sourcePath, destinationPath]\n );\n break;\n\n case \"error\":\n console.error(\n `[HTTP Client] Move file error: ${event.error}`\n );\n this.options.onError?.(event.error!, \"move\", [\n sourcePath,\n destinationPath,\n ]);\n break;\n }\n } catch (parseError) {\n console.warn(\n \"[HTTP Client] Failed to parse move file stream event:\",\n parseError\n );\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n } catch (error) {\n console.error(\"[HTTP Client] Error in streaming move file:\", error);\n this.options.onError?.(\n error instanceof Error ? error.message : \"Unknown error\",\n \"move\",\n [sourcePath, destinationPath]\n );\n throw error;\n }\n }\n\n async exposePort(port: number, name?: string): Promise<ExposePortResponse> {\n try {\n const response = await this.doFetch(`/api/expose-port`, {\n body: JSON.stringify({\n port,\n name,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"POST\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n console.log(errorData);\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: ExposePortResponse = await response.json();\n console.log(\n `[HTTP Client] Port exposed: ${port}${name ? ` (${name})` : \"\"}, Success: ${data.success}`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error exposing port:\", error);\n throw error;\n }\n }\n\n async unexposePort(port: number): Promise<UnexposePortResponse> {\n try {\n const response = await this.doFetch(`/api/unexpose-port`, {\n body: JSON.stringify({\n port,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"DELETE\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: UnexposePortResponse = await response.json();\n console.log(\n `[HTTP Client] Port unexposed: ${port}, Success: ${data.success}`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error unexposing port:\", error);\n throw error;\n }\n }\n\n async getExposedPorts(): Promise<GetExposedPortsResponse> {\n try {\n const response = await this.doFetch(`/api/exposed-ports`, {\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"GET\",\n });\n\n if (!response.ok) {\n const errorData = (await response.json().catch(() => ({}))) as {\n error?: string;\n };\n throw new Error(\n errorData.error || `HTTP error! status: ${response.status}`\n );\n }\n\n const data: GetExposedPortsResponse = await response.json();\n console.log(\n `[HTTP Client] Got ${data.count} exposed ports`\n );\n\n return data;\n } catch (error) {\n console.error(\"[HTTP Client] Error getting exposed ports:\", error);\n throw error;\n }\n }\n\n async ping(): Promise<string> {\n try {\n const response = await this.doFetch(`/api/ping`, {\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"GET\",\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const data: PingResponse = await response.json();\n console.log(`[HTTP Client] Ping response: ${data.message}`);\n return data.timestamp;\n } catch (error) {\n console.error(\"[HTTP Client] Error pinging server:\", error);\n throw error;\n }\n }\n\n async getCommands(): Promise<string[]> {\n try {\n const response = await fetch(`${this.baseUrl}/api/commands`, {\n headers: {\n \"Content-Type\": \"application/json\",\n },\n method: \"GET\",\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const data: CommandsResponse = await response.json();\n console.log(\n `[HTTP Client] Available commands: ${data.availableCommands.length}`\n );\n return data.availableCommands;\n } catch (error) {\n console.error(\"[HTTP Client] Error getting commands:\", error);\n throw error;\n }\n }\n\n getSessionId(): string | null {\n return this.sessionId;\n }\n\n setSessionId(sessionId: string): void {\n this.sessionId = sessionId;\n }\n\n clearSession(): void {\n this.sessionId = null;\n }\n}\n\n// Example usage and utility functions\nexport function createClient(options?: HttpClientOptions): HttpClient {\n return new HttpClient(options);\n}\n\n// Convenience function for quick command execution\nexport async function quickExecute(\n command: string,\n args: string[] = [],\n options?: HttpClientOptions\n): Promise<ExecuteResponse> {\n const client = createClient(options);\n await client.createSession();\n\n try {\n return await client.execute(command, args);\n } finally {\n client.clearSession();\n }\n}\n\n// Convenience function for quick streaming command execution\nexport async function quickExecuteStream(\n command: string,\n args: string[] = [],\n options?: HttpClientOptions\n): Promise<void> {\n const client = createClient(options);\n await client.createSession();\n\n try {\n await client.executeStream(command, args);\n } finally {\n client.clearSession();\n }\n}\n\n// Convenience function for quick git checkout\nexport async function quickGitCheckout(\n repoUrl: string,\n branch: string = \"main\",\n targetDir?: string,\n options?: HttpClientOptions\n): Promise<GitCheckoutResponse> {\n const client = createClient(options);\n await client.createSession();\n\n try {\n return await client.gitCheckout(repoUrl, branch, targetDir);\n } finally {\n client.clearSession();\n }\n}\n\n// Convenience function for quick directory creation\nexport async function quickMkdir(\n path: string,\n recursive: boolean = false,\n options?: HttpClientOptions\n): Promise<MkdirResponse> {\n const client = createClient(options);\n await client.createSession();\n\n try {\n return await client.mkdir(path, recursive);\n } finally {\n client.clearSession();\n }\n}\n\n// Convenience function for quick streaming git checkout\nexport async function quickGitCheckoutStream(\n repoUrl: string,\n branch: string = \"main\",\n targetDir?: string,\n options?: HttpClientOptions\n): Promise<void> {\n const client = createClient(options);\n await client.createSession();\n\n try {\n await client.gitCheckoutStream(repoUrl, branch, targetDir);\n } finally {\n client.clearSession();\n }\n}\n\n// Convenience function for quick streaming directory creation\nexport async function quickMkdirStream(\n path: string,\n recursive: boolean = false,\n options?: HttpClientOptions\n): Promise<void> {\n const client = createClient(options);\n await client.createSession();\n\n try {\n await client.mkdirStream(path, recursive);\n } finally {\n client.clearSession();\n }\n}\n\n// Convenience function for quick file writing\nexport async function quickWriteFile(\n path: string,\n content: string,\n encoding: string = \"utf-8\",\n options?: HttpClientOptions\n): Promise<WriteFileResponse> {\n const client = createClient(options);\n await client.createSession();\n\n try {\n return await client.writeFile(path, content, encoding);\n } finally {\n client.clearSession();\n }\n}\n\n// Convenience function for quick streaming file writing\nexport async function quickWriteFileStream(\n path: string,\n content: string,\n encoding: string = \"utf-8\",\n options?: HttpClientOptions\n): Promise<void> {\n const client = createClient(options);\n await client.createSession();\n\n try {\n await client.writeFileStream(path, content, encoding);\n } finally {\n client.clearSession();\n }\n}\n\n// Convenience function for quick file reading\nexport async function quickReadFile(\n path: string,\n encoding: string = \"utf-8\",\n options?: HttpClientOptions\n): Promise<ReadFileResponse> {\n const client = createClient(options);\n await client.createSession();\n\n try {\n return await client.readFile(path, encoding);\n } finally {\n client.clearSession();\n }\n}\n\n// Convenience function for quick streaming file reading\nexport async function quickReadFileStream(\n path: string,\n encoding: string = \"utf-8\",\n options?: HttpClientOptions\n): Promise<void> {\n const client = createClient(options);\n await client.createSession();\n\n try {\n await client.readFileStream(path, encoding);\n } finally {\n client.clearSession();\n }\n}\n\n// Convenience function for quick file deletion\nexport async function quickDeleteFile(\n path: string,\n options?: HttpClientOptions\n): Promise<DeleteFileResponse> {\n const client = createClient(options);\n await client.createSession();\n\n try {\n return await client.deleteFile(path);\n } finally {\n client.clearSession();\n }\n}\n\n// Convenience function for quick streaming file deletion\nexport async function quickDeleteFileStream(\n path: string,\n options?: HttpClientOptions\n): Promise<void> {\n const client = createClient(options);\n await client.createSession();\n\n try {\n await client.deleteFileStream(path);\n } finally {\n client.clearSession();\n }\n}\n\n// Convenience function for quick file renaming\nexport async function quickRenameFile(\n oldPath: string,\n newPath: string,\n options?: HttpClientOptions\n): Promise<RenameFileResponse> {\n const client = createClient(options);\n await client.createSession();\n\n try {\n return await client.renameFile(oldPath, newPath);\n } finally {\n client.clearSession();\n }\n}\n\n// Convenience function for quick streaming file renaming\nexport async function quickRenameFileStream(\n oldPath: string,\n newPath: string,\n options?: HttpClientOptions\n): Promise<void> {\n const client = createClient(options);\n await client.createSession();\n\n try {\n await client.renameFileStream(oldPath, newPath);\n } finally {\n client.clearSession();\n }\n}\n\n// Convenience function for quick file moving\nexport async function quickMoveFile(\n sourcePath: string,\n destinationPath: string,\n options?: HttpClientOptions\n): Promise<MoveFileResponse> {\n const client = createClient(options);\n await client.createSession();\n\n try {\n return await client.moveFile(sourcePath, destinationPath);\n } finally {\n client.clearSession();\n }\n}\n\n// Convenience function for quick streaming file moving\nexport async function quickMoveFileStream(\n sourcePath: string,\n destinationPath: string,\n options?: HttpClientOptions\n): Promise<void> {\n const client = createClient(options);\n await client.createSession();\n\n try {\n await client.moveFileStream(sourcePath, destinationPath);\n } finally {\n client.clearSession();\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HttpClient
|
|
3
|
+
} from "./chunk-4J5LQCCN.js";
|
|
4
|
+
|
|
5
|
+
// src/sandbox.ts
|
|
6
|
+
import { Container, getContainer } from "@cloudflare/containers";
|
|
7
|
+
|
|
8
|
+
// src/request-handler.ts
|
|
9
|
+
async function proxyToSandbox(request, env) {
|
|
10
|
+
try {
|
|
11
|
+
const url = new URL(request.url);
|
|
12
|
+
const routeInfo = extractSandboxRoute(url);
|
|
13
|
+
if (!routeInfo) {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
const { sandboxId, port, path } = routeInfo;
|
|
17
|
+
const sandbox = getSandbox(env.Sandbox, sandboxId);
|
|
18
|
+
let proxyUrl;
|
|
19
|
+
if (port !== 3e3) {
|
|
20
|
+
proxyUrl = `http://localhost:${port}${path}${url.search}`;
|
|
21
|
+
} else {
|
|
22
|
+
proxyUrl = `http://localhost:3000${path}${url.search}`;
|
|
23
|
+
}
|
|
24
|
+
const proxyRequest = new Request(proxyUrl, {
|
|
25
|
+
method: request.method,
|
|
26
|
+
headers: {
|
|
27
|
+
...Object.fromEntries(request.headers),
|
|
28
|
+
"X-Original-URL": request.url,
|
|
29
|
+
"X-Forwarded-Host": url.hostname,
|
|
30
|
+
"X-Forwarded-Proto": url.protocol.replace(":", ""),
|
|
31
|
+
"X-Sandbox-Name": sandboxId
|
|
32
|
+
// Pass the friendly name
|
|
33
|
+
},
|
|
34
|
+
body: request.body
|
|
35
|
+
});
|
|
36
|
+
return sandbox.containerFetch(proxyRequest, port);
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.error("[Sandbox] Proxy routing error:", error);
|
|
39
|
+
return new Response("Proxy routing error", { status: 500 });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function extractSandboxRoute(url) {
|
|
43
|
+
const subdomainMatch = url.hostname.match(/^(\d+)-([a-zA-Z0-9-]+)\./);
|
|
44
|
+
if (subdomainMatch) {
|
|
45
|
+
return {
|
|
46
|
+
port: parseInt(subdomainMatch[1]),
|
|
47
|
+
sandboxId: subdomainMatch[2],
|
|
48
|
+
path: url.pathname
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
if (isLocalhostPattern(url.hostname)) {
|
|
52
|
+
const pathMatch = url.pathname.match(/^\/preview\/(\d+)\/([^/]+)(\/.*)?$/);
|
|
53
|
+
if (pathMatch) {
|
|
54
|
+
return {
|
|
55
|
+
port: parseInt(pathMatch[1]),
|
|
56
|
+
sandboxId: pathMatch[2],
|
|
57
|
+
path: pathMatch[3] || "/"
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
function isLocalhostPattern(hostname) {
|
|
64
|
+
const hostPart = hostname.split(":")[0];
|
|
65
|
+
return hostPart === "localhost" || hostPart === "127.0.0.1" || hostPart === "::1" || hostPart === "[::1]" || hostPart === "0.0.0.0";
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// src/sandbox.ts
|
|
69
|
+
function getSandbox(ns, id) {
|
|
70
|
+
const stub = getContainer(ns, id);
|
|
71
|
+
stub.setSandboxName?.(id);
|
|
72
|
+
return stub;
|
|
73
|
+
}
|
|
74
|
+
var Sandbox = class extends Container {
|
|
75
|
+
sleepAfter = "3m";
|
|
76
|
+
// Sleep the sandbox if no requests are made in this timeframe
|
|
77
|
+
client;
|
|
78
|
+
workerHostname = null;
|
|
79
|
+
sandboxName = null;
|
|
80
|
+
constructor(ctx, env) {
|
|
81
|
+
super(ctx, env);
|
|
82
|
+
this.client = new HttpClient({
|
|
83
|
+
onCommandComplete: (success, exitCode, _stdout, _stderr, command, _args) => {
|
|
84
|
+
console.log(
|
|
85
|
+
`[Container] Command completed: ${command}, Success: ${success}, Exit code: ${exitCode}`
|
|
86
|
+
);
|
|
87
|
+
},
|
|
88
|
+
onCommandStart: (command, args) => {
|
|
89
|
+
console.log(
|
|
90
|
+
`[Container] Command started: ${command} ${args.join(" ")}`
|
|
91
|
+
);
|
|
92
|
+
},
|
|
93
|
+
onError: (error, _command, _args) => {
|
|
94
|
+
console.error(`[Container] Command error: ${error}`);
|
|
95
|
+
},
|
|
96
|
+
onOutput: (stream, data, _command) => {
|
|
97
|
+
console.log(`[Container] [${stream}] ${data}`);
|
|
98
|
+
},
|
|
99
|
+
port: 3e3,
|
|
100
|
+
// Control plane port
|
|
101
|
+
stub: this
|
|
102
|
+
});
|
|
103
|
+
this.ctx.blockConcurrencyWhile(async () => {
|
|
104
|
+
this.sandboxName = await this.ctx.storage.get("sandboxName") || null;
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
// RPC method to set the sandbox name
|
|
108
|
+
async setSandboxName(name) {
|
|
109
|
+
if (!this.sandboxName) {
|
|
110
|
+
this.sandboxName = name;
|
|
111
|
+
await this.ctx.storage.put("sandboxName", name);
|
|
112
|
+
console.log(`[Sandbox] Stored sandbox name via RPC: ${name}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
onStart() {
|
|
116
|
+
console.log("Sandbox successfully started");
|
|
117
|
+
}
|
|
118
|
+
onStop() {
|
|
119
|
+
console.log("Sandbox successfully shut down");
|
|
120
|
+
if (this.client) {
|
|
121
|
+
this.client.clearSession();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
onError(error) {
|
|
125
|
+
console.log("Sandbox error:", error);
|
|
126
|
+
}
|
|
127
|
+
// Override fetch to capture the hostname and route to appropriate ports
|
|
128
|
+
async fetch(request) {
|
|
129
|
+
const url = new URL(request.url);
|
|
130
|
+
if (!this.workerHostname) {
|
|
131
|
+
this.workerHostname = url.hostname;
|
|
132
|
+
console.log(`[Sandbox] Captured hostname: ${this.workerHostname}`);
|
|
133
|
+
}
|
|
134
|
+
if (!this.sandboxName && request.headers.has("X-Sandbox-Name")) {
|
|
135
|
+
const name = request.headers.get("X-Sandbox-Name");
|
|
136
|
+
this.sandboxName = name;
|
|
137
|
+
await this.ctx.storage.put("sandboxName", name);
|
|
138
|
+
console.log(`[Sandbox] Stored sandbox name: ${this.sandboxName}`);
|
|
139
|
+
}
|
|
140
|
+
const port = this.determinePort(url);
|
|
141
|
+
return await this.containerFetch(request, port);
|
|
142
|
+
}
|
|
143
|
+
determinePort(url) {
|
|
144
|
+
const proxyMatch = url.pathname.match(/^\/proxy\/(\d+)/);
|
|
145
|
+
if (proxyMatch) {
|
|
146
|
+
return parseInt(proxyMatch[1]);
|
|
147
|
+
}
|
|
148
|
+
return 3e3;
|
|
149
|
+
}
|
|
150
|
+
async exec(command, args, options) {
|
|
151
|
+
if (options?.stream) {
|
|
152
|
+
return this.client.executeStream(command, args, void 0, options?.background);
|
|
153
|
+
}
|
|
154
|
+
return this.client.execute(command, args, void 0, options?.background);
|
|
155
|
+
}
|
|
156
|
+
async gitCheckout(repoUrl, options) {
|
|
157
|
+
if (options?.stream) {
|
|
158
|
+
return this.client.gitCheckoutStream(
|
|
159
|
+
repoUrl,
|
|
160
|
+
options.branch,
|
|
161
|
+
options.targetDir
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
return this.client.gitCheckout(repoUrl, options.branch, options.targetDir);
|
|
165
|
+
}
|
|
166
|
+
async mkdir(path, options = {}) {
|
|
167
|
+
if (options?.stream) {
|
|
168
|
+
return this.client.mkdirStream(path, options.recursive);
|
|
169
|
+
}
|
|
170
|
+
return this.client.mkdir(path, options.recursive);
|
|
171
|
+
}
|
|
172
|
+
async writeFile(path, content, options = {}) {
|
|
173
|
+
if (options?.stream) {
|
|
174
|
+
return this.client.writeFileStream(path, content, options.encoding);
|
|
175
|
+
}
|
|
176
|
+
return this.client.writeFile(path, content, options.encoding);
|
|
177
|
+
}
|
|
178
|
+
async deleteFile(path, options = {}) {
|
|
179
|
+
if (options?.stream) {
|
|
180
|
+
return this.client.deleteFileStream(path);
|
|
181
|
+
}
|
|
182
|
+
return this.client.deleteFile(path);
|
|
183
|
+
}
|
|
184
|
+
async renameFile(oldPath, newPath, options = {}) {
|
|
185
|
+
if (options?.stream) {
|
|
186
|
+
return this.client.renameFileStream(oldPath, newPath);
|
|
187
|
+
}
|
|
188
|
+
return this.client.renameFile(oldPath, newPath);
|
|
189
|
+
}
|
|
190
|
+
async moveFile(sourcePath, destinationPath, options = {}) {
|
|
191
|
+
if (options?.stream) {
|
|
192
|
+
return this.client.moveFileStream(sourcePath, destinationPath);
|
|
193
|
+
}
|
|
194
|
+
return this.client.moveFile(sourcePath, destinationPath);
|
|
195
|
+
}
|
|
196
|
+
async readFile(path, options = {}) {
|
|
197
|
+
if (options?.stream) {
|
|
198
|
+
return this.client.readFileStream(path, options.encoding);
|
|
199
|
+
}
|
|
200
|
+
return this.client.readFile(path, options.encoding);
|
|
201
|
+
}
|
|
202
|
+
async exposePort(port, options) {
|
|
203
|
+
await this.client.exposePort(port, options?.name);
|
|
204
|
+
if (!this.sandboxName) {
|
|
205
|
+
throw new Error("Sandbox name not available. Ensure sandbox is accessed through getSandbox()");
|
|
206
|
+
}
|
|
207
|
+
const hostname = this.getHostname();
|
|
208
|
+
const url = this.constructPreviewUrl(port, this.sandboxName, hostname);
|
|
209
|
+
return {
|
|
210
|
+
url,
|
|
211
|
+
port,
|
|
212
|
+
name: options?.name
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
async unexposePort(port) {
|
|
216
|
+
await this.client.unexposePort(port);
|
|
217
|
+
}
|
|
218
|
+
async getExposedPorts() {
|
|
219
|
+
const response = await this.client.getExposedPorts();
|
|
220
|
+
if (!this.sandboxName) {
|
|
221
|
+
throw new Error("Sandbox name not available. Ensure sandbox is accessed through getSandbox()");
|
|
222
|
+
}
|
|
223
|
+
const hostname = this.getHostname();
|
|
224
|
+
return response.ports.map((port) => ({
|
|
225
|
+
url: this.constructPreviewUrl(port.port, this.sandboxName, hostname),
|
|
226
|
+
port: port.port,
|
|
227
|
+
name: port.name,
|
|
228
|
+
exposedAt: port.exposedAt
|
|
229
|
+
}));
|
|
230
|
+
}
|
|
231
|
+
getHostname() {
|
|
232
|
+
return this.workerHostname || "localhost:8787";
|
|
233
|
+
}
|
|
234
|
+
constructPreviewUrl(port, sandboxId, hostname) {
|
|
235
|
+
const isLocalhost = isLocalhostPattern(hostname);
|
|
236
|
+
if (isLocalhost) {
|
|
237
|
+
return `http://${hostname}/preview/${port}/${sandboxId}`;
|
|
238
|
+
}
|
|
239
|
+
const protocol = hostname.includes(":") ? "http" : "https";
|
|
240
|
+
return `${protocol}://${port}-${sandboxId}.${hostname}`;
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
export {
|
|
245
|
+
getSandbox,
|
|
246
|
+
Sandbox,
|
|
247
|
+
proxyToSandbox,
|
|
248
|
+
isLocalhostPattern
|
|
249
|
+
};
|
|
250
|
+
//# sourceMappingURL=chunk-5SZ3RVJZ.js.map
|
|
@@ -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\";\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> {\n sleepAfter = \"3m\"; // Sleep the sandbox if no requests are made in this timeframe\n client: HttpClient;\n private workerHostname: string | null = null;\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, _args) => {\n console.log(\n `[Container] Command completed: ${command}, Success: ${success}, Exit code: ${exitCode}`\n );\n },\n onCommandStart: (command, args) => {\n console.log(\n `[Container] Command started: ${command} ${args.join(\" \")}`\n );\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: 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 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 capture the hostname and route to appropriate ports\n override async fetch(request: Request): Promise<Response> {\n const url = new URL(request.url);\n\n // Capture the hostname from the first request\n if (!this.workerHostname) {\n this.workerHostname = url.hostname;\n console.log(`[Sandbox] Captured hostname: ${this.workerHostname}`);\n }\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 async exec(command: string, args: string[], options?: { stream?: boolean; background?: boolean }) {\n if (options?.stream) {\n return this.client.executeStream(command, args, undefined, options?.background);\n }\n return this.client.execute(command, args, undefined, options?.background);\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 async writeFile(\n path: string,\n content: string,\n options: { encoding?: string; stream?: boolean } = {}\n ) {\n if (options?.stream) {\n return this.client.writeFileStream(path, content, options.encoding);\n }\n return this.client.writeFile(path, content, options.encoding);\n }\n\n async deleteFile(path: string, options: { stream?: boolean } = {}) {\n if (options?.stream) {\n return this.client.deleteFileStream(path);\n }\n return this.client.deleteFile(path);\n }\n\n async renameFile(\n oldPath: string,\n newPath: string,\n options: { stream?: boolean } = {}\n ) {\n if (options?.stream) {\n return this.client.renameFileStream(oldPath, newPath);\n }\n return this.client.renameFile(oldPath, newPath);\n }\n\n async moveFile(\n sourcePath: string,\n destinationPath: string,\n options: { stream?: boolean } = {}\n ) {\n if (options?.stream) {\n return this.client.moveFileStream(sourcePath, destinationPath);\n }\n return this.client.moveFile(sourcePath, destinationPath);\n }\n\n async readFile(\n path: string,\n options: { encoding?: string; stream?: boolean } = {}\n ) {\n if (options?.stream) {\n return this.client.readFileStream(path, options.encoding);\n }\n return this.client.readFile(path, options.encoding);\n }\n\n async exposePort(port: number, options?: { name?: 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 hostname = this.getHostname();\n const url = this.constructPreviewUrl(port, this.sandboxName, hostname);\n\n return {\n url,\n port,\n name: options?.name,\n };\n }\n\n async unexposePort(port: number) {\n await this.client.unexposePort(port);\n }\n\n async getExposedPorts() {\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 const hostname = this.getHostname();\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 private getHostname(): string {\n // Use the captured hostname or fall back to localhost for development\n return this.workerHostname || \"localhost:8787\";\n }\n\n private constructPreviewUrl(port: number, sandboxId: string, hostname: string): string {\n // Check if this is a localhost pattern\n const isLocalhost = isLocalhostPattern(hostname);\n\n if (isLocalhost) {\n // For local development, we need to use a different approach\n // Since subdomains don't work with localhost, we'll use the base URL\n // with a note that the user needs to handle routing differently\n return `http://${hostname}/preview/${port}/${sandboxId}`;\n }\n\n // For all other domains (workers.dev, custom domains, etc.)\n // Use subdomain-based routing pattern\n const protocol = hostname.includes(\":\") ? \"http\" : \"https\";\n return `${protocol}://${port}-${sandboxId}.${hostname}`;\n }\n}\n","import { getSandbox, type Sandbox } from \"./sandbox\";\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 // Production: subdomain pattern {port}-{sandboxId}.{domain}\n const subdomainMatch = url.hostname.match(/^(\\d+)-([a-zA-Z0-9-]+)\\./);\n if (subdomainMatch) {\n return {\n port: parseInt(subdomainMatch[1]),\n sandboxId: subdomainMatch[2],\n path: url.pathname,\n };\n }\n\n // Development: path pattern /preview/{port}/{sandboxId}/*\n if (isLocalhostPattern(url.hostname)) {\n const pathMatch = url.pathname.match(/^\\/preview\\/(\\d+)\\/([^/]+)(\\/.*)?$/);\n if (pathMatch) {\n return {\n port: parseInt(pathMatch[1]),\n sandboxId: pathMatch[2],\n path: pathMatch[3] || \"/\",\n };\n }\n }\n\n return null;\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\n"],"mappings":"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","names":[]}
|