97 lines
3.4 KiB
Markdown
97 lines
3.4 KiB
Markdown
# `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 three metadata lines:
|
|
`// @applet-input-schema {JSON Schema}` followed by
|
|
`// @applet-output-schema {name:type;name:type}` and
|
|
`// @applet-description "description"`. The input schema describes the GUI form posted as
|
|
`input`. The output line declares the RESULT COLUMNS as typed CSV — `name:type` pairs separated by `;`
|
|
(e.g. `id:integer;name:string;active:boolean`); allowed types are `string`, `integer`, `number`,
|
|
`boolean` and `date`. The applet exports a function that receives the posted `input` as `applet_input`
|
|
and returns a row object (or an array of row objects) keyed by those columns.
|
|
|
|
Applets return typed CSV, not JSON: `result` is a `;`-separated CSV string with a header row, and the
|
|
response also carries `columns` (name/type) and `rows` (data row count). Only declared columns are
|
|
emitted, in header order; missing values become empty cells. Execution runs in the same isolated worker
|
|
sandbox as the `javascript_execute` tool — including authenticated `fetch()` against this API,
|
|
`fs`/`vfs`, `optimizeImage`, 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,
|
|
"description": "…",
|
|
"result": "id;name\n1;Kaffee",
|
|
"columns": [
|
|
{
|
|
"name": "…",
|
|
"type": "string"
|
|
}
|
|
],
|
|
"rows": 1,
|
|
"warnings": [
|
|
"…"
|
|
],
|
|
"stdout": "…",
|
|
"consoleLines": 1,
|
|
"durationMs": 1,
|
|
"truncated": true,
|
|
"truncationNote": "…"
|
|
}
|
|
```
|
|
|
|
## Errors
|
|
|
|
| Status | Description |
|
|
|--------|-------------|
|
|
| 400 | No company selected, invalid path, not a .applet.js file, invalid input, invalid applet metadata, or applet runtime error — `{"error":"…"}` |
|
|
| 401 | Unauthorized — `{"error":"…"}` |
|
|
| 403 | Not authorized, or cannot execute read-only database paths — `{"error":"…"}` |
|
|
| 404 | Applet not found — `{"error":"…"}` |
|
|
| 500 | Sandbox worker harness failure — `{"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`._
|