UNPKG

@dawans/promptshield

Version:

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

113 lines (112 loc) 3.79 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Rule = void 0; /** * Represents a single rule in a rulepack */ class Rule { constructor(id, description, matchRegex = [], matchKeywords = [], severity = 'medium', category = 'custom', enabled = true, caseSensitive = false) { this.id = id; this.description = description; this.matchRegex = matchRegex; this.matchKeywords = matchKeywords; this.severity = severity; this.category = category; this.enabled = enabled; this.caseSensitive = caseSensitive; this.validate(); } /** * Validates the rule configuration */ validate() { if (!this.id || this.id.trim() === '') { throw new Error('Rule ID is required'); } if (!this.description || this.description.trim() === '') { throw new Error('Rule description is required'); } if (this.matchRegex.length === 0 && this.matchKeywords.length === 0) { throw new Error('Rule must have either match_regex or match_keywords'); } // Validate regex patterns this.matchRegex.forEach((pattern) => { try { new RegExp(pattern); } catch { throw new Error(`Invalid regex pattern: ${pattern}`); } }); } /** * Checks if this rule has regex patterns */ hasRegexPatterns() { return this.matchRegex.length > 0; } /** * Checks if this rule has keyword patterns */ hasKeywordPatterns() { return this.matchKeywords.length > 0; } /** * Gets compiled regex patterns */ getCompiledRegexPatterns() { const flags = this.caseSensitive ? 'g' : 'gi'; return this.matchRegex.map((pattern) => new RegExp(pattern, flags)); } /** * Gets normalized keywords for matching */ getNormalizedKeywords() { return this.caseSensitive ? this.matchKeywords : this.matchKeywords.map((k) => k.toLowerCase()); } /** * Creates a rule from YAML data */ static fromYaml(data) { // Type guard to ensure data has required properties if (!data || typeof data !== 'object') { throw new Error('Invalid rule data: must be an object'); } const ruleData = data; if (typeof ruleData.id !== 'string') { throw new Error('Invalid rule data: id must be a string'); } if (typeof ruleData.description !== 'string') { throw new Error('Invalid rule data: description must be a string'); } return new Rule(ruleData.id, ruleData.description, Array.isArray(ruleData.match_regex) ? ruleData.match_regex : [], Array.isArray(ruleData.match_keywords) ? ruleData.match_keywords : [], (typeof ruleData.severity === 'string' ? ruleData.severity : 'medium'), (typeof ruleData.category === 'string' ? ruleData.category : 'custom'), ruleData.enabled !== false, Boolean(ruleData.case_sensitive)); } /** * Converts rule to YAML format */ toYaml() { return { id: this.id, description: this.description, ...(this.matchRegex.length > 0 && { match_regex: this.matchRegex }), ...(this.matchKeywords.length > 0 && { match_keywords: this.matchKeywords, }), severity: this.severity, category: this.category, enabled: this.enabled, ...(this.caseSensitive && { case_sensitive: this.caseSensitive }), }; } } exports.Rule = Rule;