import * as vm from "node:vm"; import { IHashesCache } from "./files_change_notifier_service"; import { EventsFileChanger } from "../model/meta_data_file_manager_model"; import { Result } from "../helper/result"; import { TypedEvent } from "../helper/typed_event"; import { Trigger, TriggerType } from "../../features/triggers/trigger_model"; export class TriggerCallResult { results: Array; constructor(results: Array) { this.results = results; } get isErrorComputed(): Result { for (const el of this.results) { if (el instanceof TriggerErrorReport) { return Result.error(true); } } return Result.ok(false); } } export class TriggerSuccessResult { status: boolean; processOutput: any; trigger: string; constructor(status: boolean, trigger: string, processOutput?: any) { this.status = status; this.processOutput = processOutput; this.trigger = trigger; } } export class TriggerErrorReport extends Error { hashes: IHashesCache; trigger: string | Trigger; processOutput: any; constructor( hashes: IHashesCache, trigger: string | Trigger, processOutput?: any ) { super(); this.hashes = hashes; this.trigger = trigger; this.processOutput = processOutput; } } export class TriggerService extends TypedEvent { context: any = {}; constructor(trigger: Trigger, hashes: IHashesCache, path: string) { super(); this.trigger = trigger; this.hashes = hashes; this.path = path; this.triggerResult = null; this.init(); } triggerResult: null | TriggerCallResult; path: string; hashes: IHashesCache; trigger: Trigger; private init(): void { if (this.context["hashes"] != undefined) { this.context["hashes"] = this.hashes; } } private getAllHashesDeleteWithouts(): string[] { return Object.entries(this.hashes).map(([k, v]) => { if (v.event !== EventsFileChanger.delete) { return k.replace(new RegExp(`${this.path}`), ""); } return ""; }); } public async call(): Promise> { if (this.trigger.type === TriggerType.PROCESS) { const triggerResult = await this.triggerTypeProcess(); this.emit(triggerResult); return triggerResult.isErrorComputed; } if (this.trigger.type === TriggerType.FILE) { const triggerResult = await this.triggerTypeFile(); this.emit(triggerResult); return triggerResult.isErrorComputed; } return Result.error(false); } private triggerTypeProcess(): TriggerCallResult { const triggerResult: TriggerSuccessResult[] = []; for (const el of this.trigger.value) { const processOutput = this.processCall(el); triggerResult.push({ status: processOutput ? processOutput : false, processOutput: processOutput, trigger: el, }); } return this.reportTriggerTypeProcess(triggerResult); } private triggerTypeFile(): TriggerCallResult { const files = this.getAllHashesDeleteWithouts(); return new TriggerCallResult( this.trigger.value.map((el) => { let result = false; for (const file of files) { if (result != true) { result = new RegExp(`${el}`).test(file); } } if (result === false) { return new TriggerErrorReport(this.hashes, el); } return new TriggerSuccessResult(result, el); }) ); } private reportTriggerTypeProcess( triggerResult: Array ): TriggerCallResult { return new TriggerCallResult( triggerResult.map((el) => { if (el.status) { return el; } else { return new TriggerErrorReport(this.hashes, el.trigger); } }) ); } private processCall(code: string): undefined | boolean | any { const ctx = vm.createContext(this.context); return vm.runInContext(code, ctx); } }