@syngrisi/syngrisi
Version:
Syngrisi - Visual Testing Tool
136 lines • 4.73 kB
JavaScript
// src/server/plugins/builtin/custom-check-validator/plugin.ts
import fs from "fs";
import vm from "vm";
function loadScript(config, logger) {
let scriptSource;
if (config.script) {
scriptSource = config.script;
} else if (config.scriptPath && fs.existsSync(config.scriptPath)) {
try {
scriptSource = fs.readFileSync(config.scriptPath, "utf-8");
logger.info(`Loaded validation script from: ${config.scriptPath}`, { scope: "custom-check-validator" });
} catch (error) {
logger.error(`Failed to load validation script: ${error}`, { scope: "custom-check-validator" });
return null;
}
}
if (!scriptSource) {
return null;
}
try {
const wrappedScript = `
(function(ctx) {
${scriptSource}
})
`;
const script = new vm.Script(wrappedScript, {
filename: "validation-script.js"
});
const sandbox = {};
const context = vm.createContext(sandbox);
const fn = script.runInContext(context);
return fn;
} catch (error) {
logger.error(`Failed to compile validation script: ${error}`, { scope: "custom-check-validator" });
return null;
}
}
function createCustomCheckValidator(config = {}) {
const fullConfig = {
mismatchThreshold: config.mismatchThreshold ?? 0,
scriptPath: config.scriptPath,
script: config.script
};
let validationScript = null;
return {
manifest: {
name: "custom-check-validator",
version: "1.0.0",
description: "Custom check validation with threshold and scripting support",
author: "Syngrisi Team",
routes: ["/v1/client/*"],
priority: 50
},
async onLoad(context) {
Object.assign(fullConfig, context.pluginConfig);
context.logger.info("Custom Check Validator plugin loaded", {
scope: "custom-check-validator",
msgType: "PLUGIN",
mismatchThreshold: fullConfig.mismatchThreshold,
hasScript: !!(fullConfig.script || fullConfig.scriptPath)
});
validationScript = loadScript(fullConfig, context.logger);
},
hooks: {
"check:afterCompare": async (checkContext, compareResult, pluginContext) => {
const logger = pluginContext.logger;
const logOpts = { scope: "custom-check-validator", msgType: "VALIDATE" };
let resultData = {};
try {
if (compareResult.result) {
resultData = JSON.parse(compareResult.result);
}
} catch {
}
const mismatch = resultData.rawMisMatchPercentage ?? 0;
if (fullConfig.mismatchThreshold > 0 && mismatch > 0 && mismatch < fullConfig.mismatchThreshold) {
logger.info(
`Mismatch ${mismatch}% is below threshold ${fullConfig.mismatchThreshold}%, marking as passed`,
logOpts
);
return {
...compareResult,
status: "passed",
failReasons: [],
result: JSON.stringify({
...resultData,
pluginOverride: {
plugin: "custom-check-validator",
reason: `Mismatch ${mismatch}% below threshold ${fullConfig.mismatchThreshold}%`
}
}, null, " ")
};
}
if (validationScript) {
const validationContext = {
check: checkContext,
result: compareResult,
resultData,
log: (msg) => logger.debug(`[script] ${msg}`, logOpts)
};
try {
const scriptResult = validationScript(validationContext);
if (scriptResult && scriptResult.status) {
logger.info(
`Script override: status=${scriptResult.status}, message=${scriptResult.message || "none"}`,
logOpts
);
return {
...compareResult,
status: scriptResult.status,
failReasons: scriptResult.failReasons ?? (scriptResult.status === "passed" ? [] : compareResult.failReasons),
result: JSON.stringify({
...resultData,
pluginOverride: {
plugin: "custom-check-validator",
reason: scriptResult.message || "Custom script override",
originalStatus: compareResult.status
}
}, null, " ")
};
}
} catch (error) {
logger.error(`Validation script error: ${error}`, logOpts);
}
}
return compareResult;
}
}
};
}
var plugin_default = createCustomCheckValidator;
export {
createCustomCheckValidator,
plugin_default as default
};
//# sourceMappingURL=plugin.js.map