Code
  • 06 Nov 2024
  • 10 Minutes to read
  • Contributors
  • Dark
    Light
  • PDF

Code

  • Dark
    Light
  • PDF

Article summary

Overview

The Code node provides a convenient way to add custom functionality to your Process by allowing you to access, modify, and create task parameters using JavaScript or Erlang. Although the Code node is highly efficient in speed, you may encounter a timeout error if your code is computationally intensive and takes an extended period to execute or if it includes an infinite loop. If your code requires extra processing power, you can create a dedicated microservice and call it from Corezoid. If you need further assistance, don't hesitate to contact us for custom solutions that will better fit your needs.

The Code node is specifically intended for handling simple code snippets. For more complex coding tasks, we recommend using the Git Call node as a better alternative.

Code2

Settings

The Code node has the following parameters:

  1. (Optional) Title and Description: Name and details of the node.
  2. Code editor: Supports following programming languages:
    • Javascript: Task parameters can be found within the data object, and you can access them using dot notation.

      data.parameter_name
      

      List of supported JavaScript libraries:

      Available CryptoJS methods:

      -module(node).
      -export([main/1]).
      main(Data) -> [{<<"param">>, <<"Hello World!!!">>} | Data].
      
  • XRegExp: XRegExp is an extensive regular expression library for JavaScript, enhancing native RegExp with new capabilities and syntaxes. It simplifies complex regex operations and supports Unicode matching.
  1. Other:

    • Alert if the number of tasks in the node queue reaches the following number: Helps monitor whether the number of tasks in the node exceeds the specified threshold. When selecting the checkbox, you have to enter the needed number of tasks in the field that appears below.
    • Maximum interval, for which the task stays in the node before being forwarded: The amount of time a task is allowed to be in the node can be set in seconds, minutes, hours, and days.
      Note: The checkbox has a minimum value of 30 seconds. You can set a shorter interval by using the Unixtime function.

    Code settings

Examples

Working with date/time using moment.js

In the Code editor form of the Code node details panel, you can write your code in JavaScript using the supported libraries.
Code_Code editor

You can see the example below.

require("libs/moment.js"); 

let datetime = moment().format('MMMM Do YYYY, h:mm a');

data.message = "Hi " + data.name + ". Today is " + datetime +". What a great time to learn Corezoid!" ;
  • require("libs/moment.js"): Import the moment.js library used to obtain the current date and time.
  • let datetime = moment().format('MMMM Do YYYY, h:mm a'): Use the moment() method to obtain the current date and time and the format() method to convert it into a string. The resulting value is assigned to a local variable.
  • data.message = "Hi " + data.name + ". Today is " + datetime +". What a great time to learn Corezoid!": Create a string using the value of the name parameter from the data object and the value of the datetime variable generated. Assign this string to data.message, which creates a new task parameter with the message key and the value of the string.

The data object stores the task parameters: name is an existing task parameter, and message is added as a new one. datetime is a local variable that will not be part of the task; it only exists temporarily while the node processes it.

Moment-timezone

require("libs/moment-timezone.js");
data.date = moment().tz('Europe/Kiev').format("DD-MM-YYYY HH:mm:ss");
  • require("libs/moment-timezone.js"): Import the moment-timezone.js library used to convert and format dates for different time zones.
  • data.date = moment().tz('Europe/Kiev').format("DD-MM-YYYY HH:mm:ss"): Use the moment() method to obtain the current time, the format() method to define the desired format, and the tz() method to change the time zone to Europe/Kiev.

Hashing

  • MD5

    require("libs/md5.js");
    data.md5 = CryptoJS.MD5(data.variable).toString();
    
    • data.variable: Task parameter that will be hashed.
    • data.md5: Task parameter that will store the hash.
  • SHA-1

    require("libs/sha1.js");
    data.sha1 = CryptoJS.SHA1(data.variable).toString();
    
    • data.variable: Task parameter that will be hashed.
    • data.sha1: Task parameter that will store the hash.
  • SHA-512

    require("libs/sha512.js"); 
    data.sha512 = CryptoJS.SHA512(data.variable).toString();
    
    • data.variable: Task parameter that will be hashed.
    • data.sha512: Task parameter that will store the hash.
  • HMAC SHA-1

    require("libs/hmac-sha1.js");
    var hash = CryptoJS.HmacSHA1(data.message, data.secret);
    data.hashInHex = hash.toString(CryptoJS.enc.Hex);
    
    • data.message: Task parameter that will be hashed.
    • data.secret: Task parameter that stores the secret.
    • data.hashInHex: Task parameter that will store the hash as a hexadecimal string.
  • HMAC SHA-256

    require("libs/hmac-sha256.js");
    var hash = CryptoJS.HmacSHA256(data.message, data.secret);
    data.hashInHex = hash.toString(CryptoJS.enc.Hex);
    
    • data.message: Task parameter that will be hashed.
    • data.secret: Task parameter that stores the secret.
    • data.hashInHex: Task parameter that will store the hash as a hexadecimal string.

