Examples
The examples/ folder of the FlowForger repository holds ready-to-run flows. Each folder has one or more .ff.ts files (the DSL source) and a README that explains what the flow shows and how to run it. IR and Logic Apps JSON are generated by the CLI on demand and are not committed.
Running an example
Clone the repository and run the flow file directly. The CLI compiles .ff.ts on the fly:
git clone https://github.com/tomdam/flowforger.git
cd flowforger
# Published CLI via npx, no install
npx flowforger run examples/hello-flow/flow.ff.ts
# Or a global install
npm install -g flowforger
flowforger run examples/hello-flow/flow.ff.ts
Add flags as an example needs them: --in payload.json for the trigger body, --vars vars.json or --var name=value for variables, and --auth for connector examples. Each example's README lists its exact commands.
Start here (no credentials needed)
- hello-flow: the "hello world": manual trigger, Compose, an HTTP call, and the echoed response.
- control-flow: scope, if/else and foreach in one small offline flow.
- builtin-actions: variables, data operations, CSV and HTML tables, delay, and a Response per branch.
- expression-functions:
outputs()vsbody()vsactions(), trigger and parameter reads, property paths, and typed helpers next to raw expressions. - recurrence-trigger: a scheduled flow with frequency, schedule and time zone.
What FlowForger adds
- child-flows: a parent and three child flows written in the DSL, run offline with one command. Shows what the parent gets back from a child, try/catch/finally around a failing child, mocks, and the deploy order.
- local-testing:
--stop-before,--mock,--mocks,--liveand--replay-runagainst one flow, to inspect a write without sending it. The Local testing guide walks through it. - advanced-actions: nested loops, array variables, JSON parsing, switch, try/catch/finally inside a loop, and do-until.
- optimizer:
flowforger optimizebefore and after, with the variable-to-Compose and loop-append-to-Select rewrites. - odata-tagged-template: an OData
$filterwritten with a builder API or as a tagged template with TypeScript operators.
Connectors (need a tenant)
- sharepoint: SharePoint operations on items, files, folders, attachments, sharing links, approval and version control, one flow per operation or workflow.
- dataverse: create, list, update and delete rows, upsert, relationships, batch operations, search, file columns and custom actions.
- unreplied-emails: Office 365 Outlook: compares the inbox with sent items by conversation id and mails an HTML summary, driven by flow parameters.
- office365groups: lists groups and their members.
Pointing a connector example at your tenant
Connector examples open their run() method with a configuration block. Edit the values to match your environment:
// Configuration for this example - edit to point at your own tenant.
let siteUrl = "https://contoso.sharepoint.com/sites/MySite";
let listId = "aaaaaaaa-1111-2222-3333-444444444444";
| Value | Where to find it |
|---|---|
siteUrl | The site's address in the browser, up to and including the site name |
listId / libraryId | The List parameter in the list settings URL, or run examples/sharepoint/get-lists.ff.ts |
fileId | examples/sharepoint/get-files-properties-only.ff.ts returns each file's UniqueId |
recordId (Dataverse) | The id parameter in the record's URL in the model-driven app |
Then run with --auth and a flowforger.config.json that has an auth section (see App registration):
npx flowforger run examples/dataverse/list-rows.ff.ts --auth
flowforger scopes <flow>.ff.ts lists the permissions a flow needs before you run it.
A configuration block is fine for trying an example. In a flow you keep, prefer a flow parameter bound to an environment variable, or values from the trigger payload. With --auth, a local run resolves environment-variable-backed parameters to the environment's current values, and --param "<key>=<value>" overrides one.