Expressions
Great software incorporates logic to perform tasks without manual intervention. This can be small tasks like transforming a set of information into another structure, logical validation, and even fully automated decision-making.
With Event Modeling on prooph board you describe what information is processed by the software, and how it changes over time.
But the HOW is not only about moving data from A to B. To be able to process information, you need to express logic in a way that the software exactly knows how to do it.
In Cody Play and Cody Engine this is done in the Javascript Expression Language (short Jexl).
Expression + Context
Jexl Expressions are strings that are parsed and executed in a controlled context. Only information explicitly passed to Jexl is available within the expression. This makes it a more secure alternative to evaluating Javascript directly.
Basic Example
const context = {say: "Hello World"}
console.log(jexl.evalSync("say", context));
// > Hello World
The basic Jexl Syntax is very similar to Javascript, but it is not the same! Check out the official documentation and the playground
Usage
Jexl Expressions are supported in different JSON configurations:
- Business Rules
- Query Resolver Rules
- Projections
- UI Schema
Supported Functions
Cody Play/Engine ships with a set of preregistered functions and transforms that are available in Jexl Expressions:
Count
The count
function works with different input types:
type count = (val: object | Array | string | number | boolean) => number
count
is also available as transform
Count items of an Array
const ctx = { items: ['a', 'b', 'c'] }
jexl.evalSync("count(items)", ctx);
// or using the transform variant
jexl.evalSync("items|count()", ctx);
// 3
Count keys of an Object
const ctx = { person: { name: "Jane", age: 35, country: null, married: true}}
jexl.evalSync("count(person)", ctx);
// 3
Count chars of a string
const ctx = { person: { name: "Jane", age: 35, country: null, married: true}}
jexl.evalSync("count(person.name)", ctx);
// 4
Count chars of a number
Numbers are converted to strings to also count the chars
const ctx = { person: { name: "Jane", age: 35, country: null, married: true}}
jexl.evalSync("count(person.age)", ctx);
// 2
Count booleans
Count returns 1
for true
and 0
for any falsy value: false
, null
, undefined
.
const ctx = { person: { name: "Jane", age: 35, country: null, married: true}}
jexl.evalSync("count(person.married)", ctx);
// 1
const ctx = { person: { name: "Jane", age: 35, country: null, married: true}}
jexl.evalSync("count(person.country)", ctx);
// 0
deepMerge
The deepMerge
function is a wrapper for lodash _.merge, which provides a recursive merge mechanism for objects.
isRole
Helper function to check if a user has a specific role. If you provide an array of roles, the function returns true if the user has any of the roles.
type isRole = (
user: User,
role: UserRole | UserRole[],
disableActiveRoleCheck?: boolean
) => boolean;
If you use the activeRole feature, the function will only check the user’s activeRole. You can disable active role check to check if any of the user roles matches.
This function is also provided as a transform. See role for usage example.
merge
The merge
function combines two values
type merge = <T extends any>(val1: T, val2: any) => T;
The type of the first input argument determines the return type. Different strategies are used to merge the two values:
Array with Array
const val1 = [1,2,3];
const val2 = [4,5,6];
const ctx = {val1, val2};
jexl.evalSync("merge(val1, val2)", ctx);
// [1,2,3,4,5,6]
Array with any other type
const val1 = [1,2,3];
const val2 = 4;
const ctx = {val1, val2};
jexl.evalSync("merge(val1, val2)", ctx);
// [1,2,3,4]
Object with Object
const val1 = {foo: "bar", subKey: {a: "b"}};
const val2 = {baz: "bat", subKey: {c: "d"}};
const ctx = {val1, val2};
jexl.evalSync("merge(val1, val2)", ctx);
// {foo: "bar", baz: "bat", subKey: {c: "d"}}
Only the first level of objects are merged. If two objects have the same key, that key is overridden by the second object key. See deepMerge for an alternative behavior.
Non object with any other type
If the first input is neither an array nor an object, merge will call the toString
method on both inputs and concatenate the two strings.
const ctx = {val1: "Hello ", val2: "World"};
jexl.evalSync("merge(val1, val2)", ctx);
// Hello World
nextval
Request the next value of a sequence managed by the document store.
type nextval = (sequenceName: string) => number;
This function is only available in backend contexts and might throw an exception if used in the wrong context.
Usage
Cody Engine/Play is using UUIDs for information identifiers. While UUIDs work great technically, they are not user-friendly. For example, it is almost impossible to remember them. If workflows require humans to deal with information identifiers, you’re better off with natural identifiers or auto incremented numbers. In both cases, it is very likely that you need a sequence to ensure that no two information get the same identifier assigned.
The nextval
function makes it easy to use a sequence to assign human-friendly identifiers to information. While the primary identifier is still a UUID, you can use the human-friendly version
to show in the UI and use it as an alternative filter in queries.
Example
// The Cody production-stack requires sequences to be created upfront
// In prototype mode, sequences are created automatically
// on first nextval('your_sequence_name') call
documentStore.addSequence('invoice_number_seq');
// Example of business rule that records an Invoice Created event from a command
// and assigns an additional invoice number as a natural identfier
// using current data + auto incremented number
const rules = [
{
rule: "always",
then: {
record: {
event: "Invoice Created",
mapping: {
"$merge": "command",
invoiceNumber: "now()|isoDate() + nextval('invoice_number_seq')"
}
}
}
}
]
pageData
PageData is available in many frontend Jexl contexts, especially in UI Schema expressions.
Every Information shown on a page, is also available in the PageData registry using its namespaced name
e.g. /App/MyInformation
.
The pageData
function takes care of the loading state of information. As long as the information is not loaded on the page, pageData
returns the defaultValue
(or undefined
if you did not provide one).
type pageData = (pageData: PageData | undefined, name: string, defaultValue: any) => any
Example
// pageData is provided by Cody
const [pageData] = usePageData();
// Cody always registers pageData in the context under the key "page"
const ctx = {page: pageData};
// The current page shows details of a person like firstname, lastname, ...
// The information of the person is fetched from the backend via a query.
// The namespaced name of the information is /Crm/Person
// We can savely access firstName and it will be "Unknown" as long as
// the query is still loading (or returned an error)
const firstName = jexl.evalSync(
`pageData(page, '/Crm/Person', {firstName: ''Unknown}).firstName`,
ctx
);
pageData
is also available as a transform function. See data transform for details.
userAttr
Users can have additional attributes for fine-grained access control or custom information that is not part of the standard user interface.
The userAttr
function is a convenient helper function to access specific attributes of a user. You can pass a default value that is returned in case the attribute is not set.
type userAttr = <T>(
user: User,
attributeName: string,
notSetValue?: T
) => T | undefined;
Example
const user = useUser();
const ctx = {user};
const age = jexl.evalSync(`userAttr(user, 'age', 40)`, ctx);
Same example without helper function:
const user = useUser();
const ctx = {user};
const age = jexl.evalSync(`user.attributes.age ? user.attributes.age : 40`, ctx);
Same example using the attr transform instead:
const user = useUser();
const ctx = {user};
const age = jexl.evalSync(`user|attr('age', 40)`, ctx);
Multi-Value Attributes
You might need to assign multiple values to an attribute. This is supported by Keycloak, which is the default auth service used in the Cody Engine production stack.
But be aware, that you need to take care of the attribute type yourself. A multivalued attribute is of type array
if multiple values are set, but of type string
if only one value is set.
To get around the type mismatch, you can force an array
type by always casting the attribute value to a list.
const user = useUser();
const ctx = {user};
const hobbies = jexl.evalSync(`user|attr('hobby')|list()`, ctx);
uuid
Generate a random version 4 UUID.
Example
jexl.evalSync(`uuid()`)
// 972a00c6-0160-4ddf-aae9-ea067ce0efe3
Supported Transforms
Transforms let you chain function calls, whereby the first input of the transform is taken from the previous output.
Transforms are chained using the pipe operator |
.
Example
const person = {
firstname: "Jane",
laastname: "Doe"
}
const ctx = {person};
// Here we use two Object transforms: "set" and "pick"
jexl.evalSync(`person|set('age', 35)|pick(['firstname', 'age'])`, ctx);
// {firstname: "Jane", age: 35}
attr
Same as userAttr, but provided as a transform.
data
Same as pageData, but provided as a transform. Since Cody always registers page data under the key page
in a Jexl Context
you can write the person example from the function description like this:
const [pageData] = usePageData();
const ctx = {page: pageData};
const firstName = jexl.evalSync(
`page|data('/Crm/Person', {firstName: ''Unknown}).firstName`,
ctx
);
role
Same as isRole, but provided as a transform.
In the frontend, Cody registers the current user in each context under the key user
.
FE Example
// Current user, let's assume we're logged in with an "Admin" role
const user = useUser();
// Always available in frontend context (ensured by Cody)
const ctx = {user};
// Check if the user has the "Admin" role
jexl.evalSync(`user|role('Admin')`, ctx);
// true
In backend contexts like business rules, you have access to the user who triggered the action. You can access it via the meta
object.
BE Example
async function handleChangeProductPrice(command: Command<ChangeProductPrice>)
: Promsie {
// Command metadata includes the user who triggered the command
const meta = command.meta;
const payload = command.payload;
const ctx = {command: payload, meta};
if(!await jexl.eval(`meta.user|role('Admin')`, ctx)) {
throw new Error(`Operation not allowed!`)
}
// ...
}
typeof
Performs a type check.
const countdown = 10;
const ctx = {countdown};
jexl.evalSync(`countdown|typeof('number')`, ctx);
// true
Array functions
contains
Check if an array contains a specific value.
available as: function, transform
const tags = ['frontend', 'feature', 'easy'];
const ctx = {tags};
jexl.evalSync(`tags|contains('easy')`, ctx);
// true
filter
Returns a new array that includes all values for which the filter expression returns true.
available as: function, transform
type filter = (arr: Array, expression: string, filterContext?: object) => Array;
The expression
has access to the item
(alias _
) and the index
of the item. If you need to access variables from the
parent context, you have to pass them explicitly to the optional filterContext
.
const colors = ['red', 'blue', 'orange', 'green', 'grey'];
const eventModelingColors = ['blue', 'organge', 'green'];
const ctx = {colors, eventModelingColors};
const filteredColors = jexl.evalSync(
`colors|filter('emc|contains(item)', {emc: eventModelingColors})`,
ctx
);
// ['blue', 'organge', 'green']
first
Get the first item of an array. If array is empty undefined
is returned or the optional notSetValue
.
available as: transform
type first = <T extends unknown>(
arr: Array<T>,
notSetValue?: T
) => T | undefined;
Example
const colors = ['red', 'blue', 'orange', 'green', 'grey'];
const emptyList = [];
const ctx = {colors, emptyList};
jexl.evalSync(`colors|first()`, ctx);
// 'red'
jexl.evalSync(`emptyList|first('Default')`, ctx);
// 'Default'
join
Concatenate all array items to a string using an optional separator.
available as: function, transform
type join = (arr: Array, separator?: string) => string;
Example
const colors = ['red', 'blue', 'orange', 'green', 'grey'];
const ctx = {colors};
jexl.evalSync(`colors|join('-')`, ctx);
// "red-blue-orange-green-grey"
list
Cast any type to an array. If input type is already an array, it is returned as-is.
available as: transform
type list = <T extends unknown>(v: T) => T[];
Example
const hobbies = "running";
jexl.evalSync(`hobbies|list()|push('traveling')`, {hobbies});
// ["running", "traveling"]
last
Get the last item of an array. If array is empty undefined
is returned or the optional notSetValue
if passed to last
.
available as: transform
type last = <T extends unknown>(arr: Array<T>, notSetValue?: T) => T | undefined;
Example
const colors = ['red', 'blue', 'orange', 'green', 'grey'];
const emptyList = [];
const ctx = {colors, emptyList};
jexl.evalSync(`colors|last()`, ctx);
// 'grey'
jexl.evalSync(`emptyList|last('Default')`, ctx);
// 'Default'
map
Invokes a mapping expression for each item and returns a new array containing all mapped items.
available as: function, transform
type map = (arr: Array, expression: string, filterContext?: object) => Array;
The expression
has access to the item
(alias _
) and the index
of the item. If you need to access variables from the
parent context, you have to pass them explicitly to the optional filterContext
.
Example
const colors = ['red', 'blue', 'orange', 'green', 'grey'];
const eventModelingColors = ['blue', 'organge', 'green'];
const ctx = {colors, eventModelingColors};
// Call the "upper" string trasform for each item of the colors array,
// if it is an event modeling color
jexl.evalSync(
`colors|map('emc|contains(item) ? item|upper() : item', {emc: eventModelingColors})`,
ctx
);
// ['red', 'BLUE', 'ORANGE', 'GREEN', 'grey']
orderBy
Wrapper for lodash _.orderBy.
available as: transform
Example
const users = [
{ 'user': 'fred', 'age': 48 },
{ 'user': 'barney', 'age': 34 },
{ 'user': 'fred', 'age': 40 },
{ 'user': 'barney', 'age': 36 }
];
// Sort by `user` in ascending order and by `age` in descending order.
jexl.evalSync(`users|orderBy(['user', 'age'], ['asc', 'desc'])`, {users});
/*
* [
* { 'user': 'barney', 'age': 36 }
* { 'user': 'barney', 'age': 34 },
* { 'user': 'fred', 'age': 48 },
* { 'user': 'fred', 'age': 40 },
* ]
*/
push
Returns a new array with the value added at the end. The input array is not modified.
available as: function, transform
type push = <T>(arr: Array<T> | unknown | undefined, val: T) => Array<T>;
If the input array is undefined, val is added to an empty array.
If the arr
is not of type array, a new array is returned containing both: [arr, val]
.
const numbers = [1,2,3];
const ctx = {numbers};
const extendedNumbers = jexl.evalSync(`numbers|push(4)|push(5)`, ctx);
// [1,2,3,4,5]
Object-specific transforms
get
Get a value from an object or array. Use .
to access subkeys.
available as: transform
type get = <T>(obj: object | Array<unknown>, path: string, notSetValue?: T | undefined) => T | undefined;
Example
const person = {
name: 'Jane',
address: {
street: 'Mainstreet'
}
}
const ctx = {person}
jexl.evalSync(`person|get('address.street')`, ctx);
// Mainsteet
// Pass a default value in case path is not set
jexl.evalSync(`person|get('address.city', 'Unknown City')`, ctx);
// Unknown City
keys
Get a list of the keys of an object.
available as: transform
type keys = <T extends object, K extends keyof T>(obj: T) => K[];
Example
const pet = { name: "Lessy", animal: "dog", breed: "Colie" };
const ctx = {pet};
jexl.evalSync(`pet|keys()`, ctx);
// ["name", "animal", "breed"]
pick
Extract a subset from an object into a new object. Use .
to extract subkeys.
available as: transform
type pick = <T extends object>(obj: T, paths: string[]) => Partial<T>;
Example
const pet = { name: "Lessy", animal: "dog", breed: "Colie" };
const ctx = {pet};
jexl.evalSync(`pet|pick(['name', 'breed'])`, ctx);
// { name: "Lessy", breed: "Colie" }
set
Set a value of an object or array path. Use .
to set subkeys. If path does not exist, subkeys are created.
available as: transform
type set = <T extends object>(obj: T, path: string, value: any) => T;
Example
const person = {name: "Jane"}
const ctx = {person}
jexl.evalSync(`person|set('address.street', 'Mainstreet')`, ctx);
console.log(ctx.person);
// { name: 'Jane', address: { street: 'Mainstreet' } }
unset
Delete a key of an object or array path. Use .
to unset subkeys. If path does not exist, nothing happens.
available as: transform
type unset = <T extends object>(obj: T, path: string) => T;
Example
const user = {username: 'John', locked: true};
const ctx = {user};
// or transform
jexl.evalSync(`user|unset('locked')`, ctx);
console.log(ctx.user);
// { username: 'John' }
values
Get a list of the values of an object.
available as: transform
type values = <T extends object, V extends T[keyof T]>(obj: T) => V[];
Example
const pet = { name: "Lessy", animal: "dog", breed: "Colie" };
const ctx = {pet};
jexl.evalSync(`pet|values()`, ctx);
// ["Lessy", "dog", "Colie"]
String transforms
lower
Converts all characters of the string to lower case.
available as: transform
Example
const msg = 'HELLO';
jexl.evalSync(`msg|lower()`, {msg});
// hello
split
Splits a string into parts using a separator. The default separator is “ “.
available as: transform
Example
const path = "first.second.third";
jexl.evalSync(`path|split('.')`, {path});
// ["first", "second", "third"]
trim
Removes whitespace from both ends of the string.
available as: transform
Example
const msg = " Hello ";
jexl.evalSync(`msg|trim()`, {msg});
// "Hello"
trimStart
Removes whitespace from the start of the string.
available as: transform
Example
const msg = " Hello ";
jexl.evalSync(`msg|trimStart()`, {msg});
// "Hello "
trimEnd
Removes whitespace from the end of the string.
available as: transform
Example
const msg = " Hello ";
jexl.evalSync(`msg|trimEnd()`, {msg});
// " Hello"
upper
Converts all characters of the string to upper case.
available as: transform
Example
const msg = 'hello';
jexl.evalSync(`msg|upper()`, {msg});
// HELLO
Type Cast Transforms
toInt
Cast a string to an integer.
available as: transform
Example
const age = "42";
jexl.evalSync(`age|toInt()`, {age});
// 42
toFloat
Cast a string to a floating point number.
available as: transform
Example
const price = "10.99";
jexl.evalSync(`price|toFloat()`, {price});
// 10.99
toStr
Cast any type to string.
available as: transform
Example
const price = 10.99;
jexl.evalSync(`price|toStr()`, {price});
// "10.99"
toJSON
Calls JSON.stringify on a value.
available as: transform
type toJSON = (val: unknown, space?: number) => string;
If space
is passed as an argument, the JSON string gets formatted using the number of spaces for indentation.
Example
const person = {name: "Jane", age: 35};
jexl.evalsync(`person|toJSON(2)`, {person});
// '{
// "name": "Jane",
// "age": 35
// }'
fromJSON
Calls JSON.parse on a JSON string.
available as: transform
Example
const person = '{"name": "Jane", "age": 35}'
jexl.evalSync(`person|fromJSON()`, {person});
// {name: "Jane", age: 35}
toArray
Alias for list.
Math Transforms
round
Calls Lodash _.round to compute number rounded to precision.
available as: transform
type round = (val: number, precision?: number) => number;
If precision is not set, val is rounded to the nearest integer.
Example
const price = 10.93;
jexl.evalSync(`price|round()`, {price});
// 11
jexl.evalSync(`price|round(1)`, {price});
// 10.9
ceil
Calls Lodash _.ceil to compute number rounded up to precision.
available as: transform
type ceil = (val: number, precision?: number) => number;
If precision is not set, val is rounded up to next integer.
Example
const price = 10.83;
jexl.evalSync(`price|ceil()`, {price});
// 11
jexl.evalSync(`price|ceil(1)`, {price});
// 10.9
floor
Calls Lodash _.floor to compute number rounded down to precision.
available as: transform
type floor = (val: number, precision?: number) => number;
If precision is not set, val is rounded down to integer.
Example
const price = 10.83;
jexl.evalSync(`price|floor()`, {price});
// 10
jexl.evalSync(`price|floor(1)`, {price});
// 10.8
Datetime functions and transforms
now
Constructs a new Date
from current date and time.
available as: function
Example
console.log("This docu part was written at: " + jexl.evalSync(`now()|isoDateTime()`));
// This docu part was written at: 2025-02-14T20:41:02.032Z
date
Constructs a new Date
from given number | string | Date
.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032Z";
jexl.evalSync(`docuTime|date()|year()`, {docuTime});
// 2025
utc
Returns a string representing this date in the RFC 7231 format, with negative years allowed.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032Z";
jexl.evalSync(`docuTime|utc()`, {docuTime});
// 'Fri, 14 Feb 2025 20:51:44 GMT'
isoDate
Returns a string representing this date in the date time string format using only the date part.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032Z";
jexl.evalSync(`docuTime|isoDate()`, {docuTime});
// '2025-02-14'
isoTime
Returns a string representing this date in the date time string format using only the time part.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032Z";
jexl.evalSync(`docuTime|isoTime()`, {docuTime});
// 20:41:02.032Z
isoDateTime
Returns a string representing this date in the date time string format.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032Z";
jexl.evalSync(`docuTime|isoDateTime()`, {docuTime});
// 2025-02-14T20:41:02.032Z
localDate
Returns a string representing the date portion of the given date according to language-specific conventions.
available as: transform
Example
const docuTime = "2025-02-14T20:41:0.032+01:00";
jexl.evalSync(`docuTime|localDate()`, {docuTime});
// e.g. German date format: '14.2.2025'
localTime
Returns a string representing the time portion of the given date according to language-specific conventions.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|localTime()`, {docuTime});
// e.g. German time format: '20:41:02'
localDateTime
Returns a string representing the given date according to language-specific conventions.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|localDateTime()`, {docuTime});
// e.g. German time format: '14.2.2025 20:41:02'
year
Returns the year for the given date according to local time.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|year()`, {docuTime});
// 2025
utcYear
Returns the year for the given date according to universal time.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|utcYear()`, {docuTime});
// 2025
month
Returns the month for the given date according to local time, as a zero-based value (where zero indicates the first month of the year).
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|month()`, {docuTime});
// 1
utcMonth
Returns the month for the given date according to universal time, as a zero-based value (where zero indicates the first month of the year).
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|utcMonth()`, {docuTime});
// 1
day
Returns the day of the month for the given date according to local time.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|day()`, {docuTime});
// 14
utcDay
Returns the day of the month for the given date according to universal time.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|utcDay()`, {docuTime});
// 14
weekDay
Returns the day of the week for the given date according to local time, where 0 represents Sunday.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|weekDay()`, {docuTime});
// 5
utcWeekDay
Returns the day of the week for the given date according to universal time, where 0 represents Sunday.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|utcWeekDay()`, {docuTime});
// 5
hours
Returns the hours for the given date according to local time.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|hours()`, {docuTime});
// 20
utcHours
Returns the hours for the given date according to universal time.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|utcHours()`, {docuTime});
// 19
minutes
Returns the minutes for the given date according to local time.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|minutes()`, {docuTime});
// 41
utcMinutes
Returns the minutes for the given date according to universal time.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|utcMinutes()`, {docuTime});
// 41
seconds
Returns the seconds for the given date according to local time.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|seconds()`, {docuTime});
// 2
utcSeconds
Returns the seconds for the given date according to universal time.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|utcSeconds()`, {docuTime});
// 2
milliseconds
Returns the milliseconds for the given date according to local time.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|milliseconds()`, {docuTime});
// 32
utcMilliseconds
Returns the milliseconds for the given date according to universal time.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|utMilliseconds()`, {docuTime});
// 32
timezoneOffset
Returns the difference, in minutes, between the given date as evaluated in the UTC time zone, and the same date as evaluated in the local time zone.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|timezoneOffset()`, {docuTime});
// Local timezone Europe/Paris: -60
timestamp
Returns the number of milliseconds for the given date since the epoch, which is defined as the midnight at the beginning of January 1, 1970, UTC.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|timestamp()`, {docuTime});
// 1739562062032
addMilliseconds
Adds the number of milliseconds to the given date and returns the resulting timestamp.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|addMilliseconds(10)`, {docuTime});
// 1739562062042
subMilliseconds
Subtracts the number of milliseconds from the given date and returns the resulting timestamp.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|subMilliseconds(10)`, {docuTime});
// 1739562062022
addSeconds
Adds the number of seconds to the given date and returns the resulting timestamp.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|addSeconds(5)`, {docuTime});
// 1739562067032
subSeconds
Subtracts the number of seconds from the given date and returns the resulting timestamp.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|subSeconds(5)`, {docuTime});
// 1739562057032
addMinutes
Adds the number of minutes to the given date and returns the resulting timestamp.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|addMinutes(2)`, {docuTime});
// 1739562182032
subMinutes
Subtracts the number of minutes from the given date and returns the resulting timestamp.
available as: transform
Example
const docuTime = "2025-02-14T20:41:02.032+01:00";
jexl.evalSync(`docuTime|subMinutes(2)`, {docuTime});
// 1739561942032
addHours
Adds the number of hours to the given date and returns the resulting timestamp.
available as: transform
subHours
Subtracts the number of hours from the given date and returns the resulting timestamp.
available as: transform
addDays
Adds the number of days to the given date and returns the resulting timestamp.
available as: transform
subDays
Subtracts the number of days from the given date and returns the resulting timestamp.
available as: transform
addWeeks
Adds the number of weeks to the given date and returns the resulting timestamp.
available as: transform
subWeeks
Subtracts the number of weeks from the given date and returns the resulting timestamp.
available as: transform
Add your own
Coming soon