Documentation ¶
Overview ¶
Package lib provides a set of extension libraries for the Common Expression Language intended to be used for message stream processing.
Index ¶
- Constants
- func CSVHeader(r io.Reader) ref.Val
- func CSVNoHeader(r io.Reader) ref.Val
- func Collections() cel.EnvOption
- func Crypto() cel.EnvOption
- func Debug(handler func(tag string, value any)) cel.EnvOption
- func DraftRateLimit(h http.Header, window time.Duration) map[string]interface{}
- func File(mimetypes map[string]interface{}) cel.EnvOption
- func Globals(vars map[string]interface{}) cel.EnvOption
- func HTTP(client *http.Client, limit *rate.Limiter, auth *BasicAuth) cel.EnvOption
- func HTTPWithContext(ctx context.Context, client *http.Client, limit *rate.Limiter, auth *BasicAuth) cel.EnvOption
- func JSON(adapter types.Adapter) cel.EnvOption
- func Limit(policy map[string]LimitPolicy) cel.EnvOption
- func MIME(mimetypes map[string]interface{}) cel.EnvOption
- func NDJSON(r io.Reader) ref.Val
- func OktaRateLimit(h http.Header, window time.Duration) map[string]interface{}
- func Printf() cel.EnvOption
- func Regexp(patterns map[string]*regexp.Regexp) cel.EnvOption
- func Send(ch map[string]chan interface{}) cel.EnvOption
- func Strings() cel.EnvOption
- func Time() cel.EnvOption
- func Try() cel.EnvOption
- func XML(adapter types.Adapter, xsd map[string]string) (cel.EnvOption, error)
- func Zip(r io.Reader) ref.Val
- type BasicAuth
- type Coverage
- type DecoratedError
- type Dump
- type LimitPolicy
- type LineCoverage
- type NodeValue
Constants ¶
const OptionalTypesVersion = 1
OptionalTypesVersion is the version of the optional types library used by mito.
Variables ¶
This section is empty.
Functions ¶
func CSVHeader ¶
CSVHeader provides a file transform that returns a <list<map<string,string>>> from an io.Reader holding text/csv data. It should be handed to the File or MIME lib with
File(map[string]interface{}{ "text/csv; header=present": lib.CSVHeader, })
or
MIME(map[string]interface{}{ "text/csv; header=present": lib.CSVHeader, })
It will then be able to be used in a file or mime call.
Example:
Given a file hello.csv: "first","second","third" 1,2,3 file('hello.csv', 'text/csv; header=present') will return: [{"first": "1", "second": "2", "third": "3"}]
func CSVNoHeader ¶
CSVNoHeader provides a file transform that returns a <list<list<string>>> from an io.Reader holding text/csv data. It should be handed to the File or MIME lib with
File(map[string]interface{}{ "text/csv; header=absent": lib.CSVNoHeader, })
or
MIME(map[string]interface{}{ "text/csv; header=absent": lib.CSVNoHeader, })
It will then be able to be used in a file or mime call.
Example:
Given a file hello.csv: "first","second","third" 1,2,3 file('hello.csv', 'text/csv; header=absent') will return: [["first", "second", "third"], ["1", "2", "3"]]
func Collections ¶
Collections returns a cel.EnvOption to configure extended functions for handling collections.
As (Macro)
The as macro is syntactic sugar for [val].map(var, function)[0].
Examples:
{"a":1, "b":2}.as(v, v.a == 1) // return true {"a":1, "b":2}.as(v, v) // return {"a":1, "b":2} {"a":1, "b":2}.as(v, v.with({"c":3})) // return {"a":1, "b":2, "c":3} {"a":1, "b":2}.as(v, [v, v]) // return [{"a":1, "b":2}, {"a":1, "b":2}]
Collate ¶
Returns a list of values obtained by traversing fields in the receiver with the path or paths given as the string parameter. When a list is traversed all children are include in the resulting list:
<list<dyn>>.collate(<string>) -> <list<dyn>> <list<dyn>>.collate(<list<string>>) -> <list<dyn>> <map<string,dyn>>.collate(<string>) -> <list<dyn>> <map<string,dyn>>.collate(<list<string>>) -> <list<dyn>>
Examples:
Given v: { "a": [ {"b": 1}, {"b": 2}, {"b": 3} ], "b": [ {"b": -1, "c": 10}, {"b": -2, "c": 20}, {"b": -3, "c": 30} ] } v.collate("a") // return [{"b": 1}, {"b": 2}, {"b": 3}] v.collate("a.b") // return [1, 2, 3] v.collate(["a.b", "b.b"]) // return [1, 2, 3, -1, -2, -3] v.collate(["a", "b.b"]) // return [{"b": 1 }, {"b": 2 }, {"b": 3 }, -1, -2, -3 ]
If the the path to be dropped includes a dot, it can be escaped with a literal backslash. See drop below.
Drop ¶
Returns the value of the receiver with the object at the given paths remove:
<list<dyn>>.drop(<string>) -> <list<dyn>> <list<dyn>>.drop(<list<string>>) -> <list<dyn>> <map<string,dyn>>.drop(<string>) -> <map<string,dyn>> <map<string,dyn>>.drop(<list<string>>) -> <map<string,dyn>>
Examples:
Given v: { "a": [ {"b": 1}, {"b": 2}, {"b": 3} ], "b": [ {"b": -1, "c": 10}, {"b": -2, "c": 20}, {"b": -3, "c": 30} ] } v.drop("a") // return {"b": [{"b": -1, "c": 10}, {"b": -2, "c": 20}, {"b": -3, "c": 30}]} v.drop("a.b") // return {"a": [{}, {}, {}], "b": [{"b": -1, "c": 10}, {"b": -2, "c": 20}, {"b": -3, "c": 30}]} v.drop(["a.b", "b.b"]) // return {"a": [{}, {}, {}], "b": [{"c": 10}, {"c": 20}, {"c": 30}]} v.drop(["a", "b.b"]) // return {"b": [{"c": 10}, {"c": 20}, {"c": 30}]}
If the the path to be dropped includes a dot, it can be escaped with a literal backslash.
Examples:
Given v: { "dotted.path": [ {"b": -1, "c": 10}, {"b": -2, "c": 20}, {"b": -3, "c": 30} ] } v.drop("dotted\\.path.b") // return {"dotted.path": [{"c": 10}, {"c": 20}, {"c": 30}]}
Drop Empty ¶
Returns the value of the receiver with all empty lists and maps removed, recursively
<list<dyn>>.drop_empty() -> <list<dyn>> <map<string,dyn>>.drop_empty() -> <map<string,dyn>>
Examples:
Given v: { "a": [ {}, {}, {} ], "b": [ {"b": -1, "c": 10}, {"b": -2, "c": 20}, {"b": -3, "c": 30} ] } v.drop_empty() // return {"b":[{"b":-1, "c":10}, {"b":-2, "c":20}, {"b":-3, "c":30}]}
Flatten ¶
Returns a list of non-list objects resulting from the depth-first traversal of a nested list:
<list<dyn>...>.flatten() -> <list<dyn>>
Examples:
[[1],[2,3],[[[4]],[5,6]]].flatten() // return [1, 2, 3, 4, 5, 6] [[{"a":1,"b":[10, 11]}],[2,3],[[[4]],[5,6]]].flatten() // return [{"a":1, "b":[10, 11]}, 2, 3, 4, 5, 6]
Keys ¶
Returns a list of keys from a map:
keys(<map<dyn,dyn>>) -> <list<dyn>> <map<dyn,dyn>>.keys() -> <list<dyn>>
Examples:
keys({"a":1, "b":2}) // return ["a", "b"] {1:"a", 2:"b"}.keys() // return [1, 2]
Max ¶
Returns the maximum value of a list or pair of comparable objects:
<list<dyn>>.max() -> <dyn> max(<list<dyn>>) -> <dyn> max(<dyn>, <dyn>) -> <dyn>
Examples:
[1,2,3,4,5,6,7].max() // return 7 max([1,2,3,4,5,6,7]) // return 7 max(1,7) // return 7
Min ¶
Returns the minimum value of a list or pair of comparable objects:
<list<dyn>>.min() -> <dyn> min(<list<dyn>>) -> <dyn> min(<dyn>, <dyn>) -> <dyn>
Examples:
[1,2,3,4,5,6,7].min() // return 1 min([1,2,3,4,5,6,7]) // return 1 min(1,7) // return 1
Tail ¶
Returns the elements of a list after the first element:
tail(<list<dyn>>) -> <optional<dyn>>
Examples:
tail([1, 2, 3, 4, 5, 6]) // return [2, 3, 4, 5, 6] tail([6]) // return [] tail([]) // return []
The conjugate of tail, getting the first element, can be achieved directly using list indexing, for example if a is [1, 2, 3, 4, 5, 6] and b is []:
a[?0] // return 1 b[?0] // return optional.none
Values ¶
Returns a list of values from a map:
values(<map<dyn,dyn>>) -> <list<dyn>> <map<dyn,dyn>>.values() -> <list<dyn>>
Examples:
values({"a":1, "b":2}) // return [1, 2] {1:"a", 2:"b"}.values() // return ["a", "b"]
With ¶
Returns the receiver's value with the value of the parameter updating or adding fields:
<map<K,V>>.with(<map<K,V>>) -> <map<K,V>>
Examples:
{"a":1, "b":2}.with({"a":10, "c":3}) // return {"a":10, "b":2, "c":3}
With Replace ¶
Returns the receiver's value with the value of the parameter replacing existing fields:
<map<K,V>>.with_replace(<map<K,V>>) -> <map<K,V>>
Examples:
{"a":1, "b":2}.with_replace({"a":10, "c":3}) // return {"a":10, "b":2}
With Update ¶
Returns the receiver's value with the value of the parameter updating the map without replacing any existing fields:
<map<K,V>>.with_update(<map<K,V>>) -> <map<K,V>>
Examples:
{"a":1, "b":2}.with_update({"a":10, "c":3}) // return {"a":1, "b":2, "c":3}
Zip ¶
Returns a map keyed on elements of a list with values from another equally sized list:
zip(<list<K>>, <list<V>>) -> <map<K,V>> <list<K>>.zip(<list<V>>) -> <map<K,V>>
Examples:
zip(["a", "b"], [1, 2]) // return {"a":1, "b":2} ["a", "b"].zip([1, 2]) // return {"a":1, "b":2}
func Crypto ¶
Crypto returns a cel.EnvOption to configure extended functions for cryptographic hash functions and encoding.
Base64 ¶
Returns a string of the base64 encoding of a string or bytes:
base64(<bytes>) -> <string> base64(<string>) -> <string> <bytes>.base64() -> <string> <string>.base64() -> <string>
Examples:
"hello world".base64() // return "aGVsbG8gd29ybGQ="
Base64 Decode ¶
Returns a bytes from the base64 encoding in a string:
base64_decode(<string>) -> <bytes> <string>.base64_decode() -> <bytes>
Examples:
"aGVsbG8gd29ybGQ=".base64_decode() // return b"hello world"
Base64 Raw ¶
Returns a string of the raw unpadded base64 encoding of a string or bytes:
base64_raw(<bytes>) -> <string> base64_raw(<string>) -> <string> <bytes>.base64_raw() -> <string> <string>.base64_raw() -> <string>
Examples:
"hello world".base64_raw() // return "aGVsbG8gd29ybGQ"
Base64 Raw Decode ¶
Returns a bytes from the raw base64 encoding in a string:
base64_raw_decode(<string>) -> <bytes> <string>.base64_raw_decode() -> <bytes>
Examples:
"aGVsbG8gd29ybGQ".base64_raw_decode() // return b"hello world"
Hex ¶
Returns a string of the hexadecimal representation of a string or bytes:
hex(<bytes>) -> <string> hex(<string>) -> <string> <bytes>.hex() -> <string> <string>.hex() -> <string>
Examples:
"hello world".hex() // return "68656c6c6f20776f726c64"
MD5 ¶
Returns a bytes of the md5 hash of a string or bytes:
md5(<bytes>) -> <bytes> md5(<string>) -> <bytes> <bytes>.md5() -> <bytes> <string>.md5() -> <bytes>
Examples:
"hello world".md5() // return "XrY7u+Ae7tCTyyK7j1rNww==" "hello world".md5().hex() // return "5eb63bbbe01eeed093cb22bb8f5acdc3"
SHA-1 ¶
Returns a bytes of the sha-1 hash of a string or bytes:
sha1(<bytes>) -> <bytes> sha1(<string>) -> <bytes> <bytes>.sha1() -> <bytes> <string>.sha1() -> <bytes>
Examples:
"hello world".sha1() // return "Kq5sNclPz7QV2+lfQIuc6R7oRu0=" "hello world".sha1().hex() // return "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed"
SHA-256 ¶
Returns a bytes of the sha-256 cryptographic hash of a string or bytes:
sha256(<bytes>) -> <bytes> sha256(<string>) -> <bytes> <bytes>.sha256() -> <bytes> <string>.sha256() -> <bytes>
Examples:
"hello world".sha1() // return "uU0nuZNNPgilLlLX2n2r+sSE7+N6U4DukIj3rOLvzek=" "hello world".sha1().hex() // return "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
HMAC ¶
Returns a bytes of the HMAC keyed MAC of a string or bytes using either the sha-1 or sha-256 hash function depending on the the second parameter:
hmac(<bytes>, <string>, <bytes>) -> <bytes> hmac(<string>, <string>, <bytes>) -> <bytes> <bytes>.hmac(<string>, <bytes>) -> <bytes> <string>.hmac(<string>, <bytes>) -> <bytes>
Examples:
"hello world".hmac("sha256", b"key") // return "C6BvH5pjAEYeQ0VFNdw8QiPkex01cHPXU26ukOwJW+E=" "hello world".hmac("sha256", b"key").hex() // return "0ba06f1f9a6300461e43454535dc3c4223e47b1d357073d7536eae90ec095be1"
UUID ¶
Returns a string of a random (Version 4) UUID based on the the Go crypto/rand source:
uuid() -> <string>
Examples:
uuid() // return "582fc58b-f983-4c35-abb1-65c507c1dc0c"
func Debug ¶ added in v1.6.0
Debug returns a cel.EnvOption to configure extended functions for allowing intermediate values to be logged without disrupting program flow.
The debug function will pass errors through without halting the program's execution. If the value cannot be serialised, an error will be passed to the handler.
Debug ¶
The second parameter is returned unaltered and the value is logged to the lib's logger:
debug(<string>, <dyn>) -> <dyn>
Examples:
debug("tag", expr) // return expr even if it is an error and logs with "tag".
func DraftRateLimit ¶
DraftRateLimit implements the draft rate limit policy translation. It should be handed to the Limit lib with
Limit(map[string]lib.LimitPolicy{ "draft": lib.DraftRateLimit, })
It will then be able to be used in a limit call where the duration is the default quota window.
Example:
rate_limit(h, 'draft', duration('60s')) might return something like: { "burst": 1, "headers": "Rate-Limit-Limit=\"5000\" Rate-Limit-Remaining=\"100\" Rate-Limit-Reset=\"Sat, 16 Apr 2022 07:48:40 GMT\"", "next": 83.33333333333333, "rate": 0.16689431007474315, "reset": "2022-04-16T07:48:40Z" } or { "burst": 1000, "headers": "Rate-Limit-Limit=\"12, 12;window=1; burst=1000;policy=\\\"leaky bucket\\\"\" Rate-Limit-Remaining=\"100\" Rate-Limit-Reset=\"Sat, 16 Apr 2022 07:48:40 GMT\"", "next": 12, "rate": 100, "reset": "2022-04-16T07:48:40Z" }
See https://datatracker.ietf.org/doc/html/draft-polli-ratelimit-headers-00
func File ¶
File returns a cel.EnvOption to configure extended functions for reading files. It takes a mapping of mimetypes to transforms to allow reading specific mime type. The values in the map must be one of: func([]byte), func(io.Reader) io.Reader, func(io.Reader) (io.Reader, error) or func(io.Reader) ref.Val. If the transform is func([]byte) it is expected to mutate the bytes in place.
Dir ¶
dir returns either a directory for the provided path:
dir(<string>) -> <list<map<string,dyn>>>
Examples:
dir('subdir') will return something like: [ { "is_dir": true, "mod_time": "2022-04-05T20:53:11.923840504+09:30", "name": "subsubdir", "size": 4096 }, { "is_dir": false, "mod_time": "2022-04-05T20:53:11.923840504+09:30", "name": "a.txt", "size": 13 }, { "is_dir": false, "mod_time": "2022-04-05T20:53:11.923840504+09:30", "name": "b.txt", "size": 11 } ]
File ¶
file returns either a <bytes> or a <dyn> depending on whether it is called with one parameter or two:
file(<string>) -> <bytes> file(<string>, <string>) -> <dyn>
The first parameter is a file path and the second is a look-up into the transforms map provided by to the File cel.EnvOption.
Examples:
Given a file hello.txt: world! And the following transforms map (rot13 is a transforming reader): map[string]interface{}{ "text/rot13": func(r io.Reader) io.Reader { return rot13{r} }, "text/upper": func(p []byte) { for i, b := range p { if 'a' <= b && b <= 'z' { p[i] &^= 'a' - 'A' } } }, } string(file('hello.txt')) // return "world!\n" string(file('hello.txt', 'text/rot13')) // return "jbeyq!\n" string(file('hello.txt', 'text/upper')) // return "WORLD!\n"
func Globals ¶
Globals returns a cel.EnvOption to configure global variables for the environment. Each variable will be visible as the key in the vars map. Not all Go variable types are acceptable to the CEL environment, but Globals will make a best-effort to map types to their CEL equivalents. This typing is only done for the values in the map and does not apply recursively if those values are nested.
func HTTP ¶
HTTP returns a cel.EnvOption to configure extended functions for HTTP requests. Requests and responses are returned as maps corresponding to the Go http.Request and http.Response structs. The client and limit parameters will be used for the requests and API rate limiting. If client is nil the http.DefaultClient will be used and if limit is nil an non-limiting rate.Limiter will be used. If auth is not nil, the Authorization header is populated for Basic Authentication in requests constructed for direct HEAD, GET and POST method calls. Explicitly constructed requests used in do_request are not affected by auth. In cases where Basic Authentication is needed for these constructed requests, the basic_authentication method can be used to add the necessary header.
HEAD ¶
head performs a HEAD method request and returns the result:
head(<string>) -> <map<string,dyn>>
Example:
head('http://www.example.com/') // returns {"Body": "", "Close": false,
GET ¶
get performs a GET method request and returns the result:
get(<string>) -> <map<string,dyn>>
Example:
get('http://www.example.com/') // returns {"Body": "PCFkb2N0e...
GET Request ¶
get_request returns a GET method request:
get_request(<string>) -> <map<string,dyn>>
Example:
get_request('http://www.example.com/') will return: { "Close": false, "ContentLength": 0, "Header": {}, "Host": "www.example.com", "Method": "GET", "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "URL": "http://www.example.com/" }
POST ¶
post performs a POST method request and returns the result:
post(<string>, <string>, <bytes>) -> <map<string,dyn>> post(<string>, <string>, <string>) -> <map<string,dyn>>
Example:
post("http://www.example.com/", "text/plain", "test") // returns {"Body": "PCFkb2N0e...
POST Request ¶
post_request returns a POST method request:
post_request(<string>, <string>, <bytes>) -> <map<string,dyn>> post_request(<string>, <string>, <string>) -> <map<string,dyn>>
Example:
post_request("http://www.example.com/", "text/plain", "test") will return: { "Body": "test", "Close": false, "ContentLength": 4, "Header": { "Content-Type": [ "text/plain" ] }, "Host": "www.example.com", "Method": "POST", "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "URL": "http://www.example.com/" }
Request ¶
request returns a user-defined method request:
request(<string>, <string>) -> <map<string,dyn>> request(<string>, <string>, <bytes>) -> <map<string,dyn>> request(<string>, <string>, <string>) -> <map<string,dyn>>
Example:
request("GET", "http://www.example.com/").with({"Header":{ "Authorization": ["Basic "+string(base64("username:password"))], }}) will return: { "Close": false, "ContentLength": 0, "Header": { "Authorization": [ "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" ] }, "Host": "www.example.com", "Method": "GET", "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "URL": "http://www.example.com/" }
Basic Authentication ¶
basic_authentication adds a Basic Authentication Authorization header to a request, returning the modified request.
<map<string,dyn>>.basic_authentication(<string>, <string>) -> <map<string,dyn>>
Example:
request("GET", "http://www.example.com/").basic_authentication("username", "password") will return: { "Close": false, "ContentLength": 0, "Header": { "Authorization": [ "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" ] }, "Host": "www.example.com", "Method": "GET", "Proto": "HTTP/1.1", "ProtoMajor": 1, "ProtoMinor": 1, "URL": "http://www.example.com/" }
Do Request ¶
do_request executes an HTTP request:
<map<string,dyn>>.do_request() -> <map<string,dyn>>
Example:
get_request("http://www.example.com/").do_request() // returns {"Body": "PCFkb2N0e...
Parse URL ¶
parse_url returns a map holding the details of the parsed URL corresponding to the Go url.URL struct:
<string>.parse_url() -> <map<string,dyn>>
Example:
"https://pkg.go.dev/net/url#URL".parse_url() will return: { "ForceQuery": false, "Fragment": "URL", "Host": "pkg.go.dev", "Opaque": "", "Path": "/net/url", "RawFragment": "", "RawPath": "", "RawQuery": "", "Scheme": "https", "User": null }
Format URL ¶
format_url returns string corresponding to the URL map that is the receiver:
<map<string,dyn>>.format_url() -> <string>
Example:
"https://pkg.go.dev/net/url#URL".parse_url().with_replace({"Host": "godoc.org"}).format_url() will return: "https://godoc.org/net/url#URL"
Parse Query ¶
parse_query returns a map holding the details of the parsed query corresponding to the Go url.Values map:
<string>.parse_query() -> <map<string,<list<string>>>
Example:
"page=1&line=25".parse_url() will return: { "line": ["25"], "page": ["1"] }
Format Query ¶
format_query returns string corresponding to the query map that is the receiver:
<map<string,<list<string>>>.format_query() -> <string>
Example:
"page=1&line=25".parse_query().with_replace({"page":[string(2)]}).format_query() will return: line=25&page=2"
func HTTPWithContext ¶
func HTTPWithContext(ctx context.Context, client *http.Client, limit *rate.Limiter, auth *BasicAuth) cel.EnvOption
HTTPWithContext returns a cel.EnvOption to configure extended functions for HTTP requests that include a context.Context in network requests.
func JSON ¶
JSON returns a cel.EnvOption to configure extended functions for JSON coding and decoding. The parameter specifies the CEL type adapter to use. A nil adapter is valid an will give an option using the default type adapter, types.DefaultTypeAdapter.
Encode JSON ¶
encode_json returns a string of the JSON encoding of the receiver or parameter:
encode_json(<dyn>) -> <string> <dyn>.encode_json() -> <string>
Examples:
{"a":1, "b":[1, 2, 3]}.encode_json() // return "{\"a\":1,\"b\":[1,2,3]}" encode_json({"a":1, "b":[1, 2, 3]}) // return "{\"a\":1,\"b\":[1,2,3]}"
Decode JSON ¶
decode_json returns the object described by the JSON encoding of the receiver or parameter:
<bytes>.decode_json() -> <dyn> <string>.decode_json() -> <dyn> decode_json(<bytes>) -> <dyn> decode_json(<string>) -> <dyn>
Examples:
"{\"a\":1,\"b\":[1,2,3]}".decode_json() // return {"a":1, "b":[1, 2, 3]} b"{\"a\":1,\"b\":[1,2,3]}".decode_json() // return {"a":1, "b":[1, 2, 3]}
Decode JSON Stream ¶
decode_json_stream returns a list of objects described by the JSON stream of the receiver or parameter:
<bytes>.decode_json_stream() -> <list<dyn>> <string>.decode_json_stream() -> <list<dyn>> decode_json_stream(<bytes>) -> <list<dyn>> decode_json_stream(<string>) -> <list<dyn>>
Examples:
'{"a":1}{"b":2}'.decode_json_stream() // return [{"a":1}, {"b":2}] b'{"a":1}{"b":2}'.decode_json_stream() // return [{"a":1}, {"b":2}]
func Limit ¶
func Limit(policy map[string]LimitPolicy) cel.EnvOption
Limit returns a cel.EnvOption to configure extended functions for interpreting request rate limit policies.
It takes a mapping of policy names to policy interpreters to allow implementing specific rate limit policies. The map returned by the policy functions should have "rate" and "next" fields with type rate.Limit or string with the value "inf", a "burst" field with type int and a "reset" field with type time.Time in the UTC location. The semantics of "rate" and "burst" are described in the documentation for the golang.org/x/time/rate package.
The map may have other fields that can be logged. If a field named "error" exists it should be a string with an error message indicating the result can not be used.
Rate Limit ¶
rate_limit returns <map<string,dyn>> interpreted through the registered rate limit policy or with a generalised policy constructor:
rate_limit(<map<string,dyn>>, <string>, <duration>) -> <map<string,dyn>> rate_limit(<map<string,dyn>>, <string>, <bool>, <bool>, <duration>, <int>) -> <map<string,dyn>>
In the first form the string is the policy name and the duration is the default quota window to use in the absence of window information from headers.
In the second form the parameters are the header, the prefix for the rate limit header keys, whether the keys are canonically formatted MIME header keys, whether the reset header is a delta as opposed to a timestamp, the duration of the quota window, and the burst rate. rate_limit in the second form will never set a burst rate to zero.
In all cases if any of the three rate limit headers is missing the rate_limit call returns a map with only the headers written. This should be considered an error condition.
Examples:
rate_limit(h, 'okta', duration('1m')) rate_limit(h, 'draft', duration('1m')) // Similar semantics to the okta policy. rate_limit(h, 'X-Rate-Limit', true, false, duration('1s'), 1) // Similar semantics to the draft policy in the simplest case. rate_limit(h, 'Rate-Limit', true, true, duration('1s'), 1) // Non-canonical keys. rate_limit(h, 'X-RateLimit', false, false, duration('1s'), 1)
func MIME ¶
MIME returns a cel.EnvOption to configure extended functions for reading files. It takes a mapping of mimetypes to transforms to allow interpreting specific mime type. The values in the map must be one of: func([]byte), func(io.Reader) io.Reader, func(io.Reader) (io.Reader, error) or func(io.Reader) ref.Val. If the transform is func([]byte) it is expected to mutate the bytes in place.
MIME ¶
mime returns <dyn> interpreted through the registered MIME type:
<bytes>.mime(<string>) -> <dyn>
Examples:
string(b"hello world!".mime("text/rot13")) // return "uryyb jbeyq!" string(b"hello world!".mime("text/upper")) // return "HELLO WORLD!" string(b"\x1f\x8b\b\x00\x00\x00\x00\x00\x00\xff\xcaH\xcd\xc9\xc9W(\xcf/\xcaIQ\x04\x04\x00\x00\xff\xffm´\x03\f\x00\x00\x00" .mime("application/gzip")) // return "hello world!"
See also File and NDJSON.
func NDJSON ¶
NDJSON provides a file transform that returns a <list<dyn>> from an io.Reader holding ND-JSON data. It should be handed to the File or MIME lib with
File(map[string]interface{}{ "application/x-ndjson": lib.NDJSON, })
or
MIME(map[string]interface{}{ "application/x-ndjson": lib.NDJSON, })
It will then be able to be used in a file or mime call.
Example:
Given a file hello.ndjson: {"message":"hello"} {"message":"world"} file('hello.ndjson', 'application/x-ndjson') will return: [ { "message": "hello" }, { "message": "world" } ]
Messages in the ND-JSON stream that are invalid will be added to the list as CEL errors and will need to be processed using the try function.
Example:
Given a file hello.ndjson: {"message":"hello"} {"message":"oops" {"message":"world"} file('hello.ndjson', 'application/x-ndjson').map(e, try(e, "error.message")) will return: [ { "message": "hello" }, { "error.message": "unexpected end of JSON input: {\"message\":\"oops\"" }, { "message": "world" } ]
func OktaRateLimit ¶
OktaRateLimit implements the Okta rate limit policy translation. It should be handed to the Limit lib with
Limit(map[string]lib.LimitPolicy{ "okta": lib.OktaRateLimit, })
It will then be able to be used in a limit call with the window duration given by the Okta documentation.
Example:
rate_limit(h, 'okta', duration('1m')) might return: { "burst": 1, "headers": "X-Rate-Limit-Limit=\"600\" X-Rate-Limit-Remaining=\"598\" X-Rate-Limit-Reset=\"1650094960\"", "next": 10, "rate": 0.9975873271836141, "reset": "2022-04-16T07:48:40Z" },
See https://developer.okta.com/docs/reference/rl-best-practices/
func Printf ¶ added in v1.16.0
Printf returns a cel.EnvOption to configure an extended function for formatting strings and associated arguments.
Sprintf ¶
Formats a string from a format string and a set of arguments using the Go fmt syntax:
<string>.sprintf(<list<dyn>>) -> <string> sprintf(<string>, <list<dyn>>) -> <string>
Since CEL does not support variadic functions, arguments are provided as an array corresponding to the normal Go variadic slice.
Examples:
"Hello, %s".sprintf(["World!"]) // return "Hello, World!" sprintf("Hello, %s", ["World!"]) // return "Hello, World!"
func Regexp ¶
Regexp returns a cel.EnvOption to configure extended functions for using regular expressions on strings and bytes. It takes a mapping of names to Go regular expressions. The names are used to specify the pattern in the CEL regexp call.
Each function corresponds to methods on regexp.Regexp in the Go standard library.
For the examples below assume an input patterns map:
map[string]*regexp.Regexp{ "foo": regexp.MustCompile("foo(.)"), "foo_rep": regexp.MustCompile("(f)oo([ld])"), }
RE Match ¶
Returns whether the named pattern matches the receiver:
<bytes>.re_match(<string>) -> <bool> <string>.re_match(<string>) -> <bool>
Examples:
'food'.re_match('foo') // return true b'food'.re_match(b'foo') // return true
RE Find ¶
Returns a string or bytes of the named pattern's match:
<bytes>.re_find(<string>) -> <bytes> <string>.re_find(<string>) -> <string>
Examples:
'food'.re_find('foo') // return "food" b'food'.re_find(b'foo') // return "Zm9vZA=="
RE Find All ¶
Returns a list of strings or bytes of all the named pattern's matches:
<bytes>.re_find_all(<string>) -> <list<bytes>> <string>.re_find_all(<string>) -> <list<string>>
Examples:
'food fool'.re_find_all('foo') // return ["food", "fool"] b'food fool'.re_find_all(b'foo') // return ["Zm9vZA==", "Zm9vZA=="]
RE Find Submatch ¶
Returns a list of strings or bytes of the named pattern's submatches:
<bytes>.re_find_submatch(<string>) -> <list<bytes>> <string>.re_find_submatch(<string>) -> <list<string>>
Examples:
'food fool'.re_find_submatch('foo') // return ["food", "d"] b'food fool'.re_find_submatch('foo') // return ["Zm9vZA==", "ZA=="]
RE Find All Submatch ¶
Returns a list of lists of strings or bytes of all the named pattern's submatches:
<bytes>.re_find_all_submatch(<string>) -> <list<list<bytes>>> <string>.re_find_all_submatch(<string>) -> <list<list<string>>>
Examples:
'food fool'.re_find_all_submatch('foo') // return [["food", "d"], ["fool", "l"]]
RE Replace All ¶
Returns a strings or bytes applying a replacement to all matches of the named pattern:
<bytes>.re_replace_all(<string>, <bytes>) -> <bytes> <string>.re_replace_all(<string>, <string>) -> <string>
Examples:
'food fool'.re_replace_all('foo_rep', '${1}u${2}') // return "fud ful" b'food fool'.re_replace_all('foo_rep', b'${1}u${2}') // return "ZnVkIGZ1bA=="
func Send ¶
Send returns a cel.EnvOption to configure extended functions for sending values on a Go channel during expression evaluation. The channel should be received from by a goroutine running in the host program. Send to calls will allow error values to be passed as arguments in the <dyn> position.
Send ref.Val To ¶
Sends a value as a ref.Val to the named channel and returns the value:
<dyn>.send_to(<string>) -> <dyn> send_to(<dyn>, <string>) -> <dyn>
Send To ¶
Sends a value to the named channel and returns the value:
<dyn>.send_to(<string>) -> <dyn> send_to(<dyn>, <string>) -> <dyn>
Close ¶
Closes the named channel and returns true. It will cause an error if the same name is closed more than once in an expression. The dyn received is ignored.
<dyn>.close(<string>) -> <bool>
func Strings ¶
Strings returns a cel.EnvOption to configure extended functions for handling strings.
All functions provided by Strings are methods on the string type or list<string> type with the exception of to_valid_utf8 and valid_utf8 which are methods on the bytes type.
Relevant documentation for the methods can obtained from the Go standard library. In all cases the first parameter in the Go function corresponds to the CEL method receiver.
String Methods ¶
- compare: strings.Compare(a, b string) int
- contains_substr: strings.Contains(s, substr string) bool
- contains_any: strings.ContainsAny(s, chars string) bool
- count: strings.Count(s, substr string) int
- equal_fold: strings.EqualFold(s, t string) bool
- fields: strings.Fields(s string) []string
- has_prefix: strings.HasPrefix(s, prefix string) bool
- has_suffix: strings.HasSuffix(s, suffix string) bool
- index: strings.Index(s, substr string) int
- index_any: strings.IndexAny(s, chars string) int
- last_index: strings.LastIndex(s, substr string) int
- last_index_any: strings.LastIndexAny(s, chars string) int
- repeat: strings.Repeat(s string, count int) string
- replace: strings.Replace(s, old, new string, n int) string
- replace_all: strings.ReplaceAll(s, old, new string) string
- split: strings.Split(s, sep string) []string
- split_after: strings.SplitAfter(s, sep string) []string
- split_after_n: strings.SplitAfterN(s, sep string, n int) []string
- split_n: strings.SplitN(s, sep string, n int) []string
- to_lower: strings.ToLower(s string) string
- to_title: strings.ToTitle(s string) string
- to_upper: strings.ToUpper(s string) string
- trim: strings.Trim(s, cutset string) string
- trim_left: strings.TrimLeft(s, cutset string) string
- trim_prefix: strings.TrimPrefix(s, prefix string) string
- trim_right: strings.TrimRight(s, cutset string) string
- trim_space: strings.TrimSpace(s string) string
- trim_suffix: strings.TrimSuffix(s, suffix string) string
In addition to the strings package functions, a sub-string method is provided that allows string slicing at unicode code point boundaries. It differs from Go's string slicing operator which may slice within a code point resulting in invalid UTF-8. The substring method will always return a valid UTF-8 string, or an error if the indexes are out of bounds or invalid.
- substring: s[start:end]
String List Methods ¶
- join: strings.Join(elems []string, sep string) string
Bytes Methods ¶
The to_valid_utf8 method is equivalent to strings.ToValidUTF8 with the receiver first converted to a Go string. This special case is required as CEL does not permit invalid UTF-8 string conversions.
- to_valid_utf8: strings.ToValidUTF8(s, replacement string) string
- valid_utf8: utf8.Valid(s []byte) bool
- compare: bytes.Compare(a, b []byte) int
- contains_substr: bytes.Contains(s, substr []byte) bool
- has_prefix: bytes.HasPrefix(s, prefix []byte) bool
- has_suffix: bytes.HasSuffix(s, suffix []byte) bool
- index: bytes.Index(s, substr []byte) int
- last_index: bytes.LastIndex(s, substr []byte) int
- trim: bytes.Trim(s []byte, cutset string) []byte
- trim_left: bytes.TrimLeft(s []byte, cutset string) []byte
- trim_prefix: bytes.TrimPrefix(s, prefix []byte) []byte
- trim_right: bytes.TrimRight(s []byte, cutset string) []byte
- trim_space: bytes.TrimSpace(s []byte) []byte
- trim_suffix: bytes.TrimSuffix(s, suffix []byte) []byte
The substring method on bytes slices has the same semantics as the Go byte slice slicing operation.
- substring: s[start:end]
func Time ¶
Time returns a cel.EnvOption to configure extended functions for handling timestamps.
Now (function)
Returns a timestamp for when the call was made:
now() -> <timestamp>
Examples:
now() // return "2022-03-30T11:17:57.078390759Z"
Now (Global Variable)
Returns a timestamp for when the expression evaluation started:
now -> <timestamp>
Examples:
now // return "2022-03-30T11:17:57.078389559Z"
Format ¶
Returns a string representation of the timestamp formatted according to the provided layout:
<timestamp>.format(<string>) -> <string>
Examples:
now().format(time_layout.Kitchen) // return "11:17AM"
Parse Time ¶
Returns a timestamp from a string based on a time layout or list of possible layouts. If a list of formats is provided, the first successful layout is used:
<string>.parse_time(<string>) -> <timestamp> <string>.parse_time(<list<string>>) -> <timestamp>
Examples:
"11:17AM".parse_time(time_layout.Kitchen) // return <timestamp> "11:17AM".parse_time([time_layout.RFC3339,time_layout.Kitchen]) // return <timestamp> "11:17AM".parse_time(time_layout.RFC3339) // return error
Global Variables ¶
A collection of global variable are provided to give access to the start time of the evaluation and to the time formatting layouts provided by the Go standard library time package.
"now": <timestamp of evaluation start>, "time_layout": { "Layout": time.Layout, "ANSIC": time.ANSIC, "UnixDate": time.UnixDate, "RubyDate": time.RubyDate, "RFC822": time.RFC822, "RFC822Z": time.RFC822Z, "RFC850": time.RFC850, "RFC1123": time.RFC1123, "RFC1123Z": time.RFC1123Z, "RFC3339": time.RFC3339, "RFC3339Nano": time.RFC3339Nano, "Kitchen": time.Kitchen, "Stamp": time.Stamp, "StampMilli": time.StampMilli, "StampMicro": time.StampMicro, "StampNano": time.StampNano, "HTTP": http.TimeFormat, "DateOnly": time.DateOnly, "DateTime": time.DateTime, "TimeOnly": time.TimeOnly }
func Try ¶
Try returns a cel.EnvOption to configure extended functions for allowing errors to be weakened to strings or objects.
Try ¶
try returns either passes a value through unaltered if it is valid and not an error, or it returns a string or object describing the error:
try(<error>) -> <map<string,string>> try(<dyn>) -> <dyn> try(<error>, <string>) -> <map<string,string>> try(<dyn>, <string>) -> <dyn>
Examples:
try(0/1) // return 0 try(0/0) // return "division by zero" try(0/0, "error") // return {"error": "division by zero"}
Is Error ¶
is_error returns a bool indicating whether the argument is an error:
is_error(<dyn>) -> <bool>
Examples:
is_error(0/1) // return false is_error(0/0) // return true
func XML ¶
XML returns a cel.EnvOption to configure extended functions for XML decoding. The parameter specifies the CEL type adapter to use and a map of names to XSD document descriptions. A nil adapter is valid and will give an option using the default type adapter, types.DefaultTypeAdapter. A nil XSD mapping is valid and will give an option that performs best effort decoding leaving all values as strings and elevating elements to lists when more than one item is found for the path.
Decode XML ¶
decode_xml returns the object described by the XML encoding of the receiver or parameter, using an optional named XSD:
<bytes>.decode_xml() -> <dyn> <string>.decode_xml() -> <dyn> decode_xml(<bytes>) -> <dyn> decode_xml(<string>) -> <dyn> <bytes>.decode_xml(<string>) -> <dyn> <string>.decode_xml(<string>) -> <dyn> decode_xml(<bytes>, <string>) -> <dyn> decode_xml(<string>, <string>) -> <dyn>
Examples:
"<?xml vers... ...>".decode_xml() // return { ... } b"<?xml vers... ...>".decode_xml() // return { ... } "<?xml vers... ...>".decode_xml("xsd") // return { ... } b"<?xml vers... ...>".decode_xml("xsd") // return { ... }
func Zip ¶
Zip provides a file transform that returns a <map<dyn>> from an io.Reader holding a zip archive data. It should be handed to the File or MIME lib with
File(map[string]interface{}{ "application/zip": lib.Zip, })
or
MIME(map[string]interface{}{ "application/zip": lib.Zip, })
It will then be able to be used in a file or mime call.
The returned map reflects the structure of the Go zip.Reader struct.
Example:
file('hello.zip', 'application/zip') might return: { "Comment": "hello zip file" "File": [ { "CRC32": 0, "Comment": "", "Data": "", "Extra": "VVQFAAMCCFhidXgLAAEE6AMAAAToAwAA", "IsDir": true, "Modified": "2022-04-14T21:09:46+09:30", "Name": "subdir/", "NonUTF8": false, "Size": 0 }, { "CRC32": 30912436, "Comment": "", "Data": "aGVsbG8gd29ybGQhCg==", "Extra": "VVQFAAP0B1hidXgLAAEE6AMAAAToAwAA", "IsDir": false, "Modified": "2022-04-14T21:09:32+09:30", "Name": "subdir/a.txt", "NonUTF8": false, "Size": 13 } ] }
Note that the entire contents of the zip file is expanded into memory.
Types ¶
type BasicAuth ¶
type BasicAuth struct {
Username, Password string
}
BasicAuth is used to populate the Authorization header to use HTTP Basic Authentication with the provided username and password for direct HTTP method calls.
type Coverage ¶ added in v1.16.0
type Coverage struct {
// contains filtered or unexported fields
}
Coverage is a CEL program execution coverage statistics collector.
func NewCoverage ¶ added in v1.16.0
NewCoverage return an execution coverage statistics collector for the provided AST.
func (*Coverage) Details ¶ added in v1.16.0
func (c *Coverage) Details() []LineCoverage
Details returns the coverage details from running the target CEL program.
func (*Coverage) Merge ¶ added in v1.16.0
Merge adds node coverage from o into c. If c was constructed with NewCoverage o and c must have been constructed with the AST from the same source. If o is nil, Merge is a no-op.
func (*Coverage) ProgramOption ¶ added in v1.16.0
func (c *Coverage) ProgramOption() cel.ProgramOption
ProgramOption return a cel.ProgramOption that can be used in a call to cel.Env.Program to collect coverage information from the program's execution.
type DecoratedError ¶ added in v1.8.0
DecoratedError implements error source location rendering.
func (DecoratedError) Error ¶ added in v1.8.0
func (e DecoratedError) Error() string
type Dump ¶ added in v1.16.0
type Dump struct {
// contains filtered or unexported fields
}
Dump is an evaluation dump.
func NewDump ¶ added in v1.16.0
func NewDump(ast *cel.Ast, details *cel.EvalDetails) *Dump
NewDump returns an evaluation dump that can be used to examine the complete set of evaluation states from a CEL program. The program must have been constructed with a cel.Env.Program call including the cel.OptTrackState evaluation option. The ast and details parameters must be valid for the program.
func (*Dump) NodeValues ¶ added in v1.16.0
NodeValues returns the evaluation results, source location and source snippets for the expressions in the dump. The nodes are sorted in source order.
type LimitPolicy ¶
type LineCoverage ¶ added in v1.16.0
type LineCoverage struct { // Line is the line number of the program. Line int `json:"line"` // Coverage is the fraction of CEL expression nodes // executed on the line. Coverage float64 `json:"coverage"` // Nodes is the full set of expression nodes on // the line. Nodes []int64 `json:"nodes"` // Nodes is the set of expression nodes that were // executed. Covered []int64 `json:"covered"` // Nodes is the set of expression nodes that were // not executed. Missed []int64 `json:"missed"` // Annotation is a textual representation of the // line, marking positions that were not executed. Annotation string `json:"annotation"` }
LineCoverage is the execution coverage data for a single line of a CEL program.
func (LineCoverage) String ¶ added in v1.16.0
func (c LineCoverage) String() string
type NodeValue ¶ added in v1.16.0
type NodeValue struct {
// contains filtered or unexported fields
}
NodeValue is a CEL expression node value and annotation.