78 lines
3.6 KiB
Markdown
78 lines
3.6 KiB
Markdown
# `GET /vfs/{*path}`
|
||
|
||
Protected. Requires a valid session cookie (`credentials: 'include'`).
|
||
|
||
Get a virtual filesystem file
|
||
|
||
Returns a file from the virtual filesystem for the authenticated user's selected company.
|
||
Commonly used to retrieve artifacts generated by the model in the `javascript_execute` sandbox or uploaded by users.
|
||
|
||
### URL Format
|
||
Accepts:
|
||
- Relative VFS paths: `example.png`, `reports/summary.pdf`
|
||
- Full endpoint paths: `/vfs/example.png`, `/api/vfs/example.png` (leading `api/` and `vfs/` prefixes are automatically stripped)
|
||
- Absolute URLs: `https://.../api/vfs/example.png`
|
||
- Traversal (`..`), null bytes (`\0`), and backslashes (`\`) are strictly forbidden and rejected with HTTP 400.
|
||
|
||
### Image Previews & Thumbnails
|
||
Supported raster images (`image/png`, `image/jpeg`, `image/gif`, `image/webp`, `image/avif`, `image/bmp`)
|
||
are automatically transformed into a **250×250 aspect-preserving preview thumbnail** (WebP format, quality 88):
|
||
- Scaled to fit within a 250×250 box without distortion (e.g. 2000×100 becomes 250×13).
|
||
- Images whose larger edge is below 100px are upscaled to 100px for icon legibility.
|
||
- A translucent dark metadata strip (`#101317`, max 50% height) with monospace text (`DejaVu Sans Mono`)
|
||
is rendered along the bottom edge, displaying original dimensions and file size.
|
||
- Served with `Content-Security-Policy: default-src 'none'; sandbox`.
|
||
- Use `?raw=1` (or `?raw=true`) to bypass preview generation and return the original unmodified image inline.
|
||
|
||
### Inline vs Attachment
|
||
- Browser-compatible types (HTML, CSS, JS, JSON, PDF, text, images, audio, video, fonts, WASM)
|
||
are served with `Content-Disposition: inline; filename="..."` so they open directly in modern browsers.
|
||
- Non-browser/binary types default to `Content-Disposition: attachment; filename="..."`.
|
||
- Use `?download=1` (or `?download=true`) to force file download with `Content-Disposition: attachment`.
|
||
|
||
### Caching & Conditional Requests
|
||
- Generates weak ETags (`W/"thumb-..."` for previews, `W/"<timestamp>-<mode>"` for originals).
|
||
- Sets `Cache-Control: private, max-age=0, must-revalidate`.
|
||
- Supports `If-None-Match` conditional requests returning HTTP `304 Not Modified`.
|
||
|
||
|
||
## Path parameters
|
||
|
||
| Param | Required | Type | Description |
|
||
|-------|----------|------|-------------|
|
||
| `path` | yes | string | VFS file path (e.g. `example.png`, `charts/graph.svg`) |
|
||
|
||
## Query parameters
|
||
|
||
| Param | Required | Type | Description |
|
||
|-------|----------|------|-------------|
|
||
| `download` | no | boolean | Force file download with Content-Disposition: attachment (1 or true). |
|
||
| `raw` | no | boolean | Return original unmodified image inline without generating a preview thumbnail (1 or true). |
|
||
|
||
## Response `200`
|
||
|
||
File bytes. Served inline for browser-renderable formats or as a download.
|
||
Includes headers:
|
||
- `Content-Type`: MIME type of file, or `image/webp` for previews
|
||
- `Content-Length`: Size of served payload in bytes
|
||
- `Content-Disposition`: `inline; filename="..."` or `attachment; filename="..."`
|
||
- `Cache-Control`: `private, max-age=0, must-revalidate`
|
||
- `ETag`: Weak ETag identifier
|
||
- `X-Content-Type-Options`: `nosniff`
|
||
- `Content-Security-Policy`: `default-src 'none'; sandbox` (for preview thumbnails)
|
||
|
||
|
||
## Errors
|
||
|
||
| Status | Description |
|
||
|--------|-------------|
|
||
| 304 | Not modified (If-None-Match matched ETag) |
|
||
| 400 | Invalid path, path escapes VFS boundary, or no company selected — `{"error":"…"}` |
|
||
| 401 | Unauthorized — `{"error":"…"}` |
|
||
| 403 | Not authorized — `{"error":"…"}` |
|
||
| 404 | File not found — `{"error":"…"}` |
|
||
|
||
---
|
||
|
||
_Generated from `@openapi` JSDoc. Do not edit by hand — run `npm run docs:api`._
|