Skip to content

Commit 9554185

Browse files
committed
docs: detailed expression language documentation
1 parent 98abfb6 commit 9554185

4 files changed

Lines changed: 390 additions & 62 deletions

File tree

docs/.vitepress/config.mts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ export default defineConfig({
6363
items: [
6464
{ text: 'Imported Executables', link: '/guides/generated-config' },
6565
{ text: 'Templates & Workflow Generation', link: '/guides/templating' },
66+
{ text: 'Expression Language', link: '/guides/expressions' },
6667
{ text: 'Advanced Workflows', link: '/guides/advanced' },
6768
{ text: 'Interactive UI', link: '/guides/interactive' },
6869
{ text: 'Integrations', link: '/guides/integrations' },

docs/guides/executables.md

Lines changed: 87 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ title: Executables
44

55
# Executables
66

7-
Executables are the building blocks of flow automation. They can be simple commands, complex multi-step workflows, HTTP requests, or even GUI applications.
7+
Executables are the building blocks of flow automation. They can be simple commands, complex multi-step workflows, HTTP requests, or even GUI applications.
88
This guide covers all executable types and configuration options.
99

1010
## Finding Executables
@@ -67,7 +67,7 @@ Customize executable behavior with environment variables or temporary files usin
6767

6868
> [!INFO]
6969
> Executables inherit environment variables from their parent executable, workspace, and system.
70-
>
70+
>
7171
> By default, values defined in the `.env` file at the workspace root are automatically loaded. This can be overriden
7272
> in the workspace configuration file with the `envFiles` field.
7373

@@ -87,15 +87,15 @@ executables:
8787
envKey: API_TOKEN
8888
- secretRef: production/database-url
8989
envKey: DATABASE_URL
90-
90+
9191
# Interactive prompts
9292
- prompt: "Which environment?"
9393
envKey: ENVIRONMENT
94-
94+
9595
# Static values
9696
- text: "production"
9797
envKey: DEPLOY_ENV
98-
98+
9999
# Env File (key=value format)
100100
- envFile: "development.env"
101101
- envFile: "staging.env"
@@ -127,13 +127,13 @@ executables:
127127
- pos: 1
128128
envKey: IMAGE_TAG
129129
required: true
130-
130+
131131
# Flag arguments
132132
- flag: publish
133133
envKey: PUBLISH
134134
type: bool
135135
default: false
136-
136+
137137
- flag: registry
138138
envKey: REGISTRY
139139
default: "docker.io"
@@ -179,19 +179,19 @@ executables:
179179
exec:
180180
cmd: npm run build
181181
dir: "./frontend" # Relative to flowfile
182-
182+
183183
- verb: clean
184184
name: downloads
185185
exec:
186186
cmd: rm -rf downloads/*
187187
dir: "~/Downloads" # User home directory
188-
188+
189189
- verb: deploy
190190
name: from-root
191191
exec:
192192
cmd: kubectl apply -f k8s/
193193
dir: "//" # Workspace root
194-
194+
195195
- verb: test
196196
name: isolated
197197
exec:
@@ -220,7 +220,7 @@ executables:
220220
name: app
221221
exec:
222222
cmd: npm run build && npm test
223-
223+
224224
- verb: deploy
225225
name: app
226226
exec:
@@ -299,12 +299,12 @@ executables:
299299
launch:
300300
uri: "$FLOW_WORKSPACE_PATH"
301301
app: "Visual Studio Code"
302-
302+
303303
- verb: open
304304
name: docs
305305
launch:
306306
uri: "https://flowexec.io"
307-
307+
308308
- verb: open
309309
name: note
310310
launch:
@@ -338,8 +338,7 @@ executables:
338338
timeout: 30s
339339
validStatusCodes: [200, 201]
340340
logResponse: true
341-
transformResponse: |
342-
"Deployment " + fromJSON(data)["status"]
341+
transformResponse: '"Deployed " + fromJSON(body)["status"]'
343342
responseFile:
344343
filename: "deploy-response.json"
345344
```
@@ -348,16 +347,51 @@ executables:
348347
- `method`: HTTP method (GET, POST, PUT, PATCH, DELETE)
349348
- `url`: Request URL (required)
350349
- `headers`: Custom headers
351-
- `body`: Request body with Expr templating
350+
- `body`: Request body
352351
- `timeout`: Request timeout
353352
- `validStatusCodes`: Acceptable status codes
354353
- `logResponse`: Log response body
355-
- `transformResponse`: Transform response with Expr templating
354+
- `transformResponse`: Expr expression to reshape the response before output or file save
356355
- `responseFile`: Save response to file
357356

357+
**Transforming responses with `transformResponse`:**
358+
359+
The `transformResponse` field is a single [Expr expression](./expressions) evaluated after the request completes. Its result replaces the raw response body in any output or `responseFile`. The expression has access to:
360+
361+
| Variable | Type | Description |
362+
|----------|------|-------------|
363+
| `body` | `string` | Raw response body |
364+
| `code` | `int` | HTTP status code (e.g. `200`, `404`) |
365+
| `status` | `string` | Full status line (e.g. `"200 OK"`) |
366+
| `headers` | `map[string][]string` | Response headers |
367+
368+
> [!NOTE]
369+
> `headers` is a `map[string][]string` — each name maps to a slice of values. Access the first value with `headers["Content-Type"][0]`, not `headers["Content-Type"]`.
370+
371+
Common patterns:
372+
373+
```yaml
374+
# Extract a field from a JSON body
375+
transformResponse: fromJSON(body)["name"]
376+
377+
# Uppercase a status field
378+
transformResponse: upper(fromJSON(body)["status"])
379+
380+
# Format an array as newline-separated output
381+
transformResponse: join(map(fromJSON(body)["items"], #["name"]), "\n")
382+
383+
# Conditional with fallback
384+
transformResponse: code == 200 ? fromJSON(body)["result"] : "error " + string(code) + ": " + body
385+
386+
# Let binding to avoid reparsing
387+
transformResponse: let data = fromJSON(body); data["id"] + " — " + data["name"]
388+
```
389+
390+
See the [Expression Language](./expressions) guide for the full syntax reference.
391+
358392
### render - Dynamic Documentation
359393

360-
Generate and display markdown with templates:
394+
Process a template file and display its output — useful for status dashboards, reports, and any dynamically-generated text:
361395

362396
```yaml
363397
executables:
@@ -368,25 +402,41 @@ executables:
368402
templateDataFile: "status-data.json"
369403
```
370404

371-
**Template file example:**
372-
```markdown
373-
# System Status
405+
**Options:**
406+
- `templateFile`: Markdown template file (required)
407+
- `templateDataFile`: JSON/YAML data file for the `data` variable
408+
- `dir`: Working directory
409+
- `params`: Environment variable definitions (available as `env["KEY"]`)
410+
411+
**Available template variables:**
374412

375-
Current time: {{ data["timestamp"] }}
413+
| Variable | Type | Description |
414+
|----------|------|-------------|
415+
| `env` | `map[string]string` | Params and environment variables from the executable |
416+
| `data` | `any` | Parsed contents of `templateDataFile` (nil if not set) |
376417

377-
## Services
378-
{{- range .services }}
379-
- **{{ .name }}**: {{ data["status"] }}
380-
{{- end }}
418+
`data` is typed based on the file content — a JSON object becomes a map, a JSON array becomes a slice. Access fields with bracket notation: `data["key"]` or `data[0]["field"]`.
381419

382-
## Metrics
383-
- CPU: {{ data["cpu"] }}%
384-
- Memory: {{ data["memory"] }}%
420+
**Template file example** — given a `status-data.json`:
421+
```json
422+
{"service": "api", "version": "2.1.0", "replicas": 3}
385423
```
386424

387-
**Options:**
388-
- `templateFile`: Markdown template file (required)
389-
- `templateDataFile`: JSON/YAML data file
425+
A `status-template.md` template:
426+
```markdown
427+
# Deployment Status
428+
429+
Service: {{ data["service"] }}
430+
Version: {{ data["version"] }}
431+
Replicas: {{ string(data["replicas"]) }}
432+
Environment: {{ env["DEPLOY_ENV"] }}
433+
434+
{{ if data["version"] != "" }}
435+
Last deployed: {{ data["version"] }}
436+
{{ end }}
437+
```
438+
439+
The template syntax uses `{{ expression }}` delimiters where expressions are evaluated using the [Expr language](./expressions). See the [Expression Language](./expressions) guide for syntax and built-ins.
390440

391441
## Importing Executables
392442

@@ -508,12 +558,12 @@ services:
508558
build: .
509559
ports:
510560
- "3000:3000"
511-
561+
512562
db:
513563
image: postgres:13
514564
environment:
515565
POSTGRES_DB: myapp
516-
566+
517567
redis:
518568
image: redis:6
519569
```
@@ -539,12 +589,12 @@ executables:
539589
name: api
540590
exec:
541591
cmd: docker build -t api .
542-
592+
543593
- verb: test
544594
name: api
545595
exec:
546596
cmd: npm test
547-
597+
548598
# Composite workflows
549599
- verb: deploy
550600
name: full
@@ -553,7 +603,7 @@ executables:
553603
- ref: build api
554604
- ref: test api
555605
- cmd: kubectl apply -f api.yaml
556-
606+
557607
# Cross-workspace references (requires public visibility)
558608
- verb: deploy
559609
name: with-monitoring

0 commit comments

Comments
 (0)