This commit is contained in:
seb
2026-10-12 14:07:40 +02:00
parent 280ed1b2b8
commit 88ecf5bf5c

View File

@@ -0,0 +1,126 @@
Applet Guide: Sandboxed Execution, Typed CSV Output
# Overview
An applet is a flat, reusable `.applet.js` script stored in the VFS that queries Dashback REST endpoints and computes tabular data.
Applets return structured, semicolon-separated (`;`) typed CSV conforming to output metadata headers.
Applets can be executed by:
1. `javascript_execute` tool using `{ "appletvfsfile": "<name>.applet.js", "applet_input": { ... } }`.
2. REST API endpoint `POST /vfs/<name>.applet.js` with `{ "input": { ... } }`.
---
# Every `.applet.js` file MUST start with three metadata lines:
```
// @applet-input-schema {"type":"object","properties":{...},"required":[...]}
// @applet-output-schema name:type;name:type
// @applet-description "Lorem ipsum"
```
`@applet-input-schema`
- JSON Schema object (`"type": "object"`).
- Parameter descriptions in the schema are optional
`@applet-output-schema`
- Semicolon-separated (`col1:type;col2:type;...`) column declarations.
- Bare column names without `:type` default to `string`.
- Allowed data types:
- `string`: plain text or serialized object.
- `integer`: truncated integer number.
- `number`: floating-point number.
- `boolean`: boolean value (`true`, `false`, `1`, `0`, `"true"`, `"false"`).
- `date`: Date object or ISO string.
---
# Execution Environment & Globals
Applets run in an isolated worker thread pool sandbox.
- **Entry point**: Export an async function taking `applet_input`:
```javascript
module.exports = async function (applet_input) { ... };
```
- **No `require()` or `import`**: Attempting to import modules throws an error.
- **Pre-injected Globals**:
- `fetch(path, options)`: Authenticated `fetch` pre-configured with a JWT scoped to the current user and selected company. Use root-relative API routes, e.g. `fetch('/article/42000009')`.
- `fs` / `vfs`: Sandboxed VFS filesystem interface for reading/writing local company files.
- `ExcelJS`: Pre-injected spreadsheet library.
- `PDFDocument`: Pre-injected PDFKit library.
- `sharp`: Pre-injected image manipulation library.
- `crypto`: Node / WebCrypto API.
- `console.log(...)`: returned in the tool response
---
# Return Value & Typed CSV Mapping
The exported function must return:
- An **Array of row objects**: `[ { col1: 'val1', col2: 10 }, { col1: 'val2', col2: 20 } ]`
- Or a **Single row object**: `{ col1: 'val1', col2: 10 }` (treated as a 1-row table)
---
# Standard Applet Template
```javascript
// @applet-input-schema {"type":"object","properties":{"sku":{"type":"string","title":"Article SKU","description":"SKU to lookup"}},"required":["sku"]}
// @applet-output-schema sku:string;name:string;netPrice:number;tracked:boolean;brand:string
// @applet-description "Lorem ipsum"
module.exports = async function (applet_input) {
const sku = String(applet_input?.sku || '').trim();
if (!sku) {
throw new Error('Missing required parameter: sku');
}
const res = await fetch(`/article/${encodeURIComponent(sku)}`);
if (res.status === 404) throw new Error(`Article "${sku}" not found.`);
if (!res.ok) throw new Error(`GET /article/${sku} failed with status ${res.status}`);
const { article } = await res.json();
const price = (article.prices || [])[0];
console.log(`Found article ${article.sku}: ${article.name}`);
return [{
sku: article.sku,
name: article.name || '',
netPrice: price?.net ?? '',
tracked: Boolean(article.track_stock),
brand: article.brand?.name || ''
}];
};
```
---
# Common Implementation Patterns
### 1. Paging List Endpoints
Page using `offset` and `limit` until all items are loaded or `limit` is reached:
```javascript
const items = [];
let offset = 0;
while (true) {
const res = await fetch(`/order?offset=${offset}&limit=100`);
if (!res.ok) throw new Error(`Fetch failed: ${res.status}`);
const data = await res.json();
const page = data.orders || [];
items.push(...page);
offset += page.length;
if (page.length === 0 || offset >= (data.total ?? items.length)) break;
}
```
---
# Shipped Reference Applets
Pre-installed examples in the VFS root provide working reference code:
- `v1-article-lookup.applet.js`: Single entity lookup and key/value sheet generation.
- `v1-article-catalogue.applet.js`: Walking category trees and joining category article lists.
- `v1-category-inventory.applet.js`: Recursive tree flattening and depth calculation.
- `v1-delivery-register.applet.js`: Paged list fetching with batched detail requests.
- `v1-order-revenue-by-month.applet.js`: Paged order retrieval with calendar month aggregation.