/journeys: expose loyaltyCard and firstClass, rebuild API docs ✅📝
fixes #9 closes #23
This commit is contained in:
parent
622fcfbf70
commit
666c84b5f7
5 changed files with 93 additions and 3 deletions
19
api.js
19
api.js
|
@ -8,7 +8,9 @@ const withCache = require('cached-hafas-client')
|
||||||
const redisStore = require('cached-hafas-client/stores/redis')
|
const redisStore = require('cached-hafas-client/stores/redis')
|
||||||
const {join: pathJoin} = require('path')
|
const {join: pathJoin} = require('path')
|
||||||
const serveStatic = require('serve-static')
|
const serveStatic = require('serve-static')
|
||||||
|
const {parseBoolean} = require('hafas-rest-api/lib/parse')
|
||||||
const pkg = require('./package.json')
|
const pkg = require('./package.json')
|
||||||
|
const {loyaltyCardParser} = require('./lib/loyalty-cards')
|
||||||
const stations = require('./routes/stations')
|
const stations = require('./routes/stations')
|
||||||
const station = require('./routes/station')
|
const station = require('./routes/station')
|
||||||
|
|
||||||
|
@ -41,7 +43,21 @@ if (process.env.REDIS_URL) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const modifyRoutes = (routes) => {
|
const mapRouteParsers = (route, parsers) => {
|
||||||
|
if (route !== 'journeys') return parsers
|
||||||
|
return {
|
||||||
|
...parsers,
|
||||||
|
loyaltyCard: loyaltyCardParser,
|
||||||
|
firstClass: {
|
||||||
|
description: 'Search for first-class options?',
|
||||||
|
type: 'boolean',
|
||||||
|
default: 'false',
|
||||||
|
parse: parseBoolean,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const modifyRoutes = (routes, hafas, config) => {
|
||||||
routes['/stations/:id'] = station
|
routes['/stations/:id'] = station
|
||||||
routes['/stations'] = stations
|
routes['/stations'] = stations
|
||||||
return routes
|
return routes
|
||||||
|
@ -61,6 +77,7 @@ const config = {
|
||||||
etags: 'strong',
|
etags: 'strong',
|
||||||
csp: `default-src 'none' style-src 'self' 'unsafe-inline' img-src https:`,
|
csp: `default-src 'none' style-src 'self' 'unsafe-inline' img-src https:`,
|
||||||
healthCheck,
|
healthCheck,
|
||||||
|
mapRouteParsers,
|
||||||
modifyRoutes,
|
modifyRoutes,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -381,6 +381,8 @@ parameter | description | type | default value
|
||||||
`remarks` | Parse & return hints & warnings? | boolean | `true`
|
`remarks` | Parse & return hints & warnings? | boolean | `true`
|
||||||
`scheduledDays` | Parse & return dates each journey is valid on? | boolean | `false`
|
`scheduledDays` | Parse & return dates each journey is valid on? | boolean | `false`
|
||||||
`language` | Language of the results. | string | `en`
|
`language` | Language of the results. | string | `en`
|
||||||
|
`loyaltyCard` | Type of loyalty card in use. See https://github.com/public-transport/hafas-client/blob/68ecd7c5e976dd2f51c5c64a81600e7e181a8996/p/db/loyalty-cards.js#L6-L11. | string | *none*
|
||||||
|
`firstClass` | Search for first-class options? | boolean | `false`
|
||||||
`nationalExpress` | Include InterCityExpress (ICE)? | boolean | `true`
|
`nationalExpress` | Include InterCityExpress (ICE)? | boolean | `true`
|
||||||
`national` | Include InterCity & EuroCity (IC/EC)? | boolean | `true`
|
`national` | Include InterCity & EuroCity (IC/EC)? | boolean | `true`
|
||||||
`regionalExp` | Include RegionalExpress & InterRegio (RE/IR)? | boolean | `true`
|
`regionalExp` | Include RegionalExpress & InterRegio (RE/IR)? | boolean | `true`
|
||||||
|
|
36
lib/loyalty-cards.js
Normal file
36
lib/loyalty-cards.js
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
const {data: cards} = require('hafas-client/p/db/loyalty-cards')
|
||||||
|
|
||||||
|
const DOCS_URL = 'https://github.com/public-transport/hafas-client/blob/68ecd7c5e976dd2f51c5c64a81600e7e181a8996/p/db/loyalty-cards.js#L6-L11'
|
||||||
|
|
||||||
|
const typesByName = new Map([
|
||||||
|
['bahncard-1st-25', {type: cards.BAHNCARD, discount: 25, class: 1}],
|
||||||
|
['bahncard-2nd-25', {type: cards.BAHNCARD, discount: 25, class: 2}],
|
||||||
|
['bahncard-1st-50', {type: cards.BAHNCARD, discount: 50, class: 1}],
|
||||||
|
['bahncard-2nd-50', {type: cards.BAHNCARD, discount: 50, class: 2}],
|
||||||
|
['vorteilscard', {type: cards.VORTEILSCARD}],
|
||||||
|
['halbtaxabo-railplus', {type: cards.HALBTAXABO, railplus: true}],
|
||||||
|
['halbtaxabo', {type: cards.HALBTAXABO, railplus: false}],
|
||||||
|
['voordeelurenabo-railplus', {type: cards.VOORDEELURENABO, railplus: true}],
|
||||||
|
['voordeelurenabo', {type: cards.VOORDEELURENABO, railplus: false}],
|
||||||
|
['shcard', {type: cards.SHCARD}],
|
||||||
|
['generalabonnement', {type: cards.GENERALABONNEMENT}],
|
||||||
|
])
|
||||||
|
const types = Array.from(typesByName.keys())
|
||||||
|
|
||||||
|
const parseLoyaltyCard = (key, val) => {
|
||||||
|
if (typesByName.has(val)) return typesByName.get(val)
|
||||||
|
throw new Error(key + ' must be one of ' + types.join(', '))
|
||||||
|
}
|
||||||
|
|
||||||
|
const loyaltyCardParser = {
|
||||||
|
description: `Type of loyalty card in use. See ${DOCS_URL}.`,
|
||||||
|
type: 'string',
|
||||||
|
enum: types,
|
||||||
|
defaultStr: '*none*',
|
||||||
|
parse: parseLoyaltyCard,
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
parseLoyaltyCard,
|
||||||
|
loyaltyCardParser,
|
||||||
|
}
|
|
@ -29,7 +29,7 @@
|
||||||
"db-stations-autocomplete": "^2.2.0",
|
"db-stations-autocomplete": "^2.2.0",
|
||||||
"etag": "^1.8.1",
|
"etag": "^1.8.1",
|
||||||
"hafas-client-health-check": "^2.1.1",
|
"hafas-client-health-check": "^2.1.1",
|
||||||
"hafas-rest-api": "^3.7.0",
|
"hafas-rest-api": "^3.8.0",
|
||||||
"ioredis": "^4.28.1",
|
"ioredis": "^4.28.1",
|
||||||
"serve-buffer": "^2.0.0",
|
"serve-buffer": "^2.0.0",
|
||||||
"serve-static": "^1.14.1"
|
"serve-static": "^1.14.1"
|
||||||
|
|
|
@ -1,6 +1,41 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const tape = require('tape')
|
const tape = require('tape')
|
||||||
|
const {loyaltyCards} = require('../lib/loyalty-cards')
|
||||||
const {fetchWithTestApi} = require('./util')
|
const {fetchWithTestApi} = require('./util')
|
||||||
|
|
||||||
// todo
|
const NO_JOURNEYS = {
|
||||||
|
// todo?
|
||||||
|
journeys: [],
|
||||||
|
}
|
||||||
|
|
||||||
|
tape.test('/journeys?firstClass works', async (t) => {
|
||||||
|
await fetchWithTestApi({
|
||||||
|
journeys: async (from, to, opt = {}) => {
|
||||||
|
t.equal(opt.firstClass, true, 'journeys() called with invalid opt.firstClass')
|
||||||
|
return NO_JOURNEYS
|
||||||
|
}
|
||||||
|
}, {}, '/journeys?from=123&to=234&firstClass=true')
|
||||||
|
})
|
||||||
|
|
||||||
|
tape.test('/journeys?loyaltyCard works', async (t) => {
|
||||||
|
await fetchWithTestApi({
|
||||||
|
journeys: async (from, to, opt = {}) => {
|
||||||
|
t.deepEqual(opt.loyaltyCard, {
|
||||||
|
type: loyaltyCards.SHCARD,
|
||||||
|
}, 'journeys() called with invalid opt.loyaltyCard')
|
||||||
|
return NO_JOURNEYS
|
||||||
|
}
|
||||||
|
}, {}, '/journeys?from=123&to=234&loyaltyCard=shcard')
|
||||||
|
|
||||||
|
await fetchWithTestApi({
|
||||||
|
journeys: async (from, to, opt = {}) => {
|
||||||
|
t.deepEqual(opt.loyaltyCard, {
|
||||||
|
type: loyaltyCards.BAHNCARD,
|
||||||
|
discount: 50,
|
||||||
|
class: 2,
|
||||||
|
}, 'journeys() called with invalid opt.loyaltyCard')
|
||||||
|
return NO_JOURNEYS
|
||||||
|
}
|
||||||
|
}, {}, '/journeys?from=123&to=234&loyaltyCard=bahncard-2nd-50')
|
||||||
|
})
|
||||||
|
|
Loading…
Reference in a new issue