| 207 | } |
| 208 | |
| 209 | async function handleExec(request: Request, env: Env, name: string): Promise<Response> { |
| 210 | if (request.method !== "POST") { |
| 211 | return new Response("method not allowed", { status: 405, headers: { allow: "POST" } }); |
| 212 | } |
| 213 | let body: ExecRequest; |
| 214 | try { |
| 215 | body = (await request.json()) as ExecRequest; |
| 216 | } catch { |
| 217 | return errorJSON(new Error("invalid JSON body"), 400); |
| 218 | } |
| 219 | |
| 220 | let command: string; |
| 221 | if (typeof body.command === "string" && body.command.length > 0) { |
| 222 | command = body.command; |
| 223 | } else if (Array.isArray(body.argv) && body.argv.length > 0) { |
| 224 | command = body.argv.map(shellQuote).join(" "); |
| 225 | } else { |
| 226 | return errorJSON(new Error("must provide command or argv"), 400); |
| 227 | } |
| 228 | |
| 229 | const stub = env.ContainerExample.get(env.ContainerExample.idFromName(name)); |
| 230 | const ws = await getWorkspace(stub as unknown as Parameters<typeof getWorkspace>[0]); |
| 231 | try { |
| 232 | const handle = await ws.runtime.exec(command, { cwd: body.cwd, encoding: "utf8" }); |
| 233 | const result = await handle.result(); |
| 234 | return new Response(JSON.stringify(result), { |
| 235 | status: 200, |
| 236 | headers: { "content-type": "application/json" }, |
| 237 | }); |
| 238 | } catch (error) { |
| 239 | return errorJSON(error, 500); |
| 240 | } |
| 241 | } |
| 242 | |
| 243 | function errorJSON(error: unknown, status: number): Response { |
| 244 | const message = error instanceof Error ? error.message : String(error); |