lt-public-transport-sdk 1.0.0 → 1.1.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 (47) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +340 -283
  3. package/dist/config.d.ts +41 -0
  4. package/dist/config.d.ts.map +1 -1
  5. package/dist/config.js +34 -0
  6. package/dist/config.js.map +1 -1
  7. package/dist/errors.d.ts +12 -13
  8. package/dist/errors.d.ts.map +1 -1
  9. package/dist/errors.js +1 -1
  10. package/dist/errors.js.map +1 -1
  11. package/dist/index.d.ts +80 -18
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +124 -37
  14. package/dist/index.js.map +1 -1
  15. package/dist/parsers/gps-lite.d.ts +34 -36
  16. package/dist/parsers/gps-lite.d.ts.map +1 -1
  17. package/dist/parsers/gps-lite.js +77 -69
  18. package/dist/parsers/gps-lite.js.map +1 -1
  19. package/dist/parsers/index.d.ts +2 -1
  20. package/dist/parsers/index.d.ts.map +1 -1
  21. package/dist/parsers/index.js +4 -1
  22. package/dist/parsers/index.js.map +1 -1
  23. package/dist/schemas.d.ts +158 -1
  24. package/dist/schemas.d.ts.map +1 -1
  25. package/dist/schemas.js +87 -1
  26. package/dist/schemas.js.map +1 -1
  27. package/package.json +1 -1
  28. package/dist/scripts/test-city-specific.d.ts +0 -2
  29. package/dist/scripts/test-city-specific.d.ts.map +0 -1
  30. package/dist/scripts/test-city-specific.js +0 -264
  31. package/dist/scripts/test-city-specific.js.map +0 -1
  32. package/dist/scripts/test-config-options.d.ts +0 -2
  33. package/dist/scripts/test-config-options.d.ts.map +0 -1
  34. package/dist/scripts/test-config-options.js +0 -166
  35. package/dist/scripts/test-config-options.js.map +0 -1
  36. package/dist/scripts/test-data-quality.d.ts +0 -2
  37. package/dist/scripts/test-data-quality.d.ts.map +0 -1
  38. package/dist/scripts/test-data-quality.js +0 -204
  39. package/dist/scripts/test-data-quality.js.map +0 -1
  40. package/dist/scripts/test-error-handling.d.ts +0 -2
  41. package/dist/scripts/test-error-handling.d.ts.map +0 -1
  42. package/dist/scripts/test-error-handling.js +0 -146
  43. package/dist/scripts/test-error-handling.js.map +0 -1
  44. package/dist/scripts/test-live.d.ts +0 -2
  45. package/dist/scripts/test-live.d.ts.map +0 -1
  46. package/dist/scripts/test-live.js +0 -121
  47. package/dist/scripts/test-live.js.map +0 -1
package/dist/index.js CHANGED
@@ -24,10 +24,10 @@
24
24
  */
25
25
  import { tmpdir } from 'node:os';
26
26
  import { join } from 'node:path';
27
- import { CITY_CONFIGS, getCityConfig, ALL_CITY_IDS } from './config.js';
27
+ import { CITY_CONFIGS, ALL_CITY_IDS } from './config.js';
28
28
  import { TransportNetworkError, GpsNotAvailableError, SyncRequiredError, InvalidCityError, } from './errors.js';
29
29
  import { parseGpsFullStream } from './parsers/gps-full.js';
30
- import { parseGpsLiteStream, isLiteCity } from './parsers/gps-lite.js';
30
+ import { parseGpsLiteStream, getLiteFormatDescriptor } from './parsers/gps-lite.js';
31
31
  import { syncGtfs, loadGtfsCache, loadCachedRoutes, loadCachedStops } from './gtfs/sync.js';
32
32
  import { enrichVehicles, buildRouteCache } from './enrichment/route-matcher.js';
33
33
  import { clientConfigSchema } from './schemas.js';