Ciphers

  • AES

    Encrypting

    require("libs/aes.js");
    data.encrypted = CryptoJS.AES.encrypt(data.message, data.password).toString();
    
    • data.message: Task parameter that will be encrypted.
    • data.password: Task parameter that contains the password.
    • data.encrypted: Task parameter that will store the encrypted string.

    Decrypting

    require("libs/aes.js");
    data.decrypted = CryptoJS.AES.decrypt(data.encrypted, data.password).toString(CryptoJS.enc.Utf8);
    
    • data.encrypted: Task parameter that will be decrypted.
    • data.password: Task parameter that contains the password.
    • data.decrypted: Task parameter that will store the decrypted string.
  • DES

    Encrypting

    require("libs/tripledes.js");
    data.encrypted = CryptoJS.DES.encrypt(data.message, data.password).toString();
    
    • data.message: Task parameter that will be encrypted.
    • data.password: Task parameter that contains the password.
    • data.encrypted: Task parameter that will store the encrypted string.

    Decrypting

    require("libs/tripledes.js");
    data.decrypted = CryptoJS.DES.decrypt(data.encrypted, data.password).toString(CryptoJS.enc.Utf8);
    
    • data.encrypted: Task parameter that will be decrypted.
    • data.password: Task parameter that contains the password.
    • data.decrypted: Task parameter that will store the decrypted string.
  • Triple DES

    Encrypting

    require("libs/tripledes.js");
    data.encrypted = CryptoJS.TripleDES.encrypt(data.message, data.password).toString();
    
    • data.message: Task parameter that will be encrypted.
    • data.password: Task parameter that contains the password.
    • data.encrypted: Task parameter that will store the encrypted string.

    Decrypting

    require("libs/tripledes.js");
    data.decrypted = CryptoJS.TripleDES.decrypt(data.encrypted, data.password).toString(CryptoJS.enc.Utf8);
    
    • data.encrypted: Task parameter that will be decrypted.
    • data.password: Task parameter that contains the password.
    • data.decrypted: Task parameter that will store the decrypted string.
  • Rabbit
    Encrypting

    require("libs/rabbit.js");
    data.encrypted = CryptoJS.Rabbit.encrypt(data.message, data.password).toString();
    
    • data.message: Task parameter that will be encrypted.
    • data.password: Task parameter that contains the password.
    • data.encrypted: Task parameter that will store the encrypted string.

    Decrypting

    require("libs/rabbit.js");
    data.decrypted = CryptoJS.Rabbit.decrypt(data.encrypted, data.password).toString(CryptoJS.enc.Utf8);
    
    • data.encrypted: Task parameter that will be decrypted.
    • data.password: Task parameter that contains the password.
    • data.decrypted: Task parameter that will store the decrypted string.
  • RC4
    Encrypting

    require("libs/rc4.js");
    data.encrypted = CryptoJS.RC4.encrypt(data.message, data.password).toString();
    
    • data.message: Task parameter that will be encrypted.
    • data.password: Task parameter that contains the password.
    • data.encrypted: Task parameter that will store the encrypted string.

    Decrypting

    require("libs/rc4.js");
    data.decrypted = CryptoJS.RC4.decrypt(data.encrypted, data.password).toString(CryptoJS.enc.Utf8);
    
    • data.encrypted: Task parameter that will be decrypted.
    • data.password: Task parameter that contains the password.
    • data.decrypted: Task parameter that will store the decrypted string.

Encoders

