UNPKG

@syntropysoft/praetorian

Version:

Praetorian CLI – A universal multi-environment configuration validator for DevSecOps teams. Validate, compare, and secure YAML/ENV files with ease.

232 lines 7.96 kB
"use strict"; /** * @file src/application/services/rule-loading/UltraSimpleRuleDictionary.ts * @description Ultra-simple rule dictionary - ID as key, name as value (SOLID SRP + Functional Programming) */ Object.defineProperty(exports, "__esModule", { value: true }); exports.dictionaryToArray = exports.arrayToDictionary = exports.overrideRulesInDictionary = exports.removeRulesFromDictionary = exports.filterDictionary = exports.getDictionaryStats = exports.hasRule = exports.getRuleNameById = exports.mergeRuleDictionaries = exports.addRulesToDictionary = exports.createEmptyDictionary = void 0; /** * Creates an empty rule dictionary * @returns Empty rule dictionary */ const createEmptyDictionary = () => ({}); exports.createEmptyDictionary = createEmptyDictionary; /** * Adds rules to dictionary, skipping duplicates (Guard Clause Pattern) * @param dictionary - Current dictionary * @param rules - Rules to add (ID -> Name mapping) * @param source - Source identifier for warnings * @returns Dictionary result with added/skipped rules */ const addRulesToDictionary = (dictionary, rules, source = 'unknown') => { // Guard clause: no rules to add if (!rules || Object.keys(rules).length === 0) { return { dictionary, added: [], skipped: [], warnings: [], }; } const newDictionary = { ...dictionary }; const added = []; const skipped = []; const warnings = []; for (const [ruleId, ruleName] of Object.entries(rules)) { // Guard clause: no ID if (!ruleId || ruleId.trim().length === 0) { warnings.push(`Rule from ${source} has no ID, skipping`); continue; } // Guard clause: no name if (!ruleName || ruleName.trim().length === 0) { warnings.push(`Rule '${ruleId}' from ${source} has no name, skipping`); continue; } if (newDictionary[ruleId]) { // Rule already exists skipped.push(ruleId); warnings.push(`Rule '${ruleId}' already exists, skipping duplicate from ${source}`); } else { // Add new rule newDictionary[ruleId] = ruleName; added.push(ruleId); } } return { dictionary: newDictionary, added, skipped, warnings, }; }; exports.addRulesToDictionary = addRulesToDictionary; /** * Merges multiple rule dictionaries (Functional Composition) * @param dictionaries - Array of dictionaries to merge * @param sources - Source identifiers for warnings * @returns Merged dictionary result */ const mergeRuleDictionaries = (dictionaries, sources = []) => { // Guard clause: no dictionaries if (!dictionaries || dictionaries.length === 0) { return { dictionary: (0, exports.createEmptyDictionary)(), added: [], skipped: [], warnings: [], }; } let result = (0, exports.createEmptyDictionary)(); const allAdded = []; const allSkipped = []; const allWarnings = []; for (let i = 0; i < dictionaries.length; i++) { const dict = dictionaries[i]; const source = sources[i] || `source-${i}`; const mergeResult = (0, exports.addRulesToDictionary)(result, dict, source); result = mergeResult.dictionary; allAdded.push(...mergeResult.added); allSkipped.push(...mergeResult.skipped); allWarnings.push(...mergeResult.warnings); } return { dictionary: result, added: allAdded, skipped: allSkipped, warnings: allWarnings, }; }; exports.mergeRuleDictionaries = mergeRuleDictionaries; /** * Gets rule name by ID (Pure Function) * @param dictionary - Rule dictionary * @param ruleId - Rule ID to find * @returns Rule name if found, undefined otherwise */ const getRuleNameById = (dictionary, ruleId) => { return dictionary[ruleId]; }; exports.getRuleNameById = getRuleNameById; /** * Checks if rule exists in dictionary (Pure Function) * @param dictionary - Rule dictionary * @param ruleId - Rule ID to check * @returns True if rule exists */ const hasRule = (dictionary, ruleId) => { return ruleId in dictionary; }; exports.hasRule = hasRule; /** * Gets dictionary statistics (Pure Function) * @param dictionary - Rule dictionary * @returns Statistics about the dictionary */ const getDictionaryStats = (dictionary) => { const ruleIds = Object.keys(dictionary); const ruleNames = Object.values(dictionary); return { totalRules: ruleIds.length, uniqueIds: ruleIds.length, ruleIds: ruleIds.sort(), ruleNames: ruleNames.sort(), }; }; exports.getDictionaryStats = getDictionaryStats; /** * Filters dictionary by predicate (Pure Function) * @param dictionary - Rule dictionary * @param predicate - Filter function * @returns Filtered dictionary */ const filterDictionary = (dictionary, predicate) => { const filtered = {}; for (const [ruleId, ruleName] of Object.entries(dictionary)) { if (predicate(ruleId, ruleName)) { filtered[ruleId] = ruleName; } } return filtered; }; exports.filterDictionary = filterDictionary; /** * Removes rules from dictionary (Pure Function) * @param dictionary - Rule dictionary * @param ruleIds - Rule IDs to remove * @returns New dictionary without specified rules */ const removeRulesFromDictionary = (dictionary, ruleIds) => { const newDictionary = { ...dictionary }; for (const ruleId of ruleIds) { delete newDictionary[ruleId]; } return newDictionary; }; exports.removeRulesFromDictionary = removeRulesFromDictionary; /** * Overrides rules in dictionary (Pure Function) * @param dictionary - Rule dictionary * @param overrides - Rules to override (ID -> Name mapping) * @returns New dictionary with overridden rules */ const overrideRulesInDictionary = (dictionary, overrides) => { const newDictionary = { ...dictionary }; const overridden = []; const warnings = []; for (const override of overrides) { for (const [ruleId, ruleName] of Object.entries(override)) { // Guard clause: no ID in override if (!ruleId || ruleId.trim().length === 0) { warnings.push('Override rule has no ID, skipping'); continue; } // Guard clause: no name in override if (!ruleName || ruleName.trim().length === 0) { warnings.push(`Override rule '${ruleId}' has no name, skipping`); continue; } if (newDictionary[ruleId]) { // Override existing rule newDictionary[ruleId] = ruleName; overridden.push(ruleId); } else { warnings.push(`Cannot override rule '${ruleId}' - rule not found in dictionary`); } } } return { dictionary: newDictionary, added: overridden, skipped: [], warnings, }; }; exports.overrideRulesInDictionary = overrideRulesInDictionary; /** * Converts array of rule objects to dictionary (Pure Function) * @param rules - Array of rule objects with id and name * @returns Dictionary mapping */ const arrayToDictionary = (rules) => { const dictionary = {}; for (const rule of rules) { if (rule.id && rule.name) { dictionary[rule.id] = rule.name; } } return dictionary; }; exports.arrayToDictionary = arrayToDictionary; /** * Converts dictionary to array of rule objects (Pure Function) * @param dictionary - Rule dictionary * @returns Array of rule objects */ const dictionaryToArray = (dictionary) => { return Object.entries(dictionary).map(([id, name]) => ({ id, name })); }; exports.dictionaryToArray = dictionaryToArray; //# sourceMappingURL=UltraSimpleRuleDictionary.js.map