Studio Expressions
  • 03 Jun 2023
  • 7 Minutes to read
  • Dark
    Light

Studio Expressions

  • Dark
    Light

Article Summary

Studio Expressions

Studio expressions operate within a Mozilla Rhino 1.7.12 run context, similar to RapidIdentity Connect Action Sets. That means you can use arbitrary JavaScript within Studio expressions, at the same ECMAScript level as RapidIdentity Connect.

Whereas Connect has a run context containing all of the available actions as well as special variables, like Global, Studio has its own unique set of variables available.

These variables will be listed below.

LOGGER Variable

The LOGGER variable provides a handle on the Studio job logger. You can use the variable to print logs from a Studio expression. Supported methods include:

trace(object)

Emits a string version of the object to the job log at TRACE level if the job log level is at TRACE.

Examples:

LOGGER.trace("Hello, world!")
LOGGER.trace("Source record key: " + SRC.recordKey[0])
LOGGER.trace(SRC.org)
LOGGER.trace(SRC.listRecords("org", null, 1000).length)

debug(object)

Emits a string version of the object to the job log at DEBUG level if the job log level is at DEBUG or lower.

Examples:

LOGGER.debug("Hello, world!")
LOGGER.debug("Source record key: " + SRC.recordKey[0])
LOGGER.debug(SRC.org)
LOGGER.debug(SRC.listRecords("org", null, 1000).length)

info(object)

Emits a string version of the object to the job log at INFO level if the job log level is at INFO or lower.

Examples:

LOGGER.info("Hello, world!")
LOGGER.info("Source record key: " + SRC.recordKey[0])
LOGGER.info(SRC.org)
LOGGER.info(SRC.listRecords("org", null, 1000).length)

warn(object)

Emits a string version of the object to the job log at WARN level if the job log level is at WARN or lower.

Examples:

LOGGER.warn("Hello, world!")
LOGGER.warn("Source record key: " + SRC.recordKey[0])
LOGGER.warn(SRC.org)
LOGGER.warn(SRC.listRecords("org", null, 1000).length)

error(object)

Emits a string version of the object to the job log at ERROR level if the job log level is at ERROR or lower.

Examples:

LOGGER.error("Hello, world!")
LOGGER.error("Source record key: " + SRC.recordKey[0])
LOGGER.error(SRC.org)
LOGGER.error(SRC.listRecords("org", null, 1000).length)

HASH Variable

The HASH variable provides a handle on a hashing helper. Supported methods include:

crc32(toHash[, salt])

CRC32 is a not a secure hash function. Never use for sensitive use cases.

Takes a string toHash and an optional salt string and returns a CRC32 hash string (hex encoded).

Example:

HASH.crc32(SRC.recordKey[0])

md5(toHash[, salt])

MD5 is a not a secure hash function. Never use for sensitive use cases.

Takes a string toHash and an optional salt string and returns a MD5 hash string (Base64 encoded).

Example:

HASH.md5(SRC.recordKey[0])

sha1(toHash[, salt])

SHA-1 is a not a secure hash function. Never use for sensitive use cases.

Takes a string toHash and an optional salt string and returns a SHA-1 hash string (Base64 encoded).

Example:

HASH.sha1(SRC.recordKey[0])

sha256(toHash[, salt])

Takes a string toHash and an optional salt string and returns a SHA-256 hash string (Base64 encoded).

Example:

HASH.sha256(SRC.recordKey[0])

sha384(toHash[, salt])

Takes a string toHash and an optional salt string and returns a SHA-384 hash string (Base64 encoded).

Example:

HASH.sha384(SRC.recordKey[0])

sha512(toHash[, salt])

Takes a string toHash and an optional salt string and returns a SHA-512 hash string (Base64 encoded).

Example:

HASH.sha512(SRC.recordKey[0])

SRC Variable

The SRC variable is a Studio Scriptable Record object. That means it functions as both:

We will cover Scriptable Record objects, including all allowed fields and methods, after introducing the other variable of this type.

(Deprecated) This variable may also be referenced as SOURCE. Prefer SRC.

DEST Variable

The DEST variable is a Studio Scriptable Record object. That means it functions as both:

Scriptable Records

As covered above, both SRC and DEST are instances of Scriptable Records. All Scriptable Records support the following methods:

get(fieldName)

The get method on a record takes a fieldName and returns an array containing the field values. The result array will be empty if no values could be found.

Examples:

// All three of the following return an array like ["<recordKey>"]
SRC.get("recordKey")
SRC["recordKey"]
SRC.recordKey // most idiomatic way

