@dawans/promptshield
Version:
Secure your LLM stack with enterprise-grade RulePacks for AI safety scanning
176 lines (175 loc) • 6.4 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.YamlRuleRepository = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const yaml = __importStar(require("js-yaml"));
const Result_1 = require("../../../shared/types/Result");
const RulePack_1 = require("../core/entities/RulePack");
/**
* YAML-based rule repository implementation
*/
class YamlRuleRepository {
constructor(defaultRulepackDir = 'rulepacks') {
this.defaultRulepackDir = defaultRulepackDir;
}
/**
* Loads rules from a YAML file
*/
async loadFromYaml(filePath) {
try {
// Check if file exists
if (!fs.existsSync(filePath)) {
return (0, Result_1.err)(new Error(`RulePack file not found: ${filePath}`));
}
// Read file content
const content = await fs.promises.readFile(filePath, 'utf-8');
// Parse YAML
const data = yaml.load(content);
if (!data) {
return (0, Result_1.err)(new Error('Empty or invalid YAML file'));
}
// Create RulePack from YAML data
try {
const rulePack = RulePack_1.RulePack.fromYaml(data);
return (0, Result_1.ok)(rulePack);
}
catch (validationError) {
return (0, Result_1.err)(new Error(`Invalid RulePack format: ${validationError}`));
}
}
catch (error) {
return (0, Result_1.err)(new Error(`Failed to load RulePack from YAML: ${error}`));
}
}
/**
* Saves rules to a YAML file
*/
async saveToYaml(filePath, rulePack) {
try {
// Convert RulePack to YAML format
const yamlData = rulePack.toYaml();
// Convert to YAML string
const yamlContent = yaml.dump(yamlData, {
indent: 2,
lineWidth: -1,
noRefs: true,
sortKeys: false,
});
// Ensure directory exists
const dir = path.dirname(filePath);
if (!fs.existsSync(dir)) {
await fs.promises.mkdir(dir, { recursive: true });
}
// Write to file
await fs.promises.writeFile(filePath, yamlContent, 'utf-8');
return (0, Result_1.ok)(undefined);
}
catch (error) {
return (0, Result_1.err)(new Error(`Failed to save RulePack to YAML: ${error}`));
}
}
/**
* Lists available rulepacks
*/
async listAvailable() {
try {
const rulepackDir = this.defaultRulepackDir;
if (!fs.existsSync(rulepackDir)) {
return (0, Result_1.ok)([]);
}
const files = await fs.promises.readdir(rulepackDir);
const yamlFiles = files
.filter((file) => file.endsWith('.yaml') || file.endsWith('.yml'))
.map((file) => path.join(rulepackDir, file));
return (0, Result_1.ok)(yamlFiles);
}
catch (error) {
return (0, Result_1.err)(new Error(`Failed to list available rulepacks: ${error}`));
}
}
/**
* Gets the default rulepack path
*/
getDefaultPath() {
// Look for default rulepacks in order of preference
const candidates = [
path.join(this.defaultRulepackDir, 'prompt-injection.yaml'),
path.join(this.defaultRulepackDir, 'pii.yaml'),
path.join(this.defaultRulepackDir, 'default.yaml'),
];
for (const candidate of candidates) {
if (fs.existsSync(candidate)) {
return candidate;
}
}
// If no default found, return the first available
const availableResult = this.listAvailableSync();
if (availableResult.length > 0) {
return availableResult[0];
}
// Fallback to prompt-injection.yaml
return path.join(this.defaultRulepackDir, 'prompt-injection.yaml');
}
/**
* Synchronous version of listAvailable for getDefaultPath
*/
listAvailableSync() {
try {
if (!fs.existsSync(this.defaultRulepackDir)) {
return [];
}
const files = fs.readdirSync(this.defaultRulepackDir);
return files
.filter((file) => file.endsWith('.yaml') || file.endsWith('.yml'))
.map((file) => path.join(this.defaultRulepackDir, file));
}
catch {
return [];
}
}
/**
* Validates that a YAML file contains valid rulepack structure
*/
async validateYamlFile(filePath) {
const loadResult = await this.loadFromYaml(filePath);
if (loadResult.isErr()) {
return (0, Result_1.err)(loadResult.error);
}
return (0, Result_1.ok)(undefined);
}
}
exports.YamlRuleRepository = YamlRuleRepository;