| 167 | } |
| 168 | |
| 169 | async function handleExec(request: Request, env: Env, name: string): Promise<Response> { |
| 170 | if (request.method !== "POST") { |
| 171 | return new Response("method not allowed", { status: 405, headers: { allow: "POST" } }); |
| 172 | } |
| 173 | let body: ExecRequest; |
| 174 | try { |
| 175 | body = (await request.json()) as ExecRequest; |
| 176 | } catch { |
| 177 | return errorJSON(new Error("invalid JSON body"), 400); |
| 178 | } |
| 179 | |
| 180 | let command: string; |
| 181 | if (typeof body.command === "string" && body.command.length > 0) { |
| 182 | command = body.command; |
| 183 | } else if (Array.isArray(body.argv) && body.argv.length > 0) { |
| 184 | command = body.argv.map(shellQuote).join(" "); |
| 185 | } else { |
| 186 | return errorJSON(new Error("must provide command or argv"), 400); |
| 187 | } |
| 188 | |
| 189 | const stub = env.ContainerExample.get(env.ContainerExample.idFromName(name)); |
| 190 | const ws = await getWorkspace(stub as unknown as Parameters<typeof getWorkspace>[0]); |
| 191 | try { |
| 192 | const handle = await ws.runtime.exec(command, { cwd: body.cwd, encoding: "utf8" }); |
| 193 | const result = await handle.result(); |
| 194 | return new Response(JSON.stringify(result), { |
| 195 | status: 200, |
| 196 | headers: { "content-type": "application/json" }, |
| 197 | }); |
| 198 | } catch (error) { |
| 199 | return errorJSON(error, 500); |
| 200 | } |
| 201 | } |
| 202 | |
| 203 | function errorJSON(error: unknown, status: number): Response { |
| 204 | const message = error instanceof Error ? error.message : String(error); |