-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrequests.ts
96 lines (82 loc) · 2.82 KB
/
requests.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import type { Connection, Journey } from "../../models/connection.ts";
import { DateTime } from "luxon";
import { mergeConnections } from "../../lib/merge.ts";
import { mapConnection } from "../../lib/mapping.ts";
export enum RequestType {
DEPARTURES = "departures",
ARRIVALS = "arrivals"
}
/**
* specifies the profile used in boards
* db = RIS
* dbnav = HAFAS
* combined = both
*/
export enum Profile {
DB = "db",
DBNAV = "dbnav",
COMBINED = "combined"
}
export interface Query {
evaNumber: string;
type: RequestType;
profile?: Profile;
when?: string;
duration?: number;
results?: number;
locale?: string;
}
export const retrieveConnections = async (query: Query): Promise<Connection[]> => {
const request = await fetch(
`https://vendo-prof-${query.profile}.voldechse.wtf/stops/${query.evaNumber}/${query.type}?when=${encodeURIComponent(
query.when!
)}&duration=${query.duration}&results=${query.results}`,
{ method: "GET" }
);
if (!request.ok) return [];
const data = await request.json();
if (!data[query.type] || !Array.isArray(data[query.type])) return [];
const map = new Map<string, Connection>();
data[query.type].forEach((connectionRaw: any) => {
const tripId = connectionRaw?.tripId;
if (!tripId || map.has(tripId)) return;
const connection: Connection = mapConnection(connectionRaw, query.type, query.profile!.toString() as "db" | "dbnav");
if (!connection) return;
map.set(tripId, connection);
});
return Array.from(map.values());
};
export const retrieveCombinedConnections = async (
query: Query,
destinationOriginCriteria: boolean = false
): Promise<Connection[]> => {
const [db, dbnav] = await Promise.all([
retrieveConnections({ ...query, profile: Profile.DB }),
retrieveConnections({ ...query, profile: Profile.DBNAV })
]);
const connections = mergeConnections(db, dbnav, query.type, destinationOriginCriteria);
if (!connections) return [];
return connections.sort((a, b) => {
const dir = query.type === "departures" ? "departure" : "arrival";
const getTime = (c: Connection) => {
const time = c[dir]?.actualTime ?? c[dir]?.plannedTime;
return time ? DateTime.fromISO(time).toMillis() : 0;
};
return getTime(a) - getTime(b);
});
};
export const retrieveBahnhofJourneys = async (query: Query): Promise<Journey[]> => {
const request = await fetch(
`https://bahnhof.de/api/boards/${query.type}?evaNumbers=${query.evaNumber}&duration=${query.duration}&locale=${query.locale}`
);
if (!request.ok) return [];
const response = await request.json();
if (!response?.entries || !Array.isArray(response?.entries)) return [];
return Object.values(response?.entries)
.filter(Array.isArray)
.map((journeyRaw) => ({
connections: journeyRaw
.filter((connectionRaw) => connectionRaw?.journeyID)
.map((connectionRaw) => mapConnection(connectionRaw, query.type, "db"))
}));
};