This commit is contained in:
seb
2026-10-10 05:52:15 +02:00
parent c012b82af3
commit eed10ea38d
5 changed files with 325 additions and 4 deletions

View File

@@ -0,0 +1,77 @@
# `POST /vfs/{*path}`
Protected. Requires a valid session cookie (`credentials: 'include'`).
Execute a virtual filesystem applet
Runs a `.applet.js` file from the virtual filesystem for the authenticated user's selected company
and returns the exported function's result.
The applet file must begin with two metadata lines:
`// @applet-input-schema {JSON Schema}` followed by
`// @applet-output-schema {JSON Schema}`. The file exports a function that receives the posted `input`
as `applet_input`, and execution runs in the same isolated worker sandbox as the `javascript_execute`
tool — including authenticated `fetch()` against this API, `fs`/`vfs`, `sharp`, ExcelJS, PDFKit and
WebCrypto globals.
The path is taken from the URL (like `DELETE /vfs/{*path}`); the run arguments are the JSON body.
Path traversal (`..`), null bytes, and backslashes are rejected with HTTP 400, as is a path that does
not end in `.applet.js`. Read-only database paths are rejected with HTTP 403.
## Path parameters
| Param | Required | Type | Description |
|-------|----------|------|-------------|
| `path` | yes | string | VFS-relative path to the applet file (e.g. `demo.applet.js`, `apps/report.applet.js`) |
## Body (JSON) — _optional_
| Field | Required | Type | Description |
|-------|----------|------|-------------|
| `input` | no | object | Input values passed to the exported applet function as `applet_input`. Defaults to an empty object. |
| `timeout` | no | integer | Execution timeout in milliseconds, clamped to 1000…60000. Default 20000. |
| `max_output` | no | integer | Maximum stdout characters before truncation. Default 20000. |
```json
{
"input": {},
"timeout": 1,
"max_output": 1
}
```
## Signals
On success, emits SSE signal: `vfs` (see [`GET /events`](../events.md)).
## Response `200`
Applet executed successfully
```json
{
"ok": true,
"result": null,
"stdout": "…",
"consoleLines": 1,
"durationMs": 1,
"truncated": true,
"truncationNote": "…"
}
```
## Errors
| Status | Description |
|--------|-------------|
| 400 | No company selected, invalid path, not a .applet.js file, invalid input, or invalid applet metadata — `{"error":"…"}` |
| 401 | Unauthorized — `{"error":"…"}` |
| 403 | Not authorized, or cannot execute read-only database paths — `{"error":"…"}` |
| 404 | Applet not found — `{"error":"…"}` |
| 500 | The applet threw during execution — `{"error":"…"}` |
| 504 | The applet exceeded the execution timeout and was terminated — `{"error":"…"}` |
---
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._