// SPDX-License-Identifier: Apache-2.0
// Copyright 2024-2026 Vorion LLC
export class VendorRegistry {
    storage;
    auditLogger;
    notificationService;
    workflowEngine;
    constructor(config) {
        this.storage = config.storage;
        this.auditLogger = config.auditLogger;
        this.notificationService = config.notificationService;
        this.workflowEngine = config.workflowEngine;
    }
    // ============================================================================
    // Vendor Management
    // ============================================================================
    async createVendor(input, actorId) {
        // Validate input
        this.validateVendorInput(input);
        // Check for duplicates
        const existingVendor = await this.storage.findVendorByDomain(input.domain);
        if (existingVendor) {
            throw new VendorRegistryError('DUPLICATE_VENDOR', `Vendor with domain ${input.domain} already exists`);
        }
        const now = new Date();
        const vendor = {
            id: this.generateVendorId(),
            name: input.name,
            legalName: input.legalName || input.name,
            domain: input.domain,
            industry: input.industry,
            category: input.category,
            tier: input.tier || 'medium',
            status: 'prospective',
            contactInfo: input.contactInfo,
            metadata: {
                headquarters: input.metadata?.headquarters || '',
                yearFounded: input.metadata?.yearFounded,
                employeeCount: input.metadata?.employeeCount,
                annualRevenue: input.metadata?.annualRevenue,
                publiclyTraded: input.metadata?.publiclyTraded || false,
                stockSymbol: input.metadata?.stockSymbol,
                parentCompany: input.metadata?.parentCompany,
                subsidiaries: input.metadata?.subsidiaries || [],
                dataLocations: input.metadata?.dataLocations || [],
                certifications: input.metadata?.certifications || [],
                tags: input.metadata?.tags || [],
            },
            createdAt: now,
            updatedAt: now,
        };
        await this.storage.saveVendor(vendor);
        await this.auditLogger.log({
            action: 'vendor.created',
            actorId,
            resourceType: 'vendor',
            resourceId: vendor.id,
            details: { vendorName: vendor.name, domain: vendor.domain },
        });
        return vendor;
    }
    async updateVendor(vendorId, updates, actorId) {
        const vendor = await this.getVendor(vendorId);
        const updatedVendor = {
            ...vendor,
            ...updates,
            id: vendor.id, // Prevent ID modification
            createdAt: vendor.createdAt, // Prevent creation date modification
            updatedAt: new Date(),
        };
        await this.storage.saveVendor(updatedVendor);
        await this.auditLogger.log({
            action: 'vendor.updated',
            actorId,
            resourceType: 'vendor',
            resourceId: vendorId,
            details: { updates },
        });
        return updatedVendor;
    }
    async getVendor(vendorId) {
        const vendor = await this.storage.getVendor(vendorId);
        if (!vendor) {
            throw new VendorRegistryError('VENDOR_NOT_FOUND', `Vendor ${vendorId} not found`);
        }
        return vendor;
    }
    async listVendors(options) {
        return this.storage.listVendors(options);
    }
    async searchVendors(query) {
        return this.storage.searchVendors(query);
    }
    async deleteVendor(vendorId, actorId) {
        const vendor = await this.getVendor(vendorId);
        // Check for active contracts
        const contracts = await this.storage.getVendorContracts(vendorId);
        const activeContracts = contracts.filter(c => c.status === 'active');
        if (activeContracts.length > 0) {
            throw new VendorRegistryError('ACTIVE_CONTRACTS_EXIST', `Cannot delete vendor with ${activeContracts.length} active contracts`);
        }
        await this.storage.deleteVendor(vendorId);
        await this.auditLogger.log({
            action: 'vendor.deleted',
            actorId,
            resourceType: 'vendor',
            resourceId: vendorId,
            details: { vendorName: vendor.name },
        });
    }
    // ============================================================================
    // Vendor Onboarding Workflow
    // ============================================================================
    async initiateOnboarding(vendorId, actorId) {
        const vendor = await this.getVendor(vendorId);
        if (vendor.status !== 'prospective') {
            throw new VendorRegistryError('INVALID_STATUS', `Vendor must be in 'prospective' status to initiate onboarding`);
        }
        const workflow = await this.workflowEngine.createWorkflow({
            type: 'vendor_onboarding',
            vendorId,
            steps: this.getOnboardingSteps(vendor.tier),
            initiatedBy: actorId,
        });
        await this.updateVendor(vendorId, { status: 'onboarding' }, actorId);
        await this.notificationService.notify({
            type: 'onboarding_initiated',
            vendorId,
            workflowId: workflow.id,
            recipients: [actorId],
        });
        return workflow;
    }
    async completeOnboardingStep(workflowId, stepId, data, actorId) {
        const workflow = await this.workflowEngine.getWorkflow(workflowId);
        const step = workflow.steps.find(s => s.id === stepId);
        if (!step) {
            throw new VendorRegistryError('STEP_NOT_FOUND', `Step ${stepId} not found in workflow`);
        }
        // Validate step completion
        const validation = await this.validateOnboardingStep(step.type, data);
        if (!validation.valid) {
            throw new VendorRegistryError('VALIDATION_FAILED', validation.errors.join(', '));
        }
        const updatedWorkflow = await this.workflowEngine.completeStep(workflowId, stepId, data, actorId);
        // Check if all steps are complete
        if (updatedWorkflow.steps.every(s => s.status === 'completed')) {
            await this.completeOnboarding(updatedWorkflow.vendorId, actorId);
        }
        return updatedWorkflow;
    }
    async completeOnboarding(vendorId, actorId) {
        const vendor = await this.getVendor(vendorId);
        if (vendor.status !== 'onboarding') {
            throw new VendorRegistryError('INVALID_STATUS', `Vendor must be in 'onboarding' status to complete onboarding`);
        }
        const updatedVendor = await this.updateVendor(vendorId, { status: 'active' }, actorId);
        await this.notificationService.notify({
            type: 'onboarding_completed',
            vendorId,
            recipients: this.getStakeholders(vendor),
        });
        await this.auditLogger.log({
            action: 'vendor.onboarding_completed',
            actorId,
            resourceType: 'vendor',
            resourceId: vendorId,
            details: { vendorName: vendor.name },
        });
        return updatedVendor;
    }
    getOnboardingSteps(tier) {
        const baseSteps = [
            { id: 'basic_info', type: 'basic_info', name: 'Basic Information', required: true, status: 'pending' },
            { id: 'security_questionnaire', type: 'security_questionnaire', name: 'Security Questionnaire', required: true, status: 'pending' },
            { id: 'compliance_verification', type: 'compliance_verification', name: 'Compliance Verification', required: true, status: 'pending' },
            { id: 'contract_review', type: 'contract_review', name: 'Contract Review', required: true, status: 'pending' },
        ];
        if (tier === 'critical' || tier === 'high') {
            baseSteps.push({ id: 'penetration_test', type: 'penetration_test', name: 'Penetration Test Review', required: true, status: 'pending' }, { id: 'architecture_review', type: 'architecture_review', name: 'Architecture Review', required: true, status: 'pending' }, { id: 'incident_response', type: 'incident_response', name: 'Incident Response Verification', required: true, status: 'pending' });
        }
        if (tier === 'critical') {
            baseSteps.push({ id: 'onsite_audit', type: 'onsite_audit', name: 'On-site Security Audit', required: true, status: 'pending' }, { id: 'executive_approval', type: 'executive_approval', name: 'Executive Approval', required: true, status: 'pending' });
        }
        return baseSteps;
    }
    async validateOnboardingStep(stepType, data) {
        const validators = {
            basic_info: (d) => this.validateBasicInfo(d),
            security_questionnaire: (d) => this.validateSecurityQuestionnaire(d),
            compliance_verification: (d) => this.validateComplianceVerification(d),
            contract_review: (d) => this.validateContractReview(d),
            penetration_test: (d) => this.validatePenetrationTest(d),
            architecture_review: (d) => this.validateArchitectureReview(d),
            incident_response: (d) => this.validateIncidentResponse(d),
            onsite_audit: (d) => this.validateOnsiteAudit(d),
            executive_approval: (d) => this.validateExecutiveApproval(d),
        };
        const validator = validators[stepType];
        if (!validator) {
            return { valid: true, errors: [] };
        }
        return validator(data);
    }
    validateBasicInfo(data) {
        const errors = [];
        if (!data.legalName)
            errors.push('Legal name is required');
        if (!data.headquarters)
            errors.push('Headquarters location is required');
        if (!data.primaryContact)
            errors.push('Primary contact is required');
        return { valid: errors.length === 0, errors };
    }
    validateSecurityQuestionnaire(data) {
        const errors = [];
        if (!data.completedAt)
            errors.push('Questionnaire completion date is required');
        if (!data.responses)
            errors.push('Questionnaire responses are required');
        if (typeof data.score === 'number' && data.score < 60) {
            errors.push('Security questionnaire score is below minimum threshold (60)');
        }
        return { valid: errors.length === 0, errors };
    }
    validateComplianceVerification(data) {
        const errors = [];
        if (!data.certificationsVerified)
            errors.push('Certifications must be verified');
        return { valid: errors.length === 0, errors };
    }
    validateContractReview(data) {
        const errors = [];
        if (!data.contractId)
            errors.push('Contract ID is required');
        if (!data.legalApproval)
            errors.push('Legal approval is required');
        return { valid: errors.length === 0, errors };
    }
    validatePenetrationTest(data) {
        const errors = [];
        if (!data.reportDate)
            errors.push('Penetration test report date is required');
        if (!data.criticalFindings !== undefined && Number(data.criticalFindings) > 0) {
            errors.push('Critical findings must be remediated');
        }
        return { valid: errors.length === 0, errors };
    }
    validateArchitectureReview(data) {
        const errors = [];
        if (!data.reviewedBy)
            errors.push('Architecture reviewer is required');
        if (!data.approvalStatus)
            errors.push('Approval status is required');
        return { valid: errors.length === 0, errors };
    }
    validateIncidentResponse(data) {
        const errors = [];
        if (!data.planVerified)
            errors.push('Incident response plan must be verified');
        if (!data.contactsVerified)
            errors.push('Emergency contacts must be verified');
        return { valid: errors.length === 0, errors };
    }
    validateOnsiteAudit(data) {
        const errors = [];
        if (!data.auditDate)
            errors.push('Audit date is required');
        if (!data.auditorName)
            errors.push('Auditor name is required');
        if (!data.findings)
            errors.push('Audit findings are required');
        return { valid: errors.length === 0, errors };
    }
    validateExecutiveApproval(data) {
        const errors = [];
        if (!data.approverId)
            errors.push('Approver ID is required');
        if (!data.approvalDate)
            errors.push('Approval date is required');
        return { valid: errors.length === 0, errors };
    }
    getStakeholders(vendor) {
        const stakeholders = [];
        if (vendor.contactInfo.primaryContact?.email) {
            stakeholders.push(vendor.contactInfo.primaryContact.email);
        }
        return stakeholders;
    }
    // ============================================================================
    // Contract Management
    // ============================================================================
    async createContract(input, actorId) {
        const vendor = await this.getVendor(input.vendorId);
        const now = new Date();
        const contract = {
            id: this.generateContractId(),
            vendorId: input.vendorId,
            type: input.type,
            status: 'draft',
            startDate: input.startDate,
            endDate: input.endDate,
            renewalDate: input.renewalDate,
            autoRenewal: input.autoRenewal || false,
            value: input.value,
            slas: input.slas || [],
            dataProcessingTerms: input.dataProcessingTerms,
            securityRequirements: input.securityRequirements || [],
            documents: [],
            createdAt: now,
            updatedAt: now,
        };
        await this.storage.saveContract(contract);
        await this.auditLogger.log({
            action: 'contract.created',
            actorId,
            resourceType: 'contract',
            resourceId: contract.id,
            details: { vendorId: input.vendorId, vendorName: vendor.name, contractType: input.type },
        });
        return contract;
    }
    async updateContract(contractId, updates, actorId) {
        const contract = await this.getContract(contractId);
        const updatedContract = {
            ...contract,
            ...updates,
            id: contract.id,
            vendorId: contract.vendorId,
            createdAt: contract.createdAt,
            updatedAt: new Date(),
        };
        // Update status based on dates
        updatedContract.status = this.calculateContractStatus(updatedContract);
        await this.storage.saveContract(updatedContract);
        await this.auditLogger.log({
            action: 'contract.updated',
            actorId,
            resourceType: 'contract',
            resourceId: contractId,
            details: { updates },
        });
        return updatedContract;
    }
    async getContract(contractId) {
        const contract = await this.storage.getContract(contractId);
        if (!contract) {
            throw new VendorRegistryError('CONTRACT_NOT_FOUND', `Contract ${contractId} not found`);
        }
        return contract;
    }
    async getVendorContracts(vendorId) {
        return this.storage.getVendorContracts(vendorId);
    }
    async activateContract(contractId, actorId) {
        const contract = await this.getContract(contractId);
        if (contract.status !== 'draft' && contract.status !== 'pending_review') {
            throw new VendorRegistryError('INVALID_STATUS', `Contract must be in 'draft' or 'pending_review' status to activate`);
        }
        return this.updateContract(contractId, { status: 'active' }, actorId);
    }
    async terminateContract(contractId, reason, actorId) {
        const contract = await this.getContract(contractId);
        const updatedContract = await this.updateContract(contractId, { status: 'terminated' }, actorId);
        await this.auditLogger.log({
            action: 'contract.terminated',
            actorId,
            resourceType: 'contract',
            resourceId: contractId,
            details: { reason },
        });
        await this.notificationService.notify({
            type: 'contract_terminated',
            vendorId: contract.vendorId,
            contractId,
            recipients: this.getContractStakeholders(contract),
        });
        return updatedContract;
    }
    async addContractDocument(contractId, document, actorId) {
        const contract = await this.getContract(contractId);
        const updatedContract = {
            ...contract,
            documents: [...contract.documents, document],
            updatedAt: new Date(),
        };
        await this.storage.saveContract(updatedContract);
        await this.auditLogger.log({
            action: 'contract.document_added',
            actorId,
            resourceType: 'contract',
            resourceId: contractId,
            details: { documentName: document.name, documentType: document.type },
        });
        return updatedContract;
    }
    async updateSLA(contractId, slaId, updates, actorId) {
        const contract = await this.getContract(contractId);
        const slaIndex = contract.slas.findIndex(s => s.id === slaId);
        if (slaIndex === -1) {
            throw new VendorRegistryError('SLA_NOT_FOUND', `SLA ${slaId} not found in contract`);
        }
        const updatedSLAs = [...contract.slas];
        updatedSLAs[slaIndex] = { ...updatedSLAs[slaIndex], ...updates };
        const updatedContract = {
            ...contract,
            slas: updatedSLAs,
            updatedAt: new Date(),
        };
        await this.storage.saveContract(updatedContract);
        await this.auditLogger.log({
            action: 'contract.sla_updated',
            actorId,
            resourceType: 'contract',
            resourceId: contractId,
            details: { slaId, updates },
        });
        return updatedContract;
    }
    async recordSLABreach(contractId, slaId, breach, actorId) {
        const contract = await this.getContract(contractId);
        const slaIndex = contract.slas.findIndex(s => s.id === slaId);
        if (slaIndex === -1) {
            throw new VendorRegistryError('SLA_NOT_FOUND', `SLA ${slaId} not found in contract`);
        }
        const sla = contract.slas[slaIndex];
        sla.breachCount++;
        sla.currentPerformance = breach.actualValue;
        await this.storage.saveContract(contract);
        await this.storage.saveSLABreach(contractId, slaId, breach);
        await this.notificationService.notify({
            type: 'sla_breach',
            vendorId: contract.vendorId,
            contractId,
            slaId,
            breach,
            recipients: this.getContractStakeholders(contract),
        });
        await this.auditLogger.log({
            action: 'contract.sla_breach',
            actorId,
            resourceType: 'contract',
            resourceId: contractId,
            details: { slaId, breach },
        });
    }
    calculateContractStatus(contract) {
        const now = new Date();
        const thirtyDaysFromNow = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000);
        if (contract.status === 'terminated')
            return 'terminated';
        if (contract.status === 'draft')
            return 'draft';
        if (contract.status === 'pending_review')
            return 'pending_review';
        if (contract.endDate < now)
            return 'expired';
        if (contract.endDate < thirtyDaysFromNow)
            return 'expiring_soon';
        return 'active';
    }
    getContractStakeholders(contract) {
        // Return appropriate stakeholders based on contract
        return [];
    }
    // ============================================================================
    // Compliance Certification Management
    // ============================================================================
    async addCertification(input, actorId) {
        const vendor = await this.getVendor(input.vendorId);
        const now = new Date();
        const certification = {
            id: this.generateCertificationId(),
            vendorId: input.vendorId,
            framework: input.framework,
            status: this.calculateCertificationStatus(input.expirationDate),
            certificationBody: input.certificationBody,
            certificateNumber: input.certificateNumber,
            issueDate: input.issueDate,
            expirationDate: input.expirationDate,
            scope: input.scope,
            documents: input.documents || [],
            lastVerified: now,
            verificationMethod: input.verificationMethod || 'manual',
        };
        await this.storage.saveCertification(certification);
        // Update vendor metadata
        const certifications = new Set(vendor.metadata.certifications);
        certifications.add(input.framework);
        await this.updateVendor(input.vendorId, { metadata: { ...vendor.metadata, certifications: Array.from(certifications) } }, actorId);
        await this.auditLogger.log({
            action: 'certification.added',
            actorId,
            resourceType: 'certification',
            resourceId: certification.id,
            details: { vendorId: input.vendorId, framework: input.framework },
        });
        return certification;
    }
    async updateCertification(certificationId, updates, actorId) {
        const certification = await this.getCertification(certificationId);
        const updatedCertification = {
            ...certification,
            ...updates,
            id: certification.id,
            vendorId: certification.vendorId,
            status: updates.expirationDate
                ? this.calculateCertificationStatus(updates.expirationDate)
                : certification.status,
            lastVerified: new Date(),
        };
        await this.storage.saveCertification(updatedCertification);
        await this.auditLogger.log({
            action: 'certification.updated',
            actorId,
            resourceType: 'certification',
            resourceId: certificationId,
            details: { updates },
        });
        return updatedCertification;
    }
    async getCertification(certificationId) {
        const certification = await this.storage.getCertification(certificationId);
        if (!certification) {
            throw new VendorRegistryError('CERTIFICATION_NOT_FOUND', `Certification ${certificationId} not found`);
        }
        return certification;
    }
    async getVendorCertifications(vendorId) {
        return this.storage.getVendorCertifications(vendorId);
    }
    async verifyCertification(certificationId, verificationResult, actorId) {
        const certification = await this.getCertification(certificationId);
        const status = verificationResult.valid
            ? this.calculateCertificationStatus(certification.expirationDate)
            : 'revoked';
        const updatedCertification = {
            ...certification,
            status,
            lastVerified: new Date(),
            verificationMethod: verificationResult.method,
        };
        await this.storage.saveCertification(updatedCertification);
        if (!verificationResult.valid) {
            await this.notificationService.notify({
                type: 'certification_invalid',
                vendorId: certification.vendorId,
                certificationId,
                framework: certification.framework,
                reason: verificationResult.reason,
                recipients: [], // Add appropriate recipients
            });
        }
        await this.auditLogger.log({
            action: 'certification.verified',
            actorId,
            resourceType: 'certification',
            resourceId: certificationId,
            details: { verificationResult },
        });
        return updatedCertification;
    }
    async addCertificationDocument(certificationId, document, actorId) {
        const certification = await this.getCertification(certificationId);
        const updatedCertification = {
            ...certification,
            documents: [...certification.documents, document],
            lastVerified: new Date(),
        };
        await this.storage.saveCertification(updatedCertification);
        await this.auditLogger.log({
            action: 'certification.document_added',
            actorId,
            resourceType: 'certification',
            resourceId: certificationId,
            details: { documentName: document.name, documentType: document.type },
        });
        return updatedCertification;
    }
    async getExpiringCertifications(daysAhead) {
        return this.storage.getExpiringCertifications(daysAhead);
    }
    calculateCertificationStatus(expirationDate) {
        const now = new Date();
        const thirtyDaysFromNow = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000);
        if (expirationDate < now)
            return 'expired';
        if (expirationDate < thirtyDaysFromNow)
            return 'expiring_soon';
        return 'valid';
    }
    // ============================================================================
    // Vendor Status Management
    // ============================================================================
    async suspendVendor(vendorId, reason, actorId) {
        const vendor = await this.getVendor(vendorId);
        if (vendor.status === 'terminated') {
            throw new VendorRegistryError('INVALID_STATUS', `Cannot suspend a terminated vendor`);
        }
        const updatedVendor = await this.updateVendor(vendorId, { status: 'suspended' }, actorId);
        await this.notificationService.notify({
            type: 'vendor_suspended',
            vendorId,
            reason,
            recipients: this.getStakeholders(vendor),
        });
        await this.auditLogger.log({
            action: 'vendor.suspended',
            actorId,
            resourceType: 'vendor',
            resourceId: vendorId,
            details: { reason },
        });
        return updatedVendor;
    }
    async reinstateVendor(vendorId, actorId) {
        const vendor = await this.getVendor(vendorId);
        if (vendor.status !== 'suspended') {
            throw new VendorRegistryError('INVALID_STATUS', `Vendor must be in 'suspended' status to reinstate`);
        }
        const updatedVendor = await this.updateVendor(vendorId, { status: 'active' }, actorId);
        await this.auditLogger.log({
            action: 'vendor.reinstated',
            actorId,
            resourceType: 'vendor',
            resourceId: vendorId,
            details: {},
        });
        return updatedVendor;
    }
    async initiateOffboarding(vendorId, reason, actorId) {
        const vendor = await this.getVendor(vendorId);
        const updatedVendor = await this.updateVendor(vendorId, { status: 'offboarding' }, actorId);
        // Create offboarding workflow
        await this.workflowEngine.createWorkflow({
            type: 'vendor_offboarding',
            vendorId,
            steps: this.getOffboardingSteps(),
            initiatedBy: actorId,
            metadata: { reason },
        });
        await this.notificationService.notify({
            type: 'offboarding_initiated',
            vendorId,
            reason,
            recipients: this.getStakeholders(vendor),
        });
        return updatedVendor;
    }
    async terminateVendor(vendorId, actorId) {
        const vendor = await this.getVendor(vendorId);
        if (vendor.status !== 'offboarding') {
            throw new VendorRegistryError('INVALID_STATUS', `Vendor must be in 'offboarding' status to terminate`);
        }
        // Terminate all active contracts
        const contracts = await this.storage.getVendorContracts(vendorId);
        for (const contract of contracts) {
            if (contract.status === 'active') {
                await this.terminateContract(contract.id, 'Vendor termination', actorId);
            }
        }
        const updatedVendor = await this.updateVendor(vendorId, { status: 'terminated' }, actorId);
        await this.auditLogger.log({
            action: 'vendor.terminated',
            actorId,
            resourceType: 'vendor',
            resourceId: vendorId,
            details: {},
        });
        return updatedVendor;
    }
    getOffboardingSteps() {
        return [
            { id: 'data_deletion', type: 'data_deletion', name: 'Data Deletion Verification', required: true, status: 'pending' },
            { id: 'access_revocation', type: 'access_revocation', name: 'Access Revocation', required: true, status: 'pending' },
            { id: 'contract_termination', type: 'contract_termination', name: 'Contract Termination', required: true, status: 'pending' },
            { id: 'final_audit', type: 'final_audit', name: 'Final Security Audit', required: true, status: 'pending' },
        ];
    }
    // ============================================================================
    // Utility Methods
    // ============================================================================
    generateVendorId() {
        return `vnd_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
    }
    generateContractId() {
        return `ctr_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
    }
    generateCertificationId() {
        return `cert_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
    }
    validateVendorInput(input) {
        if (!input.name || input.name.trim().length === 0) {
            throw new VendorRegistryError('VALIDATION_ERROR', 'Vendor name is required');
        }
        if (!input.domain || !this.isValidDomain(input.domain)) {
            throw new VendorRegistryError('VALIDATION_ERROR', 'Valid domain is required');
        }
        if (!input.industry) {
            throw new VendorRegistryError('VALIDATION_ERROR', 'Industry is required');
        }
        if (!input.category) {
            throw new VendorRegistryError('VALIDATION_ERROR', 'Vendor category is required');
        }
        if (!input.contactInfo?.primaryContact) {
            throw new VendorRegistryError('VALIDATION_ERROR', 'Primary contact is required');
        }
    }
    isValidDomain(domain) {
        const domainRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$/;
        return domainRegex.test(domain);
    }
}
// ============================================================================
// Error Class
// ============================================================================
export class VendorRegistryError extends Error {
    code;
    constructor(code, message) {
        super(message);
        this.code = code;
        this.name = 'VendorRegistryError';
    }
}
//# sourceMappingURL=vendor-registry.js.map