# 腳本執行環境

各語言 wrapper 如何接收輸入、執行使用者程式碼並輸出結果。

## 輸入注入

Handler 把 `{"code": ..., "input": ...}` 以 JSON 寫入 wrapper 的 stdin。wrapper 將 `input` 字串解析為 JSON 物件，並同時以兩個全域變數提供：

| 全域變數 | 內容 |
|----------|------|
| `event` | 解析後的 `input`；`input` 為空時為 `{}` |
| `input` | 與 `event` 相同的物件 |

`input` 不是合法 JSON 時，wrapper 寫入 stderr 並以退出碼 1 結束。

## 各語言行為

| 語言 | Runtime | 執行方式 | 結果輸出 |
|------|---------|----------|----------|
| Python | `python3 -u` | 程式碼逐行縮排後包進 `__user_main__()`，讓頂層 `return` 可用 | `json.dumps(回傳值)` 印到 stdout；無法序列化時不輸出 |
| JavaScript | `node` | 包進 `async function`，以 `vm.Script` 在全域 context 執行；可用 `await` | 回傳值非 `undefined` 時 `JSON.stringify` 印出 |
| TypeScript | `tsx` | 先以 `esbuild.transformSync`（`loader: ts`、`format: cjs`、`target: node18`）轉譯，再同 JavaScript 執行 | 頂層 `return` 值或全域 `result`，`JSON.stringify` 印出 |

## 範例

```python
total = sum(event["items"])
print("summing", len(event["items"]))
return {"total": total}
```

```javascript
const res = await Promise.resolve(event.a * 2);
return { doubled: res };
```

```typescript
interface User { name: string; age: number }
const adults = (event.users as User[]).filter(u => u.age >= 18);
return adults.map(u => u.name);
```

中間的 `print`／`console.log` 在非串流模式會被忽略（只取最後一行合法 JSON），在串流模式會成為 `log` 事件。

## 錯誤處理

- 例外會寫入 stderr（`Error: ...`）並以退出碼 1 結束。
- 非串流模式：回 HTTP 500，內容為 `failed to run: <錯誤>`。
- 串流模式：任何 stderr 輸出都會立即終止行程並送出 `error` 事件；第三方套件印到 stderr 的警告也會觸發。

## 相關頁面

- [回應與 SSE](/zh/responses)
- [沙箱](/zh/sandbox)
