# CEL API Reference

> The elide:cel module: compile and evaluate Common Expression Language expressions.

`elide:cel` compiles and evaluates [CEL](https://cel.dev) expressions. Expressions have no side effects and
always terminate, so they suit user-supplied rules, filters and policies.

```js
import { compile } from "elide:cel";

const rule = compile("user.age >= 18 && 'admin' in user.roles");
rule.variables; // ["user"]
rule.test({ user: { age: 30, roles: ["admin"] } }); // true
compile("xs.filter(x, x % 2 == 0)").evaluate({ xs: [1, 2, 3, 4] }); // [2, 4]
```

- `compile(expression)` parses and type-checks once and returns a reusable program. Free identifiers become
  variables, typed `dyn`. Invalid expressions throw an `Error` with the CEL diagnostic.
- `program.evaluate(variables?)` returns the result; `program.test(variables?)` requires a boolean.
  Evaluation failures throw an `Error`.
- The standard library and macros (`has`, `all`, `exists`, `exists_one`, `map`, `filter`) are available.
  CEL extension libraries are not.

## Values

| JavaScript | CEL |
| --- | --- |
| integral `number`, `bigint` within int64 | `int` |
| other `number` | `double` |
| `string`, `boolean`, `null` | `string`, `bool`, `null` |
| `Uint8Array`, `Buffer` | `bytes` |
| array, plain object | `list`, `map` |

Results convert back the same way. An `int` beyond `Number.MAX_SAFE_INTEGER` returns as a `bigint`; a
timestamp or duration returns as its string form. Comparisons mix `int` and `double` freely, arithmetic
does not: write `double(x) / 2.0` when `x` may be integral.

## Samples

- [Access rules with CEL](https://elide.help/docs/code-samples#access-rules-with-cel)
