From 252ce5b515aa0d4f2d18dad4d2e8ea330a5d25f1 Mon Sep 17 00:00:00 2001 From: Jannis R Date: Sun, 20 Oct 2019 01:47:09 +0200 Subject: [PATCH] lib/request, index: use ctx object :boom: --- index.js | 116 ++++++++++++++++++++++------------------- lib/default-profile.js | 2 +- lib/request.js | 16 ++++-- 3 files changed, 73 insertions(+), 61 deletions(-) diff --git a/index.js b/index.js index 5b67e14b..1b2514b8 100644 --- a/index.js +++ b/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 diff --git a/lib/default-profile.js b/lib/default-profile.js index cf2b40ea..9d501cf5 100644 --- a/lib/default-profile.js +++ b/lib/default-profile.js @@ -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, diff --git a/lib/request.js b/lib/request.js index 8b3cd4d8..b6fbff06 100644 --- a/lib/request.js +++ b/lib/request.js @@ -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}) + } }) }