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
