makes.ts 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /**
  2. * Makes as the code service keys them (`ford`, `land-rover`) and as people write them, for
  3. * the import's make picker and for naming a make's codes. A make the service has that is not
  4. * listed here still works; its name is made from its key.
  5. */
  6. export interface Make {
  7. key: string
  8. name: string
  9. /** Outboards and marine engines, offered to a marine workshop. */
  10. marine?: boolean
  11. /** Other ways a vehicle's make is written, as keys: a Vauxhall is an Opel, a VW a Volkswagen. */
  12. aliases?: string[]
  13. }
  14. export const MAKES: Make[] = [
  15. { key: 'acura', name: 'Acura' },
  16. { key: 'alfa-romeo', name: 'Alfa Romeo' },
  17. { key: 'audi', name: 'Audi' },
  18. { key: 'bmw', name: 'BMW' },
  19. { key: 'byd', name: 'BYD' },
  20. { key: 'cadillac', name: 'Cadillac' },
  21. { key: 'chevrolet', name: 'Chevrolet', aliases: ['chevy'] },
  22. { key: 'chrysler', name: 'Chrysler' },
  23. { key: 'citroen', name: 'Citroën' },
  24. { key: 'cupra', name: 'Cupra' },
  25. { key: 'dacia', name: 'Dacia' },
  26. { key: 'dodge', name: 'Dodge' },
  27. { key: 'ds', name: 'DS' },
  28. { key: 'fiat', name: 'Fiat' },
  29. { key: 'ford', name: 'Ford' },
  30. { key: 'gmc', name: 'GMC' },
  31. { key: 'honda', name: 'Honda' },
  32. { key: 'hyundai', name: 'Hyundai' },
  33. { key: 'infiniti', name: 'Infiniti' },
  34. { key: 'isuzu', name: 'Isuzu' },
  35. { key: 'iveco', name: 'Iveco' },
  36. { key: 'jaguar', name: 'Jaguar' },
  37. { key: 'jeep', name: 'Jeep' },
  38. { key: 'kia', name: 'Kia' },
  39. { key: 'land-rover', name: 'Land Rover', aliases: ['landrover', 'range-rover'] },
  40. { key: 'lexus', name: 'Lexus' },
  41. { key: 'man', name: 'MAN' },
  42. { key: 'mazda', name: 'Mazda' },
  43. { key: 'mercedes-benz', name: 'Mercedes-Benz', aliases: ['mercedes', 'mb', 'mercedesbenz'] },
  44. { key: 'mg', name: 'MG' },
  45. { key: 'mitsubishi', name: 'Mitsubishi' },
  46. { key: 'nissan', name: 'Nissan' },
  47. { key: 'opel', name: 'Opel / Vauxhall', aliases: ['vauxhall', 'opel-vauxhall'] },
  48. { key: 'peugeot', name: 'Peugeot' },
  49. { key: 'polestar', name: 'Polestar' },
  50. { key: 'porsche', name: 'Porsche' },
  51. { key: 'ram', name: 'Ram' },
  52. { key: 'renault', name: 'Renault' },
  53. { key: 'scania', name: 'Scania' },
  54. { key: 'seat', name: 'SEAT' },
  55. { key: 'skoda', name: 'Škoda' },
  56. { key: 'smart', name: 'smart' },
  57. { key: 'subaru', name: 'Subaru' },
  58. { key: 'suzuki', name: 'Suzuki' },
  59. { key: 'tesla', name: 'Tesla' },
  60. { key: 'toyota', name: 'Toyota' },
  61. { key: 'volkswagen', name: 'Volkswagen', aliases: ['vw'] },
  62. { key: 'volvo', name: 'Volvo' },
  63. { key: 'evinrude', name: 'Evinrude', marine: true },
  64. { key: 'honda-marine', name: 'Honda Marine', marine: true },
  65. { key: 'mercruiser', name: 'MerCruiser', marine: true },
  66. { key: 'mercury', name: 'Mercury', marine: true },
  67. { key: 'suzuki-marine', name: 'Suzuki Marine', marine: true },
  68. { key: 'tohatsu', name: 'Tohatsu', marine: true },
  69. { key: 'volvo-penta', name: 'Volvo Penta', marine: true },
  70. { key: 'yamaha', name: 'Yamaha', marine: true },
  71. { key: 'yanmar', name: 'Yanmar', marine: true },
  72. ]
  73. const BY_KEY = new Map(MAKES.map((m) => [m.key, m]))
  74. /** A make as the service keys it: lower case letters and digits, words joined by dashes. */
  75. export const MAKE_KEY_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/
  76. export function isMakeKey(value: string | null | undefined): value is string {
  77. return !!value && value.length <= 30 && MAKE_KEY_PATTERN.test(value)
  78. }
  79. /** "Land Rover" as `land-rover`, "Škoda" as `skoda`; null when nothing is left of it. */
  80. export function makeKey(name: string): string | null {
  81. const key = name
  82. .normalize('NFKD')
  83. .replace(/[̀-ͯ]/g, '')
  84. .toLowerCase()
  85. .replace(/[^a-z0-9]+/g, '-')
  86. .replace(/^-+|-+$/g, '')
  87. .replace(/^[0-9-]+/, '')
  88. .slice(0, 30)
  89. .replace(/-+$/, '')
  90. return isMakeKey(key) ? key : null
  91. }
  92. /**
  93. * The make a vehicle's make names, as the service keys it: "Vauxhall" and "Opel / Vauxhall"
  94. * are opel, "Škoda" is skoda, "VW" volkswagen. A make not listed keeps its own key.
  95. */
  96. export function canonicalMakeKey(name: string | null | undefined): string | null {
  97. if (!name) return null
  98. const key = makeKey(name)
  99. if (!key) return null
  100. if (BY_KEY.has(key)) return key
  101. return MAKES.find((m) => m.aliases?.includes(key))?.key ?? key
  102. }
  103. /** How people write a make: "BMW", "Land Rover"; a key not listed as its words. */
  104. export function makeName(key: string): string {
  105. const known = BY_KEY.get(key)
  106. if (known) return known.name
  107. return key
  108. .split('-')
  109. .map((w) => (w.length <= 3 ? w.toUpperCase() : w.charAt(0).toUpperCase() + w.slice(1)))
  110. .join(' ')
  111. }