UNPKG

@dawans/promptshield

Version:

Secure your LLM stack with enterprise-grade RulePacks for AI safety scanning

156 lines (155 loc) 4.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RulePack = void 0; const Rule_1 = require("./Rule"); /** * Represents a collection of rules */ class RulePack { constructor(name, description, rules, version = '1.0.0', lastUpdated = new Date()) { this.name = name; this.description = description; this.rules = rules; this.version = version; this.lastUpdated = lastUpdated; this.validate(); } /** * Validates the rulepack configuration */ validate() { if (!this.name || this.name.trim() === '') { throw new Error('RulePack name is required'); } if (!this.description || this.description.trim() === '') { throw new Error('RulePack description is required'); } if (this.rules.length === 0) { throw new Error('RulePack must have at least one rule'); } // Check for duplicate rule IDs const ruleIds = new Set(); this.rules.forEach((rule) => { if (ruleIds.has(rule.id)) { throw new Error(`Duplicate rule ID: ${rule.id}`); } ruleIds.add(rule.id); }); } /** * Gets enabled rules only */ getEnabledRules() { return this.rules.filter((rule) => rule.enabled); } /** * Gets rules by category */ getRulesByCategory(category) { return this.rules.filter((rule) => rule.category === category); } /** * Gets rules by severity */ getRulesBySeverity(severity) { return this.rules.filter((rule) => rule.severity === severity); } /** * Gets rules by multiple categories */ getRulesByCategories(categories) { if (categories.length === 0) return this.rules; return this.rules.filter((rule) => categories.includes(rule.category)); } /** * Gets rules by multiple severities */ getRulesBySeverities(severities) { if (severities.length === 0) return this.rules; return this.rules.filter((rule) => severities.includes(rule.severity)); } /** * Finds a rule by ID */ findRuleById(id) { return this.rules.find((rule) => rule.id === id); } /** * Gets all categories present in this rulepack */ getCategories() { const categories = new Set(this.rules.map((rule) => rule.category)); return Array.from(categories); } /** * Gets all severities present in this rulepack */ getSeverities() { const severities = new Set(this.rules.map((rule) => rule.severity)); return Array.from(severities); } /** * Gets rule count by category */ getRuleCountByCategory() { const counts = {}; this.rules.forEach((rule) => { counts[rule.category] = (counts[rule.category] || 0) + 1; }); return counts; } /** * Gets rule count by severity */ getRuleCountBySeverity() { const counts = {}; this.rules.forEach((rule) => { counts[rule.severity] = (counts[rule.severity] || 0) + 1; }); return counts; } /** * Creates a rulepack from YAML data */ static fromYaml(data) { // Type guard to ensure data has required properties if (!data || typeof data !== 'object') { throw new Error('Invalid rulepack data: must be an object'); } const rulePackData = data; if (typeof rulePackData.name !== 'string') { throw new Error('Invalid rulepack data: name must be a string'); } if (typeof rulePackData.description !== 'string') { throw new Error('Invalid rulepack data: description must be a string'); } if (!Array.isArray(rulePackData.rules)) { throw new Error('Invalid rulepack data: rules must be an array'); } const rules = rulePackData.rules.map((ruleData) => Rule_1.Rule.fromYaml(ruleData)); return new RulePack(rulePackData.name, rulePackData.description, rules, typeof rulePackData.version === 'string' ? rulePackData.version : '1.0.0', typeof rulePackData.last_updated === 'string' ? new Date(rulePackData.last_updated) : new Date()); } /** * Converts rulepack to YAML format */ toYaml() { return { version: this.version, last_updated: this.lastUpdated.toISOString().split('T')[0], name: this.name, description: this.description, rules: this.rules.map((rule) => rule.toYaml()), }; } /** * Creates an empty rulepack */ static empty() { return new RulePack('Empty RulePack', 'No rules defined', []); } } exports.RulePack = RulePack;