From 3afeb5352b97f5a9639203a6e81334695e47da25 Mon Sep 17 00:00:00 2001 From: marudor Date: Tue, 14 Jan 2025 00:13:20 +0100 Subject: [PATCH] chore: remove mgate functionality --- scripts/clearCorruptCache.ts | 30 -- src/bahnde/journeyDetails/journeyDetails.ts | 6 +- src/bahnde/occupancy.ts | 6 +- src/client/Abfahrten/Components/ExtraMenu.tsx | 12 +- src/client/Abfahrten/Components/FavEntry.tsx | 10 +- src/client/Abfahrten/Components/FavList.tsx | 9 +- src/client/Abfahrten/Components/Header.tsx | 2 +- src/client/Abfahrten/Components/MostUsed.tsx | 7 +- src/client/Abfahrten/hooks/useFavs.ts | 33 +- src/client/Common/Storage.ts | 1 - .../Components/Search/BC100Disclaimer.tsx | 26 - .../Components/Search/NetzcardDisclaimer.tsx | 38 -- .../Components/Search/SettingsPanel.tsx | 82 +--- .../provider/RoutingConfigProvider.tsx | 12 - .../Routing/provider/useFetchRouting.ts | 112 ++--- src/external/risJourneys.ts | 6 +- src/external/risJourneysV2.ts | 8 +- src/external/risMaps.ts | 12 +- src/external/risTransports/occupancy.ts | 11 +- src/external/risTransports/sequence.ts | 4 +- src/external/risTransports/vehicles.ts | 15 +- src/routes/_abfahrten/index.tsx | 2 +- src/server/HAFAS/Detail.ts | 155 ------ src/server/HAFAS/HimSearch.ts | 93 ---- src/server/HAFAS/JourneyDetails.ts | 69 --- src/server/HAFAS/JourneyMatch.ts | 146 ------ src/server/HAFAS/LocMatch.ts | 62 --- src/server/HAFAS/Request.ts | 169 ------- src/server/HAFAS/SearchOnTrip.ts | 33 -- .../StationBoard/StationBoardToTimetables.ts | 86 ---- src/server/HAFAS/StationBoard/index.ts | 61 --- src/server/HAFAS/StationBoard/parse.ts | 63 --- .../HAFAS/TripSearch/NetzcardBetreiber.json | 31 -- src/server/HAFAS/TripSearch/TripSearch.ts | 185 ------- .../HAFAS/TripSearch/mapLoyalityCard.ts | 28 -- src/server/HAFAS/TripSearch/mergeSegments.ts | 26 - src/server/HAFAS/TripSearch/parse.ts | 242 ---------- .../helper/__tests__/createCtxRecon.test.ts | 68 --- .../HAFAS/helper/adjustProductOperator.ts | 29 -- src/server/HAFAS/helper/checkCoachSequence.ts | 15 - src/server/HAFAS/helper/createCtxRecon.ts | 37 -- src/server/HAFAS/helper/parseAuslastung.ts | 38 -- src/server/HAFAS/helper/parseCommonArrival.ts | 31 -- .../HAFAS/helper/parseCommonDeparture.ts | 38 -- src/server/HAFAS/helper/parseDuration.ts | 13 - src/server/HAFAS/helper/parseLocL.ts | 30 -- src/server/HAFAS/helper/parseMessages.ts | 22 - src/server/HAFAS/helper/parsePolyline.ts | 11 - src/server/HAFAS/helper/parseProduct.ts | 72 --- src/server/HAFAS/helper/parseStop.ts | 32 -- src/server/HAFAS/helper/parseTarif.ts | 30 -- src/server/HAFAS/helper/parseTime.ts | 33 -- src/server/HAFAS/occupancy.ts | 87 ---- src/server/HAFAS/profiles.ts | 367 -------------- src/server/StopPlace/Lageplan/DBLageplan.ts | 4 +- .../StopPlace/Lageplan/NAHSHLageplan.ts | 55 --- src/server/StopPlace/Lageplan/index.ts | 8 +- src/server/StopPlace/hafasSearch.ts | 59 --- src/server/StopPlace/search.ts | 56 +-- src/server/StopPlace/vrrOccupancy.ts | 6 +- src/server/cache.ts | 98 +++- src/server/coachSequence/DB/index.ts | 8 +- src/server/coachSequence/DB/removedData.ts | 21 +- src/server/iris/Timetable.ts | 95 +--- src/server/iris/station.ts | 4 +- .../journeys/additionalJourneyInformation.ts | 96 ++-- src/server/rpc/hafas.ts | 89 ---- src/server/rpc/journeys.ts | 60 +-- src/server/sanitizeStorage.ts | 27 +- src/types/HAFAS/HimSearch.ts | 75 --- src/types/HAFAS/JourneyDetails.ts | 43 +- src/types/HAFAS/JourneyMatch.ts | 63 +-- src/types/HAFAS/LocMatch.ts | 41 -- src/types/HAFAS/SearchOnTrip.ts | 31 +- src/types/HAFAS/StationBoard.ts | 77 --- src/types/HAFAS/Tarif.ts | 26 - src/types/HAFAS/TripSearch.ts | 328 ------------- src/types/HAFAS/deprecated/JourneyCourse.ts | 54 --- src/types/HAFAS/deprecated/JourneyGraph.ts | 18 - src/types/HAFAS/deprecated/JourneyTree.ts | 25 - src/types/HAFAS/index.ts | 455 ------------------ src/types/routing.ts | 4 - 82 files changed, 290 insertions(+), 4482 deletions(-) delete mode 100644 scripts/clearCorruptCache.ts delete mode 100644 src/client/Routing/Components/Search/BC100Disclaimer.tsx delete mode 100644 src/client/Routing/Components/Search/NetzcardDisclaimer.tsx delete mode 100644 src/server/HAFAS/HimSearch.ts delete mode 100644 src/server/HAFAS/JourneyDetails.ts delete mode 100644 src/server/HAFAS/JourneyMatch.ts delete mode 100644 src/server/HAFAS/LocMatch.ts delete mode 100644 src/server/HAFAS/Request.ts delete mode 100644 src/server/HAFAS/SearchOnTrip.ts delete mode 100644 src/server/HAFAS/StationBoard/StationBoardToTimetables.ts delete mode 100644 src/server/HAFAS/StationBoard/index.ts delete mode 100644 src/server/HAFAS/StationBoard/parse.ts delete mode 100644 src/server/HAFAS/TripSearch/NetzcardBetreiber.json delete mode 100644 src/server/HAFAS/TripSearch/TripSearch.ts delete mode 100644 src/server/HAFAS/TripSearch/mapLoyalityCard.ts delete mode 100644 src/server/HAFAS/TripSearch/mergeSegments.ts delete mode 100644 src/server/HAFAS/TripSearch/parse.ts delete mode 100644 src/server/HAFAS/helper/__tests__/createCtxRecon.test.ts delete mode 100644 src/server/HAFAS/helper/adjustProductOperator.ts delete mode 100644 src/server/HAFAS/helper/checkCoachSequence.ts delete mode 100644 src/server/HAFAS/helper/createCtxRecon.ts delete mode 100644 src/server/HAFAS/helper/parseAuslastung.ts delete mode 100644 src/server/HAFAS/helper/parseCommonArrival.ts delete mode 100644 src/server/HAFAS/helper/parseCommonDeparture.ts delete mode 100644 src/server/HAFAS/helper/parseDuration.ts delete mode 100644 src/server/HAFAS/helper/parseLocL.ts delete mode 100644 src/server/HAFAS/helper/parseMessages.ts delete mode 100644 src/server/HAFAS/helper/parsePolyline.ts delete mode 100644 src/server/HAFAS/helper/parseProduct.ts delete mode 100644 src/server/HAFAS/helper/parseStop.ts delete mode 100644 src/server/HAFAS/helper/parseTarif.ts delete mode 100644 src/server/HAFAS/helper/parseTime.ts delete mode 100644 src/server/HAFAS/occupancy.ts delete mode 100644 src/server/HAFAS/profiles.ts delete mode 100644 src/server/StopPlace/Lageplan/NAHSHLageplan.ts delete mode 100644 src/server/StopPlace/hafasSearch.ts delete mode 100644 src/types/HAFAS/HimSearch.ts delete mode 100644 src/types/HAFAS/LocMatch.ts delete mode 100644 src/types/HAFAS/StationBoard.ts delete mode 100644 src/types/HAFAS/Tarif.ts delete mode 100644 src/types/HAFAS/TripSearch.ts delete mode 100644 src/types/HAFAS/deprecated/JourneyCourse.ts delete mode 100644 src/types/HAFAS/deprecated/JourneyGraph.ts delete mode 100644 src/types/HAFAS/deprecated/JourneyTree.ts diff --git a/scripts/clearCorruptCache.ts b/scripts/clearCorruptCache.ts deleted file mode 100644 index 7fff0be80..000000000 --- a/scripts/clearCorruptCache.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Cache, CacheDatabase } from '@/server/cache'; - -const cachesThatMightBeBroken = [ - // CacheDatabase.StopPlaceSearch, - // CacheDatabase.StopPlaceSalesSearch, - // CacheDatabase.StopPlaceByEva, - // CacheDatabase.StopPlaceByRil, - CacheDatabase.JourneyFind, - CacheDatabase.JourneyFindV2, -].map((cacheNumber) => { - return new Cache(cacheNumber); -}); - -async function doStuff() { - for (const cache of cachesThatMightBeBroken) { - const allEntries = await cache.getAll(); - const relevantEntries = allEntries.filter( - ([, value]) => !value || (Array.isArray(value) && !value.length), - ); - // biome-ignore lint/suspicious/noConsoleLog: script - console.log(`clearing ${relevantEntries.length}`); - for (const [key] of relevantEntries) { - await cache.delete(key); - } - } -} - -doStuff().then(() => { - process.exit(0); -}); diff --git a/src/bahnde/journeyDetails/journeyDetails.ts b/src/bahnde/journeyDetails/journeyDetails.ts index 3beb29d60..7302aef24 100644 --- a/src/bahnde/journeyDetails/journeyDetails.ts +++ b/src/bahnde/journeyDetails/journeyDetails.ts @@ -1,7 +1,7 @@ import { mapFahrt } from '@/bahnde/journeyDetails/parseJourneyDetails'; import { addRandomBrowserUseragent } from '@/bahnde/randomUseragent'; import { axiosUpstreamInterceptor } from '@/server/admin'; -import { Cache, CacheDatabase } from '@/server/cache'; +import { CacheDatabase, getCache } from '@/server/cache'; import { logger } from '@/server/logger'; import type { ParsedSearchOnTripResponse } from '@/types/HAFAS/SearchOnTrip'; import axios from 'axios'; @@ -21,9 +21,7 @@ journeyDetailsAxios.interceptors.request.use((req) => { }); axiosUpstreamInterceptor(journeyDetailsAxios, 'bahn.de-journeyDetails'); -const quickJourneyDetailsCache = new Cache( - CacheDatabase.BahnDEJourneyDetails, -); +const quickJourneyDetailsCache = getCache(CacheDatabase.BahnDEJourneyDetails); export const bahnJourneyDetails = async ( jid: string, diff --git a/src/bahnde/occupancy.ts b/src/bahnde/occupancy.ts index 53bfac2c2..4aa5e6e21 100644 --- a/src/bahnde/occupancy.ts +++ b/src/bahnde/occupancy.ts @@ -1,6 +1,6 @@ import { routing } from '@/bahnde/routing/routing'; import { searchStopPlace } from '@/server/StopPlace/search'; -import { Cache, CacheDatabase } from '@/server/cache'; +import { CacheDatabase, getCache } from '@/server/cache'; import { timezone } from '@/timezone'; import type { RouteAuslastung, @@ -59,9 +59,7 @@ async function getRelevantTrip( return relevantTrip; } -const stopOccupancyCache = new Cache( - CacheDatabase.HafasStopOccupancy, -); +const stopOccupancyCache = getCache(CacheDatabase.HafasStopOccupancy); const createBaseCacheKey = ( trainNumber: string, diff --git a/src/client/Abfahrten/Components/ExtraMenu.tsx b/src/client/Abfahrten/Components/ExtraMenu.tsx index c0c3e8aae..c71d3abd9 100644 --- a/src/client/Abfahrten/Components/ExtraMenu.tsx +++ b/src/client/Abfahrten/Components/ExtraMenu.tsx @@ -17,11 +17,7 @@ import { useCallback, useState } from 'react'; import type { FC, SyntheticEvent } from 'react'; import { FilterModal } from './FilterModal'; -interface Props { - favKey: 'regionalFavs' | 'favs'; -} - -export const ExtraMenu: FC = ({ favKey }) => { +export const ExtraMenu: FC = () => { const setFilterOpen = useAbfahrtenFilterOpen(); const currentStopPlace = useCurrentAbfahrtenStopPlace(); const { data: lageplan } = trpc.stopPlace.lageplan.useQuery( @@ -31,9 +27,9 @@ export const ExtraMenu: FC = ({ favKey }) => { staleTime: Number.POSITIVE_INFINITY, }, ); - const favs = useFavs(favKey); - const fav = useFavAction(favKey); - const unfav = useUnfavAction(favKey); + const favs = useFavs(); + const fav = useFavAction(); + const unfav = useUnfavAction(); const isFaved = Boolean(currentStopPlace && favs[currentStopPlace.evaNumber]); const [anchor, setAnchor] = useState(); const toggleFav = useCallback(() => { diff --git a/src/client/Abfahrten/Components/FavEntry.tsx b/src/client/Abfahrten/Components/FavEntry.tsx index 88d0b9f6d..f85d3140b 100644 --- a/src/client/Abfahrten/Components/FavEntry.tsx +++ b/src/client/Abfahrten/Components/FavEntry.tsx @@ -38,8 +38,8 @@ const UnclickablePaper = styled(BasePaper)` interface Props { fav: MinimalStopPlace; - favKey?: 'regionalFavs' | 'favs'; 'data-testid'?: string; + noDelete?: boolean; } interface FavEntryDisplayProps { @@ -75,14 +75,14 @@ export const FavEntryDisplay: FC = ({ export const FavEntry: FC = ({ fav, 'data-testid': testid = 'favEntry', - favKey, + noDelete, }) => { - const unfav = useUnfavAction(favKey); + const unfav = useUnfavAction(); const deleteFav = useCallback( (e: MouseEvent) => { e.stopPropagation(); e.preventDefault(); - unfav?.(fav); + unfav(fav); }, [fav, unfav], ); @@ -98,7 +98,7 @@ export const FavEntry: FC = ({ > ); diff --git a/src/client/Abfahrten/Components/FavList.tsx b/src/client/Abfahrten/Components/FavList.tsx index fa9bdf411..4434b669b 100644 --- a/src/client/Abfahrten/Components/FavList.tsx +++ b/src/client/Abfahrten/Components/FavList.tsx @@ -10,19 +10,18 @@ import { FavEntry, FavEntryDisplay } from './FavEntry'; interface Props { children?: ReactNode; - favKey: 'regionalFavs' | 'favs'; mostUsed?: boolean; } -export const FavList: FC = ({ children, favKey, mostUsed }) => { - const favs = useFavs(favKey); +export const FavList: FC = ({ children, mostUsed }) => { + const favs = useFavs(); const sortedFavs = useMemo(() => { const values: MinimalStopPlace[] = Object.values(favs); return values .sort((a, b) => (a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1)) - .map((fav) => ); - }, [favs, favKey]); + .map((fav) => ); + }, [favs]); const { updateTitle, updateDescription, updateKeywords } = useHeaderTagsActions(); diff --git a/src/client/Abfahrten/Components/Header.tsx b/src/client/Abfahrten/Components/Header.tsx index 6a569c6e2..5d0f0d13c 100644 --- a/src/client/Abfahrten/Components/Header.tsx +++ b/src/client/Abfahrten/Components/Header.tsx @@ -71,7 +71,7 @@ export const Header: FC = ({ regional = false }: Props) => { )} - + ); }; diff --git a/src/client/Abfahrten/Components/MostUsed.tsx b/src/client/Abfahrten/Components/MostUsed.tsx index bcb0eefa3..fbfaaa5b9 100644 --- a/src/client/Abfahrten/Components/MostUsed.tsx +++ b/src/client/Abfahrten/Components/MostUsed.tsx @@ -22,7 +22,12 @@ export const MostUsed: FC = () => { return ( <> {mostUsed.map((m) => ( - + ))} ); diff --git a/src/client/Abfahrten/hooks/useFavs.ts b/src/client/Abfahrten/hooks/useFavs.ts index 8b648902f..5198196ae 100644 --- a/src/client/Abfahrten/hooks/useFavs.ts +++ b/src/client/Abfahrten/hooks/useFavs.ts @@ -3,19 +3,16 @@ import type { MinimalStopPlace } from '@/types/stopPlace'; import { useCallback } from 'react'; export type Favs = Record; -export const useFavs = (key?: 'favs' | 'regionalFavs') => { - const [cookies] = useExpertCookies([key!]); - if (!key) { - return {}; - } - const savedFavs = cookies[key]; +export const useFavs = () => { + const [cookies] = useExpertCookies(['favs']); + const savedFavs = cookies.favs; return savedFavs || {}; }; -export const useFavAction = (key: 'favs' | 'regionalFavs') => { - const [_, setCookie] = useExpertCookies([key]); - const favs = useFavs(key); +export const useFavAction = () => { + const [_, setCookie] = useExpertCookies(['favs']); + const favs = useFavs(); return useCallback( (stopPlace: MinimalStopPlace) => { @@ -26,28 +23,24 @@ export const useFavAction = (key: 'favs' | 'regionalFavs') => { evaNumber: stopPlace.evaNumber, }, }; - setCookie(key, newFavs); + setCookie('favs', newFavs); return newFavs; }, - [setCookie, favs, key], + [setCookie, favs], ); }; -export const useUnfavAction = (key?: 'favs' | 'regionalFavs') => { - const [_, setCookie] = useExpertCookies([key!]); - const favs = useFavs(key); +export const useUnfavAction = () => { + const [_, setCookie] = useExpertCookies(['favs']); + const favs = useFavs(); return useCallback( (stopPlace: MinimalStopPlace) => { - if (!key) { - return undefined; - } - delete favs[stopPlace.evaNumber]; const newFavs = { ...favs }; - setCookie(key, newFavs); + setCookie('favs', newFavs); return newFavs; }, - [key, favs, setCookie], + [favs, setCookie], ); }; diff --git a/src/client/Common/Storage.ts b/src/client/Common/Storage.ts index 25731efe2..80d1ea999 100644 --- a/src/client/Common/Storage.ts +++ b/src/client/Common/Storage.ts @@ -14,7 +14,6 @@ const setCookieOptions: CookieSetOptions = { export interface WebConfigMap extends CommonConfig, RoutingSettings { readonly selectedDetail: string; - readonly regionalFavs: Favs; readonly favs: Favs; readonly rfavs: RoutingFavs; readonly defaultFilter: string[]; diff --git a/src/client/Routing/Components/Search/BC100Disclaimer.tsx b/src/client/Routing/Components/Search/BC100Disclaimer.tsx deleted file mode 100644 index 95edfa88f..000000000 --- a/src/client/Routing/Components/Search/BC100Disclaimer.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { Dialog, DialogContent, DialogTitle } from '@mui/material'; -import { useState } from 'react'; -import type { FC } from 'react'; - -export const BC100Disclaimer: FC = () => { - const [open, setOpen] = useState(true); - return ( - setOpen(false)} - > - BC100 Disclaimer - - Dieser Filter funktioniert NICHT mit "bahn.de" als Backend!
- Dieser Filter nimmt alle Fahrten raus welche mit "DB-Fahrscheine gelten - nicht" markiert sind.
- Ganz konkret basiert es auf dem Attribut "DU". Keine Garantie das nicht - doch Verbindungen ausgegeben werden welche nicht gefahren werden dürfen! - Bitte informiert euch selbstständig! -
-
- ); -}; diff --git a/src/client/Routing/Components/Search/NetzcardDisclaimer.tsx b/src/client/Routing/Components/Search/NetzcardDisclaimer.tsx deleted file mode 100644 index b0dba1e49..000000000 --- a/src/client/Routing/Components/Search/NetzcardDisclaimer.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import { Dialog, DialogContent, DialogTitle } from '@mui/material'; -import { useState } from 'react'; -import type { FC } from 'react'; - -export const NetzcardDisclaimer: FC = () => { - const [open, setOpen] = useState(true); - return ( - setOpen(false)} - > - Netzcard Disclaimer - - Dieser Filter funktioniert NICHT mit "bahn.de" als Backend!
- Dies ist ein experimenteller Filter um möglichst nur Verbindungen zu - suchen welche mit der Netzcard erlaubt sind. -
- USE AT YOUR OWN RISK! -
- Aktuell werden nur EVUs der DB AG berücksichtigt. Die aktuelle Liste - findet sich hier:{' '} - - NetzcardBetreiber.json - {' '} -
- Das bedeutet vor allem das die Ausnahmen für bestimmte Strecken NICHT - berücksichtigt werden! -
-
- ); -}; diff --git a/src/client/Routing/Components/Search/SettingsPanel.tsx b/src/client/Routing/Components/Search/SettingsPanel.tsx index 83fa2a01a..81b3f596f 100644 --- a/src/client/Routing/Components/Search/SettingsPanel.tsx +++ b/src/client/Routing/Components/Search/SettingsPanel.tsx @@ -1,11 +1,8 @@ -import { BC100Disclaimer } from '@/client/Routing/Components/Search/BC100Disclaimer'; -import { NetzcardDisclaimer } from '@/client/Routing/Components/Search/NetzcardDisclaimer'; import { useRoutingConfigActions, useRoutingSettings, } from '@/client/Routing/provider/RoutingConfigProvider'; import type { RoutingSettings } from '@/client/Routing/provider/RoutingConfigProvider'; -import { AllowedHafasProfile } from '@/types/HAFAS'; import AllInclusive from '@mui/icons-material/AllInclusive'; import Cached from '@mui/icons-material/Cached'; import ExpandMore from '@mui/icons-material/ExpandMore'; @@ -17,10 +14,7 @@ import { AccordionSummary, Badge, Chip, - FormControl, FormControlLabel, - MenuItem, - Select, Stack, Switch, TextField, @@ -28,7 +22,7 @@ import { styled, } from '@mui/material'; import type { SelectChangeEvent } from '@mui/material'; -import { useCallback, useMemo, useState } from 'react'; +import { useCallback, useMemo } from 'react'; import type { ChangeEvent, FC } from 'react'; const StyledAccordion = styled(Accordion)` @@ -57,8 +51,6 @@ const inputCss = css` export const SettingsPanel: FC = () => { const settings = useRoutingSettings(); - const [showNetzcardDisclaimer, setShowNetzcardDisclaimer] = useState(false); - const [showBC100Disclaimer, setShowBC100Disclaimer] = useState(false); const { updateSettings } = useRoutingConfigActions(); const handleInputChange = useCallback( (key: keyof RoutingSettings) => (e: ChangeEvent) => @@ -71,21 +63,6 @@ export const SettingsPanel: FC = () => { }, [updateSettings], ); - const handleNetzcard = useCallback( - (_: unknown, checked: boolean) => { - updateSettings('onlyNetzcard', checked); - setShowNetzcardDisclaimer(checked); - }, - [updateSettings], - ); - - const handleBC100 = useCallback( - (_: unknown, checked: boolean) => { - updateSettings('onlyBC100', checked); - setShowBC100Disclaimer(checked); - }, - [updateSettings], - ); const handleHafasProfile = useCallback( (event: SelectChangeEvent) => { @@ -104,23 +81,12 @@ export const SettingsPanel: FC = () => { }, [settings.maxChanges]); let filterLabel = 'Alle Zuege'; - if (settings.onlyNetzcard && settings.onlyRegional) { - filterLabel = 'Nahverkehr (Netzcard)'; - } - if (settings.onlyNetzcard) { - filterLabel = 'Netzcard'; - } if (settings.onlyRegional) { filterLabel = 'Nahverkehr'; } - if (settings.onlyBC100) { - filterLabel = 'BC100'; - } return ( <> - {showNetzcardDisclaimer && } - {showBC100Disclaimer && } { } label="Nur Regionalzüge" /> - - - bahn.de - - Business DB Navigator (Legacy) - - - OEBB Scotty - - - } - label="Datenlieferant" - /> - - - - } - label="Netzcard erlaubt" - /> - - - } - label="BC100 erlaubt" - /> diff --git a/src/client/Routing/provider/RoutingConfigProvider.tsx b/src/client/Routing/provider/RoutingConfigProvider.tsx index 1184d0e60..b52d0c35a 100644 --- a/src/client/Routing/provider/RoutingConfigProvider.tsx +++ b/src/client/Routing/provider/RoutingConfigProvider.tsx @@ -1,6 +1,5 @@ import { useExpertCookies } from '@/client/Common/hooks/useExpertCookies'; import constate from '@/constate'; -import { AllowedHafasProfile } from '@/types/HAFAS'; import type { MinimalStopPlace } from '@/types/stopPlace'; import { useCallback, useMemo, useState } from 'react'; import type { PropsWithChildren, SyntheticEvent } from 'react'; @@ -9,19 +8,11 @@ export interface RoutingSettings { maxChanges: string; transferTime: string; onlyRegional: boolean; - onlyNetzcard: boolean; - onlyBC100: boolean; - hafasProfileN?: - | AllowedHafasProfile.DB - | AllowedHafasProfile.OEBB - | AllowedHafasProfile.BAHN; } const routingConfigKeys = [ 'maxChanges', 'transferTime', 'onlyRegional', - 'onlyNetzcard', - 'hafasProfileN', ] as (keyof RoutingSettings)[]; const useRoutingConfigInternal = ({ @@ -160,9 +151,6 @@ export const RoutingConfigProvider: FCC<{ maxChanges: routingConfig.maxChanges?.toString() ?? '-1', transferTime: routingConfig.transferTime?.toString() ?? '0', onlyRegional: routingConfig.onlyRegional ?? false, - onlyNetzcard: routingConfig.onlyNetzcard ?? false, - onlyBC100: routingConfig.onlyBC100 ?? false, - hafasProfileN: routingConfig.hafasProfileN ?? AllowedHafasProfile.BAHN, }; return ( diff --git a/src/client/Routing/provider/useFetchRouting.ts b/src/client/Routing/provider/useFetchRouting.ts index 0780c240e..4d03a1c66 100644 --- a/src/client/Routing/provider/useFetchRouting.ts +++ b/src/client/Routing/provider/useFetchRouting.ts @@ -6,7 +6,6 @@ import { useRouting } from '@/client/Routing/provider/RoutingProvider'; import { useRoutingNavigate } from '@/client/Routing/util'; import { uniqBy } from '@/client/util'; import { trpc } from '@/router'; -import { AllowedHafasProfile } from '@/types/HAFAS'; import type { RoutingResult } from '@/types/routing'; import type { MinimalStopPlace } from '@/types/stopPlace'; import { useCallback } from 'react'; @@ -65,44 +64,26 @@ export const useFetchRouting = () => { setRoutes(undefined); let routingResult: RoutingResult; try { - if (routeSettings.hafasProfileN !== AllowedHafasProfile.BAHN) { - routingResult = await trpcUtils.hafas.tripSearch.fetch( - { - time: touchedDate ? date : new Date(), - searchForDeparture: departureMode === 'ab', - ...routeSettings, - }, - { - // @ts-expect-error needs https://github.com/trpc/trpc/issues/6028 - trpc: { - context: { - skipBatch: true, - }, - }, - }, - ); - } else { - routingResult = await trpcUtils.bahn.routing.fetch( - { - time: touchedDate ? date : new Date(), - searchForDeparture: departureMode === 'ab', - maxChanges: routeSettings.maxChanges, - start: routeSettings.start, - destination: routeSettings.destination, - onlyRegional: routeSettings.onlyRegional, - transferTime: routeSettings.transferTime, - via: routeSettings.via, - }, - { - // @ts-expect-error needs https://github.com/trpc/trpc/issues/6028 - trpc: { - context: { - skipBatch: true, - }, + routingResult = await trpcUtils.bahn.routing.fetch( + { + time: touchedDate ? date : new Date(), + searchForDeparture: departureMode === 'ab', + maxChanges: routeSettings.maxChanges, + start: routeSettings.start, + destination: routeSettings.destination, + onlyRegional: routeSettings.onlyRegional, + transferTime: routeSettings.transferTime, + via: routeSettings.via, + }, + { + // @ts-expect-error needs https://github.com/trpc/trpc/issues/6028 + trpc: { + context: { + skipBatch: true, }, }, - ); - } + }, + ); setRoutes(routingResult.routes); setEarlierContext(routingResult.context.earlier); @@ -112,7 +93,6 @@ export const useFetchRouting = () => { } }, [ - trpcUtils.hafas.tripSearch, trpcUtils.bahn.routing, date, setEarlierContext, @@ -146,44 +126,27 @@ export const useFetchRouting = () => { let routingResult: RoutingResult; try { - if (routeSettings.hafasProfileN === AllowedHafasProfile.BAHN) { - routingResult = await trpcUtils.bahn.routing.fetch( - { - time: touchedDate ? date : new Date(), - searchForDeparture: departureMode === 'ab', - maxChanges: routeSettings.maxChanges, - start: routeSettings.start, - destination: routeSettings.destination, - onlyRegional: routeSettings.onlyRegional, - transferTime: routeSettings.transferTime, - via: routeSettings.via, - ctxScr: type === 'earlier' ? earlierContext : laterContext, - }, - { - // @ts-expect-error needs https://github.com/trpc/trpc/issues/6028 - trpc: { - context: { - skipBatch: true, - }, - }, - }, - ); - } else { - routingResult = await trpcUtils.hafas.tripSearch.fetch( - { - ctxScr: type === 'earlier' ? earlierContext : laterContext, - ...routeSettings, - }, - { - // @ts-expect-error needs https://github.com/trpc/trpc/issues/6028 - trpc: { - context: { - skipBatch: true, - }, + routingResult = await trpcUtils.bahn.routing.fetch( + { + time: touchedDate ? date : new Date(), + searchForDeparture: departureMode === 'ab', + maxChanges: routeSettings.maxChanges, + start: routeSettings.start, + destination: routeSettings.destination, + onlyRegional: routeSettings.onlyRegional, + transferTime: routeSettings.transferTime, + via: routeSettings.via, + ctxScr: type === 'earlier' ? earlierContext : laterContext, + }, + { + // @ts-expect-error needs https://github.com/trpc/trpc/issues/6028 + trpc: { + context: { + skipBatch: true, }, }, - ); - } + }, + ); setRoutes((oldRoutes = []) => { const newRoutes = @@ -204,7 +167,6 @@ export const useFetchRouting = () => { } }, [ - trpcUtils.hafas.tripSearch, trpcUtils.bahn.routing, date, touchedDate, diff --git a/src/external/risJourneys.ts b/src/external/risJourneys.ts index 85d0f1a41..3713fce92 100644 --- a/src/external/risJourneys.ts +++ b/src/external/risJourneys.ts @@ -8,7 +8,7 @@ import type { import type { StopPlaceEmbedded } from '@/external/generated/risJourneysV2'; import { sortJourneys } from '@/external/risJourneysV2'; import { axiosUpstreamInterceptor } from '@/server/admin'; -import { Cache, CacheDatabase } from '@/server/cache'; +import { CacheDatabase, getCache } from '@/server/cache'; import { logger } from '@/server/logger'; import type { ParsedProduct } from '@/types/HAFAS'; import type { ParsedJourneyMatchResponse } from '@/types/HAFAS/JourneyMatch'; @@ -26,9 +26,9 @@ const risJourneysConfiguration = new RisJourneysConfiguration({ }, }); -const journeyFindCache = new Cache(CacheDatabase.JourneyFind); +const journeyFindCache = getCache(CacheDatabase.JourneyFind); -const journeyCache = new Cache(CacheDatabase.Journey); +const journeyCache = getCache(CacheDatabase.Journey); logger.info( `using ${process.env.RIS_JOURNEYS_USER_AGENT} as RIS::Journeys UserAgent`, diff --git a/src/external/risJourneysV2.ts b/src/external/risJourneysV2.ts index 36cd4803e..57cd2f1d1 100644 --- a/src/external/risJourneysV2.ts +++ b/src/external/risJourneysV2.ts @@ -12,7 +12,7 @@ import type { } from '@/external/generated/risJourneysV2'; import { getStopPlaceByEva } from '@/server/StopPlace/search'; import { axiosUpstreamInterceptor } from '@/server/admin'; -import { Cache, CacheDatabase } from '@/server/cache'; +import { CacheDatabase, getCache } from '@/server/cache'; import type { ParsedProduct } from '@/types/HAFAS'; import type { ParsedJourneyMatchResponse } from '@/types/HAFAS/JourneyMatch'; import type { RouteStop } from '@/types/routing'; @@ -39,11 +39,9 @@ const client = new JourneysApi( axiosWithTimeout, ); -const journeyFindCache = new Cache( - CacheDatabase.JourneyFindV2, -); +const journeyFindCache = getCache(CacheDatabase.JourneyFindV2); -const journeyCache = new Cache(CacheDatabase.JourneyV2); +const journeyCache = getCache(CacheDatabase.JourneyV2); export const health = { has401: false, diff --git a/src/external/risMaps.ts b/src/external/risMaps.ts index 9c81201f8..72cb15492 100644 --- a/src/external/risMaps.ts +++ b/src/external/risMaps.ts @@ -1,10 +1,6 @@ -import { - Configuration, - type VehicleLayoutFeatureCollection, - VehicleLayoutsApi, -} from '@/external/generated/risMaps'; +import { Configuration, VehicleLayoutsApi } from '@/external/generated/risMaps'; import { axiosUpstreamInterceptor } from '@/server/admin'; -import { Cache, CacheDatabase } from '@/server/cache'; +import { CacheDatabase, getCache } from '@/server/cache'; import axios, { isAxiosError } from 'axios'; const risConnectionsConfiguration = new Configuration({ @@ -29,9 +25,7 @@ const mapsClient = new VehicleLayoutsApi( axiosWithTimeout, ); -const cache = new Cache( - CacheDatabase.VehicleLayoutsMaps, -); +const cache = getCache(CacheDatabase.VehicleLayoutsMaps); export async function getVehicleLayout(vehicleId: string) { if (await cache.exists(vehicleId)) { diff --git a/src/external/risTransports/occupancy.ts b/src/external/risTransports/occupancy.ts index d34b3e159..d859daf69 100644 --- a/src/external/risTransports/occupancy.ts +++ b/src/external/risTransports/occupancy.ts @@ -1,10 +1,7 @@ -import { - type JourneyOccupancy, - OccupanciesApi, -} from '@/external/generated/risTransports'; +import { OccupanciesApi } from '@/external/generated/risTransports'; import { risTransportsConfiguration } from '@/external/risTransports/config'; import { axiosUpstreamInterceptor } from '@/server/admin'; -import { Cache, CacheDatabase } from '@/server/cache'; +import { CacheDatabase, getCache } from '@/server/cache'; import { Temporal } from '@js-temporal/polyfill'; import Axios from 'axios'; const axiosWithTimeout = Axios.create({ @@ -39,9 +36,7 @@ if (process.env.NODE_ENV === 'production') { ); } -const occupancyCache = new Cache( - CacheDatabase.TransportsOccupancy, -); +const occupancyCache = getCache(CacheDatabase.TransportsOccupancy); export async function getJourneyOccupancy({ journeyId, diff --git a/src/external/risTransports/sequence.ts b/src/external/risTransports/sequence.ts index 2dcd2468e..c05f53b17 100644 --- a/src/external/risTransports/sequence.ts +++ b/src/external/risTransports/sequence.ts @@ -5,7 +5,7 @@ import { risTransportsConfiguration, } from '@/external/risTransports/config'; import { axiosUpstreamInterceptor } from '@/server/admin'; -import { Cache, CacheDatabase } from '@/server/cache'; +import { CacheDatabase, getCache } from '@/server/cache'; import { logger } from '@/server/logger'; import { Temporal } from '@js-temporal/polyfill'; import Axios from 'axios'; @@ -47,7 +47,7 @@ if (process.env.NODE_ENV === 'production') { ); } -const negativeHitCache = new Cache(CacheDatabase.NegativeNewSequence); +const negativeHitCache = getCache(CacheDatabase.NegativeNewSequence); export async function getDepartureSequence( trainCategory: string, diff --git a/src/external/risTransports/vehicles.ts b/src/external/risTransports/vehicles.ts index 110bf512f..81535cde8 100644 --- a/src/external/risTransports/vehicles.ts +++ b/src/external/risTransports/vehicles.ts @@ -1,14 +1,11 @@ import { uniqBy } from '@/client/util'; -import { - type MatchVehicleID, - VehiclesApi, -} from '@/external/generated/risTransports'; +import { VehiclesApi } from '@/external/generated/risTransports'; import { isWithin20Hours, risTransportsConfiguration, } from '@/external/risTransports/config'; import { axiosUpstreamInterceptor } from '@/server/admin'; -import { Cache, CacheDatabase } from '@/server/cache'; +import { CacheDatabase, getCache } from '@/server/cache'; import { journeyDetails } from '@/server/journeys/v2/journeyDetails'; import Axios from 'axios'; import { addDays, format, isBefore, subDays } from 'date-fns'; @@ -19,13 +16,7 @@ const axiosWithTimeout = Axios.create({ axiosUpstreamInterceptor(axiosWithTimeout, 'vehicles-risTransports'); -type CacheType = { - previousJourneys: MatchVehicleID[]; - nextJourneys: MatchVehicleID[]; -}; -const journeyForVehiclesCache = new Cache( - CacheDatabase.JourneysForVehicle, -); +const journeyForVehiclesCache = getCache(CacheDatabase.JourneysForVehicle); const vehiclesClient = new VehiclesApi( risTransportsConfiguration, diff --git a/src/routes/_abfahrten/index.tsx b/src/routes/_abfahrten/index.tsx index 184f10ca9..d0f62f246 100644 --- a/src/routes/_abfahrten/index.tsx +++ b/src/routes/_abfahrten/index.tsx @@ -6,5 +6,5 @@ export const Route = createFileRoute('/_abfahrten/')({ }); function RouteComponent() { - return ; + return ; } diff --git a/src/server/HAFAS/Detail.ts b/src/server/HAFAS/Detail.ts index eb8455074..7cef1e564 100644 --- a/src/server/HAFAS/Detail.ts +++ b/src/server/HAFAS/Detail.ts @@ -1,14 +1,6 @@ -import { HafasJourneyDetails } from '@/server/HAFAS/JourneyDetails'; -import JourneyMatch from '@/server/HAFAS/JourneyMatch'; -import createCtxRecon from '@/server/HAFAS/helper/createCtxRecon'; -import { addIrisMessagesToDetails } from '@/server/journeys/journeyDetails'; -import { AllowedHafasProfile } from '@/types/HAFAS'; -import type { ParsedJourneyDetails } from '@/types/HAFAS/JourneyDetails'; -import type { ParsedJourneyMatchResponse } from '@/types/HAFAS/JourneyMatch'; import type { ParsedSearchOnTripResponse } from '@/types/HAFAS/SearchOnTrip'; import type { RouteStop } from '@/types/routing'; import { isAfter } from 'date-fns'; -import searchOnTrip from './SearchOnTrip'; export function calculateCurrentStopPlace( segment: ParsedSearchOnTripResponse, @@ -36,150 +28,3 @@ export function calculateCurrentStopPlace( return currentStop; } - -const filterByAdministration = ( - journeys: ParsedJourneyMatchResponse[], - administration?: string, -) => { - if (!administration) return journeys; - return journeys.filter( - (j) => j.train.admin?.replaceAll('_', '') === administration, - ); -}; - -export default async ( - trainName: string, - currentStopId?: string, - station?: string, - date: Date = new Date(), - plainDetails = false, - hafasProfile: AllowedHafasProfile = AllowedHafasProfile.DB, - administration?: string, - jid?: string, -): Promise => { - let journeyDetails: ParsedJourneyDetails | undefined; - if (!jid) { - let possibleTrains: ParsedJourneyMatchResponse[] = []; - - possibleTrains = await JourneyMatch( - { - trainName, - initialDepartureDate: date, - }, - hafasProfile, - ); - possibleTrains = filterByAdministration(possibleTrains, administration); - - if (!possibleTrains.length) { - return undefined; - } - - if (station) { - while (!journeyDetails && possibleTrains.length) { - const currentTrain = possibleTrains.shift()!; - const maybeJourneyDetails = await HafasJourneyDetails( - currentTrain.jid, - hafasProfile, - ); - if (!maybeJourneyDetails) { - break; - } - for (const stop of maybeJourneyDetails.stops) { - if (stop.station.evaNumber === station) { - journeyDetails = maybeJourneyDetails; - break; - } - } - } - } else { - journeyDetails = await HafasJourneyDetails( - possibleTrains[0].jid, - hafasProfile, - ); - } - } else { - journeyDetails = await HafasJourneyDetails(jid, hafasProfile); - } - - if (!journeyDetails) return undefined; - - let relevantSegment: ParsedSearchOnTripResponse = { - type: 'JNY', - cancelled: journeyDetails.stops.every((s) => s.cancelled), - finalDestination: journeyDetails.lastStop.station.name, - jid: journeyDetails.jid, - train: journeyDetails.train, - segmentDestination: journeyDetails.lastStop.station, - segmentStart: journeyDetails.firstStop.station, - stops: journeyDetails.stops, - messages: journeyDetails.messages, - arrival: journeyDetails.lastStop.arrival, - departure: journeyDetails.firstStop.departure, - polyline: journeyDetails.polylines?.[0], - }; - if (plainDetails) { - return relevantSegment; - } - - try { - const route = await searchOnTrip( - { - ctxRecon: createCtxRecon({ - firstStop: journeyDetails.firstStop, - lastStop: journeyDetails.lastStop, - trainName: journeyDetails.train.name, - messages: journeyDetails.messages, - }), - sotMode: 'RC', - }, - hafasProfile, - ); - - relevantSegment = route.segments.find((s) => s.type === 'JNY')!; - } catch { - // we keep using the JourneyDetailsOne - } - - if (relevantSegment.stops.length !== journeyDetails.stops.length) { - for (const [index, stop] of journeyDetails.stops.entries()) { - if (stop.additional) { - relevantSegment.stops.splice(index, 0, stop); - } - } - } - - const lastStop = relevantSegment.stops - .filter((s) => s.arrival && !s.arrival.cancelled) - .pop(); - - if (currentStopId) { - relevantSegment.currentStop = relevantSegment.stops.find( - (s) => s.station.evaNumber === currentStopId, - ); - } - - if (lastStop?.arrival?.delay == null) { - for (const [index, stop] of relevantSegment.stops.entries()) { - const jDetailStop = journeyDetails.stops[index]; - - if (jDetailStop.station.evaNumber !== stop.station.evaNumber) continue; - if (jDetailStop.arrival && stop.arrival) { - stop.arrival.delay = jDetailStop.arrival.delay; - stop.arrival.time = jDetailStop.arrival.time; - } - if (jDetailStop.departure && stop.departure) { - stop.departure.delay = jDetailStop.departure.delay; - stop.departure.time = jDetailStop.departure.time; - } - } - } - - relevantSegment.currentStop = calculateCurrentStopPlace( - relevantSegment, - currentStopId, - ); - - await addIrisMessagesToDetails(relevantSegment); - - return relevantSegment; -}; diff --git a/src/server/HAFAS/HimSearch.ts b/src/server/HAFAS/HimSearch.ts deleted file mode 100644 index da8e1d3fe..000000000 --- a/src/server/HAFAS/HimSearch.ts +++ /dev/null @@ -1,93 +0,0 @@ -import makeRequest from '@/server/HAFAS/Request'; -import parseTime from '@/server/HAFAS/helper/parseTime'; -import { Cache, CacheDatabase } from '@/server/cache'; -import { logger } from '@/server/logger'; -import type { - AllowedHafasProfile, - HafasResponse, - ParsedCommon, -} from '@/types/HAFAS'; -import type { - HimMessage, - HimSearchRequest, - HimSearchResponse, - ParsedHimMessage, - ParsedHimSearchResponse, -} from '@/types/HAFAS/HimSearch'; -import { parse } from 'date-fns'; - -const parseHimMessage = (himMessage: HimMessage, common: ParsedCommon) => { - const head = himMessage.head.replaceAll(` (Quelle: ${himMessage.comp})`, ''); - return { - ...himMessage, - head: head.endsWith('.') ? head.slice(0, -1) : head, - affectedProducts: - himMessage.affProdRefL?.map((prodRef) => common.prodL[prodRef]) ?? [], - startTime: parseTime( - parse(himMessage.sDate, 'yyyyMMdd', Date.now()), - himMessage.sTime, - ), - endTime: parseTime( - parse(himMessage.eDate, 'yyyyMMdd', Date.now()), - himMessage.eTime, - ), - fromStopPlace: common.locL[himMessage.fLocX], - toStopPlace: common.locL[himMessage.tLocX], - }; -}; -const parseHimSearch = ( - d: HafasResponse, - common: ParsedCommon, -): Promise => { - return Promise.resolve({ - messages: - d.svcResL[0].res?.msgL?.map((m) => parseHimMessage(m, common)) ?? [], - }); -}; - -const HimSearch = ( - request: HimSearchRequest['req'], - profile?: AllowedHafasProfile, - raw?: boolean, -): Promise => { - const req: HimSearchRequest = { - req: request, - meth: 'HimSearch', - }; - return makeRequest(req, raw ? undefined : parseHimSearch, profile); -}; - -const himMessageCache = new Cache(CacheDatabase.HIMMessage); - -const maxNum = Number.parseInt(process.env.HIM_MAX_FETCH || '5000', 10); - -async function fetchTodaysHimMessages() { - try { - logger.debug('Fetching HimMessages'); - const messages = await HimSearch({ - onlyToday: true, - maxNum, - }); - - if (!messages.messages) return; - - for (const message of messages.messages) { - await himMessageCache.set(message.hid, message); - } - logger.debug(`fetched ${messages.messages.length} HIM Messages`); - } catch { - logger.error('HIM Messages fetch failed'); - } -} - -// if (process.env.NODE_ENV !== 'test') { -// void fetchTodaysHimMessages(); -// setInterval( -// fetchTodaysHimMessages, -// Temporal.Duration.from('PT5M').total('millisecond'), -// ); -// } - -export const getSingleHimMessageOfToday = ( - hid: string, -): Promise => himMessageCache.get(hid); diff --git a/src/server/HAFAS/JourneyDetails.ts b/src/server/HAFAS/JourneyDetails.ts deleted file mode 100644 index e2b74ea45..000000000 --- a/src/server/HAFAS/JourneyDetails.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { adjustProductOperator } from '@/server/HAFAS/helper/adjustProductOperator'; -import type { - AllowedHafasProfile, - HafasResponse, - ParsedCommon, -} from '@/types/HAFAS'; -import type { - JourneyDetailsRequest, - JourneyDetailsResponse, - ParsedJourneyDetails, -} from '@/types/HAFAS/JourneyDetails'; -import { parse } from 'date-fns'; -import makeRequest from './Request'; -import parseAuslastung from './helper/parseAuslastung'; -import parseMessages from './helper/parseMessages'; -import parseStop from './helper/parseStop'; - -export const parseJourneyDetails = ( - d: HafasResponse, - common: ParsedCommon, -): Promise => { - const journey = d.svcResL[0].res.journey; - const mainProduct = common.prodL[journey.prodX]; - adjustProductOperator(mainProduct, common, journey.stopL); - - const date = parse(journey.date, 'yyyyMMdd', new Date()); - if (!mainProduct.name) { - mainProduct.name = `${mainProduct.type} ${mainProduct.number}`; - } - const stops = journey.stopL.map((stop) => parseStop(stop, common, date)); - if (!stops.length) { - return Promise.resolve(undefined); - } - - const parsedJourney = { - train: mainProduct, - auslastung: parseAuslastung(journey.dTrnCmpSX, common.tcocL), - jid: journey.jid, - stops, - firstStop: stops[0], - lastStop: stops.at(-1), - messages: parseMessages(journey.msgL, common), - polylines: common.polyL, - }; - - return Promise.resolve(parsedJourney as ParsedJourneyDetails); -}; - -export const HafasJourneyDetails = async ( - jid: string, - profile?: AllowedHafasProfile, - raw?: boolean, -): Promise => { - const req: JourneyDetailsRequest = { - req: { jid, getPolyline: true, polySplitting: true }, - meth: 'JourneyDetails', - }; - - try { - const result = await makeRequest( - req, - raw ? undefined : parseJourneyDetails, - profile, - ); - return result; - } catch { - return undefined; - } -}; diff --git a/src/server/HAFAS/JourneyMatch.ts b/src/server/HAFAS/JourneyMatch.ts deleted file mode 100644 index f7534f36d..000000000 --- a/src/server/HAFAS/JourneyMatch.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { HafasJourneyDetails } from '@/server/HAFAS/JourneyDetails'; -import { Cache, CacheDatabase } from '@/server/cache'; -import { AllowedHafasProfile } from '@/types/HAFAS'; -import type { HafasResponse, ParsedCommon } from '@/types/HAFAS'; -import type { - EnrichedJourneyMatchOptions, - JourneyMatchOptions, - JourneyMatchRequest, - JourneyMatchResponse, - ParsedJourneyMatchResponse, -} from '@/types/HAFAS/JourneyMatch'; -import { format, parse, subDays } from 'date-fns'; -import makeRequest, { HafasError } from './Request'; -import parseMessages from './helper/parseMessages'; -import parseStop from './helper/parseStop'; - -const journeyMatchCache = new Cache( - CacheDatabase.HAFASJourneyMatch, -); - -const parseJourneyMatch = ( - d: HafasResponse, - common: ParsedCommon, -): Promise => { - return Promise.all( - d.svcResL[0].res.jnyL.map((j) => { - const date = parse(j.date, 'yyyyMMdd', new Date()); - const train = common.prodL[j.prodX]; - const stops = j.stopL.map((stop) => parseStop(stop, common, date)); - - return { - train, - stops, - jid: j.jid, - firstStop: stops[0], - lastStop: stops.at(-1)!, - messages: parseMessages(j.msgL, common), - }; - }), - ); -}; - -const JourneyMatch = async ( - { - trainName, - initialDepartureDate, - withOEV, - }: Omit & { - withOEV?: boolean; - }, - profile: AllowedHafasProfile = AllowedHafasProfile.DB, - raw?: boolean, -): Promise => { - let date = initialDepartureDate; - - if (!date) { - const now = new Date(); - - date = now.getHours() < 3 ? subDays(now, 1) : now; - } - - const formattedDate = format(date, 'yyyyMMdd'); - const cacheKey = `${trainName}-${formattedDate}-${withOEV}-${profile}`; - try { - if (!raw) { - const cached = await journeyMatchCache.get(cacheKey); - if (cached) { - return cached; - } - } - const req: JourneyMatchRequest = { - req: { - date: formattedDate, - input: trainName, - jnyFltrL: withOEV - ? undefined - : [ - { - mode: 'INC', - type: 'PROD', - value: '31', - }, - ], - onlyRT: false, - }, - meth: 'JourneyMatch', - }; - - const result = await makeRequest( - req, - raw ? undefined : parseJourneyMatch, - profile, - ); - - if (!raw) { - const shorterTTL = !result.length ? 'PT2H' : undefined; - void journeyMatchCache.set(cacheKey, result, shorterTTL); - } - - return result; - } catch (e) { - if (e instanceof HafasError && e.errorCode === 'NO_MATCH') { - void journeyMatchCache.set(cacheKey, [], 'PT1H'); - } - // We just ignore errors and pretend nothing got returned. - return []; - } -}; - -export default JourneyMatch; - -const fallbackTypeRegex = /(.+?)( |\d|\b).*\d+/; - -export async function enrichedJourneyMatch( - { - withOEV, - ...options - }: Omit & { - withOEV?: boolean; - }, - profile?: AllowedHafasProfile, -): Promise { - const journeyMatches = (await JourneyMatch(options, profile)).filter( - (match) => match.train.type !== 'Flug', - ); - - const limitedJourneyMatches = options.limit - ? journeyMatches.slice(0, options.limit) - : journeyMatches; - - for (const j of limitedJourneyMatches) { - const details = await HafasJourneyDetails(j.jid, profile); - if (!details) continue; - - j.firstStop = details.firstStop; - j.lastStop = details.lastStop; - j.stops = details.stops; - // j.train = details.train; - - if (!j.train.type) { - j.train.type = fallbackTypeRegex.exec(j.train.name)?.[1]; - } - } - - return limitedJourneyMatches; -} diff --git a/src/server/HAFAS/LocMatch.ts b/src/server/HAFAS/LocMatch.ts deleted file mode 100644 index ac23ce16f..000000000 --- a/src/server/HAFAS/LocMatch.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { Cache, CacheDatabase } from '@/server/cache'; -import type { - AllowedHafasProfile, - HafasResponse, - HafasStation, - ParsedCommon, -} from '@/types/HAFAS'; -import type { LocMatchRequest, LocMatchResponse } from '@/types/HAFAS/LocMatch'; -import makeRequest from './Request'; -import { parseLocL } from './helper/parseLocL'; - -const cache = new Cache(CacheDatabase.LocMatch); - -function parseFn( - d: HafasResponse, - parsedCommon: ParsedCommon, -): Promise { - const stations = d.svcResL[0].res.match.locL; - - return Promise.all( - stations - // .filter(s => s.extId) - .map((s) => parseLocL(s, parsedCommon.prodL)), - ); -} - -export const locMatch = async ( - searchTerm: string, - type: 'S' | 'ALL', - profile?: AllowedHafasProfile, - raw?: boolean, -): Promise => { - const req: LocMatchRequest = { - req: { - input: { - loc: { - name: searchTerm, - type, - }, - field: 'S', - }, - }, - meth: 'LocMatch', - }; - - if (raw) { - return makeRequest(req, undefined, profile) as any; - } - - const cacheKey = `${profile}:${type}:${searchTerm}`; - const cached = await cache.get(cacheKey); - - if (cached) { - return cached; - } - - const result = await makeRequest(req, raw ? undefined : parseFn, profile); - - void cache.set(cacheKey, result); - - return result; -}; diff --git a/src/server/HAFAS/Request.ts b/src/server/HAFAS/Request.ts deleted file mode 100644 index 1b7e15f76..000000000 --- a/src/server/HAFAS/Request.ts +++ /dev/null @@ -1,169 +0,0 @@ -import parsePolyline from '@/server/HAFAS/helper/parsePolyline'; -import { UpstreamApiRequestMetric } from '@/server/admin'; -import { AllowedHafasProfile } from '@/types/HAFAS'; -import type { - Common, - GenericHafasRequest, - GenericRes, - HafasResponse, - ParsedCommon, - SingleHafasRequest, -} from '@/types/HAFAS'; -import type { - HimSearchRequest, - HimSearchResponse, -} from '@/types/HAFAS/HimSearch'; -import type { - JourneyDetailsRequest, - JourneyDetailsResponse, -} from '@/types/HAFAS/JourneyDetails'; -import type { - JourneyMatchRequest, - JourneyMatchResponse, -} from '@/types/HAFAS/JourneyMatch'; -import type { LocMatchRequest, LocMatchResponse } from '@/types/HAFAS/LocMatch'; -import type { - SearchOnTripRequest, - SearchOnTripResponse, -} from '@/types/HAFAS/SearchOnTrip'; -import type { - StationBoardRequest, - StationBoardResponse, -} from '@/types/HAFAS/StationBoard'; -import type { - TripSearchRequest, - TripSearchResponse, -} from '@/types/HAFAS/TripSearch'; -import { TRPCError } from '@trpc/server'; -import Axios from 'axios'; -import { parseLocL } from './helper/parseLocL'; -import parseProduct from './helper/parseProduct'; -import * as HafasProfiles from './profiles'; - -function createRequest( - req: SingleHafasRequest, - profileType: AllowedHafasProfile, -) { - const profile = HafasProfiles[profileType]; - const data: any = profile.config; - - const auth = data.auth; - - data.auth = undefined; - - data.svcReqL = [req]; - - data.auth = auth; - - const extraParam = 'secret' in profile ? profile.secret(data) : undefined; - - return { - data, - extraParam, - }; -} - -async function parseCommon(common: Common): Promise { - const prodL = common.prodL.map((p) => parseProduct(p, common)); - const locL = await Promise.all(common.locL.map((l) => parseLocL(l, prodL))); - const polyL = common.polyL?.map((p) => parsePolyline(p, locL)); - - return { - ...common, - locL, - prodL, - polyL, - }; -} - -export class HafasError extends TRPCError { - customError = true; - data: { - request: SingleHafasRequest; - response: HafasResponse; - profile: AllowedHafasProfile; - }; - errorCode: string | undefined; - constructor( - request: SingleHafasRequest, - response: HafasResponse, - profile: AllowedHafasProfile, - ) { - super({ - message: `${request.meth} HAFAS Error`, - code: 'INTERNAL_SERVER_ERROR', - }); - Error.captureStackTrace(this, HafasError); - if (response?.svcResL?.length) { - this.errorCode = response.svcResL[0].err; - this.message = response.svcResL[0].err; - } - this.data = { - request, - response, - profile, - }; - } -} - -type CommonHafasResponse< - T extends string, - R extends GenericHafasRequest, -> = R extends TripSearchRequest - ? TripSearchResponse - : R extends StationBoardRequest - ? StationBoardResponse - : R extends HimSearchRequest - ? HimSearchResponse - : R extends JourneyMatchRequest - ? JourneyMatchResponse - : R extends LocMatchRequest - ? LocMatchResponse - : R extends JourneyDetailsRequest - ? JourneyDetailsResponse - : R extends SearchOnTripRequest - ? SearchOnTripResponse - : never; -async function makeRequest< - R extends SingleHafasRequest, - HR extends GenericRes = CommonHafasResponse, - P = HR, ->( - hafasRequest: R, - parseFn: (d: HafasResponse
, pc: ParsedCommon) => Promise

= (d) => - d as any, - profile: AllowedHafasProfile = AllowedHafasProfile.DB, -): Promise

{ - const { data, extraParam } = createRequest(hafasRequest, profile); - - if (process.env.NODE_ENV === 'test') { - // biome-ignore lint/suspicious/noConsoleLog: test - console.log(JSON.stringify(hafasRequest)); - // biome-ignore lint/suspicious/noConsoleLog: test - console.log(extraParam); - } - UpstreamApiRequestMetric.inc({ - api: `hafas-${hafasRequest.meth}`, - }); - - const r = ( - await Axios.post>(HafasProfiles[profile].url, data, { - params: extraParam, - }) - ).data; - - if (('err' in r && r.err !== 'OK') || r.svcResL[0].err !== 'OK') { - throw new HafasError(hafasRequest, r, profile); - } - - const rawCommon = r.svcResL[0].res.common; - - if (!rawCommon) { - throw new HafasError(hafasRequest, r, profile); - } - const parsedCommon = await parseCommon(rawCommon); - - return parseFn(r, parsedCommon); -} - -export default makeRequest; diff --git a/src/server/HAFAS/SearchOnTrip.ts b/src/server/HAFAS/SearchOnTrip.ts deleted file mode 100644 index 7dbc98f64..000000000 --- a/src/server/HAFAS/SearchOnTrip.ts +++ /dev/null @@ -1,33 +0,0 @@ -import type { - AllowedHafasProfile, - HafasResponse, - ParsedCommon, -} from '@/types/HAFAS'; -import type { - SearchOnTripRequest, - SearchOnTripResponse, -} from '@/types/HAFAS/SearchOnTrip'; -import type { SingleRoute } from '@/types/routing'; -import makeRequest from './Request'; -import { Journey } from './TripSearch/parse'; - -const parseSearchOnTrip = ( - d: HafasResponse, - common: ParsedCommon, -) => { - const joruney = new Journey(d.svcResL[0].res.outConL[0], common); - return joruney.parseJourney(); -}; - -export default ( - req: SearchOnTripRequest['req'], - profile?: AllowedHafasProfile, - raw?: boolean, -): Promise => { - const request: SearchOnTripRequest = { - req, - meth: 'SearchOnTrip', - }; - - return makeRequest(request, raw ? undefined : parseSearchOnTrip, profile); -}; diff --git a/src/server/HAFAS/StationBoard/StationBoardToTimetables.ts b/src/server/HAFAS/StationBoard/StationBoardToTimetables.ts deleted file mode 100644 index b86588ac2..000000000 --- a/src/server/HAFAS/StationBoard/StationBoardToTimetables.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { calculateVia } from '@/server/iris/helper'; -import type { Abfahrt } from '@/types/iris'; -import type { RouteStop } from '@/types/routing'; -import type { - ArrivalStationBoardEntry, - DepartureStationBoardEntry, -} from '@/types/stationBoard'; - -export type MappedHafasArrivals = Record< - string, - ArrivalStationBoardEntry | undefined ->; - -const stationMap = (s: RouteStop) => ({ - name: s.station.name, - cancelled: s.cancelled, - additional: s.additional, -}); - -const mapDepartureRoute = (departureRoute: RouteStop[]) => { - const mapped = departureRoute.map(stationMap); - - calculateVia(mapped.slice(1)); - - return mapped; -}; - -export default ( - j: DepartureStationBoardEntry, - hafasArrivals: MappedHafasArrivals, - idSet: Set, -): Abfahrt | undefined => { - if (!j.stops) return; - - const id = `${j.jid}${j.train.number}`; - - if (idSet.has(id)) return; - idSet.add(id); - const matchingArrival = hafasArrivals[id]; - const arrivalRoute = matchingArrival?.stops?.map(stationMap) || []; - - arrivalRoute.pop(); - const splittedName = j.stops[0].station.name.split(','); - const townSuffix = `,${splittedName.at(-1)}`; - - if (j.stops.every((s) => s.station.name.endsWith(townSuffix))) { - for (const s of j.stops) - s.station.name = s.station.name.replace(townSuffix, ''); - } - - return { - initialDeparture: j.stops[0].departure!.scheduledTime, - initialStopPlace: j.stops[0].station.evaNumber, - arrival: matchingArrival?.arrival, - departure: j.departure, - currentStopPlace: { - name: j.currentStation.name, - evaNumber: j.currentStation.evaNumber, - }, - destination: j.finalDestination, - scheduledDestination: j.finalDestination, - id, - cancelled: j.cancelled, - rawId: id, - mediumId: id, - productClass: '', - messages: { - qos: [], - delay: [], - him: - j.messages?.map((m) => ({ - text: m.txtN, - head: m.txtS || 'Information', - value: -1, - })) || [], - }, - platform: j.departure.platform ?? '', - scheduledPlatform: j.departure.scheduledPlatform ?? '', - route: [...arrivalRoute, ...mapDepartureRoute(j.stops)], - train: { - type: '', - number: '', - ...j.train, - }, - }; -}; diff --git a/src/server/HAFAS/StationBoard/index.ts b/src/server/HAFAS/StationBoard/index.ts deleted file mode 100644 index 8bca5c661..000000000 --- a/src/server/HAFAS/StationBoard/index.ts +++ /dev/null @@ -1,61 +0,0 @@ -import makeRequest from '@/server/HAFAS/Request'; -import { timezone } from '@/timezone'; -import type { AllowedHafasProfile, JourneyFilter } from '@/types/HAFAS'; -import type { StationBoardRequest } from '@/types/HAFAS/StationBoard'; -import type { - ArrivalStationBoardEntry, - DepartureStationBoardEntry, - StationBoardEntry, -} from '@/types/stationBoard'; -import { format } from 'date-fns'; -import parse from './parse'; - -interface Options { - date?: Date; - direction?: string; - station: string; - type: 'ARR' | 'DEP'; - filter?: JourneyFilter[]; -} -function stationBoard( - options: Omit & { type: 'ARR' }, - profile?: AllowedHafasProfile, - raw?: boolean, -): Promise; -function stationBoard( - options: Omit & { type: 'DEP' }, - profile?: AllowedHafasProfile, - raw?: boolean, -): Promise; -function stationBoard( - { station, date = new Date(), type, direction, filter }: Options, - profile?: AllowedHafasProfile, - raw?: boolean, -): Promise { - const req: StationBoardRequest = { - req: { - type, - getPasslist: true, - maxJny: 250, - jnyFltrL: filter, - date: format(date, 'yyyyMMdd', { - in: timezone.europeBerlin, - }), - time: format(date, 'HHmmss', { - in: timezone.europeBerlin, - }), - stbLoc: { - lid: `A=1@L=${station}`, - }, - dirLoc: direction - ? { - lid: `A=1@L=${direction}`, - } - : undefined, - }, - meth: 'StationBoard', - }; - - return makeRequest(req, raw ? undefined : parse, profile); -} -export default stationBoard; diff --git a/src/server/HAFAS/StationBoard/parse.ts b/src/server/HAFAS/StationBoard/parse.ts deleted file mode 100644 index 2c16b45aa..000000000 --- a/src/server/HAFAS/StationBoard/parse.ts +++ /dev/null @@ -1,63 +0,0 @@ -import parseCommonArrival from '@/server/HAFAS/helper/parseCommonArrival'; -import parseCommonDeparture from '@/server/HAFAS/helper/parseCommonDeparture'; -import parseMessages from '@/server/HAFAS/helper/parseMessages'; -import parseStop from '@/server/HAFAS/helper/parseStop'; -import type { - CommonArrival, - CommonDeparture, - HafasResponse, - ParsedCommon, -} from '@/types/HAFAS'; -import type { - StationBoardJny, - StationBoardResponse, -} from '@/types/HAFAS/StationBoard'; -import type { StationBoardEntry } from '@/types/stationBoard'; -import { parse } from 'date-fns'; - -const isArrival = (a: CommonArrival | CommonDeparture): a is CommonArrival => - 'aOutR' in a; - -const parseStationBoardResponse = ( - jny: StationBoardJny, - common: ParsedCommon, -): StationBoardEntry => { - const date = parse(jny.date, 'yyyyMMdd', new Date()); - const product = common.prodL[jny.prodX]; - const commonResponse = { - train: product || {}, - finalDestination: jny.dirTxt, - jid: jny.jid, - cancelled: jny.isCncl, - currentStation: common.locL[jny.stbStop.locX], - stops: jny.stopL?.map((s) => parseStop(s, common, date)), - messages: parseMessages(jny.msgL, common), - }; - - if (!commonResponse.finalDestination && commonResponse.stops) { - commonResponse.finalDestination = commonResponse.stops.at(-1)!.station.name; - } - - if (isArrival(jny.stbStop)) { - return { - ...commonResponse, - arrival: parseCommonArrival(jny.stbStop, date, common), - }; - } - - return { - ...commonResponse, - departure: parseCommonDeparture(jny.stbStop, date, common), - }; -}; - -export default ( - r: HafasResponse, - parsedCommon: ParsedCommon, -): Promise => { - const abfahrten: StationBoardEntry[] = r.svcResL[0].res.jnyL.map((j) => - parseStationBoardResponse(j, parsedCommon), - ); - - return Promise.resolve(abfahrten); -}; diff --git a/src/server/HAFAS/TripSearch/NetzcardBetreiber.json b/src/server/HAFAS/TripSearch/NetzcardBetreiber.json deleted file mode 100644 index da2be607b..000000000 --- a/src/server/HAFAS/TripSearch/NetzcardBetreiber.json +++ /dev/null @@ -1,31 +0,0 @@ -[ - "DB Fernverkehr Bus", - "DB Fernverkehr AG", - "DB Regio AG", - "DB Regio AG Baden-Württemberg", - "DB Regio AG Bayern", - "DB Regio AG Mitte", - "DB Regio AG Nord", - "DB Regio AG Nordost", - "DB Regio AG NRW", - "DB Arriva", - "Sylt Shuttle Plus", - "DB Regio AG Südost", - "DB Regio AG Südost DEKT 2017", - "DB Regio Bus Mitte", - "Autokraft", - "Dithmarschenbus (DB Regio Bus Nord GmbH)", - "DB RegioNetz Verkehrs GmbH Erzgebirgsbahn", - "DB RegioNetz Verkehrs GmbH Gäubodenbahn", - "DB RegioNetz Verkehrs GmbH Kurhessenbahn", - "DB RegioNetz Verkehrs GmbH Oberweißbacher Berg+Schwarzatalbahn", - "DB Fernverkehr AG", - "DB Regio AG S-Bahn München", - "DB Regio AG S-Bahn Rhein-Main", - "DB Regio AG S-Bahn Stuttgart", - "S-Bahn Berlin", - "S-Bahn Hamburg", - "DB RegioNetz Verkehrs GmbH Südostbayernbahn", - "DB Regio AG Mitte SÜWEX", - "DB RegioNetz Verkehrs GmbH Westfrankenbahn" -] diff --git a/src/server/HAFAS/TripSearch/TripSearch.ts b/src/server/HAFAS/TripSearch/TripSearch.ts deleted file mode 100644 index 3e3efd5fa..000000000 --- a/src/server/HAFAS/TripSearch/TripSearch.ts +++ /dev/null @@ -1,185 +0,0 @@ -import makeRequest from '@/server/HAFAS/Request'; -import mapLoyalityCard from '@/server/HAFAS/TripSearch/mapLoyalityCard'; -import { timezone } from '@/timezone'; -import type { - AllowedHafasProfile, - JourneyFilter, - OptionalLocL, -} from '@/types/HAFAS'; -import type { - TripSearchOptionsV3, - TripSearchOptionsV4, - TripSearchRequest, -} from '@/types/HAFAS/TripSearch'; -import type { RoutingResult } from '@/types/routing'; -import { format } from 'date-fns'; -import NetzcardBetreiber from './NetzcardBetreiber.json'; -import tripSearchParse from './parse'; - -const netzcardFilter: JourneyFilter[] = NetzcardBetreiber.map((betreiber) => ({ - mode: 'INC', - type: 'OP', - value: betreiber, -})); - -const bc100Filter: JourneyFilter[] = [ - { - mode: 'EXC', - type: 'ATTRJ', - value: 'DU', - }, -]; - -const onlyRegionalFilter: JourneyFilter[] = [ - { - value: '1016', - mode: 'INC', - type: 'PROD', - }, -]; - -const profileConfig = { - db: { - cfg: { - rtMode: 'HYBRID', - }, - }, -}; - -function convertSingleCoordinate(singleCoordinate: number): number { - const splittedCoordinate = singleCoordinate.toString().split('.'); - const pre = splittedCoordinate[0].padStart(2, '0'); - const post = (splittedCoordinate[1] || '').padEnd(6, '0').slice(0, 6); - - return Number.parseInt(`${pre}${post}`); -} - -function startDestinationMap( - startDest: string | TripSearchOptionsV4['start'], -): OptionalLocL { - let eva: string | undefined; - if (typeof startDest === 'string') { - eva = startDest; - } else { - if (startDest.type === 'coordinate') { - return { - crd: { - x: convertSingleCoordinate(startDest.longitude), - y: convertSingleCoordinate(startDest.latitude), - }, - }; - } - eva = startDest.evaNumber; - } - - return { - lid: `A=1@L=${eva}@B=1`, - }; -} - -export function tripSearch( - { - start, - destination, - via, - time, - transferTime = -1, - maxChanges = -1, - searchForDeparture = true, - getPasslist = true, - economic = true, - ushrp = false, - getPolyline = false, - getIV = true, - numF = 6, - ctxScr, - onlyRegional, - onlyNetzcard, - onlyBC100, - tarif, - }: TripSearchOptionsV3 | TripSearchOptionsV4, - profile?: AllowedHafasProfile, - raw?: boolean, -): Promise { - let requestTypeSpecific: - | { outDate: string; outTime: string } - | { - ctxScr: string; - }; - if (!time && !ctxScr) { - time = new Date(); - } - - if (time) { - requestTypeSpecific = { - outDate: format(time, 'yyyyMMdd', { - in: timezone.europeBerlin, - }), - outTime: format(time, 'HHmmss', { - in: timezone.europeBerlin, - }), - }; - } else if (ctxScr) { - requestTypeSpecific = { - ctxScr, - }; - } else { - throw new Error('Either Time or Context required'); - } - - const journeyFilter: JourneyFilter[] = []; - if (onlyRegional) { - journeyFilter.push(...onlyRegionalFilter); - } - if (onlyNetzcard) { - journeyFilter.push(...netzcardFilter); - } - if (onlyBC100) { - journeyFilter.push(...bc100Filter); - } - const arrLoc = startDestinationMap(destination); - const depLoc = startDestinationMap(start); - - const req: TripSearchRequest = { - req: { - jnyFltrL: journeyFilter.length ? journeyFilter : undefined, - // getPT: true, - numF, - ...requestTypeSpecific, - maxChg: maxChanges === -1 ? undefined : maxChanges, - minChgTime: transferTime || undefined, - getPasslist, - economic, - ushrp, - getPolyline, - getIV, - // arrival / departure - outFrwd: searchForDeparture ? undefined : false, - arrLocL: [arrLoc], - depLocL: [depLoc], - viaLocL: via?.length - ? via.map((via) => ({ - loc: { - lid: `A=1@L=${'evaNumber' in via ? via.evaNumber : via.evaId}`, - }, - min: via.minChangeTime, - })) - : undefined, - trfReq: tarif - ? { - jnyCl: tarif.class, - cType: 'PK', - tvlrProf: tarif.traveler.map((t) => ({ - type: t.type, - redtnCard: mapLoyalityCard(t.loyalityCard, profile), - })), - } - : undefined, - }, - meth: 'TripSearch', - // @ts-expect-error spread works - ...profileConfig[profile ?? 'db'], - }; - - return makeRequest(req, raw ? undefined : tripSearchParse, profile); -} diff --git a/src/server/HAFAS/TripSearch/mapLoyalityCard.ts b/src/server/HAFAS/TripSearch/mapLoyalityCard.ts deleted file mode 100644 index 3114f22d1..000000000 --- a/src/server/HAFAS/TripSearch/mapLoyalityCard.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { AllowedHafasProfile } from '@/types/HAFAS'; -import type { LoyalityCard } from '@/types/HAFAS/Tarif'; - -const DBLoyalityCards: { [key in LoyalityCard]: number } = { - BC25First: 1, - BC25Second: 2, - BC50First: 3, - BC50Second: 4, - SHCard: 14, - ATVorteilscard: 9, - CHGeneral: 15, - CHHalfWithRailplus: 10, - CHHalfWithoutRailplus: 11, - NLWithRailplus: 12, - NLWithoutRailplus: 13, - BC100First: 16, - BC100Second: 17, -}; - -// TODO: Expand for other profiles, DB only for now -export default ( - loyalityCard?: LoyalityCard, - _profile: AllowedHafasProfile = AllowedHafasProfile.DB, -): number | undefined => { - if (!loyalityCard) return; - - return DBLoyalityCards[loyalityCard]; -}; diff --git a/src/server/HAFAS/TripSearch/mergeSegments.ts b/src/server/HAFAS/TripSearch/mergeSegments.ts deleted file mode 100644 index cf4cdd5d7..000000000 --- a/src/server/HAFAS/TripSearch/mergeSegments.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { RouteJourneySegment } from '@/types/routing'; - -export default (segments: RouteJourneySegment[]): RouteJourneySegment[] => { - const mergedSegments: RouteJourneySegment[] = []; - let currentSegment = segments.shift(); - - while (currentSegment) { - const nextSegment = segments.shift(); - - if (currentSegment.type !== 'WALK' || !nextSegment) { - mergedSegments.push(currentSegment); - currentSegment = nextSegment; - } else if (nextSegment.type === 'WALK') { - currentSegment.arrival = nextSegment.arrival; - currentSegment.duration += nextSegment.duration; - currentSegment.segmentDestination = nextSegment.segmentDestination; - mergedSegments.push(currentSegment); - currentSegment = segments.shift(); - } else { - mergedSegments.push(currentSegment, nextSegment); - currentSegment = segments.shift(); - } - } - - return mergedSegments; -}; diff --git a/src/server/HAFAS/TripSearch/parse.ts b/src/server/HAFAS/TripSearch/parse.ts deleted file mode 100644 index 1fdb5ab29..000000000 --- a/src/server/HAFAS/TripSearch/parse.ts +++ /dev/null @@ -1,242 +0,0 @@ -import { TransportType } from '@/external/types'; -import mergeSegments from '@/server/HAFAS/TripSearch/mergeSegments'; -import { adjustProductOperator } from '@/server/HAFAS/helper/adjustProductOperator'; -import parseAuslastung from '@/server/HAFAS/helper/parseAuslastung'; -import parseCommonArrival from '@/server/HAFAS/helper/parseCommonArrival'; -import parseCommonDeparture from '@/server/HAFAS/helper/parseCommonDeparture'; -import parseDuration from '@/server/HAFAS/helper/parseDuration'; -import parseMessages from '@/server/HAFAS/helper/parseMessages'; -import parseStop from '@/server/HAFAS/helper/parseStop'; -import parseTarif from '@/server/HAFAS/helper/parseTarif'; -import { getGroups } from '@/server/StopPlace/search'; -import type { - CommonStop, - CommonStopInfo, - HafasResponse, - ParsedCommon, -} from '@/types/HAFAS'; -import type { - Jny, - OutConL, - SecL, - TripSearchResponse, -} from '@/types/HAFAS/TripSearch'; -import type { - RouteJourney, - RouteJourneySegment, - RouteStop, - RoutingResult, - SingleRoute, -} from '@/types/routing'; -import type { MinimalStopPlace } from '@/types/stopPlace'; -import { differenceInMilliseconds, parse } from 'date-fns'; - -const nameRegex = /O=([^@]+)/; -const evaRegex = /L=(\d+)/; - -async function isSameSalesGroup(eva1: string, eva2: string) { - const [groupsOf1, groupsOf2] = await Promise.all([ - getGroups(eva1), - getGroups(eva2), - ]); - return groupsOf1.STATION?.includes(eva2) && groupsOf2.STATION?.includes(eva1); -} - -function parseFullStation(fullStation: string): MinimalStopPlace { - const titleMatch = nameRegex.exec(fullStation); - const idMatch = evaRegex.exec(fullStation); - - let name = ''; - let evaNumber = ''; - - if (titleMatch?.[1]) name = titleMatch[1]; - if (idMatch?.[1]) evaNumber = idMatch[1].padStart(7, '0'); - - return { - name, - evaNumber, - }; -} - -function adjustToFirstTrain( - departure: CommonStopInfo, - segments: RouteJourneySegment[], -) { - if (segments.length && segments[0].type !== 'JNY') { - const firstTrainSegment = segments.find((s) => s.type === 'JNY'); - - if (firstTrainSegment) { - departure.delay = firstTrainSegment.arrival.delay; - } - } -} - -function adjustToLastTrain( - arrival: CommonStopInfo, - segments: RouteJourneySegment[], -) { - if (segments.length && segments.at(-1)?.type !== 'JNY') { - const allTrainSegments = segments.filter((s) => s.type === 'JNY'); - - if (allTrainSegments.length) { - const lastTrainSegment = allTrainSegments.at(-1)!; - - arrival.delay = lastTrainSegment.arrival.delay; - } - } -} - -const AllowedLegTypes = new Set(['JNY', 'WALK', 'TRSF']); - -export class Journey { - private date: Date; - constructor( - private raw: OutConL, - private common: ParsedCommon, - ) { - this.date = parse(raw.date, 'yyyyMMdd', new Date()); - } - parseJourney = async (): Promise => { - const allSegments = ( - await Promise.all( - this.raw.secL - .filter((leg) => AllowedLegTypes.has(leg.type)) - .map(this.parseSegment), - ) - ).filter(Boolean); - - const segments = mergeSegments(allSegments); - - const arrival = parseCommonArrival(this.raw.arr, this.date, this.common); - const departure = parseCommonDeparture( - this.raw.dep, - this.date, - this.common, - ); - - adjustToFirstTrain(departure, segments); - adjustToLastTrain(arrival, segments); - - return Promise.resolve({ - id: this.raw.cksum, - cid: this.raw.cid, - date: this.date, - duration: parseDuration(this.raw.dur), - changes: this.raw.chg, - isRideable: !this.raw.isNotRdbl, - arrival, - departure, - segments, - segmentTypes: segments - .map((s) => (s.type === 'JNY' ? s.train.type : s.train.name)) - .filter(Boolean as any), - tarifSet: parseTarif(this.raw.trfRes), - }); - }; - private parseStops = (stops: CommonStop[] | undefined): RouteStop[] => { - if (!stops) return []; - - return stops.map((stop) => parseStop(stop, this.common, this.date)); - }; - private parseSegmentJourney = (jny: Jny): RouteJourney => { - const [, fullStart, fullDestination, , , , , , ,] = jny.ctxRecon.split('$'); - const product = this.common.prodL[jny.prodX]; - adjustProductOperator(product, this.common, jny.stopL); - - return { - train: product, - cancelled: jny.isCncl, - changeDuration: jny.chgDurR, - segmentStart: parseFullStation(fullStart), - segmentDestination: parseFullStation(fullDestination), - stops: this.parseStops(jny.stopL), - finalDestination: jny.dirTxt, - jid: jny.jid, - auslastung: parseAuslastung(jny.dTrnCmpSX, this.common.tcocL), - messages: parseMessages(jny.msgL, this.common), - }; - }; - private parseSegment = async ( - t: SecL, - ): Promise => { - switch (t.type) { - case 'JNY': { - const arrival = parseCommonArrival(t.arr, this.date, this.common); - const departure = parseCommonDeparture(t.dep, this.date, this.common); - - return { - arrival, - departure, - duration: - arrival.scheduledTime && - departure.scheduledTime && - differenceInMilliseconds( - arrival.scheduledTime, - departure.scheduledTime, - ), - wings: t.parJnyL - ? t.parJnyL.map(this.parseSegmentJourney) - : undefined, - // reservationStatus: t.resState, - // reservationRecommandation: t.resRecommendation, - // icoX: this.common.icoL[t.icoX], - ...this.parseSegmentJourney(t.jny), - type: 'JNY', - }; - } - case 'TRSF': - case 'WALK': { - const segmentStart = this.common.locL[t.dep.locX]; - const segmentDestination = this.common.locL[t.arr.locX]; - - // same sales group = same Station - if ( - await isSameSalesGroup( - segmentStart.evaNumber, - segmentDestination.evaNumber, - ) - ) { - return; - } - - return { - type: 'WALK', - train: { - name: 'Fußweg', - type: 'Fußweg', - transportType: TransportType.Walk, - }, - arrival: parseCommonArrival(t.arr, this.date, this.common), - departure: parseCommonDeparture(t.dep, this.date, this.common), - duration: parseDuration(t.gis.durS), - segmentStart: this.common.locL[t.dep.locX], - segmentDestination: this.common.locL[t.arr.locX], - }; - } - default: { - return undefined; - } - } - }; -} - -export default async ( - r: HafasResponse, - parsedCommon: ParsedCommon, -): Promise => { - const routes = ( - await Promise.all( - r.svcResL[0].res.outConL.flatMap((j) => - new Journey(j, parsedCommon).parseJourney(), - ), - ) - ).filter((j) => j.segments.length); - - return { - context: { - earlier: r.svcResL[0].res.outCtxScrB, - later: r.svcResL[0].res.outCtxScrF, - }, - routes, - }; -}; diff --git a/src/server/HAFAS/helper/__tests__/createCtxRecon.test.ts b/src/server/HAFAS/helper/__tests__/createCtxRecon.test.ts deleted file mode 100644 index 770cb729d..000000000 --- a/src/server/HAFAS/helper/__tests__/createCtxRecon.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -import createCtxRecon from '@/server/HAFAS/helper/createCtxRecon'; -import type { - RouteValidArrivalStop, - RouteValidDepartureStop, -} from '@/types/HAFAS/JourneyDetails'; -import { addSeconds, parse } from 'date-fns'; -import { describe, expect, it } from 'vitest'; - -describe('createCtxRecon', () => { - const expectedDeparture = '201912131045'; - const expectedArrival = '201912131220'; - const departureTime = parse(expectedDeparture, 'yyyyMMddHHmm', 0); - const arrivalTime = parse(expectedArrival, 'yyyyMMddHHmm', 0); - - const firstStop: RouteValidDepartureStop = { - station: { - evaNumber: '123', - name: 'dummy', - }, - departure: { - scheduledTime: departureTime, - time: departureTime, - }, - }; - - const lastStop: RouteValidArrivalStop = { - station: { - evaNumber: '321', - name: 'otherDummy', - }, - arrival: { - scheduledTime: arrivalTime, - time: addSeconds(arrivalTime, 123), - }, - }; - - it('Default replacementNumber is one', () => { - expect( - createCtxRecon({ - firstStop, - lastStop, - trainName: 'test', - }), - ).toBe( - `¶HKI¶T$A=1@L=${firstStop.station.evaNumber}@a=128@$A=1@L=${lastStop.station.evaNumber}@a=128@$${expectedDeparture}$${expectedArrival}$test$$1$`, - ); - }); - - it('Ersatzfahrt has replacement 2', () => { - expect( - createCtxRecon({ - firstStop, - lastStop, - trainName: 'ersatz', - messages: [ - { - type: '', - code: '', - icoX: 0, - txtN: 'Ersatzfahrt', - }, - ], - }), - ).toBe( - `¶HKI¶T$A=1@L=${firstStop.station.evaNumber}@a=128@$A=1@L=${lastStop.station.evaNumber}@a=128@$${expectedDeparture}$${expectedArrival}$ersatz$$2$`, - ); - }); -}); diff --git a/src/server/HAFAS/helper/adjustProductOperator.ts b/src/server/HAFAS/helper/adjustProductOperator.ts deleted file mode 100644 index f2abf18eb..000000000 --- a/src/server/HAFAS/helper/adjustProductOperator.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { - CommonProductInfo, - CommonStop, - ParsedCommon, -} from '@/types/HAFAS'; - -export const adjustProductOperator = ( - mainProduct: CommonProductInfo, - common: ParsedCommon, - stops?: CommonStop[], -): void => { - if (!stops) return; - const relevantProdX = new Set( - stops.flatMap((s) => [s.aProdX, s.dProdX]).filter(Boolean), - ); - const operatorNames = new Set(); - if (mainProduct.operator?.name) { - operatorNames.add(mainProduct.operator.name); - } - for (const prodX of relevantProdX) { - const operatorName = common.prodL[prodX].operator?.name; - if (operatorName) { - operatorNames.add(operatorName); - } - } - if (operatorNames.size && mainProduct.operator) { - mainProduct.operator.name = [...operatorNames].join(', '); - } -}; diff --git a/src/server/HAFAS/helper/checkCoachSequence.ts b/src/server/HAFAS/helper/checkCoachSequence.ts deleted file mode 100644 index 818a19ef7..000000000 --- a/src/server/HAFAS/helper/checkCoachSequence.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { ParsedProduct, TrnCmpSX } from '@/types/HAFAS'; -import { addDays, isBefore } from 'date-fns'; - -const allowdTypes = new Set(['ICE', 'IC', 'TGV', 'EC', 'ECE', 'RJ', 'D']); - -export default ( - scheduledTime: Date, - trnCmpSX?: TrnCmpSX, - train?: ParsedProduct, -): boolean | undefined => { - if (isBefore(addDays(new Date(), 1), scheduledTime)) return false; - if (train?.type && allowdTypes.has(train.type)) return true; - - if (trnCmpSX?.tcM) return true; -}; diff --git a/src/server/HAFAS/helper/createCtxRecon.ts b/src/server/HAFAS/helper/createCtxRecon.ts deleted file mode 100644 index 119766685..000000000 --- a/src/server/HAFAS/helper/createCtxRecon.ts +++ /dev/null @@ -1,37 +0,0 @@ -import type { RemL } from '@/types/HAFAS'; -import type { - RouteValidArrivalStop, - RouteValidDepartureStop, -} from '@/types/HAFAS/JourneyDetails'; -import { format } from 'date-fns'; - -interface CreateCtxReconOptions { - firstStop: RouteValidDepartureStop; - lastStop: RouteValidArrivalStop; - trainName: string; - messages?: RemL[]; -} -export default ({ - firstStop, - lastStop, - trainName, - messages, -}: CreateCtxReconOptions): string => { - // highly unknown what this exactly does - // some replacement trains need a 2 here. - let replacementNumber = 1; - - if (messages?.some((m) => m.txtN.includes('Ersatzfahrt'))) { - replacementNumber = 2; - } - - return `¶HKI¶T$A=1@L=${firstStop.station.evaNumber}@a=128@$A=1@L=${ - lastStop.station.evaNumber - }@a=128@$${format( - firstStop.departure.scheduledTime, - 'yyyyMMddHHmm', - )}$${format( - lastStop.arrival.scheduledTime, - 'yyyyMMddHHmm', - )}$${trainName}$$${replacementNumber}$`; -}; diff --git a/src/server/HAFAS/helper/parseAuslastung.ts b/src/server/HAFAS/helper/parseAuslastung.ts deleted file mode 100644 index 1ae5cc241..000000000 --- a/src/server/HAFAS/helper/parseAuslastung.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { TcocL, TrnCmpSX } from '@/types/HAFAS'; - -export default ( - dTrnCmpSX?: TrnCmpSX, - tcocL?: TcocL[], -): - | { - first?: number; - second?: number; - } - | undefined => { - if (!tcocL || !dTrnCmpSX?.tcocX) return; - - const auslastung: { - first?: number; - second?: number; - } = {}; - - for (const i of dTrnCmpSX.tcocX) { - const a = tcocL[i]; - - switch (a.c) { - case 'FIRST': { - auslastung.first = a.r; - break; - } - case 'SECOND': { - auslastung.second = a.r; - break; - } - default: { - break; - } - } - } - - return auslastung; -}; diff --git a/src/server/HAFAS/helper/parseCommonArrival.ts b/src/server/HAFAS/helper/parseCommonArrival.ts deleted file mode 100644 index 59d36d42c..000000000 --- a/src/server/HAFAS/helper/parseCommonArrival.ts +++ /dev/null @@ -1,31 +0,0 @@ -import type { - CommonArrival, - CommonStopInfo, - ParsedCommon, -} from '@/types/HAFAS'; -import { differenceInMinutes } from 'date-fns'; -import parseTime from './parseTime'; - -export default ( - a: CommonArrival, - date: Date, - _common: ParsedCommon, -): CommonStopInfo => { - const scheduledTime = parseTime(date, a.aTimeS, a.aTZOffset); - let time = scheduledTime; - let delay: number | undefined; - - if (a.aTimeR) { - time = parseTime(date, a.aTimeR, a.aTZOffset); - delay = time && scheduledTime && differenceInMinutes(time, scheduledTime); - } - - return { - scheduledPlatform: a.aPlatfR && a.aPlatfS, - platform: a.aPlatfR || a.aPlatfS, - scheduledTime, - time, - delay, - cancelled: a.aCncl, - }; -}; diff --git a/src/server/HAFAS/helper/parseCommonDeparture.ts b/src/server/HAFAS/helper/parseCommonDeparture.ts deleted file mode 100644 index c542a8468..000000000 --- a/src/server/HAFAS/helper/parseCommonDeparture.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { - CommonDeparture, - CommonStopInfo, - ParsedCommon, -} from '@/types/HAFAS'; -import { differenceInMinutes } from 'date-fns'; -import parseTime from './parseTime'; - -export default ( - d: CommonDeparture, - date: Date, - _common: ParsedCommon, -): CommonStopInfo => { - const scheduledTime = parseTime(date, d.dTimeS, d.dTZOffset); - - let time = scheduledTime; - let delay: number | undefined; - - if (d.dTimeR) { - time = parseTime(date, d.dTimeR, d.dTZOffset); - delay = - time && - scheduledTime && - differenceInMinutes(time, scheduledTime, { - roundingMethod: 'floor', - }); - } - - return { - scheduledPlatform: d.dPlatfR && d.dPlatfS, - platform: d.dPlatfR || d.dPlatfS, - scheduledTime, - time, - delay, - cancelled: d.dCncl, - // messages: d.msgL ? parseMessages(d.msgL, common) : undefined, - }; -}; diff --git a/src/server/HAFAS/helper/parseDuration.ts b/src/server/HAFAS/helper/parseDuration.ts deleted file mode 100644 index f388e12c9..000000000 --- a/src/server/HAFAS/helper/parseDuration.ts +++ /dev/null @@ -1,13 +0,0 @@ -export default (duration: string | undefined | null): number => { - if (!duration) return 0; - const sanitized = duration.padStart(8, '0'); - - const days = Number.parseInt(sanitized.slice(0, 2), 10); - const hours = Number.parseInt(sanitized.slice(2, 4), 10); - const minutes = Number.parseInt(sanitized.slice(4, 6), 10); - const seconds = Number.parseInt(sanitized.slice(6, 8), 10); - - return ( - (seconds + minutes * 60 + hours * 60 * 60 + days * 60 * 60 * 24) * 1000 - ); -}; diff --git a/src/server/HAFAS/helper/parseLocL.ts b/src/server/HAFAS/helper/parseLocL.ts deleted file mode 100644 index 4be1e45ee..000000000 --- a/src/server/HAFAS/helper/parseLocL.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { getIdentifiers } from '@/server/StopPlace/search'; -import type { Crd, HafasStation, LocL, ParsedProduct } from '@/types/HAFAS'; - -function normalizeStopPlaceName(name: string) { - return name.replace('(', ' (').replace(')', ') ').trim(); -} - -export function parseCoordinates(crd: Crd): { - lng: number; - lat: number; -} { - return { - lng: crd.x / 1000000, - lat: crd.y / 1000000, - }; -} - -export const parseLocL = async ( - locL: LocL, - products: ParsedProduct[], -): Promise => { - const identifiers = await getIdentifiers(locL.extId, true); - return { - evaNumber: locL.extId, - name: normalizeStopPlaceName(locL.name), - coordinates: locL.crd && parseCoordinates(locL.crd), - products: locL.pRefL?.map((p) => products[p]), - ril100: identifiers?.ril100, - }; -}; diff --git a/src/server/HAFAS/helper/parseMessages.ts b/src/server/HAFAS/helper/parseMessages.ts deleted file mode 100644 index 54f9482b3..000000000 --- a/src/server/HAFAS/helper/parseMessages.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { uniqBy } from '@/client/util'; -import type { MsgL, ParsedCommon, RemL } from '@/types/HAFAS'; - -export default ( - msgL: undefined | MsgL[], - common: ParsedCommon, -): undefined | RemL[] => { - if (!msgL) return undefined; - - const messages = uniqBy( - msgL - .map((msg) => { - const rem = common.remL[msg.remX]; - - return rem; - }) - .filter((msg) => msg && msg.txtN !== 'Gleiswechsel'), - 'txtN', - ); - - return messages; -}; diff --git a/src/server/HAFAS/helper/parsePolyline.ts b/src/server/HAFAS/helper/parsePolyline.ts deleted file mode 100644 index d125d4392..000000000 --- a/src/server/HAFAS/helper/parsePolyline.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { HafasStation, ParsedPolyline, PolyL } from '@/types/HAFAS'; -import googlePolyline from 'google-polyline'; -const { decode } = googlePolyline; - -export default (polyline: PolyL, locL: HafasStation[]): ParsedPolyline => { - return { - points: decode(polyline.crdEncYX)?.map((x) => [x[1], x[0]]), - delta: polyline.delta, - locations: polyline.ppLocRefL.map((l) => locL[l.locX]), - }; -}; diff --git a/src/server/HAFAS/helper/parseProduct.ts b/src/server/HAFAS/helper/parseProduct.ts deleted file mode 100644 index cbd1feb28..000000000 --- a/src/server/HAFAS/helper/parseProduct.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { TransportType } from '@/external/types'; -import { getLineFromNumber } from '@/server/journeys/lineNumberMapping'; -import type { Common, ParsedProduct, ProdL } from '@/types/HAFAS'; - -function mapTransportType(catCode?: string, catIn?: string): TransportType { - // SEV is categorized wrong - if (catIn === 'BSV' || catIn === 'Bsv') { - return TransportType.Bus; - } - // Flights are categorized wrong (There is no HAFAS flight catCode) - if (catIn === 'AIR') { - return TransportType.Flight; - } - switch (catCode) { - case '0': { - return TransportType.HighSpeedTrain; - } - case '1': { - return TransportType.IntercityTrain; - } - case '2': { - return TransportType.InterRegionalTrain; - } - case '3': { - return TransportType.RegionalTrain; - } - case '4': { - return TransportType.CityTrain; - } - case '5': { - return TransportType.Bus; - } - case '6': { - return TransportType.Ferry; - } - case '7': { - return TransportType.Subway; - } - case '8': { - return TransportType.Tram; - } - case '9': { - return TransportType.Shuttle; - } - default: { - return TransportType.Unknown; - } - } -} - -export default (product: ProdL, common: Common): ParsedProduct => { - const operator = - product.oprX === undefined ? undefined : common.opL[product.oprX]; - const number = product.prodCtx?.num ?? product.number; - - return { - name: product.addName || product.name, - line: - product.prodCtx?.line || - product.prodCtx?.lineId || - product.prodCtx?.matchId || - product.matchId || - product.nameS || - getLineFromNumber(number), - admin: product.prodCtx?.admin?.replaceAll('_', ''), - number, - type: - product.prodCtx && (product.prodCtx.catOut || product.prodCtx.catOutL), - transportType: mapTransportType(product.prodCtx?.catCode), - operator, - }; -}; diff --git a/src/server/HAFAS/helper/parseStop.ts b/src/server/HAFAS/helper/parseStop.ts deleted file mode 100644 index c34ea95ae..000000000 --- a/src/server/HAFAS/helper/parseStop.ts +++ /dev/null @@ -1,32 +0,0 @@ -import type { CommonStop, ParsedCommon } from '@/types/HAFAS'; -import type { RouteStop } from '@/types/routing'; -import parseAuslastung from './parseAuslastung'; -import parseCommonArrival from './parseCommonArrival'; -import parseCommonDeparture from './parseCommonDeparture'; -import parseMessages from './parseMessages'; - -export default ( - stop: CommonStop, - common: ParsedCommon, - date: Date, -): RouteStop => { - const arrival = stop.aTimeS - ? parseCommonArrival(stop, date, common) - : undefined; - const departure = stop.dTimeS - ? parseCommonDeparture(stop, date, common) - : undefined; - - return { - station: common.locL[stop.locX], - arrival, - departure, - auslastung: parseAuslastung(stop.dTrnCmpSX, common.tcocL), - additional: stop.isAdd, - cancelled: - (arrival || departure) && - (!arrival || stop.aCncl) && - (!departure || stop.dCncl), - messages: parseMessages(stop.msgL, common), - }; -}; diff --git a/src/server/HAFAS/helper/parseTarif.ts b/src/server/HAFAS/helper/parseTarif.ts deleted file mode 100644 index bd3830cee..000000000 --- a/src/server/HAFAS/helper/parseTarif.ts +++ /dev/null @@ -1,30 +0,0 @@ -import type { - HafasTarifResponse, - TarifFare, - TarifFareSet, -} from '@/types/HAFAS/TripSearch'; -import type { RouteTarifFare, RouteTarifFareSet } from '@/types/routing'; - -const parseFare = (fare: TarifFare): RouteTarifFare => { - return { - price: fare.prc, - moreExpensiveAvailable: fare.isFromPrice, - bookable: fare.isBookable, - upsell: fare.isUpsell, - targetContext: fare.targetCtx, - }; -}; - -const parseFareSet = (fareSet: TarifFareSet): RouteTarifFareSet => { - return { - fares: fareSet.fareL.map(parseFare), - }; -}; - -export default ( - tarifResponse?: HafasTarifResponse, -): RouteTarifFareSet[] | undefined => { - if (tarifResponse?.statusCode !== 'OK') return; - - return tarifResponse.fareSetL.map(parseFareSet); -}; diff --git a/src/server/HAFAS/helper/parseTime.ts b/src/server/HAFAS/helper/parseTime.ts deleted file mode 100644 index bd62e9477..000000000 --- a/src/server/HAFAS/helper/parseTime.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { addMilliseconds, addMinutes } from 'date-fns'; -import parseDuration from './parseDuration'; - -function parseTime(date: Date, time: string, tzOffset?: number): Date; -function parseTime(date: Date, time: undefined, tzOffset?: number): undefined; -function parseTime( - date: Date, - time?: string, - tzOffset?: number, -): Date | undefined { - if (time) { - let parsedDate = addMilliseconds(date, parseDuration(time)); - // Summer/Winter Time - const tzDifference = - parsedDate.getTimezoneOffset() - date.getTimezoneOffset(); - - if (tzDifference !== 0) { - parsedDate = addMinutes(parsedDate, tzDifference); - } - - if (tzOffset) { - const parsedDateTZOffset = -1 * parsedDate.getTimezoneOffset(); - if (parsedDateTZOffset !== tzOffset) { - const difference = parsedDateTZOffset - tzOffset; - parsedDate = addMinutes(parsedDate, difference); - } - } - - return parsedDate; - } -} - -export default parseTime; diff --git a/src/server/HAFAS/occupancy.ts b/src/server/HAFAS/occupancy.ts deleted file mode 100644 index 1e48e268a..000000000 --- a/src/server/HAFAS/occupancy.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { searchStopPlace } from '@/server/StopPlace/search'; -import { Cache, CacheDatabase } from '@/server/cache'; -import type { RouteAuslastung, SingleRoute } from '@/types/routing'; -import { tripSearch } from './TripSearch/TripSearch'; - -async function getRelevantTrip( - start: string, - destination: string, - trainNumber: string, - time: Date, -): Promise { - const startStations = await searchStopPlace(start, 1); - const destStations = await searchStopPlace(destination, 1); - - const startStation = startStations[0]; - const destStation = destStations[0]; - - if (!startStation) { - throw { - message: 'Start Station unknown', - data: start, - }; - } - if (!destStation) { - throw { - message: 'Destination Station unknown', - data: destination, - }; - } - - const trips = await tripSearch({ - start: startStation.evaNumber, - destination: destStation.evaNumber, - time, - maxChanges: 0, - }); - - const relevantTrip = trips.routes.find((t) => - t.segments.some( - (s) => - s.type === 'JNY' && - (s.train.number === trainNumber || - Boolean(s.wings?.some((w) => w.train.number === trainNumber))), - ), - ); - - return relevantTrip; -} - -const stopOccupancyCache = new Cache( - CacheDatabase.HafasStopOccupancy, -); - -async function stopOccupancy( - start: string, - destination: string, - trainNumber: string, - time: Date, - stopEva: string, -): Promise { - const keyWithouEva = `${start}-${destination}-${trainNumber}-${time}`; - const key = `${keyWithouEva}-${stopEva}`; - if (await stopOccupancyCache.exists(key)) { - return await stopOccupancyCache.get(key); - } - const relevantTrip = await getRelevantTrip( - start, - destination, - trainNumber, - time, - ); - - if (relevantTrip?.segments[0].type !== 'JNY') { - return; - } - - await Promise.all([ - relevantTrip.segments[0].stops.map((s) => - stopOccupancyCache.set( - `${keyWithouEva}-${s.station.evaNumber}`, - s.auslastung, - ), - ), - ]); - - return await stopOccupancyCache.get(key); -} diff --git a/src/server/HAFAS/profiles.ts b/src/server/HAFAS/profiles.ts deleted file mode 100644 index 4dcb82e67..000000000 --- a/src/server/HAFAS/profiles.ts +++ /dev/null @@ -1,367 +0,0 @@ -import Crypto from 'node:crypto'; - -function getSecret(hciChecksum: string) { - const enc = Buffer.from(hciChecksum, 'base64'); - const key = Buffer.from([ - 97, 72, 54, 70, 56, 122, 82, 117, 105, 66, 110, 109, 51, 51, 102, 85, - ]); - const iv = Buffer.alloc(16); - const cipher = Crypto.createDecipheriv('aes-128-cbc', key, iv); - const secret = cipher.update(enc, undefined, 'ascii') + cipher.final('ascii'); - - return secret; -} - -function createChecksumFn(secret: string) { - return (data: any) => { - const hasher = Crypto.createHash('md5'); - - hasher.update(JSON.stringify(data) + secret); - - return { - checksum: hasher.digest('hex'), - }; - }; -} - -function createMicMacFn(secret: string) { - return (data: any) => { - const micHasher = Crypto.createHash('md5'); - - micHasher.update(JSON.stringify(data)); - const mic = micHasher.digest('hex'); - const macHasher = Crypto.createHash('md5'); - - macHasher.update(mic + secret); - - return { mic, mac: macHasher.digest('hex') }; - }; -} - -export const vbn = { - url: 'https://fahrplaner.vbn.de/bin/mgate.exe', - secret: createMicMacFn( - getSecret('HLMpSMJpWe8wBXKtp2g1ey+XzkGxhYE3NsONGEmd8GE='), - ), - config: { - client: { - os: 'iOS 13.4.1', - id: 'VBN', - name: 'vbn', - type: 'IPH', - v: '6000000', - }, - ver: '1.18', - lang: 'de', - auth: { - aid: 'kaoxIXLn03zCr2KR', - type: 'AID', - }, - }, -}; - -export const smartrbl = { - url: 'https://db-smartrbl.hafas.de/mct/mgate', - config: { - client: { - id: 'HAFAS', - name: 'Test-Client', - type: 'WEB', - v: '1.0.0', - }, - lang: 'deu', - ver: '1.18', - auth: { - aid: 'izfpmpj8tnh6acye', - type: 'AID', - }, - }, -}; - -export const dbregio = { - url: 'https://bnav.hafas.de/bin/mgate.exe', - secret: createMicMacFn( - getSecret('scuNsYWPma+dzYl3K5cpjb+EsHxQJ/2VGnFwjInCQX4='), - ), - config: { - client: { - id: 'DB-REGIO-BNAV', - v: '3000500', - type: 'IPH', - name: 'StreckenagentPROD-APPSTORE', - }, - lang: 'de', - ext: 'DB.R19.12.a', - ver: '1.18', - auth: { - aid: 'Xd91BNAVkuI6rr6z', - type: 'AID', - }, - }, -}; - -export const db = { - url: 'https://reiseauskunft.bahn.de/bin/mgate.exe', - secret: createChecksumFn( - getSecret('rGhXPq+xAlvJd8T8cMnojdD0IoaOY53X7DPAbcXYe5g='), - ), - config: { - client: { - id: 'DB', - v: '20100000', - type: 'IPH', - name: 'DB Navigator', - }, - ext: 'DB.R22.04.a', - lang: 'de', - ver: '1.18', - auth: { - aid: 'n91dB8Z77MLdoR0K', - type: 'AID', - }, - }, -}; -// dummy; -export const bahn = db; - -export const pkp = { - url: 'https://mobil.rozklad-pkp.pl:8019/bin/mgate.exe', - config: { - client: { - id: 'HAFAS', - // v: '4010200', - type: 'AND', - // name: 'bilkomAPPSTORE', - }, - lang: 'en', - ver: '1.18', - auth: { - aid: 'DrxJYtYZQpEBCtcb', - type: 'AID', - }, - }, -}; - -export const rmv = { - url: 'https://www.rmv.de/auskunft/bin/jp/mgate.exe', - config: { - client: { - id: 'RMV', - l: 'vs_webapp', - type: 'WEB', - name: 'webapp', - }, - ext: 'RMV.1', - lang: 'de', - ver: '1.18', - auth: { - aid: 'x0k4ZR33ICN9CWmj', - type: 'AID', - }, - }, -}; - -export const oebb = { - url: 'https://fahrplan.oebb.at/bin/mgate.exe', - config: { - client: { - os: 'iOS 12.4', - id: 'OEBB', - v: '6020300', - type: 'IPH', - name: 'oebbADHOC', - }, - lang: 'de', - ver: '1.18', - auth: { - aid: 'OWDL4fE4ixNiPBBm', - type: 'AID', - }, - }, -}; - -export const sncb = { - url: 'http://www.belgianrail.be/jp/sncb-nmbs-routeplanner/mgate.exe', - config: { - client: { - os: 'iOS 12.4', - id: 'SNCB', - v: '4030200', - type: 'IPH', - name: 'sncb', - }, - lang: 'de', - ver: '1.18', - auth: { aid: 'sncb-mobi', type: 'AID' }, - }, -}; - -export const avv = { - url: 'https://auskunft.avv.de/bin/mgate.exe', - config: { - client: { - id: 'HAFAS', - type: 'WEB', - name: 'Test-Client', - v: '100', - }, - lang: 'deu', - ver: '1.18', - auth: { - type: 'AID', - aid: '4vV1AcH3N511icH', - }, - }, -}; - -export const nahsh = { - url: 'https://nah.sh.hafas.de/bin/mgate.exe', - config: { - client: { - os: 'iOS 12.4', - id: 'NAHSH', - v: '5000100', - type: 'IPH', - name: 'NAHSHPROD-APPSTORE', - }, - lang: 'de', - ver: '1.18', - auth: { aid: 'r0Ot9FLFNAFxijLW', type: 'AID' }, - }, -}; - -export const hvv = { - url: 'https://hvv-app.hafas.de/bin/mgate.exe', - secret: createMicMacFn( - getSecret('ktlwfW4vVOf/LwJ4wsnENvzRQZf3WS9b1RMPbIQNEOw='), - ), - config: { - client: { - os: 'iOS 12.4', - id: 'HVV', - v: '4020100', - type: 'IPH', - name: 'HVVPROD_ADHOC', - }, - lang: 'de', - ext: 'HVV.1', - ver: '1.18', - auth: { - aid: 'andcXUmC9Mq6hjrwDIGd2l3oiaMrTUzyH', - type: 'aid', - }, - }, -}; - -export const bvg = { - url: 'https://bvg-apps.hafas.de/bin/mgate.exe', - config: { - client: { - os: 'iOS 12.4', - id: 'BVG', - v: '6021600', - type: 'IPH', - name: 'Fahrinfo', - }, - lang: 'de', - ver: '1.18', - auth: { - aid: 'Mz0YdF9Fgx0Mb9', - type: 'AID', - }, - }, -}; - -export const insa = { - url: 'https://reiseauskunft.insa.de/bin/mgate.exe', - config: { - client: { - os: 'iOS 12.4.1', - id: 'NASA', - v: '4020300', - type: 'IPH', - name: 'nasaPROD-APPSTORE', - }, - lang: 'de', - ver: '1.18', - auth: { - aid: 'nasa-apps', - type: 'AID', - }, - }, -}; - -export const anachb = { - url: 'https://anachb.vor.at/bin/mgate.exe', - config: { - client: { - id: 'VAO', - type: 'WEB', - name: 'webapp', - }, - ver: '1.18', - lang: 'deu', - ext: 'VAO.10', - auth: { - type: 'AID', - aid: 'wf7mcf9bv3nv8g5f', - }, - }, -}; - -export const vao = { - url: 'http://app.verkehrsauskunft.at/bin/mgate.exe', - config: { - client: { - id: 'VAO', - type: 'IPH', - }, - ver: '1.18', - lang: 'deu', - ext: 'VAO.10', - auth: { - type: 'USER', - user: 'mobile', - pw: '87a6f8ZbnBih32', - aid: 'hf7mcf9bv3nv8g5f', - }, - }, -}; - -export const sbb = { - url: 'http://fahrplan.sbb.ch/bin/mgate.exe', - config: { - auth: { - aid: 'hf7mcf9bv3nv8g5f', - type: 'AID', - }, - client: { - id: 'DBZUGRADARNETZ', - type: 'AND', - v: '', - }, - ext: 'DBNETZZUGRADAR.2', - formatted: false, - lang: 'deu', - ver: '1.18', - }, -}; - -export const dbnetz = { - url: 'https://db-livemaps.hafas.de/bin/mgate.exe', - config: { - client: { - id: 'DBZUGRADARNETZ', - v: '0.1.0', - type: 'WEB', - name: 'webapp', - }, - ext: 'DBNETZZUGRADAR.2', - ver: '1.18', - auth: { - type: 'AID', - aid: 'hf7mcf9bv3nv8g5f', - }, - lang: 'deu', - }, -}; diff --git a/src/server/StopPlace/Lageplan/DBLageplan.ts b/src/server/StopPlace/Lageplan/DBLageplan.ts index 1478adc11..2a913045f 100644 --- a/src/server/StopPlace/Lageplan/DBLageplan.ts +++ b/src/server/StopPlace/Lageplan/DBLageplan.ts @@ -1,8 +1,8 @@ import { getStopPlaceByEva } from '@/server/StopPlace/search'; -import { Cache, CacheDatabase } from '@/server/cache'; +import { CacheDatabase, getCache } from '@/server/cache'; import Axios from 'axios'; -const cache = new Cache(CacheDatabase.DBLageplan); +const cache = getCache(CacheDatabase.DBLageplan); export async function getDBLageplan( evaNumber: string, diff --git a/src/server/StopPlace/Lageplan/NAHSHLageplan.ts b/src/server/StopPlace/Lageplan/NAHSHLageplan.ts deleted file mode 100644 index af5c69273..000000000 --- a/src/server/StopPlace/Lageplan/NAHSHLageplan.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { locMatch } from '@/server/HAFAS/LocMatch'; -import { Cache, CacheDatabase } from '@/server/cache'; -import { AllowedHafasProfile } from '@/types/HAFAS'; -import Axios from 'axios'; - -const cache = new Cache(CacheDatabase.NAHSHLageplan); - -function normalizeStationName(stationName: string) { - return stationName - .replace(' AKN', '') - .replace('ü', 'ue') - .replace('Ü', 'Ue') - .replace('ä', 'ae') - .replace('Ä', 'Ae') - .replace('ü', 'ue') - .replace('Ü', 'Ue') - .replace(' ', '_'); -} - -export async function getNAHSHLageplan( - evaId: string, -): Promise { - try { - const cached = await getCachedNAHSHLageplan(evaId); - if (cached) return cached; - if (cached === null) return undefined; - - const station = ( - await locMatch(evaId, 'S', AllowedHafasProfile['NAH.SH']) - )[0]; - if (station) { - const fullLink = `https://www.nah.sh/assets/downloads/Stationsplaene/${normalizeStationName( - station.name, - )}.pdf`; - - try { - await Axios.get(fullLink); - void cache.set(evaId, fullLink); - return fullLink; - } catch { - // we ignore failing requests and fall back to undefined for lageplanURL - } - } - void cache.set(evaId, null); - return undefined; - } catch { - return undefined; - } -} - -export function getCachedNAHSHLageplan( - evaId: string, -): Promise { - return cache.get(evaId); -} diff --git a/src/server/StopPlace/Lageplan/index.ts b/src/server/StopPlace/Lageplan/index.ts index cef5583fe..cf51856c1 100644 --- a/src/server/StopPlace/Lageplan/index.ts +++ b/src/server/StopPlace/Lageplan/index.ts @@ -1,11 +1,7 @@ import { getDBLageplan } from './DBLageplan'; -import { getNAHSHLageplan } from './NAHSHLageplan'; export async function getLageplan(evaNumber: string): Promise { - const [DBLageplan, NahSHLageplan] = await Promise.all([ - getDBLageplan(evaNumber), - getNAHSHLageplan(evaNumber), - ]); + const [DBLageplan] = await Promise.all([getDBLageplan(evaNumber)]); - return DBLageplan || NahSHLageplan || null; + return DBLageplan || null; } diff --git a/src/server/StopPlace/hafasSearch.ts b/src/server/StopPlace/hafasSearch.ts deleted file mode 100644 index 1d1532ce0..000000000 --- a/src/server/StopPlace/hafasSearch.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { locMatch } from '@/server/HAFAS/LocMatch'; -import { irisFilter } from '@/server/StopPlace/search'; -import { getSingleStation } from '@/server/iris/station'; -import type { GroupedStopPlace } from '@/types/stopPlace'; - -async function byRl100(rl100: string): Promise { - if (rl100.length > 5) { - return; - } - try { - const irisRl100 = await getSingleStation(rl100); - return { - name: irisRl100.name, - evaNumber: irisRl100.eva, - availableTransports: [], - ril100: irisRl100.ds100, - }; - } catch { - // we just return nothing on fail - } -} - -export async function searchWithHafas( - searchTerm?: string, - max?: number, - filterForIris?: boolean, -): Promise { - if (!searchTerm) return []; - const results = await Promise.all([ - await locMatch(searchTerm, 'S'), - byRl100(searchTerm), - ]); - let hafasResult = results[0]; - const rl100ByIris = results[1]; - if (max) { - hafasResult = hafasResult.splice(0, max); - } - - const result: GroupedStopPlace[] = hafasResult - .filter((s) => s.evaNumber.length <= 7 || !s.evaNumber.startsWith('99')) - .map((s) => ({ - evaNumber: s.evaNumber, - name: s.name, - position: { - latitude: s.coordinates.lat, - longitude: s.coordinates.lng, - }, - availableTransports: [], - })); - - if (rl100ByIris) { - result.unshift(rl100ByIris); - } - - if (filterForIris) { - return irisFilter(result); - } - return result; -} diff --git a/src/server/StopPlace/search.ts b/src/server/StopPlace/search.ts index ee21e0178..05ad8dbb9 100644 --- a/src/server/StopPlace/search.ts +++ b/src/server/StopPlace/search.ts @@ -5,31 +5,20 @@ import type { StopPlace, StopPlaceSearchResult, } from '@/external/types'; -import { searchWithHafas } from '@/server/StopPlace/hafasSearch'; import { manualNameOverrides } from '@/server/StopPlace/manualNameOverrides'; -import { Cache, CacheDatabase } from '@/server/cache'; +import { CacheDatabase, getCache } from '@/server/cache'; import { getSingleStation } from '@/server/iris/station'; import type { GroupedStopPlace, StopPlaceIdentifier } from '@/types/stopPlace'; -const stopPlaceStationSearchCache = new Cache( - CacheDatabase.StopPlaceSearch, -); -const stopPlaceSalesSearchCache = new Cache( - CacheDatabase.StopPlaceSalesSearch, -); -const stopPlaceIdentifierCache = new Cache( - CacheDatabase.StopPlaceIdentifier, -); -const stopPlaceByRilCache = new Cache(CacheDatabase.StopPlaceByRil); -const stopPlaceByRilGroupedCache = new Cache( +const stopPlaceStationSearchCache = getCache(CacheDatabase.StopPlaceSearch); +const stopPlaceSalesSearchCache = getCache(CacheDatabase.StopPlaceSalesSearch); +const stopPlaceIdentifierCache = getCache(CacheDatabase.StopPlaceIdentifier); +const stopPlaceByRilCache = getCache(CacheDatabase.StopPlaceByRil); +const stopPlaceByRilGroupedCache = getCache( CacheDatabase.StopPlaceByRilGrouped, ); -const stopPlaceByEvaCache = new Cache( - CacheDatabase.StopPlaceByEva, -); -const stopPlaceGroupCache = new Cache( - CacheDatabase.StopPlaceGroups, -); +const stopPlaceByEvaCache = getCache(CacheDatabase.StopPlaceByEva); +const stopPlaceGroupCache = getCache(CacheDatabase.StopPlaceGroups); function mapToGroupedStopPlace( stopPlace: Pick< @@ -68,18 +57,12 @@ export async function searchStopPlace( filterForIris?: boolean, groupBySales?: boolean, ): Promise { - try { - const result = await searchStopPlaceRisStations( - searchTerm, - max, - filterForIris, - groupBySales, - ); - if (result?.length || filterForIris || groupBySales) return result; - return searchWithHafas(searchTerm, max, filterForIris); - } catch { - return searchWithHafas(searchTerm, max, filterForIris); - } + return await searchStopPlaceRisStations( + searchTerm, + max, + filterForIris, + groupBySales, + ); } export async function searchStopPlaceRisStations( @@ -128,17 +111,6 @@ export async function getStopPlaceByEva( void stopPlaceByEvaCache.set(groupedStopPlace.evaNumber, groupedStopPlace); return groupedStopPlace; } - if (!forceLive) { - const hafasResults = await searchWithHafas(evaNumber, 1, false); - const groupedHafasResult = hafasResults[0]; - if (groupedHafasResult && groupedHafasResult.evaNumber === evaNumber) { - void stopPlaceByEvaCache.set( - groupedHafasResult.evaNumber, - groupedHafasResult, - ); - return groupedHafasResult; - } - } } async function byRl100WithSpaceHandling( diff --git a/src/server/StopPlace/vrrOccupancy.ts b/src/server/StopPlace/vrrOccupancy.ts index 626286abd..65d7525fa 100644 --- a/src/server/StopPlace/vrrOccupancy.ts +++ b/src/server/StopPlace/vrrOccupancy.ts @@ -1,5 +1,5 @@ import { axiosUpstreamInterceptor } from '@/server/admin'; -import { Cache, CacheDatabase } from '@/server/cache'; +import { CacheDatabase, getCache } from '@/server/cache'; import { AuslastungsValue } from '@/types/routing'; import type { TrainOccupancy, @@ -12,9 +12,7 @@ import axios from 'axios'; const occupancyAxios = axios.create(); axiosUpstreamInterceptor(occupancyAxios, 'vrrf-occupancy'); -const vrrOccupancyCache = new Cache( - CacheDatabase.VRROccupancy, -); +const vrrOccupancyCache = getCache(CacheDatabase.VRROccupancy); function mapVrrOccupancy( vrrOccupancy: VRRTrainOccupancyValues, diff --git a/src/server/cache.ts b/src/server/cache.ts index eb8fc3770..8040aee4c 100644 --- a/src/server/cache.ts +++ b/src/server/cache.ts @@ -1,5 +1,34 @@ import os from 'node:os'; +import type { + JourneyEventBased as JourneyEventBasedV1, + JourneyMatch, +} from '@/external/generated/risJourneys'; +import type { + JourneyEventBased, + JourneyFindResult, +} from '@/external/generated/risJourneysV2'; +import type { VehicleLayoutFeatureCollection } from '@/external/generated/risMaps'; +import type { StopPlace } from '@/external/generated/risStations'; +import type { + JourneyOccupancy, + MatchVehicleID, +} from '@/external/generated/risTransports'; +import type { ResolvedStopPlaceGroups } from '@/external/types'; import { logger } from '@/server/logger'; +import type { AdditionalJourneyInformation } from '@/types/HAFAS/JourneyDetails'; +import type { ParsedJourneyMatchResponse } from '@/types/HAFAS/JourneyMatch'; +import type { ParsedSearchOnTripResponse } from '@/types/HAFAS/SearchOnTrip'; +import type { + CoachSequenceCoachFeatures, + CoachSequenceInformation, +} from '@/types/coachSequence'; +import type { IrisStation } from '@/types/iris'; +import type { RouteAuslastung } from '@/types/routing'; +import type { + GroupedStopPlace, + StopPlaceIdentifier, + TrainOccupancyList, +} from '@/types/stopPlace'; import { Temporal } from '@js-temporal/polyfill'; import Redis from 'ioredis'; @@ -49,9 +78,9 @@ export enum CacheDatabase { IrisTTSStation = 0, TimetableParsedWithWings = 1, DBLageplan = 2, - LocMatch = 3, - HIMMessage = 4, - NAHSHLageplan = 5, + // LocMatch = 3, + // HIMMessage = 4, + // NAHSHLageplan = 5, StopPlaceSearch = 6, StopPlaceByRilGrouped = 7, StopPlaceIdentifier = 8, @@ -76,13 +105,52 @@ export enum CacheDatabase { BahnDEJourneyDetails = 27, } -const CacheTTLs: Record = { +interface CacheDatabaseTypes { + [CacheDatabase.AdditionalJourneyInformation]: + | AdditionalJourneyInformation + | undefined; + [CacheDatabase.BahnDEJourneyDetails]: ParsedSearchOnTripResponse; + [CacheDatabase.CoachSequenceRemovedData]: Record< + string, + { + identificationNumber: string; + features: CoachSequenceCoachFeatures; + } + >; + [CacheDatabase.DBLageplan]: string | null; + [CacheDatabase.HAFASJourneyMatch]: ParsedJourneyMatchResponse[]; + [CacheDatabase.HafasStopOccupancy]: RouteAuslastung | undefined; + [CacheDatabase.IrisTTSStation]: IrisStation | null; + [CacheDatabase.Journey]: JourneyEventBasedV1; + [CacheDatabase.JourneyFind]: JourneyMatch[]; + [CacheDatabase.JourneyFindV2]: JourneyFindResult[]; + [CacheDatabase.JourneyV2]: JourneyEventBased; + [CacheDatabase.JourneysForVehicle]: { + previousJourneys: MatchVehicleID[]; + nextJourneys: MatchVehicleID[]; + }; + [CacheDatabase.NegativeNewSequence]: boolean; + [CacheDatabase.ParsedCoachSequenceFound]: CoachSequenceInformation; + [CacheDatabase.StopPlaceByEva]: GroupedStopPlace; + [CacheDatabase.StopPlaceByRil]: StopPlace; + [CacheDatabase.StopPlaceByRilGrouped]: GroupedStopPlace; + [CacheDatabase.StopPlaceGroups]: ResolvedStopPlaceGroups; + [CacheDatabase.StopPlaceIdentifier]: StopPlaceIdentifier | undefined; + [CacheDatabase.StopPlaceSalesSearch]: GroupedStopPlace[]; + [CacheDatabase.StopPlaceSearch]: GroupedStopPlace[]; + [CacheDatabase.TimetableParsedWithWings]: { + timetable: Record; + wingIds: Record; + }; + [CacheDatabase.TransportsOccupancy]: JourneyOccupancy | undefined; + [CacheDatabase.VRROccupancy]: TrainOccupancyList | null; + [CacheDatabase.VehicleLayoutsMaps]: VehicleLayoutFeatureCollection | null; +} + +const CacheTTLs: Record = { [CacheDatabase.IrisTTSStation]: 'P2D', [CacheDatabase.TimetableParsedWithWings]: 'P1D', [CacheDatabase.DBLageplan]: 'P1D', - [CacheDatabase.LocMatch]: 'P1D', - [CacheDatabase.HIMMessage]: 'P1D', - [CacheDatabase.NAHSHLageplan]: 'P3D', [CacheDatabase.StopPlaceSearch]: 'P3D', [CacheDatabase.ParsedCoachSequenceFound]: parseCacheTTL( 'PT15M', @@ -124,7 +192,21 @@ export function disconnectRedis(): void { } } -export class Cache { +const caches: Partial>> = {}; + +export function getCache( + type: T, +): Cache { + if (!caches[type]) { + caches[type] = new Cache(type); + } + return caches[type]; +} + +export type CacheType> = C extends Cache + ? X + : never; +class Cache { private redisCache?: Redis; private ttl: number; constructor(database: CacheDatabase, providedRedisSettings = redisSettings) { diff --git a/src/server/coachSequence/DB/index.ts b/src/server/coachSequence/DB/index.ts index b9035bb7f..4436fb568 100644 --- a/src/server/coachSequence/DB/index.ts +++ b/src/server/coachSequence/DB/index.ts @@ -1,17 +1,13 @@ import { isWithin20Hours } from '@/external/risTransports/config'; -import { Cache, CacheDatabase } from '@/server/cache'; +import { CacheDatabase, getCache } from '@/server/cache'; import { getRisTransportsCoachSequence } from '@/server/coachSequence/DB/risTransports'; import type { CoachSequenceInformation } from '@/types/coachSequence'; import { format } from 'date-fns'; const formatDate = (date?: Date) => date ? format(date, 'yyyyMMddHHmm') : undefined; -// const formatPlannedDate = (date?: Date) => -// date ? format(utcToZonedTime(date, 'Europe/Berlin'), 'yyyyMMdd') : undefined; -const coachSequenceCache = new Cache( - CacheDatabase.ParsedCoachSequenceFound, -); +const coachSequenceCache = getCache(CacheDatabase.ParsedCoachSequenceFound); export async function DBCoachSequence( trainNumber: string, diff --git a/src/server/coachSequence/DB/removedData.ts b/src/server/coachSequence/DB/removedData.ts index c9d1e4c66..84f58034b 100644 --- a/src/server/coachSequence/DB/removedData.ts +++ b/src/server/coachSequence/DB/removedData.ts @@ -1,21 +1,8 @@ -import { Cache, CacheDatabase } from '@/server/cache'; -import type { - CoachSequenceCoachFeatures, - CoachSequenceInformation, -} from '@/types/coachSequence'; +import { CacheDatabase, type CacheType, getCache } from '@/server/cache'; +import type { CoachSequenceInformation } from '@/types/coachSequence'; -// evn => removedData for a specific journeyId -type RemovedData = Record< - string, - { - identificationNumber: string; - features: CoachSequenceCoachFeatures; - } ->; - -const removedDataCache = new Cache( - CacheDatabase.CoachSequenceRemovedData, -); +const removedDataCache = getCache(CacheDatabase.CoachSequenceRemovedData); +type RemovedData = CacheType; export async function fixRemovedData( risTransportsSequence: CoachSequenceInformation, diff --git a/src/server/iris/Timetable.ts b/src/server/iris/Timetable.ts index 808731f47..c5f44999c 100644 --- a/src/server/iris/Timetable.ts +++ b/src/server/iris/Timetable.ts @@ -3,14 +3,12 @@ ** derf did awesome work reverse engineering the XML stuff! */ import { uniqBy } from '@/client/util'; -import { getSingleHimMessageOfToday } from '@/server/HAFAS/HimSearch'; import { getStopPlaceByEva } from '@/server/StopPlace/search'; -import { Cache, CacheDatabase } from '@/server/cache'; +import { CacheDatabase, getCache } from '@/server/cache'; import { getSingleStation } from '@/server/iris/station'; import { getLineFromNumber } from '@/server/journeys/lineNumberMapping'; import type { AbfahrtenResult, - HimIrisMessage, IrisMessage, IrisMessages, Stop, @@ -66,10 +64,7 @@ type ParsedAr = ArDp & { plannedRoutePre?: string[]; }; -const timetableCache = new Cache<{ - timetable: Record; - wingIds: Record; -}>(CacheDatabase.TimetableParsedWithWings); +const timetableCache = getCache(CacheDatabase.TimetableParsedWithWings); interface Route { name: string; @@ -404,90 +399,13 @@ export class Timetable { name, }; } - async parseHafasMessage( - mNode: xmljs.Element, - viaNames: string[], - seenHafasNotes: Set, - ) { - const id = getAttr(mNode, 'id'); - - if (!id) return undefined; - - const himMessage = await getSingleHimMessageOfToday(id.slice(1)); - - if (!himMessage) return undefined; - // Sadly this is not accurate. Often affected Products is not corectly set - // if (!himMessage.affectedProducts.some((p) => p.name.endsWith(trainNumber))) - // return undefined; - const now = new Date(); - - if ( - isBefore(now, himMessage.startTime) || - isAfter(now, himMessage.endTime) - ) { - return undefined; - } - - const message: HimIrisMessage = { - timestamp: getTsOfNode(mNode), - head: himMessage.head, - text: himMessage.text, - // short: himMessage.lead === himMessage.text ? undefined : himMessage.lead, - source: himMessage.comp, - endTime: himMessage.endTime, - // @ts-expect-error raw only in dev - raw: process.env.NODE_ENV === 'production' ? undefined : himMessage, - }; - - if (himMessage.fromStopPlace && himMessage.toStopPlace) { - const fromIndex = viaNames.indexOf(himMessage.fromStopPlace.name); - const toIndex = viaNames.indexOf(himMessage.toStopPlace.name); - if (fromIndex !== -1 && toIndex !== -1) { - const from = - fromIndex < toIndex - ? himMessage.fromStopPlace.name - : himMessage.toStopPlace.name; - const to = - fromIndex > toIndex - ? himMessage.fromStopPlace.name - : himMessage.toStopPlace.name; - - let stopPlaceInfo = from; - if (from !== to) { - stopPlaceInfo += ` - ${to}`; - } - message.stopPlaceInfo = stopPlaceInfo; - } - } - - const hafasMessageKey = message.text + message.stopPlaceInfo; - if (seenHafasNotes.has(hafasMessageKey)) { - return undefined; - } - seenHafasNotes.add(hafasMessageKey); - - return { - type: 'him', - value: id, - message, - }; - } - async parseMessage( - mNode: xmljs.Element, - viaNames: string[], - seenHafasNotes: Set, - ) { + async parseMessage(mNode: xmljs.Element) { const value = getNumberAttr(mNode, 'c'); const indexType = getAttr(mNode, 't'); if (!indexType) return undefined; if (indexType === 'h') { - const message = await this.parseHafasMessage( - mNode, - viaNames, - seenHafasNotes, - ); - return message; + return undefined; } const type: undefined | string = messageTypeLookup[indexType as keyof typeof messageTypeLookup]; @@ -555,11 +473,8 @@ export class Timetable { him: {}, }; - const seenHafasNotes = new Set(); const parsedMessages = await Promise.all( - mArr.map((m) => - this.parseMessage(m, this.timetable[rawId].rawRoute, seenHafasNotes), - ), + mArr.map((m) => this.parseMessage(m)), ); for (const { type, message, value } of parsedMessages diff --git a/src/server/iris/station.ts b/src/server/iris/station.ts index 232a8730c..6a6e7154e 100644 --- a/src/server/iris/station.ts +++ b/src/server/iris/station.ts @@ -1,11 +1,11 @@ -import { Cache, CacheDatabase } from '@/server/cache'; +import { CacheDatabase, getCache } from '@/server/cache'; import { stationMetaFilter } from '@/server/iris/stationMetaFilter'; import type { IrisStation, IrisStationWithRelated } from '@/types/iris'; import xmljs from 'libxmljs2'; import type { Element } from 'libxmljs2'; import { irisGetRequest } from './helper'; -const cache = new Cache(CacheDatabase.IrisTTSStation); +const cache = getCache(CacheDatabase.IrisTTSStation); export function parseStation(stationNode: xmljs.Element): IrisStation { const station: any = {}; diff --git a/src/server/journeys/additionalJourneyInformation.ts b/src/server/journeys/additionalJourneyInformation.ts index 292f58b6c..c0a32fbaa 100644 --- a/src/server/journeys/additionalJourneyInformation.ts +++ b/src/server/journeys/additionalJourneyInformation.ts @@ -1,15 +1,11 @@ -import Detail from '@/server/HAFAS/Detail'; -import { Cache, CacheDatabase } from '@/server/cache'; +import { CacheDatabase, getCache } from '@/server/cache'; import { getOccupancy } from '@/server/coachSequence/occupancy'; -import { journeyDetails } from '@/server/journeys/v2/journeyDetails'; import type { AdditionalJourneyInformation } from '@/types/HAFAS/JourneyDetails'; import type { ParsedSearchOnTripResponse } from '@/types/HAFAS/SearchOnTrip'; -import type { EvaNumber } from '@/types/common'; -import type { RouteAuslastung } from '@/types/routing'; -const additionalInformationCache = new Cache< - AdditionalJourneyInformation | undefined ->(CacheDatabase.AdditionalJourneyInformation); +const additionalInformationCache = getCache( + CacheDatabase.AdditionalJourneyInformation, +); async function enrichTransportOccupancy( journeyId: string, @@ -26,47 +22,49 @@ async function enrichTransportOccupancy( * This currently queries HAFAS to get operatorNames & occupancy */ export async function additionalJourneyInformation( - trainName: string, - journeyId: string, - evaNumberAlongRoute?: string, - initialDepartureDate?: Date, + _trainName: string, + _journeyId: string, + _evaNumberAlongRoute?: string, + _initialDepartureDate?: Date, ): Promise { - if (await additionalInformationCache.exists(journeyId)) { - const additionalInformation = - await additionalInformationCache.get(journeyId); - if (additionalInformation) { - await enrichTransportOccupancy(journeyId, additionalInformation); - } - return additionalInformation; - } - const risJourneyDetails = await journeyDetails(journeyId); - const firstUncancelledStop = risJourneyDetails?.stops.find( - (s) => !s.departure?.cancelled, - ); - const hafasJourneyDetails = await Detail( - trainName, - undefined, - firstUncancelledStop?.station.evaNumber || evaNumberAlongRoute, - firstUncancelledStop?.departure?.scheduledTime || initialDepartureDate, - true, - ); - if (!hafasJourneyDetails) { - return; - } + return; - const occupancy: Record = {}; - for (const stop of hafasJourneyDetails.stops) { - if (stop.auslastung) { - occupancy[stop.station.evaNumber] = stop.auslastung; - } - } - const result: AdditionalJourneyInformation = { - jid: hafasJourneyDetails.jid, - occupancy, - operatorName: hafasJourneyDetails.train.operator?.name, - polyline: hafasJourneyDetails.polyline, - }; - void additionalInformationCache.set(journeyId, result); - await enrichTransportOccupancy(journeyId, result, risJourneyDetails); - return result; + // if (await additionalInformationCache.exists(journeyId)) { + // const additionalInformation = + // await additionalInformationCache.get(journeyId); + // if (additionalInformation) { + // await enrichTransportOccupancy(journeyId, additionalInformation); + // } + // return additionalInformation; + // } + // const risJourneyDetails = await journeyDetails(journeyId); + // const firstUncancelledStop = risJourneyDetails?.stops.find( + // (s) => !s.departure?.cancelled, + // ); + // const hafasJourneyDetails = await Detail( + // trainName, + // undefined, + // firstUncancelledStop?.station.evaNumber || evaNumberAlongRoute, + // firstUncancelledStop?.departure?.scheduledTime || initialDepartureDate, + // true, + // ); + // if (!hafasJourneyDetails) { + // return; + // } + + // const occupancy: Record = {}; + // for (const stop of hafasJourneyDetails.stops) { + // if (stop.auslastung) { + // occupancy[stop.station.evaNumber] = stop.auslastung; + // } + // } + // const result: AdditionalJourneyInformation = { + // jid: hafasJourneyDetails.jid, + // occupancy, + // operatorName: hafasJourneyDetails.train.operator?.name, + // polyline: hafasJourneyDetails.polyline, + // }; + // void additionalInformationCache.set(journeyId, result); + // await enrichTransportOccupancy(journeyId, result, risJourneyDetails); + // return result; } diff --git a/src/server/rpc/hafas.ts b/src/server/rpc/hafas.ts index 4bcb8a580..8b1a57699 100644 --- a/src/server/rpc/hafas.ts +++ b/src/server/rpc/hafas.ts @@ -1,75 +1,13 @@ import { bahnDeOccupancy } from '@/bahnde/occupancy'; -import StationBoard from '@/server/HAFAS/StationBoard'; -import StationBoardToTimetables from '@/server/HAFAS/StationBoard/StationBoardToTimetables'; -import { tripSearch } from '@/server/HAFAS/TripSearch/TripSearch'; import { vrrOccupancy } from '@/server/StopPlace/vrrOccupancy'; import { getOccupancy } from '@/server/coachSequence/occupancy'; import { additionalJourneyInformation } from '@/server/journeys/additionalJourneyInformation'; import { rpcAppRouter, rpcProcedure } from '@/server/rpc/base'; -import type { AbfahrtenRPCQuery } from '@/server/rpc/iris'; -import { AllowedHafasProfile } from '@/types/HAFAS'; import type { RouteAuslastungWithSource } from '@/types/routing'; -import type { ArrivalStationBoardEntry } from '@/types/stationBoard'; import { TRPCError } from '@trpc/server'; import { z } from 'zod'; -const routingStopPlaceLocation = z.object({ - type: z.literal('stopPlace'), - evaNumber: z.string(), -}); - -const routingCoordinateLocation = z.object({ - type: z.literal('coordinate'), - latitude: z.number(), - longitude: z.number(), -}); - -const routingLocationInput = z.union([ - routingStopPlaceLocation, - routingCoordinateLocation, -]); - export const hafasRpcRouter = rpcAppRouter({ - irisAbfahrten: rpcProcedure - .input( - z.object({ - evaNumber: z.string(), - }), - ) - .query(async ({ input: { evaNumber } }) => { - const hafasDeparture = await StationBoard({ - type: 'DEP', - station: evaNumber, - }); - const hafasArrivals = await StationBoard({ - type: 'ARR', - station: evaNumber, - }).catch(() => undefined); - - const mappedHafasArrivals = - hafasArrivals?.reduce( - (map: Record, arrival) => { - map[`${arrival.jid}${arrival.train.number}`] = arrival; - - return map; - }, - {}, - ) || {}; - - const idSet = new Set(); - - return { - lookbehind: [], - departures: hafasDeparture - .map((departure) => - StationBoardToTimetables(departure, mappedHafasArrivals, idSet), - ) - .filter(Boolean) - .slice(0, 75), - wings: {}, - stopPlaces: [evaNumber], - }; - }) as AbfahrtenRPCQuery, occupancy: rpcProcedure .input( z.object({ @@ -165,31 +103,4 @@ export const hafasRpcRouter = rpcAppRouter({ }); }, ), - tripSearch: rpcProcedure - .input( - z.object({ - profile: z - .nativeEnum(AllowedHafasProfile) - .default(AllowedHafasProfile.DB), - start: routingLocationInput, - destination: routingLocationInput, - via: z.array( - z.object({ - evaNumber: z.string(), - minChangeTime: z.number().optional(), - }), - ), - time: z.date().optional(), - transferTime: z.number().optional(), - maxChanges: z.number().optional(), - searchForDeparture: z.boolean().optional(), - onlyRegional: z.boolean().optional(), - onlyNetzcard: z.boolean().optional(), - onlyBC100: z.boolean().optional(), - ctxScr: z.string().optional(), - }), - ) - .query(async ({ input: { profile, ...options } }) => { - return await tripSearch(options, profile); - }), }); diff --git a/src/server/rpc/journeys.ts b/src/server/rpc/journeys.ts index 4565072aa..9c781e444 100644 --- a/src/server/rpc/journeys.ts +++ b/src/server/rpc/journeys.ts @@ -7,13 +7,10 @@ import { findJourneyHafasCompatible as findJourneyHafasCompatibleV2, findJourney as findJourneyV2, } from '@/external/risJourneysV2'; -import Detail from '@/server/HAFAS/Detail'; -import { enrichedJourneyMatch } from '@/server/HAFAS/JourneyMatch'; import { getCategoryAndNumberFromName } from '@/server/journeys/journeyDetails'; import { journeyDetails } from '@/server/journeys/v2/journeyDetails'; import { logger } from '@/server/logger'; import { rpcAppRouter, rpcProcedure } from '@/server/rpc/base'; -import type { ParsedJourneyMatchResponse } from '@/types/HAFAS/JourneyMatch'; import type { ParsedSearchOnTripResponse } from '@/types/HAFAS/SearchOnTrip'; import { TRPCError } from '@trpc/server'; import type { QueryProcedure } from '@trpc/server/unstable-core-do-not-import'; @@ -101,30 +98,13 @@ export const journeysRpcRouter = rpcAppRouter({ category, }, }) => { - let risPromise: Promise = Promise.resolve( - [], + let result = await findV1OrV2HafasCompatible( + trainNumber, + initialDepartureDate, + category, + withOEV, ); - if (trainNumber) { - risPromise = findV1OrV2HafasCompatible( - trainNumber, - initialDepartureDate, - category, - withOEV, - ); - } - - const trainName = trainNumber.toString(); - const hafasFallback = () => - enrichedJourneyMatch({ - withOEV, - trainName, - initialDepartureDate, - limit, - }); - - const risResult = await risPromise; - let result = risResult.length ? risResult : await hafasFallback(); if (initialEvaNumber) { result = result.filter( (r) => r.firstStop.station.evaNumber === initialEvaNumber, @@ -172,27 +152,11 @@ export const journeysRpcRouter = rpcAppRouter({ } return journey; } - const hafasFallback = async () => { - const hafasResult = await Detail( - trainName, - undefined, - evaNumberAlongRoute, - initialDepartureDate, - undefined, - undefined, - administration, - jid, - ); - if (!hafasResult) { - throw new TRPCError({ - code: 'NOT_FOUND', - }); - } - return hafasResult; - }; const productDetails = getCategoryAndNumberFromName(trainName); if (!productDetails) { - return hafasFallback(); + throw new TRPCError({ + code: 'NOT_FOUND', + }); } let hafasResult: ParsedSearchOnTripResponse | undefined; if (jid && productDetails.trainNumber === 0) { @@ -216,7 +180,9 @@ export const journeysRpcRouter = rpcAppRouter({ administration, ); if (!possibleJourneys.length) { - return hafasFallback(); + throw new TRPCError({ + code: 'NOT_FOUND', + }); } let foundJourney: ParsedSearchOnTripResponse | undefined; @@ -235,7 +201,9 @@ export const journeysRpcRouter = rpcAppRouter({ foundJourney = await journeyDetails(possibleJourneys[0].journeyID); } if (!foundJourney) { - return hafasFallback(); + throw new TRPCError({ + code: 'NOT_FOUND', + }); } if (hafasResult) { diff --git a/src/server/sanitizeStorage.ts b/src/server/sanitizeStorage.ts index fc8cea6ee..7da4c87bd 100644 --- a/src/server/sanitizeStorage.ts +++ b/src/server/sanitizeStorage.ts @@ -2,21 +2,17 @@ import type { ServerStorage } from '@/client/Common/Storage'; import type { MinimalStopPlace } from '@/types/stopPlace'; export function sanitizeStorage(storage: ServerStorage): void { - sanitizeFavs(storage, 'favs'); - sanitizeFavs(storage, 'regionalFavs'); - sanitizeRoutingFavs(storage, 'rfavs'); + sanitizeFavs(storage); + sanitizeRoutingFavs(storage); } -function sanitizeFavs( - storage: ServerStorage, - storageKey: 'favs' | 'regionalFavs', -) { - const favs = storage.get(storageKey); +function sanitizeFavs(storage: ServerStorage) { + const favs = storage.get('favs'); if (!favs) { return; } if (typeof favs !== 'object') { - storage.remove(storageKey); + storage.remove('favs'); return; } let modified = false; @@ -26,23 +22,20 @@ function sanitizeFavs( modified = true; } } - if (modified) storage.set(storageKey, favs); + if (modified) storage.set('favs', favs); } function isCurrentFormatFav(stop?: MinimalStopPlace): boolean { return Boolean(stop?.evaNumber && stop.name); } -export function sanitizeRoutingFavs( - storage: ServerStorage, - storageKey: 'rfavs', -): void { - const favs = storage.get(storageKey); +export function sanitizeRoutingFavs(storage: ServerStorage): void { + const favs = storage.get('rfavs'); if (!favs) { return; } if (typeof favs !== 'object') { - storage.remove(storageKey); + storage.remove('rfavs'); return; } let modified = false; @@ -58,5 +51,5 @@ export function sanitizeRoutingFavs( modified = true; } } - if (modified) storage.set(storageKey, favs); + if (modified) storage.set('rfavs', favs); } diff --git a/src/types/HAFAS/HimSearch.ts b/src/types/HAFAS/HimSearch.ts deleted file mode 100644 index 97458d850..000000000 --- a/src/types/HAFAS/HimSearch.ts +++ /dev/null @@ -1,75 +0,0 @@ -import type { - Common, - GenericHafasRequest, - HafasStation, - HimFilter, - OptionalLocL, - ParsedProduct, -} from '@/types/HAFAS'; - -export interface HimSearchRequestOptions { - comp?: string; - dailyB?: string; - dailyE?: string; - dateB?: string; - dateE?: string; - dept?: string; - dirLoc?: OptionalLocL; - himFltrL?: HimFilter[]; - maxNum?: number; - onlyHimId?: boolean; - onlyToday?: boolean; - stLoc?: OptionalLocL; - timeB?: string; - timeE?: string; -} -export interface HimSearchRequest - extends GenericHafasRequest<'HimSearch', HimSearchRequestOptions> {} - -export interface PubChL { - name: string; - fDate: string; - fTime: string; - tDate: string; - tTime: string; -} -export interface HimMessage { - hid: string; - act: boolean; - head: string; - lead: string; - text: string; - icoX: number; - prio: number; - fLocX: number; - tLocX: number; - prod: number; - affProdRefL: number[]; - IModDate: string; - IModTime: string; - sDate: string; - sTime: string; - eDate: string; - eTime: string; - comp: string; - cat: number; - pubChL: PubChL[]; - edgeRefL: number[]; -} - -export interface ParsedHimMessage extends HimMessage { - affectedProducts: ParsedProduct[]; - startTime: Date; - endTime: Date; - fromStopPlace?: HafasStation; - toStopPlace?: HafasStation; -} - -export interface HimSearchResponse { - common: Common; - msgL: HimMessage[]; -} - -export interface ParsedHimSearchResponse { - messages: ParsedHimMessage[]; -} diff --git a/src/types/HAFAS/JourneyDetails.ts b/src/types/HAFAS/JourneyDetails.ts index fa0ac0042..922c6dc6a 100644 --- a/src/types/HAFAS/JourneyDetails.ts +++ b/src/types/HAFAS/JourneyDetails.ts @@ -1,15 +1,6 @@ import type { EvaNumber } from '@/types/common'; import type { RouteAuslastung, RouteStop } from '@/types/routing'; -import type { - Common, - CommonStopInfo, - GenericHafasRequest, - Journey, - OptionalLocL, - ParsedPolyline, - ParsedProduct, - RemL, -} from '.'; +import type { CommonStopInfo, ParsedPolyline, ParsedProduct, RemL } from '.'; // Additional Information we can only get from HAFAS in case of RIS Details. (Occupancy & correct operator names) export interface AdditionalJourneyInformation { @@ -19,38 +10,6 @@ export interface AdditionalJourneyInformation { polyline?: ParsedPolyline; } -export interface JourneyDetailsResponse { - common: Common; - journey: Journey; - fpB: string; - fpE: string; - planrtTS: string; -} - -interface JourneyDetailsRequestReq { - jid: string; - getAltCoordinates?: boolean; - getAnnotations?: boolean; - getPasslist?: boolean; - getPolyline?: boolean; - getSimpleTrainComposition?: boolean; - getTrainComposition?: boolean; - - aDate?: string; - aIdx?: number; - aLoc?: OptionalLocL; - aTime?: string; - dDate?: string; - dIdx?: number; - dLoc?: OptionalLocL; - dTime?: string; - date?: string; - name?: string; - polySplitting?: boolean; -} -export interface JourneyDetailsRequest - extends GenericHafasRequest<'JourneyDetails', JourneyDetailsRequestReq> {} - export interface RouteValidArrivalStop extends RouteStop { arrival: CommonStopInfo; } diff --git a/src/types/HAFAS/JourneyMatch.ts b/src/types/HAFAS/JourneyMatch.ts index 8de84aacf..f222660ef 100644 --- a/src/types/HAFAS/JourneyMatch.ts +++ b/src/types/HAFAS/JourneyMatch.ts @@ -1,40 +1,5 @@ import type { RouteStop } from '@/types/routing'; -import type { - Common, - GenericHafasRequest, - Journey, - JourneyFilter, - ParsedProduct, - RemL, -} from '.'; - -interface JounreyMatchRequestRes { - jnyFltrL?: JourneyFilter[]; - date: string; - dateB?: string; - dateE?: string; - extId?: string; - input: string; - - onlyCR?: boolean; - onlyRT?: boolean; - onlyTN?: boolean; - time?: string; - timeE?: string; - timeB?: string; - tripId?: string; - useAeqi?: boolean; -} -export interface JourneyMatchRequest - extends GenericHafasRequest<'JourneyMatch', JounreyMatchRequestRes> {} - -export interface JourneyMatchResponse { - common: Common; - jnyL: Journey[]; - fpB: string; - fpE: string; - planrtTS: string; -} +import type { ParsedProduct } from '.'; export interface ParsedJourneyMatchResponse { train: ParsedProduct; @@ -42,30 +7,4 @@ export interface ParsedJourneyMatchResponse { jid: string; firstStop: RouteStop; lastStop: RouteStop; - messages?: RemL[]; -} -export interface JourneyMatchOptions { - /** - * Usually " " - * @example "ICE 23" - * @Example "Bus 94212" - */ - trainName: string; - /** - * Used to find the correct journey for a specific day. - * @default now - */ - initialDepartureDate?: Date; - /** - * These are raw HAFAS Filter and quite advanced. - */ - jnyFltrL?: JourneyFilter[]; - - // onlyRT?: boolean; -} - -export interface EnrichedJourneyMatchOptions extends JourneyMatchOptions { - limit?: number; - // Only FV, will also use "onlyRT" (unknown what the exact purpose is) - filtered?: boolean; } diff --git a/src/types/HAFAS/LocMatch.ts b/src/types/HAFAS/LocMatch.ts deleted file mode 100644 index 5f8f45b58..000000000 --- a/src/types/HAFAS/LocMatch.ts +++ /dev/null @@ -1,41 +0,0 @@ -import type { Common, GenericHafasRequest } from '.'; - -export interface LocMatchResponse { - common: Common; - match: { - field: string; - state: string; - locL: { - lid: string; - type: string; - name: string; - icoX: number; - extId: string; - state: string; - crd: { - x: number; - y: number; - layerX: number; - crdSysX: number; - z?: number; - }; - meta: boolean; - pCls: number; - pRefL: number[]; - wt: number; - }[]; - }; -} - -interface LocMatchRequestReq { - input: { - loc: { - name: string; - type: 'S' | 'ALL'; - }; - field: 'S'; - }; -} - -export interface LocMatchRequest - extends GenericHafasRequest<'LocMatch', LocMatchRequestReq> {} diff --git a/src/types/HAFAS/SearchOnTrip.ts b/src/types/HAFAS/SearchOnTrip.ts index c808afee7..0d85bbe12 100644 --- a/src/types/HAFAS/SearchOnTrip.ts +++ b/src/types/HAFAS/SearchOnTrip.ts @@ -5,36 +5,7 @@ import type { import type { MatchVehicleID } from '@/external/generated/risTransports'; import type { HimIrisMessage } from '@/types/iris'; import type { RouteJourneySegmentTrain, RouteStop } from '@/types/routing'; -import type { Common, GenericHafasRequest, ParsedPolyline } from '.'; -import type { OutConL, SotCtxt } from './TripSearch'; - -export interface SearchOnTripResponse { - common: Common; - fpB: string; - fpE: string; - bfATS: number; - bflOSTS: number; - planrtTS: number; - sotCtxt: SotCtxt; - outConL: OutConL[]; -} - -export type AllowedSotMode = 'JI' | 'RC'; -interface SearchOnTripJIDRequest { - jid: string; - sotMode: 'JI'; -} - -interface SearchOnTripCTXRequest { - ctxRecon: string; - sotMode: 'RC'; -} - -export interface SearchOnTripRequest - extends GenericHafasRequest< - 'SearchOnTrip', - SearchOnTripJIDRequest | SearchOnTripCTXRequest - > {} +import type { ParsedPolyline } from '.'; export interface ParsedSearchOnTripResponse extends RouteJourneySegmentTrain { himMessages?: HimIrisMessage[]; diff --git a/src/types/HAFAS/StationBoard.ts b/src/types/HAFAS/StationBoard.ts deleted file mode 100644 index a15c2e496..000000000 --- a/src/types/HAFAS/StationBoard.ts +++ /dev/null @@ -1,77 +0,0 @@ -import type { - Common, - CommonArrival, - CommonDeparture, - CommonJny, - GenericHafasRequest, - JourneyFilter, - OptionalLocL, -} from '.'; - -export enum StationBoardSortType { - EVAID = 'EVAID', - PT = 'PT', - RT = 'RT', -} - -interface StationBoardRequestReq { - type: 'DEP' | 'ARR'; - date: string; - dateB?: string; - dateE?: string; - dur?: number; - getPasslist?: boolean; - getSimpleTrainComposition?: boolean; - getTrainComposition?: boolean; - time: string; - stbLoc: OptionalLocL; - dirLoc?: OptionalLocL; - jnyFltrL?: JourneyFilter[]; - locFltrL?: unknown[]; - maxJny?: number; - minDur?: number; - per?: boolean; - qrCode?: string; - sort?: StationBoardSortType; - stbFltrEquiv?: boolean; -} - -export interface StationBoardRequest - extends GenericHafasRequest<'StationBoard', StationBoardRequestReq> {} -export interface CommonStationBoardResponse { - common: Common; - fpB: string; - fpE: string; - planrtTS: string; - sD: string; - sT: string; - locRefL: number[]; -} -export interface ArrivalStationBoardResponse - extends CommonStationBoardResponse { - type: 'ARR'; - jnyL: ArrivalJny[]; -} -export interface DepartureStationBoardResponse - extends CommonStationBoardResponse { - type: 'DEP'; - jnyL: DepartureJny[]; -} -export type StationBoardResponse = - | ArrivalStationBoardResponse - | DepartureStationBoardResponse; - -export type DepStbStop = CommonDeparture; - -export type ArrStbStop = CommonArrival; - -export interface ArrivalJny extends CommonJny { - date: string; - stbStop: ArrStbStop; -} -export interface DepartureJny extends CommonJny { - date: string; - stbStop: DepStbStop; -} - -export type StationBoardJny = ArrivalJny | DepartureJny; diff --git a/src/types/HAFAS/Tarif.ts b/src/types/HAFAS/Tarif.ts deleted file mode 100644 index c10ab4a56..000000000 --- a/src/types/HAFAS/Tarif.ts +++ /dev/null @@ -1,26 +0,0 @@ -export enum JnyCl { - first = 1, - second = 2, -} - -export enum LoyalityCard { - BC25First = 'BC25First', - BC25Second = 'BC25Second', - BC50First = 'BC50First', - BC50Second = 'BC50Second', - SHCard = 'SHCard', - ATVorteilscard = 'ATVorteilscard', - CHGeneral = 'CHGeneral', - CHHalfWithRailplus = 'CHHalfWithRailplus', - CHHalfWithoutRailplus = 'CHHalfWithoutRailplus', - NLWithRailplus = 'NLWithRailplus', - NLWithoutRailplus = 'NLWithoutRailplus', - first100 = 'BC100First', - second100 = 'BC100Second', -} - -export enum TravelerType { - Adult = 'E', - Kid = 'K', - Baby = 'B', -} diff --git a/src/types/HAFAS/TripSearch.ts b/src/types/HAFAS/TripSearch.ts deleted file mode 100644 index 604e8068a..000000000 --- a/src/types/HAFAS/TripSearch.ts +++ /dev/null @@ -1,328 +0,0 @@ -import type { Coordinate2D } from '@/external/types'; -import type { JnyCl, LoyalityCard, TravelerType } from '@/types/HAFAS/Tarif'; -import type { EvaNumber } from '@/types/common'; -import type { - Common, - CommonArrival, - CommonDeparture, - CommonJny, - CommonStop, - GenericHafasRequest, - JourneyFilter, - MsgL, - OptionalLocL, - TrnCmpSX, -} from '.'; - -export interface TripSearchTraveler { - type: TravelerType; - /** - * Testing Comment - */ - loyalityCard?: LoyalityCard; -} - -export interface TripSearchTarifRequest { - class: JnyCl; - traveler: TripSearchTraveler[]; -} - -interface BaseTripSearchOptions extends SharedTripSearchOptions { - time?: Date; - - transferTime?: number; - maxChanges?: number; - searchForDeparture?: boolean; - onlyRegional?: boolean; - // Experimental filter to only use stuff that Netzcard allows. Use at own risk! - onlyNetzcard?: boolean; - // Filters out Attribute "DU" - "DB Fahrsscheine gelten nicht" - onlyBC100?: boolean; - tarif?: TripSearchTarifRequest; -} - -interface TripSearchViaV3 { - evaId: string; - minChangeTime?: number; -} - -export interface TripSearchOptionsV3 extends BaseTripSearchOptions { - start: EvaNumber; - destination: EvaNumber; - via?: TripSearchViaV3[]; -} - -interface StopPlaceLocation { - type: 'stopPlace'; - evaNumber: EvaNumber; -} - -interface CoordinateLocation extends Coordinate2D { - type: 'coordinate'; -} - -interface TripSearchViaV4 { - evaNumber: string; - minChangeTime?: number; -} - -type RoutingLocationInput = StopPlaceLocation | CoordinateLocation; - -export interface TripSearchOptionsV4 extends BaseTripSearchOptions { - start: RoutingLocationInput; - destination: RoutingLocationInput; - via?: TripSearchViaV4[]; -} - -interface SharedTripSearchOptions { - /** - * true = not only fastest route - */ - economic?: boolean; - /** - * Unknown flag - */ - getIV?: boolean; - /** - * Get Stop inbetween - */ - getPasslist?: boolean; - /** - * Polylines - unknown format - */ - getPolyline?: boolean; - numF?: number; - ctxScr?: string; - /** - * Is a station nearby enough for routing? - */ - ushrp?: boolean; -} - -export interface TravelerProfile { - type: TravelerType; - redtnCard?: number; -} - -export interface TarifRequest { - jnyCl: JnyCl; - cType: 'PK'; - tvlrProf: TravelerProfile[]; -} - -interface GenericTripSearchRequest extends SharedTripSearchOptions { - arrLocL: OptionalLocL[]; - depLocL: OptionalLocL[]; - viaLocL: { - loc: OptionalLocL; - min?: number; - }[]; - antiViaLocL?: { - loc: OptionalLocL; - }[]; - getPT: boolean; - maxChg: number; - minChgTime: number; - outFrwd: boolean; - jnyFltrL?: JourneyFilter[]; - trfReq?: TarifRequest; - - baim?: boolean; - ctxScr?: string; - getConGroups?: boolean; - numB?: number; - outReconL?: unknown[]; - retDate?: string; - retReconL?: unknown[]; - retTime?: string; - extChgTime?: number; - getAltCoordinates?: boolean; - getAnnotations?: boolean; - getEco?: boolean; - getEcoCmp?: boolean; - getIST?: boolean; - liveSearch?: boolean; - prefLocL?: { - loc: OptionalLocL; - }[]; - pt?: string; -} -interface DateTimeTripSeachRequest extends GenericTripSearchRequest { - outDate: string; - outTime: string; -} -interface AfterBeforeTripSearchRequest extends GenericTripSearchRequest { - ctxScr: string; -} -export interface TripSearchRequest - extends GenericHafasRequest< - 'TripSearch', - DateTimeTripSeachRequest | AfterBeforeTripSearchRequest - > { - cfg?: { - rtMode: 'HYBRID'; - }; -} - -export interface SDays { - sDaysR: string; - sDaysI: string; - sDaysB: string; -} - -export interface JnyL extends CommonJny { - stopL: CommonStop[]; -} - -export interface Freq { - minC: number; - maxC: number; - numC: number; - jnyL: JnyL[]; -} - -export interface Jny extends CommonJny { - chgDurR?: number; - isCncl?: boolean; - stopL?: CommonStop[]; - ctxRecon: string; - dTrnCmpSXmsgL: MsgL[]; - dTrnCmpSX?: TrnCmpSX; - freq: Freq; - msgL?: MsgL[]; -} - -export interface SecLJNY { - type: 'JNY'; - icoX: number; - dep: CommonDeparture; - arr: CommonArrival; - jny: Jny; - parJnyL?: Jny[]; - resState: 'N' | 'B' | 'S'; - resRecommendation: string; -} - -export interface Gis { - dist: number; - durS: string; - dirGeo: number; - ctx: string; - gisPrvr: string; - getDescr: boolean; - getPoly: boolean; -} -export interface SecLWALK { - type: 'WALK' | 'TRSF'; - icoX: number; - dep: CommonDeparture; - arr: CommonArrival; - gis: Gis; -} - -export interface SecLKISS { - type: 'KISS'; -} - -export type SecL = SecLJNY | SecLWALK | SecLKISS; - -export interface SotCtxt { - cnLocX: number; - calcDate: string; - jid: string; - locMode: string; - pLocX: number; - reqMode: string; - sectX: number; - calcTime: string; -} - -export interface TarifFare { - /** - * In Cent - */ - prc: number; - /** - * Does a more expensive Tarif exist? - */ - isFromPrice: boolean; - /** - * Can you you still buy this? - */ - isBookable: boolean; - /** - * ??? - */ - isUpsell: boolean; - /** - * ??? - */ - targetCtx: string; - buttonText: string; -} -export interface TarifFareSet { - fareL: TarifFare[]; -} -export interface HafasTarifResponse { - statusCode: 'OK' | Omit; - fareSetL: TarifFareSet[]; -} - -export interface OutConL { - isNotRdbl?: boolean; - cid: string; - date: string; - dur: string; - chg: number; - sDays: SDays; - dep: CommonDeparture; - arr: CommonArrival; - secL: SecL[]; - ctxRecon: string; - trfRes?: HafasTarifResponse; - conSubscr: string; - resState: string; - resRecommendation: string; - recState: string; - sotRating: number; - isSotCon: boolean; - showARSLink: boolean; - sotCtxt: SotCtxt; - cksum: string; - cksumDti: string; - msgL: MsgL[]; - dTrnCmpSX: TrnCmpSX; - freq: Freq; - isAlt?: boolean; -} - -export interface ConScoreL { - score: number; - conRefL: number[]; -} - -export interface ConScoringL { - type: string; - conScoreL: ConScoreL[]; -} - -export interface OutConGrpL { - name: string; - icoX: number; - grpid: string; - conScoringL: ConScoringL[]; - initScoringType: string; -} - -export interface TripSearchResponse { - common: Common; - outConL: OutConL[]; - outCtxScrB: string; - outCtxScrF: string; - fpB: string; - fpE: string; - bfATS: number; - bfIOSTS: number; - planrtTS: string; - outConGrpL: OutConGrpL[]; -} diff --git a/src/types/HAFAS/deprecated/JourneyCourse.ts b/src/types/HAFAS/deprecated/JourneyCourse.ts deleted file mode 100644 index 89231b132..000000000 --- a/src/types/HAFAS/deprecated/JourneyCourse.ts +++ /dev/null @@ -1,54 +0,0 @@ -import type { - Common, - GeoRect, - HafasDirection, - JourneyFilter, - OptionalLocL, - ParsedPolyline, -} from '@/types/HAFAS'; - -export interface JourneyCourseRequestOptions { - arrLoc?: OptionalLocL; - /** - * yyyyMMdd - */ - date: string; - depLoc?: OptionalLocL; - dir?: HafasDirection; - getEdgeAni?: boolean; - getEdgeCourse?: boolean; - getIST?: boolean; - getMainAni?: boolean; - getMainCourse?: boolean; - getPassLoc?: boolean; - getPolyline?: boolean; - jid: string; - jnyFltrL?: JourneyFilter[]; - perSize?: number; - perStep?: number; - /** - * HHmm - */ - time?: string; -} - -export interface JourneyCourseRequest { - req: JourneyCourseRequestOptions; - meth: 'JourneyCourse'; -} - -export interface JourneyCourseResponse { - common: Common; - date: string; - time: string; - mainPoly: { - polyXL: number[]; - }; - rect: GeoRect; - layerX: number; - crdSysX: number; -} - -export interface ParsedJourneyCourseResponse { - polylines: ParsedPolyline[]; -} diff --git a/src/types/HAFAS/deprecated/JourneyGraph.ts b/src/types/HAFAS/deprecated/JourneyGraph.ts deleted file mode 100644 index d718fe2e1..000000000 --- a/src/types/HAFAS/deprecated/JourneyGraph.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { JourneyFilter } from '@/types/HAFAS'; - -export interface JourneyGraphRequestOptions { - /** - * yyyyMMdd - */ - date?: string; - getPasslist?: boolean; - getProductStartEndInfo?: boolean; - jnyFltrL?: JourneyFilter[]; -} - -export interface JourneyGraphRequest { - req: JourneyGraphRequestOptions; - meth: 'JourneyGraph'; -} - -export type JourneyGraphResponse = any; diff --git a/src/types/HAFAS/deprecated/JourneyTree.ts b/src/types/HAFAS/deprecated/JourneyTree.ts deleted file mode 100644 index d6418ce24..000000000 --- a/src/types/HAFAS/deprecated/JourneyTree.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { - GenericHafasRequest, - GeoRect, - GeoRing, - HimFilter, - JourneyFilter, -} from '@/types/HAFAS'; - -export interface JourneyTreeRequestOptions { - getChilds?: number; - getHIM?: boolean; - getParent?: boolean; - getStatus?: boolean; - himFltrL?: HimFilter[]; - jnyFltrL?: JourneyFilter[]; - pid?: string; - rect?: GeoRect; - ring?: GeoRing; -} - -export interface JourneyTreeRequest extends GenericHafasRequest<'JourneyTree'> { - req: JourneyTreeRequestOptions; -} - -export type JourneyTreeResponse = unknown; diff --git a/src/types/HAFAS/index.ts b/src/types/HAFAS/index.ts index 871b92fae..0516f4fcb 100644 --- a/src/types/HAFAS/index.ts +++ b/src/types/HAFAS/index.ts @@ -1,180 +1,4 @@ -import type { HimSearchRequest } from '@/types/HAFAS/HimSearch'; -import type { JourneyMatchRequest } from '@/types/HAFAS/JourneyMatch'; -import type { SearchOnTripRequest } from '@/types/HAFAS/SearchOnTrip'; -import type { StationBoardRequest } from '@/types/HAFAS/StationBoard'; -import type { JourneyTreeRequest } from '@/types/HAFAS/deprecated/JourneyTree'; import type { MinimalStopPlace } from '@/types/stopPlace'; -import type { JourneyDetailsRequest } from './JourneyDetails'; -import type { LocMatchRequest } from './LocMatch'; -import type { TripSearchRequest } from './TripSearch'; - -export type JourneyFilterMode = 'BIT' | 'EXC' | 'INC' | 'UNDEF'; -export type JourneyFilterType = - | 'ADM' - | 'ATTRF' - | 'ATTRJ' - | 'ATTRL' - | 'BC' - | 'CAT' - | 'COUCH' - | 'CTX_RECON' - | 'GROUP' - | 'INFOTEXTS' - | 'JID' - | 'LID' - | 'LINE' - | 'LINEID' - | 'META' - | 'NAME' - | 'NUM' - | 'OP' - | 'PID' - | 'PROD' - | 'ROUTE' - | 'SLEEP' - | 'STATIONS' - | 'UIC'; - -export type AllowedHafasMethods = - | 'BookingAssortment' - | 'BookingData' - | 'BookingValidation' - | 'FeederBoard' - | 'FetcherBoard' - | 'GisRoute' - | 'HimMatch' - | 'HimSearch' - | 'JourneyCourse' - | 'JourneyDetails' - | 'JourneyGeoPos' - | 'JourneyGraph' - | 'JourneyMatch' - | 'JourneyTree' - | 'LocDetails' - | 'LocGeoPos' - | 'LocGeoReach' - | 'LocGraph' - | 'LocMatch' - | 'MatchMe' - | 'OneFieldSearch' - | 'PartialSearch' - | 'Reconstruction' - | 'SearchOnTrip' - | 'ServerInfo' - | 'StationBoard' - | 'StationDetails' - | 'SubscriptionCreate' - | 'SubscriptionDelete' - | 'SubscriptionDetails' - | 'SubscriptionNotification' - | 'SubscriptionSearch' - | 'SubscriptionStatus' - | 'SubscriptionUpdate' - | 'SubscriptionUserCreate' - | 'SubscriptionUserDelete' - | 'SubscriptionUserUpdate' - | 'SubscriptionValidate' - | 'TripSearch'; - -export type HafasDirection = 'B' | 'F' | 'FB'; -export type HimFilterMode = 'BIT' | 'EXC' | 'INC' | 'UNDEF'; -export type HimFilterType = - | 'ADMIN' - | 'CAT' - | 'CH' - | 'COMP' - | 'DEPT' - | 'EID' - | 'HIMCAT' - | 'HIMID' - | 'LINE' - | 'OPR' - | 'PID' - | 'PROD' - | 'REG' - | 'TRAIN'; -export interface HimFilter { - mode: HimFilterMode; - type: HimFilterType; - value: string; -} -export interface JourneyFilter { - mode: JourneyFilterMode; - type: JourneyFilterType; - value: string; -} - -export type LocationFilterMode = 'BIT' | 'EXC' | 'INC'; -export type LocationFilterType = - | 'ATTRL' - | 'ATTRP' - | 'META' - | 'NGR' - | 'PLATF' - | 'PROD' - | 'ROUP_A' - | 'ROUP_N' - | 'ROUP_S' - | 'ROUP_V' - | 'ROUP_Z' - | 'ROUS_A' - | 'ROUS_N' - | 'ROUS_S' - | 'ROUS_V' - | 'ROUS_Z' - | 'ROU_A' - | 'ROU_N' - | 'ROU_S' - | 'ROU_Z' - | 'SLCTP_A' - | 'SLCTP_N' - | 'SLCTP_V' - | 'SLCTP_Z' - | 'SLCTS_A' - | 'SLCTS_N' - | 'SLCTS_S' - | 'SLCTS_V' - | 'SLCTS_Z' - | 'SLCT_A' - | 'SLCT_N' - | 'SLCT_S' - | 'SLCT_V' - | 'SLCVT_Z'; - -export type LocationNGrammFilterMode = - | 'DIST_ATTR' - | 'DIST_INFO' - | 'DIST_PERI' - | 'DIST_RNG' - | 'DIST_STNR' - | 'EXCL_ATTR' - | 'EXCL_INFO' - | 'EXCL_META' - | 'EXCL_PERI' - | 'EXCL_RNG' - | 'EXCL_STNR' - | 'ONLY_META' - | 'SLCT_ATTR' - | 'SLCT_INFO' - | 'SLCT_PERI' - | 'SLCT_PROD' - | 'SLCT_RNG' - | 'SLCT_STNR'; -export interface LocationNGrammFilter { - attr?: string; - crd?: Crd; - endIds?: string; - fTxt?: string; - maxDist?: number; - startIds?: string; - type: LocationNGrammFilterMode; -} -export interface LocationFilter { - mode: LocationFilterMode; - ngramm: LocationNGrammFilter; - type: LocationFilterType; - value: string; -} export interface CommonProductInfo { name: string; @@ -236,14 +60,6 @@ export interface RemL { sIdx?: number; } -export interface SDaysL { - sDaysR: string; - sDaysI: string; - sDaysB: string; - fLocX: number; - tLocX: number; -} - export interface HafasCoordinates { lat: number; lng: number; @@ -277,268 +93,10 @@ export enum AllowedHafasProfile { // all = 'all', } -export interface GenericHafasRequest< - out Meth extends string, - out Req = unknown, -> { - meth: Meth; - req: Req; -} -export type HafasRequest = SingleHafasRequest[]; -export type SingleHafasRequest = - // | JourneyCourseRequest - // | JourneyGraphRequest - | JourneyTreeRequest - | StationBoardRequest - | HimSearchRequest - | JourneyMatchRequest - | LocMatchRequest - | JourneyDetailsRequest - | SearchOnTripRequest - | TripSearchRequest; - -interface CInfo { - code: string; - url: string; - msg: string; -} - -interface SvcResL { - meth: string; - err: string; - res: Res; -} - -export interface GenericRes { - common: Common; -} - -export interface HafasResponse { - ver: string; - lang: string; - id: string; - err: string; - cInfo: CInfo; - svcResL: SvcResL[]; -} - -export interface ProdCtx { - name: string; - num?: string; - matchId?: string; - catOut?: string; - catOutS?: string; - catOutL?: string; - catIn?: string; - catCode?: string; - admin?: string; - lineId?: string; - line?: string; - cls: number; - icoX: number; -} - -export interface ProdL { - name: string; - number?: string; - icoX: number; - cls: number; - oprX?: number; - prodCtx?: ProdCtx; - addName?: string; - nameS?: string; - matchId?: string; -} - -export interface LayerL { - id: string; - name: string; - index: number; - annoCnt: number; -} - -export interface CrdSysL { - id: string; - index: number; - type: string; -} - -export interface IcoL { - res: string; - txt?: string; -} - -export interface Crd { - x: number; - y: number; - z?: number; - layerX?: number; - crdSysX?: number; -} - -export interface PolyG { - polyXL: number[]; - layerX: number; - crdSysX: number; -} - -export interface Journey { - jid: string; - date: string; - prodX: number; - status?: string; - isRchbl?: boolean; - stopL: CommonStop[]; - sDaysL: SDaysL[]; - polyG?: PolyG; - msgL?: MsgL[]; - subscr?: string; - prodL?: ProdL[]; - dTrnCmpSX?: TrnCmpSX; -} -export interface OptionalLocL { - lid?: string; - type?: string; - name?: string; - icoX?: number; - extId?: string; - state?: string; - crd?: Crd; - pCls?: number; - /** - * Reference to prodL - */ - pRefL?: number[]; -} - -export type LocL = Required; - -export interface PpLocRefL { - ppIdx: number; - locX: number; -} - -export interface PolyL { - delta: boolean; - dim: number; - crdEncYX: string; - crdEncS: string; - crdEncF: string; - ppLocRefL: PpLocRefL[]; -} - export interface OpL { name: string; - icoX?: number; -} - -export interface TcocL { - c: string; - r?: number; -} - -export interface HimMsgEdgeL { - icoCrd: { - x: string; - y: string; - }; } -export interface Common { - locL: LocL[]; - prodL: ProdL[]; - polyL: PolyL[]; - layerL: LayerL[]; - crdSysL: CrdSysL[]; - opL: OpL[]; - remL: RemL[]; - icoL: IcoL[]; - tcocL?: TcocL[]; - himMsgEdgeL?: HimMsgEdgeL[]; -} - -export interface CommonJny { - jid: string; - prodX: number; - dirTxt: string; - status: string; - isRchbl: boolean; - isCncl?: boolean; - isPartCncl?: boolean; - subscr: string; - stopL?: CommonStop[]; - msgL?: MsgL[]; -} - -export interface CommonArrival { - locX: number; - idx?: number; - aCncl?: boolean; - aProdX?: number; - aOutR: boolean; - aTimeS: string; - aTimeR?: string; - aPlatfS?: string; - aPlatfR?: string; - aProgType?: string; - type?: string; - aTZOffset?: number; - aTrnCmpSX?: TrnCmpSX; - msgL?: MsgL[]; -} - -export interface CommonDeparture { - locX: number; - idx?: number; - dCncl?: boolean; - dProdX?: number; - dInS: boolean; - dInR: boolean; - dTimeS: string; - dTimeR?: string; - dPlatfS?: string; - dPlatfR?: string; - dProgType?: string; - type?: string; - dTZOffset?: number; - dTrnCmpSX?: TrnCmpSX; - msgL?: MsgL[]; -} - -export interface CommonStop extends CommonArrival, CommonDeparture { - isAdd?: boolean; -} - -export interface TxtC { - r: number; - g: number; - b: number; -} - -export interface MsgL { - type: string; - remX: number; - txtC: TxtC; - prio: number; - fIdx: number; - tIdx: number; - tagL: string[]; -} - -export interface TrnCmpSX { - tcocX?: number[]; - tcM?: number; -} - -// ParsedStuff -interface _ParsedCommon { - locL: HafasStation[]; - prodL: ParsedProduct[]; - polyL?: ParsedPolyline[]; -} -export type ParsedCommon = _ParsedCommon & - Omit; - export type ParsedProduct = CommonProductInfo; export interface ParsedPolyline { @@ -547,16 +105,3 @@ export interface ParsedPolyline { delta?: boolean; locations: HafasStation[]; } - -export type InOutMode = 'B' | 'I' | 'N' | 'O'; - -export interface GeoRect { - llCrd: Crd; - urCrd: Crd; -} - -export interface GeoRing { - cCrd: Crd; - maxDist: number; - minDist?: number; -} diff --git a/src/types/routing.ts b/src/types/routing.ts index 3a3fdd778..90f035308 100644 --- a/src/types/routing.ts +++ b/src/types/routing.ts @@ -9,10 +9,8 @@ import type { CommonStopInfo, HafasStation, ParsedProduct, - ProdL, RemL, } from './HAFAS'; -import type { SecL } from './HAFAS/TripSearch'; import type { Message } from './iris'; export interface RouteStop { @@ -64,8 +62,6 @@ export interface RouteJourney { jid?: string; // RIS JourneyID journeyId?: string; - product?: ProdL; - raw?: SecL; segmentDestination: MinimalStopPlace; segmentStart: MinimalStopPlace; stops: RouteStop[];