// SPDX-License-Identifier: Apache-2.0
// Copyright 2024-2026 Vorion LLC
// ============================================================================
// Data Source Manager
// ============================================================================
export class DataSourceManager {
    config;
    sources = new Map();
    cache;
    rateLimiter;
    constructor(config) {
        this.config = config;
        this.cache = new DataCache(config.globalCacheConfig);
        this.rateLimiter = new RateLimiter(config.globalRateLimit);
        this.initializeSources();
    }
    initializeSources() {
        // Security Rating Sources
        this.registerSource(new BitSightDataSource(this.config.sources.bitSight));
        this.registerSource(new SecurityScorecardDataSource(this.config.sources.securityScorecard));
        this.registerSource(new RiskReconDataSource(this.config.sources.riskRecon));
        // Breach Databases
        this.registerSource(new HaveIBeenPwnedDataSource(this.config.sources.haveIBeenPwned));
        this.registerSource(new BreachDirectoryDataSource(this.config.sources.breachDirectory));
        // Certificate Transparency
        this.registerSource(new CertTransparencyDataSource(this.config.sources.certTransparency));
        // Sanctions Lists
        this.registerSource(new OFACDataSource(this.config.sources.ofac));
        this.registerSource(new EUSanctionsDataSource(this.config.sources.euSanctions));
        this.registerSource(new UNSanctionsDataSource(this.config.sources.unSanctions));
        // Threat Intelligence
        this.registerSource(new ThreatFeedDataSource(this.config.sources.threatFeed));
        this.registerSource(new DarkWebMonitorDataSource(this.config.sources.darkWebMonitor));
    }
    registerSource(source) {
        this.sources.set(source.name, source);
    }
    async getSecurityRatings(domain) {
        const ratings = [];
        const ratingsSources = this.getSourcesByType('security_rating');
        const results = await Promise.allSettled(ratingsSources.map(source => this.fetchWithCache(source, `rating:${domain}`, () => source.getSecurityRating(domain))));
        for (const result of results) {
            if (result.status === 'fulfilled' && result.value) {
                ratings.push(result.value);
            }
        }
        return ratings;
    }
    async getBreachRecords(domain) {
        const records = [];
        const breachSources = this.getSourcesByType('breach_database');
        const results = await Promise.allSettled(breachSources.map(source => this.fetchWithCache(source, `breach:${domain}`, () => source.getBreaches(domain))));
        for (const result of results) {
            if (result.status === 'fulfilled' && result.value) {
                records.push(...result.value);
            }
        }
        // Deduplicate by breach ID
        const uniqueRecords = new Map();
        for (const record of records) {
            if (!uniqueRecords.has(record.id)) {
                uniqueRecords.set(record.id, record);
            }
        }
        return Array.from(uniqueRecords.values());
    }
    async getCertificateInfo(domain) {
        const certSources = this.getSourcesByType('certificate_transparency');
        const certificates = [];
        const results = await Promise.allSettled(certSources.map(source => this.fetchWithCache(source, `cert:${domain}`, () => source.getCertificates(domain))));
        for (const result of results) {
            if (result.status === 'fulfilled' && result.value) {
                certificates.push(...result.value);
            }
        }
        return certificates;
    }
    async checkSanctions(entityName, entityType) {
        const sanctionsSources = this.getSourcesByType('sanctions_list');
        const entries = [];
        const results = await Promise.allSettled(sanctionsSources.map(source => this.fetchWithCache(source, `sanctions:${entityName}:${entityType}`, () => source.checkEntity(entityName, entityType))));
        for (const result of results) {
            if (result.status === 'fulfilled' && result.value) {
                entries.push(...result.value);
            }
        }
        return entries;
    }
    async getThreatIntelligence(domain) {
        const threatSources = this.getSourcesByType('threat_feed');
        const intelligence = [];
        const results = await Promise.allSettled(threatSources.map(source => this.fetchWithCache(source, `threat:${domain}`, () => source.getIndicators(domain))));
        for (const result of results) {
            if (result.status === 'fulfilled' && result.value) {
                intelligence.push(result.value);
            }
        }
        return intelligence;
    }
    async scanDarkWeb(domain) {
        const darkWebSources = this.getSourcesByType('dark_web');
        const mentions = [];
        const results = await Promise.allSettled(darkWebSources.map(source => this.fetchWithCache(source, `darkweb:${domain}`, () => source.scanForMentions(domain))));
        for (const result of results) {
            if (result.status === 'fulfilled' && result.value) {
                mentions.push(...result.value);
            }
        }
        return mentions;
    }
    getSourcesByType(type) {
        return Array.from(this.sources.values())
            .filter(source => source.type === type && source.isEnabled());
    }
    async fetchWithCache(source, cacheKey, fetcher) {
        const fullCacheKey = `${source.name}:${cacheKey}`;
        // Check cache
        const cached = this.cache.get(fullCacheKey);
        if (cached !== null) {
            return cached;
        }
        // Rate limit check
        await this.rateLimiter.acquire(source.name);
        try {
            const result = await fetcher();
            this.cache.set(fullCacheKey, result, source.getCacheTTL());
            return result;
        }
        catch (error) {
            console.error(`Error fetching from ${source.name}:`, error);
            return null;
        }
    }
    getSourceStatus() {
        return Array.from(this.sources.values()).map(source => ({
            name: source.name,
            type: source.type,
            enabled: source.isEnabled(),
            healthy: source.isHealthy(),
            lastCheck: source.getLastHealthCheck(),
            errorCount: source.getErrorCount(),
        }));
    }
}
// ============================================================================
// Base Data Source
// ============================================================================
export class DataSource {
    name;
    type;
    config;
    lastHealthCheck = new Date();
    healthy = true;
    errorCount = 0;
    constructor(name, type, config) {
        this.name = name;
        this.type = type;
        this.config = config;
    }
    isEnabled() {
        return this.config.enabled;
    }
    isHealthy() {
        return this.healthy;
    }
    getLastHealthCheck() {
        return this.lastHealthCheck;
    }
    getErrorCount() {
        return this.errorCount;
    }
    getCacheTTL() {
        return this.config.cacheConfig.ttlSeconds;
    }
    async makeRequest(endpoint, options = {}) {
        const url = `${this.config.apiEndpoint}${endpoint}`;
        const headers = {
            'Content-Type': 'application/json',
            ...options.headers,
        };
        if (this.config.apiKey) {
            headers['Authorization'] = `Bearer ${this.config.apiKey}`;
        }
        const response = await fetch(url, {
            method: options.method || 'GET',
            headers,
            body: options.body ? JSON.stringify(options.body) : undefined,
        });
        if (!response.ok) {
            this.errorCount++;
            throw new DataSourceError(this.name, `HTTP ${response.status}: ${response.statusText}`, response.status);
        }
        this.errorCount = 0;
        this.healthy = true;
        this.lastHealthCheck = new Date();
        return response.json();
    }
}
export class DataSourceError extends Error {
    source;
    statusCode;
    constructor(source, message, statusCode) {
        super(`[${source}] ${message}`);
        this.source = source;
        this.statusCode = statusCode;
        this.name = 'DataSourceError';
    }
}
class BitSightDataSource extends DataSource {
    constructor(config) {
        super('BitSight', 'security_rating', config);
    }
    async getSecurityRating(domain) {
        const data = await this.makeRequest(`/ratings/v1/companies?domain=${domain}`);
        return {
            source: this.name,
            vendorId: data.guid,
            domain,
            rating: data.rating,
            grade: this.mapRatingToGrade(data.rating),
            factors: this.mapFactors(data.rating_details),
            fetchedAt: new Date(),
            expiresAt: new Date(Date.now() + this.getCacheTTL() * 1000),
        };
    }
    mapRatingToGrade(rating) {
        if (rating >= 740)
            return 'A';
        if (rating >= 640)
            return 'B';
        if (rating >= 540)
            return 'C';
        if (rating >= 440)
            return 'D';
        return 'F';
    }
    mapFactors(details) {
        return details.map(detail => ({
            name: detail.name,
            score: detail.rating,
            weight: detail.weight,
            issues: detail.findings.map(f => ({
                id: f.id,
                severity: this.mapSeverity(f.severity),
                category: detail.name,
                title: f.title,
                description: f.description,
                firstSeen: new Date(f.first_seen),
                lastSeen: new Date(f.last_seen),
                resolved: f.resolved,
            })),
        }));
    }
    mapSeverity(severity) {
        const mapping = {
            'critical': 'critical',
            'severe': 'high',
            'moderate': 'medium',
            'minor': 'low',
            'informational': 'info',
        };
        return mapping[severity.toLowerCase()] || 'info';
    }
    async healthCheck() {
        try {
            await this.makeRequest('/health');
            return true;
        }
        catch {
            return false;
        }
    }
}
class SecurityScorecardDataSource extends DataSource {
    constructor(config) {
        super('SecurityScorecard', 'security_rating', config);
    }
    async getSecurityRating(domain) {
        const data = await this.makeRequest(`/companies/${domain}`);
        return {
            source: this.name,
            vendorId: data.id,
            domain,
            rating: data.score,
            grade: data.grade,
            factors: data.factors.map(f => ({
                name: f.name,
                score: f.score,
                weight: f.weight || 1,
                issues: f.issue_summary.map(issue => ({
                    id: issue.type,
                    severity: issue.severity,
                    category: f.name,
                    title: issue.type,
                    description: `${issue.count} issues found`,
                    firstSeen: new Date(),
                    lastSeen: new Date(),
                    resolved: false,
                })),
            })),
            fetchedAt: new Date(),
            expiresAt: new Date(Date.now() + this.getCacheTTL() * 1000),
        };
    }
    async healthCheck() {
        try {
            await this.makeRequest('/health');
            return true;
        }
        catch {
            return false;
        }
    }
}
class RiskReconDataSource extends DataSource {
    constructor(config) {
        super('RiskRecon', 'security_rating', config);
    }
    async getSecurityRating(domain) {
        const data = await this.makeRequest(`/api/v1/entities?domain=${domain}`);
        const entity = data.entities[0];
        if (!entity) {
            throw new DataSourceError(this.name, `No entity found for domain: ${domain}`);
        }
        return {
            source: this.name,
            vendorId: entity.id,
            domain,
            rating: entity.rating * 10, // RiskRecon uses 0-10 scale
            grade: this.mapRatingToGrade(entity.rating),
            factors: entity.domains.map(d => ({
                name: d.name,
                score: d.rating * 10,
                weight: 1,
                issues: d.findings.map(f => ({
                    id: f.id,
                    severity: f.severity,
                    category: d.name,
                    title: f.name,
                    description: f.description,
                    firstSeen: new Date(f.discovered),
                    lastSeen: new Date(f.last_observed),
                    resolved: f.status === 'resolved',
                })),
            })),
            fetchedAt: new Date(),
            expiresAt: new Date(Date.now() + this.getCacheTTL() * 1000),
        };
    }
    mapRatingToGrade(rating) {
        if (rating >= 8)
            return 'A';
        if (rating >= 6)
            return 'B';
        if (rating >= 4)
            return 'C';
        if (rating >= 2)
            return 'D';
        return 'F';
    }
    async healthCheck() {
        try {
            await this.makeRequest('/health');
            return true;
        }
        catch {
            return false;
        }
    }
}
class HaveIBeenPwnedDataSource extends DataSource {
    constructor(config) {
        super('HaveIBeenPwned', 'breach_database', config);
    }
    async getBreaches(domain) {
        const data = await this.makeRequest(`/api/v3/breaches?domain=${domain}`);
        return data.map(breach => ({
            id: `hibp:${breach.Name}`,
            vendorDomain: domain,
            breachDate: new Date(breach.BreachDate),
            disclosureDate: new Date(breach.AddedDate),
            source: this.name,
            recordsAffected: breach.PwnCount,
            dataTypes: breach.DataClasses,
            description: breach.Description,
            verified: breach.IsVerified,
        }));
    }
    async healthCheck() {
        try {
            await this.makeRequest('/api/v3/breaches');
            return true;
        }
        catch {
            return false;
        }
    }
}
class BreachDirectoryDataSource extends DataSource {
    constructor(config) {
        super('BreachDirectory', 'breach_database', config);
    }
    async getBreaches(domain) {
        const data = await this.makeRequest(`/api/search?domain=${domain}`);
        return data.results.map(breach => ({
            id: `bd:${breach.id}`,
            vendorDomain: domain,
            breachDate: new Date(breach.date),
            disclosureDate: new Date(breach.added),
            source: this.name,
            recordsAffected: breach.records,
            dataTypes: breach.data_types,
            description: breach.description,
            verified: breach.verified,
        }));
    }
    async healthCheck() {
        try {
            await this.makeRequest('/health');
            return true;
        }
        catch {
            return false;
        }
    }
}
class CertTransparencyDataSource extends DataSource {
    constructor(config) {
        super('CertTransparency', 'certificate_transparency', config);
    }
    async getCertificates(domain) {
        // Query Certificate Transparency logs
        const data = await this.makeRequest(`/api/v1/search?domain=${domain}`);
        return data.certificates.map(cert => {
            const validTo = new Date(cert.not_after);
            const now = new Date();
            const daysUntilExpiry = Math.ceil((validTo.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));
            return {
                domain: cert.common_name,
                issuer: cert.issuer_name,
                subject: cert.subject_name,
                validFrom: new Date(cert.not_before),
                validTo,
                daysUntilExpiry,
                algorithm: cert.signature_algorithm,
                keySize: cert.key_size,
                serialNumber: cert.serial_number,
                fingerprint: cert.fingerprint,
                ctLogged: true,
            };
        });
    }
    async healthCheck() {
        try {
            await this.makeRequest('/health');
            return true;
        }
        catch {
            return false;
        }
    }
}
class OFACDataSource extends DataSource {
    constructor(config) {
        super('OFAC', 'sanctions_list', config);
    }
    async checkEntity(entityName, entityType) {
        const data = await this.makeRequest(`/api/v1/search?name=${encodeURIComponent(entityName)}&type=${entityType}`);
        return data.matches.map(match => ({
            source: this.name,
            entityName: match.name,
            matchScore: match.score,
            listType: match.program,
            addedDate: new Date(match.add_date),
            reason: match.reason,
            aliases: match.aliases || [],
        }));
    }
    async healthCheck() {
        try {
            await this.makeRequest('/health');
            return true;
        }
        catch {
            return false;
        }
    }
}
class EUSanctionsDataSource extends DataSource {
    constructor(config) {
        super('EU_Sanctions', 'sanctions_list', config);
    }
    async checkEntity(entityName, entityType) {
        const data = await this.makeRequest(`/api/search?q=${encodeURIComponent(entityName)}&entity_type=${entityType}`);
        return data.entities.map(entity => ({
            source: this.name,
            entityName: entity.name,
            matchScore: entity.confidence,
            listType: entity.regime,
            addedDate: new Date(entity.listed_on),
            reason: entity.grounds,
            aliases: entity.name_aliases || [],
        }));
    }
    async healthCheck() {
        try {
            await this.makeRequest('/health');
            return true;
        }
        catch {
            return false;
        }
    }
}
class UNSanctionsDataSource extends DataSource {
    constructor(config) {
        super('UN_Sanctions', 'sanctions_list', config);
    }
    async checkEntity(entityName, entityType) {
        const data = await this.makeRequest(`/api/v1/consolidated?name=${encodeURIComponent(entityName)}&type=${entityType}`);
        return data.individuals.concat(data.entities).map(record => ({
            source: this.name,
            entityName: record.name,
            matchScore: record.match_score,
            listType: record.un_list,
            addedDate: new Date(record.listed_on),
            reason: record.narrative,
            aliases: record.aliases || [],
        }));
    }
    async healthCheck() {
        try {
            await this.makeRequest('/health');
            return true;
        }
        catch {
            return false;
        }
    }
}
class ThreatFeedDataSource extends DataSource {
    constructor(config) {
        super('ThreatFeed', 'threat_feed', config);
    }
    async getIndicators(domain) {
        const data = await this.makeRequest(`/api/v2/indicators?domain=${domain}`);
        return {
            source: this.name,
            vendorDomain: domain,
            indicators: data.indicators.map(ind => ({
                type: ind.type,
                value: ind.value,
                confidence: ind.confidence,
                severity: ind.severity,
                description: ind.description,
                firstSeen: new Date(ind.first_seen),
                lastSeen: new Date(ind.last_seen),
            })),
            fetchedAt: new Date(),
        };
    }
    async healthCheck() {
        try {
            await this.makeRequest('/health');
            return true;
        }
        catch {
            return false;
        }
    }
}
class DarkWebMonitorDataSource extends DataSource {
    constructor(config) {
        super('DarkWebMonitor', 'dark_web', config);
    }
    async scanForMentions(domain) {
        const data = await this.makeRequest(`/api/v1/search?query=${encodeURIComponent(domain)}`);
        return data.mentions.map(mention => ({
            id: mention.id,
            source: this.name,
            domain,
            mentionType: mention.type,
            content: mention.snippet,
            discoveredAt: new Date(mention.discovered_at),
            confidence: mention.confidence,
            url: mention.source_url,
        }));
    }
    async healthCheck() {
        try {
            await this.makeRequest('/health');
            return true;
        }
        catch {
            return false;
        }
    }
}
// ============================================================================
// Cache & Rate Limiting
// ============================================================================
class DataCache {
    config;
    cache = new Map();
    constructor(config) {
        this.config = config;
    }
    get(key) {
        if (!this.config.enabled)
            return null;
        const entry = this.cache.get(key);
        if (!entry)
            return null;
        if (Date.now() > entry.expiresAt) {
            this.cache.delete(key);
            return null;
        }
        return entry.value;
    }
    set(key, value, ttlSeconds) {
        if (!this.config.enabled)
            return;
        // Enforce max entries
        if (this.cache.size >= this.config.maxEntries) {
            const oldestKey = this.cache.keys().next().value;
            if (oldestKey) {
                this.cache.delete(oldestKey);
            }
        }
        const ttl = ttlSeconds || this.config.ttlSeconds;
        this.cache.set(key, {
            value,
            expiresAt: Date.now() + ttl * 1000,
        });
    }
    clear() {
        this.cache.clear();
    }
}
class RateLimiter {
    config;
    requests = new Map();
    constructor(config) {
        this.config = config;
    }
    async acquire(sourceId) {
        const now = Date.now();
        const requests = this.requests.get(sourceId) || [];
        // Clean old requests
        const oneMinuteAgo = now - 60000;
        const recentRequests = requests.filter(time => time > oneMinuteAgo);
        // Check rate limit
        if (recentRequests.length >= this.config.requestsPerMinute) {
            const waitTime = recentRequests[0] + 60000 - now;
            await this.sleep(waitTime);
        }
        recentRequests.push(now);
        this.requests.set(sourceId, recentRequests);
    }
    sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
}
// ============================================================================
// Factory Function
// ============================================================================
export function createDataSourceManager(config) {
    return new DataSourceManager(config);
}
export function getDefaultDataSourceConfig() {
    return {
        globalCacheConfig: {
            enabled: true,
            ttlSeconds: 3600, // 1 hour
            maxEntries: 10000,
        },
        globalRateLimit: {
            requestsPerMinute: 60,
            requestsPerDay: 10000,
            burstLimit: 10,
        },
        sources: {
            bitSight: {
                name: 'BitSight',
                type: 'security_rating',
                enabled: true,
                apiEndpoint: process.env.BITSIGHT_API_URL || 'https://api.bitsighttech.com',
                apiKey: process.env.BITSIGHT_API_KEY,
                rateLimit: { requestsPerMinute: 30, requestsPerDay: 5000, burstLimit: 5 },
                cacheConfig: { enabled: true, ttlSeconds: 3600, maxEntries: 1000 },
                retryConfig: { maxRetries: 3, backoffMs: 1000, backoffMultiplier: 2 },
            },
            securityScorecard: {
                name: 'SecurityScorecard',
                type: 'security_rating',
                enabled: true,
                apiEndpoint: process.env.SECURITYSCORECARD_API_URL || 'https://api.securityscorecard.io',
                apiKey: process.env.SECURITYSCORECARD_API_KEY,
                rateLimit: { requestsPerMinute: 30, requestsPerDay: 5000, burstLimit: 5 },
                cacheConfig: { enabled: true, ttlSeconds: 3600, maxEntries: 1000 },
                retryConfig: { maxRetries: 3, backoffMs: 1000, backoffMultiplier: 2 },
            },
            riskRecon: {
                name: 'RiskRecon',
                type: 'security_rating',
                enabled: false,
                apiEndpoint: process.env.RISKRECON_API_URL || 'https://api.riskrecon.com',
                apiKey: process.env.RISKRECON_API_KEY,
                rateLimit: { requestsPerMinute: 20, requestsPerDay: 2000, burstLimit: 3 },
                cacheConfig: { enabled: true, ttlSeconds: 3600, maxEntries: 1000 },
                retryConfig: { maxRetries: 3, backoffMs: 1000, backoffMultiplier: 2 },
            },
            haveIBeenPwned: {
                name: 'HaveIBeenPwned',
                type: 'breach_database',
                enabled: true,
                apiEndpoint: 'https://haveibeenpwned.com',
                apiKey: process.env.HIBP_API_KEY,
                rateLimit: { requestsPerMinute: 10, requestsPerDay: 1000, burstLimit: 2 },
                cacheConfig: { enabled: true, ttlSeconds: 86400, maxEntries: 5000 },
                retryConfig: { maxRetries: 3, backoffMs: 1500, backoffMultiplier: 2 },
            },
            breachDirectory: {
                name: 'BreachDirectory',
                type: 'breach_database',
                enabled: false,
                apiEndpoint: process.env.BREACH_DIRECTORY_API_URL || 'https://api.breachdirectory.com',
                apiKey: process.env.BREACH_DIRECTORY_API_KEY,
                rateLimit: { requestsPerMinute: 20, requestsPerDay: 2000, burstLimit: 5 },
                cacheConfig: { enabled: true, ttlSeconds: 86400, maxEntries: 5000 },
                retryConfig: { maxRetries: 3, backoffMs: 1000, backoffMultiplier: 2 },
            },
            certTransparency: {
                name: 'CertTransparency',
                type: 'certificate_transparency',
                enabled: true,
                apiEndpoint: process.env.CT_API_URL || 'https://crt.sh',
                rateLimit: { requestsPerMinute: 30, requestsPerDay: 5000, burstLimit: 10 },
                cacheConfig: { enabled: true, ttlSeconds: 3600, maxEntries: 2000 },
                retryConfig: { maxRetries: 3, backoffMs: 1000, backoffMultiplier: 2 },
            },
            ofac: {
                name: 'OFAC',
                type: 'sanctions_list',
                enabled: true,
                apiEndpoint: process.env.OFAC_API_URL || 'https://sanctionslist.ofac.treas.gov',
                rateLimit: { requestsPerMinute: 60, requestsPerDay: 10000, burstLimit: 20 },
                cacheConfig: { enabled: true, ttlSeconds: 86400, maxEntries: 10000 },
                retryConfig: { maxRetries: 3, backoffMs: 1000, backoffMultiplier: 2 },
            },
            euSanctions: {
                name: 'EU_Sanctions',
                type: 'sanctions_list',
                enabled: true,
                apiEndpoint: process.env.EU_SANCTIONS_API_URL || 'https://webgate.ec.europa.eu/fsd/fsf',
                rateLimit: { requestsPerMinute: 30, requestsPerDay: 5000, burstLimit: 10 },
                cacheConfig: { enabled: true, ttlSeconds: 86400, maxEntries: 10000 },
                retryConfig: { maxRetries: 3, backoffMs: 1000, backoffMultiplier: 2 },
            },
            unSanctions: {
                name: 'UN_Sanctions',
                type: 'sanctions_list',
                enabled: true,
                apiEndpoint: process.env.UN_SANCTIONS_API_URL || 'https://scsanctions.un.org/api',
                rateLimit: { requestsPerMinute: 30, requestsPerDay: 5000, burstLimit: 10 },
                cacheConfig: { enabled: true, ttlSeconds: 86400, maxEntries: 10000 },
                retryConfig: { maxRetries: 3, backoffMs: 1000, backoffMultiplier: 2 },
            },
            threatFeed: {
                name: 'ThreatFeed',
                type: 'threat_feed',
                enabled: true,
                apiEndpoint: process.env.THREAT_FEED_API_URL || 'https://api.threatfeed.example.com',
                apiKey: process.env.THREAT_FEED_API_KEY,
                rateLimit: { requestsPerMinute: 60, requestsPerDay: 10000, burstLimit: 20 },
                cacheConfig: { enabled: true, ttlSeconds: 1800, maxEntries: 5000 },
                retryConfig: { maxRetries: 3, backoffMs: 1000, backoffMultiplier: 2 },
            },
            darkWebMonitor: {
                name: 'DarkWebMonitor',
                type: 'dark_web',
                enabled: true,
                apiEndpoint: process.env.DARK_WEB_API_URL || 'https://api.darkwebmonitor.example.com',
                apiKey: process.env.DARK_WEB_API_KEY,
                rateLimit: { requestsPerMinute: 20, requestsPerDay: 2000, burstLimit: 5 },
                cacheConfig: { enabled: true, ttlSeconds: 3600, maxEntries: 2000 },
                retryConfig: { maxRetries: 3, backoffMs: 1000, backoffMultiplier: 2 },
            },
        },
    };
}
//# sourceMappingURL=data-sources.js.map