@syntropysoft/praetorian
Version:
Praetorian CLI – A universal multi-environment configuration validator for DevSecOps teams. Validate, compare, and secure YAML/ENV files with ease.
168 lines • 6.6 kB
JavaScript
;
/**
* @file src/application/services/RuleLoaderService.ts
* @description Service for loading and composing validation rules (SOLID SRP refactored)
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.RuleLoaderService = void 0;
const core_rules_1 = require("../../shared/rules/core-rules");
const RuleSetLoader_1 = require("./rule-loading/RuleSetLoader");
const RuleComposer_1 = require("./rule-loading/RuleComposer");
const RuleDictionary_1 = require("./rule-loading/RuleDictionary");
/**
* @class RuleLoaderService
* @description Service for loading and composing validation rules (SOLID SRP)
*/
class RuleLoaderService {
constructor(options = {}) {
this.workingDirectory = options.workingDirectory || process.cwd();
this.includeCoreRules = options.includeCoreRules ?? true;
this.validateRules = options.validateRules ?? true;
}
/**
* Loads rules from a configuration
* @param config - Rule configuration
* @returns Promise with loaded rules and any errors/warnings
*/
async loadRules(config) {
// Guard clause: no config
if (!config) {
return createEmptyResult(['Configuration is required']);
}
try {
// Initialize rule dictionary
let ruleDictionary = (0, RuleDictionary_1.createEmptyDictionary)();
const allWarnings = [];
const allErrors = [];
// Load rule sets and add to dictionary
const ruleSetResults = await this.loadRuleSets(config.ruleSets);
const loadedRules = extractRulesFromResults(ruleSetResults);
// Add loaded rules to dictionary
if (loadedRules.length > 0) {
const dictResult = (0, RuleDictionary_1.addRulesToDictionary)(ruleDictionary, loadedRules, 'rule-sets');
ruleDictionary = dictResult.dictionary;
allWarnings.push(...dictResult.warnings);
}
// Determine if we should include core rules as base
const hasCoreAllRequest = config.ruleSets.includes('@praetorian/core/all');
const shouldIncludeAllCoreRules = this.includeCoreRules &&
(config.ruleSets.length === 0 || hasCoreAllRequest);
// Add core rules to dictionary if needed
if (shouldIncludeAllCoreRules) {
const coreRules = this.getBaseRules();
const coreDictResult = (0, RuleDictionary_1.addRulesToDictionary)(ruleDictionary, coreRules, 'core-rules');
ruleDictionary = coreDictResult.dictionary;
allWarnings.push(...coreDictResult.warnings);
}
// Apply rule overrides using dictionary
if (config.overrideRules && config.overrideRules.length > 0) {
const overrideResult = (0, RuleDictionary_1.overrideRulesInDictionary)(ruleDictionary, config.overrideRules);
ruleDictionary = overrideResult.dictionary;
allWarnings.push(...overrideResult.warnings);
}
// Add custom rules to dictionary
if (config.customRules && config.customRules.length > 0) {
const customDictResult = (0, RuleDictionary_1.addRulesToDictionary)(ruleDictionary, config.customRules, 'custom-rules');
ruleDictionary = customDictResult.dictionary;
allWarnings.push(...customDictResult.warnings);
}
// Get final rules from dictionary
const finalRules = (0, RuleDictionary_1.dictionaryToRules)(ruleDictionary);
// Validate if enabled
const validationWarnings = this.validateRules
? (0, RuleComposer_1.validateLoadedRules)(finalRules)
: [];
return {
rules: finalRules,
errors: [...extractErrorsFromResults(ruleSetResults), ...allErrors],
warnings: [
...extractWarningsFromResults(ruleSetResults),
...allWarnings,
...validationWarnings
],
};
}
catch (error) {
return createEmptyResult([`Failed to load rules: ${error.message}`]);
}
}
/**
* Gets base rules to start with
* @returns Base rules
*/
getBaseRules() {
return this.includeCoreRules ? core_rules_1.ALL_CORE_RULES : [];
}
/**
* Loads multiple rule sets
* @param ruleSetPaths - Array of rule set paths
* @returns Array of rule load results
*/
async loadRuleSets(ruleSetPaths) {
// Guard clause: no rule sets
if (!ruleSetPaths || ruleSetPaths.length === 0) {
return [];
}
const options = {
workingDirectory: this.workingDirectory,
validateRules: this.validateRules,
};
const loadPromises = ruleSetPaths.map(path => (0, RuleSetLoader_1.loadRuleSet)(path, options));
return Promise.all(loadPromises);
}
/**
* Gets available core rule sets
* @returns Available core rule set names
*/
getAvailableCoreRuleSets() {
return Object.keys(core_rules_1.CORE_RULE_SETS);
}
}
exports.RuleLoaderService = RuleLoaderService;
/**
* Creates an empty rule load result with errors
* @param errors - Array of error messages
* @returns Empty result with errors
*/
const createEmptyResult = (errors = []) => ({
rules: [],
errors,
warnings: [],
});
/**
* Extracts rules from multiple load results
* @param results - Array of rule load results
* @returns Combined rules array
*/
const extractRulesFromResults = (results) => {
// Guard clause: no results
if (!results || results.length === 0) {
return [];
}
return results.flatMap(result => result.rules);
};
/**
* Extracts errors from multiple load results
* @param results - Array of rule load results
* @returns Combined errors array
*/
const extractErrorsFromResults = (results) => {
// Guard clause: no results
if (!results || results.length === 0) {
return [];
}
return results.flatMap(result => result.errors);
};
/**
* Extracts warnings from multiple load results
* @param results - Array of rule load results
* @returns Combined warnings array
*/
const extractWarningsFromResults = (results) => {
// Guard clause: no results
if (!results || results.length === 0) {
return [];
}
return results.flatMap(result => result.warnings);
};
//# sourceMappingURL=RuleLoaderService.js.map