UNPKG

nehoid

Version:

Advanced unique ID generation utility with multi-layer encoding, collision detection, and context-aware features

120 lines 4.06 kB
export class Validator { static validate(id, options = {}) { const { checkFormat = true } = options; if (!id || typeof id !== 'string') { return false; } if (checkFormat) { // Basic format validation if (id.length < 8) { return false; } // Check for invalid characters if (/[^A-Za-z0-9_-]/.test(id)) { return false; } } return true; } static validateBatch(ids, options = {}) { const result = { valid: [], invalid: [], duplicates: [], }; const seen = new Set(); for (const id of ids) { if (!this.validate(id, options)) { result.invalid.push(id); continue; } if (options.checkCollisions && seen.has(id)) { result.duplicates.push(id); continue; } result.valid.push(id); seen.add(id); } return result; } static healthCheck(id) { const score = this.calculateHealthScore(id); const entropy = this.calculateEntropy(id); const predictability = this.assessPredictability(id); const recommendations = this.generateRecommendations(score, entropy, id.length); return { score, entropy: entropy > 0.75 ? 'high' : entropy > 0.5 ? 'medium' : 'low', predictability: predictability < 0.3 ? 'low' : predictability < 0.6 ? 'medium' : 'high', recommendations, }; } static calculateHealthScore(id) { let score = 1.0; // Length check if (id.length < 8) score *= 0.5; if (id.length > 32) score *= 0.9; // Character variety const hasUpper = /[A-Z]/.test(id); const hasLower = /[a-z]/.test(id); const hasNumber = /[0-9]/.test(id); const hasSpecial = /[^A-Za-z0-9]/.test(id); if (!hasUpper) score *= 0.9; if (!hasLower) score *= 0.9; if (!hasNumber) score *= 0.9; if (!hasSpecial) score *= 0.95; return Math.min(1, Math.max(0, score)); } static calculateEntropy(id) { const charFreq = new Map(); for (const char of id) { charFreq.set(char, (charFreq.get(char) || 0) + 1); } let entropy = 0; const length = id.length; for (const freq of charFreq.values()) { const probability = freq / length; entropy -= probability * Math.log2(probability); } return entropy / Math.log2(charFreq.size); } static assessPredictability(id) { let predictability = 0; // Check for patterns const hasRepeatingPattern = /(.+?)\1+/.test(id); if (hasRepeatingPattern) predictability += 0.3; // Check for sequential characters const hasSequential = /(?:abc|123|xyz)/i.test(id); if (hasSequential) predictability += 0.2; // Check for common words const hasCommonWords = /(?:test|admin|user|temp)/i.test(id); if (hasCommonWords) predictability += 0.4; return Math.min(1, predictability); } static generateRecommendations(score, entropy, length) { const recommendations = []; if (score < 0.8) { if (length < 12) recommendations.push('increase_length'); if (entropy < 0.6) recommendations.push('increase_complexity'); } if (length > 50) recommendations.push('consider_shorter'); if (entropy < 0.4) recommendations.push('add_more_variety'); return recommendations; } } Validator.UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; Validator.NANO_REGEX = /^[A-Za-z0-9_-]+$/; //# sourceMappingURL=validator.js.map