diff --git a/api.js b/api.js index defc97fd..2712e7de 100644 --- a/api.js +++ b/api.js @@ -2,32 +2,8 @@ import {createClient} from './index.js'; import {profile as dbProfile} from './p/db/index.js'; import {profile as dbnavProfile} from './p/dbnav/index.js'; import {profile as dbwebProfile} from './p/dbweb/index.js'; +import {mapRouteParsers} from './lib/api-parsers.js'; import {createHafasRestApi as createApi} from 'hafas-rest-api'; -import {loyaltyCardParser} from 'db-rest/lib/loyalty-cards.js'; -import {parseBoolean, parseInteger} from 'hafas-rest-api/lib/parse.js'; - -// TODO product support for nearby etc? -const mapRouteParsers = (route, parsers) => { - if (!route.includes('journey')) { - return parsers; - } - return { - ...parsers, - loyaltyCard: loyaltyCardParser, - firstClass: { - description: 'Search for first-class options?', - type: 'boolean', - default: 'false', - parse: parseBoolean, - }, - age: { - description: 'Age of traveller', - type: 'integer', - defaultStr: '*adult*', - parse: parseInteger, - }, - }; -}; const config = { hostname: process.env.HOSTNAME || 'localhost', diff --git a/format/loyalty-cards.js b/format/loyalty-cards.js index 03180eaa..bbd30465 100644 --- a/format/loyalty-cards.js +++ b/format/loyalty-cards.js @@ -6,9 +6,10 @@ const c = { VOORDEELURENABO: Symbol('Voordeelurenabo'), SHCARD: Symbol('SH-Card'), GENERALABONNEMENT: Symbol('General-Abonnement'), + NL_40: Symbol('NL-40%'), + AT_KLIMATICKET: Symbol('AT-KlimaTicket'), }; -// see https://gist.github.com/juliuste/202bb04f450a79f8fa12a2ec3abcd72d const formatLoyaltyCard = (data) => { if (!data) { return { @@ -19,7 +20,7 @@ const formatLoyaltyCard = (data) => { const cls = data.class === 1 ? 'KLASSE_1' : 'KLASSE_2'; if (data.type.toString() === c.BAHNCARD.toString()) { return { - art: 'BAHNCARD' + data.discount, + art: 'BAHNCARD' + (data.business ? 'BUSINESS' : '') + data.discount, klasse: cls, }; } @@ -35,13 +36,24 @@ const formatLoyaltyCard = (data) => { klasse: 'KLASSENLOS', }; } - // TODO Rest if (data.type.toString() === c.GENERALABONNEMENT.toString()) { return { art: 'CH-GENERAL-ABONNEMENT', klasse: cls, }; } + if (data.type.toString() === c.NL_40.toString()) { + return { + art: 'NL-40_OHNE_RAILPLUS', + klasse: 'KLASSENLOS', + }; + } + if (data.type.toString() === c.AT_KLIMATICKET.toString()) { + return { + art: 'KLIMATICKET_OE', + klasse: 'KLASSENLOS', + }; + } return { art: 'KEINE_ERMAESSIGUNG', klasse: 'KLASSENLOS', diff --git a/lib/api-parsers.js b/lib/api-parsers.js new file mode 100644 index 00000000..cfa41da0 --- /dev/null +++ b/lib/api-parsers.js @@ -0,0 +1,74 @@ +import {data as cards} from '../format/loyalty-cards.js'; +import {parseBoolean, parseInteger} from 'hafas-rest-api/lib/parse.js'; + +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}], + ['bahncard-1st-100', {type: cards.BAHNCARD, discount: 100, class: 1}], + ['bahncard-2nd-100', {type: cards.BAHNCARD, discount: 100, class: 2}], + ['vorteilscard', {type: cards.VORTEILSCARD}], + ['halbtaxabo-railplus', {type: cards.HALBTAXABO}], + ['halbtaxabo', {type: cards.HALBTAXABO}], + ['voordeelurenabo-railplus', {type: cards.VOORDEELURENABO}], + ['voordeelurenabo', {type: cards.VOORDEELURENABO}], + ['shcard', {type: cards.SHCARD}], + ['generalabonnement-1st', {type: cards.GENERALABONNEMENT, class: 1}], + ['generalabonnement-2nd', {type: cards.GENERALABONNEMENT, class: 2}], + ['generalabonnement', {type: cards.GENERALABONNEMENT}], + ['nl-40', {type: cards.NL_40}], + ['at-klimaticket', {type: cards.AT_KLIMATICKET}], +]); +const types = Array.from(typesByName.keys()); + +const parseLoyaltyCard = (key, val) => { + if (typesByName.has(val)) { + return typesByName.get(val); + } + if (!val) { + return null; + } + throw new Error(key + ' must be one of ' + types.join(', ')); +}; + +const parseArrayOr = (parseEntry) => { + return (key, val) => { + if (Array.isArray(val)) { + return val.map(e => parseEntry(key, e)); + } + return parseEntry(key, val); + }; +}; + +const mapRouteParsers = (route, parsers) => { + if (route !== 'journeys') { + return parsers; + } + return { + ...parsers, + firstClass: { + description: 'Search for first-class options?', + type: 'boolean', + default: 'false', + parse: parseBoolean, + }, + loyaltyCard: { + description: 'Type of loyalty card in use.', + type: 'string', + enum: types, + defaultStr: '*none*', + parse: parseArrayOr(parseLoyaltyCard), + }, + age: { + description: 'Age of traveller', + type: 'integer', + defaultStr: '*adult*', + parse: parseArrayOr(parseInteger), + }, + }; +}; + +export { + mapRouteParsers, +};