lt-public-transport-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +283 -0
  3. package/assets/architecture.png +0 -0
  4. package/dist/config.d.ts +221 -0
  5. package/dist/config.d.ts.map +1 -0
  6. package/dist/config.js +200 -0
  7. package/dist/config.js.map +1 -0
  8. package/dist/enrichment/index.d.ts +6 -0
  9. package/dist/enrichment/index.d.ts.map +1 -0
  10. package/dist/enrichment/index.js +6 -0
  11. package/dist/enrichment/index.js.map +1 -0
  12. package/dist/enrichment/route-matcher.d.ts +64 -0
  13. package/dist/enrichment/route-matcher.d.ts.map +1 -0
  14. package/dist/enrichment/route-matcher.js +121 -0
  15. package/dist/enrichment/route-matcher.js.map +1 -0
  16. package/dist/errors.d.ts +70 -0
  17. package/dist/errors.d.ts.map +1 -0
  18. package/dist/errors.js +104 -0
  19. package/dist/errors.js.map +1 -0
  20. package/dist/gtfs/index.d.ts +7 -0
  21. package/dist/gtfs/index.d.ts.map +1 -0
  22. package/dist/gtfs/index.js +7 -0
  23. package/dist/gtfs/index.js.map +1 -0
  24. package/dist/gtfs/parser.d.ts +39 -0
  25. package/dist/gtfs/parser.d.ts.map +1 -0
  26. package/dist/gtfs/parser.js +189 -0
  27. package/dist/gtfs/parser.js.map +1 -0
  28. package/dist/gtfs/sync.d.ts +72 -0
  29. package/dist/gtfs/sync.d.ts.map +1 -0
  30. package/dist/gtfs/sync.js +271 -0
  31. package/dist/gtfs/sync.js.map +1 -0
  32. package/dist/index.d.ts +203 -0
  33. package/dist/index.d.ts.map +1 -0
  34. package/dist/index.js +342 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/parsers/gps-full.d.ts +39 -0
  37. package/dist/parsers/gps-full.d.ts.map +1 -0
  38. package/dist/parsers/gps-full.js +212 -0
  39. package/dist/parsers/gps-full.js.map +1 -0
  40. package/dist/parsers/gps-lite.d.ts +60 -0
  41. package/dist/parsers/gps-lite.d.ts.map +1 -0
  42. package/dist/parsers/gps-lite.js +141 -0
  43. package/dist/parsers/gps-lite.js.map +1 -0
  44. package/dist/parsers/index.d.ts +7 -0
  45. package/dist/parsers/index.d.ts.map +1 -0
  46. package/dist/parsers/index.js +7 -0
  47. package/dist/parsers/index.js.map +1 -0
  48. package/dist/schemas.d.ts +129 -0
  49. package/dist/schemas.d.ts.map +1 -0
  50. package/dist/schemas.js +200 -0
  51. package/dist/schemas.js.map +1 -0
  52. package/dist/scripts/test-city-specific.d.ts +2 -0
  53. package/dist/scripts/test-city-specific.d.ts.map +1 -0
  54. package/dist/scripts/test-city-specific.js +264 -0
  55. package/dist/scripts/test-city-specific.js.map +1 -0
  56. package/dist/scripts/test-config-options.d.ts +2 -0
  57. package/dist/scripts/test-config-options.d.ts.map +1 -0
  58. package/dist/scripts/test-config-options.js +166 -0
  59. package/dist/scripts/test-config-options.js.map +1 -0
  60. package/dist/scripts/test-data-quality.d.ts +2 -0
  61. package/dist/scripts/test-data-quality.d.ts.map +1 -0
  62. package/dist/scripts/test-data-quality.js +204 -0
  63. package/dist/scripts/test-data-quality.js.map +1 -0
  64. package/dist/scripts/test-error-handling.d.ts +2 -0
  65. package/dist/scripts/test-error-handling.d.ts.map +1 -0
  66. package/dist/scripts/test-error-handling.js +146 -0
  67. package/dist/scripts/test-error-handling.js.map +1 -0
  68. package/dist/scripts/test-live.d.ts +2 -0
  69. package/dist/scripts/test-live.d.ts.map +1 -0
  70. package/dist/scripts/test-live.js +121 -0
  71. package/dist/scripts/test-live.js.map +1 -0
  72. package/dist/types.d.ts +120 -0
  73. package/dist/types.d.ts.map +1 -0
  74. package/dist/types.js +25 -0
  75. package/dist/types.js.map +1 -0
  76. package/dist/utils/coordinates.d.ts +68 -0
  77. package/dist/utils/coordinates.d.ts.map +1 -0
  78. package/dist/utils/coordinates.js +98 -0
  79. package/dist/utils/coordinates.js.map +1 -0
  80. package/dist/utils/encoding.d.ts +47 -0
  81. package/dist/utils/encoding.d.ts.map +1 -0
  82. package/dist/utils/encoding.js +153 -0
  83. package/dist/utils/encoding.js.map +1 -0
  84. package/dist/utils/index.d.ts +8 -0
  85. package/dist/utils/index.d.ts.map +1 -0
  86. package/dist/utils/index.js +8 -0
  87. package/dist/utils/index.js.map +1 -0
  88. package/dist/utils/time.d.ts +50 -0
  89. package/dist/utils/time.d.ts.map +1 -0
  90. package/dist/utils/time.js +94 -0
  91. package/dist/utils/time.js.map +1 -0
  92. package/package.json +84 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Giedrius Macevičius
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,283 @@
1
+ # lt-public-transport-sdk
2
+
3
+ A robust, type-safe TypeScript SDK for accessing **real-time public transport data** in Lithuanian cities.
4
+
5
+ It handles the complexity of parsing raw GPS streams (HTML/CSV), normalizing coordinate formats, handling text encodings (Windows-1257), and merging live data with static GTFS schedules (routes, stops).
6
+
7
+ ![License](https://img.shields.io/badge/license-MIT-blue.svg)
8
+ ![TypeScript](https://img.shields.io/badge/TypeScript-5.0-blue.svg)
9
+ ![Tests](https://img.shields.io/badge/Coverage-100%25-brightgreen.svg)
10
+
11
+ ## 🚀 Why use this SDK?
12
+
13
+ Raw public transport data in Lithuania (from stops.lt) is fragmented and messy:
14
+
15
+ - **Inconsistent Formats**: Vilnius uses 18 CSV columns, Kaunas uses 14, Panevėžys uses 9 (with no header).
16
+ - **Weird Encodings**: Data is often in `windows-1257` or mixed encodings.
17
+ - **Weird Coordinates**: Some cities provide WGS84, others provide integers divided by 1,000,000.
18
+ - **Sparse Data**: GPS streams often lack route names or destinations, requiring lookup against GTFS data.
19
+
20
+ **This SDK solves all of that.** It provides a **single, unified `Vehicle` interface** regardless of the city or underlying data format.
21
+
22
+ ## ✨ Features
23
+
24
+ - **Unified API**: One method (`getVehicles`) validates and normalizes data for all supported cities.
25
+ - **Auto-Enrichment**: optional automatic merging of live GPS data with GTFS routes (adds `destination`, `tripId`).
26
+ - **Resilience**: Robust error handling for network timeouts, stale data, and malformed responses.
27
+ - **Type-Safe**: Built with TypeScript and Zod for runtime validation.
28
+
29
+ ## 📦 Installation
30
+
31
+ ```bash
32
+ npm install lt-public-transport-sdk
33
+ ```
34
+
35
+ ## ⚡ Quick Start
36
+
37
+ ```typescript
38
+ import { LtTransport } from "lt-public-transport-sdk";
39
+
40
+ // 1. Initialize the client
41
+ const client = new LtTransport({
42
+ autoEnrich: true, // Automatically download GTFS and match routes
43
+ cacheDir: "./.cache", // Where to store GTFS/ZIP files
44
+ });
45
+
46
+ async function main() {
47
+ try {
48
+ // 2. Get real-time vehicles for Vilnius
49
+ console.log("Fetching Vilnius buses...");
50
+ const vehicles = await client.getVehicles("vilnius");
51
+
52
+ console.log(`Found ${vehicles.length} active vehicles:`);
53
+
54
+ vehicles.slice(0, 3).forEach((v) => {
55
+ console.log(`🚌 [${v.route}] ${v.vehicleNumber} -> ${v.destination}`);
56
+ console.log(` 📍 ${v.latitude}, ${v.longitude} (${v.speed} km/h)`);
57
+ });
58
+ } catch (err) {
59
+ console.error("Error fetching data:", err);
60
+ }
61
+ }
62
+
63
+ main();
64
+ ```
65
+
66
+ ## 🏙️ Supported Cities
67
+
68
+ | City | Tier | GPS Data | GTFS Data | Formats Handled |
69
+ | ---------------- | --------- | -------- | --------- | -------------------------------------- |
70
+ | **Vilnius** | 🥇 Gold | ✅ Full | ✅ Yes | 18-col CSV, GTFS lookup |
71
+ | **Kaunas** | 🥇 Gold | ✅ Full | ✅ Yes | 14-col CSV, Trip/Stop matching |
72
+ | **Klaipėda** | 🥇 Gold | ✅ Full | ✅ Yes | 12-col CSV |
73
+ | **Alytus** | 🥇 Gold | ✅ Full | ✅ Yes | 13-col CSV |
74
+ | **Druskininkai** | 🥇 Gold | ✅ Full | ✅ Yes | 13-col CSV |
75
+ | **Panevėžys** | 🥈 Silver | ✅ Lite | ✅ Yes | 9-col (no header), Integer coords |
76
+ | **Tauragė** | 🥈 Silver | ✅ Lite | ✅ Yes | 8-col (no header), Alphanumeric routes |
77
+ | **Šiauliai** | 🥉 Bronze | ❌ No | ✅ Yes | GTFS only |
78
+ | **Utena** | 🥉 Bronze | ❌ No | ✅ Yes | GTFS only |
79
+
80
+ ## 🧩 How It Works
81
+
82
+ ![Architecture Diagram](assets/architecture.png)
83
+
84
+ > **Note**: Bronze tier cities (Šiauliai, Utena) do not publish real-time GPS data. Calling `getVehicles()` will throw a `GpsNotAvailableError`, but `getRoutes()` and `getStops()` **work normally** with GTFS data.
85
+
86
+ ### `LtTransport` Class
87
+
88
+ #### Configuration
89
+
90
+ ```typescript
91
+ const client = new LtTransport({
92
+ // Directory to store downloaded GTFS zip files (default: os.tmpdir())
93
+ cacheDir: "./cache",
94
+
95
+ // Max age of GPS data to consider "live" (default: 5 minutes)
96
+ staleThresholdMs: 5 * 60 * 1000,
97
+
98
+ // Filter out vehicles that haven't updated recently (default: false)
99
+ filterStale: true,
100
+
101
+ // Fetch and parse GTFS to add destination/route info (default: true)
102
+ autoEnrich: true,
103
+
104
+ // Filter out coordinates outside Lithuania (default: true)
105
+ filterInvalidCoords: true,
106
+
107
+ // Request timeout in ms (default: 10000)
108
+ requestTimeout: 10000,
109
+ });
110
+ ```
111
+
112
+ #### Methods
113
+
114
+ #### Methods
115
+
116
+ | Method | Returns | Description |
117
+ | ------------------------- | --------------------- | -------------------------------------------------------------------------------------------------------- |
118
+ | **`getVehicles(city)`** | `Promise<Vehicle[]>` | Fetches real-time vehicle positions. If `autoEnrich` is true, ensures GTFS data is synced and merges it. |
119
+ | **`sync(city, force?)`** | `Promise<SyncResult>` | Manually downloads/updates GTFS static data (routes/stops). Throttled to 60s unless `force=true`. |
120
+ | **`getRoutes(city)`** | `Promise<Route[]>` | Returns the list of static routes from GTFS. Requires prior `sync()`. |
121
+ | **`getStops(city)`** | `Promise<Stop[]>` | Returns the list of static stops from GTFS. Requires prior `sync()`. |
122
+ | **`getCities()`** | `CityId[]` | Returns a list of all supported city identifiers. |
123
+ | **`getCityConfig(city)`** | `CityConfig` | Returns configuration details (tier, URLs) for a specific city. |
124
+
125
+ ### Key Types
126
+
127
+ #### `Vehicle`
128
+
129
+ ```typescript
130
+ interface Vehicle {
131
+ /** Unique identifier (e.g. "vilnius-1234") */
132
+ readonly id: string;
133
+
134
+ /** Vehicle number visible on the bus/trolley */
135
+ readonly vehicleNumber: string;
136
+
137
+ /** Route number (e.g. "3G", "10") */
138
+ readonly route: string;
139
+
140
+ /** Type of vehicle */
141
+ readonly type: "bus" | "trolleybus" | "ferry" | "unknown";
142
+
143
+ /** Latitude in WGS84 decimal degrees */
144
+ readonly latitude: number;
145
+
146
+ /** Longitude in WGS84 decimal degrees */
147
+ readonly longitude: number;
148
+
149
+ /** Bearing in degrees (0-360) */
150
+ readonly bearing: number;
151
+
152
+ /** Speed in km/h */
153
+ readonly speed: number;
154
+
155
+ /** Destination name (e.g. "Santariškės") */
156
+ readonly destination: string | null;
157
+
158
+ /** Delay in seconds (positive = late, negative = early) */
159
+ readonly delaySeconds: number | null;
160
+
161
+ /** Trip identifier from source system */
162
+ readonly tripId: string | null;
163
+
164
+ /** GTFS trip reference (Vilnius only) */
165
+ readonly gtfsTripId: string | null;
166
+
167
+ /** Whether data is older than staleThreshold */
168
+ readonly isStale: boolean;
169
+
170
+ /** When the position was measured */
171
+ readonly measuredAt: Date;
172
+ }
173
+ ```
174
+
175
+ #### `Route` (GTFS)
176
+
177
+ ```typescript
178
+ interface Route {
179
+ /** Unique route ID (e.g. "routes_123") */
180
+ readonly id: string;
181
+
182
+ /** Short name (e.g. "3G") */
183
+ readonly shortName: string;
184
+
185
+ /** Long name (e.g. "Oro uostas - Centras - Fabijoniškės") */
186
+ readonly longName: string;
187
+
188
+ /** Transport type */
189
+ readonly type: VehicleType;
190
+
191
+ /** Route color (hex without #) */
192
+ readonly color: string;
193
+
194
+ /** Text color (hex without #) */
195
+ readonly textColor: string;
196
+ }
197
+ ```
198
+
199
+ #### `Stop` (GTFS)
200
+
201
+ ```typescript
202
+ interface Stop {
203
+ /** Unique stop ID */
204
+ readonly id: string;
205
+
206
+ /** Check digit code (if available) */
207
+ readonly code: string | null;
208
+
209
+ /** Stop name */
210
+ readonly name: string;
211
+
212
+ /** Stop description/details */
213
+ readonly description: string | null;
214
+
215
+ /** Latitude */
216
+ readonly latitude: number;
217
+
218
+ /** Longitude */
219
+ readonly longitude: number;
220
+ }
221
+ ```
222
+
223
+ ## 💾 Caching & Best Practices
224
+
225
+ By default, GTFS data (routes & stops) is cached in your system's temporary directory (`os.tmpdir()/lt-transport-sdk-cache`).
226
+
227
+ ### Microservices / Docker
228
+
229
+ If you are running in a containerized environment (Docker, Kubernetes), it is recommended to:
230
+
231
+ 1. **Persist the cache**: Mount a volume to avoid re-downloading GTFS data (5-10MB) on every container restart.
232
+ 2. **Configure path**: Set `cacheDir` to your mounted volume.
233
+
234
+ ```typescript
235
+ const client = new LtTransport({
236
+ cacheDir: "/data/cache", // Mount a volume here
237
+ });
238
+ ```
239
+
240
+ ### Serverless (AWS Lambda, etc.)
241
+
242
+ The SDK works in serverless environments by writing to `/tmp`. Note that "cold starts" will incur a latency penalty while GTFS data is downloaded and parsed.
243
+
244
+ ## ⚠️ Error Handling
245
+
246
+ The SDK throws specific errors you can catch:
247
+
248
+ ```typescript
249
+ import {
250
+ GpsNotAvailableError, // City doesn't support GPS
251
+ InvalidCityError, // Typo in city name
252
+ SyncRequiredError, // Need to run syncGtfs() (if autoEnrich: false)
253
+ TransportNetworkError, // Network timeout/failure
254
+ } from "lt-public-transport-sdk/errors";
255
+
256
+ try {
257
+ await client.getVehicles("unknown-city");
258
+ } catch (err) {
259
+ if (err instanceof InvalidCityError) {
260
+ console.log("Invalid city ID!");
261
+ }
262
+ }
263
+ ```
264
+
265
+ ## 🛠️ Development & Testing
266
+
267
+ This project uses **Vitest** for testing and **TypeScript** for building.
268
+
269
+ ```bash
270
+ # Install dependencies
271
+ npm install
272
+
273
+ # Run unit tests (fast, using fixtures)
274
+ npm test
275
+
276
+ # Run integration tests (hits live APIs - verify functionality)
277
+ npm run build
278
+ npm run test:integration
279
+ ```
280
+
281
+ ## 📄 License
282
+
283
+ MIT
Binary file
@@ -0,0 +1,221 @@
1
+ /**
2
+ * City configuration matrix for Lithuanian Public Transport SDK
3
+ * @module config
4
+ */
5
+ /**
6
+ * City data tier classification based on data quality and availability.
7
+ * - gold: Full GPS streams with rich metadata (destination, delay, equipment)
8
+ * - silver: Lite GPS streams requiring GTFS enrichment
9
+ * - bronze: GTFS data only, no real-time GPS
10
+ */
11
+ export type CityTier = 'gold' | 'silver' | 'bronze';
12
+ /**
13
+ * GPS data stream configuration for a city.
14
+ */
15
+ export interface GpsConfig {
16
+ /** Whether GPS data is available for this city */
17
+ readonly enabled: boolean;
18
+ /**
19
+ * Format of GPS data stream.
20
+ * - 'full': Header-based CSV with rich metadata (gold tier)
21
+ * - 'lite': Headerless CSV with minimal data (silver tier)
22
+ * - null: No GPS data available (bronze tier)
23
+ */
24
+ readonly format: 'full' | 'lite' | null;
25
+ /** URL to fetch GPS data, or null if not available */
26
+ readonly url: string | null;
27
+ }
28
+ /**
29
+ * GTFS static data configuration for a city.
30
+ */
31
+ export interface GtfsConfig {
32
+ /** Whether GTFS data is available for this city */
33
+ readonly enabled: boolean;
34
+ /**
35
+ * URL to download GTFS ZIP archive.
36
+ * Pattern: https://www.stops.lt/${city}/${city}/gtfs.zip
37
+ */
38
+ readonly url: string;
39
+ }
40
+ /**
41
+ * Complete configuration for a city's transport data.
42
+ * Note: 'id' field is typed as string here but CityId union is derived from CITY_CONFIGS keys.
43
+ */
44
+ export interface CityConfig {
45
+ /** City identifier */
46
+ readonly id: string;
47
+ /** Data quality tier */
48
+ readonly tier: CityTier;
49
+ /** GPS stream configuration */
50
+ readonly gps: GpsConfig;
51
+ /** GTFS static data configuration */
52
+ readonly gtfs: GtfsConfig;
53
+ }
54
+ /**
55
+ * City configuration matrix with all supported cities.
56
+ *
57
+ * Data Quality Tiers:
58
+ * - Gold: Full GPS streams with 12-18 columns including destination, delay, equipment
59
+ * - Silver: Lite GPS streams with 8-9 columns, requires GTFS enrichment for destinations
60
+ * - Bronze: GTFS only, no real-time GPS data available
61
+ *
62
+ * Column Counts (empirically verified 2026-01-05):
63
+ * - Vilnius: 18 columns (MatavimoLaikas, KryptiesTipas, ReisoIdGTFS)
64
+ * - Kaunas: 14 columns (Grafikas, SekanciosStotelesNum, AtvykimoLaikasSekundemis - NO MatavimoLaikas)
65
+ * - Klaipėda: 12 columns (minimal format)
66
+ * - Alytus: 13 columns
67
+ * - Druskininkai: 13 columns
68
+ * - Panevėžys: 9 columns lite (no header)
69
+ * - Tauragė: 8 columns lite (no header, alphanumeric routes like S11)
70
+ */
71
+ declare const CITY_CONFIGS_INTERNAL: {
72
+ readonly vilnius: {
73
+ readonly id: "vilnius";
74
+ readonly tier: "gold";
75
+ readonly gps: {
76
+ readonly enabled: true;
77
+ readonly format: "full";
78
+ readonly url: string;
79
+ };
80
+ readonly gtfs: {
81
+ readonly enabled: true;
82
+ readonly url: string;
83
+ };
84
+ };
85
+ readonly kaunas: {
86
+ readonly id: "kaunas";
87
+ readonly tier: "gold";
88
+ readonly gps: {
89
+ readonly enabled: true;
90
+ readonly format: "full";
91
+ readonly url: string;
92
+ };
93
+ readonly gtfs: {
94
+ readonly enabled: true;
95
+ readonly url: string;
96
+ };
97
+ };
98
+ readonly klaipeda: {
99
+ readonly id: "klaipeda";
100
+ readonly tier: "gold";
101
+ readonly gps: {
102
+ readonly enabled: true;
103
+ readonly format: "full";
104
+ readonly url: string;
105
+ };
106
+ readonly gtfs: {
107
+ readonly enabled: true;
108
+ readonly url: string;
109
+ };
110
+ };
111
+ readonly alytus: {
112
+ readonly id: "alytus";
113
+ readonly tier: "gold";
114
+ readonly gps: {
115
+ readonly enabled: true;
116
+ readonly format: "full";
117
+ readonly url: string;
118
+ };
119
+ readonly gtfs: {
120
+ readonly enabled: true;
121
+ readonly url: string;
122
+ };
123
+ };
124
+ readonly druskininkai: {
125
+ readonly id: "druskininkai";
126
+ readonly tier: "gold";
127
+ readonly gps: {
128
+ readonly enabled: true;
129
+ readonly format: "full";
130
+ readonly url: string;
131
+ };
132
+ readonly gtfs: {
133
+ readonly enabled: true;
134
+ readonly url: string;
135
+ };
136
+ };
137
+ readonly panevezys: {
138
+ readonly id: "panevezys";
139
+ readonly tier: "silver";
140
+ readonly gps: {
141
+ readonly enabled: true;
142
+ readonly format: "lite";
143
+ readonly url: string;
144
+ };
145
+ readonly gtfs: {
146
+ readonly enabled: true;
147
+ readonly url: string;
148
+ };
149
+ };
150
+ readonly taurage: {
151
+ readonly id: "taurage";
152
+ readonly tier: "silver";
153
+ readonly gps: {
154
+ readonly enabled: true;
155
+ readonly format: "lite";
156
+ readonly url: string;
157
+ };
158
+ readonly gtfs: {
159
+ readonly enabled: true;
160
+ readonly url: string;
161
+ };
162
+ };
163
+ readonly siauliai: {
164
+ readonly id: "siauliai";
165
+ readonly tier: "bronze";
166
+ readonly gps: {
167
+ readonly enabled: false;
168
+ readonly format: null;
169
+ readonly url: null;
170
+ };
171
+ readonly gtfs: {
172
+ readonly enabled: true;
173
+ readonly url: string;
174
+ };
175
+ };
176
+ readonly utena: {
177
+ readonly id: "utena";
178
+ readonly tier: "bronze";
179
+ readonly gps: {
180
+ readonly enabled: false;
181
+ readonly format: null;
182
+ readonly url: null;
183
+ };
184
+ readonly gtfs: {
185
+ readonly enabled: true;
186
+ readonly url: string;
187
+ };
188
+ };
189
+ };
190
+ /**
191
+ * Supported city identifiers derived from configuration keys.
192
+ * Each city has specific GPS and GTFS data availability.
193
+ */
194
+ export type CityId = keyof typeof CITY_CONFIGS_INTERNAL;
195
+ /**
196
+ * City configuration matrix with all supported cities.
197
+ */
198
+ export declare const CITY_CONFIGS: Readonly<Record<CityId, CityConfig>>;
199
+ /**
200
+ * List of all supported city IDs.
201
+ */
202
+ export declare const ALL_CITY_IDS: readonly CityId[];
203
+ /**
204
+ * Get configuration for a specific city.
205
+ * @throws Error if city ID is invalid
206
+ */
207
+ export declare function getCityConfig(city: CityId): CityConfig;
208
+ /**
209
+ * Get all cities of a specific tier.
210
+ */
211
+ export declare function getCitiesByTier(tier: CityTier): CityId[];
212
+ /**
213
+ * Check if a city has GPS data available.
214
+ */
215
+ export declare function hasGpsData(city: CityId): boolean;
216
+ /**
217
+ * Check if a city has GTFS data available.
218
+ */
219
+ export declare function hasGtfsData(city: CityId): boolean;
220
+ export {};
221
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH;;;;;GAKG;AACH,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAMpD;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,kDAAkD;IAClD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAExC,sDAAsD;IACtD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,mDAAmD;IACnD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,sBAAsB;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,wBAAwB;IACxB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAExB,+BAA+B;IAC/B,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;IAExB,qCAAqC;IACrC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;CAC3B;AAiCD;;;;;;;;;;;;;;;;GAgBG;AACH,QAAA,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8HjB,CAAC;AAEX;;;GAGG;AACH,MAAM,MAAM,MAAM,GAAG,MAAM,OAAO,qBAAqB,CAAC;AAExD;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAyB,CAAC;AAExF;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,MAAM,EAA0C,CAAC;AAErF;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAEtD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,EAAE,CAExD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD"}