mirror of
https://github.com/public-transport/db-vendo-client.git
synced 2025-02-22 22:59:35 +02:00
lib/request, index: use ctx object 💥
This commit is contained in:
parent
fb7a5653e3
commit
252ce5b515
3 changed files with 73 additions and 61 deletions
116
index.js
116
index.js
|
@ -44,7 +44,7 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
request
|
||||
} = Object.assign({}, defaults, opt)
|
||||
|
||||
const _stationBoard = (station, type, parser, opt = {}) => {
|
||||
const _stationBoard = (station, type, parse, opt = {}) => {
|
||||
if (isObj(station)) station = profile.formatStation(station.id)
|
||||
else if ('string' === typeof station) station = profile.formatStation(station)
|
||||
else throw new TypeError('station must be an object or a string.')
|
||||
|
@ -87,15 +87,17 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
}
|
||||
if (profile.departuresGetPasslist) req.getPasslist = !!opt.stopovers
|
||||
if (profile.departuresStbFltrEquiv) req.stbFltrEquiv = !opt.includeRelatedStations
|
||||
return request(profile, userAgent, opt, {
|
||||
|
||||
return request({profile, opt}, userAgent, {
|
||||
meth: 'StationBoard',
|
||||
req
|
||||
})
|
||||
.then((d) => {
|
||||
if (!Array.isArray(d.jnyL)) return []
|
||||
const parse = parser(profile, opt, d)
|
||||
return d.jnyL.map(parse)
|
||||
.sort((a, b) => new Date(a.when) - new Date(b.when))
|
||||
.then(({res, common}) => {
|
||||
if (!Array.isArray(res.jnyL)) return []
|
||||
|
||||
const ctx = {profile, opt, common, res}
|
||||
return res.jnyL.map(res => parse(ctx, res))
|
||||
.sort((a, b) => new Date(a.when) - new Date(b.when)) // todo
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -228,35 +230,35 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
if (profile.journeysNumF && opt.results !== null) query.numF = opt.results
|
||||
if (profile.journeysOutFrwd) query.outFrwd = outFrwd
|
||||
|
||||
return request(profile, userAgent, opt, {
|
||||
return request({profile, opt}, userAgent, {
|
||||
cfg: {polyEnc: 'GPA'},
|
||||
meth: 'TripSearch',
|
||||
req: profile.transformJourneysQuery(query, opt)
|
||||
req: profile.transformJourneysQuery({profile, opt}, query)
|
||||
})
|
||||
.then((d) => {
|
||||
if (!Array.isArray(d.outConL)) return []
|
||||
.then(({res, common}) => {
|
||||
if (!Array.isArray(res.outConL)) return []
|
||||
// todo: outConGrpL
|
||||
|
||||
const parse = profile.parseJourney(profile, opt, d)
|
||||
const ctx = {profile, opt, common, res}
|
||||
|
||||
if (!earlierRef) earlierRef = d.outCtxScrB
|
||||
if (!earlierRef) earlierRef = res.outCtxScrB
|
||||
|
||||
let latestDep = -Infinity
|
||||
for (let j of d.outConL) {
|
||||
j = parse(j)
|
||||
journeys.push(j)
|
||||
for (const rawJourney of res.outConL) {
|
||||
const journey = profile.parseJourney(ctx, rawJourney)
|
||||
journeys.push(journey)
|
||||
|
||||
if (opt.results !== null && journeys.length >= opt.results) { // collected enough
|
||||
laterRef = d.outCtxScrF
|
||||
laterRef = res.outCtxScrF
|
||||
return {earlierRef, laterRef, journeys}
|
||||
}
|
||||
const dep = +new Date(j.legs[0].departure)
|
||||
const dep = +new Date(journey.legs[0].departure) // todo
|
||||
if (dep > latestDep) latestDep = dep
|
||||
}
|
||||
|
||||
if (opt.results === null) return {earlierRef, laterRef, journeys}
|
||||
const when = new Date(latestDep)
|
||||
return more(when, d.outCtxScrF) // otherwise continue
|
||||
return more(when, res.outCtxScrF) // otherwise continue
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -275,7 +277,7 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
remarks: true // parse & expose hints & warnings?
|
||||
}, opt)
|
||||
|
||||
return request(profile, userAgent, opt, {
|
||||
return request({profile, opt}, userAgent, {
|
||||
meth: 'Reconstruction',
|
||||
req: {
|
||||
ctxRecon: refreshToken,
|
||||
|
@ -285,13 +287,13 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
getTariff: !!opt.tickets
|
||||
}
|
||||
})
|
||||
.then((d) => {
|
||||
if (!Array.isArray(d.outConL) || !d.outConL[0]) {
|
||||
.then(({res, common}) => {
|
||||
if (!Array.isArray(res.outConL) || !res.outConL[0]) {
|
||||
throw new Error('invalid response')
|
||||
}
|
||||
|
||||
const parse = profile.parseJourney(profile, opt, d)
|
||||
return parse(d.outConL[0])
|
||||
const ctx = {profile, opt, common, res}
|
||||
return profile.parseJourney(ctx, res.outConL[0])
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -309,7 +311,7 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
}, opt)
|
||||
|
||||
const f = profile.formatLocationFilter(opt.stops, opt.addresses, opt.poi)
|
||||
return request(profile, userAgent, opt, {
|
||||
return request({profile, opt}, userAgent, {
|
||||
cfg: {polyEnc: 'GPA'},
|
||||
meth: 'LocMatch',
|
||||
req: {input: {
|
||||
|
@ -321,10 +323,11 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
field: 'S' // todo: what is this?
|
||||
}}
|
||||
})
|
||||
.then((d) => {
|
||||
if (!d.match || !Array.isArray(d.match.locL)) return []
|
||||
const parse = profile.parseLocation
|
||||
return d.match.locL.map(loc => parse(profile, opt, d, loc))
|
||||
.then(({res, common}) => {
|
||||
if (!res.match || !Array.isArray(res.match.locL)) return []
|
||||
|
||||
const ctx = {profile, opt, common, res}
|
||||
return res.match.locL.map(loc => profile.parseLocation(ctx, loc))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -336,18 +339,20 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
opt = Object.assign({
|
||||
linesOfStops: false // parse & expose lines at the stop/station?
|
||||
}, opt)
|
||||
return request(profile, userAgent, opt, {
|
||||
return request({profile, opt}, userAgent, {
|
||||
meth: 'LocDetails',
|
||||
req: {
|
||||
locL: [stop]
|
||||
}
|
||||
})
|
||||
.then((d) => {
|
||||
if (!d || !Array.isArray(d.locL) || !d.locL[0]) {
|
||||
.then(({res, common}) => {
|
||||
if (!res || !Array.isArray(res.locL) || !res.locL[0]) {
|
||||
// todo: proper stack trace?
|
||||
throw new Error('invalid response')
|
||||
}
|
||||
return profile.parseLocation(profile, opt, d, d.locL[0])
|
||||
|
||||
const ctx = {profile, opt, res, common}
|
||||
return profile.parseLocation(ctx, res.locL[0])
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -362,7 +367,7 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
linesOfStops: false // parse & expose lines at each stop/station?
|
||||
}, opt)
|
||||
|
||||
return request(profile, userAgent, opt, {
|
||||
return request({profile, opt}, userAgent, {
|
||||
cfg: {polyEnc: 'GPA'},
|
||||
meth: 'LocGeoPos',
|
||||
req: {
|
||||
|
@ -379,10 +384,11 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
maxLoc: opt.results
|
||||
}
|
||||
})
|
||||
.then((d) => {
|
||||
if (!Array.isArray(d.locL)) return []
|
||||
const parse = profile.parseNearby
|
||||
return d.locL.map(loc => parse(profile, opt, d, loc))
|
||||
.then(({common, res}) => {
|
||||
if (!Array.isArray(res.locL)) return []
|
||||
|
||||
const ctx = {profile, opt, common, res}
|
||||
return res.locL.map(loc => profile.parseNearby(ctx, loc))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -399,7 +405,7 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
remarks: true // parse & expose hints & warnings?
|
||||
}, opt)
|
||||
|
||||
return request(profile, userAgent, opt, {
|
||||
return request({profile, opt}, userAgent, {
|
||||
cfg: {polyEnc: 'GPA'},
|
||||
meth: 'JourneyDetails',
|
||||
req: {
|
||||
|
@ -412,16 +418,16 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
getPolyline: !!opt.polyline
|
||||
}
|
||||
})
|
||||
.then((d) => {
|
||||
const parse = profile.parseJourneyLeg(profile, opt, d)
|
||||
.then(({common, res}) => {
|
||||
const ctx = {profile, opt, common, res}
|
||||
|
||||
const rawLeg = { // pretend the leg is contained in a journey
|
||||
type: 'JNY',
|
||||
dep: minBy(d.journey.stopL, 'idx'),
|
||||
arr: maxBy(d.journey.stopL, 'idx'),
|
||||
jny: d.journey
|
||||
dep: minBy(res.journey.stopL, 'idx'),
|
||||
arr: maxBy(res.journey.stopL, 'idx'),
|
||||
jny: res.journey
|
||||
}
|
||||
const trip = parse(d.journey, rawLeg, !!opt.stopovers)
|
||||
const trip = profile.parseJourneyLeg(ctx, rawLeg, res.journey.date)
|
||||
trip.id = trip.tripId
|
||||
delete trip.tripId
|
||||
return trip
|
||||
|
@ -448,7 +454,7 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
if (Number.isNaN(+opt.when)) throw new TypeError('opt.when is invalid')
|
||||
|
||||
const durationPerStep = opt.duration / Math.max(opt.frames, 1) * 1000
|
||||
return request(profile, userAgent, opt, {
|
||||
return request({profile, opt}, userAgent, {
|
||||
meth: 'JourneyGeoPos',
|
||||
req: {
|
||||
maxJny: opt.results,
|
||||
|
@ -466,11 +472,11 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
trainPosMode: 'CALC' // todo: what is this? what about realtime?
|
||||
}
|
||||
})
|
||||
.then((d) => {
|
||||
if (!Array.isArray(d.jnyL) || d.jnyL.length === 0) return []
|
||||
.then(({res, common}) => {
|
||||
if (!Array.isArray(res.jnyL)) return []
|
||||
|
||||
const parse = profile.parseMovement(profile, opt, d)
|
||||
return d.jnyL.map(parse)
|
||||
const ctx = {profile, opt, common, res}
|
||||
return res.jnyL.map(m => profile.parseMovement(ctx, m))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -486,7 +492,7 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
if (Number.isNaN(+opt.when)) throw new TypeError('opt.when is invalid')
|
||||
|
||||
const refetch = () => {
|
||||
return request(profile, userAgent, opt, {
|
||||
return request({profile, opt}, userAgent, {
|
||||
meth: 'LocGeoReach',
|
||||
req: {
|
||||
loc: profile.formatLocation(profile, address, 'address'),
|
||||
|
@ -500,8 +506,8 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
]
|
||||
}
|
||||
})
|
||||
.then((d) => {
|
||||
if (!Array.isArray(d.posL)) {
|
||||
.then(({res, common}) => {
|
||||
if (!Array.isArray(res.posL)) {
|
||||
const err = new Error('invalid response')
|
||||
err.shouldRetry = true
|
||||
throw err
|
||||
|
@ -509,8 +515,8 @@ const createClient = (profile, userAgent, opt = {}) => {
|
|||
|
||||
const byDuration = []
|
||||
let i = 0, lastDuration = NaN
|
||||
for (const pos of sortBy(d.posL, 'dur')) {
|
||||
const loc = d.locations[pos.locX]
|
||||
for (const pos of sortBy(res.posL, 'dur')) {
|
||||
const loc = common.locations[pos.locX]
|
||||
if (!loc) continue
|
||||
if (pos.dur !== lastDuration) {
|
||||
lastDuration = pos.dur
|
||||
|
|
|
@ -31,7 +31,7 @@ const formatLocation = require('../format/location')
|
|||
const formatRectangle = require('../format/rectangle')
|
||||
const filters = require('../format/filters')
|
||||
|
||||
const id = x => x
|
||||
const id = (ctx, x) => x
|
||||
|
||||
const defaultProfile = {
|
||||
salt: null,
|
||||
|
|
|
@ -30,14 +30,16 @@ const addErrorInfo = (err, errorCode, errorText) => {
|
|||
}
|
||||
}
|
||||
|
||||
const request = (profile, userAgent, opt, data) => {
|
||||
const body = profile.transformReqBody({
|
||||
const request = (ctx, userAgent, reqData) => {
|
||||
const {profile, opt} = ctx
|
||||
|
||||
const body = profile.transformReqBody(ctx, {
|
||||
lang: opt.language || 'en', // todo: is it `eng` actually?
|
||||
svcReqL: [data]
|
||||
svcReqL: [reqData]
|
||||
})
|
||||
if (DEBUG) console.error(JSON.stringify(body))
|
||||
|
||||
const req = profile.transformReq({
|
||||
const req = profile.transformReq(ctx, {
|
||||
method: 'post',
|
||||
// todo: CORS? referrer policy?
|
||||
body: JSON.stringify(body),
|
||||
|
@ -106,7 +108,11 @@ const request = (profile, userAgent, opt, data) => {
|
|||
throw err
|
||||
}
|
||||
|
||||
return profile.parseCommon(profile, opt, b.svcResL[0].res)
|
||||
const res = b.svcResL[0].res
|
||||
return {
|
||||
res,
|
||||
common: profile.parseCommon({...ctx, res})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue