141 lines
3.9 KiB
TypeScript
141 lines
3.9 KiB
TypeScript
![]() |
import { Trigger, TriggerType } from "../model/process_model.js";
|
||
|
import * as vm from "node:vm";
|
||
|
import { IHashesCache } from "./files_change_notifier_service.js";
|
||
|
import { EventsFileChanger } from "../model/meta_data_file_manager_model.js";
|
||
|
import { Result } from "../helper/result.js";
|
||
|
import { TypedEvent } from "../helper/typed_event.js";
|
||
|
|
||
|
export class TriggerCallResult {
|
||
|
results: Array<TriggerSuccessResult | TriggerErrorReport>;
|
||
|
|
||
|
constructor(results: Array<TriggerSuccessResult | TriggerErrorReport>) {
|
||
|
this.results = results;
|
||
|
}
|
||
|
|
||
|
get isErrorComputed(): Result<boolean, boolean> {
|
||
|
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<TriggerCallResult> {
|
||
|
context = {};
|
||
|
|
||
|
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 {
|
||
|
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<Result<boolean, boolean>> {
|
||
|
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<TriggerSuccessResult>
|
||
|
): 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);
|
||
|
}
|
||
|
}
|