0
# Expression Management
1
2
Core functionality for creating and evaluating JSONata expressions against JSON data.
3
4
## Capabilities
5
6
### JSONata Factory Function
7
8
Creates a JSONata expression object from a query string.
9
10
```javascript { .api }
11
/**
12
* Create a JSONata expression object
13
* @param expression - JSONata query expression string
14
* @param options - Optional configuration object
15
* @returns Expression object with evaluation methods
16
*/
17
function jsonata(expression, options);
18
```
19
20
**Parameters:**
21
- `expression` (string): JSONata query expression to parse
22
- `options` (object, optional): Configuration options
23
- `recover` (boolean, optional): Attempt to recover on parse errors
24
- `RegexEngine` (RegExp, optional): Custom regex engine constructor
25
26
**Returns:** Expression object with methods for evaluation and manipulation
27
28
**Usage Examples:**
29
30
```javascript
31
const jsonata = require("jsonata");
32
33
// Basic expression creation
34
const expr1 = jsonata("Account.Order[0].Product");
35
36
// With recovery option for error handling
37
const expr2 = jsonata("potentially.invalid[syntax", { recover: true });
38
39
// With custom regex engine
40
const expr3 = jsonata('$match(text, /pattern/)', { RegexEngine: MyRegExp });
41
```
42
43
### Expression Evaluation
44
45
Evaluates the expression against input data with optional variable bindings.
46
47
```javascript { .api }
48
/**
49
* Evaluate expression against input data
50
* @param input - Input data to evaluate against
51
* @param bindings - Optional variable bindings
52
* @param callback - Optional Node.js-style callback
53
* @returns Promise resolving to evaluation result, or calls callback
54
*/
55
evaluate(input: any, bindings?: Record<string, any>): Promise<any>;
56
evaluate(input: any, bindings: Record<string, any> | undefined, callback: (err: JsonataError, resp: any) => void): void;
57
```
58
59
**Parameters:**
60
- `input` (any): Input data to evaluate the expression against
61
- `bindings` (object, optional): Object containing variable name-value pairs
62
- `callback` (function, optional): Node.js-style callback `(error, result) => void`
63
64
**Returns:** Promise<any> when used without callback, or calls callback with result
65
66
**Usage Examples:**
67
68
```javascript
69
const data = {
70
users: [
71
{ name: "Alice", age: 30 },
72
{ name: "Bob", age: 25 }
73
]
74
};
75
76
// Basic evaluation
77
const expr = jsonata("users[age > 25].name");
78
const result = await expr.evaluate(data); // ["Alice"]
79
80
// With variable bindings
81
const expr2 = jsonata("users[age > $threshold].name");
82
const result2 = await expr2.evaluate(data, { threshold: 27 }); // ["Alice"]
83
84
// With callback (Node.js style)
85
expr.evaluate(data, {}, (err, result) => {
86
if (err) {
87
console.error("Evaluation error:", err);
88
} else {
89
console.log("Result:", result);
90
}
91
});
92
```
93
94
### Variable Assignment
95
96
Assigns a variable in the expression's evaluation environment.
97
98
```javascript { .api }
99
/**
100
* Assign a variable in the expression environment
101
* @param name - Variable name
102
* @param value - Variable value
103
*/
104
assign(name: string, value: any): void;
105
```
106
107
**Parameters:**
108
- `name` (string): Variable name to assign
109
- `value` (any): Value to assign to the variable
110
111
**Usage Examples:**
112
113
```javascript
114
const expr = jsonata("$greeting & ' ' & name & '!'");
115
116
expr.assign("greeting", "Hello");
117
const result = await expr.evaluate({ name: "World" }); // "Hello World!"
118
119
// Multiple assignments
120
expr.assign("prefix", "Mr.");
121
expr.assign("suffix", "Esq.");
122
```
123
124
### Function Registration
125
126
Registers a custom function in the expression's evaluation environment.
127
128
```javascript { .api }
129
/**
130
* Register a custom function in the expression environment
131
* @param name - Function name
132
* @param implementation - Function implementation
133
* @param signature - Optional function signature for validation
134
*/
135
registerFunction(name: string, implementation: Function, signature?: string): void;
136
```
137
138
**Parameters:**
139
- `name` (string): Function name (will be callable as `$name` in expressions)
140
- `implementation` (function): Function implementation
141
- `signature` (string, optional): Function signature for parameter validation
142
143
**Usage Examples:**
144
145
```javascript
146
// Register a simple function
147
expr.registerFunction("double", (x) => x * 2);
148
// Now usable as: $double(5) returns 10
149
150
// Register function with signature validation
151
expr.registerFunction("add", (a, b) => a + b, "<nn:n>");
152
// Signature: takes two numbers, returns number
153
154
// Register async function
155
expr.registerFunction("delay", async (ms) => {
156
await new Promise(resolve => setTimeout(resolve, ms));
157
return "completed";
158
});
159
160
// Function with access to evaluation context
161
expr.registerFunction("contextAware", function(value) {
162
// 'this' refers to Focus object with environment and input
163
const input = this.input;
164
const env = this.environment;
165
return { value, hasInput: input !== undefined };
166
});
167
```
168
169
### AST Access
170
171
Returns the abstract syntax tree of the parsed expression.
172
173
```javascript { .api }
174
/**
175
* Get the abstract syntax tree of the expression
176
* @returns ExprNode representing the parsed expression
177
*/
178
ast(): ExprNode;
179
```
180
181
**Returns:** ExprNode object representing the expression's AST
182
183
**Usage Examples:**
184
185
```javascript
186
const expr = jsonata("users[0].name");
187
const ast = expr.ast();
188
189
console.log(ast.type); // "path"
190
console.log(ast.steps); // Array of path steps
191
192
// Useful for expression analysis and debugging
193
function analyzeExpression(expression) {
194
const expr = jsonata(expression);
195
const ast = expr.ast();
196
return {
197
type: ast.type,
198
complexity: countNodes(ast),
199
hasVariables: hasVariableReferences(ast)
200
};
201
}
202
```
203
204
### Error Access
205
206
Returns any parse errors from the expression compilation.
207
208
```javascript { .api }
209
/**
210
* Get parse errors from expression compilation
211
* @returns Array of errors or undefined if no errors
212
*/
213
errors(): any;
214
```
215
216
**Returns:** Array of error objects or undefined if expression parsed successfully
217
218
**Usage Examples:**
219
220
```javascript
221
// Check for parse errors
222
const expr = jsonata("invalid[syntax");
223
const errors = expr.errors();
224
225
if (errors) {
226
errors.forEach(error => {
227
console.log(`Error at position ${error.position}: ${error.message}`);
228
});
229
} else {
230
console.log("Expression parsed successfully");
231
}
232
233
// Error handling workflow
234
function createSafeExpression(expressionStr) {
235
try {
236
const expr = jsonata(expressionStr);
237
const errors = expr.errors();
238
239
if (errors) {
240
throw new Error(`Parse errors: ${errors.map(e => e.message).join(", ")}`);
241
}
242
243
return expr;
244
} catch (error) {
245
console.error("Failed to create expression:", error.message);
246
return null;
247
}
248
}
249
```
250
251
## Types
252
253
```javascript { .api }
254
interface JsonataOptions {
255
recover?: boolean; // Attempt to recover on parse errors
256
RegexEngine?: RegExp; // Custom regex engine constructor
257
}
258
259
interface Expression {
260
evaluate(input: any, bindings?: object, callback?: function): Promise<any>;
261
assign(name: string, value: any): void;
262
registerFunction(name: string, implementation: function, signature?: string): void;
263
ast(): ExprNode;
264
errors(): JsonataError[] | undefined;
265
}
266
267
interface ExprNode {
268
type: string;
269
value?: any;
270
position?: number;
271
arguments?: ExprNode[];
272
name?: string;
273
procedure?: ExprNode;
274
steps?: ExprNode[];
275
expressions?: ExprNode[];
276
stages?: ExprNode[];
277
lhs?: ExprNode | ExprNode[];
278
rhs?: ExprNode;
279
}
280
281
interface JsonataError {
282
code: string;
283
position: number;
284
token: string;
285
message: string;
286
}
287
288
interface Focus {
289
environment: Environment;
290
input: any;
291
}
292
293
interface Environment {
294
bind(name: string | symbol, value: any): void;
295
lookup(name: string | symbol): any;
296
timestamp: Date;
297
async: boolean;
298
}
299
```