mirror of
https://github.com/public-transport/db-vendo-client.git
synced 2025-09-18 12:09:22 +03:00
Compare commits
No commits in common. "main" and "v6.8.0" have entirely different histories.
21 changed files with 64 additions and 2488 deletions
|
@ -95,8 +95,6 @@
|
||||||
"bitmasks",
|
"bitmasks",
|
||||||
"Blaschkoallee",
|
"Blaschkoallee",
|
||||||
"Blissestr",
|
"Blissestr",
|
||||||
"bmis",
|
|
||||||
"BMIS",
|
|
||||||
"BNWNZF",
|
"BNWNZF",
|
||||||
"Böhme",
|
"Böhme",
|
||||||
"BONVOYO",
|
"BONVOYO",
|
||||||
|
@ -197,7 +195,6 @@
|
||||||
"Fehrbelliner",
|
"Fehrbelliner",
|
||||||
"Fernbf",
|
"Fernbf",
|
||||||
"Fernverkehr",
|
"Fernverkehr",
|
||||||
"firmen",
|
|
||||||
"Flexpreis",
|
"Flexpreis",
|
||||||
"Flix",
|
"Flix",
|
||||||
"Fltr",
|
"Fltr",
|
||||||
|
@ -266,7 +263,6 @@
|
||||||
"Hohenzollerndamm",
|
"Hohenzollerndamm",
|
||||||
"Hüngheim",
|
"Hüngheim",
|
||||||
"IBNR",
|
"IBNR",
|
||||||
"identifikationsart",
|
|
||||||
"Ihren",
|
"Ihren",
|
||||||
"Ihrer",
|
"Ihrer",
|
||||||
"Informationen",
|
"Informationen",
|
||||||
|
@ -614,7 +610,6 @@
|
||||||
"Zoologischer",
|
"Zoologischer",
|
||||||
"Zuege",
|
"Zuege",
|
||||||
"zugart",
|
"zugart",
|
||||||
"Zugehoerigkeit",
|
|
||||||
"zugattrib",
|
"zugattrib",
|
||||||
"zugattribute",
|
"zugattribute",
|
||||||
"Zuges",
|
"Zuges",
|
||||||
|
@ -632,11 +627,7 @@
|
||||||
"Intervalle",
|
"Intervalle",
|
||||||
"tagesbest",
|
"tagesbest",
|
||||||
"dbbahnhof",
|
"dbbahnhof",
|
||||||
"Deutschlandticket",
|
"cancelation"
|
||||||
"fahrverguenstigungen",
|
|
||||||
"cancelation",
|
|
||||||
"MOTIS",
|
|
||||||
"motis"
|
|
||||||
],
|
],
|
||||||
"ignorePaths": [
|
"ignorePaths": [
|
||||||
"docs/dumps/**",
|
"docs/dumps/**",
|
||||||
|
|
|
@ -81,7 +81,6 @@ With `opt`, you can override the default options, which look like this:
|
||||||
firstClass: false, // first or second class for tickets
|
firstClass: false, // first or second class for tickets
|
||||||
loyaltyCard: null, // BahnCards etc., see below
|
loyaltyCard: null, // BahnCards etc., see below
|
||||||
language: 'en', // language to get results in
|
language: 'en', // language to get results in
|
||||||
bmisNumber: null, // 7-digit BMIS number for business customer rates
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -317,27 +316,6 @@ hafas.journeys(from, to, {
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
## Using the `bmisNumber` option
|
|
||||||
|
|
||||||
bahn.business customers with a BMIS number can get their corporate rates and corporate tariffs by providing their 7-digit BMIS number:
|
|
||||||
|
|
||||||
```js
|
|
||||||
// Option 1: Using the bmisNumber parameter directly
|
|
||||||
await client.journeys(from, to, {
|
|
||||||
bmisNumber: '1234567' // Your 7-digit BMIS number
|
|
||||||
})
|
|
||||||
|
|
||||||
// Option 2: Using the createBusinessClient helper function
|
|
||||||
import {createBusinessClient} from 'db-vendo-client'
|
|
||||||
import {profile as dbProfile} from 'db-vendo-client/p/db/index.js'
|
|
||||||
|
|
||||||
const businessClient = createBusinessClient(dbProfile, userAgent, '1234567')
|
|
||||||
// Now all journey searches will automatically include the BMIS number
|
|
||||||
await businessClient.journeys(from, to)
|
|
||||||
```
|
|
||||||
|
|
||||||
When a BMIS number is provided, the request will include a `firmenZugehoerigkeit` object with the BMIS number and identification type, allowing business customers to access their special rates and conditions.
|
|
||||||
|
|
||||||
## The `routingMode` option
|
## 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](https://github.com/public-transport/hafas-client/blob/main/p/db/readme.md#using-the-routingmode-option), i.e. cancelled trains/infeasible journeys will also be contained for informational purpose.
|
The `routingMode` option is not supported by db-vendo-client. The behavior will be the same as the [`HYBRID` mode of hafas-client](https://github.com/public-transport/hafas-client/blob/main/p/db/readme.md#using-the-routingmode-option), i.e. cancelled trains/infeasible journeys will also be contained for informational purpose.
|
|
@ -10,7 +10,7 @@ With `opt`, you can override the default options, which look like this:
|
||||||
{
|
{
|
||||||
results: 8, // maximum number of results
|
results: 8, // maximum number of results
|
||||||
distance: null, // maximum walking distance in meters
|
distance: null, // maximum walking distance in meters
|
||||||
poi: false, // not supported
|
poi: false, // return points of interest?
|
||||||
stops: true, // return stops/stations?
|
stops: true, // return stops/stations?
|
||||||
subStops: true, // not supported
|
subStops: true, // not supported
|
||||||
entrances: true, // not supported
|
entrances: true, // not supported
|
||||||
|
|
|
@ -613,7 +613,7 @@ paths:
|
||||||
default: true
|
default: true
|
||||||
- name: linesOfStops
|
- name: linesOfStops
|
||||||
in: query
|
in: query
|
||||||
description: not supported
|
description: Parse & return lines of each stop/station?
|
||||||
schema:
|
schema:
|
||||||
type: boolean
|
type: boolean
|
||||||
default: false
|
default: false
|
||||||
|
@ -1887,11 +1887,11 @@ components:
|
||||||
default: false
|
default: false
|
||||||
type: boolean
|
type: boolean
|
||||||
subStops:
|
subStops:
|
||||||
description: not supported
|
description: parse & expose sub-stops of stations?
|
||||||
default: false
|
default: false
|
||||||
type: boolean
|
type: boolean
|
||||||
entrances:
|
entrances:
|
||||||
description: not supported
|
description: parse & expose entrances of stops/stations?
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
remarks:
|
remarks:
|
||||||
|
@ -1995,11 +1995,11 @@ components:
|
||||||
default: false
|
default: false
|
||||||
type: boolean
|
type: boolean
|
||||||
subStops:
|
subStops:
|
||||||
description: not supported
|
description: parse & expose sub-stops of stations?
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
entrances:
|
entrances:
|
||||||
description: not supported
|
description: parse & expose entrances of stops/stations?
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
remarks:
|
remarks:
|
||||||
|
@ -2034,15 +2034,15 @@ components:
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
subStops:
|
subStops:
|
||||||
description: not supported
|
description: parse & expose sub-stops of stations?
|
||||||
default: false
|
default: false
|
||||||
type: boolean
|
type: boolean
|
||||||
entrances:
|
entrances:
|
||||||
description: not supported
|
description: parse & expose entrances of stops/stations?
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
linesOfStops:
|
linesOfStops:
|
||||||
description: not supported
|
description: parse & expose lines at each stop/station?
|
||||||
default: false
|
default: false
|
||||||
type: boolean
|
type: boolean
|
||||||
language:
|
language:
|
||||||
|
@ -2061,11 +2061,11 @@ components:
|
||||||
default: false
|
default: false
|
||||||
type: boolean
|
type: boolean
|
||||||
subStops:
|
subStops:
|
||||||
description: not supported
|
description: parse & expose sub-stops of stations?
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
entrances:
|
entrances:
|
||||||
description: not supported
|
description: parse & expose entrances of stops/stations?
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
remarks:
|
remarks:
|
||||||
|
@ -2088,11 +2088,11 @@ components:
|
||||||
default: false
|
default: false
|
||||||
type: boolean
|
type: boolean
|
||||||
subStops:
|
subStops:
|
||||||
description: not supported
|
description: parse & expose sub-stops of stations?
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
entrances:
|
entrances:
|
||||||
description: not supported
|
description: parse & expose entrances of stops/stations?
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
remarks:
|
remarks:
|
||||||
|
@ -2128,11 +2128,11 @@ components:
|
||||||
default: 10
|
default: 10
|
||||||
type: number
|
type: number
|
||||||
subStops:
|
subStops:
|
||||||
description: not supported
|
description: parse & expose sub-stops of stations?
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
entrances:
|
entrances:
|
||||||
description: not supported
|
description: parse & expose entrances of stops/stations?
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
linesOfStops:
|
linesOfStops:
|
||||||
|
@ -2206,7 +2206,7 @@ components:
|
||||||
default: undefined
|
default: undefined
|
||||||
type: number
|
type: number
|
||||||
poi:
|
poi:
|
||||||
description: not supported
|
description: return points of interest?
|
||||||
default: false
|
default: false
|
||||||
type: boolean
|
type: boolean
|
||||||
stops:
|
stops:
|
||||||
|
@ -2218,15 +2218,15 @@ components:
|
||||||
description: products
|
description: products
|
||||||
default: undefined
|
default: undefined
|
||||||
subStops:
|
subStops:
|
||||||
description: not supported
|
description: parse & expose sub-stops of stations?
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
entrances:
|
entrances:
|
||||||
description: not supported
|
description: parse & expose entrances of stops/stations?
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
linesOfStops:
|
linesOfStops:
|
||||||
description: not supported
|
description: parse & expose lines at each stop/station?
|
||||||
default: false
|
default: false
|
||||||
type: boolean
|
type: boolean
|
||||||
language:
|
language:
|
||||||
|
@ -2254,11 +2254,11 @@ components:
|
||||||
description: products
|
description: products
|
||||||
default: undefined
|
default: undefined
|
||||||
subStops:
|
subStops:
|
||||||
description: not supported
|
description: parse & expose sub-stops of stations?
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
entrances:
|
entrances:
|
||||||
description: not supported
|
description: parse & expose entrances of stops/stations?
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
polylines:
|
polylines:
|
||||||
|
@ -2296,11 +2296,11 @@ components:
|
||||||
default: 20
|
default: 20
|
||||||
type: number
|
type: number
|
||||||
subStops:
|
subStops:
|
||||||
description: not supported
|
description: parse & expose sub-stops of stations?
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
entrances:
|
entrances:
|
||||||
description: not supported
|
description: parse & expose entrances of stops/stations?
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
polylines:
|
polylines:
|
||||||
|
|
32
index.js
32
index.js
|
@ -181,9 +181,6 @@ const createClient = (profile, userAgent, opt = {}) => {
|
||||||
scheduledDays: false, // parse & expose dates each journey is valid on?
|
scheduledDays: false, // parse & expose dates each journey is valid on?
|
||||||
notOnlyFastRoutes: false, // if true, also show routes that are mathematically non-optimal
|
notOnlyFastRoutes: false, // if true, also show routes that are mathematically non-optimal
|
||||||
bestprice: false, // search for lowest prices across the entire day
|
bestprice: false, // search for lowest prices across the entire day
|
||||||
deutschlandTicketDiscount: false,
|
|
||||||
deutschlandTicketConnectionsOnly: false,
|
|
||||||
bmisNumber: null, // 7-digit BMIS number for business customer rates
|
|
||||||
}, opt);
|
}, opt);
|
||||||
|
|
||||||
if (opt.when !== undefined) {
|
if (opt.when !== undefined) {
|
||||||
|
@ -242,9 +239,6 @@ const createClient = (profile, userAgent, opt = {}) => {
|
||||||
entrances: true, // parse & expose entrances of stops/stations?
|
entrances: true, // parse & expose entrances of stops/stations?
|
||||||
remarks: true, // parse & expose hints & warnings?
|
remarks: true, // parse & expose hints & warnings?
|
||||||
scheduledDays: false, // parse & expose dates the journey is valid on?
|
scheduledDays: false, // parse & expose dates the journey is valid on?
|
||||||
deutschlandTicketDiscount: false,
|
|
||||||
deutschlandTicketConnectionsOnly: false,
|
|
||||||
bmisNumber: null, // 7-digit BMIS number for business customer rates
|
|
||||||
}, opt);
|
}, opt);
|
||||||
|
|
||||||
const req = profile.formatRefreshJourneyReq({profile, opt}, refreshToken);
|
const req = profile.formatRefreshJourneyReq({profile, opt}, refreshToken);
|
||||||
|
@ -397,33 +391,7 @@ const createClient = (profile, userAgent, opt = {}) => {
|
||||||
return client;
|
return client;
|
||||||
};
|
};
|
||||||
|
|
||||||
const createBusinessClient = (profile, userAgent, bmisNumber, opt = {}) => {
|
|
||||||
if (!bmisNumber || typeof bmisNumber !== 'string') {
|
|
||||||
throw new TypeError('bmisNumber must be a non-empty string');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a client with BMIS number included in all journey requests
|
|
||||||
const client = createClient(profile, userAgent, opt);
|
|
||||||
|
|
||||||
// Wrap journeys method to always include BMIS number
|
|
||||||
const originalJourneys = client.journeys;
|
|
||||||
client.journeys = async (from, to, opt = {}) => {
|
|
||||||
return originalJourneys(from, to, {...opt, bmisNumber});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Wrap refreshJourney method to always include BMIS number
|
|
||||||
if (client.refreshJourney) {
|
|
||||||
const originalRefreshJourney = client.refreshJourney;
|
|
||||||
client.refreshJourney = async (refreshToken, opt = {}) => {
|
|
||||||
return originalRefreshJourney(refreshToken, {...opt, bmisNumber});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return client;
|
|
||||||
};
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
createClient,
|
createClient,
|
||||||
createBusinessClient,
|
|
||||||
loadEnrichedStationData,
|
loadEnrichedStationData,
|
||||||
};
|
};
|
||||||
|
|
|
@ -76,18 +76,6 @@ const mapRouteParsers = (route, parsers) => {
|
||||||
default: false,
|
default: false,
|
||||||
parse: parseBoolean,
|
parse: parseBoolean,
|
||||||
},
|
},
|
||||||
deutschlandTicketDiscount: {
|
|
||||||
description: 'Calculate ticket prices assuming Deutschlandticket is present',
|
|
||||||
type: 'boolean',
|
|
||||||
default: false,
|
|
||||||
parse: parseBoolean,
|
|
||||||
},
|
|
||||||
deutschlandTicketConnectionsOnly: {
|
|
||||||
description: 'Only return journeys that can be used with the Deutschlandticket',
|
|
||||||
type: 'boolean',
|
|
||||||
default: false,
|
|
||||||
parse: parseBoolean,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (route.includes('departures') || route.includes('arrivals')) {
|
if (route.includes('departures') || route.includes('arrivals')) {
|
||||||
|
|
|
@ -105,6 +105,7 @@ const request = async (ctx, userAgent, reqData) => {
|
||||||
if (reqOptions.query) {
|
if (reqOptions.query) {
|
||||||
url += '?' + stringify(reqOptions.query, {arrayFormat: 'brackets', encodeValuesOnly: true});
|
url += '?' + stringify(reqOptions.query, {arrayFormat: 'brackets', encodeValuesOnly: true});
|
||||||
}
|
}
|
||||||
|
console.log(url);
|
||||||
const reqId = randomBytesHexString(6);
|
const reqId = randomBytesHexString(6);
|
||||||
const fetchReq = new Request(url, reqOptions);
|
const fetchReq = new Request(url, reqOptions);
|
||||||
profile.logRequest(ctx, fetchReq, reqId);
|
profile.logRequest(ctx, fetchReq, reqId);
|
||||||
|
@ -121,7 +122,6 @@ const request = async (ctx, userAgent, reqData) => {
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
// todo [breaking]: make this a FetchError or a HafasClientError?
|
// todo [breaking]: make this a FetchError or a HafasClientError?
|
||||||
console.log(JSON.stringify(res), await res.text());
|
|
||||||
const err = new Error(res.statusText);
|
const err = new Error(res.statusText);
|
||||||
Object.assign(err, errProps);
|
Object.assign(err, errProps);
|
||||||
throw err;
|
throw err;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import dbnavBase from '../dbnav/base.json' with { type: 'json' };
|
import dbnavBase from '../dbnav/base.json' with { type: 'json' };
|
||||||
|
import dbregioguideBase from '../dbregioguide/base.json' with { type: 'json' };
|
||||||
import {products} from '../../lib/products.js';
|
import {products} from '../../lib/products.js';
|
||||||
|
|
||||||
// journeys()
|
// journeys()
|
||||||
|
@ -25,11 +26,12 @@ const {nearbyEndpoint} = dbnavBase;
|
||||||
|
|
||||||
// trip()
|
// trip()
|
||||||
import {formatTripReq} from './trip-req.js';
|
import {formatTripReq} from './trip-req.js';
|
||||||
const {tripEndpoint} = dbnavBase;
|
const tripEndpoint_dbnav = dbnavBase.tripEndpoint;
|
||||||
|
const tripEndpoint_dbregioguide = dbregioguideBase.tripEndpoint;
|
||||||
|
|
||||||
// arrivals(), departures()
|
// arrivals(), departures()
|
||||||
import {formatStationBoardReq} from '../dbnav/station-board-req.js';
|
import {formatStationBoardReq} from '../dbregioguide/station-board-req.js';
|
||||||
const {boardEndpoint} = dbnavBase;
|
const {boardEndpoint} = dbregioguideBase;
|
||||||
|
|
||||||
const profile = {
|
const profile = {
|
||||||
locale: 'de-DE',
|
locale: 'de-DE',
|
||||||
|
@ -53,7 +55,7 @@ const profile = {
|
||||||
nearbyEndpoint,
|
nearbyEndpoint,
|
||||||
|
|
||||||
formatTripReq,
|
formatTripReq,
|
||||||
tripEndpoint,
|
tripEndpoint_dbnav, tripEndpoint_dbregioguide,
|
||||||
|
|
||||||
formatStationBoardReq,
|
formatStationBoardReq,
|
||||||
boardEndpoint,
|
boardEndpoint,
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
import {formatTripReq as hafasFormatTripReq} from '../dbnav/trip-req.js';
|
import {formatTripReq as hafasFormatTripReq} from '../dbnav/trip-req.js';
|
||||||
|
import {formatTripReq as risTripReq} from '../dbregioguide/trip-req.js';
|
||||||
|
|
||||||
|
|
||||||
const formatTripReq = ({profile, opt}, id) => {
|
const formatTripReq = ({profile, opt}, id) => {
|
||||||
const _profile = {...profile};
|
const _profile = {...profile};
|
||||||
_profile['tripEndpoint'] = profile.tripEndpoint;
|
if (id.includes('#')) {
|
||||||
return hafasFormatTripReq({profile: _profile, opt}, id);
|
_profile['tripEndpoint'] = profile.tripEndpoint_dbnav;
|
||||||
|
return hafasFormatTripReq({profile: _profile, opt}, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
_profile['tripEndpoint'] = profile.tripEndpoint_dbregioguide;
|
||||||
|
return risTripReq({profile: _profile, opt}, id);
|
||||||
};
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
|
@ -4,15 +4,11 @@ const formatBaseJourneysReq = (ctx) => {
|
||||||
// TODO opt.accessibility
|
// TODO opt.accessibility
|
||||||
// TODO routingMode
|
// TODO routingMode
|
||||||
const travellers = ctx.profile.formatTravellers(ctx);
|
const travellers = ctx.profile.formatTravellers(ctx);
|
||||||
const baseReq = {
|
return {
|
||||||
autonomeReservierung: false,
|
autonomeReservierung: false,
|
||||||
einstiegsTypList: [
|
einstiegsTypList: [
|
||||||
'STANDARD',
|
'STANDARD',
|
||||||
],
|
],
|
||||||
fahrverguenstigungen: {
|
|
||||||
deutschlandTicketVorhanden: ctx.opt.deutschlandTicketDiscount,
|
|
||||||
nurDeutschlandTicketVerbindungen: ctx.opt.deutschlandTicketConnectionsOnly,
|
|
||||||
},
|
|
||||||
klasse: travellers.klasse,
|
klasse: travellers.klasse,
|
||||||
reisendenProfil: {
|
reisendenProfil: {
|
||||||
reisende: travellers.reisende.map(t => {
|
reisende: travellers.reisende.map(t => {
|
||||||
|
@ -27,16 +23,6 @@ const formatBaseJourneysReq = (ctx) => {
|
||||||
},
|
},
|
||||||
reservierungsKontingenteVorhanden: false,
|
reservierungsKontingenteVorhanden: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add business customer affiliation if BMIS number is provided
|
|
||||||
if (ctx.opt.bmisNumber) {
|
|
||||||
baseReq.firmenZugehoerigkeit = {
|
|
||||||
bmisNr: ctx.opt.bmisNumber,
|
|
||||||
identifikationsart: 'BMIS',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return baseReq;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const formatJourneysReq = (ctx, from, to, when, outFrwd, journeysRef) => {
|
const formatJourneysReq = (ctx, from, to, when, outFrwd, journeysRef) => {
|
||||||
|
|
|
@ -15,7 +15,7 @@ const profile = {
|
||||||
journeysOutFrwd: false,
|
journeysOutFrwd: false,
|
||||||
departuresGetPasslist: false,
|
departuresGetPasslist: false,
|
||||||
departuresStbFltrEquiv: true,
|
departuresStbFltrEquiv: true,
|
||||||
trip: true,
|
trip: false,
|
||||||
radar: false,
|
radar: false,
|
||||||
refreshJourney: false,
|
refreshJourney: false,
|
||||||
journeysFromTrip: false,
|
journeysFromTrip: false,
|
||||||
|
|
|
@ -10,8 +10,8 @@ const formatJourneysReq = (ctx, from, to, when, outFrwd, journeysRef) => {
|
||||||
let query = {
|
let query = {
|
||||||
maxUmstiege: transfers,
|
maxUmstiege: transfers,
|
||||||
minUmstiegszeit: opt.transferTime,
|
minUmstiegszeit: opt.transferTime,
|
||||||
deutschlandTicketVorhanden: opt.deutschlandTicketDiscount,
|
deutschlandTicketVorhanden: false,
|
||||||
nurDeutschlandTicketVerbindungen: opt.deutschlandTicketConnectionsOnly,
|
nurDeutschlandTicketVerbindungen: false,
|
||||||
reservierungsKontingenteVorhanden: false,
|
reservierungsKontingenteVorhanden: false,
|
||||||
schnelleVerbindungen: !opt.notOnlyFastRoutes,
|
schnelleVerbindungen: !opt.notOnlyFastRoutes,
|
||||||
sitzplatzOnly: false,
|
sitzplatzOnly: false,
|
||||||
|
|
4
package-lock.json
generated
4
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "db-vendo-client",
|
"name": "db-vendo-client",
|
||||||
"version": "6.10.0",
|
"version": "6.8.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "db-vendo-client",
|
"name": "db-vendo-client",
|
||||||
"version": "6.10.0",
|
"version": "6.8.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"content-type": "^1.0.5",
|
"content-type": "^1.0.5",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "db-vendo-client",
|
"name": "db-vendo-client",
|
||||||
"description": "Client for bahn.de public transport APIs.",
|
"description": "Client for bahn.de public transport APIs.",
|
||||||
"version": "6.10.0",
|
"version": "6.8.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"files": [
|
"files": [
|
||||||
|
|
19
readme.md
19
readme.md
|
@ -27,21 +27,21 @@ Depending on the configured profile, db-vendo-client will use multiple different
|
||||||
| ------------- | ------------- | ------------- | ------------- | ------------- | ------------- |
|
| ------------- | ------------- | ------------- | ------------- | ------------- | ------------- |
|
||||||
| no API key required | ✅ | ✅ | ✅ | ✅ | ❌ |
|
| no API key required | ✅ | ✅ | ✅ | ✅ | ❌ |
|
||||||
| all above endpoints supported | ✅ | ✅ | except `stop()` | only boards | only boards |
|
| all above endpoints supported | ✅ | ✅ | except `stop()` | only boards | only boards |
|
||||||
| duration for boards | always 1h | always 1h | always 1h | up to 6h, only from current time | up to 12h |
|
| duration for boards | up to 12h | always 1h | always 1h | up to 6h, only from current time | up to 12h |
|
||||||
| remarks | for boards only most important remarks | for boards only most important remarks | all remarks on boards and journeys | most remarks | all remarks |
|
| remarks | not for boards | for boards only most important remarks | all remarks on boards and journeys | most remarks | all remarks |
|
||||||
| cancelled trips | contained with cancelled flag | contained with cancelled flag | contained with cancelled flag | contained with cancelled flag | contained with cancelled flag |
|
| cancelled trips | contained with cancelled flag in journeys, not contained in boards | contained with cancelled flag | contained with cancelled flag | contained with cancelled flag | contained with cancelled flag |
|
||||||
| tickets | only for `refreshJourney()`, mutually exclusive with polylines | only for `refreshJourney()`, mutually exclusive with polylines | only for `refreshJourney()`, mutually exclusive with polylines | ❌ | ❌ |
|
| tickets | only for `refreshJourney()`, mutually exclusive with polylines | only for `refreshJourney()`, mutually exclusive with polylines | only for `refreshJourney()`, mutually exclusive with polylines | ❌ | ❌ |
|
||||||
| polylines | only for `refreshJourney()/trip()`, mutually exclusive with tickets | only for `refreshJourney()/trip()`, mutually exclusive with tickets | only for `refreshJourney()/trip()`, mutually exclusive with tickets | ❌ | ❌ |
|
| polylines | only for `refreshJourney()` (mutually exclusive with tickets) and for `trip()` (only for HAFAS trip ids) | only for `refreshJourney()/trip()`, mutually exclusive with tickets | only for `refreshJourney()/trip()`, mutually exclusive with tickets | ❌ | ❌ |
|
||||||
| trip ids used | HAFAS trip ids | HAFAS trip ids | HAFAS trip ids | RIS trip ids | RIS trip ids |
|
| trip ids used | HAFAS trip ids for journeys, RIS trip ids for boards (static on train splits?) | HAFAS trip ids | HAFAS trip ids | RIS trip ids | RIS trip ids |
|
||||||
| line.id/fahrtNr used | actual fahrtNr for journeys, unreliable/route id for boards and `trip()` | actual fahrtNr for journeys, unreliable/route id for boards and `trip()` | unreliable/route id | unreliable/route id | ✅ |
|
| line.id/fahrtNr used | actual fahrtNr | actual fahrtNr for journeys, unreliable/route id for boards and `trip()` | unreliable/route id | unreliable/route id | ✅ |
|
||||||
| adminCode/operator | only for journeys | only for journeys | only operator | only adminCode | ✅ |
|
| adminCode/operator | ✅ | only for journeys | only operator | only adminCode | ✅ |
|
||||||
| stopovers | not in boards | not in boards | ✅ | some | ✅ |
|
| stopovers | not in boards | not in boards | ✅ | some | ✅ |
|
||||||
| assumed backend API stability | less stable | more stable | less stable | less stable | more stable |
|
| assumed backend API stability | less stable | more stable | less stable | less stable | more stable |
|
||||||
| quotas | 60 requests per minute (IPv4) | 60 requests per minute (IPv4) | aggressive blocking (IPv4/IPv6) | ? | depends on API key |
|
| quotas | 60 requests per minute for journeys, unknown for boards (IPv4) | 60 requests per minute (IPv4) | aggressive blocking (IPv4/IPv6) | ? | depends on API key |
|
||||||
|
|
||||||
|
|
||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
> If you think that for your project, quotas may become an issue, [consider alternative ways to obtain the data you need.](https://github.com/derhuerst/db-rest/blob/6/docs/readme.md#why-not-to-use-this-api), e.g. [motis-fptf-client](https://github.com/motis-project/motis-fptf-client) (a drop-in replacement for db-vendo-client/hafas-client) in conjunction with https://transitous.org or a self-hosted [MOTIS](https://github.com/motis-project/motis) instance.
|
> If you think that for your project, quotas may become an issue, [consider alternative ways to obtain the data you need.](https://github.com/derhuerst/db-rest/blob/6/docs/readme.md#why-not-to-use-this-api).
|
||||||
|
|
||||||
Feel free to report anything that you stumble upon via Issues or create a PR :)
|
Feel free to report anything that you stumble upon via Issues or create a PR :)
|
||||||
|
|
||||||
|
@ -92,7 +92,6 @@ There are [community-maintained TypeScript typings available as `@types/hafas-cl
|
||||||
- [hafas-client](https://github.com/public-transport/hafas-client/) – including further related projects
|
- [hafas-client](https://github.com/public-transport/hafas-client/) – including further related projects
|
||||||
- [hafas-rest-api](https://github.com/public-transport/hafas-rest-api/) – expose a hafas-client or db-vendo-client instance as a REST API
|
- [hafas-rest-api](https://github.com/public-transport/hafas-rest-api/) – expose a hafas-client or db-vendo-client instance as a REST API
|
||||||
- [db-rest](https://github.com/derhuerst/db-rest/) – for the legacy DB HAFAS endpoint
|
- [db-rest](https://github.com/derhuerst/db-rest/) – for the legacy DB HAFAS endpoint
|
||||||
- [motis-fptf-client](https://github.com/motis-project/motis-fptf-client) – a drop-in replacement for db-vendo-client/hafas-client wrapping a [MOTIS](https://github.com/motis-project/motis) instance
|
|
||||||
- [`*.transport.rest`](https://transport.rest/) – Public APIs wrapping some HAFAS endpoints.
|
- [`*.transport.rest`](https://transport.rest/) – Public APIs wrapping some HAFAS endpoints.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
|
@ -127,7 +127,7 @@ if (!process.env.VCR_OFF) {
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('refreshJourney – valid tickets', async (t) => {
|
tap.test('refreshJourney – valid tickets', async (t) => {
|
||||||
const T_MOCK = 1758279600 * 1000;
|
const T_MOCK = 1710831600 * 1000; // 2024-03-19T08:00:00+01:00
|
||||||
const when = createWhen(dbProfile.timezone, dbProfile.locale, T_MOCK);
|
const when = createWhen(dbProfile.timezone, dbProfile.locale, T_MOCK);
|
||||||
|
|
||||||
const journeysRes = await client.journeys(berlinHbf, münchenHbf, {
|
const journeysRes = await client.journeys(berlinHbf, münchenHbf, {
|
||||||
|
@ -261,7 +261,7 @@ if (!process.env.VCR_MODE) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tap.test('refreshJourney', async (t) => {
|
tap.test('refreshJourney', async (t) => {
|
||||||
const T_MOCK = 1763542800 * 1000;
|
const T_MOCK = 1710831600 * 1000; // 2024-03-19T08:00:00+01:00
|
||||||
const when = createWhen(dbProfile.timezone, dbProfile.locale, T_MOCK);
|
const when = createWhen(dbProfile.timezone, dbProfile.locale, T_MOCK);
|
||||||
const validate = createValidate({...cfg, when});
|
const validate = createValidate({...cfg, when});
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ tap.test('journeys – Berlin Schwedter Str. to München Hbf', async (t) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.test('refreshJourney – valid tickets', async (t) => {
|
tap.test('refreshJourney – valid tickets', async (t) => {
|
||||||
const T_MOCK = 1758279600 * 1000;
|
const T_MOCK = 1710831600 * 1000; // 2024-03-19T08:00:00+01:00
|
||||||
const when = createWhen(dbProfile.timezone, dbProfile.locale, T_MOCK);
|
const when = createWhen(dbProfile.timezone, dbProfile.locale, T_MOCK);
|
||||||
|
|
||||||
const journeysRes = await client.journeys(berlinHbf, münchenHbf, {
|
const journeysRes = await client.journeys(berlinHbf, münchenHbf, {
|
||||||
|
@ -261,7 +261,7 @@ if (!process.env.VCR_OFF) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tap.test('refreshJourney', async (t) => {
|
tap.test('refreshJourney', async (t) => {
|
||||||
const T_MOCK = 1763542800 * 1000;
|
const T_MOCK = 1710831600 * 1000; // 2024-03-19T08:00:00+01:00
|
||||||
const when = createWhen(dbProfile.timezone, dbProfile.locale, T_MOCK);
|
const when = createWhen(dbProfile.timezone, dbProfile.locale, T_MOCK);
|
||||||
const validate = createValidate({...cfg, when});
|
const validate = createValidate({...cfg, when});
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -38,10 +38,10 @@ tap.test('db trip(): dynamic request formatting', (t) => {
|
||||||
|
|
||||||
const reqDbNav = profile.formatTripReq(ctx, tripIdHafas);
|
const reqDbNav = profile.formatTripReq(ctx, tripIdHafas);
|
||||||
delete reqDbNav.headers['X-Correlation-ID'];
|
delete reqDbNav.headers['X-Correlation-ID'];
|
||||||
// const reqDbRegioGuide = profile.formatTripReq(ctx, tripIdRis);
|
const reqDbRegioGuide = profile.formatTripReq(ctx, tripIdRis);
|
||||||
|
|
||||||
t.same(reqDbNav, reqDbNavExpected);
|
t.same(reqDbNav, reqDbNavExpected);
|
||||||
// t.same(reqDbRegioGuide, reqDbRegioGuideExpected);
|
t.same(reqDbRegioGuide, reqDbRegioGuideExpected);
|
||||||
|
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
|
|
@ -41,10 +41,6 @@ const berlinWienQuery0 = Object.freeze(
|
||||||
einstiegsTypList: [
|
einstiegsTypList: [
|
||||||
'STANDARD',
|
'STANDARD',
|
||||||
],
|
],
|
||||||
fahrverguenstigungen: {
|
|
||||||
deutschlandTicketVorhanden: undefined,
|
|
||||||
nurDeutschlandTicketVerbindungen: undefined,
|
|
||||||
},
|
|
||||||
klasse: 'KLASSE_2',
|
klasse: 'KLASSE_2',
|
||||||
reiseHin: {
|
reiseHin: {
|
||||||
wunsch: {
|
wunsch: {
|
||||||
|
|
|
@ -57,8 +57,8 @@ const berlinWienQuery0 = Object.freeze(
|
||||||
sitzplatzOnly: false,
|
sitzplatzOnly: false,
|
||||||
bikeCarriage: false,
|
bikeCarriage: false,
|
||||||
reservierungsKontingenteVorhanden: false,
|
reservierungsKontingenteVorhanden: false,
|
||||||
nurDeutschlandTicketVerbindungen: undefined,
|
nurDeutschlandTicketVerbindungen: false,
|
||||||
deutschlandTicketVorhanden: undefined,
|
deutschlandTicketVorhanden: false,
|
||||||
maxUmstiege: null,
|
maxUmstiege: null,
|
||||||
zwischenhalte: null,
|
zwischenhalte: null,
|
||||||
minUmstiegszeit: 0,
|
minUmstiegszeit: 0,
|
||||||
|
|
Loading…
Add table
Reference in a new issue