Extensions
TL;DR
Script signature
An automation script must conform to the given interface:
export interface Script extends ScriptFile {
label?: string;(1)
description?: string;(2)
security?: {(3)
runAs?: string;
deny: string[];
allow: string[];
}|string;
triggers?: Trigger[];(4)
iterator?: Iterator;(5)
exec?: ScriptFn;
}
1 | User-friendly name for the script. |
2 | Additional description if needed. |
3 | Security context for the script; if defining runAs , you can provide a string. |
4 | Script triggers; refer to Automation triggers for details. |
5 | Script iterator; refer to [extensions:automation-iterators] for details. |
File structure
Server-scripts
/server-scripts (1)
/... (2)
1 | Root folder for all server scripts (under each search path). |
2 | Undefined file structure; can be defined as needed. |
Client-scripts
/client-scripts (1)
/auth (2)
/... (7)
/admin (3)
/... (7)
/compose (4)
/... (7)
/messaging (5)
/... (7)
/shared (6)
/... (7)
1 | Root folder for all client scripts (under each search path). |
2 | Defines a bundle for Corteza Auth. |
3 | Defines a bundle for Corteza Admin. |
4 | Defines a bundle for Corteza Low Code. |
5 | Defines a bundle for Corteza Messaging. |
6 | Reserved directory for any shared logic, such as custom libraries, assets, … |
7 | Undefined file structure; can be defined as needed. |
Server-scripts
Server-scripts are executed in the Corteza Corredor server.
Client-scripts
Client-scripts are executed in the client’s browser (user agent; UA).
Automation triggers
An automation triggers specify under what conditions an automation script should be executed execute and its execution context.
Explicit triggers
Explicit triggers execute on a specific user invocation, such as a button press. These include:
-
Manual.
Implicit triggers
Implicit triggers execute as a collateral to another system event such as record creation. These triggers include any before/after event. For a full list of events see resources and events.
Deferred triggers
The minimum time precision is 1 minute. |
Requires explicit security context. |
Only available inside server-scripts. |
Deferred automation triggers are executed at a specific point in time; once or multiple times, such as a reminder. These include:
-
Scheduled,
-
interval.
Scheduled triggers use a ISO 8601 timestamp. |
Interval triggers use cron expressions. |
Sink triggers
Only available inside server-scripts. |
Requires explicit security context. |
Sink automation triggers are executed on a specific http request. They can be used to implement new routes on the API, such as a web hook to some external service.
Automation iterators
An automation iterators specify under what conditions an automation script iterator should execute and part of the execution context.
The given operation is executed over a set of resources defined by the iterator. |
Conventions
Writing triggers
- Use object destructuring
-
This helps you shorten the entire thing. For example:
// Instead of using:
triggers (t) {
return t.after('create')
.for('compose:record')
.where('module', 'super_secret_module')
},
// you can do:
triggers ({ after }) {
return after('create')
.for('compose:record')
.where('module', 'super_secret_module')
},
// Neat, right?!
- Make trigger constraints as strict as possible
-
Having loose constraints can cause unwanted issues when there are multiple namespaces under the same Corteza Low Code. Two namespaces could easily define a module with the same handle, which would cause both of them to execute the given script. For example:
// Instead of using:
triggers (t) {
return t.after('create')
.for('compose:record')
.where('module', 'super_secret_module')
},
// you can do:
triggers ({ after }) {
return after('create')
.for('compose:record')
.where('module', 'super_secret_module')
.where('namespace', 'super_secret_namespace')
},
Automation triggers
An automation trigger (later refereed as "trigger") specifies under what conditions an automation script should execute and part of the execution context.
The main difference between triggers and iterators is, that an iterator is executed for multiple resources defined by the constraints, one after another. A trigger is executed for a single resource defined by the constraints. |
Triggers are defined by the triggers (t) {…}
method defined by the automation script.
Triggers are evaluated in an isolated context, outside of the actual automation script. This prevents use of any constants or other symbols defiled outside of the trigger. For example, the following trigger will not work:
|
Trigger and iterator are not compatible; you can only use one or the other within the same automation script. |
Conventions
- Use object destructuring
-
This helps you shorten the entire thing. For example:
// Instead of using:
triggers (t) {
return t.after('create')
.for('compose:record')
.where('module', 'super_secret_module')
},
// you can do:
triggers ({ after }) {
return after('create')
.for('compose:record')
.where('module', 'super_secret_module')
},
// Neat, right?!
- Make trigger constraints as strict as possible
-
Having loose constraints can cause unwanted issues when there are multiple namespaces under the same Corteza Low Code. Two namespaces could easily define a module with the same handle, which would cause both of them to execute the given script. For example:
// Instead of using:
triggers (t) {
return t.after('create')
.for('compose:record')
.where('module', 'super_secret_module')
},
// you can do:
triggers ({ after }) {
return after('create')
.for('compose:record')
.where('module', 'super_secret_module')
.where('namespace', 'super_secret_namespace')
},
Trigger interface
t.on
-
Defines the event type, such as
'manual'
,'request'
(see resources and events).
Not compatible with |
t.before
-
Defines that the automation script is executed before a specific operation occurs.
You can define multiple event types for the given resource. For example:
|
Not compatible with |
t.after
-
Defines that the automation script is executed after a specific operation occurs.
You can define multiple event types for the given resource. For example:
|
Not compatable with |
t.at
-
Defines that the automation script is executed at a specific time, defined as a ISO 8601 timestamp.
Not compatable with |
t.every
-
Defines the interval in which the automation script is executed, defined as a cron expression.
Not compatable with |
t.for
-
Defines the resource type, such as
'compose:record'
(see resources and events). t.where
-
Defines the constraints that must match in order for the automation script to be executed (eg.
t.where('module', 'Lead')
). Refer to constraint resources for the full list of available resources and constraint options. See Trigger constraints for extra bits on this.
You can define multiple constraints inside the same trigger. For example:
|
t.uiProp
-
Defines the visual representation of the manual automation trigger, such as its color and label.
Only available for explicit scripts. |
Trigger types
Explicit
Explicit triggers execute on a specific user invocation, such as a button press. These include:
- Manual
-
They most commonly appear inside Low Code automation page blocks or inside Low Code record list toolbars.
Implicit
Implicit triggers execute as a collateral to another system event such as record creation. These triggers include before/after events. For a full list of available events refer to resources and events.
Deferred
Deferred automation triggers are executed at most once every minute, so you should not define an interval or timestamp that uses higher precision (seconds or milliseconds). |
Deferred automation triggers are executed at a specific point in time; once or multiple times, such as a reminder. These include:
- Scheduled
-
scheduled triggers are executed at an exact time specified by a time stamp in ISO 8601 format (This one —
YYYY-MM-DDTHH:mm:ss.sssZ
). This trigger is executed exactly once. - Interval
-
interval triggers are executed periodically in an interval defined by a cron expression (see robfig/cron package for details).
Trigger constraints
Trigger constraints allow you to specify when the script should be executed based on the resource that would like to execute it. Constraints take 2 + 1 arguments:
t.where(
resourceAttribute,(1)
comparator/value,(2)
[value],(3)
)
1 | The resource attribute that the constraint should check against. Refer to resources and events for a complete list of available things. |
2 | When 2 arguments are provided, this is the value to check against; when 3 arguments are provided, this is the comparison operator; see below. |
3 | When provided, this is the value to check against. |
Available comparison operators:
- Equals (default)
-
-
eq
-
=
-
==
-
===
-
- Not equals
-
-
not eq
-
ne
-
!=
-
!==
-
- Partial comparison
-
-
like
-
Supported wildcards:
|
- Partial comparison; negated
-
-
not like
-
Supported wildcards:
|
- Regex comparison
-
-
~
-
- Regex comparison; negated
-
-
!~
-
Automation iterators
An automation iterator (later refereed as "iterator") specifies under what conditions an automation script iterator should execute and part of the execution context.
The main difference between triggers and iterators is, that an iterator is executed for multiple resources defined by the constraints, one after another. A trigger is executed for a single resource defined by the constraints. |
Iterators are defined by the iterator (i) {…}
method defined by the automation script.
Iterators are evaluated in an isolated context, outside of the actual automation script. This prevents use of any constants or other symbols defiled outside of the iterator. For example, the following iterator will not work:
|
Trigger and iterator are not compatible; you can only use one or the other within the same automation script. |
Iterator interface
i
-
Defines the resource, action and the filter used for resource fetching. Passed object must conform to the interface:
interface {
resourceType: string; (1)
eventType: 'onManual' | 'onInterval' | 'onTimestamp' = 'onManual'; (2)
action: 'update' | 'delete' | 'clone' | '' = ''; (3)
filter: IteratorFilter; (4)
}
1 | define the resource type; see resources and events for details. |
2 | define the event type; see resources and events for details. |
3 | define what action the script performs; see Iterator actions for details, |
4 | define the filter to use. |
interface IteratorFilter {
query: string; (1)
sort: string; (2)
limit: number | string; (3)
offset: number | string; (4)
[_: string]: number | string; (5)
}
1 | SQL like query filter to use (WHERE <query> ). |
2 | SQL like sort to use (ORDER BY <sort> ). |
3 | Maximum number of resource. |
4 | Offset from first record. |
5 | additional non-standard resource specific parameters.
|
Iterator actions
Iterator script doesn’t perform any operation on the resource except if explicitly specified by the |
- update
-
The result of the automation script will be used to update the original resource.
- delete
-
The result of the automation script will be used to delete the original resource.
- clone
-
The result of the automation script will be used to create a new resource with updated values; original resource is left unchanged.
API clients
API clients simplify the process of accessing information stored inside Corteza via the API. API clients can be found in the GitHub corteza-js repository.
When writing automation scripts, these API clients are automatically provided via the execution context.
These API clients greatly simplify the code so you should always use these instead of writing your own. |
Corredor helpers
Corredor helpers simplify some of the more common operations that are usually performed inside automation scripts — creating records, filtering for specific records, creating messages, … These can be found in the GitHub corteza-js repository and the GitHub corteza-vue repository.
When writing automation scripts, these helpers are automatically provided via the execution context.
These helpers greatly simplify the code so you should always use these instead of writing your own. |
These helpers can also be used outside of automation scripts, when creating portals based on Corteza, for example. |
Corredor helpers are context-aware, meaning that they can determine some parts of the execution context on their own. For example, when a script is run for a record creation. ComposeHelper can automatically determine what namespace was used, what module and the created record.
Security Context
The security
property allows you to manage security and access related things from inside the automation script.
Deferred and sink scripts require you to specify the security context as the invoker is unknown. |
Iterators require you to specify the security context as the invoker is unknown. |
You can specify the following:
security.runAs
-
Specify what user credentials should be used when executing the automation script. For example, if the value of
admin@corredor.crust.tech
is provided, the given user’s credentials will be used instead of the invoking user.
This is available only inside server-scripts. |
security.allow
-
Explicitly define what roles have access to the automation script.
security.deny
-
Explicitly define what roles do not have access to the automation script.
Instead of giving users more permissions you can create a new system user with valid permissions and define the scripts security context. |
Script execution
What operation the given script performs is determined by the execution function (referred to as the exec function). The function conforms to the following interface:
interface ScriptFn {
(args: exec.Args, ctx?: exec.Ctx): unknown;
}
Execution arguments
Arguments to a client-script are provided via references to the original objects, meaning that any change to the argument parameter will reflect to the original object. For example, running the following code in the client script’s exec function will reflect the values without the need of returning the updated record.
|
The execution arguments provide an object containing all of the arguments related to the given operation and resource.
For example, when working with records this will contain the $record
, $module
and $namespace
.
Refer to resources and events for a complete list of available arguments.
Execution context
The execution context provides an object containing things related to the given system. It contains:
ctx.console
-
Used for logging. When running in the UA, this will be native
window.console
. When running in Corredor, this will be aPino
instance, ctx.log
-
Shortcut for
ctx.console.log
, ctx.$authUser
-
User object corresponding to the security context,
ctx.SystemAPI
-
API client for Corteza System interaction,
ctx.ComposeAPI
-
API client for Corteza Low Code interaction,
ctx.MessagingAPI
-
API client for Corteza Messaging interaction,
ctx.System
-
Helper class instance for the Corteza System,
ctx.Compose
-
Helper class instance for the Corteza Low Code,
ctx.ComposeUI
-
Helper class instance for the Corteza Low Code user interface,
ctx.Messaging
-
Helper class instance for the Corteza Messaging,
ctx.frontendBaseURL
-
Base URL used by front-end web applications. This is useful when generating URL’s inside server scripts.
Execution result
- Unknown Error
-
An error aborts the script’s execution chain (the current script and all following scripts).
- Aborted Error
-
An error with the value of
'Aborted'
stops the execution of the current automation script. Any further scripts down the chain are executed as usual. false
-
Same as aborted error. A return value of
false
stops the execution of the current automation script. Any further scripts down the chain are executed as usual. - unknown
-
Any other return value specifies that the execution was successful and the following script (if any) can execute.
Debugging
Why is this script not valid?
-
Defined in a
.js
file, -
is located under
client-scripts
orserver-scripts
, -
it defines an
export default {…}
, -
defines at least one valid trigger or iterator,
-
defines a security context if it the script is a sink or deferred,
-
conforms to the Script signature.