Compare commits

..

5 commits

Author SHA1 Message Date
Traines
785f5fcc37 add checks back to release, fix readme
[skip ci]
2025-10-24 20:16:32 +00:00
Traines
ca6ceabbed fix bestprice for db profile 2025-10-24 19:40:50 +00:00
Jannis
d0120439e6
chore: CI: publish to npm using OIDC tokens (#36)
Some checks failed
test / lint-and-spellcheck (push) Has been cancelled
test / unit-tests (18.x) (push) Has been cancelled
test / unit-tests (20.x) (push) Has been cancelled
test / unit-tests (22.x) (push) Has been cancelled
test / integration-tests (18.x) (push) Has been cancelled
test / integration-tests (20.x) (push) Has been cancelled
test / integration-tests (22.x) (push) Has been cancelled
test / e2e-tests (18.x) (push) Has been cancelled
see also https://docs.npmjs.com/trusted-publishers
2025-10-22 20:44:53 +02:00
Traines
c2216120c9 set db profile to old dbnav domain as an alternative, since the new domain
Some checks are pending
test / lint-and-spellcheck (push) Waiting to run
test / unit-tests (18.x) (push) Waiting to run
test / unit-tests (20.x) (push) Waiting to run
test / unit-tests (22.x) (push) Waiting to run
test / integration-tests (18.x) (push) Waiting to run
test / integration-tests (20.x) (push) Waiting to run
test / integration-tests (22.x) (push) Waiting to run
test / e2e-tests (18.x) (push) Blocked by required conditions
might have more agressive blocking
2025-10-21 20:54:11 +00:00
Traines
bdbf4f3761 fix ticket parsing 2025-10-21 20:37:50 +00:00
9 changed files with 2060 additions and 19 deletions

View file

@ -10,6 +10,9 @@ env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
permissions:
id-token: write # for OIDC-based publishing to npm
jobs:
build-and-push-docker:
runs-on: ubuntu-latest
@ -53,7 +56,9 @@ jobs:
with:
node-version: '20.x'
registry-url: 'https://registry.npmjs.org'
# for OIDC-based publishing to npm
- name: setup npm v11
run: npm install -g npm@11
- run: npm ci
- run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

12
p/db/base.json Normal file
View file

@ -0,0 +1,12 @@
{
"journeysEndpoint": "https://app.vendo.noncd.db.de/mob/angebote/fahrplan",
"bestpriceEndpoint": "https://app.vendo.noncd.db.de/mob/angebote/tagesbestpreis",
"refreshJourneysEndpointTickets": "https://app.vendo.noncd.db.de/mob/angebote/recon",
"refreshJourneysEndpointPolyline": "https://app.vendo.noncd.db.de/mob/trip/recon",
"locationsEndpoint": "https://app.vendo.noncd.db.de/mob/location/search",
"stopEndpoint": "https://app.vendo.noncd.db.de/mob/location/details/",
"nearbyEndpoint": "https://app.vendo.noncd.db.de/mob/location/nearby",
"tripEndpoint": "https://app.vendo.noncd.db.de/mob/zuglauf/",
"boardEndpoint": "https://app.vendo.noncd.db.de/mob/bahnhofstafel/",
"defaultLanguage": "en"
}

View file

@ -1,35 +1,36 @@
import dbnavBase from '../dbnav/base.json' with { type: 'json' };
import base from './base.json' with { type: 'json' };
import {products} from '../../lib/products.js';
// journeys()
import {formatJourneysReq} from '../dbnav/journeys-req.js';
const {journeysEndpoint} = dbnavBase;
const {journeysEndpoint} = base;
const {bestpriceEndpoint} = base;
// refreshJourneys()
import {formatRefreshJourneyReq} from '../dbnav/journeys-req.js';
const {refreshJourneysEndpointTickets, refreshJourneysEndpointPolyline} = dbnavBase;
const {refreshJourneysEndpointTickets, refreshJourneysEndpointPolyline} = base;
// locations()
import {formatLocationsReq} from '../dbnav/locations-req.js';
import {formatLocationFilter} from '../dbnav/location-filter.js';
const {locationsEndpoint} = dbnavBase;
const {locationsEndpoint} = base;
// stop()
import {formatStopReq} from '../dbnav/stop-req.js';
import {parseStop} from '../dbnav/parse-stop.js';
const {stopEndpoint} = dbnavBase;
const {stopEndpoint} = base;
// nearby()
import {formatNearbyReq} from '../dbnav/nearby-req.js';
const {nearbyEndpoint} = dbnavBase;
const {nearbyEndpoint} = base;
// trip()
import {formatTripReq} from './trip-req.js';
const {tripEndpoint} = dbnavBase;
const {tripEndpoint} = base;
// arrivals(), departures()
import {formatStationBoardReq} from '../dbnav/station-board-req.js';
const {boardEndpoint} = dbnavBase;
const {boardEndpoint} = base;
const profile = {
locale: 'de-DE',
@ -39,6 +40,7 @@ const profile = {
formatJourneysReq,
journeysEndpoint,
bestpriceEndpoint,
formatRefreshJourneyReq,
refreshJourneysEndpointTickets, refreshJourneysEndpointPolyline,

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "db-vendo-client",
"version": "6.10.3",
"version": "6.10.5",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "db-vendo-client",
"version": "6.10.3",
"version": "6.10.5",
"license": "ISC",
"dependencies": {
"content-type": "^1.0.5",

View file

@ -1,7 +1,7 @@
{
"name": "db-vendo-client",
"description": "Client for bahn.de public transport APIs.",
"version": "6.10.3",
"version": "6.10.5",
"type": "module",
"main": "index.js",
"files": [
@ -95,7 +95,7 @@
"test-e2e": "VCR_OFF=true tap -t60 -j16 test/e2e/*.js",
"test-spelling": "cspell .",
"test": "npm run test-unit && npm run test-integration && npm run test-spelling",
"prepublishOnly": "npm run lint",
"prepublishOnly": "npm run lint && npm test",
"api": "node api.js"
},
"tap": {

View file

@ -26,7 +26,9 @@ const parseTickets = (ctx, j) => {
.flatMap(p => [
p.einfacheFahrt?.standard?.reisePosition,
p.einfacheFahrt?.upsellEntgelt?.einfacheFahrt?.reisePosition,
].filter(p => p)
p.einfacheFahrt?.upsellAngebote?.map(a => a.upsellEntgelt?.einfacheFahrt?.reisePosition),
].flatMap(p => p)
.filter(p => p)
.map(p => {
p.reisePosition.teilpreis = Boolean(p.teilpreisInformationen?.length);
return p.reisePosition;
@ -44,7 +46,7 @@ const parseTickets = (ctx, j) => {
amount: Math.round(s.preis?.betrag * 100),
currency: s.preis?.waehrung,
},
firstClass: s.klasse == 'KLASSE_1' || s.premium || Boolean(s.nutzungsInformationen?.find(i => i.klasse == 'KLASSE_1')),
firstClass: s.klasse == 'KLASSE_1' || Boolean(s.nutzungsInformationen?.find(i => i.klasse == 'KLASSE_1')),
partialFare: s.teilpreis,
};
if (s.teilpreis) {

View file

@ -25,7 +25,7 @@ Depending on the configured profile, db-vendo-client will use multiple different
| Profile | `db` | `dbnav` | `dbweb` | `dbris` |
| ------------- | ------------- | ------------- | ------------- | ------------- |
| no API key required | ✅ | ✅ | ✅ | ✅ | ❌ |
| no API key required | ✅ | ✅ | ✅ | ❌ |
| all above endpoints supported | ✅ | ✅ | except `stop()` | only boards |
| duration for boards | always 1h | always 1h | always 1h | up to 12h |
| remarks | for boards only most important remarks | for boards only most important remarks | all remarks on boards and journeys | all remarks |
@ -37,7 +37,7 @@ Depending on the configured profile, db-vendo-client will use multiple different
| adminCode/operator | only for journeys | only for journeys | only operator | ✅ |
| stopovers | not in boards | not in boards | ✅ | ✅ |
| assumed backend API stability | less stable | more stable | less stable | more stable |
| quotas | 60 requests per minute (IPv4) | 60 requests per minute (IPv4) | aggressive blocking (IPv4/IPv6) | depends on API key |
| quotas | 60 requests per minute (IPv4), current backend possibly shut off soon | 60 requests per minute (IPv4), possibly aggressive blocking | aggressive blocking (IPv4/IPv6) | depends on API key |
> [!IMPORTANT]

File diff suppressed because one or more lines are too long

View file

@ -17,7 +17,7 @@ const tripIdHafas = '2|#VN#1#ST#1738783727#PI#0#ZI#222242#TA#0#DA#70225#1S#80002
const tripIdRis = '20250207-e6b2807e-bb48-39f9-89eb-8491ebc4b32c';
const reqDbNavExpected = {
endpoint: 'https://app.services-bahn.de/mob/zuglauf/',
endpoint: 'https://app.vendo.noncd.db.de/mob/zuglauf/',
path: '2%7C%23VN%231%23ST%231738783727%23PI%230%23ZI%23222242%23TA%230%23DA%2370225%231S%238000237%231T%231317%23LS%238000261%23LT%232002%23PU%2380%23RT%231%23CA%23ICE%23ZE%231007%23ZB%23ICE%201007%23PC%230%23FR%238000237%23FT%231317%23TO%238000261%23TT%232002%23',
headers: {
'Accept': 'application/x.db.vendo.mob.zuglauf.v2+json',