raw vPIC response → typed common model
Decode a VIN. Watch the noise become a clean, typed model.
NHTSA’s vPIC API returns ~150 loosely-typed fields per VIN — most empty or "Not Applicable". This demo reshapes that into one consistent Vehicle contract, the same way a telematics API normalizes a messy external source into a common model.
What the normalization layer does
A single pure function, normalize(raw, vin), owns every rule below. It is the valuable, testable core — everything else is plumbing.
Empties become null
"", "Not Applicable", and whitespace-only values all collapse to a single null. "0" is kept on purpose — vPIC uses ErrorCode "0" to mean a clean decode.
Typed coercion
ModelYear, Doors, and EngineCylinders are coerced to numbers and DisplacementL to a float. Anything absent or non-numeric returns null, never NaN.
GVWR is parsed
The weight rating "Class 8: 33,001 lb and above" is split into gvwrClass ("Class 8") plus the full original range text — structure recovered from a string.
Quality is preserved
vPIC's ErrorCode and ErrorText are always carried through, so the consumer of the common model can judge data quality for itself.
The common model
Every consumer codes against this typed contract — never against raw vPIC.
interface Vehicle {
vin: string;
make: string | null;
model: string | null;
year: number | null;
vehicleType: string | null;
bodyClass: string | null;
gvwrClass: string | null; // parsed from GVWR, e.g. "Class 8"
gvwrRange: string | null; // the raw GVWR range text
fuelTypePrimary: string | null;
fuelTypeSecondary: string | null;
driveType: string | null;
engineCylinders: number | null;
displacementL: number | null;
manufacturer: string | null;
plantCountry: string | null;
doors: number | null;
errorCode: string | null; // vPIC data-quality signal
errorText: string | null;
}