Add JSDoc documentation to all TypeScript files
This commit is contained in:
@@ -1,6 +1,15 @@
|
||||
// Countdown utilities for TimeToLeave
|
||||
import { CountdownInfo } from "./types";
|
||||
|
||||
/**
|
||||
* Determine the countdown label, color and urgency for a target time.
|
||||
*
|
||||
* Thresholds (minutes until target):
|
||||
* - 0 → red, "Now"
|
||||
* - ≤10 → orange (urgent)
|
||||
* - ≤30 → yellow
|
||||
* - ≤60 → green
|
||||
* - >60 → blue ("Xh Ymin")
|
||||
*/
|
||||
export function calculateCountdown(targetDate: Date): CountdownInfo {
|
||||
const now = new Date();
|
||||
const diffMs = targetDate.getTime() - now.getTime();
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
// ── Defaults ──
|
||||
// Fallback origin station (Mödling, Austria) used when geolocation is
|
||||
// unavailable or the user hasn't set a custom origin.
|
||||
|
||||
import type { Station } from "./types";
|
||||
|
||||
export const DEFAULT_ORIGIN_ADDRESS = "Goethegasse 36, 2340 Moedling";
|
||||
@@ -6,6 +10,7 @@ export const DEFAULT_ORIGIN_LNG = 16.2908052;
|
||||
export const DEFAULT_ORIGIN_STATION_NAME = "Mödling Bahnhof";
|
||||
export const DEFAULT_ORIGIN_STATION_EXT_ID = "1231701";
|
||||
|
||||
/** Pre-assembled default station object for convenience. */
|
||||
export const DEFAULT_ORIGIN_STATION: Station = {
|
||||
name: DEFAULT_ORIGIN_ADDRESS,
|
||||
extId: DEFAULT_ORIGIN_STATION_EXT_ID,
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
// Formatting utilities for TimeToLeave
|
||||
// ── Formatting utilities ──
|
||||
// All formatters use Austrian locale (de-AT) for consistency with the target market.
|
||||
|
||||
/** Format a Date as a 24h clock time string (HH:mm). */
|
||||
export function formatTime(date: Date): string {
|
||||
return date.toLocaleTimeString("de-AT", { hour: "2-digit", minute: "2-digit" });
|
||||
}
|
||||
|
||||
/** Format a Date as a localized date string (weekday, day, month, year). */
|
||||
export function formatDate(date: Date): string {
|
||||
return date.toLocaleDateString("de-AT", {
|
||||
weekday: "short",
|
||||
@@ -13,6 +16,7 @@ export function formatDate(date: Date): string {
|
||||
});
|
||||
}
|
||||
|
||||
/** Format a Date as a full date+time string for display. */
|
||||
export function formatDateTime(date: Date): string {
|
||||
return date.toLocaleString("de-AT", {
|
||||
day: "numeric",
|
||||
@@ -23,6 +27,7 @@ export function formatDateTime(date: Date): string {
|
||||
});
|
||||
}
|
||||
|
||||
/** Convert seconds to a human-readable duration (e.g. "1h 30min"). */
|
||||
export function formatDuration(seconds: number): string {
|
||||
const hours = Math.floor(seconds / 3600);
|
||||
const minutes = Math.floor((seconds % 3600) / 60);
|
||||
@@ -33,6 +38,7 @@ export function formatDuration(seconds: number): string {
|
||||
return `${minutes}min`;
|
||||
}
|
||||
|
||||
/** Convert meters to a human-readable distance (meters or km). */
|
||||
export function formatDistance(meters: number): string {
|
||||
if (meters < 1000) {
|
||||
return `${meters}m`;
|
||||
|
||||
@@ -1,9 +1,25 @@
|
||||
// ── HAFAS Response Parser ──
|
||||
// Transforms raw HAFAS protocol JSON into clean `Journey` objects.
|
||||
// HAFAS encodes times relative to a date boundary (day wraps at 00:00),
|
||||
// so the caller must provide the original query date for correct parsing.
|
||||
|
||||
import type { Journey } from "./types";
|
||||
import { parseHafasTime } from "./hafas-time";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
type RawJson = any;
|
||||
|
||||
/**
|
||||
* Parse the `outConL` array from a HAFAS TripSearch response into Journey objects.
|
||||
*
|
||||
* Each connection (`con`) contains a list of sections (`secL`). The first section's
|
||||
* departure and the last section's arrival define the journey boundaries. Train names
|
||||
* are extracted from the first stop of each train leg.
|
||||
*
|
||||
* @param json - Raw HAFAS response body
|
||||
* @param hafasDate - The HAFAS date string ("YYYYMMDD") used for the query
|
||||
* @param queryDate - The original JavaScript Date used for the query (fallback for missing times)
|
||||
*/
|
||||
export function parseHafasJourneys(json: RawJson, hafasDate: string, queryDate: Date): Journey[] {
|
||||
const outConL: RawJson[] = json?.svcResL?.[0]?.res?.outConL ?? [];
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Re-export everything for clean imports
|
||||
// ── Re-exports ──
|
||||
// Barrel file: import everything from `@timetoleave/core` in one go.
|
||||
|
||||
export * from './types';
|
||||
export * from './countdown-utils';
|
||||
export * from './formatting';
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Status utilities for TimeToLeave
|
||||
// ── Status utilities ──
|
||||
import type { ServerStatus, Event, Journey } from "./types";
|
||||
|
||||
/** Utility class for server health checks. */
|
||||
export class StatusUtils {
|
||||
static async checkServerStatus(url: string): Promise<ServerStatus> {
|
||||
try {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Core domain types
|
||||
// Core domain types for TimeToLeave
|
||||
|
||||
/** Event stored in the application (eventTime as Date). */
|
||||
export interface Event {
|
||||
id: string;
|
||||
title: string;
|
||||
@@ -8,6 +9,7 @@ export interface Event {
|
||||
source: string;
|
||||
}
|
||||
|
||||
/** Calendar event from an ICS feed (eventTime as ISO string for serialization). */
|
||||
export interface CalendarEvent {
|
||||
id: string;
|
||||
title: string;
|
||||
@@ -16,6 +18,7 @@ export interface CalendarEvent {
|
||||
source: string;
|
||||
}
|
||||
|
||||
/** HAFAS station with optional GPS coordinates. */
|
||||
export interface Station {
|
||||
name: string;
|
||||
extId: string;
|
||||
@@ -23,6 +26,7 @@ export interface Station {
|
||||
lng?: number;
|
||||
}
|
||||
|
||||
/** A single transit journey with schedule vs. real-time data. */
|
||||
export interface Journey {
|
||||
id: string;
|
||||
sD: Date; // scheduled departure
|
||||
@@ -36,6 +40,7 @@ export interface Journey {
|
||||
cancelled: boolean;
|
||||
}
|
||||
|
||||
/** Bike routing step from OSRM. */
|
||||
export interface BikeStep {
|
||||
name: string;
|
||||
distance: number;
|
||||
@@ -43,18 +48,21 @@ export interface BikeStep {
|
||||
instruction: string;
|
||||
}
|
||||
|
||||
/** Complete bike route with step-by-step directions. */
|
||||
export interface BikeRoute {
|
||||
distance: number;
|
||||
duration: number;
|
||||
steps: BikeStep[];
|
||||
}
|
||||
|
||||
/** Walking route from OSRM with turn-by-turn steps. */
|
||||
export interface WalkRoute {
|
||||
distance: number;
|
||||
duration: number;
|
||||
steps: WalkStep[];
|
||||
}
|
||||
|
||||
/** Walking step from OSRM route data. */
|
||||
export interface WalkStep {
|
||||
name: string;
|
||||
distance: number;
|
||||
@@ -62,17 +70,21 @@ export interface WalkStep {
|
||||
instruction: string;
|
||||
}
|
||||
|
||||
/** Countdown display info derived from the time remaining until an event. */
|
||||
export interface CountdownInfo {
|
||||
label: string;
|
||||
color: string;
|
||||
urgent: boolean;
|
||||
}
|
||||
|
||||
/** Geolocation permission state. */
|
||||
export type LocState = "pending" | "granted" | "denied";
|
||||
/** Calendar sync status. */
|
||||
export type CalStatus = null | "loading" | "ok" | "error";
|
||||
|
||||
// ── Reminder Settings ──────────────────────────────────
|
||||
|
||||
/** Persistent reminder preferences stored in localStorage. */
|
||||
export interface ReminderSettings {
|
||||
bufferMinutes: number;
|
||||
enabled: boolean;
|
||||
@@ -81,21 +93,25 @@ export interface ReminderSettings {
|
||||
showBikeOption: boolean; // show bike route section (default true)
|
||||
}
|
||||
|
||||
/** Server health check result. */
|
||||
export type ServerStatus = boolean | null;
|
||||
|
||||
/** Result from Nominatim geocoding. */
|
||||
export interface GeocodeResult {
|
||||
lat: number;
|
||||
lng: number;
|
||||
display_name: string;
|
||||
}
|
||||
|
||||
// WienerLinien types
|
||||
// ── WienerLinien (Vienna public transport) types ──
|
||||
|
||||
/** A WienerLinien vehicle line. */
|
||||
export interface WienerLinienLine {
|
||||
name: string;
|
||||
type?: string;
|
||||
}
|
||||
|
||||
/** A WienerLinien stop with GPS coordinates. */
|
||||
export interface WienerLinienStop {
|
||||
id: string;
|
||||
name: string;
|
||||
@@ -103,6 +119,7 @@ export interface WienerLinienStop {
|
||||
lng: number;
|
||||
}
|
||||
|
||||
/** Departure from a WienerLinien stop. */
|
||||
export interface WienerLinienDeparture {
|
||||
stopId: string;
|
||||
line: WienerLinienLine;
|
||||
@@ -111,6 +128,7 @@ export interface WienerLinienDeparture {
|
||||
delay?: number;
|
||||
}
|
||||
|
||||
/** Response from the WienerLinien monitor endpoint. */
|
||||
export interface WienerLinienMonitorResponse {
|
||||
stops: {
|
||||
stopId: string;
|
||||
@@ -118,6 +136,7 @@ export interface WienerLinienMonitorResponse {
|
||||
}[];
|
||||
}
|
||||
|
||||
/** Stop found nearby the user's location. */
|
||||
export interface NearbyStop {
|
||||
id: string;
|
||||
name: string;
|
||||
|
||||
Reference in New Issue
Block a user