mirror of
https://github.com/public-transport/db-vendo-client.git
synced 2025-02-22 22:59:35 +02:00
refactoring journeysReq
This commit is contained in:
parent
ec723b3414
commit
9f5e1fa6bd
3 changed files with 46 additions and 132 deletions
125
index.js
125
index.js
|
@ -120,9 +120,6 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
};
|
||||
|
||||
const journeys = async (from, to, opt = {}) => {
|
||||
from = profile.formatLocation(profile, from, 'from');
|
||||
to = profile.formatLocation(profile, to, 'to');
|
||||
|
||||
if ('earlierThan' in opt && 'laterThan' in opt) {
|
||||
throw new TypeError('opt.earlierThan and opt.laterThan are mutually exclusive.');
|
||||
}
|
||||
|
@ -168,9 +165,6 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
remarks: true, // parse & expose hints & warnings?
|
||||
scheduledDays: false, // parse & expose dates each journey is valid on?
|
||||
}, opt);
|
||||
if (opt.via) {
|
||||
opt.via = profile.formatLocation(profile, opt.via, 'opt.via');
|
||||
}
|
||||
|
||||
if (opt.when !== undefined) {
|
||||
throw new Error('opt.when is not supported anymore. Use opt.departure/opt.arrival.');
|
||||
|
@ -192,38 +186,7 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
outFrwd = false;
|
||||
}
|
||||
|
||||
const filters = profile.formatProductsFilter({profile}, opt.products || {});
|
||||
// TODO opt.accessibility
|
||||
|
||||
const query = {
|
||||
maxUmstiege: opt.transfers,
|
||||
minUmstiegszeit: opt.transferTime,
|
||||
deutschlandTicketVorhanden: false,
|
||||
nurDeutschlandTicketVerbindungen: false,
|
||||
reservierungsKontingenteVorhanden: false,
|
||||
schnelleVerbindungen: true,
|
||||
sitzplatzOnly: false,
|
||||
abfahrtsHalt: from.lid,
|
||||
zwischenhalte: opt.via
|
||||
? [{id: opt.via.lid}]
|
||||
: null,
|
||||
ankunftsHalt: to.lid,
|
||||
produktgattungen: filters,
|
||||
bikeCarriage: opt.bike,
|
||||
// TODO
|
||||
// todo: this is actually "take additional stations nearby the given start and destination station into account"
|
||||
// see rest.exe docs
|
||||
// ushrp: Boolean(opt.startWithWalking),
|
||||
};
|
||||
query.anfrageZeitpunkt = profile.formatTime(profile, when);
|
||||
if (journeysRef) {
|
||||
query.pagingReference = journeysRef;
|
||||
}
|
||||
query.ankunftSuche = outFrwd ? 'ABFAHRT' : 'ANKUNFT';
|
||||
if (opt.results !== null) {
|
||||
// TODO query.numF = opt.results;
|
||||
}
|
||||
const req = profile.formatJourneysReq({profile, opt}, query);
|
||||
const req = profile.formatJourneysReq({profile, opt}, from, to, when, outFrwd, journeysRef);
|
||||
const {res} = await profile.request({profile, opt}, userAgent, req);
|
||||
const ctx = {profile, opt, common, res};
|
||||
const verbindungen = opt.results ? res.verbindungen.slice(0, opt.results) : res.verbindungen;
|
||||
|
@ -373,90 +336,8 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
};
|
||||
|
||||
// todo [breaking]: rename to trips()?
|
||||
const tripsByName = async (lineNameOrFahrtNr = '*', opt = {}) => {
|
||||
if (!isNonEmptyString(lineNameOrFahrtNr)) {
|
||||
throw new TypeError('lineNameOrFahrtNr must be a non-empty string.');
|
||||
}
|
||||
opt = Object.assign({
|
||||
when: null,
|
||||
fromWhen: null, untilWhen: null,
|
||||
onlyCurrentlyRunning: true,
|
||||
products: {},
|
||||
currentlyStoppingAt: null,
|
||||
lineName: null,
|
||||
operatorNames: null,
|
||||
additionalFilters: [], // undocumented
|
||||
}, opt);
|
||||
|
||||
const req = {
|
||||
// fields: https://github.com/marudor/BahnhofsAbfahrten/blob/f619e754f212980261eb7e2b151cd73ba0213da8/packages/types/HAFAS/JourneyMatch.ts#L4-L23
|
||||
input: lineNameOrFahrtNr,
|
||||
onlyCR: opt.onlyCurrentlyRunning,
|
||||
jnyFltrL: [
|
||||
profile.formatProductsFilter({profile}, opt.products),
|
||||
],
|
||||
// todo: passing `tripId` yields a `CGI_READ_FAILED` error
|
||||
// todo: passing a stop ID as `extId` yields a `PARAMETER` error
|
||||
// todo: `onlyRT: true` reduces the number of results, but filters recent trips 🤔
|
||||
// todo: `onlyTN: true` yields a `NO_MATCH` error
|
||||
// todo: useAeqi
|
||||
};
|
||||
if (opt.when !== null) {
|
||||
req.date = profile.formatDate(profile, new Date(opt.when));
|
||||
req.time = profile.formatTime(profile, new Date(opt.when));
|
||||
}
|
||||
// todo: fromWhen doesn't work yet, but untilWhen does
|
||||
if (opt.fromWhen !== null) {
|
||||
req.dateB = profile.formatDate(profile, new Date(opt.fromWhen));
|
||||
req.timeB = profile.formatTime(profile, new Date(opt.fromWhen));
|
||||
}
|
||||
if (opt.untilWhen !== null) {
|
||||
req.dateE = profile.formatDate(profile, new Date(opt.untilWhen));
|
||||
req.timeE = profile.formatTime(profile, new Date(opt.untilWhen));
|
||||
}
|
||||
const filter = (mode, type, value) => ({mode, type, value});
|
||||
if (opt.currentlyStoppingAt !== null) {
|
||||
if (!isNonEmptyString(opt.currentlyStoppingAt)) {
|
||||
throw new TypeError('opt.currentlyStoppingAt must be a non-empty string.');
|
||||
}
|
||||
req.jnyFltrL.push(filter('INC', 'STATIONS', opt.currentlyStoppingAt));
|
||||
}
|
||||
if (opt.lineName !== null) {
|
||||
if (!isNonEmptyString(opt.lineName)) {
|
||||
throw new TypeError('opt.lineName must be a non-empty string.');
|
||||
}
|
||||
// todo: does this target `line` or `lineId`?
|
||||
req.jnyFltrL.push(filter('INC', 'LINE', opt.lineName));
|
||||
}
|
||||
if (opt.operatorNames !== null) {
|
||||
if (
|
||||
!Array.isArray(opt.operatorNames)
|
||||
|| opt.operatorNames.length === 0
|
||||
|| !opt.operatorNames.every(isNonEmptyString)
|
||||
) {
|
||||
throw new TypeError('opt.operatorNames must be an array of non-empty strings.');
|
||||
}
|
||||
// todo: is the an escaping mechanism for ","
|
||||
req.jnyFltrL.push(filter('INC', 'OP', opt.operatorNames.join(',')));
|
||||
}
|
||||
req.jnyFltrL = [...req.jnyFltrL, ...opt.additionalFilters];
|
||||
|
||||
const {res} = await profile.request({profile, opt}, userAgent, {
|
||||
cfg: {polyEnc: 'GPA'},
|
||||
meth: 'JourneyMatch',
|
||||
req,
|
||||
});
|
||||
// todo [breaking]: catch `NO_MATCH` errors, return []
|
||||
const ctx = {profile, opt, common, res};
|
||||
|
||||
const trips = res.jnyL.map(t => profile.parseTrip(ctx, t));
|
||||
|
||||
return {
|
||||
trips,
|
||||
realtimeDataUpdatedAt: res.planrtTS && res.planrtTS !== '0'
|
||||
? parseInt(res.planrtTS)
|
||||
: null,
|
||||
};
|
||||
const tripsByName = async (_lineNameOrFahrtNr = '*', _opt = {}) => {
|
||||
throw new Error('not implemented');
|
||||
};
|
||||
|
||||
const client = {
|
||||
|
|
|
@ -1,4 +1,39 @@
|
|||
const formatJourneysReq = (ctx, query) => {
|
||||
const formatJourneysReq = (ctx, from, to, when, outFrwd, journeysRef) => {
|
||||
const {profile, opt} = ctx;
|
||||
|
||||
from = profile.formatLocation(profile, from, 'from');
|
||||
to = profile.formatLocation(profile, to, 'to');
|
||||
const filters = profile.formatProductsFilter({profile}, opt.products || {});
|
||||
// TODO opt.accessibility
|
||||
|
||||
let query = {
|
||||
maxUmstiege: opt.transfers,
|
||||
minUmstiegszeit: opt.transferTime,
|
||||
deutschlandTicketVorhanden: false,
|
||||
nurDeutschlandTicketVerbindungen: false,
|
||||
reservierungsKontingenteVorhanden: false,
|
||||
schnelleVerbindungen: true,
|
||||
sitzplatzOnly: false,
|
||||
abfahrtsHalt: from.lid,
|
||||
zwischenhalte: opt.via
|
||||
? [{id: profile.formatLocation(profile, opt.via, 'opt.via').lid}]
|
||||
: null,
|
||||
ankunftsHalt: to.lid,
|
||||
produktgattungen: filters,
|
||||
bikeCarriage: opt.bike,
|
||||
// TODO
|
||||
// todo: this is actually "take additional stations nearby the given start and destination station into account"
|
||||
// see rest.exe docs
|
||||
// ushrp: Boolean(opt.startWithWalking),
|
||||
};
|
||||
query.anfrageZeitpunkt = profile.formatTime(profile, when);
|
||||
if (journeysRef) {
|
||||
query.pagingReference = journeysRef;
|
||||
}
|
||||
query.ankunftSuche = outFrwd ? 'ABFAHRT' : 'ANKUNFT';
|
||||
if (opt.results !== null) {
|
||||
// TODO query.numF = opt.results;
|
||||
}
|
||||
query = Object.assign(query, ctx.profile.formatTravellers(ctx));
|
||||
return {
|
||||
endpoint: ctx.profile.journeysEndpoint,
|
||||
|
|
|
@ -11,8 +11,8 @@ const opt = {
|
|||
results: null,
|
||||
via: null,
|
||||
stopovers: false,
|
||||
transfers: -1,
|
||||
transferTime: 0,
|
||||
transfers: null,
|
||||
transferTime: 0,
|
||||
accessibility: 'none',
|
||||
bike: false,
|
||||
walkingSpeed: 'normal',
|
||||
|
@ -59,6 +59,9 @@ const berlinWienQuery0 = Object.freeze(
|
|||
reservierungsKontingenteVorhanden: false,
|
||||
nurDeutschlandTicketVerbindungen: false,
|
||||
deutschlandTicketVorhanden: false,
|
||||
maxUmstiege: null,
|
||||
zwischenhalte: null,
|
||||
minUmstiegszeit: 0,
|
||||
});
|
||||
|
||||
tap.test('formats a journeys() request correctly (DB)', (t) => {
|
||||
|
@ -67,10 +70,7 @@ tap.test('formats a journeys() request correctly (DB)', (t) => {
|
|||
delete _opt.age;
|
||||
const ctx = {profile, opt: _opt};
|
||||
|
||||
// transformJourneysQuery() mutates its 2nd argument!
|
||||
const query = {...berlinWienQuery0};
|
||||
const req = profile.formatJourneysReq(ctx, query);
|
||||
|
||||
const req = profile.formatJourneysReq(ctx, '8098160', '8000284', new Date('2024-12-07T23:50:12+01:00'), true, null);
|
||||
t.same(req.body, {
|
||||
...berlinWienQuery0,
|
||||
reisende: [
|
||||
|
@ -94,9 +94,7 @@ tap.test('formats a journeys() request correctly (DB)', (t) => {
|
|||
tap.test('formats a journeys() request with BC correctly (DB)', (t) => {
|
||||
const ctx = {profile, opt};
|
||||
|
||||
// transformJourneysQuery() mutates its 2nd argument!
|
||||
const query = {...berlinWienQuery0};
|
||||
const req = profile.formatJourneysReq(ctx, query);
|
||||
const req = profile.formatJourneysReq(ctx, '8098160', '8000284', new Date('2024-12-07T23:50:12+01:00'), true, null);
|
||||
|
||||
t.same(req.body, {
|
||||
...berlinWienQuery0,
|
||||
|
|
Loading…
Add table
Reference in a new issue