JavaScript Executor Operator
The JavaScript Executor operator allows you to safely execute custom JavaScript code within workflows, providing powerful data processing and transformation capabilities. Code runs in a secure sandbox with a rich set of built-in utility functions.
Configuration Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
timeout | number | 30000 | Execution timeout in milliseconds, range 1000–300000 |
allowAsync | boolean | false | Whether to allow asynchronous operations |
allowedModules | Array | [] | List of allowed modules, options: lodash, moment, crypto |
maxMemory | number | 52428800 | Memory limit in bytes, default 50MB |
Input Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
code | string | ✅ | JavaScript code to execute, maximum 100KB (100,000 characters) |
parameters | object | ❌ | Parameters passed to the sandbox, accessible in code via parameters or params |
Output Structure
On Success
{
"result": "Return value of user code",
"executedAt": "2025-06-15T10:30:00.000Z",
"codeLength": 150,
"executionTime": 12
}
On Failure
{
"error": "Error message",
"executedAt": "2025-06-15T10:30:00.000Z",
"codeLength": 150,
"failed": true
}
Quick Start
Add a JavaScript Executor node in your workflow and write processing logic:
// Get input parameters
const userAge = parameters.age;
const userName = parameters.name;
// Data processing
if (utils.isNumber(userAge) && userAge >= 18) {
return {
message: `Welcome ${userName}, you are an adult`,
category: 'adult',
canAccess: true
};
} else {
return {
message: `${userName}, you are a minor`,
category: 'minor',
canAccess: false
};
}
Sandbox Available Features
Input Parameter Access
parameters.paramName— Access node input parameters (recommended)params.paramName— Access node input parameters (shorthand alias)context.nodeId.result— Access other nodes' execution results (read-only deep copy)
utils Utility Functions
Type Checking
utils.isString(value) // Is string
utils.isNumber(value) // Is number (and not NaN)
utils.isInteger(value) // Is integer (Number.isInteger)
utils.isFloat(value) // Is floating point (number but not integer)
utils.isBoolean(value) // Is boolean
utils.isObject(value) // Is object (not null, not array)
utils.isArray(value) // Is array (Array.isArray)
utils.isFunction(value) // Is function
utils.isNull(value) // Is null
utils.isUndefined(value) // Is undefined
utils.isEmpty(value) // Is empty (null/undefined/empty string/empty array/empty object)
utils.isEmail(value) // Is email format (regex validation)
utils.isURL(value) // Is URL format (new URL() validation)
utils.isJSON(value) // Is valid JSON string (JSON.parse validation)
Data Validation
utils.validate.required(value, fieldName) // Required validation, throws "fieldName is required" if empty
utils.validate.minLength(value, min, fieldName) // Minimum length validation
utils.validate.range(value, min, max, fieldName) // Numeric range validation
Data Processing
utils.deepClone(obj) // Deep clone (JSON serialization method)
utils.merge(...objects) // Merge objects (Object.assign({}, ...objects))
utils.pick(obj, keys) // Pick specified keys from an object
String Processing
utils.trim(str) // Trim leading and trailing whitespace
utils.uppercase(str) // Convert to uppercase
utils.lowercase(str) // Convert to lowercase
utils.capitalize(str) // Capitalize first letter, lowercase rest
utils.camelCase(str) // Convert to camelCase
utils.truncate(str, length, suffix) // Truncate string (default suffix '...')
Array Processing
utils.unique(arr) // Array deduplication (Set method)
utils.flatten(arr, depth) // Array flattening (default depth 1)
utils.chunk(arr, size) // Array chunking
utils.shuffle(arr) // Randomly shuffle array (Fisher-Yates algorithm)
Object Processing
utils.keys(obj) // Object.keys
utils.values(obj) // Object.values
utils.entries(obj) // Object.entries
utils.hasProperty(obj, prop) // Check if object has property
Math Utilities
utils.math.sum(arr) // Array sum
utils.math.average(arr) // Array average
utils.math.max(arr) // Maximum value
utils.math.min(arr) // Minimum value
utils.math.round(num, decimals) // Round (default 0 decimal places)
Date Utilities
utils.date.formatDate(date, locale) // Format date (default 'zh-CN')
utils.date.toISOString(date) // Convert to ISO 8601 string
utils.date.addDays(date, days) // Add/subtract days from date
Formatting Utilities
utils.format.bytes(bytes, decimals) // Format bytes → "1 KB" (default 2 decimal places)
utils.format.currency(amount, currency, locale) // Format currency (default CNY, zh-CN)
Security Utilities
utils.security.generateId(length) // Generate random alphanumeric ID (default 16 characters)
utils.security.generateUUID() // Generate v4 UUID
utils.security.base64Encode(str) // Base64 encode
utils.security.base64Decode(str) // Base64 decode
crypto Encryption Module
Activation Required
The crypto module requires an administrator to include 'crypto' in the allowedModules configuration array to be available.
Hash Computation
crypto.hash.md5(data) // MD5 hash (hex)
crypto.hash.sha1(data) // SHA-1 hash (hex)
crypto.hash.sha256(data) // SHA-256 hash (hex)
crypto.hash.sha512(data) // SHA-512 hash (hex)
HMAC Signing
crypto.hmac.sha256(data, key) // HMAC-SHA256 signature (hex)
crypto.hmac.sha512(data, key) // HMAC-SHA512 signature (hex)
Encoding Utilities
crypto.encoding.base64Encode(data) // Base64 encode
crypto.encoding.base64Decode(data) // Base64 decode → utf8 string
crypto.encoding.hexEncode(data) // Hex encode
crypto.encoding.hexDecode(data) // Hex decode → utf8 string
Secure Random Numbers
crypto.secure.randomString(length, chars) // Random string (default 32 chars, A-Za-z0-9)
crypto.secure.randomHex(length) // Random hex string (default 32 chars)
crypto.secure.randomBase64(length) // Random base64 string (default 32 chars)
crypto.secure.randomInt(min, max) // Random integer (inclusive of max)
Low-Level API
crypto.createHash(algorithm) // Create Hash instance
crypto.createHmac(algorithm, key) // Create Hmac instance
crypto.randomBytes(size) // Random bytes Buffer
crypto.randomUUID() // UUID string
crypto.randomInt(min, max) // Random integer
Practical Examples
1. User Data Validation and Processing
const email = parameters.email;
const name = parameters.name;
try {
utils.validate.required(email, 'Email');
utils.validate.required(name, 'Name');
if (!utils.isEmail(email)) {
throw new Error('Invalid email format');
}
return {
success: true,
user: {
email: utils.lowercase(email),
name: utils.capitalize(name),
registeredAt: new Date().toISOString()
}
};
} catch (error) {
return { success: false, error: error.message };
}
2. Data Statistics and Analysis
const orders = parameters.orders || [];
const amounts = orders.map(order => order.amount);
const totalAmount = utils.math.sum(amounts);
const averageAmount = utils.math.average(amounts);
return {
summary: {
totalOrders: orders.length,
totalAmount: utils.math.round(totalAmount, 2),
averageAmount: utils.math.round(averageAmount, 2),
maxAmount: utils.math.max(amounts),
minAmount: utils.math.min(amounts),
currency: utils.format.currency(totalAmount)
},
reportGeneratedAt: utils.date.formatDate(new Date())
};
3. Context Data Processing
Access data from other nodes in the workflow:
// Get the previous node's result (context is a read-only deep copy)
const previousData = context.dataProcessorNode?.result?.data;
if (previousData && utils.isArray(previousData)) {
const enhanced = previousData.map(item => ({
...utils.deepClone(item),
processed: true,
timestamp: new Date().toISOString(),
userInput: parameters.userInput
}));
return {
source: 'previous_node',
count: enhanced.length,
data: enhanced
};
}
return { message: 'No preceding data found' };
4. Encryption and Signing
// Requires crypto module to be enabled
const password = parameters.password;
const apiSecret = parameters.apiSecret;
const payload = parameters.payload;
// Password hashing
const hashedPassword = crypto.hash.sha256(password);
// API signing
const signature = crypto.hmac.sha256(
JSON.stringify(payload),
apiSecret
);
// Generate secure token
const token = crypto.secure.randomHex(32);
return {
hashedPassword,
signature,
token,
encodedPayload: crypto.encoding.base64Encode(JSON.stringify(payload))
};
Security Restrictions
Code runs in a secure sandbox, and the following operations are prohibited:
| Category | Prohibited Items |
|---|---|
| Module Imports | require(), import |
| Global Access | process.*, global.* |
| File System | fs.*, __dirname, __filename |
| Process Management | child_process, cluster, worker_threads |
| Dynamic Execution | eval(), Function(), vm.* |
| Prototype Chain | constructor, prototype, this.constructor, arguments.callee |
In the sandbox, setTimeout, setInterval, clearTimeout, and clearInterval are all set to undefined.
Best Practices
- Explicit Return Values: Always use a
returnstatement to return results - Data Validation: Use
utils.validateto validate user input before processing - Error Handling: Wrap main logic in try-catch
- Type Checking: Use
utils.is*methods to check data types
// Recommended code structure
try {
// 1. Parameter validation
const input = parameters.input;
utils.validate.required(input, 'Input data');
// 2. Data processing
const result = processData(input);
// 3. Return result
return {
success: true,
data: result,
timestamp: new Date().toISOString()
};
} catch (error) {
return {
success: false,
error: error.message
};
}
Common Use Cases
- Data Validation: Validate the format and validity of user input
- Data Transformation: Format, clean, and transform data
- Conditional Logic: Execute different processing branches based on conditions
- Data Statistics: Calculate sums, averages, counts, and other statistics
- Text Processing: String formatting, truncation, case conversion
- Array Operations: Filtering, sorting, grouping, deduplication, etc.
- Encryption and Signing: Password hashing, API signing, token generation