Explanation of Notation:
- Values separated by a pipe-symbol (
|
) can be used interchangeably. For example, if you seestring | array
, the function can accept either a string or an array. - A question mark (
?
) implies that something is optional. - Characters and words followed by ellipses (
x...
) indicate that multiple parameters can be supplied
The word predicate is used frequently in the definitions in this topic. In this context, a predicate is a statement or expression that must evaluate to true or false. For example, an expression comparing Hire Date and Seniority Date to see if they are the same is a predicate. If the dates are the same, the predicate evaluates to true. If they aren’t, the predicate evaluates to false.
any(array, (item) => boolean) -> boolean
Given an array and a predicate, return true if the predicate is true for any element in the array.
output = any([1, 2, 3, 4, 5, 6], x => x < 4); // => true
output = any([1, 2, 3, 4, 5, 6], x => x > 6); // => false
block_type(block) -> string
Returns the type/name of a block. For anonymous blocks (those that are the right-hand side of a field assignment), the key is returned.
// Block types of named blocks
foo = { bar = 123; }
baz { qux = 456; }
...
output_foo = block_type(foo); // => "foo"
output_baz = block_type(baz); // => "baz"
...
// Block Type of an anonymous block
named { qux = {}; output = block_type(this.qux); }
...
coalesce(value_to_check, value_if_nil) -> value
If the value to check is nil, return the given value_if_nil; otherwise, return the value itself.
If the value to check is nil
, return the given value_if_nil
; otherwise, return the value itself.
Note that the ??
operator functions like the `coalesce()` function, but has lower precedence.
foo = nil;
bar = 123;
...
output_foo = coalesce(foo, 0); // => 0
output_bar = coalesce(bar, 0); // => 123
concat(array, ...) -> array
Concatenate a series of arrays together into a single new array.
foo = concat([1, 2, 3], [4, 5, 6]); => [1, 2, 3, 4, 5, 6]
contains(block | array, value) -> boolean
If an array is given, returns true
if and only if the array contains the given value. Returns false
otherwise.
If a block is given, returns true
if and only if the given value is a key that the block contains. Returns false
otherwise.
contains([1, 2, 3], 2) // => true
contains([1, 2, 3], 7) // => false
contains({ foo = "bar"; }, "foo") // => true
contains({ foo = "bar"; }, "baz") // => false
date(year, month, day) -> date
Return a date for the given year, month, and day.
d = date(2023, 4, 13) // => 2023-04-13
date_add(date, delta, unit) -> date
Add time to a given date/time. The delta must be an integer. The unit is one of the following strings:
days
months
years
hours
minutes
seconds
milliseconds
For convenience, you can also use the singular version—example, "day"
—of these units.
date_add(date(2023, 1, 3), 1, "day"); // => 2023-01-04
date_diff(date1, date2, unit) -> number
Given two dates and a unit of time, return the difference between those two dates, in that unit of time.
w = date_diff(date(2023, 1, 5), date(2023, 1, 3), "days"); // => 2
x = date_diff(nil, date(2023, 1, 3), "days"); // => nil
y = date_diff(date(2023, 1, 3), nil, "days"); // => nil
z = date_diff(nil, nil, "days"); // => nil
datetime(year, month, day, hour, minute, second) -> date/time
Return a date/time for the given year, month, day, hour, minute, and second.
d = date(2023, 4, 13, 15, 23, 22) // => 2023-04-13T15:23:22
date_within(date, lower_bound, upper_bound) -> boolean
date_within(date, oneParticularDay) -> boolean
Return true
if the date is within a date range from lower_bound
to upper_bound
inclusively, or if the date is within one particular day inclusively. Return false
otherwise.
date_within(date(2023, 4, 13, 15, 23, 22), date(2023, 4, 10), date(2023, 4, 16)) // => true
date_within(date(2023, 4, 13, 15, 23, 22), date(2023, 4, 13)) // => true
day(date) -> number
Return the day part (day of the month) of a date, and return nil
if the date is nil
.
error(message)
Raise an error with the given message. This will stop the integration from completing.
x = error("OH NO");
exists(value) -> boolean
Given a value’s path, determine if that value actually exists in the input data. Note that this isn’t the same thing as a value being nil.
data { a = 123; b = nil; }
does_exist = exists(data.a); // => true
nil_exists = exists(data.b); // => true
does_not_exist = exists(data.c); // => false
external(name) -> value
Given a name, it will find and return the value from the external list of data. If the name isn’t found in the external list, an error will be thrown.
ExternalList = {
"LAST_SUCCESSFUL_RUN_DATE": 2023-06-22T00:00:00
}
external("LAST_SUCCESSFUL_RUN_DATE") // => 2023-06-22T00:00:00
external("NOT_FOUND_NAME") // => error
field(block, field_name) -> value
Given a block and the name of a field (as a string), return the value of that field on the object.
foo { bar = 123; }
...
baz = field(foo, "bar"); // => 123
field(block) -> array of { key = string; value = value; }
Given a block, return an array of key/value pairs for the fields within that object.
foo {
bar = { a = 111; b = 222; };
baz = fields(foo.bar); // => [{ key = "a"; value = 111; }, { key = "b"; value = 222; }]
}
filter(array, (item) => boolean) -> array
Given an array and a predicate, return an array composed of only those elements from the supplied array for which the predicate evaluated to true.
output = filter([1, 2, 3, 4, 5, 6], x => x < 4); // => [1, 2, 3]
find(array, (item) => boolean) -> value
Given an array and a predicate, return the first item in that array for which the predicate evaluates to true, or NilValue
if there is no such item.
output = find([
{ id = "123"; name = "John Doe"; },
{ id = "456"; name = "Jane Doe"; },
{ id = "456"; name = "Nobody"; },
], person => person.id == "456"); // => { id = "456"; name = "Jane Doe"; }
outputNil = find([
{ id = "123"; name = "John Doe"; },
{ id = "456"; name = "Jane Doe"; },
{ id = "789"; name = "Nobody"; },
], person => person.id == "000"); // => nil
find_children(block, child_type...) -> array
Given a block and a number of keys (i.e. strings), return the child blocks of the given block such that the child blocks have any of the given types.
foo { bar { baz = 111; } bar { baz = 222; } }
children = find_children(foo, "bar"); // => bar { baz = 111; } bar { baz = 222; }
find_single(array, (item) => boolean) -> value
Given an array and a predicate, return the only item in that array for which the predicate evaluates to true, or NilValue if there is no such item. If multiple elements match the condition, an error is raised. This combines the semantic of find
and single
.
output = find_single([
{ id = "123"; name = "John Doe"; },
{ id = "456"; name = "Jane Doe"; },
{ id = "456"; name = "Nobody"; },
], person => person.id == "456"); // => { id = "456"; name = "Jane Doe"; }
outputNil = find_single([
{ id = "123"; name = "John Doe"; },
{ id = "456"; name = "Jane Doe"; },
{ id = "789"; name = "Nobody"; },
], person => person.id == "000"); // => nil
errorCase = find_single([
{ id = "111"; name = "John Doe"; },
{ id = "111"; name = "Jane Doe"; },
{ id = "789"; name = "Nobody"; },
], person => person.id == "111"); // => ERROR
first(array, (item) => boolean) -> value
Given an array and a predicate, return the first item in that array for which the predicate evaluates to true. If no predicate is given, the first element of the array will be returned.
output = first([
{ id = "123"; name = "John Doe"; },
{ id = "456"; name = "Jane Doe"; },
{ id = "789"; name = "Nobody"; },
], person => person.id == "456"); // => { id = "456"; name = "Jane Doe"; }
output_no_predicate = first([3, 1, 4]); // => 3
An error will be raised if no elements match the given condition.
flat_map(array, (item) => value) -> array
Given an array and a lambda that returns a value, return an array such that arrays returned by the lambda are “flattened” by one level.
output = flat_map([{ a = [1, 2]; }, { a = [3, 4]; }], x => x.a); // => [1, 2, 3, 4]
Given a block with child blocks with non-overlapping field names, merge the fields of the child blocks into a copy of the parent block and return that.
foo {
bar {
baz = { a = 123; };
qux = { b = 456; };
}
quux = flatten(foo.bar); // => { a = 123; b = 456; }
}
If any child block names are passed, only those blocks will be merged.
format_date(date, format_string) -> string
Given a date and a format string, return a string representation of that date, formatted accordingly.
output = date(2023, 1, 3) |> format_date("MM/dd/yyyy"); // => "01/03/2023"
format_number(number, decimal_places, decimal_separator?) -> string
Given a number, a number of decimal places, and an optional decimal separator, return a corresponding string representation of that number. Note that decimals will be rounded, not truncated.
output1 = format_number(123.456, 2); // => 123.46
output2 = format_number(1111.2222, 2, \\",\\"); // => "1111,22"
identity(value) -> value
Given any value, return that value. This function isn’t usually useful except internally to IDL.
x = identity(123); // => 123
y = identity("test"); // => "test"
is_material(value) -> boolean
Return false if the given value is either nil, missing from the source, or if the value is an empty “container” value, otherwise return true. Container values are values conceptually composed of sub-values--i.e. blocks, arrays, or strings (of characters).
foo { bar = 123; }
...
t = is_material(foo.qux); // => false
u = is_material([]); // => false
v = is_material({}); // => false
w = is_material(nil); // => false
x = is_material(""); // => false
y = is_material(123); // => true
z = is_material("abc"); // => true
Return true if the given value is nil, otherwise return false.
foo { bar = 123; baz = nil; }
...
output_bar = is_nil(foo.bar); // => false
output_baz = is_nil(foo.baz); // => true
join(array, delim) -> number
Concatenate each element in the array as a string, separated by the given delimiter.
x = join([3, 1, 2], ","); // => "3,1,2"
## Last
```txt
last(array, (item) => boolean) -> array
Given an array and a predicate, return the last item in that array for which the predicate evaluates to true.
output = first([1, 2, 3, 4, 5, 6], x => x > 3); // => 6
last(array) -> value
Returns the final/last value of an array.
foo {
bar = [1, 2, 3];
output = last(foo.bar); // => 3
}
length(array) -> number
Return the number of items in an array.
x = length([3, 1, 2]); // => 3
y = length([]); // => 0
map(array, (item, index?) => value) -> array
Given an array and a lambda function that produces a value, return a new array where every item in the new array is a function of the item in the same index in the given array. This is used to transform one array of values into another and is the usually most fundamental operation in any integration.
squared = map([1, 2, 3], x => x * x); // => [1, 4, 9]
names = map([
{ xref = "EMP001"; name = "John"; },
{ xref = "EMP002"; name = "Jane"; },
{ xref = "EMP003"; name = "Alex"; }
], employee => employee.name); // => ["John", "Jane", "Alex"];
output = map([
{ xref = "EMP001", first_name = "John"; last_name = "Smith"; },
{ xref = "EMP002", first_name = "Jane"; last_name = "Doe"; }
], emp => {
id = emp.xref;
full_name = concat(emp.first_nam, " ", emp.last_name);
}); // => [{ id = "EMP001"; full_name = "John Smith"; }, { id = "EMP002"; full_name = "Jane Doe"; }]
map_single(block, (item) => value) -> block
Analogous to map
, except it works on a single block rather than an array, and returns nil with nil input.
output = map_single({ xref = "EMP001", first_name = "John"; last_name = "Smith"; }, emp => {
id = emp.xref;
full_name = concat(emp.first_nam, " ", emp.last_name);
}); // => { id = "EMP001"; full_name = "John Smith"; }
outputNil = map_single(nil, emp => {
id = emp.xref;
}); // => nil
max(array) -> number
max(array, (value) => number) -> number
Return the largest item in an array. Error if the list is empty.
x = max([3, 1, 2]); // => 3
y = max([]); // => error
z = max([{ b = 111; }, { b = 222; }], x => x.b); // => 222
merge(block, block...);
Given a series of blocks with non-overlapping sets of keys, merge them into a new block having all of the keys and values from the given blocks.
result = merge({ a = 1; }, { b = 2; }); // => { a = 1; b = 2; }
min(array) -> number
min(array, (value) => number) -> number
Return the smallest item in an array. Error if the list is empty.
x = min([3, 1, 2]); // => 1
y = min([]); // => error
z = min([{ b = 111; }, { b = 222; }], x => x.b); // => 111
month_end(date) -> datetime
Return end of the month.
month_end(date(2023, 1, 20)); // => 2023-01-31T23:59:59
month_start(date) -> datetime
Return start of the month.
month_start(date(2023, 1, 20)); // => 2023-01-01T00:00:00
now() -> datetime
Return the current date/time, at the time of running the integration. Internally, the time is represented as being in Coordinated Universal Time (or UTC).
x = now(); // => e.g. 2023-01-20T09:22:34
nth(array, index) -> value
Return the n
-th value (that is, the item at the given index) within an array. Note that the first element of an array is at index 0
.
x = nth([3, 1, 2], 0); // => 3
y = nth([3, 1, 2], 1); // => 1
z = nth([3, 1, 2], 2); // => 2
omit() -> [Removed]
Remove the field from the final output. In the below example, the foo block will be empty—that is, won’t have any fields or keys in it—in the output.
foo {
bar = omit();
}
omit_nil(value) -> [Removed] | value
If the given value is nil
, remove the resultant field from the output (like the omit()
function call does); otherwise, return the given value.
foo {
bar = omit_nil(nil); // REMOVED
baz = omit_nil(123); // 123
}
order_by(array, (item) -> value) -> array
order_by_desc(array, (item) -> value) -> array
Given an array and a lambda that will produce a field for any item in the array, return a new array with the items in the original array ordered by the specified field.
The order_by_desc
function is the same except that it uses a descending, rather than ascending, order.
source {
employee {
xref = ""EMP001"";
hire_date = date(2022, 3, 6);
}
employee {
xref = ""EMP002"";
hire_date = date(2020, 1, 2);
}
employee {
xref = ""EMP003"";
hire_date = date(2021, 9, 17);
}
}
destination {
output = source.employee |> order_by_desc(emp => emp.hire_date);
}
pad_left(string, length, paddingCharacter) -> string
Given a string, length and padding character, it will produce a new string with padding characters added to the left of the original string.
w = pad_left(nil, 5, "a"); // => "aaaaa"
x = pad_left("testing", 10, "a"); // => "aaatesting"
y = pad_left("testing", 4, "a"); // => "testing"
z = pad_left("test", 4, "a"); // => "test"
pad_right(string, length, paddingCharacter) -> string
Given a string, length, and padding character, it will produce a new string with padding characters added to the right of the original string.
w = pad_right(nil, 5, "a"); // => "aaaaa"
x = pad_right("testing", 10, "a"); // => "testingaaa"
y = pad_right("testing", 4, "a"); // => "testing"
z = pad_right("test", 4, "a"); // => "test"
parse_date(string) -> date/time
Given a date formatted as a standard date string, parse that date and return it as an IDL date/time value.
date_value = parse_date("2023-03-08"); // => 8 March 2023
parse_number(string) -> number
Given a number, formatted as a string, parse that to an IDL number value.
n = parse_number("123.45"); // => 123.45
reduce(array, (accumulator, item) -> value, initial_value) -> value
Given an array and a reducer function, use that function to produce a single value from the array.
output = reduce([1, 2, 3, 4], (product, x) => product * x, 1); // => 24
replace(string, to_replace, replacement) -> string
Return a new string such that all instances of the string to_replace within the original string have been replaced by the replacement string.
x = replace("This is a test.", "a test", "the result"); // => "This is the result."
round(number, decimal_places) -> number
Given a number and a number of decimal places, it rounds the number to a specified number of fractional digits. When a number is halfway between two others, it will round towards the nearest number away from zero.
output1 = round(2.5, 3); // => 2.500
output2 = round(2.51267, 3); // => 2.513
output3 = round(2.51227, 3); // => 2.512
single(array, (item) => boolean) -> value
Given an array and a predicate, return the first item in that array for which the predicate evaluates to true. If zero or multiple elements match the condition, an error is raised. If no predicate is given, the only element of the array will be returned.
output = single([
{ id = "123"; name = "John Doe"; },
{ id = "456"; name = "Jane Doe"; },
{ id = "789"; name = "Nobody"; },
], person => person.id == "456"); // => { id = "456"; name = "Jane Doe"; }
output_no_predicate = single([3, 1, 4]); // => ERROR
skip(array, n) -> array
Return the remainder of the array, skipping the first n number of items.
x = skip([3, 1, 2], 2); // => [2]
y = skip([3, 1, 2], 0); // => [3, 1, 2]
z = skip([3, 1, 2], 5); // => []
sort(array, (item) -> number) -> array
Given an array and a comparator function, return a new array consisting of the items in the given array, sorted according to the comparator. If no comparator is given, a default sort will be applied.
x = sort([2, 1, 3]); // => [1, 2, 3]
y = sort([
{
xref = "EMP001";
hire_date = date(2023, 1, 2);
},
{
xref = "EMP001";
hire_date = date(2021, 11, 6);
}
]); // => [ { xref = "EMP002"; hire_date = date(2023, 1, 2); }, { xref = "EMP001"; hire_date = date(2021, 11, 6); } ]
split(string, delimiter) -> array
Given a string and a delimiter, return an array of strings where each string in the array is a substring of the original string, each substring being separated by the given delimiter.
x = split("this,is,a,test", ","); // => ["this", "is", "a", "test"]
string_concat(string, ...) -> string
Concatenate a series of strings together into a single string.
bar = string_concat("abc", "def") // => "abcdef"
baz = string_concat("one", nil, "two") // => "onetwo"
string_contains(string, substring, case_insensitive?) -> boolean
If the substring is contained within the given string, return true and return false otherwise. By default, this function is case-sensitive but this can be changed by passing true as the case_insensitive parameter.
output = \\"testing\\" |> string_contains(\\"test\\"); // => true
output = \\"testing\\" |> string_contains(\\"nope\\"); // => false
output = \\"testing\\" |> string_contains(\\"TEST\\"); // => false
test { output = \\"testing\\" |> string_contains(\\"TeSt\\", true); // => true
string_left(string, length) -> string
Return the first length characters in a string.
x = string_left("testing", 4); // => "test"
y = string_left(nil, 4); // => nil
string_right(string, length) -> string
Return the last length characters in a string.
x = string_right("testing", 3); // => "ing"
y = string_right(nil, 3); // => nil
substring(string, start, length) -> string
Return a substring of the given string, starting at the given index and having the given length. If a negative start index is used, the index is counted from the end of the string rather than the beginning. If the indices are out of the bounds of the string, an empty string is returned.
x = substring("testing", 1, 3); // => "est"
y = substring("testing", -3, 2); // => "in"
sum(array) -> number
sum(array, (value) => number) -> number
Return the sum of the items in an array.
x = sum([3, 1, 2]); // => 6
y = sum([]); // => 0
z = sum([{ b = 111; }, { b = 222; }], x => x.b); // => 333
take(array, n) -> array
Return the first n number of items in an array.
x = take([3, 1, 2], 2); // => [3, 1]
y = take([3, 1, 2], 0); // => []
z = take([3, 1, 2], 5); // => [3, 1, 2]
then(input, (value) => value) -> value
Return the result of the given lambda where the lambda’s variable is the input value. The purpose of the then function (read it as “and then do this…”) is to allow you to pipeline things that aren’t functions and, therefore, cannot normally be pipelined.
x = concat("TEST", "_", "ING")
|> then(s => if s == "TESTING" { 111 } else { 222 }); // => 222
to_string(value) -> string
Convert an arbitrary value into a string representation of itself.
foo {
bar = to_string(123); // => "123"
}
today() -> datetime
Return the current date/time with time being midnight.
foo {
bar = today(); // => e.g. 2023-01-20T00:00:00
}
unique(array) -> array
unique(array, (item) -> value) -> array
Given an array and a lambda that will produce a field for any item in the array, return a new array with the unique values.
foo {
bar {
baz = ""EMP001"";
hire_date = date(2022, 3, 6);
}
bar {
baz = ""EMP002"";
hire_date = date(2022, 3, 6);
}
bar {
baz = ""EMP002"";
hire_date = date(2021, 9, 17);
}
w = unique(foo.bar, item => item.baz); // => ["EMP001", "EMP002"]
x = unique(foo.bar, item => item.hire_date); // => [2022-03-06, 2021-09-17]
y = unique([111, 222, 333, 222]); // => [111, 222, 333]
z = unique([111, test, date(2021, 9, 17), 111]); // => [111, "test", 2021-09-17]
}";
vars(values, lambda) -> value
IDL doesn’t have variable scope, except for that in lambda functions. The vars function is used to create named variables and a scope in which they exist.
foo {
bar = 3;
baz = vars([test.input, 4], (x, y) => x * y); // => baz will be equal to 12
}
week_start(date, day_of_week) -> datetime
Return start of the week based on day_of_week.
week_start(date(2023, 4, 12), "Sunday"); // => 2023-04-09T00:00:00