Files
motovaultpro/backend/src/features/vehicles/domain/name-normalizer.ts
2025-12-21 19:56:52 -06:00

53 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Normalizes vehicle make and model names for human-friendly display.
* - Replaces underscores with spaces
* - Collapses whitespace
* - Title-cases standard words
* - Uppercases common acronyms (e.g., HD, GT, Z06)
*/
const MODEL_ACRONYMS = new Set([
'HD','GT','GL','SE','LE','XLE','RS','SVT','XR','ST','FX4','TRD','ZR1','Z06','GTI','GLI','SI','SS','LT','LTZ','RT','SRT','SR','SR5','XSE','SEL'
]);
export function normalizeModelName(input?: string | null): string | undefined {
if (input == null) return input ?? undefined;
let s = String(input).replace(/_/g, ' ');
s = s.replace(/\s+/g, ' ').trim();
if (s.length === 0) return s;
const tokens = s.split(' ');
const normalized = tokens.map(t => {
const raw = t;
const upper = raw.toUpperCase();
const lower = raw.toLowerCase();
// Uppercase known acronyms (match case-insensitively)
if (MODEL_ACRONYMS.has(upper)) return upper;
// Tokens with letters+digits (e.g., Z06) prefer uppercase
if (/^[a-z0-9]+$/i.test(raw) && /[a-z]/i.test(raw) && /\d/.test(raw) && raw.length <= 4) {
return upper;
}
// Pure letters: title case
if (/^[a-z]+$/i.test(raw)) {
return lower.charAt(0).toUpperCase() + lower.slice(1);
}
// Numbers or mixed/punctuated tokens: keep as-is except collapse case
return raw;
});
return normalized.join(' ');
}
export function normalizeMakeName(input?: string | null): string | undefined {
if (input == null) return input ?? undefined;
const s = String(input).replace(/_/g, ' ').replace(/\s+/g, ' ').trim();
if (s.length === 0) return s;
const title = s.toLowerCase().split(' ').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
// Special cases
if (/^bmw$/i.test(s)) return 'BMW';
if (/^gmc$/i.test(s)) return 'GMC';
if (/^mini$/i.test(s)) return 'MINI';
if (/^mclaren$/i.test(s)) return 'McLaren';
return title;
}