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