An open API service indexing awesome lists of open source software.

https://github.com/excelano/paxc

A compiler for the pax DSL, producing Power Automate cloud flow definitions
https://github.com/excelano/paxc

Last synced: about 1 month ago
JSON representation

A compiler for the pax DSL, producing Power Automate cloud flow definitions

Awesome Lists containing this project

README

          

# paxc — the pax compiler

`paxc` compiles the **pax** DSL into [Power Automate](https://powerautomate.microsoft.com/) cloud flow definitions. Write terse, readable code; get the verbose `definition.json` that Power Automate expects. Companion interpreter `paxr` runs the same source locally for fast iteration.

For the full language reference, see [REFERENCE.md](REFERENCE.md).

3.6.0 shipped. Every construct listed in REFERENCE.md is implemented and tested, end-to-end deployment to Power Automate has been validated, and a legacy-format package target lets you import compiled flows directly through the Power Automate portal. Round-trip ingest from real PA exports is meaningfully complete: `paxc --decode ` reads an exported PA flow JSON and writes a `.pax` source file plus a `pa/` folder. Variables, Compose, container actions (`if`/`foreach`/`until`/`switch`/`scope`), `on` error-path handlers, `terminate`, and PA expressions including the standard accessors (`triggerBody()`, `triggerOutputs()`, `parameters('X')`, `body('Foo')`, `iterationIndexes('Loop')`, etc.) and slash- or index-style path expressions (`triggerBody()?["body/email"]`, `arr?[0]`) all round-trip to pax source. PA action keys with characters outside pax's identifier rules (e.g. `Send_an_email_(V2)`) are normalized on decode and restored byte-for-byte on re-encode via `pa/flow.json.actionNameMap`. Connectors (`OpenApiConnection`, `OpenApiConnectionWebhook`, `ParseJson`, etc.) stay opaque as `pa ` blocks with their bodies in the `pa/` folder — the design endpoint, not a residual gap.

3.0.0 reflected a strategic reframing of the language: round-trip from existing PA flows is now the primary forward direction. Connector bodies, ParseJson, and any non-default trigger live in JSON files next to the source under a `pa/` folder. pax owns the programmable parts (variables, control flow, expressions); files own the PA-specific parts. The `raw{}` escape hatch and the `trigger ...` syntax are gone, replaced by the file convention.

## Why

The Power Automate browser designer is slow and click-heavy. The underlying flow definition is JSON that's technically hand-editable but structured in ways that fight you: actions are a map keyed by name, dependencies are encoded as a `runAfter` graph, and expressions live inside escaped strings. pax is a small DSL that turns all of that into source code you can actually read and maintain, and `paxc` is the compiler that emits the JSON.

Equivalent pax and JSON for initializing a counter:

```
var counter: int = 1
```

```json
{
"Initialize_counter": {
"type": "InitializeVariable",
"inputs": {
"variables": [
{ "name": "counter", "type": "Integer", "value": 1 }
]
},
"runAfter": {}
}
}
```

The source is shorter, and more importantly, the `runAfter` dependency graph is inferred from source order so you never hand-wire it.

## What pax covers

The language supports typed variables and `let` Compose bindings; assignment and compound assignment; arithmetic, boolean, and string concatenation expressions; member access; `if`/`else if`/`else`, `foreach`, `until`, `switch`, `scope`, `terminate`, and `on ` error-path handlers; function calls that pass through to Power Automate's expression language; a `pa ` primitive for any PA-shaped action whose body lives in `pa/.json` next to the source (connectors, ParseJson, anything PA-designer-shaped); and a `debug()` statement that paxr prints at runtime and paxc strips at compile time.

Triggers are file-based: drop a single `pa/.trigger.json` next to the source to pick the trigger; without one, paxc generates a default manual ("Button") trigger. Connection references go in `pa/connectionReferences.json` and end up at the flow's top level on emit.

## Install

The fastest path on Linux or macOS is the prebuilt-binary installer:

```sh
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/excelano/paxc/releases/latest/download/paxc-installer.sh | sh
```

On Windows, in PowerShell:

```powershell
powershell -ExecutionPolicy ByPass -c "irm https://github.com/excelano/paxc/releases/latest/download/paxc-installer.ps1 | iex"
```

The installer downloads the right tarball for your platform from the GitHub release, verifies its checksum, and drops both `paxc` and `paxr` into `~/.cargo/bin` (or the equivalent on Windows). Releases also ship raw tarballs (`paxc-*.tar.xz` / `.zip`) for manual installation.

### Debian and Ubuntu

If you've added the Excelano apt repository, paxc is also available as a `.deb`:

```bash
sudo apt install paxc
```

To add the repository (one-time setup):

```bash
curl -fsSL https://excelano.com/apt/setup.sh | sudo sh
```

Both `paxc` and `paxr` are installed into `/usr/bin/`, with reference docs at `/usr/share/doc/paxc/`. Supported architectures: `amd64`, `arm64`.

### Build from source

Requires Rust (edition 2024, toolchain 1.85+). If you don't have Rust, install it first via [rustup](https://rustup.rs).

```sh
cargo install --git https://github.com/excelano/paxc
```

This builds both `paxc` and `paxr` and places them in `~/.cargo/bin/`. Alternatively:

```sh
git clone https://github.com/excelano/paxc
cd paxc
cargo build --release
```

The binaries will be at `target/release/paxc` and `target/release/paxr`.

## License

MIT. See [LICENSE](LICENSE).