Functions:Definitions - bettyblocks/cli GitHub Wiki
A Function Definition describes the input and output of your function. It determines how the IDE renders the ActionStep that is based on the function. And it tells the IDE what values a no-coder can or must configure for the function to work properly.
Given an application cli-wiki
and a function called say-hello
, you can find the function definition in
cli-wiki/functions/say-hello/1.0/function.json
. See new on how to create a new function.
This Function Definition follows strict guidelines, based on the JSON Schema. The JSON Schema can be a bit intimidating at first sight, so we've added several examples below to help you get started.
Example: New Function
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async () => {
// Your implementation
};
export default exampleFunction;
Please note that the function needs to be asynchronous. Given that your function is named sayHello
and it accepts no options, your function head could look like this:
const sayHello = async () => {
The return value should be a named object corresponding to the blueprint (function.json
). Given that your function has an output option that is called greet
:
return { greet: "Hello world!" };
You should export the function as default at the bottom of the file:
export default sayHello;
If your function has (input) options, then your function should receive a named object as a first argument. Given that your function accepts an input option called name
:
const sayHello = async ({ name }) => {
If your function yields child steps, your function should receive a second argument that is an asynchronous function you can invoke / await:
const doSomethingWithChildSteps = async (_, steps) => {
await steps();
If your functions yields paths, the second argument will be an object on which you can await the forEach
function for executing each path:
const condition = async (_, paths) => {
await paths.forEach(async ({ value, steps }, halt) => {
if (value) {
await steps();
halt();
}
});
};
See our native functions for all kinds of examples.
For more information about the available options you can also check the JSON Schema
Example: Action
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "action",
"label": "Action",
"meta": {
"type": "Action"
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({ action }) => {
// e.g.: action === "44af8404efab43d8b825529a4a92aa24"
};
export default exampleFunction;
Example: AuthenticationProfile
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "authenticationProfile",
"label": "Authentication Profile",
"meta": {
"type": "AuthenticationProfile",
"validations": {
"required": true
}
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({ authenticationProfile }) => {
// e.g.: authenticationProfile === {"authenticationProfile":{"id":"4fd6d526ae36494680ae2ba6a5397482","kind":"usernamePassword"},"password":"1234","username":"John Doe"}
// e.g.: authenticationProfile === {"authenticationProfile":{"id":"fda8ec953030423ea139e203f6cfcbc0","kind":"customAuthentication"},"userId":1}
};
export default exampleFunction;
Example: Collection
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "collection",
"label": "Collection",
"meta": {
"type": "Collection"
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({ collection: { data: collection } }) => {
// e.g.: collection === [{id: 1, name: "John Doe"}, {id: 2, name: "Jane Doe"}]
};
export default exampleFunction;
Example: Collection with additional model data
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "collection",
"label": "Collection",
"meta": {
"type": "Collection",
"additional": {
"model": ["name", { "properties": ["kind"] }]
}
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({ collection: { data: collection, model: { name, properties } }) => {
// e.g.: collection === [{id: 1, name: "John Doe"}, {id: 2, name: "Jane Doe"}]
}
export default exampleFunction;
Example: Record
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "record",
"label": "Record",
"meta": {
"type": "Record"
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({
selectedRecord: {
data: { id },
},
}) => {};
export default exampleFunction;
Example: Record with additional model data
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "record",
"label": "Record",
"meta": {
"type": "Record",
"additional": {
"model": ["name", { "properties": ["kind"] }]
}
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({
selectedRecord: {
data: { id },
model: { name: modelName, properties },
},
}) => {};
export default exampleFunction;
Example: Value
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "anyValue",
"label": "Value",
"meta": {
"type": "Value",
"allowedKinds": []
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({ anyValue }) => {};
export default exampleFunction;
Example: Text
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "firstName",
"label": "Firstname",
"meta": {
"type": "Text",
"default": "John"
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({ firstName }) => {
// e.g.: firstName === "Betty"
};
export default exampleFunction;
Example: Number
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "age",
"label": "Age",
"meta": {
"type": "Number",
"default": 18
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({ age }) => {
// e.g.: age >= 18
};
export default exampleFunction;
Example: Boolean
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "adult",
"label": "Adult",
"meta": {
"type": "Boolean",
"default": true
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({ adult }) => {
// e.g.: adult === true
};
export default exampleFunction;
Example: MultilineText
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "info",
"label": "Info",
"meta": {
"type": "MultilineText"
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({ info }) => {
// e.g.: info >= "Information text"
};
export default exampleFunction;
Example: Select
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "language",
"label": "Language",
"meta": {
"type": "Select",
"default": "EN",
"values": [
{ "label": "Dutch", "value": "NL" },
{ "label": "English", "value": "EN" },
{ "label": "German", "value": "DE" }
]
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({ language }) => {
// e.g.: language === "NL"
};
export default exampleFunction;
Example: Model
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "model",
"label": "Model",
"meta": {
"type": "Model"
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({ model }) => {
// e.g.: model === "44af8404efab43d8b825529a4a92aa24"
};
export default exampleFunction;
Example: Property
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"meta": {
"allowedKinds": ["FILE", "IMAGE"],
"type": "Property",
"model": "model",
"validations": {
"required": true
}
},
"configuration": {
"dependsOn": [
{
"option": "model",
"action": "CLEAR"
}
]
},
"name": "property",
"label": "Property"
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({ property: [{ name: propertyName }] }) => {
// e.g.: propertyName === "file"
};
export default exampleFunction;
Example: PropertyMap
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "selectedModel",
"label": "Model",
"meta": {
"type": "Model"
}
},
{
"name": "propertyMapping",
"label": "Assign",
"meta": {
"type": "PropertyMap",
"model": "selectedModel"
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({ selectedModel, propertyMapping }) => {
// e.g.: selectedModel === "44af8404efab43d8b825529a4a92aa24"
// e.g.: propertyMapping === [{key: {name: "firstName"}, value: "Betty"}]
};
export default exampleFunction;
Note: The PropertyMap requires you to set a "model" key, where the value refers to a Model option. In this case the "selectedModel" in the "Assign" option refers to the "Model" option named "selectedModel".
Example: Map
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "headers",
"label": "Headers",
"meta": {
"type": "Map"
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({ headers }) => {
// e.g.: headers === [{"key":"Betty","value":"Blocks"}]
};
export default exampleFunction;
Example: InputVariableMap
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "action",
"label": "Action",
"meta": {
"type": "Action"
}
},
{
"name": "input",
"label": "Input Variables",
"meta": {
"type": "InputVariableMap",
"action": "action"
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({ action, input }) => {
// e.g.: action === "44af8404efab43d8b825529a4a92aa24"
// e.g.: input === [{key: {name: "firstName"}, value: "Betty"}]
};
export default exampleFunction;
Note: The InputVariableMap requires you to set an "action" key, where the value refers to an Action option. In this case, the "action" in the "InputVariableMap" option refers to the "Action" option named "action".
Example: Text
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "result",
"label": "Result",
"meta": {
"type": "Output",
"output": {
"type": "Text"
}
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async () => {
return {
result: "Hello World!",
};
};
export default exampleFunction;
Example: Record
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "selectedModel",
"label": "Model",
"meta": {
"type": "Model"
}
},
{
"name": "result",
"label": "Result",
"meta": {
"type": "Output",
"output": {
"type": "Record",
"model": "selectedModel"
}
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({ selectedModel }) => {
return {
result: "Hello World!",
};
};
export default exampleFunction;
Note: Output is not passed as an argument to your function. Instead, it's a key you have to set in the return object of your function.
Example: Inherit
Inherit will dynamically set the output type based on another input option.cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "action",
"label": "Action",
"meta": {
"type": "Action"
}
},
{
"name": "result",
"label": "Result",
"meta": {
"type": "Output",
"output": {
"type": "Inherit",
"source": "action"
}
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({ selectedModel }) => {
return {
result: await runAction({ id, input }),
};
};
export default exampleFunction;
Note: Output is not passed as an argument to your function. Instead, it's a key you have to set in the return object of your function.
Example: Array
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "result",
"label": "Result",
"meta": {
"type": "Output",
"output": {
"type": "Array",
"dataType": "STRING"
}
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async () => {
return {
result: ["Apple", "Banana", "Orange"],
};
};
export default exampleFunction;
Note: Output is not passed as an argument to your function. Instead, it's a key you have to set in the return object of your function.
Example: Any Of
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"info": "The schema model can be utilized to type the output of this step when it is an object or an array of objects.",
"meta": {
"type": "SchemaModel"
},
"name": "schemaModel",
"label": "Schema Model"
},
{
"name": "result",
"label": "Result",
"meta": {
"type": "Output",
"output": {
"anyOf": [
{ "type": "Text" },
{ "type": "Object", "schemaModel": "schemaModel" },
{
"type": "Array",
"schemaModel": "schemaModel",
"dataType": "SCHEMA"
},
{ "type": "Number" }
]
}
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async () => {
return {
result: "Hello World!",
};
};
export default exampleFunction;
Note: You can use this to provide the option to the user of the action step to choose between multiple output types.
Example: Min/Max
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "age",
"label": "Age",
"meta": {
"type": "Number",
"validations": {
"min": 18,
"max": 88
}
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({ age }) => {
// e.g.: age === 65
};
export default exampleFunction;
Example: Required
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [
{
"name": "model",
"label": "Model",
"meta": {
"type": "Model",
"validations": {
"required": true
}
}
}
],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({ model }) => {
// e.g.: model === {name: "User"}
};
export default exampleFunction;
The Yields field gives functions the option to execute nested steps within your function. We currently support three different values for this field, namely: NONE, ALL, PATHS
You can use this if you don't want any steps to be nested within your function. An example of this is the log function.
Example: NONE
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Misc",
"icon": {
"name": "ActionsIcon",
"color": "Orange"
},
"options": [],
"yields": "NONE"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async () => {};
export default exampleFunction;
You can use this if you want to execute a set of steps nested within your function. Your function implementation is responsible for executing this set of steps. An example of this is the loop function.
Example: ALL
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"description": "Loops through a given collection.",
"label": "Loop",
"category": "FLOW",
"icon": {
"name": "LoopIcon",
"color": "Blue"
},
"options": [
{
"meta": {
"type": "Collection",
"validations": {
"required": true
}
},
"name": "collection",
"label": "Collection",
"info": "The collection you want to loop through."
},
{
"meta": {
"type": "Output",
"output": {
"type": "Record",
"model": "collection",
"scoped": true
},
"validations": {
"required": true
}
},
"name": "iterator",
"label": "Iterator name",
"info": "Iterator info."
},
{
"meta": {
"type": "Output",
"output": {
"type": "Number",
"scoped": true
}
},
"name": "index",
"label": "Index",
"info": "Index info."
}
],
"yields": "ALL"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async ({ collection: { data: collection } }, steps) => {
for (let index = 0; index < collection.length; index += 1) {
// steps contains all steps nested within the loop.
// Which all have "iterator" and "index" as available variables.
await steps({ iterator: collection[index], index });
}
return {};
};
export default exampleFunction;
You can use this if you want to execute sets of steps based on whether one or more conditions are met. Your function implementation is reponsible for deciding which sets of steps, if any, to execute. An example of this is the condition function. Which executes the first set of steps for which the condition is truthy.
Example: PATHS
cli-wiki/functions/exampleFunction/1.0/function.json
:
{
"label": "Example Function",
"description": "Description",
"category": "Flow",
"icon": {
"name": "ConditionIcon",
"color": "Yellow"
},
"paths": {
"min": 1,
"max": 1,
"filterOption": {
"meta": {
"type": "Value",
"allowedKinds": ["BOOLEAN"],
"validations": {
"required": true
}
},
"name": "value",
"label": "Value",
"info": "If this value is evaluated truthy the child steps will be executed."
},
"values": [
{
"label": "True"
}
]
},
"yields": "PATHS"
}
cli-wiki/functions/exampleFunction/1.0/index.js
:
const exampleFunction = async (_, paths) => {
await paths.forEach(async ({ value, steps }, halt) => {
if (value) {
// The steps function contains all steps for a single path.
await steps();
// Be sure to call the halt function if only one path should be evaluated.
halt();
}
});
};
export default exampleFunction;
You can mark specific options with advanced true
. This will hide your options by default and those can be found under an advanced section. This option is optional.
{
"meta": {
"type": "Boolean"
},
"advanced": true,
"name": "advancedOption",
"label": "Advanced Option",
"info": "This option will be rendered in the advanced options section"
}
Note: As of the 25th of October, 2022 we have changed the JSON schema requirement of the icon field from a string to an object.
You can provide your action functions with an icon and color as follows:
{
"name": "ActionsIcon",
"color": "Orange"
}
The available icons can be found here and the available colors are:
- Yellow
- Green
- Pink
- Orange
- Purple
- Blue
- Teal
- Grey