feat: enhance query handling with modules and plugins
- Added ManyToMany relationship for plugins in Query entity. - Updated QueryExecuterController to accept structured query data. - Enhanced QueryExecuterService to support plugin initialization and execution. - Implemented QueryHandlerService methods for creating and updating queries, modules, and plugins. - Introduced new endpoints for creating and adding modules and plugins to queries. - Created Plugin base class and DatabasePlugin implementation for database interactions. - Updated VM class to integrate plugin functionality during script execution. - Added test cases for project, query, module, and plugin operations.
This commit is contained in:
@ -1,20 +1,28 @@
|
||||
import * as ivm from "isolated-vm";
|
||||
import { VModule } from "./module.class";
|
||||
import { Plugin } from "./plugin.class";
|
||||
|
||||
export class Vm {
|
||||
private memoryLimit: number;
|
||||
private modules: VModule[];
|
||||
private context: any;
|
||||
private jail: any;
|
||||
private plugins: Plugin[];
|
||||
private isolate: ivm.Isolate;
|
||||
|
||||
constructor(configs: { memoryLimit: number; modules: VModule[] }) {
|
||||
constructor(configs: {
|
||||
memoryLimit: number;
|
||||
modules: VModule[];
|
||||
plugins: Plugin[];
|
||||
}) {
|
||||
this.memoryLimit = configs.memoryLimit;
|
||||
this.modules = configs.modules;
|
||||
this.plugins = configs.plugins;
|
||||
}
|
||||
|
||||
async init() {
|
||||
const isolate = new ivm.Isolate({ memoryLimit: this.memoryLimit });
|
||||
this.context = isolate.createContext();
|
||||
async init(): Promise<Vm> {
|
||||
this.isolate = new ivm.Isolate({ memoryLimit: this.memoryLimit });
|
||||
this.context = await this.isolate.createContext();
|
||||
this.jail = this.context.global;
|
||||
|
||||
this.jail.set("global", this.jail.derefInto());
|
||||
@ -22,13 +30,22 @@ export class Vm {
|
||||
for (const mod of this.modules) {
|
||||
this.jail.setSync(mod.getName(), mod.getSource());
|
||||
}
|
||||
|
||||
for (const plugin of this.plugins) {
|
||||
this.jail.setSync(
|
||||
plugin.getName(),
|
||||
new ivm.Reference(plugin.run.bind(plugin))
|
||||
);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
setFunction(name: string, func: (...args) => any) {
|
||||
this.jail.setSync(name, func);
|
||||
}
|
||||
|
||||
async runScript(script: string) {
|
||||
async runScript(script: string, args: Record<string, any>): Promise<any> {
|
||||
let resolvePromise: (value: any) => void;
|
||||
let rejectPromise: (reason?: any) => void;
|
||||
|
||||
@ -37,11 +54,14 @@ export class Vm {
|
||||
rejectPromise = reject;
|
||||
});
|
||||
|
||||
this.setFunction("result", (...args) => {
|
||||
this.setFunction("returnResult", (...args) => {
|
||||
console.log("Script result:", args);
|
||||
|
||||
resolvePromise(args);
|
||||
});
|
||||
|
||||
// TODO: log
|
||||
|
||||
this.setFunction("error", (error: any) => {
|
||||
console.error("Script error:", error);
|
||||
rejectPromise(error);
|
||||
@ -51,19 +71,25 @@ export class Vm {
|
||||
(async () => {
|
||||
${script}
|
||||
try {
|
||||
const result = await main()
|
||||
result(result)
|
||||
const result = await main(${JSON.stringify(args)});
|
||||
returnResult(result)
|
||||
} catch (e) {
|
||||
error(e)
|
||||
}
|
||||
})()
|
||||
`;
|
||||
|
||||
const compiledScript = await this.context.isolate.compileScript(
|
||||
scriptWithResult
|
||||
);
|
||||
const compiledScript = await this.isolate.compileScript(scriptWithResult);
|
||||
|
||||
compiledScript.run(this.context);
|
||||
this.onFinish();
|
||||
|
||||
return await resultPromise;
|
||||
}
|
||||
|
||||
onFinish() {
|
||||
this.plugins.forEach((plugin) => {
|
||||
plugin.onFinish();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user