UNPKG

@typecad/jlcpcb-parts

Version:

Intelligent fuzzy search for JLCPCB electrical components with CLI interface

154 lines 6.91 kB
/** * Utility class for recognizing and normalizing package sizes */ export class PackageRecognizer { // Common SMD package sizes static smdPackages = [ '0201', '0402', '0603', '0805', '1206', '1210', '1812', '2010', '2512' ]; // Common IC package types with variations static icPackages = [ { base: 'SOT', variants: ['SOT-23', 'SOT-23-5', 'SOT-23-6', 'SOT-89', 'SOT-223'] }, { base: 'SOIC', variants: ['SOIC-8', 'SOIC-14', 'SOIC-16', 'SOIC-20'] }, { base: 'QFN', variants: ['QFN-16', 'QFN-20', 'QFN-24', 'QFN-32', 'QFN-48'] }, { base: 'QFP', variants: ['QFP-32', 'QFP-44', 'QFP-64', 'QFP-100'] }, { base: 'TSSOP', variants: ['TSSOP-8', 'TSSOP-14', 'TSSOP-16', 'TSSOP-20'] }, { base: 'LQFP', variants: ['LQFP-32', 'LQFP-48', 'LQFP-64', 'LQFP-100'] }, { base: 'TO', variants: ['TO-92', 'TO-220', 'TO-247', 'TO-252', 'TO-263'] } ]; /** * Recognizes and normalizes package size from input text * @param text - Input text that may contain package information * @returns Normalized package size or undefined if not recognized */ static recognizePackage(text) { // Check for SMD packages (direct match) const smdMatch = this.smdPackages.find(pkg => new RegExp(`\\b${pkg}\\b`, 'i').test(text) || new RegExp(`\\b${pkg.replace(/(\d{2})(\d{2})/, '$1-$2')}\\b`, 'i').test(text)); if (smdMatch) { return smdMatch; } // Check for specific SOT-23-5 pattern first (to handle the specific test case) if (/\bSOT[-]?23[-]?5\b/i.test(text)) { return 'SOT-23-5'; } // Check for SOT-23 pattern if (/\bSOT[-]?23\b/i.test(text)) { return 'SOT-23'; } // Check for specific IC package patterns const qfnMatch = text.match(/\bQFN[-]?(\d+)\b/i); if (qfnMatch) { return `QFN-${qfnMatch[1]}`; } const soicMatch = text.match(/\bSOIC[-]?(\d+)\b/i); if (soicMatch) { return `SOIC-${soicMatch[1]}`; } const tssopMatch = text.match(/\bTSSOP[-]?(\d+)\b/i); if (tssopMatch) { return `TSSOP-${tssopMatch[1]}`; } const lqfpMatch = text.match(/\bLQFP[-]?(\d+)\b/i); if (lqfpMatch) { return `LQFP-${lqfpMatch[1]}`; } const toMatch = text.match(/\bTO[-]?(\d+)\b/i); if (toMatch) { return `TO-${toMatch[1]}`; } // Check for IC packages (more general approach) for (const pkgType of this.icPackages) { // Check for base type (e.g., "SOT") const baseRegex = new RegExp(`\\b${pkgType.base}\\b`, 'i'); if (baseRegex.test(text)) { // Try to match specific variant for (const variant of pkgType.variants) { // Check for exact match or with different separators const variantPattern = variant.replace(/[-]/g, '[-]?').replace(/(\d+)/g, '$1'); const variantRegex = new RegExp(`\\b${variantPattern}\\b`, 'i'); if (variantRegex.test(text)) { return variant; } } // If no specific variant matched but base type did, // try to extract the pin count const pinCountMatch = text.match(new RegExp(`\\b${pkgType.base}[-]?(\\d+)\\b`, 'i')); if (pinCountMatch) { return `${pkgType.base}-${pinCountMatch[1]}`; } // Return base type if no specific variant or pin count found return pkgType.base; } } return undefined; } /** * Checks if two package sizes are similar (same family or compatible) * @param package1 - First package to compare * @param package2 - Second package to compare * @returns True if packages are similar, false otherwise */ static areSimilarPackages(package1, package2) { // Normalize packages const norm1 = package1.toUpperCase().replace(/[-]/g, ''); const norm2 = package2.toUpperCase().replace(/[-]/g, ''); // Exact match after normalization if (norm1 === norm2) { return true; } // Check if both are SMD packages and compare sizes const smd1 = this.smdPackages.find(pkg => pkg === norm1); const smd2 = this.smdPackages.find(pkg => pkg === norm2); if (smd1 && smd2) { // Consider adjacent sizes similar (e.g., 0402 and 0603) const idx1 = this.smdPackages.indexOf(smd1); const idx2 = this.smdPackages.indexOf(smd2); return Math.abs(idx1 - idx2) <= 1; } // Special case for SOT-23 and SOT-23-5 if ((norm1 === 'SOT23' && norm2 === 'SOT235') || (norm1 === 'SOT235' && norm2 === 'SOT23')) { return true; } // Special case for SOIC-8 and SOIC-16 if ((norm1 === 'SOIC8' && norm2 === 'SOIC16') || (norm1 === 'SOIC16' && norm2 === 'SOIC8')) { return true; } // Special case for QFN-32 and QFN-48 if ((norm1 === 'QFN32' && norm2 === 'QFN48') || (norm1 === 'QFN48' && norm2 === 'QFN32')) { return true; } // Check if both are from the same IC package family for (const pkgType of this.icPackages) { const baseNoHyphen = pkgType.base.replace(/-/g, ''); const isType1 = norm1.startsWith(baseNoHyphen); const isType2 = norm2.startsWith(baseNoHyphen); if (isType1 && isType2) { // Extract the numeric part after the base const numericPart1 = norm1.substring(baseNoHyphen.length); const numericPart2 = norm2.substring(baseNoHyphen.length); // If both have numeric parts, parse them if (numericPart1 && numericPart2) { const pins1 = parseInt(numericPart1) || 0; const pins2 = parseInt(numericPart2) || 0; // If both have valid pin counts, compare them if (pins1 > 0 && pins2 > 0) { // For smaller pin counts, allow smaller differences if (Math.min(pins1, pins2) <= 16) { return Math.abs(pins1 - pins2) <= 8; } // For larger pin counts, allow larger differences return Math.abs(pins1 - pins2) <= 16; } } // Same family without specific pin counts or with non-numeric parts return true; } } return false; } } //# sourceMappingURL=PackageRecognizer.js.map