@@ -72,6 +72,13 @@ export class LtTransport {
72
72
  autoEnrich;
73
73
  filterInvalidCoords;
74
74
  filterStale;
75
+ /**
76
+ * Effective city configurations (built-in + custom + overrides merged).
77
+ * This is the source of truth for city configs in this instance.
78
+ */
79
+ effectiveCityConfigs;
80
+ /** Sorted list of all effective city IDs */
81
+ effectiveCityIds;
75
82
  /** In-memory route cache for fast enrichment */
76
83
  routeCaches = new Map();
77
84
  /** Last sync timestamps for throttling */
@@ -80,9 +87,11 @@ export class LtTransport {
80
87
  * Create a new LtTransport client.
81
88
  *
82
89
  * @param config - Client configuration options
90
+ * @throws {ZodError} If config validation fails (includes helpful error messages)
83
91
  */
84
92
  constructor(config = {}) {
85
- // Validate config with Zod schema for runtime safety
93
+ // Validate entire config with Zod schema for runtime safety
94
+ // This validates customCities and cityOverrides structure and values
86
95
  const validated = clientConfigSchema.parse({
87
96
  cacheDir: config.cacheDir,
88
97
  requestTimeout: config.requestTimeout ?? DEFAULT_TIMEOUT,
@@ -91,6 +100,8 @@ export class LtTransport {
91
100
  autoEnrich: config.autoEnrich ?? true,
92
101
  filterInvalidCoords: config.filterInvalidCoords ?? true,
93
102
  filterStale: config.filterStale ?? false,
103
+ customCities: config.customCities,
104
+ cityOverrides: config.cityOverrides,
94
105
  });
95
106
  this.cacheDir = validated.cacheDir ?? getDefaultCacheDir();
96
107
  this.requestTimeout = validated.requestTimeout;
@@ -99,6 +110,58 @@ export class LtTransport {
99
110
  this.autoEnrich = validated.autoEnrich;
100
111
  this.filterInvalidCoords = validated.filterInvalidCoords;
101
112
  this.filterStale = validated.filterStale;
113
+ // Build effective city configurations by merging:
114
+ // 1. Built-in CITY_CONFIGS
115
+ // 2. Custom cities from config.customCities
116
+ // 3. Overrides from config.cityOverrides
117
+ this.effectiveCityConfigs = this.buildEffectiveCityConfigs(validated.customCities, validated.cityOverrides);
118
+ // Build sorted list of city IDs
119
+ this.effectiveCityIds = Array.from(this.effectiveCityConfigs.keys()).sort();
120
+ }
121
+ /**
122
+ * Build effective city configurations by merging built-in, custom, and overrides.
123
+ */
124
+ buildEffectiveCityConfigs(customCities, cityOverrides) {
125
+ const configs = new Map();
126
+ // Step 1: Add all built-in cities
127
+ for (const cityId of ALL_CITY_IDS) {
128
+ configs.set(cityId, CITY_CONFIGS[cityId]);
129
+ }
130
+ // Step 2: Apply overrides to built-in cities
131
+ if (cityOverrides) {
132
+ for (const [cityId, override] of Object.entries(cityOverrides)) {
133
+ const existing = configs.get(cityId);
134
+ if (existing !== undefined) {
135
+ configs.set(cityId, this.mergeCityConfig(existing, override));
136
+ }
137
+ }
138
+ }
139
+ // Step 3: Add custom cities (can override built-in if same ID)
140
+ if (customCities) {
141
+ for (const [cityId, cityConfig] of Object.entries(customCities)) {
142
+ configs.set(cityId, cityConfig);
143
+ }
144
+ }
145
+ return configs;
146
+ }
147
+ /**
148
+ * Deep merge a city config with partial overrides.
149
+ */
150
+ mergeCityConfig(base, override) {
151
+ return {
152
+ id: override.id ?? base.id,
153
+ tier: override.tier ?? base.tier,
154
+ gps: override.gps ? { ...base.gps, ...override.gps } : base.gps,
155
+ gtfs: override.gtfs ? { ...base.gtfs, ...override.gtfs } : base.gtfs,
156
+ liteFormat: override.liteFormat ?? base.liteFormat,
157
+ };
158
+ }
159
+ /**
160
+ * Get effective city config for a city ID.
161
+ * Checks the merged config map which includes built-in, custom, and overridden configs.
162
+ */
163
+ getEffectiveCityConfig(cityId) {
164
+ return this.effectiveCityConfigs.get(cityId);
102
165
  }
103
166
  // ===========================================================================
104
167
  // Public API
@@ -106,13 +169,14 @@ export class LtTransport {
106
169
  /**
107
170
  * Get real-time vehicle positions for a city.
108
171
  *
109
- * For silver-tier cities (Panevėžys, Tauragė), vehicles will be enriched
110
- * with GTFS data if `sync()` has been called and `autoEnrich` is enabled.
172
+ * For silver-tier cities, vehicles will be enriched with GTFS data
173
+ * if `sync()` has been called and `autoEnrich` is enabled.
111
174
  *
112
- * @param city - City identifier
175
+ * @param city - City identifier (built-in or custom)
113
176
  * @returns Array of vehicle positions
114
- * @throws {GpsNotAvailableError} If city is bronze tier (no GPS data)
177
+ * @throws {GpsNotAvailableError} If city has no GPS data (bronze tier)
115
178
  * @throws {TransportNetworkError} If network request fails
179
+ * @throws {InvalidCityError} If city is not recognized
116
180
  *
117
181
  * @example
118
182
  * ```typescript
@@ -121,8 +185,10 @@ export class LtTransport {
121
185
  * ```
122
186
  */
123
187
  async getVehicles(city) {
124
- this.validateCity(city);
125
- const config = getCityConfig(city);
188
+ const config = this.getEffectiveCityConfig(city);
189
+ if (!config) {
190
+ throw new InvalidCityError(city);
191
+ }
126
192
  if (!config.gps.enabled || config.gps.url === null) {
127
193
  throw new GpsNotAvailableError(city);
128
194
  }
@@ -131,26 +197,36 @@ export class LtTransport {
131
197
  // Parse based on format
132
198
  let vehicles;
133
199
  if (config.gps.format === 'full') {
200
+ // Gold tier: header-based CSV with rich metadata
134
201
  vehicles = parseGpsFullStream(text, city, {
135
202
  staleThresholdMs: this.staleThresholdMs,
136
203
  filterStale: this.filterStale,
137
204
  filterInvalidCoords: this.filterInvalidCoords,
138
205
  });
139
206
  }
140
- else if (isLiteCity(city)) {
141
- vehicles = parseGpsLiteStream(text, city, {
142
- filterInvalidCoords: this.filterInvalidCoords,
143
- });
144
- // Enrich silver-tier cities with GTFS data
145
- if (this.autoEnrich) {
146
- const routeCache = await this.getRouteCache(city);
147
- if (routeCache) {
148
- vehicles = enrichVehicles(vehicles, routeCache);
207
+ else if (config.gps.format === 'lite') {
208
+ // Silver tier: headerless CSV using format descriptor
209
+ const liteFormat = getLiteFormatDescriptor(city, config);
210
+ if (!liteFormat) {
211
+ // No format descriptor available - can't parse
212
+ console.warn(`No lite format descriptor for city: ${city}. Add liteFormat to city config.`);
213
+ vehicles = [];
214
+ }
215
+ else {
216
+ vehicles = parseGpsLiteStream(text, city, liteFormat, {
217
+ filterInvalidCoords: this.filterInvalidCoords,
218
+ });
219
+ // Enrich silver-tier cities with GTFS data
220
+ if (this.autoEnrich) {
221
+ const routeCache = await this.getRouteCache(city);
222
+ if (routeCache) {
223
+ vehicles = enrichVehicles(vehicles, routeCache);
224
+ }
149
225
  }
150
226
  }
151
227
  }
152
228
  else {
153
- // Unknown format
229
+ // Unknown format (bronze tier or misconfigured)
154
230
  vehicles = [];
155
231
  }
156
232
  return vehicles;
@@ -163,10 +239,11 @@ export class LtTransport {
163
239
  *
164
240
  * Throttled to minimum 60 seconds between calls for same city.
165
241
  *
166
- * @param city - City to sync
242
+ * @param city - City to sync (built-in or custom)
167
243
  * @param force - Force re-download even if cache is current
168
244
  * @returns Sync result with counts and status
169
245
  * @throws {GtfsSyncError} If sync fails
246
+ * @throws {InvalidCityError} If city is not recognized
170
247
  *
171
248
  * @example
172
249
  * ```typescript
@@ -175,7 +252,10 @@ export class LtTransport {
175
252
  * ```
176
253
  */
177
254
  async sync(city, force = false) {
178
- this.validateCity(city);
255
+ const config = this.getEffectiveCityConfig(city);
256
+ if (!config) {
257
+ throw new InvalidCityError(city);
258
+ }
179
259
  // Throttle sync calls (60s minimum between calls)
180
260
  const lastSync = this.lastSyncTimes.get(city);
181
261
  const now = Date.now();
@@ -184,7 +264,7 @@ export class LtTransport {
184
264
  const cache = await loadGtfsCache(city, this.cacheDir);
185
265
  if (cache) {
186
266
  return {
187
- city,
267
+ city: city,
188
268
  status: 'up-to-date',
189
269
  routeCount: cache.meta.routeCount,
190
270
  stopCount: cache.meta.stopCount,
@@ -212,6 +292,7 @@ export class LtTransport {
212
292
  * @param city - City to get stops for
213
293
  * @returns Array of stops
214
294
  * @throws {SyncRequiredError} If GTFS data not synced
295
+ * @throws {InvalidCityError} If city is not recognized
215
296
  *
216
297
  * @example
217
298
  * ```typescript
@@ -221,7 +302,10 @@ export class LtTransport {
221
302
  * ```
222
303
  */
223
304
  async getStops(city) {
224
- this.validateCity(city);
305
+ const config = this.getEffectiveCityConfig(city);
306
+ if (!config) {
307
+ throw new InvalidCityError(city);
308
+ }
225
309
  const stops = await loadCachedStops(this.cacheDir, city);
226
310
  if (!stops) {
227
311
  throw new SyncRequiredError(city);
@@ -236,6 +320,7 @@ export class LtTransport {
236
320
  * @param city - City to get routes for
237
321
  * @returns Array of routes
238
322
  * @throws {SyncRequiredError} If GTFS data not synced
323
+ * @throws {InvalidCityError} If city is not recognized
239
324
  *
240
325
  * @example
241
326
  * ```typescript
@@ -245,7 +330,10 @@ export class LtTransport {
245
330
  * ```
246
331
  */
247
332
  async getRoutes(city) {
248
- this.validateCity(city);
333
+ const config = this.getEffectiveCityConfig(city);
334
+ if (!config) {
335
+ throw new InvalidCityError(city);
336
+ }
249
337
  const routeCache = await this.getRouteCache(city);
250
338
  if (!routeCache) {
251
339
  throw new SyncRequiredError(city);
@@ -262,29 +350,28 @@ export class LtTransport {
262
350
  return routes;
263
351
  }
264
352
  /**
265
- * Get list of all supported city IDs.
353
+ * Get list of all available city IDs.
354
+ * Includes built-in cities and any custom cities added via config.
266
355
  */
267
356
  getCities() {
268
- return ALL_CITY_IDS;
357
+ return this.effectiveCityIds;
269
358
  }
270
359
  /**
271
360
  * Get configuration for a specific city.
361
+ * Returns effective config (with any overrides applied).
362
+ *
363
+ * @throws {InvalidCityError} If city is not found
272
364
  */
273
365
  getCityConfig(city) {
274
- this.validateCity(city);
275
- return getCityConfig(city);
366
+ const config = this.getEffectiveCityConfig(city);
367
+ if (!config) {
368
+ throw new InvalidCityError(city);
369
+ }
370
+ return config;
276
371
  }
277
372
  // ===========================================================================
278
373
  // Private Helpers
279
374
  // ===========================================================================
280
- /**
281
- * Validate that city ID is valid.
282
- */
283
- validateCity(city) {
284
- if (!(city in CITY_CONFIGS)) {
285
- throw new InvalidCityError(city);
286
- }
287
- }
288
375
  /**
289
376
  * Fetch text content from URL.
290
377
  */
@@ -334,7 +421,7 @@ export class LtTransport {
334
421
  }
335
422
  export { GTFS_ROUTE_TYPE_MAP, LT_TRANSPORT_TYPE_MAP } from './types.js';
336
423
  // Config
337
- export { CITY_CONFIGS, ALL_CITY_IDS, getCityConfig, getCitiesByTier, hasGpsData, hasGtfsData } from './config.js';
424
+ export { CITY_CONFIGS, ALL_CITY_IDS, getCityConfig, getCitiesByTier, hasGpsData, hasGtfsData, LITE_FORMAT_DESCRIPTORS } from './config.js';
338
425
  // Errors
339
426
  export { TransportError, TransportNetworkError, GpsNotAvailableError, SyncRequiredError, GtfsSyncError, ParseError, InvalidCityError, isTransportError, isNetworkError, } from './errors.js';
340
427
  // Utilities
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -2,37 +2,16 @@
2
2
  * GPS Lite Format Parser for silver-tier cities
3
3
  * @module parsers/gps-lite
4
4
  *
5
- * Handles the "lite" GPS format used by silver-tier cities (Panevėžys, Tauragė).
6
- * These streams have no header row and fewer columns.
5
+ * Handles the "lite" GPS format used by silver-tier cities.
6
+ * These streams have no header row and use a data-driven format descriptor
7
+ * to parse columns at specified indices.
7
8
  *
8
- * Column counts by city (empirically verified):
9
- * - Panevėžys: 9 columns (no header, route often empty)
10
- * - Tauragė: 8 columns (no header, alphanumeric routes like S11, S19)
11
- */
12
- import type { CityId, Vehicle } from '../types.js';
13
- /**
14
- * Panevėžys format (9 columns, no header):
15
- * [0] type - Always "2" (bus?)
16
- * [1] route - Route name (often empty)
17
- * [2] longitude - Integer format (÷1,000,000)
18
- * [3] latitude - Integer format (÷1,000,000)
19
- * [4] speed - Speed or delay?
20
- * [5] azimuth - Bearing in degrees
21
- * [6] (empty) - Unknown
22
- * [7] vehicleId - Vehicle identifier
23
- * [8] (empty) - Unknown
24
- */
25
- /**
26
- * Tauragė format (8 columns, no header):
27
- * [0] type - Always "2" (bus?)
28
- * [1] route - Route name (S11, S19) - ALPHANUMERIC!
29
- * [2] longitude - Integer format (÷1,000,000)
30
- * [3] latitude - Integer format (÷1,000,000)
31
- * [4] speed - Speed in km/h
32
- * [5] azimuth - Bearing in degrees
33
- * [6] vehicleId - Vehicle identifier
34
- * [7] (empty) - Unknown
9
+ * This design allows users to:
10
+ * - Add new cities without SDK updates
11
+ * - Override formats when cities change their data structure
35
12
  */
13
+ import type { Vehicle } from '../types.js';
14
+ import type { LiteFormatDescriptor, CityConfig } from '../config.js';
36
15
  /**
37
16
  * Options for GPS lite format parsing.
38
17
  */
@@ -41,20 +20,39 @@ export interface GpsLiteParseOptions {
41
20
  filterInvalidCoords?: boolean;
42
21
  }
43
22
  /**
44
- * Cities that use lite GPS format.
23
+ * Get the lite format descriptor for a city.
24
+ * Checks city config first, then falls back to built-in descriptors.
25
+ *
26
+ * @param cityId - The city identifier
27
+ * @param cityConfig - Optional city config with custom liteFormat
28
+ * @returns The format descriptor, or undefined if not found
45
29
  */
46
- export type LiteCityId = 'panevezys' | 'taurage';
30
+ export declare function getLiteFormatDescriptor(cityId: string, cityConfig?: CityConfig): LiteFormatDescriptor | undefined;
47
31
  /**
48
- * Check if a city uses lite GPS format.
32
+ * Check if a city uses lite GPS format based on its config.
33
+ *
34
+ * @param cityConfig - The city configuration
35
+ * @returns True if the city uses lite format
49
36
  */
50
- export declare function isLiteCity(city: CityId): city is LiteCityId;
37
+ export declare function isLiteFormat(cityConfig: CityConfig): boolean;
51
38
  /**
52
- * Parse GPS lite format stream from a silver-tier city.
39
+ * Parse GPS lite format stream using a format descriptor.
53
40
  *
54
41
  * @param text - Raw text content from gps.txt
55
- * @param city - City identifier (must be 'panevezys' or 'taurage')
42
+ * @param cityId - City identifier for vehicle ID prefixing
43
+ * @param format - Format descriptor defining column indices
56
44
  * @param options - Parse options
57
45
  * @returns Array of normalized Vehicle objects
58
46
  */
59
- export declare function parseGpsLiteStream(text: string, city: LiteCityId, options?: GpsLiteParseOptions): Vehicle[];
47
+ export declare function parseGpsLiteStream(text: string, cityId: string, format: LiteFormatDescriptor, options?: GpsLiteParseOptions): Vehicle[];
48
+ /**
49
+ * @deprecated Use isLiteFormat(cityConfig) instead.
50
+ * Legacy type for cities that use lite GPS format.
51
+ */
52
+ export type LiteCityId = 'panevezys' | 'taurage';
53
+ /**
54
+ * @deprecated Use isLiteFormat(cityConfig) instead.
55
+ * Check if a city uses lite GPS format.
56
+ */
57
+ export declare function isLiteCity(cityId: string): cityId is LiteCityId;
60
58
  //# sourceMappingURL=gps-lite.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"gps-lite.d.ts","sourceRoot":"","sources":["../../src/parsers/gps-lite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAe,MAAM,aAAa,CAAC;AAahE;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;GAUG;AAMH;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,6EAA6E;IAC7E,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAMD;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,SAAS,CAAC;AAEjD;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,UAAU,CAE3D;AAMD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,mBAAwB,GAChC,OAAO,EAAE,CAgCX"}
1
+ {"version":3,"file":"gps-lite.d.ts","sourceRoot":"","sources":["../../src/parsers/gps-lite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAe,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAarE;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,6EAA6E;IAC7E,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAMD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,UAAU,GACtB,oBAAoB,GAAG,SAAS,CAQlC;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAE5D;AAMD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,oBAAoB,EAC5B,OAAO,GAAE,mBAAwB,GAChC,OAAO,EAAE,CA8BX;AAkFD;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,SAAS,CAAC;AAEjD;;;GAGG;AAEH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,UAAU,CAE/D"}
@@ -2,33 +2,57 @@
2
2
  * GPS Lite Format Parser for silver-tier cities
3
3
  * @module parsers/gps-lite
4
4
  *
5
- * Handles the "lite" GPS format used by silver-tier cities (Panevėžys, Tauragė).
6
- * These streams have no header row and fewer columns.
5
+ * Handles the "lite" GPS format used by silver-tier cities.
6
+ * These streams have no header row and use a data-driven format descriptor
7
+ * to parse columns at specified indices.
7
8
  *
8
- * Column counts by city (empirically verified):
9
- * - Panevėžys: 9 columns (no header, route often empty)
10
- * - Tauragė: 8 columns (no header, alphanumeric routes like S11, S19)
9
+ * This design allows users to:
10
+ * - Add new cities without SDK updates
11
+ * - Override formats when cities change their data structure
11
12
  */
13
+ import { LITE_FORMAT_DESCRIPTORS } from '../config.js';
12
14
  import { normalizeCoordinate, isValidLithuaniaCoord, normalizeBearing, normalizeSpeed, } from '../utils/index.js';
13
- import { gpsLitePanevezysSchema, gpsLiteTaurageSchema } from '../schemas.js';
15
+ // =============================================================================
16
+ // Format Detection
17
+ // =============================================================================
14
18
  /**
15
- * Check if a city uses lite GPS format.
19
+ * Get the lite format descriptor for a city.
20
+ * Checks city config first, then falls back to built-in descriptors.
21
+ *
22
+ * @param cityId - The city identifier
23
+ * @param cityConfig - Optional city config with custom liteFormat
24
+ * @returns The format descriptor, or undefined if not found
25
+ */
26
+ export function getLiteFormatDescriptor(cityId, cityConfig) {
27
+ // Priority 1: Explicit liteFormat in city config
28
+ if (cityConfig?.liteFormat) {
29
+ return cityConfig.liteFormat;
30
+ }
31
+ // Priority 2: Built-in descriptor by city ID
32
+ return LITE_FORMAT_DESCRIPTORS[cityId];
33
+ }
34
+ /**
35
+ * Check if a city uses lite GPS format based on its config.
36
+ *
37
+ * @param cityConfig - The city configuration
38
+ * @returns True if the city uses lite format
16
39
  */
17
- export function isLiteCity(city) {
18
- return city === 'panevezys' || city === 'taurage';
40
+ export function isLiteFormat(cityConfig) {
41
+ return cityConfig.gps.format === 'lite';
19
42
  }
20
43
  // =============================================================================
21
44
  // Main Parser
22
45
  // =============================================================================
23
46
  /**
24
- * Parse GPS lite format stream from a silver-tier city.
47
+ * Parse GPS lite format stream using a format descriptor.
25
48
  *
26
49
  * @param text - Raw text content from gps.txt
27
- * @param city - City identifier (must be 'panevezys' or 'taurage')
50
+ * @param cityId - City identifier for vehicle ID prefixing
51
+ * @param format - Format descriptor defining column indices
28
52
  * @param options - Parse options
29
53
  * @returns Array of normalized Vehicle objects
30
54
  */
31
- export function parseGpsLiteStream(text, city, options = {}) {
55
+ export function parseGpsLiteStream(text, cityId, format, options = {}) {
32
56
  const { filterInvalidCoords = true } = options;
33
57
  const lines = text.split('\n').filter(line => line.trim());
34
58
  if (lines.length === 0) {
@@ -38,9 +62,7 @@ export function parseGpsLiteStream(text, city, options = {}) {
38
62
  for (const line of lines) {
39
63
  const cols = line.split(',');
40
64
  try {
41
- const vehicle = city === 'panevezys'
42
- ? parsePanevezysLine(cols, city)
43
- : parseTaurageLine(cols, city);
65
+ const vehicle = parseLiteLine(cols, cityId, format);
44
66
  if (vehicle) {
45
67
  if (filterInvalidCoords && !isValidLithuaniaCoord(vehicle.latitude, vehicle.longitude)) {
46
68
  continue;
@@ -56,34 +78,52 @@ export function parseGpsLiteStream(text, city, options = {}) {
56
78
  return vehicles;
57
79
  }
58
80
  // =============================================================================
59
- // City-Specific Parsers
81
+ // Generic Line Parser
60
82
  // =============================================================================
61
83
  /**
62
- * Parse a line from Panevėžys GPS lite format (9 columns).
84
+ * Parse a single line using the format descriptor.
85
+ * This is the core data-driven parser that uses column indices
86
+ * from the descriptor instead of hardcoded positions.
87
+ *
88
+ * @param cols - Array of column values from the CSV line
89
+ * @param cityId - City identifier for vehicle ID prefixing
90
+ * @param format - Format descriptor with column indices
91
+ * @returns Parsed Vehicle or null if line is invalid
63
92
  */
64
- function parsePanevezysLine(cols, city) {
65
- // Validate with Zod schema
66
- const parseResult = gpsLitePanevezysSchema.safeParse(cols);
67
- if (!parseResult.success) {
93
+ function parseLiteLine(cols, cityId, format) {
94
+ // Check minimum column count
95
+ if (cols.length < format.minColumns) {
96
+ return null;
97
+ }
98
+ // Extract vehicle ID
99
+ const vehicleNumber = cols[format.vehicleIdIndex]?.trim();
100
+ if (vehicleNumber === undefined || vehicleNumber === '') {
68
101
  return null;
69
102
  }
70
- const row = parseResult.data;
71
- const vehicleNumber = row[7];
72
- // Validate essential fields
73
- if (vehicleNumber === '' || !Number.isFinite(row[2]) || !Number.isFinite(row[3])) {
103
+ // Extract and validate coordinates
104
+ const latRaw = Number(cols[format.coordIndices[0]]);
105
+ const lonRaw = Number(cols[format.coordIndices[1]]);
106
+ if (!Number.isFinite(latRaw) || !Number.isFinite(lonRaw)) {
74
107
  return null;
75
108
  }
76
- const longitude = normalizeCoordinate(row[2]);
77
- const latitude = normalizeCoordinate(row[3]);
78
- const speed = normalizeSpeed(row[4]);
79
- const bearing = normalizeBearing(row[5]);
80
- const route = row[1];
81
- const id = `${city}-${vehicleNumber}`;
109
+ // Extract route (may be empty)
110
+ const route = cols[format.routeIndex]?.trim() ?? '';
111
+ // Extract speed and bearing
112
+ const speedRaw = Number(cols[format.speedIndex]);
113
+ const bearingRaw = Number(cols[format.bearingIndex]);
114
+ // Normalize values
115
+ const latitude = normalizeCoordinate(latRaw);
116
+ const longitude = normalizeCoordinate(lonRaw);
117
+ const speed = normalizeSpeed(Number.isFinite(speedRaw) ? speedRaw : 0);
118
+ const bearing = normalizeBearing(Number.isFinite(bearingRaw) ? bearingRaw : 0);
119
+ // Determine vehicle type (lite format typically doesn't specify, default to bus)
120
+ const type = 'bus';
121
+ const id = `${cityId}-${vehicleNumber}`;
82
122
  return {
83
123
  id,
84
124
  vehicleNumber,
85
125
  route,
86
- type: 'bus', // Lite format doesn't specify type
126
+ type,
87
127
  latitude,
88
128
  longitude,
89
129
  bearing,
@@ -99,43 +139,11 @@ function parsePanevezysLine(cols, city) {
99
139
  };
100
140
  }
101
141
  /**
102
- * Parse a line from Tauragė GPS lite format (8 columns).
142
+ * @deprecated Use isLiteFormat(cityConfig) instead.
143
+ * Check if a city uses lite GPS format.
103
144
  */
104
- function parseTaurageLine(cols, city) {
105
- // Validate with Zod schema
106
- const parseResult = gpsLiteTaurageSchema.safeParse(cols);
107
- if (!parseResult.success) {
108
- return null;
109
- }
110
- const row = parseResult.data;
111
- const vehicleNumber = row[6];
112
- // Validate essential fields
113
- if (vehicleNumber === '' || !Number.isFinite(row[2]) || !Number.isFinite(row[3])) {
114
- return null;
115
- }
116
- const longitude = normalizeCoordinate(row[2]);
117
- const latitude = normalizeCoordinate(row[3]);
118
- const speed = normalizeSpeed(row[4]);
119
- const bearing = normalizeBearing(row[5]);
120
- const route = row[1];
121
- const id = `${city}-${vehicleNumber}`;
122
- return {
123
- id,
124
- vehicleNumber,
125
- route,
126
- type: 'bus', // Lite format doesn't specify type
127
- latitude,
128
- longitude,
129
- bearing,
130
- speed,
131
- destination: null, // Needs GTFS enrichment
132
- delaySeconds: null,
133
- tripId: null,
134
- gtfsTripId: null,
135
- nextStopId: null,
136
- arrivalTimeSeconds: null,
137
- isStale: false, // No timestamp in lite format
138
- measuredAt: new Date(), // Use server receive time
139
- };
145
+ // eslint-disable-next-line @typescript-eslint/no-deprecated
146
+ export function isLiteCity(cityId) {
147
+ return cityId in LITE_FORMAT_DESCRIPTORS;
140
148
  }
141
149
  //# sourceMappingURL=gps-lite.js.map