canonical_id: "code" display_name: "程式碼(沙箱 inline JS)" category: "logic" version: "v1" wasi_target: "preview1" stability: "floating" runtime_compat: - "cf-workers" - "workerd" constraints: max_size_kb: 2048 max_cold_start_ms: 80 no_network_syscall: true no_filesystem_syscall: true io_model: "stdin_stdout_json" # --- 沙箱資源上限(可被節點 config 的 limits 覆蓋,但不得放寬過硬上限)--- sandbox_limits: timeout_ms: 1000 memory_bytes: 16777216 # 16 MiB max_stack_bytes: 524288 # 512 KiB max_output_bytes: 1048576 # 1 MiB max_code_bytes: 262144 # 256 KiB input_schema: type: object required: [code] properties: code: type: string description: "一段 inline JS(函式體)。可讀綁定的 `input`,以 `return` 回傳一個 JSON-able 值。碰不到網路/檔案/env/secret。" input: description: "上游資料(任意 JSON),在沙箱內綁為全域 `input`。" limits: type: object description: "選填,覆蓋預設資源上限(不得超過契約 sandbox_limits 硬上限)。" properties: timeout_ms: { type: number } memory_bytes: { type: number } max_output_bytes: { type: number } output_schema: type: object properties: success: type: boolean data: description: "user code 的回傳值(success=true 時)。" error: type: string description: "success=false 時的錯誤訊息。" error_type: type: string enum: [UserCodeError, TimeoutError, ResourceError, ContractError, SandboxError] gherkin_tests: - scenario: "基本 sum" given: '{"code":"return {sum: input.a + input.b};","input":{"a":2,"b":40}}' then_contains: '"sum":42' - scenario: "沙箱隔離:碰不到 fetch" given: '{"code":"return typeof fetch;","input":{}}' then_contains: '"data":"undefined"' - scenario: "user code 拋錯 → 結構化 error" given: '{"code":"throw new Error(\"boom\");","input":{}}' then_contains: '"success":false' tags: [builtin, logic, code, sandbox, javascript, escape-hatch] description: > 通用「程式碼逃生口」。跑一段 sandbox inline JS(n8n Code node 式): config 帶 `code`(inline JS 函式體),stdin 帶 `input`(上游 JSON), stdout 回 `{success, data}` 或 `{success:false, error, error_type}`。 user code 在 QuickJS-wasm 沙箱內執行,只有純 ECMAScript 內建 + host 明確注入的 curated builtin(目前:純函式 sha256),碰不到網路/檔案/env/secret/Worker 物件圖。 用於一次性/小段程式邏輯(如卡片→envelope 文字處理),避免各自鑄 domain 零件。 config_example: | my_code: # 節點名稱(可自訂) code: | # inline JS 函式體(必填);讀 input、return 一個 JSON-able 值 const doubled = input.items.map(x => x * 2); return { doubled, count: doubled.length }; input: # 上游資料(選填;workflow 可用引用注入) items: [1, 2, 3] limits: # 資源上限覆蓋(選填) timeout_ms: 2000