@syntropysoft/praetorian
Version:
Praetorian CLI – A universal multi-environment configuration validator for DevSecOps teams. Validate, compare, and secure YAML/ENV files with ease.
167 lines • 5.06 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BasePlugin = void 0;
/**
* Base class for all Praetorian plugins
*
* Plugins extend this class to provide validation rules
* and audit capabilities for specific domains.
*/
class BasePlugin {
constructor(metadata) {
this.rules = [];
if (!metadata || typeof metadata !== 'object') {
throw new Error('Plugin metadata is required');
}
this.metadata = metadata;
this.initializeRules();
}
/**
* Get plugin metadata
*/
getMetadata() {
return this.metadata;
}
/**
* Get all validation rules for this plugin
*/
getRules() {
return this.rules.filter(rule => rule.enabled);
}
/**
* Get a specific rule by ID
*/
getRule(ruleId) {
if (!ruleId || typeof ruleId !== 'string') {
return undefined;
}
return this.rules.find(rule => rule.id === ruleId && rule.enabled);
}
/**
* Validate a configuration using this plugin's rules
*/
async validate(config, context) {
if (!config || typeof config !== 'object') {
throw new Error('Configuration is required');
}
if (!context || typeof context !== 'object') {
throw new Error('Context is required');
}
const initialMetadata = createInitialMetadata(this.metadata);
const rules = this.getRules();
if (rules.length === 0) {
return createEmptyValidationResult(this.metadata);
}
const results = await Promise.all(rules.map(rule => this.executeRuleSafely(rule, config, context)));
return aggregateValidationResults(results, this.metadata);
}
/**
* Add a validation rule to this plugin
*/
addRule(rule) {
if (!rule || typeof rule !== 'object') {
throw new Error('Rule is required');
}
this.rules.push(rule);
}
/**
* Enable or disable a rule
*/
setRuleEnabled(ruleId, enabled) {
if (!ruleId || typeof ruleId !== 'string') {
return false;
}
if (typeof enabled !== 'boolean') {
return false;
}
const rule = this.rules.find(r => r.id === ruleId);
if (rule) {
rule.enabled = enabled;
return true;
}
return false;
}
/**
* Get plugin health status
*/
async getHealth() {
try {
return { healthy: true };
}
catch (error) {
return createUnhealthyResult(error);
}
}
/**
* Execute a rule safely with error handling
*/
async executeRuleSafely(rule, config, context) {
try {
const result = await this.executeRule(rule, config, context);
return {
success: result.success,
errors: result.errors || [],
warnings: result.warnings || [],
ruleId: rule.id,
severity: rule.severity
};
}
catch (error) {
return createRuleErrorResult(error, rule, this);
}
}
}
exports.BasePlugin = BasePlugin;
// Pure functions for functional programming approach
const createInitialMetadata = (metadata) => ({
plugin: metadata.name,
version: metadata.version,
rulesChecked: 0,
rulesPassed: 0,
rulesFailed: 0
});
const createEmptyValidationResult = (metadata) => ({
success: true,
errors: [],
warnings: [],
metadata: createInitialMetadata(metadata)
});
const createUnhealthyResult = (error) => ({
healthy: false,
message: error instanceof Error ? error.message : 'Unknown health check error'
});
const createRuleErrorResult = (error, rule, plugin) => ({
success: false,
errors: [{
code: 'PLUGIN_ERROR',
message: `Plugin ${plugin.getMetadata().name} failed to execute rule ${rule.id}: ${getErrorMessage(error)}`,
severity: 'error',
context: { ruleId: rule.id, plugin: plugin.getMetadata().name }
}],
warnings: [],
ruleId: rule.id,
severity: rule.severity
});
const getErrorMessage = (error) => {
return error instanceof Error ? error.message : 'Unknown error';
};
const aggregateValidationResults = (results, metadata) => {
const errors = results.flatMap(result => result.severity === 'error' ? result.errors : []);
const warnings = results.flatMap(result => result.severity !== 'error' ? result.warnings : []);
const rulesChecked = results.length;
const rulesPassed = results.filter(r => r.success).length;
const rulesFailed = results.filter(r => !r.success).length;
return {
success: errors.length === 0,
errors,
warnings,
metadata: {
plugin: metadata.name,
version: metadata.version,
rulesChecked,
rulesPassed,
rulesFailed
}
};
};
//# sourceMappingURL=BasePlugin.js.map