Documentation Index
Fetch the complete documentation index at: https://docs.gorules.io/llms.txt
Use this file to discover all available pages before exploring further.
Every node in a JDM file has a type that determines its behavior and content structure.
Available node types
| Type | Description |
|---|
inputNode | Entry point for decision input |
outputNode | Exit point returning the result |
decisionTableNode | Spreadsheet-style conditional logic |
expressionNode | ZEN expression transformations |
functionNode | Custom JavaScript logic |
switchNode | Conditional branching |
decisionNode | Sub-decision reference |
Common node properties
All nodes share these properties:
| Property | Type | Description |
|---|
id | string | Unique identifier |
type | string | Node type |
name | string | Display name |
position | object | Canvas position { x, y } |
content | object | Type-specific configuration |
The entry point for every decision. Receives the data you pass to evaluate().
{
"id": "input",
"type": "inputNode",
"name": "Request",
"position": { "x": 0, "y": 100 },
"content": {
"schema": ""
}
}
| Property | Type | Description |
|---|
schema | string | Optional JSON Schema for input validation |
Output node
The exit point that returns the decision result.
{
"id": "output",
"type": "outputNode",
"name": "Response",
"position": { "x": 600, "y": 100 },
"content": {
"schema": ""
}
}
| Property | Type | Description |
|---|
schema | string | Optional JSON Schema for output validation |
Decision table node
Spreadsheet-style conditional logic with inputs, outputs, and rules.
{
"type": "decisionTableNode",
"content": {
"hitPolicy": "first",
"inputs": [
{ "id": "i1", "name": "Customer Tier", "field": "customer.tier" },
{ "id": "i2", "name": "Order Total", "field": "order.total" }
],
"outputs": [
{ "id": "o1", "name": "Discount", "field": "discount" }
],
"rules": [
{ "_id": "r1", "i1": "\"gold\"", "i2": ">= 100", "o1": "0.15" },
{ "_id": "r2", "i1": "", "i2": "", "o1": "0" }
],
"passThrough": true,
"inputField": null,
"outputPath": null,
"executionMode": "single"
}
}
Content properties
| Property | Type | Default | Description |
|---|
hitPolicy | "first" | "collect" | "first" | Return first match or all matches |
inputs | array | | Input column definitions |
outputs | array | | Output column definitions |
rules | array | | Rule rows (keyed by column id) |
passThrough | boolean | true | Include input data in output |
inputField | string | null | null | Array field to iterate (for loop mode) |
outputPath | string | null | null | Path to store output |
executionMode | "single" | "loop" | "single" | Process once or iterate array |
| Property | Type | Description |
|---|
id | string | Unique identifier (used in rules) |
name | string | Display label |
field | string | Path to input value (enables unary mode) |
defaultValue | string | Default if field is null |
Output column
| Property | Type | Description |
|---|
id | string | Unique identifier (used in rules) |
name | string | Display label |
field | string | Output field name |
defaultValue | string | Default if no rule matches |
Each rule is an object with _id and entries keyed by column id:
{ "_id": "rule-1", "i1": ">= 100", "i2": "\"gold\"", "o1": "0.15" }
Leave a cell empty ("") to match any value.
Expression node
Transform data using ZEN expressions.
{
"type": "expressionNode",
"content": {
"expressions": [
{ "id": "e1", "key": "subtotal", "value": "sum(map(items, #.price * #.qty))" },
{ "id": "e2", "key": "tax", "value": "$.subtotal * 0.08" },
{ "id": "e3", "key": "total", "value": "$.subtotal + $.tax" }
],
"passThrough": true,
"inputField": null,
"outputPath": null,
"executionMode": "single"
}
}
Content properties
| Property | Type | Default | Description |
|---|
expressions | array | | Key-value expression pairs |
passThrough | boolean | true | Include input data in output |
inputField | string | null | null | Array field to iterate (for loop mode) |
outputPath | string | null | null | Path to store output |
executionMode | "single" | "loop" | "single" | Process once or iterate array |
Expression entry
| Property | Type | Description |
|---|
id | string | Unique identifier |
key | string | Output field name |
value | string | ZEN expression |
Use $ to reference values calculated earlier in the same node.
Function node
Custom JavaScript for complex logic.
{
"type": "functionNode",
"content": {
"source": "/** @type {Handler} */\nexport const handler = async (input) => {\n return { loyaltyPoints: Math.floor(input.total * 1.5) };\n}"
}
}
| Property | Type | Description |
|---|
source | string | JavaScript function code |
Function nodes support:
- ES6+ JavaScript syntax
async/await for asynchronous operations
- Built-in libraries:
dayjs, big.js, zod
Switch node
Route data through different paths based on conditions.
{
"type": "switchNode",
"content": {
"hitPolicy": "first",
"statements": [
{ "id": "s1", "condition": "customer.tier == 'enterprise'", "isDefault": false },
{ "id": "s2", "condition": "customer.tier == 'business'", "isDefault": false },
{ "id": "s3", "condition": "", "isDefault": true }
]
}
}
Content properties
| Property | Type | Default | Description |
|---|
hitPolicy | "first" | "collect" | "first" | Execute first match or all matches |
statements | array | | Branch conditions |
Statement
| Property | Type | Description |
|---|
id | string | Unique identifier (used as edge sourceHandle) |
condition | string | ZEN expression evaluating to boolean |
isDefault | boolean | True for the fallback branch |
Connecting switch outputs
Each statement id becomes a source handle for edges:
{
"edges": [
{ "id": "e1", "sourceId": "switch-1", "targetId": "enterprise-node", "sourceHandle": "s1", "type": "edge" },
{ "id": "e2", "sourceId": "switch-1", "targetId": "business-node", "sourceHandle": "s2", "type": "edge" },
{ "id": "e3", "sourceId": "switch-1", "targetId": "default-node", "sourceHandle": "s3", "type": "edge" }
]
}
Decision node
Reference another decision (sub-decision).
{
"type": "decisionNode",
"content": {
"key": "pricing/calculate-discount",
"passThrough": true,
"inputField": null,
"outputPath": null,
"executionMode": "single"
}
}
| Property | Type | Default | Description |
|---|
key | string | | Path to the referenced decision |
passThrough | boolean | true | Include input data in output |
inputField | string | null | null | Array field to iterate (for loop mode) |
outputPath | string | null | null | Path to store output |
executionMode | "single" | "loop" | "single" | Process once or iterate array |
Edge schema
Edges connect nodes in the graph:
{
"id": "edge-1",
"sourceId": "node-a",
"targetId": "node-b",
"sourceHandle": null,
"type": "edge"
}
| Property | Type | Description |
|---|
id | string | Unique identifier |
sourceId | string | Source node id |
targetId | string | Target node id |
sourceHandle | string | null | Output handle (for switch nodes) |
type | "edge" | Always “edge” |