From 1b0858a253b4f39a4cd25c22e967dc914356b715 Mon Sep 17 00:00:00 2001 From: Traines Date: Tue, 14 Jan 2025 22:16:09 +0000 Subject: [PATCH] update docs --- docs/api.md | 18 +- docs/changelog.md | 1075 ----------------------------------- docs/departures.md | 45 +- docs/hafas-mgate-api.md | 160 ------ docs/journeys-from-trip.md | 51 -- docs/journeys.md | 94 +-- docs/lines.md | 70 --- docs/locations.md | 12 +- docs/migrating-to-5.md | 108 ---- docs/migrating-to-6.md | 93 --- docs/nearby.md | 10 +- docs/profile-boilerplate.js | 45 -- docs/radar.md | 191 ------- docs/reachable-from.md | 98 ---- docs/readme.md | 72 +-- docs/refresh-journey.md | 19 +- docs/remarks.md | 150 ----- docs/server-info.md | 38 -- docs/stop.md | 6 +- docs/tests.md | 8 +- docs/trip.md | 44 +- docs/trips-by-name.md | 114 ---- docs/writing-a-profile.md | 163 ------ index.js | 2 +- readme.md | 5 +- 25 files changed, 115 insertions(+), 2576 deletions(-) delete mode 100644 docs/changelog.md delete mode 100644 docs/hafas-mgate-api.md delete mode 100644 docs/journeys-from-trip.md delete mode 100644 docs/lines.md delete mode 100644 docs/migrating-to-5.md delete mode 100644 docs/migrating-to-6.md delete mode 100644 docs/profile-boilerplate.js delete mode 100644 docs/radar.md delete mode 100644 docs/reachable-from.md delete mode 100644 docs/remarks.md delete mode 100644 docs/server-info.md delete mode 100644 docs/trips-by-name.md delete mode 100644 docs/writing-a-profile.md diff --git a/docs/api.md b/docs/api.md index 7acf15d4..ede9fd13 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,17 +1,19 @@ -# `hafas-client` API +# `db-vendo-client` API + +Also see the [root readme](https://github.com/public-transport/db-vendo-client) for a shortlist of differences of db-vendo-client to hafas-client and of differences between the profiles. - [`journeys(from, to, [opt])`](journeys.md) – get journeys between locations - [`refreshJourney(refreshToken, [opt])`](refresh-journey.md) – fetch up-to-date/more details of a `journey` -- [`journeysFromTrip(tripId, previousStopover, to, [opt])`](journeys-from-trip.md) – get journeys from a trip to a location +- `journeysFromTrip(tripId, previousStopover, to, [opt])` – not supported - [`trip(id, lineName, [opt])`](trip.md) – get details for a trip -- [`tripsByName(lineNameOrFahrtNr, [opt])`](trips-by-name.md) – get all trips matching a name +- `tripsByName(lineNameOrFahrtNr, [opt])` – not supported - [`departures(station, [opt])`](departures.md) – query the next departures at a station - [`arrivals(station, [opt])`](arrivals.md) – query the next arrivals at a station - [`locations(query, [opt])`](locations.md) – find stations, POIs and addresses - [`stop(id, [opt])`](stop.md) – get details about a stop/station - [`nearby(location, [opt])`](nearby.md) – show stations & POIs around -- [`radar(north, west, south, east, [opt])`](radar.md) – find all vehicles currently in a certain area -- [`reachableFrom(address, [opt])`](reachable-from.md) – get all stations reachable from an address within `n` minutes -- [`remarks([opt])`](remarks.md) – get all remarks -- [`lines(query, [opt])`](lines.md) – get all lines matching a name -- [`serverInfo([opt])`](server-info.md) – fetch meta information from HAFAS +- `radar(north, west, south, east, [opt])` – not supporteda +- `reachableFrom(address, [opt])` – not supported +- `remarks([opt])` – not supported +- `lines(query, [opt])` – not supported +- `serverInfo([opt])` – not supported diff --git a/docs/changelog.md b/docs/changelog.md deleted file mode 100644 index b9d2edf0..00000000 --- a/docs/changelog.md +++ /dev/null @@ -1,1075 +0,0 @@ -# Changelog - -## `6.2.1` - -- 8520eb3d [*mobil.nrw* profile](../p/mobil-nrw): fix `mode` for `ec-ic` product 🐛 -- f29ced5b handle `PROBLEMS` HAFAS error code - -[🏷 `6.2.1`](https://github.com/public-transport/hafas-client/releases/tag/6.2.1), 2024-01-18 - -## `6.2.0` - -- 244e88de add attribute `additional` to additional stopovers ✅ -- 02c781b1 `cross-fetch@4`, `p-retry@6` -- ecc8fccc `tap@18` - -[🏷 `6.2.0`](https://github.com/public-transport/hafas-client/releases/tag/6.2.0), 2023-11-27 - -## `6.1.1` - -- 45610fc9 [*IVB* profile](../p/ivb): update SSL CA certificate chain 🐛 -- 581a4751 profiles' examples: fixes, minor tweaks 📝 -- 19cdde06 document testing setup 📝 -- 0bc6ba36 [*DB* profile](../p/db): pass along `opt.age` if defined ✅ - -[🏷 `6.1.1`](https://github.com/public-transport/hafas-client/releases/tag/6.1.1), 2023-09-03 - -## `6.1.0` - -- 793cc9ee with `$HTTP(S)_PROXY`, keep connections alive for 10s -- 5ce0129c [*DB* profile](../p/db): add `routingMode` option 📝✅ - -[🏷 `6.1.0`](https://github.com/public-transport/hafas-client/releases/tag/6.1.0), 2023-07-25 - -## `6.0.5` - -- 9a1ef7c5 `journeys()`/`journeysFromTrip()`/`refreshJourney()`/`trip()`/`tripsByName()`: apply leg-wide remarks even if `opt.stopovers` is `false` 🐛 – Thanks @traines-source! - -[🏷 `6.0.5`](https://github.com/public-transport/hafas-client/releases/tag/6.0.5), 2023-05-15 - -## `6.0.4` - -- 14c9805a `journeys()`: let `earlierRef`/`laterRef` fall back to `null` 🐛 -- 8faf8ba5 [*DB* profile](../p/db): use ver `1.16` for `stop()` requests 🐛, update integration test fixture ✅ - -[🏷 `6.0.4`](https://github.com/public-transport/hafas-client/releases/tag/6.0.4), 2023-04-04 - -## `6.0.3` - -- e7602e6c `createClient()`: throw if userAgent is one of the documented ones 💥📝 -- 5910d625 docs: make user agent instructions more specific & actionable 📝 (related: [#286](https://github.com/public-transport/hafas-client/issues/286)) - -[🏷 `6.0.3`](https://github.com/public-transport/hafas-client/releases/tag/6.0.3), 2023-03-14 - -## `6.0.2` - -- 26394489 [*SNCB*/*NMBS* profile](../p/sncb): document profile as temporarily broken 📝 -- c2a71b08 `lib/request.js`: import `Buffer` 🐛 - -[🏷 `6.0.2`](https://github.com/public-transport/hafas-client/releases/tag/6.0.2), 2023-02-10 - -## `6.0.1` - -- d8805d9e/fc1afe06 docs: fix profile `import`s in code examples 📝 – Thanks @KristjanESPERANTO! -- 547dd4b2 `parseDateTime()`/`formatDate()`/`formatTime()`: share Luxon `IANAZone`s ⚡️ -- 557fc660 upgrade to `luxon@3` - -[🏷 `6.0.1`](https://github.com/public-transport/hafas-client/releases/tag/6.0.1), 2022-12-11 - -## `6.0.0` - -Note that this version is not backwords-compatible with `5.*`. Check out [the migration guide](migrating-to-6.md). - -### breaking changes 💥 - -- 1e8b5982 remove SBB profile (they have shut off their endpoint) -- 0349ebac remove HVV profile (they have shut off their endpoint) -- 339d64e9 convert all code to [ES Modules](https://exploringjs.com/es6/ch_modules.html) -- d5969bc0 require Node `>=10` -- 30cb1f3d `trip()`: remove `lineName` parameter, update integration test fixtures -- a81e550f `departures()`/`arrivals()` - - `departures{GetPasslist,StbFltrEquiv}`: default to `false` - - return object with `realtimeDataUpdatedAt` & results -- 40957d35 `reachableFrom()`: don't retry failed requests 3 times -- 751ae21d/a0a4064b/0cc50a91/2fcaa230/bb70081c/44c8e37e `journeys()`/`journeysFromTrip()`/`trip()`/`tripsByName()`/`radar()`/`reachableFrom()`/`remarks()`/`lines()`: rename `realtimeDataFrom` to `realtimeDataUpdatedAt` -- 3cbbc3c4 `refreshJourney()`: return object with `realtimeDataUpdatedAt` & results -- 7765f9d7/9b263bb3 rework errors thrown by `hafas-client` -- e0cdd559 rename `warning.{from,to}Loc` to `{from,to}Location` -- b7405390 remove `trip.reachable` -- ef9e3765 don't trim `line.adminCode` -- b030eec1/7765f9d7 make (almost) all `Promise`-based code async functions -- BVG/VBB profile: - - 1ae13629/7b037469 don't parse line props using `vbb-parse-line` - - 1f611595/5ecf03f3 don't convert 7/9 <-> 12 digit IDs - - df4124e3/d2bc1346 don't shorten stop/station names -- DB profile: - - e46514c5 rename `regionalExp` product to `regionalExpress` - - 3c17678d use `REALTIME` routing mode - -### features - -- 16671b6d SNCB: re-enable `reachableFrom()` -- 492fdeb2 add boolean `profile.randomizeUserAgent` flag 📝 -- 1000e48d handle `METHOD_NA`/`NO_MATCH`/`PARAMETER` errors - -### bugfixes 🐛 - -- db442bb5 `serverInfo()`: fix `realtimeDataUpdatedAt` parsing -- b1c2eb9b `parseWarning()`: handle missing `common.himMsgEventL[].{f,t}Time` -- cef6dcaf `lib/request.js`: pass whole request body into `profile.transformReqBody()` - -[🏷 `6.0.0`](https://github.com/public-transport/hafas-client/releases/tag/6.0.0), 2022-11-19 - -## `5.26.2` - -- a60083f8 parse `trip.scheduledDays` ✅ -- b6900a3d parse `journey.scheduleDays` using `fpB` & `fpE` 🐛✅ – Thanks @bergmannjg! -- f530a30f mention related libs 📝 -- 5ff8527b tweak & restructure docs 📝, explicit defaults - -[🏷 `5.26.2`](https://github.com/public-transport/hafas-client/releases/tag/5.26.2), 2022-10-15 - -## `5.26.1` - -- 0f7382e3 `parseArrival` & `parseDeparture`: properly parse `.origin` & `destination` 🐛 -- 7ccffa5e `profile.log{Request,Response}()`: pass in random request ID -- 66d78767 readme: mention typings & related libs 📝 - -[🏷 `5.26.1`](https://github.com/public-transport/hafas-client/releases/tag/5.26.1), 2022-10-15 - -## `5.26.0` - -- 829c9ca4 add `profile.log{Request,Response}()` hooks 📝 - -[🏷 `5.26.0`](https://github.com/public-transport/hafas-client/releases/tag/5.26.0), 2022-10-06 - -## `5.25.0` - -- 0a636981 parse `CHKI` (check-in, check-out) legs ✅ – Thanks @yu-re-ka! -- 7c68f962 `parse{Stopover,JourneyLeg, Trip}`: expose `{arrival,departure}PrognosisType` ✅ – Thanks @HybridFox! -- 95af0a01 `parseArrival` & `parseDeparture`: expose `prognosisType` ✅ - -[🏷 `5.25.0`](https://github.com/public-transport/hafas-client/releases/tag/5.25.0), 2022-07-30 - -## `5.24.1` - -- 492cb7df KVB: provide CA certificate chain via `Agent` 🐛 - -[🏷 `5.24.1`](https://github.com/public-transport/hafas-client/releases/tag/5.24.1), 2022-06-23 - -## `5.24.0` - -- 2edcd49e `serverInfo()`: add `opt.versionInfo` 📝✅ -- f3c2ee6f/1236cf63 DB: support age-based tariffs – Thanks @roehrt! -- 7e1f7ed4 BVG/VBB: parse stop DHIDs ✅ -- f8ca2d5d BVG: only expand `9*` stop IDs to 12 digits 🐛 -- 68ecd7c5 readme: fix `strecken.info` link 📝 – Thanks @fhueter! - -[🏷 `5.24.0`](https://github.com/public-transport/hafas-client/releases/tag/5.24.0), 2022-04-26 - -## `5.23.0` - -- 57084262 expose `departure.destination` & `arrival.origin` ✅ – Thanks @bddq! - -[🏷 `5.23.0`](https://github.com/public-transport/hafas-client/releases/tag/5.23.0), 2022-02-23 - -## `5.22.2` - -- f6b144f0 BVG: update API endpoint -- e3a02297 `lib/request`: tweak `User-Agent` randomisation logic -- e69d069d/fa9a8d9f update integration tests ✅ -- 2ec079ad TPG: add integration test ✅ -- 4cd0e9d9 minor tweaks 📝 - -[🏷 `5.22.2`](https://github.com/public-transport/hafas-client/releases/tag/5.22.2), 2022-01-13 - -## `5.22.1` - -- 2fd06941 use [HTTP Keep-Alive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive) ⚡️ -- 9c10a176 fix request debug-logging 🐛 - -[🏷 `5.22.1`](https://github.com/public-transport/hafas-client/releases/tag/5.22.1), 2021-12-28 - -## `5.22.0` - -- ed86ad0b add [*KVB* profile](../p/kvb) -- f6733d93 ÖBB: enable `lines()` - -[🏷 `5.22.0`](https://github.com/public-transport/hafas-client/releases/tag/5.22.0), 2021-12-08 - -## `5.21.1` - -- f41b8ac4 BVG: update API endpoint 🐛, add new integration test fixtures ✅ - -[🏷 `5.21.1`](https://github.com/public-transport/hafas-client/releases/tag/5.21.1), 2021-11-18 - -## `5.21.0` - -- 97b6a76e `parseTrip()`: expose `realtimeDataUpdatedAt` ✅ -- 3453cbe1 `parseArrival()`/`parseDeparture()`: expose `stbStop.{rem,msg}L` as `remarks[]` as well -- 69ddf5fb/6941e7a4 BVG: parse occupancy ✅ -- c270eed9 `nationalExp` -> `nationalExpress` 🐛 -- 4492b3a3 use correct `HttpsAgent` option for `LOCAL_ADDRESS` environment variable 🐛 - -[🏷 `5.21.0`](https://github.com/public-transport/hafas-client/releases/tag/5.21.0), 2021-11-01 - -## `5.20.2` - -- 84c7582a `journeys()`: fix empty `viaLocL[]` 🐛 (#247) -- dd5e4368 fix `departures()`/`arrivals()` without `opt.direction` 🐛 -- 3f75e075 BVG: update API endpoint -- 1f6e6810 DB: update `.ext` -- 39d3807c minor tweaks 📝 -- 8d4f8a83 E2E/integration tests: update fixtures ✅ - -[🏷 `5.20.2`](https://github.com/public-transport/hafas-client/releases/tag/5.20.2), 2021-10-26 - -## `5.20.1` - -- 46fb44d0 SNCB: update CA chain 🐛 -- f0d33564 `parseTrip()`: handle missing `stopL[]` (on-demand trips) 🐛✅ -- fd6a349b `tripsByName()`: more options, add to debug CLI, skipped E2E test ✅📝 -- 39ca7ede `tripsByName()`: support some journey filters -- 22a7f16e remove SBB integration/E2E test ✅ -- 102c4bf2 BVG/VBB: fix `nearby()` integration/E2E test ✅ -- 959e894d E2E/integration tests: un-skip tests, update mocked `when`, update fixtures ✅ - -[🏷 `5.20.1`](https://github.com/public-transport/hafas-client/releases/tag/5.20.1), 2021-10-24 - -## `5.20.0` - -- 0a096a13 `parseJourneyLeg()`/`parseTrip()`: expose `currentLocation` ✅📝 -- b10c1ce6 Rejseplanen `trip()` test: update fixtures ✅ -- 6507d5a7 VBB `departures()` test: update fixtures ✅ -- c1ee557c `parseArrivalOrDeparture()`: expose `currentTripLocation` ✅📝 - -[🏷 `5.20.0`](https://github.com/public-transport/hafas-client/releases/tag/5.20.0), 2021-10-18 - -## `5.19.1` - -- 042668ff add [*DART* profile](../p/dart) -- ca75c440 adapt *VBB* profile to server changes - -[🏷 `5.19.1`](https://github.com/public-transport/hafas-client/releases/tag/5.19.1), 2021-09-21 - -## `5.19.0` - -- c10f3181 `refreshJourney()`: expose `realtimeDataFrom` -- c3bdcc88 expose `prodCtx.catOut` as `line.productName` -- 21610276 first/last walking leg: handle `dTZOffset`/`aTZOffset` of `0` 🐛 -- 6de2dc7b/dd52c4ad DB: fix price parsing 🐛 -- 0114f587 adapt E2E tests to latest data ✅ - -[🏷 `5.19.0`](https://github.com/public-transport/hafas-client/releases/tag/5.19.0), 2021-08-24 - -## `5.18.0` - -- e293223c add [*VVV* profile](../p/vvv) -- f20466c2 add [*IVB* profile](../p/ivb) -- 0ae13b09 add [*STV* profile](../p/stv) -- 649a7ec0 add [*OÖVV* profile](../p/ooevv) -- db2cbfdc add [*VOR* profile](../p/vor) -- 56bd16b5 add [Salzburg profile](../p/salzburg) -- ce828176/aab7babb/0995696c [*DB* profile](../p/db): add [`journeysFromTrip()`](journeys-from-trips.md) - -[🏷 `5.18.0`](https://github.com/public-transport/hafas-client/releases/tag/5.18.0), 2021-08-05 - -## `5.17.0` - -- 24c2cc6e add [*BLS* profile](../p/bls) -- 33dab455 add [*TPG* profile](../p/tpg) - -[🏷 `5.17.0`](https://github.com/public-transport/hafas-client/releases/tag/5.17.0), 2021-07-28 - -## `5.16.0` - -- 7cb62108 `lib/request`: validate response `content-type` 🐛 -- 96b4d55f (re-)upgrade profiles, adapt feature flags -- 62843f79 update profiles' examples 📝 -- e9701648 add Rejseplanen profile to the list 📝 -- 4557e336 update the "writing a profile" guide 📝 - -96b4d55f might break your code. Eventually I would have been forced to upgrade the HAFAS protocol version anyways though, so I included this change in the `5.16` minor release. - -[🏷 `5.16.0`](https://github.com/public-transport/hafas-client/releases/tag/5.16.0), 2021-05-01 - -## `5.15.2` - -- 7025d3bc ÖBB: fix profile by using `https:` 🐛 -- ebe7c595 `lib/request`: fix `DEBUG` env var switch 🐛 -- 6f56f152 DB: enable usage of 1st class BahnCard 🐛 -- 68d8bf9f/9bfd4566/15be4a0b/b6ad9ba0/d9de0e00 fix readme/docs 📝 - -[🏷 `5.15.2`](https://github.com/public-transport/hafas-client/releases/tag/5.15.2), 2021-03-26 - -## `5.15.1` - -- 7025d3bc ÖBB: enable `remarks()` -- cb8d92be use `LOCAL_ADDRESS` environment variable to pick network interface address -- 92f1831c `departures()`/`arrivals()`: document `opt.products` 📝 -- 7025d3bc/c6fb9661 ÖBB: change `ver` to `1.33` 🐛 -- 78bbf9b6 VKG, VVT `departures()`: disable `getPasslist` & `stbFltrEquiv` 🐛 - -[🏷 `5.15.1`](https://github.com/public-transport/hafas-client/releases/tag/5.15.1), 2021-02-12 - -## `5.15.0` - -- 7106d24a add [*VOS* profile](../p/vos) -- 2ae6a9a4 add [*AVV* profile](../p/avv) -- f47343df add [*BART* profile](../p/bart) -- 2853fb04 add [*VVT* profile](../p/vvt) -- 0690724d add [*VKG* profile](../p/vkg) -- d69d2530 add `profile.remarksGetPolyline` flag -- 51af991e `lib/request`: add `profile.(auth|client|ext|ver)` to request -- 4ee062a1 `lib/request`: allow string `profile.salt` -- c260e34f DB: parse `gridL[].itemL[].remL[]` 🐛 -- 33f398bd `parseWarning`: use `fromLocations[0]` - -[🏷 `5.15.0`](https://github.com/public-transport/hafas-client/releases/tag/5.15.0), 2021-01-26 - -## `5.14.0` - -- ad6cfd22/3407ad6b/d017e627/02af67e2 add [*mobil.nrw* profile](../p/mobil-nrw) -- 174ed807 `remarks()`: support missing `res.msgL[]` 🐛 -- 4efff792 `parseJourney`: use `j.recon.ctx` as `refreshToken` too 🐛 -- 86bf3b46 docs: remove "migrating to 4" guide, fix profile examples, minor tweaks 📝 - -[🏷 `5.14.0`](https://github.com/public-transport/hafas-client/releases/tag/5.14.0), 2021-01-19 - -## `5.13.0` - -- 7444e08/bbf024d/6815c9e add [*SBB* (Switzerland) profile](../p/sbb) -- 17e08ac `parseJourneyLeg` → `parseAlternative`: handle missing `stopL[]` 🐛, add tests ✅ -- 850ec94 *mobiliteit.lu*: fix endpoint, upgrade to version `1.25` -- 54b7d28 *mobiliteit.lu*: fix `national-train` product bitmasks 🐛 - -[🏷 `5.13.0`](https://github.com/public-transport/hafas-client/releases/tag/5.13.0), 2020-12-27 - -## `5.12.0` - -- 3e6d6d9 add [`serverInfo()` method](server-info.md) -- ed48971/731d9b8 add [`remarks()` method](remarks.md) -- 9d8260b/53e10f7/1a0d97d add [`lines()` method](lines.md) -- e6bc8c6 `departures()`/`arrivals()`: add `line` option - -[🏷 `5.12.0`](https://github.com/public-transport/hafas-client/releases/tag/5.12.0), 2020-12-09 - -## `5.11.0` - -- 259fcd7 add [*VRN* (south-west Germany) profile](../p/vrn) - -[🏷 `5.11.0`](https://github.com/public-transport/hafas-client/releases/tag/5.11.0), 2020-11-26 - -## `5.10.1` - -- 6d4f29a `nearby()`: support `opt.products` -- 66ff661 `parseJourneyLeg` → `applyRemarks`: handle legs without `stopovers[]` 🐛 - -[🏷 `5.10.1`](https://github.com/public-transport/hafas-client/releases/tag/5.10.1), 2020-11-15 - -## `5.10.0` - -- 013ab2d add [*mobiliteit.lu* (Luxembourg) profile](../p/mobiliteit-lu) -- 11ca3b1 add [`tripsByName()` method](trips-by-name.md) -- 92fb29d `parseTrip`: handle `stopL[]` items without `idx` 🐛 - -[🏷 `5.10.0`](https://github.com/public-transport/hafas-client/releases/tag/5.10.0), 2020-11-01 - -## `5.9.0` - -- 8ed218f add [*Irish Rail* profile](../p/irish-rail) -- de86391 support HTTP proxies via `HTTPS_PROXY` & `HTTP_PROXY` environment variables - -[🏷 `5.9.0`](https://github.com/public-transport/hafas-client/releases/tag/5.9.0), 2020-09-24 - -## `5.8.0` - -- 4d06057/82de740/c17bd5a add [*Rejseplanen* profile](../p/rejseplanen) -- 9848dfa RMV: fix product bitmasks 🐛 (by [Adwirawien](https://github.com/Adwirawien)) -- 25fb25c `parseLeg`: use remarks without `fIdx`/`tIdx` 🐛 -- 68aaad1 *S-Bahn München*: switch to `1.21` protocol -- a621fd6 minor tweaks -- 2d139c8/c9f8cc6/b2a3ce4/e6f25a6/c17bd5a improve/update E2E & integration tests ✅ - -[🏷 `5.8.0`](https://github.com/public-transport/hafas-client/releases/tag/5.8.0), 2020-09-15 - -## `5.7.1` - -- 2612494 fix platform parsing with some profiles 🐛 (by [em0lar](https://em0lar.de)) - -[🏷 `5.7.1`](https://github.com/public-transport/hafas-client/releases/tag/5.7.1), 2020-09-09 - -## `5.7.0` - -- b2b1b75/3f4c05d/097557c add [*ZVV* profile](../p/zvv) -- 4fc4c3b fix `H9360` error message 🐛 - -[🏷 `5.7.0`](https://github.com/public-transport/hafas-client/releases/tag/5.7.0), 2020-08-01 - -## `5.6.3` - -- 71db75d `journeys()`: expose realtime data timestamp -- d2314e0 `journeys()`: don't send `outDate`/`outTime` & `ctxScr` -- f9bfd69 `parseJourneyLeg`: parse `jny.poly` 🐛 -- 51f4a66/2c04e2f `journeys()`: remove collection of results -- 6b27517 `parseMovement`: skip invalid `stopL[]` items 🐛 - -[🏷 `5.6.3`](https://github.com/public-transport/hafas-client/releases/tag/5.6.3), 2020-07-26 - -## `5.6.2` - -- de896b1 `parseCommon`: respect `opt.polyline` 🐛 -- fc2e214 ÖBB: add `trip()` test ✅ -- dce42bf move trip parsing into `parse/trip` - -[🏷 `5.6.2`](https://github.com/public-transport/hafas-client/releases/tag/5.6.2), 2020-06-13 - -## `5.6.1` - -- 542aa8c parse `DEVI` journey legs (#175) -- 3ca4a0c/57fc610 `arrivals()`: add `provenance` field (#180) -- ee94c65 ÖBB: improve `onCall` product name -- a8a9303 `nearby()`: return at most `opt.results` results - -[🏷 `5.6.1`](https://github.com/public-transport/hafas-client/releases/tag/5.6.1), 2020-06-10 - -## `5.6.0` - -- 07c77f8/76e3102/1abafb5/d92eb15/0251e31 parse stop/station entrances & sub-stops (#153) -- 9e75f42/0251e31/322004b DB: parse *Reisezentrum* opening hours & station facilities (#153) - -[🏷 `5.6.0`](https://github.com/public-transport/hafas-client/releases/tag/5.6.0), 2020-05-21 - -## `5.5.1` - -- 3c888a0 `refreshJourney()`: actually throw the error 🐛, add error code -- e02a20b readme: update links 📝 -- b302ba7 minor readme/documentation tweaks 📝 - -[🏷 `5.5.1`](https://github.com/public-transport/hafas-client/releases/tag/5.5.1), 2020-05-21 - -## `5.5.0` - -- fa3146d/9c4189a add [*SVV* profile](../p/svv) -- e032ec1 "invalid response" error: add `isHafasError: true` flag -- 0699d4d `departures()`/`arrivals()`: let `results` option default to `null` -- 1b01331 use `object-scan@13` ⚡️ - -[🏷 `5.5.0`](https://github.com/public-transport/hafas-client/releases/tag/5.5.0), 2020-04-09 - -## `5.4.0` - -- 01b3693/17031f3/7d3107e add [*SNCB*/*NMBS* profile](../p/sncb) -- ae74bb4 `departures()`/`arrivals()`: add `results` option - -[🏷 `5.4.0`](https://github.com/public-transport/hafas-client/releases/tag/5.4.0), 2020-03-29 - -## `5.3.1` - -- 916ac30 PKP: trim `-` from stop names -- a939090 INSA: `ver` `1.21` -> `1.18` 🐛 -- 2cb6a0c `parseIcon()`, `parseHint()`, `parseLocation()`: handle more edge cases 🐛 -- 0dceb41 `parseJourneyLeg()`: parse isRchbl correctly 🐛 -- 78487d9 `journeys()`: default `earlierRef` & `laterRef` to `null` 🐛 -- cda96b6 improve docs 📝 - -[🏷 `5.3.1`](https://github.com/public-transport/hafas-client/releases/tag/5.3.1), 2020-03-18 - -## `5.3.0` - -- 1c790e1/299b5ac add [*INVG* profile](../p/invg) -- d5116c2/c2b15fa add [*PKP* profile](../p/pkp) -- 682f9f9/8540f5f add [*VBN* profile](../p/vbn) -- 3a9e548/0ea2c01 add [*RMV* profile](../p/rmv) -- 84637b2/522248b add [*RSAG* profile](../p/rsag) -- 86ddf2c add [*VMT* profile](../p/vmt) - -[🏷 `5.3.0`](https://github.com/public-transport/hafas-client/releases/tag/5.3.0), 2020-03-12 - -## `5.2.0` - -- 1b03b2e INSA: protocol version `1.21`, enable [`reachableFrom()`](reachable-from.md) -- 2a24137/3ea9380 `parseLocation()`: parse foreign stop IDs -- 3ea9380 `parseLocation()`: parse fare zone, transit authority -- 8c7f164 `parseLine()`: expose admin code -- b9d5c85 add DB & INSA `stop()` tests - -[🏷 `5.2.0`](https://github.com/public-transport/hafas-client/releases/tag/5.2.0), 2020-03-08 - -## `5.1.2` - -- e5abe3d DB: fix journey leg loadFactor parsing 🐛 -- bc30309 fix undefined variables 🐛 -- db94a62/c072a70/df010fc/9874292 add linting - -[🏷 `5.1.2`](https://github.com/public-transport/hafas-client/releases/tag/5.1.2), 2020-03-02 - -## `5.1.1` - -- 8cb7d80 improve `findInTree` performance (#152) ⚡️ -- 940519b make readme more helpful 📝 -- 9522e92 `object-scan@11` - -[🏷 `5.1.1`](https://github.com/public-transport/hafas-client/releases/tag/5.1.1), 2020-02-22 - -## `5.1.0` - -- 542a9ee/1c67350/738354d add [*VSN* profile](../p/vsn) -- dfff999 `request()`: add resonse ID to error objects -- c1beb28 `Error` -> `TypeError` - -[🏷 `5.1.0`](https://github.com/public-transport/hafas-client/releases/tag/5.1.0), 2020-02-08 - -## `5.0.4` - -- db9287f [`@mapbox/polyline`](https://www.npmjs.com/package/@mapbox/polyline) -> [`google-polyline`](https://www.npmjs.com/package/google-polyline) -- 9b0e55c VBB: accept station IDs with an unknown length 🐛 -- ea4912a debug CLI: accept JS objects - -[🏷 `5.0.4`](https://github.com/public-transport/hafas-client/releases/tag/5.0.4), 2020-02-03 - -## `5.0.3` - -- 8c6a8d8 `findInTree`: improved performance ⚡️ -- c080f32 `vbb-translate-ids@4` 🐛 - -[🏷 `5.0.3`](https://github.com/public-transport/hafas-client/releases/tag/5.0.3), 2020-01-29 - -## `5.0.2` - -- e049aa3 `parseWarning()`: fix `parseMsgEvent()` 🐛 - -[🏷 `5.0.2`](https://github.com/public-transport/hafas-client/releases/tag/5.0.2), 2020-01-15 - -## `5.0.1` - -- 51b1e68 `throttle.js`, `retry.js`: use default profile 🐛 - -[🏷 `5.0.1`](https://github.com/public-transport/hafas-client/releases/tag/5.0.1), 2020-01-15 - -## `5.0.0` - -Note that this version is not backwords-compatible with `4.*`. Check out [the migration guide](migrating-to-5.md). - -### breaking changes 💥 - -- 2f8f82f require Node `>=10` -- 29a2cf3/2b9280e add `plannedArrival`/`plannedDeparture`/`plannedWhen`, `scheduled*` -> `planned*`/`prognosed*` -- 938a6f2/2d1d482 add `plannedArrivalPlatform`/`plannedDeparturePlatform`/`plannedPlatform`, `scheduled*` -> `planned*`/`prognosed*` -- 35e44d4 `parseWarning()`/`parseHint()`: change signature to `(profile, raw, data) => …` -- 4162328 `createClient()`: change signature to `(profile, userAgent, opt = {}) => …` -- fb7a565/252ce5b/9fc6664/2cfee22/e2567ef change parse fns signature to `({profile, opt, res, common}) => (rawData) => …` -- baff692 `journeys()`: don't request nr of results by default -- b8496be DB `journeys()`: let `journey.price` default to `null` -- 6d5c608 call `request()` via `profile` - -### features - -- f8210c5/9c47a39/0c145d3/9a89cd0 `journeys()`: add `walkingSpeed` option -- a40006f/1afe4ca BVG: support *BerlKönig*, add E2E test -- 352fa2e parse more warning fields -- 8b2a5a8 `parseIcon()`: use `.txt` & `.txtS` as text fallback -- 39a6267 request formatters (e.g. `formatTripReq()`) via `profile` - -### bugfixes 🐛 - -- 5ea22f7 `parseHint()`: parse `.code` & `.text` properly -- 29d7bd4 `parseJourney()`: fix `journey.scheduledDays` year -- 9a6bc2d `parseWarning()`: call `parseDateTime()` via `profile` -- 7b7293e `request()`: use *transformed* `req` - -[🏷 `5.0.0`](https://github.com/public-transport/hafas-client/releases/tag/5.0.0), 2020-01-05 - -## `4.8.0` - -- 56dee66/46eadcf/1611635 add [*DB Busradar NRW* profile](../p/db-busradar-nrw) - -[🏷 `4.8.0`](https://github.com/public-transport/hafas-client/releases/tag/4.8.0), 2019-12-29 - -## `4.7.0` - -- fceaf86 parse `Q` hints -- c883d96 documentation for `mgate.exe` endpoints - -[🏷 `4.7.0`](https://github.com/public-transport/hafas-client/releases/tag/4.7.0), 2019-12-26 - -## `4.6.2` - -- 105c18b DB: always use `rtMode: HYBRID` - -[🏷 `4.6.2`](https://github.com/public-transport/hafas-client/releases/tag/4.6.2), 2019-11-18 - -## `4.6.1` - -- 43b4a6e handle `H_UNKNOWN` error -- 1cc453b parseArrOrDep, parseLocation: bugfixes 🐛 - -[🏷 `4.6.1`](https://github.com/public-transport/hafas-client/releases/tag/4.6.1), 2019-10-28 - -## `3.10.3` - -- c9ceeca put deprecation note - -[🏷 `3.10.3`](https://github.com/public-transport/hafas-client/releases/tag/3.10.3), 2019-10-28 - -## `2.10.4` - -- 096f8a0 put deprecation note - -[🏷 `2.10.4`](https://github.com/public-transport/hafas-client/releases/tag/2.10.4), 2019-10-28 - -## `4.6.0` - -- 73ca349/19c3ee6 NVV profile - -[🏷 `4.6.0`](https://github.com/public-transport/hafas-client/releases/tag/4.6.0), 2019-08-16 - -## `4.5.2` - -- 2e88e96 install-unique client ID via `postinstall` step -> generate process-unique ID - -[🏷 `4.5.2`](https://github.com/public-transport/hafas-client/releases/tag/4.5.2), 2019-08-16 - -## `3.10.2` - -- 1babfbf `parseWarning`: handle missing summary/text 🐛 - -[🏷 `3.10.2`](https://github.com/public-transport/hafas-client/releases/tag/3.10.2), 2019-08-12 - -## `4.5.1` - -- bd7d5bb `parseWarning`: handle missing `summary`/`text` 🐛 -- 92c842b DB: enable `radar()` - -[🏷 `4.5.1`](https://github.com/public-transport/hafas-client/releases/tag/4.5.1), 2019-07-20 - -## `4.5.0` - -- b144dd5/b57c212 return nice error messages & error codes - -[🏷 `4.5.0`](https://github.com/public-transport/hafas-client/releases/tag/4.5.0), 2019-07-08 - -## `4.4.0` - -- e46d6cd `parseLocation`: expose `stop.isMeta` - -[🏷 `4.4.0`](https://github.com/public-transport/hafas-client/releases/tag/4.4.0), 2019-06-30 - -## `4.3.0` - -- 1e0182f `parseLint`: use `addName` -- d0f7ca1 follow HTTP redirects, accept `br` encoding - -[🏷 `4.3.0`](https://github.com/public-transport/hafas-client/releases/tag/4.3.0), 2019-06-25 - -## `4.2.2` - -- 64f797e `parseProductsBitmask`: fix bitmask handling 🐛 -- 707fd29 `p-retry@4`, `p-throttle@3` - -[🏷 `4.2.2`](https://github.com/public-transport/hafas-client/releases/tag/4.2.2), 2019-06-25 - -## `4.2.1` - -- 9078d2d fix `leg.reachable`, which was breaking all walking legs 🐛 - -[🏷 `4.2.1`](https://github.com/public-transport/hafas-client/releases/tag/4.2.1), 2019-06-08 - -## `4.2.0` - -- 6da1e80 add `leg.reachable` - -[🏷 `4.2.0`](https://github.com/public-transport/hafas-client/releases/tag/4.2.0), 2019-06-07 - -## `4.1.1` - -- 875ea18 parse scheduled/actual platform information on legs, fixes #116 🐛 -- f92e933 [DB](../p/db) departures/arrivals: parse load factor #112 - -[🏷 `4.1.1`](https://github.com/public-transport/hafas-client/releases/tag/4.1.1), 2019-05-29 - -## `4.1.0` - -- 831bcaf ISO date+time: suppress milliseconds if 0 -- 3e01303/75432fc CFG profile -- 820f2ab `parseWarning`: parse products -- 3ab099b/57c7186 HVV profile - -[🏷 `4.1.0`](https://github.com/public-transport/hafas-client/releases/tag/4.1.0), 2019-05-27 - -## `4.0.3` - -- 6aa57d4 `parseJourneyLeg`/`parseMovement`/`parseArrival`/`parseDeparture`: handle missing `dirTxt` 🐛 - -[🏷 `4.0.3`](https://github.com/public-transport/hafas-client/releases/tag/4.0.3), 2019-04-01 - -## `4.0.2` - -- 133cee9 `parseWarning`: expose `warning.id` 🐛 - -[🏷 `4.0.2`](https://github.com/public-transport/hafas-client/releases/tag/4.0.2), 2019-03-27 - -## `4.0.1` - -- 5d49fd0 `parseDateTime`: fix `tzOffset` & `daysOffset` 🐛 - -[🏷 `4.0.1`](https://github.com/public-transport/hafas-client/releases/tag/4.0.1), 2019-03-19 - -## `4.0.0` - -This version is not fully backwords-compatible. Check out [the migration guide](migrating-to-4.md). - -### breaking changes 💥 - -- 1e13cf1/b99ceb2 `parseLocation`: strip leading zeros from IDs -- a9fd9ff `parseDateTime`: return ISO string/timestamp -- ca1105f `parseDateTime`: parse timezone offset if given -- bf3c4c5 require Node `>=8.3.0` -- bbff1f4 `movement.nextStops` -> `movement.nextStopovers` -- bad0af8/8b87868/2e12206 rename `station(id)` -> `stop(id)` -- 96ff59d/0daa1c5/88c78c2 `leg.id` -> `leg.tripId` -- 3bc2eff `locations()`: default `opt.results` to `5` -- a1ffad3/cb535cd `parseLine`: remove `line.class` & `line.productCode` -- fcc53b5/b2b2d11/a1c40ad `journeys()`: return object with `journeys`, `earlierRef`, `laterRef` -- 61e7d14 `journeys()`: default `opt.transfers` to `-1` -- d7e439b debugging: `NODE_DEBUG` -> `DEBUG` -- 8f9b22e `locations()`, `nearby()`: `opt.stations` -> `opt.stops` -- a972dad `departures()`/`arrivals()`, `locations()`, `nearby()`, `stop()`: `opt.stationLines` -> `opt.linesOfStops` -- 0e1fcb0/0e1fcb0 `leg.mode: 'walking'` -> `leg.walking: true` -- 567cc98 DB, INSA, Nah.SH, ÖBB: `nationalExp` -> `nationalExpress` -- 9c44995 remove `arrival.trip`/`departure.trip` & `movement.trip` -- eb3ffba/eab850e mark POIs objects with `poi: true` -- 748f8ce `createThrottledClient` -> `withThrottling` -- fbde6a1 `createClientWithRetry` -> `withRetrying` -- 1646173 throw `Error`s -> `TypeError`s -- 7e39a2f/3b0740d `formerScheduled…` -> `scheduled…` - -### bugfixes 🐛 - -- fcc2a23 ÖBB `journeys()`: fix `opt.results` - -[🏷 `4.0.0`](https://github.com/public-transport/hafas-client/releases/tag/4.0.0), 2019-02-28 - -## `3.10.1` - -- dafc96a update CMTA credentials -- 46e7729 remove `console.error` call 🐛 - -[🏷 `3.10.1`](https://github.com/public-transport/hafas-client/releases/tag/3.10.1), 2019-02-28 - -## `3.10.0` - -- d797333/1e16a10 [DB](../p/db): parse additional line names - -[🏷 `3.10.0`](https://github.com/public-transport/hafas-client/releases/tag/3.10.0), 2019-02-13 - -## `3.9.1` - -- a145fea extend default retrying options 🐛 - -[🏷 `3.9.1`](https://github.com/public-transport/hafas-client/releases/tag/3.9.1), 2019-02-08 - -## `3.9.0` - -- b0f786c support for retrying failed requests ✨ – [docs](readme.md#retrying-failed-requests) - -[🏷 `3.9.0`](https://github.com/public-transport/hafas-client/releases/tag/3.9.0), 2019-02-08 - -## `3.8.1` - -- 3f58d84 handle `stop` objects as input 🐛 - -[🏷 `3.8.1`](https://github.com/public-transport/hafas-client/releases/tag/3.8.1), 2019-02-06 - -## `3.8.0` - -- 5d0096c `departures()`: profile flag for `getPasslist` & `stbFilterEquiv` -- #99 [Saarfahrplan profile](p/saarfahrplan) – Thanks @ialokim & @juliuste! - -[🏷 `3.8.0`](https://github.com/public-transport/hafas-client/releases/tag/3.8.0), 2018-12-31 - -## `3.7.0` - -- e867dac/f097022 `opt.stopovers`, `departure.nextStopovers`/`arrival.previousStopovers` - -[🏷 `3.7.0`](https://github.com/public-transport/hafas-client/releases/tag/3.7.0), 2018-12-28 - -## `3.6.3` - -- cb2d298 `stop`s/`station`s: default `id` of `null` 🐛 - -[🏷 `3.6.3`](https://github.com/public-transport/hafas-client/releases/tag/3.6.3), 2018-12-28 - -## `3.6.2` - -- 5beff47 `radar()`: fix `polylines` option 🐛 -- 48424cf `p-throttle` as normal dependency 🐛 - -[🏷 `3.6.2`](https://github.com/public-transport/hafas-client/releases/tag/3.6.2), 2018-12-16 - -## `3.6.1` - -- b809281 fix error parsing 🐛 -- bcbc366/ae2007c/e1f1d0d ÖBB `radar()`: fix filtering of `movement.nextStops` 🐛 - -[🏷 `3.6.1`](https://github.com/public-transport/hafas-client/releases/tag/3.6.1), 2018-12-10 - -## `3.6.0` - -- 4b56f66 parse `journey.cycle` if returned by HAFAS -- 17b8f14 `journeyLeg.cycle`: parse `nr` field if returned by HAFAS -- 8fac5fc `journeyLeg.alternatives`: parse `direction`, `delay`, `tripId` - -[🏷 `3.6.0`](https://github.com/public-transport/hafas-client/releases/tag/3.6.0), 2018-12-03 - -## `3.5.0` - -- 9d96902 `readableFrom()`: make `opt.maxDuration` optional -- 02e0e51 parse scheduled days of a `journey` - -[🏷 `3.5.0`](https://github.com/public-transport/hafas-client/releases/tag/3.5.0), 2018-11-13 - -## `3.4.3` - -- 9936466 `p-throttle@2`, `tape-promise@4` - -[🏷 `3.4.3`](https://github.com/public-transport/hafas-client/releases/tag/3.4.3), 2018-10-24 - -## `3.4.2` - -- 2a6b0dc speed up date+time formatting ⚡️ - -[🏷 `3.4.2`](https://github.com/public-transport/hafas-client/releases/tag/3.4.2), 2018-09-24 - -## `3.4.1` - -- 582c9de speed up date+time parsing ⚡️ - -[🏷 `3.4.1`](https://github.com/public-transport/hafas-client/releases/tag/3.4.1), 2018-09-22 - -## `3.4.0` - -- #81 [S-Bahn München profile](p/sbahn-muenchen) – Thanks @flori-uni! - -[🏷 `3.4.0`](https://github.com/public-transport/hafas-client/releases/tag/3.4.0), 2018-09-20 - -## `3.3.1` - -- 035877c `reachableFrom()` retry 🐛 - -[🏷 `3.3.1`](https://github.com/public-transport/hafas-client/releases/tag/3.3.1), 2018-09-03 - -## `3.3.0` - -- #80/b36ccda `reachableFrom()` method – [docs](reachable-from.md) - -[🏷 `3.3.0`](https://github.com/public-transport/hafas-client/releases/tag/3.3.0), 2018-09-03 - -## `3.2.1` - -- 044a5ee `arrivals()`: return a `direction` of `null` :bug: -- b37bedb parse `line.id` if possible - -[🏷 `3.2.1`](https://github.com/public-transport/hafas-client/releases/tag/3.2.1), 2018-09-03 - -## `3.2.0` - -- #79 [CapMetro/CMTA profile](p/cmta) – Thanks @nickturskyi! - -[🏷 `3.2.0`](https://github.com/public-transport/hafas-client/releases/tag/3.2.0), 2018-08-26 - -## `3.1.2` - -- f796337 handle warnings without schedule `sDate`/`eDate`/`lModDate` 🐛 - -[🏷 `3.1.2`](https://github.com/public-transport/hafas-client/releases/tag/3.1.2), 2018-08-24 - -## `3.1.1` - -- 39cc2f3 fix install on Windows 🐛 - -[🏷 `3.1.1`](https://github.com/public-transport/hafas-client/releases/tag/3.1.1), 2018-08-23 - -## `3.1.0` - -- 9257d3a parse `line.fahrtNr` - -[🏷 `3.1.0`](https://github.com/public-transport/hafas-client/releases/tag/3.1.0), 2018-08-22 - -## `3.0.0` - -This version is not fully backwords-compatible. Check out [the migration guide](migrating-to-3.md). - -### new features ✨ - -- 2d3796a BVG profile -- 0db84ce #61 parse remarks for stopovers and journey legs -- ac9819b `arrivals()` method – [docs](arrivals.md) -- 5b754aa `refreshJourney()` method – [docs](refresh-journey.md) -- 21c273c `journeys()`/`trip()`: leg stopovers: parse & expose delays -- 021ae45 `journeys()`/`trip()`: leg stopovers: parse & expose platforms -- 84bce0c `arrivals()`/`departures()`: parse & expose platforms -- 85e0bdf `journeys()`: `startWithWalking` option with default `true` -- f6ae29c journey legs with `type: 'walking'` now have a `distance` in meters -- 0d5a8fa departures, arrivals, stopovers: former scheduled platform(s) -- 0199749 `language` option with default `en` -- 1551943 `arrivals()`/`departures()`: `includeRelatedStations` option with default `true` - -### breaking changes 💥 - -- c4935bc new mandatory `User-Agent` parameter -- b7c1ee3 profiles: new products markup ([guide](https://github.com/public-transport/hafas-client/blob/ebe4fa64d871f711ced99d528c0171b180edc135/docs/writing-a-profile.md#3-products)) -- 40b559f change `radar(n, w, s, e)` signature to `radar({north, west, south, east})` -- 005f3f8 remove `journey.departure`, `journey.arrival`, … -- 0ef0301 validate `opt.when` -- 431574b parse polylines using `profile.parsePolyLine` – [docs for the output format](https://github.com/public-transport/hafas-client/blob/ebe4fa64d871f711ced99d528c0171b180edc135/docs/journey-leg.md#polyline-option) -- a356a26 throw if 0 products enabled -- c82ad23 `journeys()`: `opt.when` → `opt.departure`/`opt.arrival` -- 665bed9 rename `location(id)` to `station(id)` -- 6611f26 `journeys()`/`trip()`: `leg.passed` → `leg.stopovers` -- ebe4fa6 `journeys()`/`trip()`: `opt.passedStations` → `opt.stopovers` -- 3e672ee `journeys()`/`trip()`: `stopover.station` → `stopover.stop` -- 2e6aefe journey leg, departure, movement: `journeyId` -> `tripId` -- 8881d8a & b6fbaa5: change parsers signature to `parse…(profile, opt, data)` -- cabe5fa: option to parse & expose `station.lines`, default off -- c8ff217 rename `journeyLeg()` to `trip()` -- 8de4447 rename `profile.journeyLeg` to `profile.trip` - -### bugfixes - -- dd0a9b2 `parseStopover`: fix first/last canceled stopovers 🐛 - -[🏷 `3.0.0`](https://github.com/public-transport/hafas-client/releases/tag/3.0.0), 2018-08-17 - -## `2.10.3` - -- 50bd440 better `User-Agent` randomization - -[🏷 `2.10.3`](https://github.com/public-transport/hafas-client/releases/tag/2.10.3), 2018-08-08 - -## `2.10.2` - -- d54c26d randomize `User-Agent` - -[🏷 `2.10.2`](https://github.com/public-transport/hafas-client/releases/tag/2.10.2), 2018-07-25 - -## `2.10.1` - -- 04d550f parse `TRSF` legs as `walking` 🐛 - -[🏷 `2.10.1`](https://github.com/public-transport/hafas-client/releases/tag/2.10.1), 2018-07-02 - -## `2.10.0` - -- 4da8689 journey legs with `type: 'walking'` now have a `distance` in meters -- c1bdade `departures()`: parse & expose platforms -- fccd3d0 `journeys()`: `startWithWalking` option - -[🏷 `2.10.0`](https://github.com/public-transport/hafas-client/releases/tag/2.10.0), 2018-06-30 - -## `2.9.1` - -- a952b08 notes on how to use `hafas-client` with react-native 📝 -- 38a3749 `parseStopover`: fix first/last canceled stopovers 🐛 - -## `2.9.0` - -- 49186ae journey leg passed stations: add `arrivalDelay` & `departureDelay` -- deb8829 [`journeys()`](journeys.md): new `whenRepresents` option -- f3d8304 let the `insa` and `nahsh` profiles use HTTPS - -[🏷 `2.9.0`](https://github.com/public-transport/hafas-client/releases/tag/2.9.0), 2018-06-20 - -## `2.8.1` - -- 769f2e3 send `Accept: application/json` - -[🏷 `2.8.1`](https://github.com/public-transport/hafas-client/releases/tag/2.8.1), 2018-06-07 - -## `2.8.0` - -- 16c3f01 enable [`journeyLeg()`](journey-leg.md) for [DB](../p/db) - -[🏷 `2.8.0`](https://github.com/public-transport/hafas-client/releases/tag/2.8.0), 2018-05-24 - -## `2.7.5` - -- 908d531 [DB](../p/db) [`journeys()`](journeys.md): fix polylines parsing 🐛 - -[🏷 `2.7.5`](https://github.com/public-transport/hafas-client/releases/tag/2.7.5), 2018-05-24 - -## `2.7.4` - -- 709b7b4 update dependencies - -[🏷 `2.7.4`](https://github.com/public-transport/hafas-client/releases/tag/2.7.4), 2018-05-24 - -## `2.7.3` - -- 48f2cef each movement from `radar()` now has a `journeyId` field - -[🏷 `2.7.3`](https://github.com/public-transport/hafas-client/releases/tag/2.7.3), 2018-05-21 - -## `2.7.2` - -- a97e0d3 fix polylines parsing 🐛 - -[🏷 `2.7.2`](https://github.com/public-transport/hafas-client/releases/tag/2.7.2), 2018-05-16 - -## `2.7.1` - -- aa480e0 fix polylines parsing 🐛 - -[🏷 `2.7.1`](https://github.com/public-transport/hafas-client/releases/tag/2.7.1), 2018-05-16 - -## `2.7.0` - -- `journeys()`: `polylines` option -- `journeyLeg()`: `polyline` option -- `radar()`: `polylines` option - -[🏷 `2.7.0`](https://github.com/public-transport/hafas-client/releases/tag/2.7.0), 2018-05-15 - -## `2.6.0` - -- 5d10d76 journey legs: parse cycle - -[🏷 `2.6.0`](https://github.com/public-transport/hafas-client/releases/tag/2.6.0), 2018-04-29 - -## `2.5.3` - -- d676b84 fix parsing for journey leg alternatives 🐛 - -[🏷 `2.5.3`](https://github.com/public-transport/hafas-client/releases/tag/2.5.3), 2018-04-29 - -## `2.5.2` - -- 16e6dd6 departure docs: fix method 📝 -- c60213a DB: tram mode should be `train` 🐛 - -[🏷 `2.5.2`](https://github.com/public-transport/hafas-client/releases/tag/2.5.2), 2018-04-24 - -## `2.5.1` - -- afc0124 fix stopover parsing 🐛 - -[🏷 `2.5.1`](https://github.com/public-transport/hafas-client/releases/tag/2.5.1), 2018-04-05 - -## `2.5.0` - -- new [Schleswig-Holstein (NAH.SH)](https://de.wikipedia.org/wiki/Nahverkehrsverbund_Schleswig-Holstein) [profile](../p/nahsh) -- new [*writing a profile* guide](./writing-a-profile.md) - -[🏷 `2.5.0`](https://github.com/public-transport/hafas-client/releases/tag/2.5.0), 2018-03-18 - -## `2.4.2` - -- `parseStopover`: expose canceled arrivals & departures 🐛 - -[🏷 `2.4.2`](https://github.com/public-transport/hafas-client/releases/tag/2.4.2), 2018-03-17 - -## `2.4.1` - -- new [*writing a profile* guide](./writing-a-profile.md) -- `parseMovement`: use `parseStopover` 🐛 -- `parseStopover`: use `parseStationName` 🐛 - -[🏷 `2.4.1`](https://github.com/public-transport/hafas-client/releases/tag/2.4.1), 2018-03-17 - -## `2.4.0` - -- new [Nahverkehr Sachsen-Anhalt (NASA)](https://de.wikipedia.org/wiki/Nahverkehrsservice_Sachsen-Anhalt)/[INSA](https://insa.de) profile -- new `earlierRef`/`laterRef` feature to query earlier/later journeys (pagination) -- former scheduled date & time for canceled departures & journeys - -[🏷 `2.4.0`](https://github.com/public-transport/hafas-client/releases/tag/2.4.0), 2018-03-14 diff --git a/docs/departures.md b/docs/departures.md index 4b7e3763..4e7a7f85 100644 --- a/docs/departures.md +++ b/docs/departures.md @@ -24,58 +24,47 @@ With `opt`, you can override the default options, which look like this: ```js { when: new Date(), - direction: null, // only show departures heading to this station - line: null, // filter by line ID + direction: null, // not supported + line: null, // not supported duration: 10, // show departures for the next n minutes results: null, // max. number of results; `null` means "whatever HAFAS wants" - subStops: true, // parse & expose sub-stops of stations? - entrances: true, // parse & expose entrances of stops/stations? - linesOfStops: false, // parse & expose lines at the stop/station? + subStops: true, // not supported + entrances: true, // not supported + linesOfStops: false, // not supported remarks: true, // parse & expose hints & warnings? stopovers: false, // fetch & parse previous/next stopovers? // departures at related stations // e.g. those that belong together on the metro map. - includeRelatedStations: true, + includeRelatedStations: true, // only true supported language: 'en' // language to get results in } ``` - -If you pass an object `opt.products`, its fields will partially override the default products defined in the profile. An example with the [BVG profile](../p/bvg): - -```js -import {createClient} from 'hafas-client' -import {profile as vbbProfile} from 'hafas-client/p/vbb/index.js' - -const userAgent = 'link-to-your-project-or-email' // adapt this to your project! -const client = createClient(vbbProfile, userAgent) - -// will query with these products: suburban, subway, bus, express, regional -await client.departures('900000024101', {products: {tram: false, ferry: false}}) -``` +The maximum supported duration is 720 for `db` and 60 for `dbnav` profile. +If you pass an object `opt.products`, its fields will partially override the default products defined in the profile. ## Response *Note:* As stated in the [*Friendly Public Transport Format* v2 draft spec](https://github.com/public-transport/friendly-public-transport-format/blob/3bd36faa721e85d9f5ca58fb0f38cdbedb87bbca/spec/readme.md), the `when` field includes the current delay. The `delay` field, if present, expresses how much the former differs from the schedule. -You may pass a departure's `tripId` into [`trip(id, lineName, [opt])`](trip.md) to get details on the whole trip. +You may pass a departure's `tripId` into [`trip(id, lineName, [opt])`](trip.md) to get details on the whole trip. For the `dbnav` profile HAFAS trip ids will be returned, for the `db` profile, RIS trip ids will be returned, then the `trip()` endpoint support both id types. -As an example, we're going to use the [VBB profile](../p/vbb): +For `db` profile, cancelled trips will not be contained in the response! ```js -import {createClient} from 'hafas-client' -import {profile as vbbProfile} from 'hafas-client/p/vbb/index.js' +import {createClient} from 'db-vendo-client' +import {profile as dbnavProfile} from 'db-vendo-client/p/dbnav/index.js' const userAgent = 'link-to-your-project-or-email' // adapt this to your project! -const client = createClient(vbbProfile, userAgent) +const client = createClient(dbnavProfile, userAgent) // S Charlottenburg const { departures, realtimeDataUpdatedAt, -} = await client.departures('900000024101', {duration: 3}) +} = await client.departures('8089165', {duration: 3}) ``` -`realtimeDataUpdatedAt` is a UNIX timestamp reflecting the latest moment when (at least some) of the response's realtime data have been updated. +`realtimeDataUpdatedAt` is currently not set in db-vendo-client, because the upstream APIs don't provide it. `departures` may look like this: @@ -87,11 +76,11 @@ const { // Depending on the HAFAS endpoint, the destination may be present: destination: { type: 'stop', - id: '900000029101', + id: '8089165', name: 'S Spandau', location: { type: 'location', - id: '900029101', + id: '8089165', latitude: 52.534794, longitude: 13.197477 }, diff --git a/docs/hafas-mgate-api.md b/docs/hafas-mgate-api.md deleted file mode 100644 index 0fd82526..00000000 --- a/docs/hafas-mgate-api.md +++ /dev/null @@ -1,160 +0,0 @@ -# HAFAS `mgate.exe` protocol - -The protocol of `mgate.exe` HAFAS endpoints is not openly (and freely) documented. The following documentation is based on general observations and reverse-engineering. - -*Note:* There are also `rest.exe` (a.k.a. "open API", a.k.a. "REST API") endpoints. This documentation is *not* about them. - -## date & time format - -Dates are encoded as `YYYYMMDD`, time strings as `HHMMSS`. These are in the timezone configured on the HAFAS/server side, *per endpoint*. - -Whenever HAFAS returns a time string that exceeds the day the response describes, it will add a "day offset". As an example, when you query departures at `2019-12-12T23:50+01:00` for the next 30 minutes, it will encode the departure at `2019-12-13T00:13+01:00` as `20191212` & `01001300`. - -For working code, check out [`parseDateTime()`](../parse/date-time.js). - -## coordinate format - -All endpoints I've seen so far use [WGS84](http://wiki.gis.com/wiki/index.php/WGS84). Values are multiplied by `10^6` though, so you would encode `{latitude: 1.23, longitude: -2.34}` as `{Y: 1230000: X: -2340000}`. There's an optional parameter `z` with the elevation. - -For working code, check out [`formatAddress()`](../format/address.js). - -## querying the API - -In many aspects, the API looks and feels like [RPCs](https://en.wikipedia.org/wiki/Remote_procedure_call). You must send queries via HTTP `POST`, with the minimal JSON body looking like this: - -```js -{ - "auth": { - "type": "AID", - "aid": "…" // endpoint-specific authentication token, e.g. `1Rxs112shyHLatUX4fofnmdxK` - }, - "ver": "…", // endpoint-specific string, e.g. `1.15` - "ext": "…", // endpoint-specific string, e.g. `BVG.1` - "client": { - "type": "IPA", // might also be `IPH` for "iPhone" or `WEB` for "web client" - "id": "…", // endpoint-specific string, e.g. `BVG` - "name": "…", // endpoint-specific string, e.g. `FahrInfo` - "v": "…" // endpoint-specific string, e.g. `4070700` - }, - "lang": "…", // language, sometimes 2-digit (e.g. `de`), sometimes 3-digit (e.g. `deu`) - "svcReqL": [ - { - "meth": "…", // name of the API call, supported values depend on the endpoint - "req": { - // actual request parameters… - } - // some endpoints also require this: - "cfg": { - "cfgGrpL": [], - "cfgHash": "…" // endpoint-specific string - } - } - ] -} -``` - -- The data in `client` must be correct, otherwise HAFAS will reject your request. -- HAFAS will return slightly different response formats (and slightly different levels of detail) for different `ver`, `ext` and `client.v` values. -- All endpoints known support JSON & UTF-8, so make sure to send `Accept: application/json` & `Accept-Charset: utf-8` headers. -- Most endpoints support at least GZIP compression, so make sure to send a `Accept-Encoding: gzip` header. - -For working code, check out [`request()`](lib/request.js). - -## Authentication - -There are three known types of authentication used among `mgate.exe` endpoints. - -For working code, check out [`hafas-client`'s `request()`](lib/request.js), [`public-transport-enabler`'s Java implementation](https://github.com/schildbach/public-transport-enabler/blob/69614c87af627e2feafc576882f2ccccdbf4b7e6/src/de/schildbach/pte/AbstractHafasClientInterfaceProvider.java#L845-L860), [`TripKit`'s Swift implementation](https://github.com/alexander-albers/tripkit/blob/724b6cd8c258c9c61e7443c81e914618b79393cb/TripKit/AbstractHafasClientInterfaceProvider.swift#L1473-L1495) or [`marudor.de`'s TypeScript implementation](https://github.com/marudor/BahnhofsAbfahrten/blob/cf64d53c6902981ec529d3952253b2c83bff9221/src/server/HAFAS/profiles.ts#L30-L54). - -### unprotected endpoints - -You can just query these, as long as you send a formally correct request. - -### endpoints using the `checksum` query parameter - -`checksum` is a [message authentication code](https://en.wikipedia.org/wiki/Message_authentication_code): You can compute it by [hashing](https://en.wikipedia.org/wiki/Hash_function) the request body and a secret *salt*. - -This secret can be read from the config file inside the accompanying client app. There is no guide for this yet, so please [open an issue](https://github.com/public-transport/hafas-client/issues/new). - -### endpoints using the `mic` & `mac` query parameters - -`mic` is a [message integrity code](https://en.wikipedia.org/wiki/Message_authentication_code), the [hash](https://en.wikipedia.org/wiki/Hash_function) of the request body. - -`mac` is a [message authentication code](https://en.wikipedia.org/wiki/Message_authentication_code), the hash of `mic` and a secret *salt*. - -This secret can be read from the config file inside the accompanying client app. There is no guide for this yet, so please [open an issue](https://github.com/public-transport/hafas-client/issues/new). - -## API responses - -A minimal valid response looks like this: - -```js -{ - "ver": "…", // endpoint-specific string, e.g. `1.15` - "lang": "…", // language - "ext": "…", // endpoint-specific string, e.g. `BVG.1` - "id": "…", // unique ID for each response? - "svcResL": [ - { - "meth": "StationBoard", - "err": "OK", - "res": { - // result of the API call - } - } - ] -} -``` - -For working code, check out [`request()`](lib/request.js). - -### parse error - -todo: generic server error - -```js -{ - "ver": "…", // endpoint-specific string, e.g. `1.15` - "lang": "…", // language, sometimes 2-digit (e.g. `de`), sometimes 3-digit (e.g. `deu`) - "err": "PARSE", // error code - "errTxt": "…", // error message, not always present - "svcResL": [] -} -``` - -### authentication error - -```js -{ - "ver": "…", // endpoint-specific string, e.g. `1.15` - "lang": "…", // language - "ext": "…", // endpoint-specific string, e.g. `BVG.1` - "err": "AUTH", // error code - "errTxt": "…", // error message, not always present - "svcResL": [] -} -``` - -### API-call-specific error - -```js -{ - "ver": "…", // endpoint-specific string, e.g. `1.15` - "lang": "…", // language - "ext": "…", // endpoint-specific string, e.g. `BVG.1` - "svcResL": [ - { - "meth": "StationBoard", - "err": "…", // error code, e.g. `H9300` - "errTxt": "…", // error message, e.g. `Unknown arrival station` - "res": {} - } - ] -} -``` - -## more ressources - -- [@Nakaner's `strecken.info` API docs](https://github.com/Nakaner/bahnstoerungen/tree/62a72b1e0f0255668500b438187ff65aef39242a/api-doc/db-strecken-info) -- [unfinished HAFAS glossary](https://gist.github.com/derhuerst/74b703e2a0fc64e4a0fa8fbb1f3a61b4) -- [various `mgate.exe` HTTP traffic recordings](https://gist.github.com/search?q=post+mgate.exe&ref=searchresults) diff --git a/docs/journeys-from-trip.md b/docs/journeys-from-trip.md deleted file mode 100644 index f9b9febf..00000000 --- a/docs/journeys-from-trip.md +++ /dev/null @@ -1,51 +0,0 @@ -# `journeysFromTrip(tripId, previousStopover, to, [opt])` - -`to` must be an [*Friendly Public Transport Format* (FPTF) `stop`](https://github.com/public-transport/friendly-public-transport-format/blob/3bd36faa721e85d9f5ca58fb0f38cdbedb87bbca/spec/readme.md#stop) or [`station`](https://github.com/public-transport/friendly-public-transport-format/blob/3bd36faa721e85d9f5ca58fb0f38cdbedb87bbca/spec/readme.md#station). See [`journeys()`](journeys.md) for details. - -With `opt`, you can override the default options, which look like this: - -```js -{ - accessibility: 'none', // 'none', 'partial' or 'complete' - stopovers: false, // return stations on the way? - polylines: false, // return leg shapes? - transferTime: 0, // minimum time for a single transfer in minutes - tickets: false, // return tickets? - remarks: true // parse & expose hints & warnings? -} -``` - -## Response - -*Note:* The returned `departure` and `arrival` times include the current delay. The `departureDelay`/`arrivalDelay` fields express how much they differ from `plannedDeparture`/`plannedArrival`, respectively. - -As an example, we're going to use the [*Deutsche Bahn* profile](../p/db): - -```js -import {createClient} from 'hafas-client' -import {profile as dbProfile} from 'hafas-client/p/db/index.js' - -const userAgent = 'link-to-your-project-or-email' // adapt this to your project! -const client = createClient(dbProfile, userAgent) - -const berlinSüdkreuz = '8011113' -const münchenHbf = '8000261' -const kölnHbf = '8000207' - -// find any journey from Berlin Südkreuz to München Hbf -const [journey] = await client.journeys(berlinSüdkreuz, münchenHbf, {results: 1, stopovers: true}) -// find the ICE leg -const leg = journey.legs.find(l => l.line.product === 'nationalExpress') -// find the stopover at the stop you've just passed -const previousStopover = leg.stopovers.find(st => st.departure && new Date(st.departure) < Date.now()) - -// find journeys from the ICE train to Köln Hbf -const { - journeys, - realtimeDataUpdatedAt, -} = await client.journeysFromTrip(leg.id, previousStopover, kölnHbf) -``` - -`journeys` is an array of [FPTF `journey`s](https://github.com/public-transport/friendly-public-transport-format/blob/3bd36faa721e85d9f5ca58fb0f38cdbedb87bbca/spec/readme.md#journey), as documented in [`journeys()`](journeys.md). - -`realtimeDataUpdatedAt` is a UNIX timestamp reflecting the latest moment when (at least some of) the response's realtime data have been updated. diff --git a/docs/journeys.md b/docs/journeys.md index 115d2b72..e02a2820 100644 --- a/docs/journeys.md +++ b/docs/journeys.md @@ -53,11 +53,11 @@ With `opt`, you can override the default options, which look like this: stopovers: false, // return stations on the way? transfers: -1, // Maximum nr of transfers. Default: Let HAFAS decide. transferTime: 0, // minimum time for a single transfer in minutes - accessibility: 'none', // 'none', 'partial' or 'complete' + accessibility: 'none', // not supported bike: false, // only bike-friendly journeys - walkingSpeed: 'normal', // 'slow', 'normal', 'fast' + walkingSpeed: 'normal', // not supported // Consider walking to nearby stations at the beginning of a journey? - startWithWalking: true, + startWithWalking: true, // always true (?) products: { // these entries may vary from profile to profile suburban: true, @@ -65,15 +65,19 @@ With `opt`, you can override the default options, which look like this: tram: true, bus: true, ferry: true, - express: true, + nationalExpress: true, + national: true, regional: true + regionalExpress: true // this is actually FlixTrain and co. }, - tickets: false, // return tickets? only available with some profiles - polylines: false, // return a shape for each leg? - subStops: true, // parse & expose sub-stops of stations? - entrances: true, // parse & expose entrances of stops/stations? + tickets: false, // return tickets? only available for [refreshJourney](refresh-journey.md) + polylines: false, // return a shape for each leg? only available for [refreshJourney](refresh-journey.md) + subStops: true, // not supported + entrances: true, // not supported remarks: true, // parse & expose hints & warnings? - scheduledDays: false, // parse which days each journey is valid on + scheduledDays: false, // not yet supported + firstClass: true // first or second class for tickets + loyaltyCard: '' // BahnCards etc., see below language: 'en', // language to get results in } ``` @@ -82,17 +86,16 @@ With `opt`, you can override the default options, which look like this: *Note:* As stated in the [*Friendly Public Transport Format* v2 draft spec](https://github.com/public-transport/friendly-public-transport-format/blob/3bd36faa721e85d9f5ca58fb0f38cdbedb87bbca/spec/readme.md), the returned `departure` and `arrival` times include the current delay. The `departureDelay`/`arrivalDelay` fields express how much they differ from the schedule. -As an example, we're going to use the [VBB profile](../p/vbb): ```js -import {createClient} 'hafas-client' -import {profile as vbbProfile} from 'hafas-client/p/vbb/index.js' +import {createClient} 'db-vendo-client' +import {profile as vbbProfile} from 'db-vendo-client/p/vbb/index.js' const userAgent = 'link-to-your-project-or-email' // adapt this to your project! const client = createClient(vbbProfile, userAgent) -// Hauptbahnhof to Heinrich-Heine-Str. -await client.journeys('900000003201', '900000100008', { +// Frankfurt to Stuttgart +await client.journeys('8000105', '8000096', { results: 1, stopovers: true }) @@ -101,7 +104,7 @@ await client.journeys('900000003201', '900000100008', { `journeys()` will resolve with an object with the following fields: - `journeys` - `earlierRef`/`laterRef` – pass them as `opt.earlierThan`/`opt.laterThan` into another `journeys()` call to retrieve the next "page" of journeys -- `realtimeDataUpdatedAt` – a UNIX timestamp reflecting the latest moment when (at least some of) the response's realtime data have been updated +- `realtimeDataUpdatedAt` – is currently not set in db-vendo-client, because the upstream APIs don't provide it. This object might look like this: @@ -276,44 +279,6 @@ This object might look like this: realtimeDataUpdatedAt: 1531259400, // 2018-07-10T23:50:00+02 } ``` - -Some [profiles](../p) are able to parse the ticket information, if returned by the API. For example, if you pass `tickets: true` with the [VBB profile](../p/vbb), each `journey` will have a tickets array that looks like this: - -```js -[ { - name: 'Berlin Tarifgebiet A-B: Einzelfahrausweis – Regeltarif', - price: 2.8, - tariff: 'Berlin', - coverage: 'AB', - variant: 'adult', - amount: 1 -}, { - name: 'Berlin Tarifgebiet A-B: Einzelfahrausweis – Ermäßigungstarif', - price: 1.7, - tariff: 'Berlin', - coverage: 'AB', - variant: 'reduced', - amount: 1, - reduced: true -}, /* … */ { - name: 'Berlin Tarifgebiet A-B: Tageskarte – Ermäßigungstarif', - price: 4.7, - tariff: 'Berlin', - coverage: 'AB', - variant: '1 day, reduced', - amount: 1, - reduced: true, - fullDay: true -}, /* … */ { - name: 'Berlin Tarifgebiet A-B: 4-Fahrten-Karte – Regeltarif', - price: 9, - tariff: 'Berlin', - coverage: 'AB', - variant: '4x adult', - amount: 4 -} ] -``` - If a journey leg has been cancelled, a `cancelled: true` will be added. Also, `departure`/`departureDelay`/`departurePlatform` and `arrival`/`arrivalDelay`/`arrivalPlatform` will be `null`. To get more journeys earlier/later than the current set of results, pass `earlierRef`/`laterRef` into `opt.earlierThan`/`opt.laterThan`. For example, query *later* journeys as follows: @@ -339,19 +304,16 @@ departure of last journey 2017-12-17T19:07:00+01:00 departure of first (later) journey 2017-12-17T19:19:00+01:00 ``` -If you pass `polylines: true`, each journey leg will have a `polyline` field. Refer to [the section in the `trip()` docs](trip.md#polyline-option) for details. - -If you pass `scheduledDays: true`, each journey will have a `scheduledDays` object looking like this: +## Using the `loyaltyCard` option ```js -{ - '2018-01-01': true, - '2018-01-02': false, - // … - '2018-10-12': true, - '2018-10-13': true, - // … - '2019-01-02': false, - '2019-01-03': false -} +import {data as loyaltyCards} from 'db-vendo-client/format/loyalty-cards.js' // see there for a list + +hafas.journeys(from, to, { + loyaltyCard: {type: data.BAHNCARD, discount: 25} +}) ``` + +## The `routingMode` option + +The `routingMode` option is not supported by db-vendo-client. The behavior will be the same as the `HYBRID` mode of hafas-client, i.e. cancelled trains/infeasible journeys will also be contained for informational purpose. \ No newline at end of file diff --git a/docs/lines.md b/docs/lines.md deleted file mode 100644 index 34d86da1..00000000 --- a/docs/lines.md +++ /dev/null @@ -1,70 +0,0 @@ -# `lines([opt])` - -**Fetches all lines known to the HAFAS endpoint**, e.g. warnings about disruptions, planned construction work, and general notices about the operating situation. - -## Example - -As an example, we're going to use the [SVV profile](../p/svv): - -```js -import {createClient} from 'hafas-client' -import {profile as svvProfile} from 'hafas-client/p/svv/index.js' - -const userAgent = 'link-to-your-project-or-email' // adapt this to your project! -const client = createClient(svvProfile, userAgent) - -const { - lines, - realtimeDataUpdatedAt, -} = await client.lines('S1') -``` - -`realtimeDataUpdatedAt` is a UNIX timestamp reflecting the latest moment when (at least some of) the response's realtime data have been updated. - -`lines` may look like this: - -```js -[ - { - "id": "obb-1-S1-V-j20-1", - "type": "line", - "name": "S1", - "public": true, - "mode": "train", - "product": "bahn-s-bahn", - "operator": { - "type": "operator", - "id": "montafonerbahn-ag", - "name": "Montafonerbahn AG" - }, - "directions": [ - "Bludenz Bahnhof", - "Bregenz Hafen Bahnhof", - "Lindau Hbf", - "Bregenz Bahnhof", - "Schruns Bahnhof", - "Lochau Bahnhof" - ], - }, - // … - { - "id": "svv-42-50-j20-2", - "type": "line", - "name": "S1", - "public": true, - "mode": "train", - "product": "bahn-s-bahn", - "operator": { - "type": "operator", - "id": "salzburg-ag-salzburger-lokalbahn", - "name": "Salzburg AG - Salzburger Lokalbahn" - }, - "directions": [ - "Lamprechtshausen Bahnhof", - "Salzburg Hauptbahnhof", - "Acharting S-Bahn", - "Weitwörth-Nussdorf Bahnhof" - ], - }, -] -``` diff --git a/docs/locations.md b/docs/locations.md index 8ddda6b2..75f17fe4 100644 --- a/docs/locations.md +++ b/docs/locations.md @@ -6,14 +6,14 @@ With `opt`, you can override the default options, which look like this: ```js { - fuzzy: true // find only exact matches? + fuzzy: true // not supported , results: 5 // how many search results? , stops: true // return stops/stations? , addresses: true , poi: true // points of interest - , subStops: true // parse & expose sub-stops of stations? - , entrances: true // parse & expose entrances of stops/stations? - , linesOfStops: false // parse & expose lines at each stop/station? + , subStops: true // not supported + , entrances: true // not supported + , linesOfStops: false // not supported , language: 'en' // language to get results in } ``` @@ -23,8 +23,8 @@ With `opt`, you can override the default options, which look like this: As an example, we're going to use the [VBB profile](../p/vbb): ```js -import {createClient} from 'hafas-client' -import {profile as vbbProfile} from 'hafas-client/p/vbb/index.js' +import {createClient} from 'db-vendo-client' +import {profile as vbbProfile} from 'db-vendo-client/p/vbb/index.js' const userAgent = 'link-to-your-project-or-email' // adapt this to your project! const client = createClient(vbbProfile, userAgent) diff --git a/docs/migrating-to-5.md b/docs/migrating-to-5.md deleted file mode 100644 index 5d01db14..00000000 --- a/docs/migrating-to-5.md +++ /dev/null @@ -1,108 +0,0 @@ -# Migrating to `hafas-client@5` - -## If you use Node `8` ("Carbon")… - -…migrate to Node `10` ("Dubnium"), sorry. [Node `8` is out of maintenance now](https://nodejs.org/en/about/releases/). 83f43c6 - -## new fields for departure/arrival time & delays - -An arrival/departure now looks like this: - -```js -{ - when: null, // realtime/prognosed - plannedWhen: '2019-10-10T10:10+10:00', - platform: '3', // realtime/prognosed - plannedPlatform: '4' -} -``` - -A stopover/journey leg now will look like this: - -```js -{ - arrival: null, // realtime/prognosed - plannedArrival: '2019-10-10T10:10+10:00', - arrivalDelay: null, - arrivalPlatform: '3', // realtime/prognosed - plannedArrivalPlatform: '4', - - departure: '2019-10-10T10:12+10:00', // realtime/prognosed - plannedDeparture: '2019-10-10T10:10+10:00', - departureDelay: 120, // seconds - departurePlatform: null, // realtime/prognosed - plannedDeparturePlatform: null -} -``` - -If the same stopover/journey leg is `cancelled: true`, it will look like this: - -```js -{ - arrival: null, - prognosedArrival: null, - plannedArrival: '2019-10-10T10:10+10:00', - arrivalDelay: null, - arrivalPlatform: null, - prognosedArrivalPlatform: '3', - plannedArrivalPlatform: '4', - - departure: null, - prognosedDeparture: '2019-10-10T10:12+10:00', - plannedDeparture: '2019-10-10T10:10+10:00', - departureDelay: 120, // seconds - departurePlatform: null, - prognosedDeparturePlatform: null, - plannedDeparturePlatform: null -} -``` - -## If you use `journeys()`… - -…with the `walkingSpeed` option and a custom profile, add `journeysWalkingSpeed` to your profile. 937583e -…without the `results` option, but *expect* a certain number of results, you must pass `results` now. 0045587 - -## If you use `departures()`/`arrivals()` with the [BVG profile](../p/bvg)… - -With the latest protocol version, the BVG endpoint doesn't support these options anymore: - -- `stopovers` – Fetch & parse previous/next stopovers? Default: `false` -- `includeRelatedStations` – Fepartures at related stations, e.g. those that belong together on the metro map? Default: `true` - -2d72391 - -## If you use a custom profile… - -Let's assume you have parse function looking like this: - -```js -const createParseLine = (profile, opt, data) => (rawLine) => { - const operator = data.operators[rawLine.oprX] || null - if (operator && operator.name === 'foo') { - return { - type: 'line', - name: 'really special tram line', - mode: 'tram', - product: 'special-tram', - operator - } - } - return defaultParseLine(rawLine) -} -``` - -Adapt your parse function like this: - -```diff -const createParseLine = (profile, opt, _) => (rawLine) => { -- const operator = data.operators[rawLine.oprX] || null -+ const operator = rawLine.operator || null -``` - -See also [`#127`](https://github.com/public-transport/hafas-client/pull/127). - -If you use `icons` in `parseWarning`/`parseHint`, adapt the function(s) to take an object `data` as the first argument. You can access the list of *parsed* icons via `data.icons`, *parsed* warnings via `data.warnings`, etc. a229205 b36f0e3 - -## Other breaking changes - -- `journey.price` will be `null` if there's no pricing data returned by the endpoint, instead of `{amount: null}`. 8fe277d diff --git a/docs/migrating-to-6.md b/docs/migrating-to-6.md deleted file mode 100644 index d80f7c22..00000000 --- a/docs/migrating-to-6.md +++ /dev/null @@ -1,93 +0,0 @@ -# Migrating to `hafas-client@6` - -## If you use Node.js <16 … - -… migrate to Node `16` ("Gallium"), sorry. [Node `10`, `12` & `14` are out of (active) LTS now](https://nodejs.org/en/about/releases/). - -## If you use `hafas-client` via [CommonJS](https://en.wikipedia.org/wiki/CommonJS) … - -… you'll have to either -- migrate your code to ECMAScript Modules (ESM), or -- use [dynamic `import()`](https://nodejs.org/docs/latest-v16.x/api/esm.html#import-expressions), or -- use a (somewhat hacky) tool like [`esm`](https://www.npmjs.com/package/esm). - -For more background information, check out [MDN's ESM explainer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) and [Node.js's ESM docs](https://nodejs.org/docs/latest-v16.x/api/esm.html). - -## If you use `departures()` or `arrivals()` … - -… adapt your code as follows: -- `departures()` now returns an object `{departures: […], realtimeDataUpdatedAt: …}` -- `arrivals()` now returns an object `{arrivals: […], realtimeDataUpdatedAt: …}` - -### … with `opt.stopovers: true` … - -… check if this still works. If `hafas-client` throws "`opt.stopovers` is not supported by this endpoint", you'll have to use `trip()` for each departure/arrival to get its trip's stopovers. - -Most profiles had to be upgraded to a newer HAFAS protocol version to still work, and newer HAFAS protocol versions don't support this flag anymore. - -## If you use `journeys()`, `refreshJourney()` or `journeysFromTrip()` … - -… use `res.realtimeDataUpdatedAt` instead of `res.realtimeDataFrom`, it has been renamed. - -## If you use `refreshJourney()` … - -… adapt your code as follows: it now returns an object `{journey: …, realtimeDataUpdatedAt: …}`. - -## If you use `trip()` … - -… adapt your code as follows: it now returns an object `{trip: …, realtimeDataUpdatedAt: …}`. - -… don't pass the `lineName` parameter anymore, it is not needed anymore and has been removed. - -## If you use `tripsByName()` … - -… adapt your code as follows: it now returns an object `{trips: […], realtimeDataUpdatedAt: …}`. - -## If you use `radar()` … - -… adapt your code as follows: it now returns an object `{movements: […], realtimeDataUpdatedAt: …}`. - -## If you use `reachableFrom()` … - -… and it sometimes fails with a server error (a.k.a. HAFAS is unable to process the request), wrap it in a retry logic ([open an Issue](https://github.com/public-transport/hafas-client/issues/new) to get help). Automatic retries have been removed. - -## If you use `remarks()` … - -… adapt your code as follows: it now returns an object `{remarks: […], realtimeDataUpdatedAt: …}`. - -## If you use `lines()` … - -… adapt your code as follows: it now returns an object `{lines: […], realtimeDataUpdatedAt: …}`. - -## If you use the DB profile … - -… be aware that the `regionalExp` product has been renamed to `regionalExpress`. Among other places, you will notice this in `line.product`. - -## If you use the BVG or VBB profile … - -### … and rely on `stop.weight` … - -… use [`vbb-stations`](https://npmjs.com/package/vbb-stations) to get it instead. It has been removed from `hafas-client`. - -### … and rely on 12-digit stop IDs … - -… adapt your code to handle 9-digit (and sometimes 6-digit?) stop IDs. The translation logic has been removed from `hafas-client`. - -## If you rely on `line.adminCode` … - -… be aware that `hafas-client` now doesn't remove trailing `-` characters anymore (e.g. `DBS---` instead of `DBS`). - -## If you use the VBB profile … - -### … and rely on `line.{symbol,nr,metro,express,night}` … - -… use [`vbb-parse-line`](https://npmjs.com/package/vbb-parse-line) with `line.name` by yourself. It has been removed from `hafas-client`. - -### … and rely on `ticket.{amount,fullDay,group,tariff,coverage,variant}` … - -… use [`vbb-parse-ticket`](https://npmjs.com/package/vbb-parse-ticket) to parse details from the ticket identifier ([open an Issue](https://github.com/public-transport/hafas-client/issues/new) to get help). It has been removed from `hafas-client`. - -## Other breaking changes - -- `warning.fromLoc`/`warning.toLoc` are now called `warning.fromLocation`/`warning.toLocation` -- `trip()`/`tripsByName()`: remove `trip.reachable` (it didn't make sense anyways) diff --git a/docs/nearby.md b/docs/nearby.md index 26bb8d98..ef3c8fef 100644 --- a/docs/nearby.md +++ b/docs/nearby.md @@ -12,9 +12,9 @@ With `opt`, you can override the default options, which look like this: distance: null, // maximum walking distance in meters poi: false, // return points of interest? stops: true, // return stops/stations? - subStops: true, // parse & expose sub-stops of stations? - entrances: true, // parse & expose entrances of stops/stations? - linesOfStops: false, // parse & expose lines at each stop/station? + subStops: true, // not supported + entrances: true, // not supported + linesOfStops: false, // not supported language: 'en' // language to get results in } ``` @@ -24,8 +24,8 @@ With `opt`, you can override the default options, which look like this: As an example, we're going to use the [VBB profile](../p/vbb): ```js -import {createClient} from 'hafas-client' -import {profile as vbbProfile} from 'hafas-client/p/vbb/index.js' +import {createClient} from 'db-vendo-client' +import {profile as vbbProfile} from 'db-vendo-client/p/vbb/index.js' const userAgent = 'link-to-your-project-or-email' // adapt this to your project! const client = createClient(vbbProfile, userAgent) diff --git a/docs/profile-boilerplate.js b/docs/profile-boilerplate.js deleted file mode 100644 index ffc5784a..00000000 --- a/docs/profile-boilerplate.js +++ /dev/null @@ -1,45 +0,0 @@ -// Refer to the the ./writing-a-profile.md guide. - -const products = [ - { - id: 'commuterTrain', - mode: 'train', - bitmasks: [16], - name: 'ACME Commuter Rail', - short: 'CR', - default: true, - }, - { - id: 'metro', - mode: 'train', - bitmasks: [8], - name: 'Foo Bar Metro', - short: 'M', - default: true, - }, -]; - -const transformReqBody = (body) => { - // get these from the recorded app requests - // body.client = { … } - // body.ver = … - // body.auth = { … } - // body.lang = … - return body; -}; - -const insaProfile = { - // locale: …, - // timezone: …, - // endpoint: …, - transformReqBody, - - products: products, - - trip: false, - radar: false, -}; - -export { - insaProfile, -}; diff --git a/docs/radar.md b/docs/radar.md deleted file mode 100644 index 5139bd59..00000000 --- a/docs/radar.md +++ /dev/null @@ -1,191 +0,0 @@ -# `radar({north, west, south, east}, [opt])` - -Use this method to find all vehicles currently in an area. Note that it is not supported by every profile/endpoint. - -`north`, `west`, `south` and `eath` must be numbers (e.g. `52.52411`). Together, they form a [bounding box](https://en.wikipedia.org/wiki/Minimum_bounding_box). - -With `opt`, you can override the default options, which look like this: - -```js -{ - results: 256, // maximum number of vehicles - duration: 30, // compute frames for the next n seconds - frames: 3, // nr of frames to compute - polylines: true, // return a track shape for each vehicle? - subStops: true, // parse & expose sub-stops of stations? - entrances: true, // parse & expose entrances of stops/stations? - language: 'en' // language to get results in -} -``` - -## Response - -*Note:* As stated in the [*Friendly Public Transport Format* v2 draft spec](https://github.com/public-transport/friendly-public-transport-format/blob/3bd36faa721e85d9f5ca58fb0f38cdbedb87bbca/spec/readme.md), the returned `departure` and `arrival` times include the current delay. The `departureDelay`/`arrivalDelay` fields express how much they differ from the schedule. - -As an example, we're going to use the [VBB profile](../p/vbb): - -```js -import {createClient} from 'hafas-client' -import {profile as vbbProfile} from 'hafas-client/p/vbb/index.js' - -const userAgent = 'link-to-your-project-or-email' // adapt this to your project! -const client = createClient(vbbProfile, userAgent) - -const { - movements, - realtimeDataUpdatedAt, -} = await client.radar({ - north: 52.52411, - west: 13.41002, - south: 52.51942, - east: 13.41709 -}, {results: 5}) -``` - -`realtimeDataUpdatedAt` is a UNIX timestamp reflecting the latest moment when (at least some of) the response's realtime data have been updated. - -`movements` may look like this: - -```js -[ { - location: { - type: 'location', - latitude: 52.521508, - longitude: 13.411267 - }, - - line: { - type: 'line', - id: 's9', - fahrtNr: '12345', - name: 'S9', - public: true, - mode: 'train', - product: 'suburban', - symbol: 'S', - nr: 9, - metro: false, - express: false, - night: false, - operator: { - type: 'operator', - id: 's-bahn-berlin-gmbh', - name: 'S-Bahn Berlin GmbH' - } - }, - direction: 'S Flughafen Berlin-Schönefeld', - trip: 31463, // todo: outdated, should be tripId! - - nextStopovers: [ { - stop: { - type: 'stop', - id: '900000029101', - name: 'S Spandau', - location: { - type: 'location', - latitude: 52.534794, - longitude: 13.197477 - }, - products: { - suburban: true, - subway: false, - tram: false, - bus: true, - ferry: false, - express: true, - regional: true - } - }, - arrival: null, - plannedArrival: null, - arrivalDelay: null, - arrivalPlatform: null, - plannedArrivalPlatform: null, - departure: null, - plannedDeparture: '2017-12-17T19:16:00+01:00', - departureDelay: null, - departurePlatform: null, - plannedDeparturePlatform: '1' - } /* … */ ], - frames: [ { - origin: { - type: 'stop', - id: '900000100003', - name: 'S+U Alexanderplatz', - location: { /* … */ }, - products: { /* … */ } - }, - destination: { - type: 'stop', - id: '900000100004', - name: 'S+U Jannowitzbrücke', - location: { /* … */ }, - products: { /* … */ } - }, - t: 0 - }, /* … */ { - origin: { /* Alexanderplatz */ }, - destination: { /* Jannowitzbrücke */ }, - t: 30000 - } ] -}, { - location: { - type: 'location', - latitude: 52.523297, - longitude: 13.411151 - }, - line: { - type: 'line', - id: 'm2', - fahrtNr: '54321', - name: 'M2', - public: true, - mode: 'train', - product: 'tram', - symbol: 'M', - nr: 2, - metro: true, - express: false, - night: false, - operator: { - type: 'operator', - id: 'berliner-verkehrsbetriebe', - name: 'Berliner Verkehrsbetriebe' - } - }, - direction: 'Heinersdorf', - trip: 26321, - nextStopovers: [ { - stop: { /* S+U Alexanderplatz/Dircksenstr. */ }, - arrival: null, - plannedArrival: null, - arrivalDelay: null, - departure: null, - plannedAeparture: '2017-12-17T19:52:00+01:00', - departureDelay: null - }, { - stop: { /* Memhardstr. */ }, - arrival: null, - plannedArrival: '2017-12-17T19:54:00+01:00', - arrivalDelay: null, - arrivalPlatform: null, - plannedArrivalPlatform: null, - departure: null, - plannedDeparture: '2017-12-17T19:54:00+01:00', - departureDelay: null, - departurePlatform: null, - plannedDeparturePlatform: '1' - }, /* … */ ], - frames: [ { - origin: { /* S+U Alexanderplatz/Dircksenstr. */ }, - destination: { /* Memhardstr. */ }, - t: 0 - }, /* … */ { - origin: { /* Memhardstr. */ }, - destination: { /* Mollstr./Prenzlauer Allee */ }, - t: 30000 - } ] -}, /* … */ ] -``` - -If you pass `polylines: true`, each movement will have a `polyline` field, as documented in [the corresponding section in the `trip()` docs](trip.md#polyline-option), with the exception that station info is missing. diff --git a/docs/reachable-from.md b/docs/reachable-from.md deleted file mode 100644 index db096e64..00000000 --- a/docs/reachable-from.md +++ /dev/null @@ -1,98 +0,0 @@ -# `reachableFrom(address, [opt])` - -This method can be used to get stations reachable within a certain time from an address. This concept is called [isochrone diagram](https://en.wikipedia.org/wiki/Isochrone_map#Transportation_planning). - -*Note*: It appears that HAFAS cannot generate actual isochrones, but only the list of reachable stations, which you can estimate the isochrone(s) from. - -`address` must be an [*FPTF* `location` object](https://github.com/public-transport/friendly-public-transport-format/blob/3bd36faa721e85d9f5ca58fb0f38cdbedb87bbca/spec/readme.md#location-objects). - -With `opt`, you can override the default options, which look like this: - -```js -{ - when: new Date(), - maxTransfers: 5, // maximum of 5 transfers - maxDuration: 20, // maximum travel duration in minutes, pass `null` for infinite - products: { - // These entries may vary from profile to profile! - suburban: true, - subway: true - // … - }, - subStops: true, // parse & expose sub-stops of stations? - entrances: true, // parse & expose entrances of stops/stations? -} -``` - -## Response - -`reachableFrom(address, [opt])` returns an array, in which each item has a `duration` and an array of [*Friendly Public Transport Format* `station`s](https://github.com/public-transport/friendly-public-transport-format/blob/3bd36faa721e85d9f5ca58fb0f38cdbedb87bbca/spec/readme.md#station). - -As an example, we're going to use the [VBB profile](../p/vbb): - -```js -import {createClient} from 'hafas-client' -import {profile as vbbProfile} from 'hafas-client/p/vbb/index.js' - -const userAgent = 'link-to-your-project-or-email' // adapt this to your project! -const client = createClient(vbbProfile, userAgent) - -const { - reachable, - realtimeDataUpdatedAt, -} = await client.reachableFrom({ - type: 'location', - address: '13353 Berlin-Wedding, Torfstr. 17', - latitude: 52.541797, - longitude: 13.350042 -}, { - maxDuration: 10 // minutes -}) -``` - -`realtimeDataUpdatedAt` is a UNIX timestamp reflecting the latest moment when (at least some of) the response's realtime data have been updated. - -`reachable` may look like this: - -```js -[ - { - duration: 2, - stations: [ - { - type: 'stop', - id: '900000009101', - name: 'U Amrumer Str.', - location: {type: 'location', latitude: 52.542201, longitude: 13.34953}, - products: { /* … */ } - } - ] - }, { - duration: 3, - stations: [ - { - type: 'stop', - id: '900000001201', - name: 'S+U Westhafen', - location: {type: 'location', latitude: 52.536179, longitude: 13.343839}, - products: { /* … */ } - } - // … - ] - }, - // … - { - duration: 10, - stations: [ - { - type: 'stop', - id: '900000001203', - name: 'Döberitzer Str.', - location: {type: 'location', latitude: 52.530668, longitude: 13.36811}, - products: { /* … */ } - } - // … - ] - } -] -``` diff --git a/docs/readme.md b/docs/readme.md index 6309b542..c7818d72 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -1,19 +1,19 @@ -# `hafas-client` documentation +# `db-vendo-client` documentation **[API documentation](api.md)** -## Migrating from an old `hafas-client` version +## Migrating from an old (v5) `hafas-client` version -- [`4` → `5` migration guide](migrating-to-5.md) +`db-vendo-client` tries to be as compatible as possible with `hafas-client` v6. If you were still on v5 or earlier, see the [`5` → `6` migration guide](https://github.com/public-transport/hafas-client/blob/main/docs/migrating-to-6.md) of `hafas-client`. ## Throttling requests There's opt-in support for throttling requests to the endpoint. ```js -import {createClient} from 'hafas-client' -import {withThrottling} from 'hafas-client/throttle.js' -import {profile as dbProfile} from 'hafas-client/p/db/index.js' +import {createClient} from 'db-vendo-client' +import {withThrottling} from 'db-vendo-client/throttle.js' +import {profile as dbProfile} from 'db-vendo-client/p/db/index.js' const userAgent = 'link-to-your-project-or-email' // adapt this to your project! @@ -37,9 +37,9 @@ const client = createClient(throttledDbProfile, userAgent) There's opt-in support for retrying failed requests to the endpoint. ```js -import {createClient} from 'hafas-client' -import {withRetrying} from 'hafas-client/retry.js' -import {profile as dbProfile} from 'hafas-client/p/db/index.js' +import {createClient} from 'db-vendo-client' +import {withRetrying} from 'db-vendo-client/retry.js' +import {profile as dbProfile} from 'db-vendo-client/p/db/index.js' const userAgent = 'link-to-your-project-or-email' // adapt this to your project! @@ -61,27 +61,12 @@ const client = createClient(retryingDbProfile, userAgent) ## User agent randomization -By default, `hafas-client` randomizes the client name that you pass into `createClient`, and sends it as [`User-Agent`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent) in a randomized form: - -```js -import {createClient} from 'hafas-client' -// … - -const userAgent = 'my-awesome-program' -const client = createClient(someProfile, userAgent) - -await client.journeys(/* … */) -// User-Agent: my-awee70429some-pre70429ogram -await client.journeys(/* … */) -// User-Agent: my-awesom9bb8e2e-prog9bb8e2ram -``` - -You can turn this off by setting `profile.randomizeUserAgent` to `false`: +By default, `db-vendo-client` does not randomize the client name that you pass into `createClient`, and sends it as [`User-Agent`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent) as it is. At least DB Navigator always sends the same user agent as well (cf. `dbnav` profile). You can turn on randomization by setting `profile.randomizeUserAgent` to `false`: ```js const client = createClient({ ...someProfile, - randomizeUserAgent: false, + randomizeUserAgent: true, }, userAgent) ``` @@ -92,8 +77,8 @@ You can use `profile.logRequest` and `profile.logResponse` to process the raw [F As an example, we can implement a custom logger: ```js -import {createClient} from 'hafas-client' -import {profile as dbProfile} from 'hafas-client/p/db/index.js' +import {createClient} from 'db-vendo-client' +import {profile as dbProfile} from 'db-vendo-client/p/db/index.js' const userAgent = 'link-to-your-project-or-email' // adapt this to your project! @@ -140,15 +125,12 @@ The default `profile.logRequest` [`console.error`](https://nodejs.org/docs/lates ## Error handling -Unexpected errors – e.g. due to bugs in `hafas-client` itself – aside, its methods may reject with the following errors: +Unexpected errors – e.g. due to bugs in `db-vendo-client` itself – aside, its methods may reject with the following errors: +- `Error` – A generic error, e.g. if the DB backend returned a HTTP error. - `HafasError` – A generic error to signal that something HAFAS-related went wrong, either in the client, or in the HAFAS endpoint. -- `HafasAccessDeniedError` – The HAFAS endpoint has rejected your request because you're not allowed to access it (or the specific API call). Subclass of `HafasError`. -- `HafasInvalidRequestError` – The HAFAS endpoint reports that an invalid request has been sent. Subclass of `HafasError`. -- `HafasNotFoundError` – The HAFAS endpoint does not know about such stop/trip/etc. Subclass of `HafasError`. -- `HafasServerError` – An error occured within the HAFAS endpoint, so that it can't fulfill the request; For example, this happens when HAFAS' internal backend is unavailable. Subclass of `HafasError`. -Each error has the following properties: +Each `HafasError` error has the following properties: - `isHafasError` – Always `true`. Allows you to differente HAFAS-related errors from e.g. network errors. - `code` – A string representing the error type for all other error classes, e.g. `INVALID_REQUEST` for `HafasInvalidRequestError`. `null` for plain `HafasError`s. @@ -158,27 +140,11 @@ Each error has the following properties: - `url` – The URL of the request. - `response` – The [Fetch API `Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response). -To check **if an error from `hafas-client` is HAFAS-specific, use `error instanceof HafasError`**: -```js -import {HafasError} from 'hafas-client/lib/errors.js' +## Using `db-vendo-client` from another language -try { - await client.journeys(/* … */) -} catch (err) { - if (err instanceof HafasError) { - // HAFAS-specific error - } else { - // different error, e.g. network (ETIMEDOUT, ENETDOWN) - } -} -``` - -To determine **if you should automatically retry an error, use `!error.causedByServer`**. - -## Using `hafas-client` from another language - -If you want to use `hafas-client` to access HAFAS APIs but work with non-Node.js environments, you can use [`hafas-client-rpc`](https://github.com/derhuerst/hafas-client-rpc) to create a [JSON-RPC](https://www.jsonrpc.org) interface that you can send commands to. +If you want to use `db-vendo-client` to access DB APIs but work with non-Node.js environments, you can use it together with [hafas-rest-api](https://github.com/public-transport/hafas-rest-api) to create a REST API(see the [root readme](https://github.com/public-transport/db-vendo-client/tree/main#usage) and the Docker image). +Or use [`hafas-client-rpc`](https://github.com/derhuerst/hafas-client-rpc) to create a [JSON-RPC](https://www.jsonrpc.org) interface that you can send commands to. ## Writing a profile diff --git a/docs/refresh-journey.md b/docs/refresh-journey.md index c5e9be06..99e11787 100644 --- a/docs/refresh-journey.md +++ b/docs/refresh-journey.md @@ -7,10 +7,10 @@ With `opt`, you can override the default options, which look like this: ```js { stopovers: false, // return stations on the way? - polylines: false, // return a shape for each leg? - tickets: false, // return tickets? only available with some profiles - subStops: true, // parse & expose sub-stops of stations? - entrances: true, // parse & expose entrances of stops/stations? + polylines: false, // return a shape for each leg? mutually exclusive with tickets + tickets: false, // return tickets? mutually exclusive with polylines + subStops: true, // not supported + entrances: true, // not supported remarks: true, // parse & expose hints & warnings? language: 'en' // language to get results in } @@ -18,17 +18,14 @@ With `opt`, you can override the default options, which look like this: ## Response -As an example, we're going to use the [VBB profile](../p/vbb): - ```js -import {createClient} from 'hafas-client' -import {profile as vbbProfile} from 'hafas-client/p/vbb/index.js' +import {createClient} from 'db-vendo-client' +import {profile as vbbProfile} from 'db-vendo-client/p/vbb/index.js' const userAgent = 'link-to-your-project-or-email' // adapt this to your project! const client = createClient(vbbProfile, userAgent) -// Hauptbahnhof to Heinrich-Heine-Str. -const {journeys} = await client.journeys('900000003201', '900000100008', {results: 1}) +const {journeys} = await client.journeys('8000105', '8000096', {results: 1}) // later, fetch up-to-date info on the journey const { @@ -39,4 +36,4 @@ const { `journey` is a *single* [*Friendly Public Transport Format* v2 draft](https://github.com/public-transport/friendly-public-transport-format/blob/3bd36faa721e85d9f5ca58fb0f38cdbedb87bbca/spec/readme.md) `journey`, in the same format as returned by [`journeys()`](journeys.md). -`realtimeDataUpdatedAt` is a UNIX timestamp reflecting the latest moment when (at least some of) the response's realtime data have been updated. +`realtimeDataUpdatedAt` is currently not set in db-vendo-client, because the upstream APIs don't provide it. diff --git a/docs/remarks.md b/docs/remarks.md deleted file mode 100644 index 8f06f5ab..00000000 --- a/docs/remarks.md +++ /dev/null @@ -1,150 +0,0 @@ -# `remarks([opt])` - -**Fetches all remarks known to the HAFAS endpoint**, e.g. warnings about disruptions, planned construction work, and general notices about the operating situation. - -With `opt`, you can override the default options, which look like this: - -```js -{ - results: 100, // maximum number of remarks - // filter by time - from: Date.now(), - to: null, - products: null, // filter by affected products - language: 'en', // depends on the profile -} -``` - -## Example - -As an example, we're going to use the [SVV profile](../p/svv): - -```js -import {createClient} from 'hafas-client' -import {profile as svvProfile} from 'hafas-client/p/svv/index.js' - -const userAgent = 'link-to-your-project-or-email' // adapt this to your project! -const client = createClient(svvProfile, userAgent) - -const { - remarks, - realtimeDataUpdatedAt, -} = await client.remarks() -``` - -`realtimeDataUpdatedAt` is a UNIX timestamp reflecting the latest moment when (at least some of) the response's realtime data have been updated. - -`remarks` may look like this: - -```js -[ - { - id: 'HIM_FREETEXT_110342', - type: 'warning', - summary: 'Bus will be running at different times', - text: 'Due to operational changes, this bus will be running at different times. We apologise for any inconvenience this may cause.', - priority: 50, - company: 'KGÖVV', - validFrom: '2020-07-04T00:00:00+02:00', - validUntil: '2020-08-09T23:59:00+02:00', - modified: '2020-07-01T14:39:12+02:00', - products: { - 'bahn-s-bahn': true, - 'u-bahn': true, - strassenbahn: true, - fernbus: true, - regionalbus: true, - stadtbus: true, - 'seilbahn-zahnradbahn': true, - schiff: true, - }, - categories: [1], - icon: {type: 'HIM1', title: null}, - }, - // … - { - id: 'HIM_FREETEXT_110235', - type: 'warning', - summary: 'Linie 7 - Umleitungen', - text: 'Aufgrund einer Baustelle gibt es bei der Linie 7 umfangreiche Umleitungen.', - priority: 100, - company: 'VOR', - validFrom: '2020-07-13T00:00:00+02:00', - validUntil: '2020-08-31T23:59:00+02:00', - modified: '2020-06-30T12:37:38+02:00', - affectedLines: [{ - type: 'line', - id: '7', - name: '7', - public: true, - }], - products: { - 'bahn-s-bahn': true, - 'u-bahn': true, - strassenbahn: true, - fernbus: true, - regionalbus: true, - stadtbus: true, - 'seilbahn-zahnradbahn': false, - schiff: true, - }, - categories: [1], - icon: {type: 'HIM1', title: null}, - }, - // … - { - id: 'HIM_FREETEXT_106619', - type: 'warning', - summary: 'Stop Bad Hall Bahnhofstraße can not be approached', - text: 'The stop at Bad Hall Bahnhofstraße can not be approached during 21.04.-24.07.2020. Please use alternatively the stop at Bad Hall Busterminal (Abzw Bahnhofstraße).', - priority: 100, - company: 'OÖVG', - validFrom: '2020-04-21T00:00:00+02:00', - validUntil: '2020-07-24T23:59:00+02:00', - modified: '2020-07-08T12:52:13+02:00', - affectedLines: [{ - type: 'line', - id: '452', - name: '452', - public: true, - }], - products: { - 'bahn-s-bahn': false, - 'u-bahn': false, - strassenbahn: false, - fernbus: false, - regionalbus: true, - stadtbus: false, - 'seilbahn-zahnradbahn': false, - schiff: false - }, - categories: [1], - icon: {type: 'HIM1', title: null}, - }, - // … - { - id: 'HIM_FREETEXT_106671', - type: 'warning', - summary: 'Neue Haltestellennamen', - text: 'Im Zuge der Neuordnung der Regionalbusverkehre werden mit 6.7.2020 neue Fahrpläne und Liniennummern wirksam und dadurch können sich mitunter die Haltestellennamen verändern.', - priority: 100, - company: 'VOR', - validFrom: '2020-04-21T00:00:00+02:00', - validUntil: '2020-09-30T23:59:00+02:00', - modified: '2020-04-21T13:20:41+02:00', - products: { - 'bahn-s-bahn': true, - 'u-bahn': true, - strassenbahn: true, - fernbus: true, - regionalbus: true, - stadtbus: true, - 'seilbahn-zahnradbahn': false, - schiff: true, - }, - categories: [4], - icon: {type: 'HIM4', title: null}, - }, - // … -] -``` diff --git a/docs/server-info.md b/docs/server-info.md deleted file mode 100644 index eea4d651..00000000 --- a/docs/server-info.md +++ /dev/null @@ -1,38 +0,0 @@ -# `serverInfo([opt])` - -**Fetches meta information from the HAFAS endpoint.** - -With `opt`, you can override the default options, which look like this: - -```js -{ - versionInfo: true, // query HAFAS versions? - language: 'en', // depends on the profile -} -``` - -## Example - -As an example, we're going to use the [SVV profile](../p/svv): - -```js -import {createClient} from 'hafas-client' -import {profile as svvProfile} from 'hafas-client/p/svv/index.js' - -const userAgent = 'link-to-your-project-or-email' // adapt this to your project! -const client = createClient(svvProfile, userAgent) - -await client.serverInfo() -``` - -```js -{ - // version of the HAFAS Connection Interface (HCI), the API that hafas-client uses - hciVersion: '1.23', - - timetableStart: '20200517', - timetableEnd: '20201212', - serverTime: '2020-07-19T21:32:12+02:00', - realtimeDataUpdatedAt: 1595187102, -} -``` diff --git a/docs/stop.md b/docs/stop.md index fd2f3c1b..78ca415a 100644 --- a/docs/stop.md +++ b/docs/stop.md @@ -1,5 +1,7 @@ # `stop(id, [opt])` +This endpoint is only available with `dbnav` profile. + `id` must be in one of these formats: ```js @@ -23,8 +25,8 @@ With `opt`, you can override the default options, which look like this: ```js { - subStops: true, // parse & expose sub-stops of stations? - entrances: true, // parse & expose entrances of stops/stations? + subStops: true, // not supported + entrances: true, // not supported linesOfStops: false, // parse & expose lines at the stop/station? language: 'en' // language to get results in } diff --git a/docs/tests.md b/docs/tests.md index 325dd4a7..0ada8df6 100644 --- a/docs/tests.md +++ b/docs/tests.md @@ -1,8 +1,8 @@ -# automated tests in `hafas-client` +# automated tests in `db-vendo-client` -Because transit data is inherently dynamic (e.g. a different set of departures being returned for a stop now than in 10 minutes), and because it is of paramount importance that `hafas-client` actually works with HAFAS endpoints *as they currently work*, its testing setup is a bit unusual. +Because transit data is inherently dynamic (e.g. a different set of departures being returned for a stop now than in 10 minutes), and because it is of paramount importance that `db-vendo-client` actually works with HAFAS endpoints *as they currently work*, its testing setup is a bit unusual. -`hafas-client` has three kinds of automated tests: +`db-vendo-client` has three kinds of automated tests: - unit tests, which test individual aspects of the case base in isolation (e.g. the parsing of HAFAS-formatted dates & times) – run via `npm run test-unit` - end-to-end (E2E) tests, which run actual HTTP requests against their respective profile's HAFAS endpoint – run via `npm run test-e2e` - integration tests, which are the E2E tests running against pre-recorded (and checked-in) HTTP request fixtures – run via `npm run test-integration` @@ -16,7 +16,7 @@ Because the E2E & integration tests are based on the same code, when changing th As an example, let's assume that we have added an entirely new test to [the *DB* profile's E2E tests](../test/e2e/db.js). The behaviour of the HTTP request recording (into fixtures) and mocking (using the recorded fixtures) is controlled via an environment variable `$VCR_MODE`: -- By running the test(s) with `VCR_MODE=record`, we can record the HTTP requests being made. The tests will run just like without `$VCR_MODE`, except that they will query data for date+time specified in `T_MOCK` (e.g. [here](https://github.com/public-transport/hafas-client/blob/8ff945c07515155380de0acb33584e474d6d547c/test/e2e/db.js#L33)). +- By running the test(s) with `VCR_MODE=record`, we can record the HTTP requests being made. The tests will run just like without `$VCR_MODE`, except that they will query data for date+time specified in `T_MOCK` (e.g. [here](https://github.com/public-transport/db-vendo-client/blob/8ff945c07515155380de0acb33584e474d6d547c/test/e2e/db.js#L33)). - Then, by running the test(s) with `VCR_MODE=playback`, because their HTTP requests match the pre-recorded fixtures, they work on the corresponding mocked HTTP responses. Usually, you would not want to update all *already existing* recorded HTTP request fixtures of the test suite you have made changes in, as they are unrelated to the test you have added. To only record your *added* test, temporarily change `tap.test(…)` to read `tap.only(…)`, and run with `TAP_ONLY=1 VCR_MODE=record`; This will skip all unrelated tests entirely. diff --git a/docs/trip.md b/docs/trip.md index 16266518..9c59f31f 100644 --- a/docs/trip.md +++ b/docs/trip.md @@ -2,19 +2,16 @@ This method can be used to refetch information about a trip – a vehicle stopping at a set of stops at specific times. -*Note*: This method is not supported by every profile/endpoint. - Let's say you used [`journeys`](journeys.md) and now want to get more up-to-date data about the arrival/departure of a leg. You'd pass in the trip ID from `leg.tripId`, e.g. `'1|24983|22|86|18062017'`, and the name of the line from `leg.line.name` like this: ```js -import {createClient} from 'hafas-client' -import {profile as vbbProfile} from 'hafas-client/p/vbb/index.js' +import {createClient} from 'db-vendo-client' +import {profile as vbbProfile} from 'db-vendo-client/p/dbnav/index.js' const userAgent = 'link-to-your-project-or-email' // adapt this to your project! const client = createClient(vbbProfile, userAgent) -// Hauptbahnhof to Heinrich-Heine-Str. -const {journeys} = client.journeys('900000003201', '900000100008', {results: 1}) +const {journeys} = client.journeys('8000096', '8000105', {results: 1}) const leg = journeys[0].legs[0] await client.trip(leg.tripId) @@ -25,9 +22,9 @@ With `opt`, you can override the default options, which look like this: ```js { stopovers: true, // return stations on the way? - polyline: false, // return a shape for the trip? - subStops: true, // parse & expose sub-stops of stations? - entrances: true, // parse & expose entrances of stops/stations? + polyline: false, // return a shape for the trip? only supported with HAFAS trip id (i.e. not with a trip id from a departure/arrival board of the `db` profile) + subStops: true, // not supported + entrances: true, // not supported remarks: true, // parse & expose hints & warnings? language: 'en' // language to get results in } @@ -37,11 +34,10 @@ With `opt`, you can override the default options, which look like this: *Note:* As stated in the [*Friendly Public Transport Format* v2 draft spec](https://github.com/public-transport/friendly-public-transport-format/blob/3bd36faa721e85d9f5ca58fb0f38cdbedb87bbca/spec/readme.md), the returned `departure` and `arrival` times include the current delay. The `departureDelay`/`arrivalDelay` fields express how much they differ from the schedule. -As an example, we're going to use the [VBB profile](../p/vbb): ```js -import {createClient} from 'hafas-client' -import {profile as vbbProfile} from 'hafas-client/p/vbb/index.js' +import {createClient} from 'db-vendo-client' +import {profile as vbbProfile} from 'db-vendo-client/p/dbnav/index.js' const client = createClient(vbbProfile) @@ -53,7 +49,7 @@ const { }) ``` -`realtimeDataUpdatedAt` is a UNIX timestamp reflecting the latest moment when (at least some of) the response's realtime data have been updated. +`realtimeDataUpdatedAt` is currently not set in db-vendo-client, because the upstream APIs don't provide it. When running the code above, `trip` looked like this: @@ -142,9 +138,9 @@ When running the code above, `trip` looked like this: ### `polyline` option -If you pass `polyline: true`, the trip will have a `polyline` field, containing a [GeoJSON](http://geojson.org) [`FeatureCollection`](https://tools.ietf.org/html/rfc7946#section-3.3) of [`Point`s](https://tools.ietf.org/html/rfc7946#appendix-A.1). Every `Point` next to a station will have `properties` containing the station's metadata. +Only supported with HAFAS trip id (i.e. not with a trip id from a departure/arrival board of the `db` profile). -We'll look at an example for *U6* from *Alt-Mariendorf* to *Alt-Tegel*, taken from the [VBB profile](../p/vbb): +If you pass `polyline: true`, the trip will have a `polyline` field, containing a [GeoJSON](http://geojson.org) [`FeatureCollection`](https://tools.ietf.org/html/rfc7946#section-3.3) of [`Point`s](https://tools.ietf.org/html/rfc7946#appendix-A.1). ```js { @@ -152,12 +148,6 @@ We'll look at an example for *U6* from *Alt-Mariendorf* to *Alt-Tegel*, taken fr features: [ { type: 'Feature', - properties: { - type: 'station', - id: '900000070301', - name: 'U Alt-Mariendorf', - /* … */ - }, geometry: { type: 'Point', coordinates: [13.3875, 52.43993] // longitude, latitude @@ -166,12 +156,6 @@ We'll look at an example for *U6* from *Alt-Mariendorf* to *Alt-Tegel*, taken fr /* … */ { type: 'Feature', - properties: { - type: 'station', - id: '900000017101', - name: 'U Mehringdamm', - /* … */ - }, geometry: { type: 'Point', coordinates: [13.38892, 52.49448] // longitude, latitude @@ -189,12 +173,6 @@ We'll look at an example for *U6* from *Alt-Mariendorf* to *Alt-Tegel*, taken fr }, { type: 'Feature', - properties: { - type: 'station', - id: '900000089301', - name: 'U Alt-Tegel', - /* … */ - }, geometry: { type: 'Point', coordinates: [13.28406, 52.58915] // longitude, latitude diff --git a/docs/trips-by-name.md b/docs/trips-by-name.md deleted file mode 100644 index 3a74bfb1..00000000 --- a/docs/trips-by-name.md +++ /dev/null @@ -1,114 +0,0 @@ -# `tripsByName([lineNameOrFahrtNr], [opt])` - -Get all trips matching one or more criteria, e.g. a specific name. - -## Response - -As an example, we're going to use the [VBB profile](../p/vbb): - -```js -import {createClient} from 'hafas-client' -import {profile as vbbProfile} from 'hafas-client/p/vbb/index.js' - -const userAgent = 'link-to-your-project-or-email' // adapt this to your project! -const client = createClient(vbbProfile, userAgent) - -const { - trips, - realtimeDataUpdatedAt, -} = await client.tripsByName('S1') -``` - -With `opt`, you can override the default options, which look like this: - -```js -{ - // use either this - when: null, - // or these - fromWhen: null, untilWhen: null, - - onlyCurrentlyRunning: true, - products: { - // these entries may vary from profile to profile - suburban: true, - subway: true, - tram: true, - bus: true, - ferry: true, - express: true, - regional: true, - }, - - currentlyStoppingAt: null, // only show trips currently stopping at a stop/station, string - lineName: null, // only show trips with this line name, string - operatorNames: null, // only show trips with these operator names, array of strings -} -``` - -`realtimeDataUpdatedAt` is a UNIX timestamp reflecting the latest moment when (at least some of) the response's realtime data have been updated. - -`trips` may look like this: - -```js -[ - { - id: '1|1214|0|86|16092020' - direction: null, - line: { - type: 'line', - id: 's1', - fahrtNr: '325', - name: 'S1', - mode: 'train', - product: 'suburban', - // … - }, - - origin: { - type: 'stop', - id: '900000550239', - name: 'Warnemünde, Bhf', - location: { /* … */ }, - products: { /* … */ }, - }, - departure: '2020-09-16T04:03:00+02:00', - plannedDeparture: '2020-09-16T04:03:00+02:00', - departureDelay: null, - departurePlatform: null, - plannedDeparturePlatform: null, - - destination: { - type: 'stop', - id: '900000550002', - name: 'Rostock, Hbf', - location: { /* … */ }, - products: { /* … */ }, - }, - arrival: '2020-09-16T04:24:00+02:00', - plannedArrival: '2020-09-16T04:24:00+02:00', - arrivalDelay: null, - arrivalPlatform: null, - plannedArrivalPlatform: null, - }, - // … - { - id: '1|62554|0|86|16092020' - direction: null, - line: { - type: 'line', - id: 's1', - fahrtNr: '2001', - name: 'S1', - public: true, - mode: 'train', - product: 'suburban', - // … - }, - - origin: { /* … */ }, - destination: { /* … */ }, - // … - } -] -``` diff --git a/docs/writing-a-profile.md b/docs/writing-a-profile.md deleted file mode 100644 index 010d98bf..00000000 --- a/docs/writing-a-profile.md +++ /dev/null @@ -1,163 +0,0 @@ -# Writing a profile - -**Per HAFAS endpoint, `hafas-client` has an endpoint-specific customisation called *profile*.** A profile may, for example, do the following: - -- handle the additional requirements of the endpoint (e.g. authentication), -- extract additional information from the data provided by the endpoint, -- guard against triggering bugs of certain endpoints (e.g. time limits). - -This guide is about writing such a profile. If you just want to use an already supported endpoint, refer to the [main readme](../readme.md) instead. - -*Note*: **If you get stuck, ask for help by [creating an issue](https://github.com/public-transport/hafas-client/issues/new)**; We're happy to help you expand the scope of this library! - -## 0. How do the profiles work? - -A profile may consist of three things: - -- **mandatory details about the HAFAS endpoint** - - `endpoint`: The protocol, host and path of the endpoint. - - `locale`: The [BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag) [locale](https://en.wikipedia.org/wiki/Locale_(computer_software)) of your endpoint (or the area that your endpoint covers). - - `timezone`: An [IANA-time-zone](https://www.iana.org/time-zones)-compatible [timezone](https://en.wikipedia.org/wiki/Time_zone) of your endpoint. -- **flags indicating which features are supported by the endpoint** – e.g. `trip` -- **methods overriding the [default profile](../lib/default-profile.js)** - -Let's use a fictional endpoint for [Austria](https://en.wikipedia.org/wiki/Austria) as an example: - -```js -const myProfile = { - endpoint: 'https://example.org/bin/mgate.exe', - locale: 'de-AT', - timezone: 'Europe/Vienna' -} -``` - -Assuming their HAFAS endpoint returns all line names prefixed with `foo `, we can adapt our profile to clean them: - -```js -// get the default line parser -import {parseLine} from 'hafas-client/parse/line.js' - -// wrapper function with additional logic -const parseLineWithoutFoo = (ctx, rawLine) => { - const line = parseLine(ctx, rawLine) - line.name = line.name.replace(/foo /g, '') - return line -} - -myProfile.parseLine = parseLineWithoutFoo -``` - -If you pass this profile into `hafas-client`, the `parseLine` method will override [the default one](../parse/line.js). - -You can also use the `parseHook` helper to reduce boilerplate: - -```js -import {parseHook} from 'hafas-client/lib/profile-hooks.js' - -const removeFoo = (ctx, rawLine) => ({ - ...ctx.parsed, - name: line.name.replace(/foo /g, '') -}) - -myProfile.parseLine = parseHook(parseLine, removeFoo) -``` - -## 1. Setup - -*Note*: There are many ways to find the required values. This way is rather easy and works with most endpoints by now. - -1. **Find the journey planning webapp** corresponding to the API endpoint; Usually, you can find it on the public transport provider's website. -2. **Open your [browser's devtools](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools)**, switch to the "Network" tab, and **inspect the requests to the HAFAS API**. - -If you can't find the webapp or your public transport provider doesn't have one, you can inspect their mobile app's traffic instead: - -1. Get an iOS or Android device and **download the "official" app.** -2. **Configure a [man-in-the-middle HTTP proxy](https://docs.mitmproxy.org/stable/concepts-howmitmproxyworks/)** like [mitmproxy](https://mitmproxy.org). - - Configure your device to trust the self-signed SSL certificate, [as outlined in the mitmproxy docs](https://docs.mitmproxy.org/stable/concepts-certificates/). - - *Note*: This method does not work if the app uses [public key pinning](https://en.wikipedia.org/wiki/HTTP_Public_Key_Pinning). In this case (the app won't be able to query data), please [create an issue](https://github.com/public-transport/hafas-client/issues/new), so we can discuss other techniques. -3. **Record requests of the app.** - - [There's a video showing this step](https://stuff.jannisr.de/how-to-record-hafas-requests.mp4). - - Make sure to cover all relevant sections of the app, e.g. "journeys", "departures", "live map". Better record more than less! - - To help others in the future, post the requests (in their entirety!) on GitHub, e.g. in as format like [this](https://gist.github.com/derhuerst/5fa86ed5aec63645e5ae37e23e555886). This will also let us help you if you have any questions. - -## 2. Basic profile - -*Note:* You should have read the [general documentation on `mgate.exe` APIs](hafas-mgate-api.md) to make sense of the terminology used below. - -You may want to start with the [profile boilerplate](profile-boilerplate.js). - -- **Identify the `endpoint`.** The protocol, host and path of the endpoint, *but not* the query string. - - *Note*: **`hafas-client` for now only supports the interface providing JSON** (generated from XML), which is being used by the corresponding iOS/Android apps. It supports neither the JSONP, nor the XML, nor the HTML interface. If the endpoint does not end in `mgate.exe`, it mostly likely won't work. -- **Identify the `locale`.** Basically guess work; Use the date & time formats as an indicator. -- **Identify the `timezone`.** This may be tricky, a for example [Deutsche Bahn](https://en.wikipedia.org/wiki/Deutsche_Bahn) returns departures for Moscow as `+01:00` instead of `+03:00`. -- **Copy the authentication** and other meta fields, namely `ver`, `ext`, `client` and `lang`. - - You can find these fields in the root of each request JSON. Check [a VBB request](https://gist.github.com/derhuerst/ea5d6482b61aeb7384a2c788f43dc11d#file-0-serverinfo-http-L11-L33) and [the corresponding VBB profile](https://github.com/public-transport/hafas-client/blob/2baf2f6f0444ffc67317f8bafe0fe05f687e5fae/p/vbb/base.json#L2-L11) for an example. - - Add a function `transformReqBody(ctx, body)` to your profile, which adds the fields to `body`. todo: adapt this - - Some profiles have a `checksum` parameter (like [here](https://gist.github.com/derhuerst/2a735268bd82a0a6779633f15dceba33#file-journey-details-1-http-L1)) or two `mic` & `mac` parameters (like [here](https://gist.github.com/derhuerst/5fa86ed5aec63645e5ae37e23e555886#file-1-http-L1)). If you see one of them in your requests, jump to the [*Authentication* section of the `mgate.exe` docs](hafas-mgate-api.md#authentication). Unfortunately, this is necessary to get the profile working. - -## 3. Products - -In `hafas-client`, there's a distinction between the `mode` and the `product` fields: - -- The `mode` field describes the mode of transport in general. [Standardised by the *Friendly Public Transport Format*](https://github.com/public-transport/friendly-public-transport-format/blob/3bd36faa721e85d9f5ca58fb0f38cdbedb87bbca/spec/readme.md#modes), it is on purpose limited to a very small number of possible values, e.g. `train` or `bus`. -- The value for `product` relates to how a means of transport "works" *in local context*. Example: Even though [*S-Bahn*](https://en.wikipedia.org/wiki/Berlin_S-Bahn) and [*U-Bahn*](https://en.wikipedia.org/wiki/Berlin_U-Bahn) in Berlin are both `train`s, they have different operators, service patterns, stations and look different. Therefore, they are two distinct `product`s `subway` and `suburban`. - -**Specify `product`s that appear in the app** you recorded requests of. For a fictional transit network, this may look like this: - -```js -const products = [ - { - id: 'commuterTrain', - mode: 'train', - bitmasks: [16], - name: 'ACME Commuter Rail', - short: 'CR', - default: true - }, - { - id: 'metro', - mode: 'train', - bitmasks: [8], - name: 'Foo Bar Metro', - short: 'M', - default: true - } -] -``` - -Let's break this down: - -- `id`: A sensible, [camelCased](https://en.wikipedia.org/wiki/Camel_case#Variations_and_synonyms), alphanumeric identifier. Use it for the key in the `products` array as well. -- `mode`: A [valid *Friendly Public Transport Format* mode](https://github.com/public-transport/friendly-public-transport-format/blob/3bd36faa721e85d9f5ca58fb0f38cdbedb87bbca/spec/readme.md#modes). -- `bitmasks`: HAFAS endpoints work with a [bitmask](https://en.wikipedia.org/wiki/Mask_(computing)#Arguments_to_functions) that toggles the individual products. It should be an array of values that toggle the appropriate bit(s) in the bitmask (see below). -- `name`: A short, but distinct name for the means of transport, *just precise enough in local context*, and in the local language. In Berlin, `S-Bahn-Schnellzug` would be too much, because everyone knows what `S-Bahn` means. -- `short`: The shortest possible symbol that identifies the product. -- `default`: Should the product be used for queries (e.g. journeys) by default? - -If you want, you can now **verify that the profile works**; We've prepared [a script](https://runkit.com/derhuerst/hafas-client-profile-example/0.2.1) for that. Alternatively, [submit a Pull Request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/) and we will help you out with testing and improvements. - -### Finding the right values for the `bitmasks` field - -As shown in [the video](https://stuff.jannisr.de/how-to-record-hafas-requests.mp4), search for a journey and toggle off one product at a time, recording the requests. After extracting the products bitmask ([example](https://gist.github.com/derhuerst/193ef489f8aa50c2343f8bf1f2a22069#file-via-http-L34)) you will end up with values looking like these: - -``` -toggles value binary subtraction bit(s) -all products 31 11111 31 - 0 -all but ACME Commuter Rail 15 01111 31 - 2^4 2^4 -all but Foo Bar Metro 23 10111 31 - 2^3 2^3 -all but product E 25 11001 31 - 2^2 - 2^1 2^2, 2^1 -all but product F 30 11110 31 - 2^0 2^0 -``` - -## 4. Additional info - -We consider these improvements to be *optional*: -- **Check if the endpoint supports the `trip()` call.** - - In the app, check if you can re-fetch details for the status of a single journey leg. It should load realtime delays and the current progress. - - If this feature is supported, add `trip: true` to the profile. -- **Check if the endpoint supports the live map call.** Does the app have a "live map" showing all vehicles within an area? If so, add `radar: true` to the profile. -- **Consider transforming station & line names** into the formats that's most suitable for *local users*. This is just an optimal optimisation that makes it easier for users of the profile to use the data. Some examples: - - `M13 (Tram)` -> `M13`. With Berlin context, it is obvious that `M13` is a tram. - - `Berlin Jungfernheide Bhf` -> `Berlin Jungfernheide`. With local context, it's obvious that *Jungfernheide* is a train station. -- **Check if the endpoint has non-obvious limitations** and let use know about these. Examples: - - Some endpoints have a time limit, after which they won't return more departures, but silently discard them. diff --git a/index.js b/index.js index 72acbc7a..4fd32d44 100644 --- a/index.js +++ b/index.js @@ -76,7 +76,7 @@ const createClient = (profile, userAgent, opt = {}) => { if (!profile.departuresGetPasslist && 'stopovers' in opt) { throw new Error('opt.stopovers is not supported by this endpoint'); } - if (!profile.departuresStbFltrEquiv && 'includeRelatedStations' in opt) { + if (!profile.departuresStbFltrEquiv && 'includeRelatedStations' in opt) { // TODO artificially filter? throw new Error('opt.includeRelatedStations is not supported by this endpoint'); } diff --git a/readme.md b/readme.md index 0855db5e..e241cc92 100644 --- a/readme.md +++ b/readme.md @@ -8,7 +8,7 @@ This is a very early version. What works: * `journeys()`, `refreshJourney()` including tickets -* `locations()`, `nearby()`, `stop()` +* `locations()`, `nearby()`, * `departures()`, `arrivals()` boards * `trip()` @@ -38,8 +38,7 @@ Depending on the configured profile, db-vendo-client will use multiple different Feel free to report anything that you stumble upon via Issues or create a PR :) -Also consult the relevant **[documentation](https://github.com/public-transport/hafas-client/blob/main/docs/readme.md)** of [hafas-client](https://github.com/public-transport/hafas-client/) (but beware of the limited functionality of db-vendo-client). - +Also consult the **[documentation](docs/readme.md)**. ## Background