migrate and update loyaltyCard parsing from db-rest

This commit is contained in:
Traines 2025-02-13 23:20:37 +00:00
parent 71d1a4f1a9
commit 177a3cab3f
3 changed files with 90 additions and 28 deletions

26
api.js
View file

@ -2,32 +2,8 @@ import {createClient} from './index.js';
import {profile as dbProfile} from './p/db/index.js'; import {profile as dbProfile} from './p/db/index.js';
import {profile as dbnavProfile} from './p/dbnav/index.js'; import {profile as dbnavProfile} from './p/dbnav/index.js';
import {profile as dbwebProfile} from './p/dbweb/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 {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 = { const config = {
hostname: process.env.HOSTNAME || 'localhost', hostname: process.env.HOSTNAME || 'localhost',

View file

@ -6,9 +6,10 @@ const c = {
VOORDEELURENABO: Symbol('Voordeelurenabo'), VOORDEELURENABO: Symbol('Voordeelurenabo'),
SHCARD: Symbol('SH-Card'), SHCARD: Symbol('SH-Card'),
GENERALABONNEMENT: Symbol('General-Abonnement'), GENERALABONNEMENT: Symbol('General-Abonnement'),
NL_40: Symbol('NL-40%'),
AT_KLIMATICKET: Symbol('AT-KlimaTicket'),
}; };
// see https://gist.github.com/juliuste/202bb04f450a79f8fa12a2ec3abcd72d
const formatLoyaltyCard = (data) => { const formatLoyaltyCard = (data) => {
if (!data) { if (!data) {
return { return {
@ -19,7 +20,7 @@ const formatLoyaltyCard = (data) => {
const cls = data.class === 1 ? 'KLASSE_1' : 'KLASSE_2'; const cls = data.class === 1 ? 'KLASSE_1' : 'KLASSE_2';
if (data.type.toString() === c.BAHNCARD.toString()) { if (data.type.toString() === c.BAHNCARD.toString()) {
return { return {
art: 'BAHNCARD' + data.discount, art: 'BAHNCARD' + (data.business ? 'BUSINESS' : '') + data.discount,
klasse: cls, klasse: cls,
}; };
} }
@ -35,13 +36,24 @@ const formatLoyaltyCard = (data) => {
klasse: 'KLASSENLOS', klasse: 'KLASSENLOS',
}; };
} }
// TODO Rest
if (data.type.toString() === c.GENERALABONNEMENT.toString()) { if (data.type.toString() === c.GENERALABONNEMENT.toString()) {
return { return {
art: 'CH-GENERAL-ABONNEMENT', art: 'CH-GENERAL-ABONNEMENT',
klasse: cls, 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 { return {
art: 'KEINE_ERMAESSIGUNG', art: 'KEINE_ERMAESSIGUNG',
klasse: 'KLASSENLOS', klasse: 'KLASSENLOS',

74
lib/api-parsers.js Normal file
View file

@ -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,
};