Cordial Scripting Language
Cordial Scripting Language (CSL) has a syntax vaguely reminiscent of HCL and SQL.
Names
Compared to the URL-friendly names of resources, CSL uses a more human-readable approach
<resource-type-singular> <id> [for <parent-id>] [with <extension-id>]
resource-type-singularisaddress,credential,user, etc.idis the resource IDparent-idis required if the resource is nestedextension-idis allowed if the resource has extendable names
Examples:
user 19symbol USDC for SOLcredential 3 for eddie
However, note that when filtering (see List below), name fields must still be matched against their API form. For example: list users | name = "users/risk-agent", or users | name = "*/risk-*"
The singular and plural resource types can be written with or without dashes:
access rule 13access-rule 13client key 1list client keys(seeListbelow)
Get
[get] (<name> | $<variable>)
- specifying the string "get" is optional
nameis the full name of a resource, orvariableis a variable name (see below), dereferenced with$
Examples:
get user 19symbol USDC for SOLget $u(uassumed bound user variable)
List
[(get|list)] <resource-type-plural> [for <parent-id>] [ | <filter>]
- specifying one of the strings "get" or "list" is optional
resource-type-pluralisaddresses,credentials,users, etc.parent-idis allowed if the resource is nested, in which case only resources under the given parent are listedfilteroptionally filters results
The filtering language is an instantiation of API 160 (grammar) and will be documented in more detail.
Examples:
usersaddresses for SOLlist rolesoperations | request.action = "update" request.resource = "Account"
Create
create [<variant>] <resource-type-singular> [<resource-id>] [for <parent-id>] [with <extension-id>] [ { <data> } ]
resource-type-singularisaddress,credential,user, etc.variantis required if the resource has variantsparent-idis required if the resource is nestedextension-idis allowed if the resource has extendable namesdatais an optional TOML inline table (subset of the corresponding resource as per API documentation)
The interpreter hangs until
- either the resource is successfully created (which may require another user to approve),
- or the request fails.
Examples:
create human usercreate internal address for SOLcreate role fancy-role { credentials = ["cosmos"], users = ["human"] }create human user fancy-user { roles = ["roles/fancy-role"] }
Note that the data may contain fields of variables, see below.
Update
update (<name> | $<variable>) <data>
nameorvariableare full names of resources or variable names, as inGetdatais a TOML inline table with the new values for fields that are to be changed
The engine currently implements "replace" semantics (as per HTTP PUT). Here, we implement an equivalent of JSON Merge Patch (RFC 7396). This has the downside that we can't delete fields, as TOML has no null values. In the future, we might implement an equivalent of JSON Patch (RFC 6902) instead.
To avoid the "lost update" problem, the engine requires setting the expected next value of version; this is handled automatically.
Examples:
update user eddie { roles = ["roles/admin"] }update $us { roles = ["roles/admin"] }(usassumed bound user variable)update credential 3 for hilda { description = "The red Solo 2" }
Delete
delete (<name> | $<variable>) <data>
nameorvariableare full names of resources or variable names, as inGetandUpdate
Examples:
delete symbol USDC for SOLdelete access rule 123delete $user(userassumed bound user variable)
Variable Assignment
<variable> = ( <name> | <create> )
variableis a valid identifier (not a reserved keyword). The variable name_is special, in that it cannot be referenced later.nameis the name of a resource in the form<resource-type-singular> <id> [for <parent-id>] [with <extension-id>]used in Get.createis a create command as above
A variable is a binding of an identifier to the name of a resource, either explicitly stated, or as the result of creating a resource (if creation is successful).
Examples:
user1 = create human useradmin1 = user admin-1
Variables may later be used (prefixed by $) as argument to Get, or anywhere its name is required.
Example:
addr1 = create internal address for SOL
get $addr1
create internal account warm { addresses = [$addr1] }
The values of the resource corresponding to the variable may also be used wherever such values are required. In this case, the then current value of the resource is used.
Example:
create human user invitee
i1 = create invite client key i1 { code = "1" }
create invite credential for invitee { public_key = $i1.public_key }
Fallible Variable Assignment
<variable>, <err> = ( <create> | <update> | <delete> )
variableis a valid identifier. The variable name_is special, in that it cannot be referenced later.erris a valid identifier. The variable name_is special, in that it cannot be referenced later.createis a create command as aboveupdateis a update command as abovedeleteis a delete command as above
If the mutation fails, err has a value, and it may be asserted. This is mostly for testing purposes: To prove an operation is denied is to attempt it and fail.
The variable is only bound if creation succeeds.
Example:
a = create internal address for SOL
b = create internal address for SOL
_, err = create transfer { from = $a, to = $b, asset = "SOL", amount = "1" }
assert err
create allow transfer-rule { asset = "SOL", from = $a, to = $b }
t = create transfer { from = $a, to = $b, asset = "SOL", amount = "1" }
Assertions
assert <error>
erroris a valid identifier
This command fails if error is not bound to an error.
For Loops
for <variable> in <list> { <command> }
variableis a valid identifierlistis a valid list command (potentially filtered)commandis any command, it can make use of the variable
Examples:
for user in users | name = "legacy-machine*" { delete $user }for address in addresses | variant = "external" { update $address { labels.verified = "false" }}
Settings
set <setting> = <value>
The interpreter has several settings that maybe modified.
Examples:
set sign.with = <client-key>: theclient-keywill be used in the followingset display.strip = (true|false): iftrue, the create/update times and and states of variables will be suppressed when resources are output