DynamicExecutor Module
Introduction
The DynamicExecutor
class is a part of a low-code pipeline framework aimed at executing arbitrary code dynamically. It allows code execution with an optional configuration that controls various aspects like timeout, logging, environment variables, and more.
Table of Contents
Quick Start
ts
import { DynamicExecutor } from "@idealeap/pipeline";
const executor = new DynamicExecutor({ logging: true });
const result = await executor.execute("return args[0] + args[1]", 1, 2);
console.log(result); // Output: 3
import { DynamicExecutor } from "@idealeap/pipeline";
const executor = new DynamicExecutor({ logging: true });
const result = await executor.execute("return args[0] + args[1]", 1, 2);
console.log(result); // Output: 3
Type Definitions
ExecutorConfig
An interface to specify configuration options for the DynamicExecutor
.
ts
interface ExecutorConfig {
timeout?: number;
logging?: boolean;
environment?: Record<string, any>;
allowedBuiltins?: string[];
beforeExecute?: (code: string) => void;
afterExecute?: (result: any, code: string, error?: Error) => void;
validateCode?: (code: string) => boolean;
}
interface ExecutorConfig {
timeout?: number;
logging?: boolean;
environment?: Record<string, any>;
allowedBuiltins?: string[];
beforeExecute?: (code: string) => void;
afterExecute?: (result: any, code: string, error?: Error) => void;
validateCode?: (code: string) => boolean;
}
API
DynamicExecutor Class
constructor(config?: ExecutorConfig)
Creates a new instance of the DynamicExecutor
with optional configuration.
execute<T = any>(code: string, ...args: any[]): Promise<T | null>
Executes the provided code and returns a Promise that resolves to the result or null
if an error occurs.
static run(params: { code: string; config?: ExecutorConfig }): Promise<any>
Static method to run a code block with an optional configuration.
Examples
Basic Usage
ts
const executor = new DynamicExecutor();
const result = await executor.execute("return args[0] * 2", 5);
console.log(result); // Output: 10
const executor = new DynamicExecutor();
const result = await executor.execute("return args[0] * 2", 5);
console.log(result); // Output: 10
With Timeout
ts
const executor = new DynamicExecutor({ timeout: 1000 });
const result = await executor.execute("while(true);", 5);
console.log(result); // Output: Error - Timeout
const executor = new DynamicExecutor({ timeout: 1000 });
const result = await executor.execute("while(true);", 5);
console.log(result); // Output: Error - Timeout
With Logging
ts
const executor = new DynamicExecutor({ logging: true });
const result = await executor.execute("return args[0] + args[1]", 1, 2);
const executor = new DynamicExecutor({ logging: true });
const result = await executor.execute("return args[0] + args[1]", 1, 2);
Using Before and After Hooks
ts
const config: ExecutorConfig = {
beforeExecute: (code) => {
console.log(`About to execute: ${code}`);
},
afterExecute: (result, code, error) => {
if (error) {
console.log(`Error during execution: ${error}`);
} else {
console.log(`Executed ${code} and got result ${result}`);
}
},
};
const executor = new DynamicExecutor(config);
const result = await executor.execute("return args[0] + args[1]", 1, 2);
const config: ExecutorConfig = {
beforeExecute: (code) => {
console.log(`About to execute: ${code}`);
},
afterExecute: (result, code, error) => {
if (error) {
console.log(`Error during execution: ${error}`);
} else {
console.log(`Executed ${code} and got result ${result}`);
}
},
};
const executor = new DynamicExecutor(config);
const result = await executor.execute("return args[0] + args[1]", 1, 2);
With Environment Variables
ts
const executor = new DynamicExecutor({
logging: true,
timeout: 5000,
environment: { customVar: "Hello, world!" },
allowedBuiltins: ["fetch"],
});
await(async () => {
const result = await executor.execute<number | string | null>(
`
if (fetch) {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const data = await response.json();
return data.id;
} catch (e) {
return 'Fetch failed';
}
} else {
return customVar.length + args[0] + args[1];
}
`,
1,
2,
);
expect(result).toEqual(16);
console.log(result);
})();
const executor = new DynamicExecutor({
logging: true,
timeout: 5000,
environment: { customVar: "Hello, world!" },
allowedBuiltins: ["fetch"],
});
await(async () => {
const result = await executor.execute<number | string | null>(
`
if (fetch) {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const data = await response.json();
return data.id;
} catch (e) {
return 'Fetch failed';
}
} else {
return customVar.length + args[0] + args[1];
}
`,
1,
2,
);
expect(result).toEqual(16);
console.log(result);
})();