Base64

  • Encoding

    require("libs/base64.js");
    var wordArray = CryptoJS.enc.Utf8.parse(data.variable);
    data.base64 = CryptoJS.enc.Base64.stringify(wordArray);
    
    • data.variable: Task parameter that will be encoded.
    • wordArray: Tocal variable that stores a wordArray representation of data.variable.
    • data.base64: Task parameter that will store the encoded string.
  • Decoding

    require("libs/base64.js");
    var words = CryptoJS.enc.Base64.parse(data.base64);
    data.parsedStr = words.toString(CryptoJS.enc.Utf8);
    
    • data.base64: Task parameter that will be decoded.
    • words: Tocal variable that stores a wordArray representation of data.base64.
    • data.parsedStr: Task parameter that will store the decoded string.

JWT Token

  • Encoding

    require("libs/hmac-sha256.js");
    require("libs/base64.js");
    
    // Custom function to base64URL encode a string manually (pure JS)
    function base64UrlEncode(input) {
    // Convert the input to a word array
    const wordArray = CryptoJS.enc.Utf8.parse(input);
    // Convert the word array to a base64 string
    let base64String = CryptoJS.enc.Base64.stringify(wordArray);
    // Perform base64URL encoding (replace characters and remove padding)
    base64String = base64String.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
    return base64String;
    }
    // Function to create a secure HMAC SHA-256 signature
    function createSignature(message, secret) {
    // Generate HMAC SHA-256 signature using the loaded library
    const hash = CryptoJS.HmacSHA256(message, secret);
    // Convert the hash to a base64-encoded string
    const base64 = CryptoJS.enc.Base64.stringify(hash);
    // Convert base64 to base64url
    return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
    }
    // Function to generate the JWT token
    function generateJwtToken(header, payload, secret) {
    // Step 1: Encode the header and payload
    const encodedHeader = base64UrlEncode(JSON.stringify(header));
    const encodedPayload = base64UrlEncode(JSON.stringify(payload));
    // Step 2: Create the signature using HMAC-SHA256
    const message = `${encodedHeader}.${encodedPayload}`;
    const signature = createSignature(message, secret);
    // Step 3: Return the final JWT
    return `${message}.${signature}`;
    }
    
    const header = {
    alg: "HS256",
    typ: "JWT"
    };
    
    const payload = data.payload;
    const secret = data.secret;
    data.jwtToken = generateJwtToken(header, payload, secret);
    
  • Decoding

    require("libs/base64.js");
    require("libs/hmac-sha256.js");
    
    // Base64Url encode function
    function base64UrlEncode(input) {
    return CryptoJS.enc.Base64.stringify(input)
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '');
    }
    
    // Base64Url decode function
    function base64UrlDecode(input) {
    let base64 = input.replace(/-/g, '+').replace(/_/g, '/');
    while (base64.length % 4) {
    base64 += '=';
    }
    return CryptoJS.enc.Base64.parse(base64);
    }
    
    // Create HMAC SHA-256 signature
    function createSignature(message, secret) {
    const hash = CryptoJS.HmacSHA256(message, secret);
    return base64UrlEncode(hash);
    }
    
    // Decode and validate JWT token
    function decodeAndValidateJwtToken(token, secret) {
    const parts = token.split('.');
    if (parts.length !== 3) {
    throw new Error('Invalid JWT token format');
    }
    
    // Decode header and payload
    const header = JSON.parse(CryptoJS.enc.Utf8.stringify(base64UrlDecode(parts[0])));
    const payload = JSON.parse(CryptoJS.enc.Utf8.stringify(base64UrlDecode(parts[1])));
    const providedSignature = parts[2];
    
    // Store decoded parts and original signature
    data.jwtHeader = header;
    data.jwtPayload = payload;
    data.jwtSignature = providedSignature;
    
    // Validate signature if secret is provided
    if (secret) {
    const message = `${parts[0]}.${parts[1]}`;
    const expectedSignature = createSignature(message, secret);
    
    data.signatureValidation = (expectedSignature === providedSignature) ? 'success' : 'failed';
    } else {
    data.signatureValidation = 'not performed';
    }
    
    // Validate token expiration
    const currentTime = Math.floor(Date.now() / 1000);
    if (payload.exp && payload.exp < currentTime) {
    data.tokenStatus = 'expired';
    } else {
    data.tokenStatus = 'valid';
    }
    }
    
    // Main execution
    try {
    const token = data.token;
    const secret = data.secret || null; // Optional secret for validation
    
    decodeAndValidateJwtToken(token, secret);
    } catch (error) {
    data.error = error.message;
    }
    

