wasm-cel 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +348 -29
- package/dist/index.d.ts +56 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +180 -2
- package/dist/index.js.map +1 -1
- package/dist/options/astValidators.d.ts +135 -0
- package/dist/options/astValidators.d.ts.map +1 -0
- package/dist/options/astValidators.js +79 -0
- package/dist/options/astValidators.js.map +1 -0
- package/dist/options/base.d.ts +51 -0
- package/dist/options/base.d.ts.map +1 -0
- package/dist/options/base.js +5 -0
- package/dist/options/base.js.map +1 -0
- package/dist/options/crossTypeNumericComparisons.d.ts +56 -0
- package/dist/options/crossTypeNumericComparisons.d.ts.map +1 -0
- package/dist/options/crossTypeNumericComparisons.js +41 -0
- package/dist/options/crossTypeNumericComparisons.js.map +1 -0
- package/dist/options/index.d.ts +11 -0
- package/dist/options/index.d.ts.map +1 -0
- package/dist/options/index.js +8 -0
- package/dist/options/index.js.map +1 -0
- package/dist/options/optionalTypes.d.ts +28 -0
- package/dist/options/optionalTypes.d.ts.map +1 -0
- package/dist/options/optionalTypes.js +21 -0
- package/dist/options/optionalTypes.js.map +1 -0
- package/dist/options/options.d.ts +105 -0
- package/dist/options/options.d.ts.map +1 -0
- package/dist/options/options.js +105 -0
- package/dist/options/options.js.map +1 -0
- package/dist/options.d.ts +78 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/options.js +28 -0
- package/dist/options.js.map +1 -0
- package/dist/types.d.ts +33 -0
- package/dist/types.d.ts.map +1 -1
- package/main.wasm +0 -0
- package/package.json +11 -4
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# wasm-cel
|
|
2
2
|
|
|
3
|
-
WebAssembly module for evaluating CEL (Common Expression Language) expressions
|
|
3
|
+
WebAssembly module for evaluating CEL (Common Expression Language) expressions
|
|
4
|
+
in Node.js.
|
|
4
5
|
|
|
5
6
|
## Installation
|
|
6
7
|
|
|
@@ -14,7 +15,8 @@ yarn add wasm-cel
|
|
|
14
15
|
|
|
15
16
|
## Usage
|
|
16
17
|
|
|
17
|
-
The library follows the CEL pattern: create an environment, compile an
|
|
18
|
+
The library follows the CEL pattern: create an environment, compile an
|
|
19
|
+
expression, and then evaluate it:
|
|
18
20
|
|
|
19
21
|
```typescript
|
|
20
22
|
import { Env } from "wasm-cel";
|
|
@@ -48,17 +50,222 @@ const result3 = await program2.eval({ name: "Alice", age: 30 });
|
|
|
48
50
|
console.log(result3); // "Alice is 30 years old"
|
|
49
51
|
```
|
|
50
52
|
|
|
53
|
+
## CEL Environment Options
|
|
54
|
+
|
|
55
|
+
The library supports configurable CEL environment options to enable additional
|
|
56
|
+
CEL features. Options can be provided during environment creation or added later
|
|
57
|
+
using the `extend()` method.
|
|
58
|
+
|
|
59
|
+
### Available Options
|
|
60
|
+
|
|
61
|
+
#### OptionalTypes
|
|
62
|
+
|
|
63
|
+
Enables support for optional syntax and types in CEL, including optional field
|
|
64
|
+
access (`obj.?field`), optional indexing (`list[?0]`), and optional value
|
|
65
|
+
creation (`optional.of(value)`).
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { Env, Options } from "wasm-cel";
|
|
69
|
+
|
|
70
|
+
const env = await Env.new({
|
|
71
|
+
variables: [
|
|
72
|
+
{
|
|
73
|
+
name: "data",
|
|
74
|
+
type: { kind: "map", keyType: "string", valueType: "string" },
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
options: [Options.optionalTypes()],
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const program = await env.compile('data.?name.orValue("Anonymous")');
|
|
81
|
+
const result = await program.eval({ data: {} });
|
|
82
|
+
console.log(result); // "Anonymous"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
#### ASTValidators
|
|
86
|
+
|
|
87
|
+
Enables custom validation rules during CEL expression compilation. Validators
|
|
88
|
+
can report errors, warnings, or info messages that are collected during
|
|
89
|
+
compilation and can prevent compilation or provide detailed feedback.
|
|
90
|
+
|
|
91
|
+
**Location Information**: Each AST node provides accurate location information
|
|
92
|
+
through `nodeData.location` with `line` and `column` properties, enabling
|
|
93
|
+
precise error reporting.
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
import { Env, Options } from "wasm-cel";
|
|
97
|
+
|
|
98
|
+
const env = await Env.new({
|
|
99
|
+
variables: [
|
|
100
|
+
{
|
|
101
|
+
name: "user",
|
|
102
|
+
type: { kind: "map", keyType: "string", valueType: "string" },
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
options: [
|
|
106
|
+
Options.astValidators({
|
|
107
|
+
validators: [
|
|
108
|
+
// Validator that warns about accessing potentially unsafe fields
|
|
109
|
+
(nodeType, nodeData, context) => {
|
|
110
|
+
if (nodeType === "select" && nodeData.field === "password") {
|
|
111
|
+
return {
|
|
112
|
+
issues: [
|
|
113
|
+
{
|
|
114
|
+
severity: "warning",
|
|
115
|
+
message: "Accessing password field may not be secure",
|
|
116
|
+
location: nodeData.location, // Precise location from AST
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
// Validator that prevents certain function calls
|
|
123
|
+
(nodeType, nodeData, context) => {
|
|
124
|
+
if (
|
|
125
|
+
nodeType === "call" &&
|
|
126
|
+
nodeData.function === "dangerousFunction"
|
|
127
|
+
) {
|
|
128
|
+
return {
|
|
129
|
+
issues: [
|
|
130
|
+
{
|
|
131
|
+
severity: "error",
|
|
132
|
+
message: "Use of dangerousFunction is not allowed",
|
|
133
|
+
location: nodeData.location, // Precise location from AST
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
options: {
|
|
141
|
+
failOnWarning: false, // Don't fail compilation on warnings
|
|
142
|
+
includeWarnings: true, // Include warnings in results
|
|
143
|
+
},
|
|
144
|
+
}),
|
|
145
|
+
],
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// Use compileDetailed() to see validation issues
|
|
149
|
+
const result = await env.compileDetailed("user.password");
|
|
150
|
+
if (result.success) {
|
|
151
|
+
console.log("Compiled with issues:", result.issues);
|
|
152
|
+
// Example issue: { severity: "warning", message: "...", location: { line: 1, column: 5 } }
|
|
153
|
+
const evalResult = await result.program.eval({
|
|
154
|
+
user: { password: "secret" },
|
|
155
|
+
});
|
|
156
|
+
} else {
|
|
157
|
+
console.log("Compilation failed:", result.error);
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Available Node Types and Data:**
|
|
162
|
+
|
|
163
|
+
- **`select`**: Field access (`obj.field`)
|
|
164
|
+
- `nodeData.field`: Field name
|
|
165
|
+
- `nodeData.testOnly`: Whether it's a test-only access
|
|
166
|
+
- `nodeData.location`: Position in source
|
|
167
|
+
- **`call`**: Function calls (`func(args)`)
|
|
168
|
+
- `nodeData.function`: Function name
|
|
169
|
+
- `nodeData.argCount`: Number of arguments
|
|
170
|
+
- `nodeData.hasTarget`: Whether it's a method call
|
|
171
|
+
- `nodeData.location`: Position in source
|
|
172
|
+
- **`literal`**: Literal values (`"string"`, `42`, `true`)
|
|
173
|
+
- `nodeData.value`: The literal value
|
|
174
|
+
- `nodeData.type`: Type name
|
|
175
|
+
- `nodeData.location`: Position in source
|
|
176
|
+
- **`ident`**: Variable references (`varName`)
|
|
177
|
+
- `nodeData.name`: Variable name
|
|
178
|
+
- `nodeData.location`: Position in source
|
|
179
|
+
- **`list`**: List literals (`[1, 2, 3]`)
|
|
180
|
+
- `nodeData.elementCount`: Number of elements
|
|
181
|
+
- `nodeData.location`: Position in source
|
|
182
|
+
- **`map`**: Map literals (`{"key": "value"}`)
|
|
183
|
+
- `nodeData.entryCount`: Number of entries
|
|
184
|
+
- `nodeData.location`: Position in source
|
|
185
|
+
|
|
186
|
+
#### CrossTypeNumericComparisons
|
|
187
|
+
|
|
188
|
+
Enables cross-type numeric comparisons for ordering operators (`<`, `<=`, `>`,
|
|
189
|
+
`>=`). This allows comparing values of different numeric types like
|
|
190
|
+
`double > int` or `int <= double`. Note that this only affects ordering
|
|
191
|
+
operators, not equality operators (`==`, `!=`).
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
import { Env, Options } from "wasm-cel";
|
|
195
|
+
|
|
196
|
+
const env = await Env.new({
|
|
197
|
+
variables: [
|
|
198
|
+
{ name: "doubleValue", type: "double" },
|
|
199
|
+
{ name: "intValue", type: "int" },
|
|
200
|
+
],
|
|
201
|
+
options: [Options.crossTypeNumericComparisons()],
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// Now you can use cross-type ordering comparisons:
|
|
205
|
+
const program = await env.compile("doubleValue > intValue");
|
|
206
|
+
const result = await program.eval({ doubleValue: 3.14, intValue: 3 });
|
|
207
|
+
console.log(result); // true
|
|
208
|
+
|
|
209
|
+
// Works with all ordering operators
|
|
210
|
+
const program2 = await env.compile("intValue <= doubleValue + 1.0");
|
|
211
|
+
const result2 = await program2.eval({ doubleValue: 2.5, intValue: 3 });
|
|
212
|
+
console.log(result2); // true
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Adding Options After Creation
|
|
216
|
+
|
|
217
|
+
You can also extend an environment with options after it's created:
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
const env = await Env.new({
|
|
221
|
+
variables: [
|
|
222
|
+
{
|
|
223
|
+
name: "data",
|
|
224
|
+
type: { kind: "map", keyType: "string", valueType: "string" },
|
|
225
|
+
},
|
|
226
|
+
],
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Add options later
|
|
230
|
+
await env.extend([Options.optionalTypes()]);
|
|
231
|
+
|
|
232
|
+
const program = await env.compile('data.?greeting.orValue("Hello")');
|
|
233
|
+
const result = await program.eval({ data: {} });
|
|
234
|
+
console.log(result); // "Hello"
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Complex Options with Setup
|
|
238
|
+
|
|
239
|
+
The library supports an inverted architecture where complex options can handle
|
|
240
|
+
their own JavaScript-side setup operations. This enables options that need to
|
|
241
|
+
register custom functions or perform other setup tasks.
|
|
242
|
+
|
|
243
|
+
**Architecture Benefits:**
|
|
244
|
+
|
|
245
|
+
- Options handle their own complexity and setup operations
|
|
246
|
+
- Environment class stays simple and focused
|
|
247
|
+
- Easy to add new complex options without modifying core code
|
|
248
|
+
- Clean separation of concerns
|
|
249
|
+
|
|
250
|
+
Complex options implement the `OptionWithSetup` interface and can perform setup
|
|
251
|
+
operations before being applied to the environment.
|
|
252
|
+
|
|
51
253
|
## API
|
|
52
254
|
|
|
53
255
|
### `Env.new(options?: EnvOptions): Promise<Env>`
|
|
54
256
|
|
|
55
|
-
Creates a new CEL environment with variable declarations
|
|
257
|
+
Creates a new CEL environment with variable declarations, optional function
|
|
258
|
+
definitions, and CEL environment options.
|
|
56
259
|
|
|
57
260
|
**Parameters:**
|
|
58
261
|
|
|
59
262
|
- `options` (EnvOptions, optional): Options including:
|
|
60
|
-
- `variables` (VariableDeclaration[], optional): Array of variable
|
|
61
|
-
|
|
263
|
+
- `variables` (VariableDeclaration[], optional): Array of variable
|
|
264
|
+
declarations with name and type
|
|
265
|
+
- `functions` (CELFunctionDefinition[], optional): Array of custom function
|
|
266
|
+
definitions
|
|
267
|
+
- `options` (EnvOptionInput[], optional): Array of CEL environment options
|
|
268
|
+
(like OptionalTypes)
|
|
62
269
|
|
|
63
270
|
**Returns:**
|
|
64
271
|
|
|
@@ -67,10 +274,18 @@ Creates a new CEL environment with variable declarations and optional function d
|
|
|
67
274
|
**Example:**
|
|
68
275
|
|
|
69
276
|
```typescript
|
|
277
|
+
import { Env, Options } from "wasm-cel";
|
|
278
|
+
|
|
70
279
|
const env = await Env.new({
|
|
71
280
|
variables: [
|
|
72
281
|
{ name: "x", type: "int" },
|
|
73
|
-
{
|
|
282
|
+
{
|
|
283
|
+
name: "data",
|
|
284
|
+
type: { kind: "map", keyType: "string", valueType: "string" },
|
|
285
|
+
},
|
|
286
|
+
],
|
|
287
|
+
options: [
|
|
288
|
+
Options.optionalTypes(), // Enable optional syntax like data.?field
|
|
74
289
|
],
|
|
75
290
|
});
|
|
76
291
|
```
|
|
@@ -93,9 +308,75 @@ Compiles a CEL expression in the environment.
|
|
|
93
308
|
const program = await env.compile("x + 10");
|
|
94
309
|
```
|
|
95
310
|
|
|
311
|
+
### `env.compileDetailed(expr: string): Promise<CompilationResult>`
|
|
312
|
+
|
|
313
|
+
Compiles a CEL expression with detailed results including warnings and
|
|
314
|
+
validation issues. This method is particularly useful when using ASTValidators
|
|
315
|
+
or when you need comprehensive feedback about the compilation process.
|
|
316
|
+
|
|
317
|
+
**Parameters:**
|
|
318
|
+
|
|
319
|
+
- `expr` (string): The CEL expression to compile
|
|
320
|
+
|
|
321
|
+
**Returns:**
|
|
322
|
+
|
|
323
|
+
- `Promise<CompilationResult>`: A promise that resolves to detailed compilation
|
|
324
|
+
results with:
|
|
325
|
+
- `success` (boolean): Whether compilation succeeded
|
|
326
|
+
- `error` (string, optional): Error message if compilation failed completely
|
|
327
|
+
- `issues` (CompilationIssue[]): All issues found during compilation (errors,
|
|
328
|
+
warnings, info)
|
|
329
|
+
- `program` (Program, optional): The compiled program if compilation succeeded
|
|
330
|
+
|
|
331
|
+
**Example:**
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
const result = await env.compileDetailed("user.password");
|
|
335
|
+
if (result.success) {
|
|
336
|
+
console.log("Compiled successfully");
|
|
337
|
+
if (result.issues.length > 0) {
|
|
338
|
+
console.log("Validation issues:", result.issues);
|
|
339
|
+
// Example issue: { severity: "warning", message: "Accessing password field may not be secure" }
|
|
340
|
+
}
|
|
341
|
+
const evalResult = await result.program.eval({
|
|
342
|
+
user: { password: "secret" },
|
|
343
|
+
});
|
|
344
|
+
} else {
|
|
345
|
+
console.log("Compilation failed:", result.error);
|
|
346
|
+
console.log("All issues:", result.issues);
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### `env.extend(options: EnvOptionInput[]): Promise<void>`
|
|
351
|
+
|
|
352
|
+
Extends the environment with additional CEL environment options after creation.
|
|
353
|
+
|
|
354
|
+
**Parameters:**
|
|
355
|
+
|
|
356
|
+
- `options` (EnvOptionInput[]): Array of CEL environment option configurations
|
|
357
|
+
or complex options with setup
|
|
358
|
+
|
|
359
|
+
**Returns:**
|
|
360
|
+
|
|
361
|
+
- `Promise<void>`: A promise that resolves when the environment has been
|
|
362
|
+
extended
|
|
363
|
+
|
|
364
|
+
**Example:**
|
|
365
|
+
|
|
366
|
+
```typescript
|
|
367
|
+
const env = await Env.new({
|
|
368
|
+
variables: [{ name: "x", type: "int" }],
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
// Add options after creation
|
|
372
|
+
await env.extend([Options.optionalTypes()]);
|
|
373
|
+
```
|
|
374
|
+
|
|
96
375
|
### `env.typecheck(expr: string): Promise<TypeCheckResult>`
|
|
97
376
|
|
|
98
|
-
Typechecks a CEL expression in the environment without compiling it. This is
|
|
377
|
+
Typechecks a CEL expression in the environment without compiling it. This is
|
|
378
|
+
useful for validating expressions and getting type information before
|
|
379
|
+
compilation.
|
|
99
380
|
|
|
100
381
|
**Parameters:**
|
|
101
382
|
|
|
@@ -103,7 +384,8 @@ Typechecks a CEL expression in the environment without compiling it. This is use
|
|
|
103
384
|
|
|
104
385
|
**Returns:**
|
|
105
386
|
|
|
106
|
-
- `Promise<TypeCheckResult>`: A promise that resolves to type information with a
|
|
387
|
+
- `Promise<TypeCheckResult>`: A promise that resolves to type information with a
|
|
388
|
+
`type` property containing the inferred type
|
|
107
389
|
|
|
108
390
|
**Example:**
|
|
109
391
|
|
|
@@ -141,7 +423,8 @@ Evaluates the compiled program with the given variables.
|
|
|
141
423
|
|
|
142
424
|
**Parameters:**
|
|
143
425
|
|
|
144
|
-
- `vars` (Record<string, any> | null, optional): Variables to use in the
|
|
426
|
+
- `vars` (Record<string, any> | null, optional): Variables to use in the
|
|
427
|
+
evaluation. Defaults to `null`.
|
|
145
428
|
|
|
146
429
|
**Returns:**
|
|
147
430
|
|
|
@@ -155,9 +438,13 @@ const result = await program.eval({ x: 5 });
|
|
|
155
438
|
|
|
156
439
|
### `env.destroy(): void`
|
|
157
440
|
|
|
158
|
-
Destroys the environment and marks it as destroyed. After calling `destroy()`,
|
|
441
|
+
Destroys the environment and marks it as destroyed. After calling `destroy()`,
|
|
442
|
+
you cannot create new programs or typecheck expressions with this environment.
|
|
443
|
+
However, programs that were already created from this environment will continue
|
|
444
|
+
to work until they are destroyed themselves.
|
|
159
445
|
|
|
160
|
-
**Note:** This method is idempotent - calling it multiple times is safe and has
|
|
446
|
+
**Note:** This method is idempotent - calling it multiple times is safe and has
|
|
447
|
+
no effect after the first call.
|
|
161
448
|
|
|
162
449
|
**Example:**
|
|
163
450
|
|
|
@@ -178,9 +465,11 @@ console.log(result); // 30
|
|
|
178
465
|
|
|
179
466
|
### `program.destroy(): void`
|
|
180
467
|
|
|
181
|
-
Destroys the compiled program and frees associated WASM resources. After calling
|
|
468
|
+
Destroys the compiled program and frees associated WASM resources. After calling
|
|
469
|
+
`destroy()`, you cannot evaluate the program anymore.
|
|
182
470
|
|
|
183
|
-
**Note:** This method is idempotent - calling it multiple times is safe and has
|
|
471
|
+
**Note:** This method is idempotent - calling it multiple times is safe and has
|
|
472
|
+
no effect after the first call.
|
|
184
473
|
|
|
185
474
|
**Example:**
|
|
186
475
|
|
|
@@ -194,15 +483,18 @@ await expect(program.eval()).rejects.toThrow();
|
|
|
194
483
|
|
|
195
484
|
### `init(): Promise<void>`
|
|
196
485
|
|
|
197
|
-
Initializes the WASM module. This is called automatically by the API functions,
|
|
486
|
+
Initializes the WASM module. This is called automatically by the API functions,
|
|
487
|
+
but can be called manually to pre-initialize the module.
|
|
198
488
|
|
|
199
489
|
## Memory Management
|
|
200
490
|
|
|
201
|
-
This library implements comprehensive memory leak prevention mechanisms to
|
|
491
|
+
This library implements comprehensive memory leak prevention mechanisms to
|
|
492
|
+
ensure WASM resources are properly cleaned up.
|
|
202
493
|
|
|
203
494
|
### Explicit Cleanup
|
|
204
495
|
|
|
205
|
-
Both `Env` and `Program` instances provide a `destroy()` method for explicit
|
|
496
|
+
Both `Env` and `Program` instances provide a `destroy()` method for explicit
|
|
497
|
+
cleanup:
|
|
206
498
|
|
|
207
499
|
```typescript
|
|
208
500
|
const env = await Env.new();
|
|
@@ -215,29 +507,38 @@ env.destroy();
|
|
|
215
507
|
|
|
216
508
|
### Automatic Cleanup with FinalizationRegistry
|
|
217
509
|
|
|
218
|
-
The library uses JavaScript's `FinalizationRegistry` (available in Node.js 14+)
|
|
510
|
+
The library uses JavaScript's `FinalizationRegistry` (available in Node.js 14+)
|
|
511
|
+
to automatically clean up resources when objects are garbage collected. This
|
|
512
|
+
provides a **best-effort** safety net in case you forget to call `destroy()`.
|
|
219
513
|
|
|
220
514
|
**Important limitations:**
|
|
221
515
|
|
|
222
516
|
- FinalizationRegistry callbacks are not guaranteed to run immediately or at all
|
|
223
|
-
- They may run long after an object is garbage collected, or not at all in some
|
|
224
|
-
|
|
517
|
+
- They may run long after an object is garbage collected, or not at all in some
|
|
518
|
+
cases
|
|
519
|
+
- The timing is non-deterministic and depends on the JavaScript engine's garbage
|
|
520
|
+
collector
|
|
225
521
|
|
|
226
|
-
**Best practice:** Always explicitly call `destroy()` when you're done with an
|
|
522
|
+
**Best practice:** Always explicitly call `destroy()` when you're done with an
|
|
523
|
+
environment or program. Don't rely solely on automatic cleanup.
|
|
227
524
|
|
|
228
525
|
### Reference Counting for Custom Functions
|
|
229
526
|
|
|
230
|
-
The library uses reference counting to manage custom JavaScript functions
|
|
527
|
+
The library uses reference counting to manage custom JavaScript functions
|
|
528
|
+
registered with environments:
|
|
231
529
|
|
|
232
|
-
1. **When a program is created** from an environment, reference counts are
|
|
530
|
+
1. **When a program is created** from an environment, reference counts are
|
|
531
|
+
incremented for all custom functions in that environment
|
|
233
532
|
2. **When a program is destroyed**, reference counts are decremented
|
|
234
533
|
3. **Functions are only unregistered** when their reference count reaches zero
|
|
235
534
|
|
|
236
535
|
This means:
|
|
237
536
|
|
|
238
537
|
- **Programs continue to work** even after their parent environment is destroyed
|
|
239
|
-
- **Functions remain available** as long as any program that might use them
|
|
240
|
-
|
|
538
|
+
- **Functions remain available** as long as any program that might use them
|
|
539
|
+
still exists
|
|
540
|
+
- **Functions are automatically cleaned up** when all programs using them are
|
|
541
|
+
destroyed
|
|
241
542
|
|
|
242
543
|
**Example:**
|
|
243
544
|
|
|
@@ -266,14 +567,17 @@ program.destroy();
|
|
|
266
567
|
|
|
267
568
|
- **Destroyed environments** cannot create new programs or typecheck expressions
|
|
268
569
|
- **Existing programs** from a destroyed environment continue to work
|
|
269
|
-
- **The environment entry** is cleaned up when all programs using it are
|
|
570
|
+
- **The environment entry** is cleaned up when all programs using it are
|
|
571
|
+
destroyed
|
|
270
572
|
|
|
271
573
|
### Best Practices
|
|
272
574
|
|
|
273
575
|
1. **Always call `destroy()`** when you're done with environments and programs
|
|
274
|
-
2. **Destroy programs before environments** if you want to ensure functions are
|
|
576
|
+
2. **Destroy programs before environments** if you want to ensure functions are
|
|
577
|
+
cleaned up immediately
|
|
275
578
|
3. **Don't rely on automatic cleanup** - it's a safety net, not a guarantee
|
|
276
|
-
4. **In long-running applications**, explicitly manage the lifecycle of
|
|
579
|
+
4. **In long-running applications**, explicitly manage the lifecycle of
|
|
580
|
+
resources to prevent memory leaks
|
|
277
581
|
|
|
278
582
|
## TypeScript Support
|
|
279
583
|
|
|
@@ -283,9 +587,21 @@ This package includes TypeScript type definitions. Import types as needed:
|
|
|
283
587
|
import {
|
|
284
588
|
Env,
|
|
285
589
|
Program,
|
|
590
|
+
Options,
|
|
286
591
|
EnvOptions,
|
|
287
592
|
VariableDeclaration,
|
|
288
593
|
TypeCheckResult,
|
|
594
|
+
CompilationResult,
|
|
595
|
+
CompilationIssue,
|
|
596
|
+
ValidationIssue,
|
|
597
|
+
ValidationContext,
|
|
598
|
+
ValidatorResult,
|
|
599
|
+
ASTValidatorFunction,
|
|
600
|
+
ASTValidatorsConfig,
|
|
601
|
+
CrossTypeNumericComparisonsConfig,
|
|
602
|
+
OptionalTypesConfig,
|
|
603
|
+
EnvOptionConfig,
|
|
604
|
+
EnvOptionInput,
|
|
289
605
|
} from "wasm-cel";
|
|
290
606
|
```
|
|
291
607
|
|
|
@@ -293,7 +609,7 @@ import {
|
|
|
293
609
|
|
|
294
610
|
To build the package from source, you'll need:
|
|
295
611
|
|
|
296
|
-
- Go 1.
|
|
612
|
+
- Go 1.21 or later
|
|
297
613
|
- Node.js 18 or later
|
|
298
614
|
- pnpm (or npm/yarn)
|
|
299
615
|
|
|
@@ -317,7 +633,10 @@ pnpm run example
|
|
|
317
633
|
|
|
318
634
|
## Package Type
|
|
319
635
|
|
|
320
|
-
This is an **ESM-only** package. It uses modern ES modules and NodeNext module
|
|
636
|
+
This is an **ESM-only** package. It uses modern ES modules and NodeNext module
|
|
637
|
+
resolution. If you're using TypeScript, make sure your `tsconfig.json` has
|
|
638
|
+
`"module": "NodeNext"` or `"moduleResolution": "NodeNext"` for proper type
|
|
639
|
+
resolution.
|
|
321
640
|
|
|
322
641
|
## License
|
|
323
642
|
|
package/dist/index.d.ts
CHANGED
|
@@ -34,9 +34,13 @@ export declare class Env {
|
|
|
34
34
|
private envID;
|
|
35
35
|
private destroyed;
|
|
36
36
|
private constructor();
|
|
37
|
+
/**
|
|
38
|
+
* Get the environment ID (useful for debugging or advanced use cases)
|
|
39
|
+
*/
|
|
40
|
+
getID(): string;
|
|
37
41
|
/**
|
|
38
42
|
* Create a new CEL environment
|
|
39
|
-
* @param options - Options including variable declarations and
|
|
43
|
+
* @param options - Options including variable declarations, function definitions, and environment options
|
|
40
44
|
* @returns Promise resolving to a new Env instance
|
|
41
45
|
* @throws Error if environment creation fails
|
|
42
46
|
*
|
|
@@ -53,6 +57,9 @@ export declare class Env {
|
|
|
53
57
|
* .param("b", "int")
|
|
54
58
|
* .returns("int")
|
|
55
59
|
* .implement((a, b) => a + b)
|
|
60
|
+
* ],
|
|
61
|
+
* options: [
|
|
62
|
+
* Options.optionalTypes()
|
|
56
63
|
* ]
|
|
57
64
|
* });
|
|
58
65
|
* ```
|
|
@@ -75,6 +82,28 @@ export declare class Env {
|
|
|
75
82
|
* ```
|
|
76
83
|
*/
|
|
77
84
|
compile(expr: string): Promise<Program>;
|
|
85
|
+
/**
|
|
86
|
+
* Compile a CEL expression with detailed results including warnings and issues
|
|
87
|
+
* @param expr - The CEL expression to compile
|
|
88
|
+
* @returns Promise resolving to detailed compilation results
|
|
89
|
+
* @throws Error if environment has been destroyed
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* const result = await env.compileDetailed("x + y");
|
|
94
|
+
* if (result.success) {
|
|
95
|
+
* console.log("Compiled successfully");
|
|
96
|
+
* if (result.issues.length > 0) {
|
|
97
|
+
* console.log("Warnings:", result.issues);
|
|
98
|
+
* }
|
|
99
|
+
* const evalResult = await result.program.eval({ x: 10, y: 20 });
|
|
100
|
+
* } else {
|
|
101
|
+
* console.log("Compilation failed:", result.error);
|
|
102
|
+
* console.log("All issues:", result.issues);
|
|
103
|
+
* }
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
compileDetailed(expr: string): Promise<import("./types.js").CompilationResult>;
|
|
78
107
|
/**
|
|
79
108
|
* Typecheck a CEL expression in this environment without compiling it
|
|
80
109
|
* @param expr - The CEL expression to typecheck
|
|
@@ -94,6 +123,29 @@ export declare class Env {
|
|
|
94
123
|
* ```
|
|
95
124
|
*/
|
|
96
125
|
typecheck(expr: string): Promise<TypeCheckResult>;
|
|
126
|
+
/**
|
|
127
|
+
* Extend this environment with additional CEL environment options
|
|
128
|
+
* @param options - Array of CEL environment option configurations or complex options with setup
|
|
129
|
+
* @returns Promise that resolves when the environment has been extended
|
|
130
|
+
* @throws Error if extension fails or environment has been destroyed
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```typescript
|
|
134
|
+
* const env = await Env.new({
|
|
135
|
+
* variables: [{ name: "x", type: "int" }]
|
|
136
|
+
* });
|
|
137
|
+
*
|
|
138
|
+
* // Add options after creation
|
|
139
|
+
* await env.extend([Options.optionalTypes()]);
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
extend(options: import("./options/index.js").EnvOptionInput[]): Promise<void>;
|
|
143
|
+
/**
|
|
144
|
+
* Internal method to extend environment with options
|
|
145
|
+
* This method delegates to options that implement OptionWithSetup for complex operations
|
|
146
|
+
* @private
|
|
147
|
+
*/
|
|
148
|
+
private _extendWithOptions;
|
|
97
149
|
/**
|
|
98
150
|
* Destroy this environment and free associated WASM resources.
|
|
99
151
|
* This will also clean up any registered JavaScript functions associated
|
|
@@ -105,6 +157,8 @@ export declare class Env {
|
|
|
105
157
|
*/
|
|
106
158
|
destroy(): void;
|
|
107
159
|
}
|
|
108
|
-
export type { CELType, CELTypeDef, CELListType, CELMapType, CELFunctionDefinition, CELFunctionParam, EnvOptions, VariableDeclaration, TypeCheckResult, } from "./types.js";
|
|
160
|
+
export type { CELType, CELTypeDef, CELListType, CELMapType, CELFunctionDefinition, CELFunctionParam, EnvOptions, VariableDeclaration, TypeCheckResult, CompilationIssue, CompilationResult, } from "./types.js";
|
|
109
161
|
export { listType, mapType, CELFunction } from "./functions.js";
|
|
162
|
+
export { Options } from "./options/index.js";
|
|
163
|
+
export type { EnvOptionConfig, OptionalTypesConfig, ValidationIssue, ValidationContext, ValidatorResult, ASTValidatorFunction, ASTValidatorsConfig, } from "./options/index.js";
|
|
110
164
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAGV,UAAU,EACV,eAAe,EAChB,MAAM,YAAY,CAAC;AAkCpB;;;GAGG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAuC1C;AA2GD;;GAEG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAkB;gBAEvB,SAAS,EAAE,MAAM;IAQ7B;;;;;OAKG;IACG,IAAI,CAAC,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAW,GAAG,OAAO,CAAC,GAAG,CAAC;IAyBjE;;;;;;OAMG;IACH,OAAO,IAAI,IAAI;CAyBhB;AAED;;GAEG;AACH,qBAAa,GAAG;IACd,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAkB;IAEnC,OAAO;IAQP
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAGV,UAAU,EACV,eAAe,EAChB,MAAM,YAAY,CAAC;AAkCpB;;;GAGG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAuC1C;AA2GD;;GAEG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAkB;gBAEvB,SAAS,EAAE,MAAM;IAQ7B;;;;;OAKG;IACG,IAAI,CAAC,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAW,GAAG,OAAO,CAAC,GAAG,CAAC;IAyBjE;;;;;;OAMG;IACH,OAAO,IAAI,IAAI;CAyBhB;AAED;;GAEG;AACH,qBAAa,GAAG;IACd,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAkB;IAEnC,OAAO;IAQP;;OAEG;IACH,KAAK,IAAI,MAAM;IAIf;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;WACU,GAAG,CAAC,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC;IA6CpD;;;;;;;;;;;;;;;OAeG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA+B7C;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,eAAe,CACnB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,YAAY,EAAE,iBAAiB,CAAC;IAsDlD;;;;;;;;;;;;;;;;;OAiBG;IACG,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IA+BvD;;;;;;;;;;;;;;;OAeG;IACG,MAAM,CACV,OAAO,EAAE,OAAO,oBAAoB,EAAE,cAAc,EAAE,GACrD,OAAO,CAAC,IAAI,CAAC;IAIhB;;;;OAIG;YACW,kBAAkB;IAyFhC;;;;;;;;OAQG;IACH,OAAO,IAAI,IAAI;CAyBhB;AAGD,YAAY,EACV,OAAO,EACP,UAAU,EACV,WAAW,EACX,UAAU,EACV,qBAAqB,EACrB,gBAAgB,EAChB,UAAU,EACV,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC"}
|