UNPKG

@cardog/corgi

Version:

⚡ The fastest and most lightweight open-source VIN decoding library. Fully offline, TypeScript-first, with comprehensive NHTSA VPIC database integration for Node.js, browsers, and Cloudflare Workers.

573 lines (566 loc) 15.6 kB
import { D1Database } from '@cloudflare/workers-types'; /** * Common interface for database operations across different environments */ interface DatabaseAdapter { /** * Execute a SQL query with parameters and return the results * * @param query - SQL query to execute * @param params - Optional array of parameters to bind to the query * @returns Array of query results */ exec(query: string, params?: any[]): Promise<QueryResult[]>; /** * Close the database connection */ close(): Promise<void>; } /** * Result from a database query */ interface QueryResult { /** * Array of column names in the result set */ columns: string[]; /** * Two-dimensional array of values: * - First dimension: rows * - Second dimension: column values for each row */ values: any[][]; } /** * Factory function to create the appropriate database adapter */ interface DatabaseAdapterFactory { /** * Create a database adapter for the given path or URL * * @param pathOrUrl - Path to SQLite file or URL for remote database * @returns Initialized database adapter */ createAdapter(pathOrUrl: string): Promise<DatabaseAdapter>; } /** * Core types for the VIN decoder library */ /** * Standardized vehicle body styles */ declare enum BodyStyle { SEDAN = "Sedan", COUPE = "Coupe", CONVERTIBLE = "Convertible", HATCHBACK = "Hatchback", SUV = "SUV", CROSSOVER = "Crossover", WAGON = "Wagon", VAN = "Van", MINIVAN = "Minivan", PICKUP = "Pickup", TRUCK = "Truck", TRACTOR = "Tractor", TRAILER = "Trailer", BUS = "Bus", MOTORCYCLE = "Motorcycle", OTHER = "Other" } /** * Maps standard database body class values to user-friendly body styles */ declare const BODY_STYLE_MAP: Record<string, BodyStyle>; /** * Error severity levels */ declare enum ErrorSeverity { WARNING = "warning", ERROR = "error", FATAL = "fatal" } /** * Error category types */ declare enum ErrorCategory { VALIDATION = "validation", STRUCTURE = "structure", LOOKUP = "lookup", PATTERN = "pattern", DATABASE = "database" } /** * Specific error codes with structured grouping */ declare enum ErrorCode { INVALID_LENGTH = "100", INVALID_CHARACTERS = "101", INVALID_CHECK_DIGIT = "200", INVALID_MODEL_YEAR = "201", INVALID_REGION = "202", WMI_NOT_FOUND = "300", MANUFACTURER_NOT_FOUND = "301", MAKE_NOT_FOUND = "302", NO_PATTERNS_FOUND = "400", LOW_CONFIDENCE_PATTERNS = "401", CONFLICTING_PATTERNS = "402", DATABASE_CONNECTION_ERROR = "500", QUERY_ERROR = "501", INVALID_RESULT = "502" } /** * Base error interface for all error types */ interface BaseError { code: ErrorCode; category: ErrorCategory; severity: ErrorSeverity; message: string; positions?: number[]; details?: string; } /** * Error for validation issues (check digit, etc.) */ interface ValidationError extends BaseError { category: ErrorCategory.VALIDATION; expected?: string; actual?: string; } /** * Error for VIN structure issues (length, characters) */ interface StructureError extends BaseError { category: ErrorCategory.STRUCTURE; positions?: number[]; } /** * Error for database lookup failures */ interface LookupError extends BaseError { category: ErrorCategory.LOOKUP; searchKey: string; searchType: string; } /** * Error for pattern matching issues */ interface PatternError extends BaseError { category: ErrorCategory.PATTERN; pattern?: string; confidence?: number; } /** * Error for database-related issues */ interface DatabaseError extends BaseError { category: ErrorCategory.DATABASE; query?: string; params?: unknown[]; } /** * Union type of all possible decoder errors */ type DecodeError = ValidationError | StructureError | LookupError | PatternError | DatabaseError; /** * Position information for a VIN pattern */ interface Position { start: number; length: number; value: string; } /** * Configuration options for VIN decoding */ interface DecodeOptions { /** Include raw database records in the response */ includeRawData?: boolean; /** Include detailed pattern matching information */ includePatternDetails?: boolean; /** Override the detected model year */ modelYear?: number; /** Minimum confidence threshold for pattern matches (default: 0.5) */ confidenceThreshold?: number; /** Include timing and debug information */ includeDiagnostics?: boolean; } /** * World Manufacturer Identifier result */ interface WMIResult { /** 3-character WMI code from the VIN */ code: string; /** Manufacturer name */ manufacturer: string; /** Manufacturing country */ country: string; /** Vehicle type */ vehicleType: string; /** Geographic region */ region: string; /** Vehicle make/brand */ make: string; } /** * Model year extraction result */ interface ModelYearResult { /** Determined model year */ year: number; /** Source of the year determination */ source: 'position' | 'override' | 'calculated'; /** Confidence in the year (0-1) */ confidence: number; } /** * Check digit validation result */ interface CheckDigitResult { /** Position in the VIN (typically 9) */ position: number; /** Actual check digit from the VIN */ actual: string; /** Expected check digit based on calculation */ expected?: string; /** Whether the check digit is valid */ isValid: boolean; } /** * Core vehicle information extracted from VIN patterns */ interface VehicleInfo { /** Vehicle manufacturer (e.g., "Hyundai") */ make: string; /** Vehicle model (e.g., "Kona") */ model: string; /** Model year (e.g., 2023) */ year: number; /** Vehicle series or sub-model */ series?: string; /** Trim level */ trim?: string; /** Body style (e.g., "SUV", "Sedan") */ bodyStyle?: string; /** Drive type (e.g., "AWD", "4x2") */ driveType?: string; /** Engine type */ engineType?: string; /** Primary fuel type */ fuelType?: string; /** Transmission type */ transmission?: string; /** Number of doors */ doors?: string; /** Vehicle manufacturer name */ manufacturer?: string; } /** * Manufacturing plant information */ interface PlantInfo { /** Manufacturing country */ country: string; /** Manufacturing city */ city?: string; /** Plant operator/manufacturer */ manufacturer?: string; /** Plant code (from VIN position 11) */ code: string; } /** * Engine specifications */ interface EngineInfo { /** Engine type */ type?: string; /** Engine model code */ model?: string; /** Number of cylinders */ cylinders?: string; /** Engine displacement in liters */ displacement?: string; /** Fuel type */ fuel?: string; /** Engine power (HP) */ power?: string; } /** * Pattern match result from database */ interface PatternMatch { /** Element name (e.g., "Model", "Body Class") */ element: string; /** Element code */ code: string; /** Attribute ID */ attributeId: string | number | null; /** Decoded value */ value: string | null; /** Confidence score (0-1) */ confidence: number; /** VIN positions covered by this pattern */ positions: number[]; /** Schema name */ schema: string; /** Additional metadata */ metadata?: { /** Lookup table name */ lookupTable?: string; /** Group name */ groupName?: string; /** Element weight for priority */ elementWeight?: number; /** Pattern type */ patternType?: 'VDS' | 'VIS'; /** Original pattern string */ rawPattern?: string; /** Match details */ matchDetails?: { exactMatches?: number; wildcardMatches?: number; totalPositions?: number; }; }; } /** * Decoded VIN components */ interface VINComponents { /** World Manufacturer Identifier information */ wmi?: WMIResult; /** Model year information */ modelYear?: ModelYearResult; /** Check digit validation */ checkDigit?: CheckDigitResult; /** Vehicle Descriptor Section patterns */ vds?: { raw: string; patterns: PatternMatch[]; }; /** Vehicle Identifier Section patterns */ vis?: { raw: string; patterns: PatternMatch[]; }; /** Core vehicle information */ vehicle?: VehicleInfo; /** Manufacturing plant information */ plant?: PlantInfo; /** Engine specifications */ engine?: EngineInfo; } /** * Diagnostic and timing information */ interface DiagnosticInfo { /** Total processing time in milliseconds */ processingTime: number; /** Overall confidence score */ confidence: number; /** Library version */ schemaVersion: string; /** Primary schema used for decoding */ matchedSchema?: string; /** Total number of patterns found */ totalPatterns?: number; /** Raw database records (if requested) */ rawRecords?: any[]; /** SQL query information (if diagnostics enabled) */ queries?: { sql: string; params: any[]; timing: number; }[]; } /** * Complete VIN decoding result */ interface DecodeResult { /** Input VIN */ vin: string; /** Whether the VIN is valid */ valid: boolean; /** Decoded components */ components: VINComponents; /** Any validation or decoding errors */ errors: DecodeError[]; /** Pattern matching details (if requested) */ patterns?: PatternMatch[]; /** Diagnostic information */ metadata?: DiagnosticInfo; } /** * Helper function to decode a VIN using a provided database adapter * * @param vin - The Vehicle Identification Number to decode * @param adapter - Database adapter for the current environment * @param options - Optional configuration for the decoding process * @returns Decoded VIN information */ declare function decodeVIN(vin: string, adapter: DatabaseAdapter, options?: DecodeOptions): Promise<DecodeResult>; /** * Main VIN decoder class implementing the NHTSA VPIC decoding logic */ declare class VINDecoder { private db; private patternMatcher; /** * Create a new VIN decoder * * @param adapter - Database adapter for the current environment */ constructor(adapter: DatabaseAdapter); /** * Decode a VIN and return detailed vehicle information * * @param vin - The Vehicle Identification Number to decode * @param options - Optional configuration for the decoding process * @returns Decoded VIN information */ decode(vin: string, options?: DecodeOptions): Promise<DecodeResult>; /** * Find the primary schema from pattern matches * * @param patterns - Array of pattern matches * @returns Primary schema name or undefined */ private findPrimarySchema; /** * Map raw body style to standardized body style * * @param bodyStyle - Raw body style from database * @returns Standardized body style */ private coerceBodyStyle; /** * Extract vehicle information from pattern matches * * @param patterns - Array of pattern matches * @param wmiInfo - WMI information * @param modelYear - Model year information * @returns Vehicle information */ private extractVehicleInfo; /** * Extract plant information from pattern matches * * @param patterns - Array of pattern matches * @param vin - Complete VIN string * @returns Plant information or undefined */ private extractPlantInfo; /** * Extract engine information from pattern matches * * @param patterns - Array of pattern matches * @returns Engine information or undefined */ private extractEngineInfo; /** * Validate the structure of a VIN * * @param vin - VIN to validate * @returns Array of structure errors */ private validateStructure; /** * Extract the World Manufacturer Identifier from a VIN * * @param vin - Complete VIN string * @returns WMI code */ private extractWMI; /** * Determine model year from VIN * * @param vin - Complete VIN string * @returns Model year information or null */ private determineModelYear; /** * Validate the check digit in a VIN * * @param vin - Complete VIN string * @returns Check digit validation result */ private validateCheckDigit; /** * Close the database connection */ close(): Promise<void>; } /** * Interface for SQL.js static methods */ interface SQLJsStatic { Database: new (data: Uint8Array) => SQLJsDatabase; } /** * Interface for SQL.js database instance */ interface SQLJsDatabase { exec(sql: string, params?: any[]): SQLJsResult[]; close(): void; } /** * Interface for SQL.js query result */ interface SQLJsResult { columns: string[]; values: any[][]; } /** * Global window declarations for SQL.js */ declare global { interface Window { initSqlJs: () => Promise<SQLJsStatic>; SQL: SQLJsStatic; } } /** * Browser implementation of the DatabaseAdapter using SQL.js */ declare class BrowserDatabaseAdapter implements DatabaseAdapter { private db; private queryCount; /** * Create a new database adapter for browser environment * * @param db - SQL.js database instance */ constructor(db: SQLJsDatabase); /** * Execute a SQL query with parameters * * @param query - SQL query to execute * @param params - Parameters to bind to the query * @returns Query results */ exec(query: string, params?: any[]): Promise<QueryResult[]>; /** * Close the database connection */ close(): Promise<void>; } /** * Factory for creating browser database adapters */ declare class BrowserDatabaseAdapterFactory implements DatabaseAdapterFactory { /** * Create a new database adapter for the given URL * * @param pathOrUrl - URL to the SQLite database file * @returns Initialized database adapter */ createAdapter(pathOrUrl: string): Promise<DatabaseAdapter>; } declare class CloudflareD1Adapter implements DatabaseAdapter { private db; constructor(db: D1Database); exec(query: string, params?: any[]): Promise<QueryResult[]>; close(): Promise<void>; } declare function createD1Adapter(db: D1Database): DatabaseAdapter; export { BodyStyle as B, type CheckDigitResult as C, type DatabaseAdapter as D, type EngineInfo as E, type LookupError as L, type ModelYearResult as M, type PlantInfo as P, type QueryResult as Q, type StructureError as S, type VINComponents as V, type WMIResult as W, type DatabaseAdapterFactory as a, type DecodeOptions as b, type DecodeResult as c, type VehicleInfo as d, type PatternMatch as e, type DecodeError as f, type ValidationError as g, type PatternError as h, type DatabaseError as i, ErrorCode as j, ErrorCategory as k, ErrorSeverity as l, type Position as m, type DiagnosticInfo as n, VINDecoder as o, BrowserDatabaseAdapter as p, BrowserDatabaseAdapterFactory as q, CloudflareD1Adapter as r, createD1Adapter as s, decodeVIN as t, BODY_STYLE_MAP as u, type BaseError as v };