npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@omniyat/tomtommodule

v1.2.1

Published

Accès simplifié aux API TomTom : itinéraires, optimisation de tournées, géocodage, bornes de recharge

Readme

@omniyat/tomtommodule

Accès simplifié aux API TomTom depuis Node.js (≥ 18) : itinéraires, optimisation de tournées, géocodage, bornes de recharge.

  • Une instance partagée, configurée une fois (init).
  • Aucune exception : chaque méthode renvoie { success, response, detail?, status?, timeout? }.
  • Types TypeScript inclus, utilisable en import comme en require.
npm install @omniyat/tomtommodule
import TTModule from '@omniyat/tomtommodule'      // ou : const TTModule = require('@omniyat/tomtommodule')

TTModule.init({ apiKey: process.env.TOMTOM_API_KEY, timeout: 10000 })

const res = await TTModule.calculateRoute([{ lat: 48.8566, lng: 2.3522 }, { lat: 45.764, lng: 4.8357 }])
if (res.success) console.log(res.response.summary.lengthInMeters)
else console.error(res.status, res.response)

Sommaire

Configuration

TTModule.init({
  apiKey: '…',        // clé API TomTom (obligatoire pour appeler TomTom)
  timeout: 10000,     // délai maximal de chaque appel en ms ; 0 = aucun (défaut)
  baseUrl: 'https://api.tomtom.com/', // défaut ; utile pour un proxy (ancien nom : base_url)
  maxTourWaypoints: 12, // points max. d'une tournée, départ et arrivée compris (défaut 12)
})

maxTourWaypoints ne doit être augmenté que si TomTom a relevé la limite de votre compte (sur demande au service commercial) ; une valeur invalide (entier < 2) fait lever une erreur à init. TTModule.MAX_TOUR_WAYPOINTS donne la limite en vigueur.

init peut être rappelée : les valeurs fournies remplacent les précédentes, les autres sont conservées. TTModule.configs donne la configuration courante (lecture seule).

Toutes les méthodes acceptent en dernier argument des options de requête :

| Option | Rôle | |-----------|-----------------------------------------------------------------------| | params | paramètres de requête TomTom ({ language: 'fr-FR', traffic: true }) | | timeout | délai de cet appel en ms (prioritaire sur init) | | headers | en-têtes HTTP supplémentaires |

Format des résultats

{
  success: boolean
  response: …        // réponse TomTom (enrichie) si success, sinon message d'erreur lisible
  detail?: unknown   // corps de l'erreur renvoyée par TomTom
  status?: number    // statut HTTP TomTom ; 400 pour une entrée refusée localement ; absent si erreur réseau
  timeout?: boolean  // true si le délai a été dépassé
}

Le message d'erreur reprend celui de TomTom (code - message), complété de la raison détaillée quand TomTom en donne une (ex. BAD_REQUEST - … (waypoints[1] : The following waypoints can not be reached…)). Les réponses HTML sont réduites à leur texte.

Les entrées invalides (coordonnées manquantes, plus de 12 points de tournée, date illisible…) sont refusées sans appeler TomTom, avec status: 400 et un message en français.

Statuts TomTom fréquents : 401 clé refusée ; 403 produit non inclus dans l'abonnement, compte inactif ou crédits épuisés (InsufficientFunds) ; 429 trop de requêtes par seconde.

Coordonnées

Partout, un point s'écrit { lat, lng } ou { latitude, longitude }. Les nombres en texte ('48.85') sont acceptés ; 0 est une valeur valide.

Itinéraires

calculateRoute(waypoints, options?)

Itinéraire passant par 2 points ou plus (Routing API). La réponse TomTom est complétée de :

  • route : tous les points du premier itinéraire, à plat ([{ latitude, longitude }]) ;
  • summary : son résumé (lengthInMeters, travelTimeInSeconds, trafficDelayInSeconds, departureTime, arrivalTime…).
await TTModule.calculateRoute(
  [{ lat: 48.85, lng: 2.35 }, { lat: 48.86, lng: 2.33 }],
  { params: { travelMode: 'truck', traffic: true, routeType: 'fastest' } },
)

calculateETA({ startLocation, endLocation, options? })

Raccourci de calculateRoute entre deux points. L'objet passé n'est pas modifié.

calculateMatrix(body, options?)

Matrix Routing v2 synchrone. Le corps ({ origins, destinations, options }) est transmis tel quel, la réponse est celle de TomTom.

Optimisation de tournées

planTour({ waypoints, options? }, requestOptions?)

Calcule le meilleur ordre de passage avec Waypoint Optimization en une seule requête, et renvoie pour chaque arrêt les heures d'arrivée et de départ, l'étape parcourue et les cumuls.

const res = await TTModule.planTour({
  waypoints: [
    { point: { latitude: 48.8566, longitude: 2.3522 }, name: 'Dépôt' },
    { point: { latitude: 48.8867, longitude: 2.3431 }, name: 'Client A', serviceTimeInSeconds: 600,
      timeWindows: [{ openingHour: '09:00', closingHour: '12:00' }] },
    { point: { latitude: 48.8462, longitude: 2.3372 }, name: 'Client B' },
  ],
  options: { returnToDepot: true, travelMode: 'truck', vehicleWeight: 7500, departAt: '2026-10-07T08:00:00+02:00' },
})

Les points

| Champ | Rôle | |------------------------|------------------------------------------------------------------------------------------| | point | coordonnées (obligatoire) | | name | nom libre repris dans le résultat | | isDestination | impose ce point comme arrivée | | serviceTimeInSeconds | temps passé sur place | | timeWindows | un créneau [{ openingHour: 'HH:MM', closingHour: 'HH:MM' }] ; exige departAt ≠ any | | importance | 1 à 100 ; un point peu important peut être écarté s'il ne tient pas dans son créneau (exige timeWindows) |