XRegExp

  • Extended Syntax: This example demonstrates named capture groups for improved readability and maintainability.

Input (data.input - a text string):

[2024-11-06 14:23:00] INFO: User login successful, User ID: 12345, IP: 192.168.1.1
[2024-11-06 14:23:15] ERROR: Failed to load data, User ID: 12345
[2024-11-06 14:23:30] WARN: User requested invalid action, IP: 192.168.1.2

Code:


require("libs/xregexp.js");
 
// Define the complex multiline regex pattern
const logPattern = XRegExp(`
    ^                                 # Start of the line
    (?<timestamp>\\[[^\\]]+\\])        # Capture timestamp in square brackets
    \\s+                               # Match one or more spaces
    (?<level>\\w+)                     # Capture the log level (INFO, ERROR, etc.)
    :\\s+                              # Match colon and space after level
    (?<action>[^,]+)                   # Capture the user action description (until the first comma)
    (?:,\\s+User\\sID:\\s+(?<userId>\\d+))?  # Optionally match User ID (if available)
    (?:,\\s+IP:\\s+(?<ip>[^\\s,]+))?       # Optionally match IP address (if available)
    $                                 # End of the line
`, 'gm'); // Use 'g' for global matching and 'm' for multiline flag
data.output = [];

// Parse the log text using XRegExp.exec and iterate through matches
let match;
while ((match = XRegExp.exec(data.input, logPattern)) !== null) {
  const logEntry = {
    timestamp: match.timestamp,
    level: match.level,
    action: match.action,
  };

  if (match.userId) {
    logEntry.userId = match.userId;
  }
  if (match.ip) {
    logEntry.ip = match.ip;
  }

  // Output will now be stored in `data.output`
  data.output.push(logEntry);
}

Output (data.output - a JSON array):

[
  {
    "timestamp": "[2024-11-06 14:23:00]",
    "level": "INFO",
    "action": "User login successful",
    "userId": "12345",
    "ip": "192.168.1.1"
  },
  {
    "timestamp": "[2024-11-06 14:23:15]",
    "level": "ERROR",
    "action": "Failed to load data",
    "userId": "12345"
  },
  {
    "timestamp": "[2024-11-06 14:23:30]",
    "level": "WARN",
    "action": "User requested invalid action",
    "ip": "192.168.1.2"
  }
]

  • Unicode Matching: This pattern matches any Unicode letter, showcasing XRegExp's Unicode property support.
require("libs/xregexp.js");
XRegExp('\\p{L}');

Error handling & troubleshooting

When an error occurs in the Code node, a task goes to the auxiliary Condition output node that
is used for storing error parameters.

image.png

When an error occurs during the task processing, you may see the following error parameter names in the task.

Error parameter nameError type
__conveyor_code_return_type_error__Hardware (system error), Software (error in a node logic/settings).
__conveyor_code_return_type_tag__*Error tag.
__conveyor_code_return_type_description__Error description in human-readable language; can be static or dynamic.

*The error tag __conveyor_code_return_type_tag__ may have the following values.

ValueCauseSolution
code_timeoutCode has been running for too long.Check if your program contains an infinite loop.
code_executing_errorYour code contains an error.Debug your code.
code_return_format_errorYour code has a return statement that doesn't belong in a function and returns a value that isn't an object. The Code node wraps your code into a function, so an unexpected return statement can cause the program to end abruptly.Remove the return statement to resolve the error.
code_return_size_overflowThe size of your code exceeds the specified limit set for your environment.Reduce the size of your code.
code_fatal_errorA hardware error has occurred.Contact the support team for further assistance.

When working with your Process or State Diagram, you may encounter the following issues.

IssueCauseSolution
Failing to access task parameters.The code refers to objects or object properties absent from the task.Define the missing objects or object properties within the Code node or adjust the code to remove all references to them.
A task parameter is referenced without using the data object.Add a data object reference in front of the name of a task parameter. For example: data.amount = 1 is correct; amount = 1 is not correct.
Task parameters are gone.The data object was assigned a new value in the Code node.Data is a special object used by Corezoid to store task parameters. Therefore, access to task parameters will be removed if it is changed. You should avoid reassigning this object and use a different name for your variables instead.

Was this article helpful?

What's Next