94 lines
No EOL
2.8 KiB
TypeScript
94 lines
No EOL
2.8 KiB
TypeScript
import type { Place } from './types'
|
|
|
|
export interface BookingLink {
|
|
url: string
|
|
label: string
|
|
provider: string
|
|
}
|
|
|
|
/** Normalise un nom de ville pour l'inclure dans une URL slug. */
|
|
function slugify(label: string): string {
|
|
return label
|
|
.normalize('NFD').replace(/\p{Diacritic}/gu, '')
|
|
.toLowerCase()
|
|
.replace(/[^a-z0-9]+/g, '-')
|
|
.replace(/^-+|-+$/g, '')
|
|
}
|
|
|
|
/** Extrait le nom de ville avant la virgule ("Lille, France" -> "Lille"). */
|
|
function cityName(label: string): string {
|
|
return label.split(',')[0]?.trim() ?? label.trim()
|
|
}
|
|
|
|
/** Format de date que Kombo et CheckMyBus acceptent tous les deux. */
|
|
function dateISO(d: Date): string {
|
|
return d.toISOString().slice(0, 10)
|
|
}
|
|
|
|
/** Kombo comprend les noms de ville en clair : pas de mapping de gares a maintenir. */
|
|
export function buildKomboLink(from: Place, to: Place, date: Date): BookingLink {
|
|
const f = encodeURIComponent(cityName(from.label))
|
|
const t = encodeURIComponent(cityName(to.label))
|
|
const d = dateISO(date)
|
|
return {
|
|
url: `https://www.kombo.co/fr/app/outward/1/1/18/${d}/${f}/${t}/0/0/results`,
|
|
label: 'Reserver sur Kombo',
|
|
provider: 'Kombo',
|
|
}
|
|
}
|
|
|
|
/**
|
|
* CheckMyBus accepte un fallback avec UUID zeros quand on ne connait pas
|
|
* son identifiant interne : le nom + les coordonnees suffisent a lancer
|
|
* la recherche. Le fragment porte tout, y compris la date.
|
|
*/
|
|
export function buildCheckMyBusLink(from: Place, to: Place, date: Date): BookingLink {
|
|
const zeroId = '00000000-0000-0000-0000-000000000000'
|
|
const encodeStop = (p: Place) =>
|
|
encodeURIComponent(`${cityName(p.label)}, France`)
|
|
+ `%24${p.lat}%2C${p.lon}`
|
|
+ `%24${zeroId}%24${zeroId}%24true%24false`
|
|
|
|
const fromSlug = slugify(cityName(from.label))
|
|
const toSlug = slugify(cityName(to.label))
|
|
const d = dateISO(date)
|
|
|
|
const fragment = [
|
|
`departureDate=${d}`,
|
|
`origin=${encodeStop(from)}`,
|
|
`destination=${encodeStop(to)}`,
|
|
'sortValue=Relevance',
|
|
'sortOrder=ascending',
|
|
'adults=1',
|
|
].join('&')
|
|
|
|
return {
|
|
url: `https://www.checkmybus.fr/${fromSlug}/${toSlug}?mode=search#${fragment}`,
|
|
label: 'Chercher sur CheckMyBus',
|
|
provider: 'CheckMyBus',
|
|
}
|
|
}
|
|
|
|
/** Chargemap : on ouvre juste la page d'accueil du planificateur. */
|
|
export function buildChargemapLink(): BookingLink {
|
|
return {
|
|
url: 'https://chargemap.com/map',
|
|
label: 'Ouvrir Chargemap',
|
|
provider: 'Chargemap',
|
|
}
|
|
}
|
|
|
|
/** Retourne le lien approprie pour le mode donne, ou null si aucun. */
|
|
export function buildBookingLink(
|
|
mode: 'train' | 'bus' | 'electric_car' | 'bike',
|
|
from: Place,
|
|
to: Place,
|
|
date: Date,
|
|
): BookingLink | null {
|
|
switch (mode) {
|
|
case 'train': return buildKomboLink(from, to, date)
|
|
case 'bus': return buildCheckMyBusLink(from, to, date)
|
|
case 'electric_car': return buildChargemapLink()
|
|
case 'bike': return null
|
|
}
|
|
} |