Au plus 12 points, départ et arrivée compris (limite standard TomTom, réglable par init({ maxTourWaypoints }) si votre compte le permet). Avec returnToDepot, le retour compte : 11 points saisis au maximum.

Départ et arrivée

  • Départ : le premier point (waypointConstraints.originIndex, défaut 0 ; -1 = choisi par TomTom).
  • Arrivée, dans cet ordre de priorité :
    1. waypointConstraints.destinationIndex si fourni ;
    2. returnToDepot: true : retour au point de départ (il est ajouté en fin de liste) ;
    3. le point marqué isDestination ;
    4. sinon arrivée libre : TomTom finit la tournée là où c'est le plus efficace.

Options TomTom (toutes facultatives)

| Option | Valeurs | |-----------------------------------|---------------------------------------------------------------------------| | travelMode | car (défaut), truck | | vehicleMaxSpeed | km/h, 0 à 250 | | vehicleWeight, vehicleAxleWeight | kg | | vehicleLength, vehicleWidth, vehicleHeight | m | | vehicleCommercial | true / false | | vehicleLoadType | ['USHazmatClass1'…'USHazmatClass9', 'otherHazmatExplosive', 'otherHazmatGeneral', 'otherHazmatHarmfulToWater'] | | vehicleAdrTunnelRestrictionCode | B, C, D, E | | traffic | historical, live | | departAt | now (défaut du module), any, ou une date (Date ou texte ISO 8601) | | waypointConstraints | { originIndex, destinationIndex, visitingOrders: [[a, b], …] } (a avant b) | | groupConstraints | { groups: [{ includedPointIndexes: [...] }], groupOrders: [[g1, g2], …] } (points consécutifs, ordre des groupes) | | returnToDepot | propre au module : la tournée revient au départ |

Les extensions travelTimes et routeLengths sont toujours demandées : ce sont elles qui donnent les horaires et distances par étape.

Résultat

{
  optimizedOrder: ['Dépôt', 'Client B', 'Client A', 'Dépôt'],   // noms, dans l'ordre de passage
  optimizedIndexes: [0, 2, 1, 0],                                // index dans waypoints
  detail: [
    { index: 0, name: 'Dépôt', point, isDepot: true, isReturn: false, departureTime: '…' },
    { index: 2, name: 'Client B', point, isDepot: false, isReturn: false,
      arrivalTime: '…', departureTime: '…',
      routeSummary: {           // étape TomTom menant à cet arrêt
        originIndex, destinationIndex, lengthInMeters, travelTimeInSeconds, departureTime, arrivalTime,
        travelTimeInSecondsFromOrigin, distanceFromOrigin,   // cumuls de trajet depuis le départ
      } },
    { index: 1, name: 'Client A', …, serviceTimeInSeconds: 600 },
    { index: 0, name: 'Dépôt', isDepot: true, isReturn: true, arrivalTime: '…', routeSummary: { … } },
  ],
  excluded: [],               // points écartés par TomTom (importance + créneaux) : { index, name, point }
  summary: { routeSummary, legSummaries },   // réponse TomTom d'origine
}

Notes :

  • travelTimeInSecondsFromOrigin cumule les temps de trajet ; les temps de service et d'attente se lisent dans arrivalTime / departureTime.
  • Chez TomTom, le temps de service d'un point est compté dans l'étape qui part de ce point ; le module le reporte sur l'arrêt (serviceTimeInSeconds).
  • Les heures (HH:MM) des créneaux sont celles du lieu. Si un point ne peut être atteint dans son créneau, TomTom répond COULD_NOT_OPTIMIZE_ORDER (le message du module indique le point concerné) — sauf s'il a une importance, auquel cas il peut être écarté (excluded).

optimizeWaypoints(body, options?)

Accès brut à Waypoint Optimization : { waypoints, options } envoyé tel quel, réponse TomTom inchangée. optimizewaypoints (ancien nom) reste disponible.

Recherche

geocode(address, options?)

Adresse → coordonnées. response.result = premier résultat (response.results = tous).

const res = await TTModule.geocode('10 rue de Rivoli, Paris', { params: { countrySet: 'FR', language: 'fr-FR' } })
res.response.result?.position // { lat, lon }

reverseGeocode(coordinates, options?)

Coordonnées → adresse. response.address = première adresse, avec la position sous deux formes : lat / lng en texte (format historique) et latitude / longitude en nombres.

evSearch(input, options?)

Bornes de recharge autour d'un point (EV Search Nearby). lat et lon (ou topLeft et btmRight) obligatoires, rayon par défaut 10 000 m. Filtres : limit, status, connector, accessType, minPowerKW, maxPowerKW…

await TTModule.evSearch({ lat: 45.76, lon: 4.85, radius: 2000, minPowerKW: 50 })
await TTModule.evSearch({ params: { lat: 45.76, lon: 4.85 } }) // forme historique

evById(id, options?)

Disponibilité de bornes par identifiant : evById('FR*…'), evById({ id }) ou evById({ params: { id } }).

Développement

npm test                                 # tests unitaires + compatibilité 1.x (TomTom simulé)
TOMTOM_API_KEY=… npm run test:live       # appels réels (consomme le quota)
npm run typecheck
npm run test:dist                        # construit puis vérifie dist/ en require et import
npm run deploy                           # typecheck + tests + dist + publication npm

Le code est dans src/ (TypeScript), construit par tsup vers dist/ (ESM + CommonJS + types). test/compat.test.ts fige l'interface 1.x utilisée par les applications ; il doit toujours passer.