Files
time_to_leave/docs/API_REFERENCE.md
T
fegger 3c6df95a86 Refactor monorepo structure and replace hardcoded colors
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.
2026-05-12 21:22:40 +02:00

150 lines
6.2 KiB
Markdown

# 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.
```typescript
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:** `getTimezoneOffsetMinutes` is designed exclusively for full-hour offsets like `Europe/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"` (if `rD` is 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
```typescript
import { ApiClient } from '@timetoleave/api-client';
// Initialize with the base URL of the backend proxy
const api = new ApiClient('http://localhost:3000');
```
### Methods
#### `getHealth()`
```typescript
getHealth(): Promise<{ status: 'ok'; uptime: number }>
```
Checks the `/api/health` endpoint to verify backend availability.
#### `geocode(name: string, countrycodes?: string)`
```typescript
geocode(name: string, countrycodes?: string): Promise<GeocodeResult[]>
```
Performs forward geocoding via `/api/geocode`.
#### `reverseGeocode(lat: number, lng: number)`
```typescript
reverseGeocode(lat: number, lng: number): Promise<GeocodeResult | null>
```
Performs reverse geocoding via `/api/geocode/reverse`.
#### `fetchCalendar(url: string, days?: number)`
```typescript
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)`
```typescript
parseCalendarIcs(content: string): Promise<CalendarEvent[]>
```
Parses raw `.ics` string content via `/api/calendar/parse`.
#### `searchStation(query: string)`
```typescript
searchStation(query: string): Promise<Station[]>
```
Searches for stations by name using the HAFAS `LocMatch` method. Returns up to 5 matches with valid `extId`s.
#### `searchJourneys(fromStationExtId: string, toStationExtId: string, date: Date)`
```typescript
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)`
```typescript
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)`
```typescript
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)`
```typescript
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.