The same examples hold for DEST. Note that if the record is not present (as is the case for SRC on a delete event, or DEST on a create event), the result will be an empty array.

Since the return value is an array, you often need to reference the first element to use the value in operations, e.g. SRC.recordKey[0] to get the actual string value.

getRecord(id)

The getRecord method can take an id (i.e. the internal, Studio identifier shown as the ID in the Data Explorer and accessible on a record as in SRC["@id"][0]) and will return either the Scriptable Record that was found or null otherwise.

Example:

SRC.getRecord("13e285d1-2d40-43fb-b766-ee8cf8b1bd96")

getRecord(typeName, recordKey)

The getRecord method can also take a typeName (as shown in the Data Explorer or the Record Definition) and a recordKey value. It will return either the Scriptable Record that was found or null otherwise.

For an example, if the SRC record is an ID Hub user, then you could do the following to get the associated ID Hub org, assuming at least one org is present on the user record:

SRC.getRecord("org", SRC.org[0])

getRecord(typeName, fieldName, fieldValue)

The getRecord method can also take a typeName (as shown in the Data Explorer or the Record Definition), fieldName, and a fieldValue to perform a search on a different field (the search will look up the record within the type where the given field is equal to the given value). It will return either the first such Scriptable Record that was found or null otherwise.

Example:

SRC.getRecord("org", "name", "Identity High School")

getRecords(ids)

The getRecords method takes an array of ids (i.e. the internal, Studio identifier shown as the ID in the Data Explorer and accessible on a record as in SRC["@id"][0]) and will return an array of Scriptable Records that match (an empty array will be returned if no matches are found).

Example:

SRC.getRecords(["13e285d1-2d40-43fb-b766-ee8cf8b1bd96", "39a1e87c-7f4a-412f-af7c-e11bd24ff3a1"])

getRecords(typeName, fieldName, fieldValue[, maxResults])

The getRecords method can also take a typeName (as shown in the Data Explorer or the Record Definition), fieldName, and a fieldValue to perform a search on a different field (the search will look up the records within the type where the given field is equal to the given value). It will return an array of Scriptable Records that match (an empty array will be returned if no matches are found).

Only the first three args (typeName, fieldName, and fieldValue) are required.

If the maxResults integer is supplied, then the result array will have, at most, maxResults elements. The default value for maxResults, if not specified, is 100.

Examples:

// pull back up to 100 user records from the specified org
SRC.getRecords("user", "org", "96ba55e0-7411-4769-b133-3e5755a968a9")

// pull back at most 1 user record from the specified org
SRC.getRecords("user", "org", "96ba55e0-7411-4769-b133-3e5755a968a9", 1)

listRecords(typeName[, filter, maxResults, orderBy, firstResultIndex])

The listRecords method allows you to pull back an array of Scriptable Records matching complex criteria (similar to the Data Explorer). If no matching records are found, the result will be an empty array.

The only required argument is typeName (as shown in the Data Explorer or the Record Definition).

Beyond that, any sublist of the following args can optionally be supplied:

  • filter an optional filter string using the same syntax as the Data Explorer

    • Default: null, meaning all records, up to the maxResults limit will be supplied
  • maxResults an optional integer limiting the result array size

    • Default: 1000
  • orderBy an optional string specifying which field to order the results by

    NOTE:

    Do not use this unless you really need the results to be ordered, as there is an associated performance overhead with sorting records

    • Default: null, meaning the results will be ordered by id (i.e. the internal, Studio identifier shown as the ID in the Data Explorer and accessible on a record as in SRC["@id"][0])

firstResultIndex an optional integer specifying the index of the first record to skip to in the ordered result set (starting with 1, not 0)

Examples:

// pull back up to 1000 users
SRC.listRecords("user")

// pull back up to 1000 users with the given name Alice
SRC.listRecords("user", "givenName = Alice")

// pull back up to 2 users with the email asmith@idauto.edu
SRC.listRecords("user", "email = asmith@idauto.edu", 2)

// pull back up to 100 users ordered by givenName
SRC.listRecords("user", null, 100, "givenName")

// pull back the next page of 100 users ordered by givenName (i.e. the second set of 100)
SRC.listRecords("user", null, 100, "givenName", 100)

applyAccessGroups(records)

The applyAccessGroups method takes an array of Scriptable Records and returns an array containing only the records that make it through any active, configured Access Groups. Note: this only actually does anything for the SRC variable on a consumer mapping.

Example:

// pulls back up to 1000 org records from the source, then filters them using any
// configured Access Groups, returning only the orgs permitted by the Access Groups
SRC.applyAccessGroups(SRC.listRecords("org", null, 1000))

Was this article helpful?