Add TypeScript project references, update ESLint configs to support ESM modules, and introduce brand semantic color tokens across the web app. Add comprehensive documentation for architecture, API reference, development setup, and user guide.
6.2 KiB
Core & API Client Reference
This document provides a detailed reference for the internal packages: @timetoleave/core and @timetoleave/api-client.
📦 @timetoleave/core
The core package contains all domain types, status calculation logic, HAFAS time parsing, and formatting utilities. It has zero runtime dependencies outside of the standard library.
Types (types.ts)
| Interface | Description |
|---|---|
Event |
Represents a calendar event with an assigned destination and event time. |
CalendarEvent |
Raw calendar event data (typically string dates before conversion to Event). |
Station |
A transport station with a name, HAFAS extId, and optional coordinates. |
Journey |
A public transport connection including scheduled/real departure/arrival, delay, platform, and cancellation status. |
BikeRoute / WalkRoute |
Routing data including total distance, duration, and step-by-step instructions. |
CountdownInfo |
Output of the countdown utility containing a label, color code, and urgency flag. |
ReminderSettings |
User preferences for buffers, walking/bike options, and reminder toggles. |
WienerLinienDeparture |
Specific types for WienerLinien (Vienna public transport) monitor responses. |
HAFAS Time Utilities (hafas-time.ts)
HAFAS timestamps are strictly tied to the Europe/Vienna timezone (CET/CEST). These utilities handle the bi-directional conversion between UTC JavaScript Date objects and HAFAS strings, correctly handling Daylight Saving Time (DST) transitions.
import { parseHafasTime, hafasDateTime } from '@timetoleave/core';
// Parse HAFAS date ("YYYYMMDD") and time ("HHMMSS") into a UTC Date object
const dateObj = parseHafasTime("20231027", "143000");
// Convert a UTC Date object back to HAFAS date and time strings
const { date, time } = hafasDateTime(dateObj);
// Returns: { date: "20231027", time: "143000" }
Note:
getTimezoneOffsetMinutesis designed exclusively for full-hour offsets likeEurope/Vienna. It will produce incorrect results for fractional timezones (e.g., India +05:30).
Countdown & Status Utilities
calculateCountdown(targetDate: Date): CountdownInfo
Calculates the time delta between now and targetDate, returning a human-readable label, a color code, and an urgency boolean.
| Time Delta | Label | Color | Urgent |
|---|---|---|---|
<= 0 min |
Now |
red |
true |
<= 10 min |
[X]min |
orange |
true |
<= 30 min |
[X]min |
yellow |
false |
<= 60 min |
[X]min |
green |
false |
> 60 min |
[X]h [Y]min |
blue |
false |
getLeaveStatus(event: Event, journeys: Journey[]): string
Derives a human-readable leave-by status by finding the earliest non-cancelled journey and comparing its real departure time (rD) against the current time.
Possible Returns:
"No journey data""All journeys cancelled""Departure missed"(ifrDis in the past)"Delayed +[X] min"(if delay exceeds 10 minutes)"Leave now"(if departure is within 15 minutes)"On time"
Formatting Utilities (formatting.ts)
All formatting functions default to the de-AT locale to match the primary target region.
formatTime(date: Date)->"14:30"formatDate(date: Date)->"Mi., 27. Oktober 2023"formatDateTime(date: Date)->"27. Oktober 2023, 14:30"formatDuration(seconds: number)->"1h 23min"or"45min"formatDistance(meters: number)->"1.2km"or"800m"
🌐 @timetoleave/api-client
The API client is a lightweight wrapper around the Web App's Next.js API routes. It handles URL construction, query parameters, and JSON serialization.
Initialization
import { ApiClient } from '@timetoleave/api-client';
// Initialize with the base URL of the backend proxy
const api = new ApiClient('http://localhost:3000');
Methods
getHealth()
getHealth(): Promise<{ status: 'ok'; uptime: number }>
Checks the /api/health endpoint to verify backend availability.
geocode(name: string, countrycodes?: string)
geocode(name: string, countrycodes?: string): Promise<GeocodeResult[]>
Performs forward geocoding via /api/geocode.
reverseGeocode(lat: number, lng: number)
reverseGeocode(lat: number, lng: number): Promise<GeocodeResult | null>
Performs reverse geocoding via /api/geocode/reverse.
fetchCalendar(url: string, days?: number)
fetchCalendar(url: string, days?: number): Promise<CalendarEvent[]>
Fetches and parses a remote .ics file via /api/calendar. The optional days parameter limits the fetch to upcoming events.
parseCalendarIcs(content: string)
parseCalendarIcs(content: string): Promise<CalendarEvent[]>
Parses raw .ics string content via /api/calendar/parse.
searchStation(query: string)
searchStation(query: string): Promise<Station[]>
Searches for stations by name using the HAFAS LocMatch method. Returns up to 5 matches with valid extIds.
searchJourneys(fromStationExtId: string, toStationExtId: string, date: Date)
searchJourneys(from: string, to: string, date: Date): Promise<Journey[]>
Sends a HAFAS TripSearch request to find public transport connections between two stations. It automatically converts the Date to HAFAS-compatible strings.
getBikeRoute(fromLat, fromLng, toLat, toLng) & getWalkRoute(fromLat, fromLng, toLat, toLng)
getBikeRoute(...): Promise<BikeRoute>
getWalkRoute(...): Promise<WalkRoute>
Retrieves routing data for the "first mile / last mile" segment (e.g., biking from home to the train station).
findNearbyStops(lat: number, lng: number, radius?: number)
findNearbyStops(lat: number, lng: number, radius: number = 1000): Promise<NearbyStop[]>
Finds public transport stops within a specific radius using the WienerLinien API (/api/wienerlinien/stops).
hafasRequest<T>(body: unknown)
hafasRequest<T>(body: unknown): Promise<T>
A generic method to send arbitrary HAFAS protocol bodies to /api/hafas. Useful for advanced use-cases not covered by the wrapper methods.