gtfs 4.17.0 → 4.17.1

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.
@@ -1399,7 +1399,8 @@ var stops = {
1399
1399
  {
1400
1400
  name: "parent_station",
1401
1401
  type: "text",
1402
- index: true
1402
+ index: true,
1403
+ prefix: true
1403
1404
  },
1404
1405
  {
1405
1406
  name: "stop_timezone",
@@ -2495,21 +2496,24 @@ var tripUpdates = {
2495
2496
  required: true,
2496
2497
  primary: true,
2497
2498
  index: true,
2498
- source: "id"
2499
+ source: "id",
2500
+ prefix: true
2499
2501
  },
2500
2502
  {
2501
2503
  name: "vehicle_id",
2502
2504
  type: "text",
2503
2505
  index: true,
2504
2506
  source: "tripUpdate.vehicle.id",
2505
- default: null
2507
+ default: null,
2508
+ prefix: true
2506
2509
  },
2507
2510
  {
2508
2511
  name: "trip_id",
2509
2512
  type: "text",
2510
2513
  index: true,
2511
2514
  source: "tripUpdate.trip.tripId",
2512
- default: null
2515
+ default: null,
2516
+ prefix: true
2513
2517
  },
2514
2518
  {
2515
2519
  name: "trip_start_time",
@@ -2528,7 +2532,8 @@ var tripUpdates = {
2528
2532
  type: "text",
2529
2533
  index: true,
2530
2534
  source: "tripUpdate.trip.routeId",
2531
- default: null
2535
+ default: null,
2536
+ prefix: true
2532
2537
  },
2533
2538
  {
2534
2539
  name: "start_date",
@@ -2571,7 +2576,8 @@ var stopTimeUpdates = {
2571
2576
  type: "text",
2572
2577
  index: true,
2573
2578
  source: "parent.tripUpdate.trip.tripId",
2574
- default: null
2579
+ default: null,
2580
+ prefix: true
2575
2581
  },
2576
2582
  {
2577
2583
  name: "trip_start_time",
@@ -2590,14 +2596,16 @@ var stopTimeUpdates = {
2590
2596
  type: "text",
2591
2597
  index: true,
2592
2598
  source: "parent.tripUpdate.trip.routeId",
2593
- default: null
2599
+ default: null,
2600
+ prefix: true
2594
2601
  },
2595
2602
  {
2596
2603
  name: "stop_id",
2597
2604
  type: "text",
2598
2605
  index: true,
2599
2606
  source: "stopId",
2600
- default: null
2607
+ default: null,
2608
+ prefix: true
2601
2609
  },
2602
2610
  {
2603
2611
  name: "stop_sequence",
@@ -2659,7 +2667,8 @@ var vehiclePositions = {
2659
2667
  required: true,
2660
2668
  primary: true,
2661
2669
  index: true,
2662
- source: "id"
2670
+ source: "id",
2671
+ prefix: true
2663
2672
  },
2664
2673
  {
2665
2674
  name: "bearing",
@@ -2701,7 +2710,8 @@ var vehiclePositions = {
2701
2710
  type: "text",
2702
2711
  index: true,
2703
2712
  source: "vehicle.trip.tripId",
2704
- default: null
2713
+ default: null,
2714
+ prefix: true
2705
2715
  },
2706
2716
  {
2707
2717
  name: "trip_start_date",
@@ -2746,7 +2756,8 @@ var vehiclePositions = {
2746
2756
  type: "text",
2747
2757
  index: true,
2748
2758
  source: "vehicle.vehicle.id",
2749
- default: null
2759
+ default: null,
2760
+ prefix: true
2750
2761
  },
2751
2762
  {
2752
2763
  name: "vehicle_label",
@@ -2796,7 +2807,8 @@ var serviceAlerts = {
2796
2807
  required: true,
2797
2808
  primary: true,
2798
2809
  index: true,
2799
- source: "id"
2810
+ source: "id",
2811
+ prefix: true
2800
2812
  },
2801
2813
  {
2802
2814
  name: "active_period",
@@ -2885,21 +2897,24 @@ var serviceAlertInformedEntities = {
2885
2897
  type: "text",
2886
2898
  required: true,
2887
2899
  primary: true,
2888
- source: "parent.id"
2900
+ source: "parent.id",
2901
+ prefix: true
2889
2902
  },
2890
2903
  {
2891
2904
  name: "stop_id",
2892
2905
  type: "text",
2893
2906
  index: true,
2894
2907
  source: "stopId",
2895
- default: null
2908
+ default: null,
2909
+ prefix: true
2896
2910
  },
2897
2911
  {
2898
2912
  name: "route_id",
2899
2913
  type: "text",
2900
2914
  index: true,
2901
2915
  source: "routeId",
2902
- default: null
2916
+ default: null,
2917
+ prefix: true
2903
2918
  },
2904
2919
  {
2905
2920
  name: "route_type",
@@ -2913,7 +2928,8 @@ var serviceAlertInformedEntities = {
2913
2928
  type: "text",
2914
2929
  index: true,
2915
2930
  source: "trip.tripId",
2916
- default: null
2931
+ default: null,
2932
+ prefix: true
2917
2933
  },
2918
2934
  {
2919
2935
  name: "direction_id",
@@ -3300,8 +3316,8 @@ function isValidJSON(string) {
3300
3316
  // src/lib/import-gtfs-realtime.ts
3301
3317
  import pluralize from "pluralize";
3302
3318
  import GtfsRealtimeBindings from "gtfs-realtime-bindings";
3303
- import sqlString2 from "sqlstring-sqlite";
3304
3319
  import mapSeries from "promise-map-series";
3320
+ import { get } from "lodash-es";
3305
3321
 
3306
3322
  // src/lib/utils.ts
3307
3323
  import sqlString from "sqlstring-sqlite";
@@ -3358,39 +3374,14 @@ function padLeadingZeros(time) {
3358
3374
  function getTimestampColumnName(columnName) {
3359
3375
  return columnName.endsWith("time") ? `${columnName}stamp` : `${columnName}_timestamp`;
3360
3376
  }
3361
-
3362
- // src/lib/import-gtfs-realtime.ts
3363
- function getNestedProperty(obj, defaultValue, path3) {
3364
- if (path3 === void 0) return defaultValue;
3365
- const arr = path3.split(".");
3366
- while (arr.length) {
3367
- const nextKey = arr.shift();
3368
- if (nextKey === void 0) {
3369
- return defaultValue;
3370
- } else if (obj == null) {
3371
- return defaultValue;
3372
- } else if (nextKey?.includes("[")) {
3373
- const arrayKey = nextKey.match(/(\w*)\[(\d+)\]/);
3374
- if (arrayKey === null) {
3375
- return defaultValue;
3376
- }
3377
- if (obj[arrayKey[1]] === void 0) {
3378
- return defaultValue;
3379
- }
3380
- if (obj[arrayKey[1]][arrayKey[2]] === void 0) {
3381
- return defaultValue;
3382
- }
3383
- obj = obj[arrayKey[1]][arrayKey[2]];
3384
- } else {
3385
- if (obj[nextKey] === void 0) {
3386
- return defaultValue;
3387
- }
3388
- obj = obj[nextKey];
3389
- }
3377
+ function applyPrefixToValue(value, columnShouldBePrefixed, prefix) {
3378
+ if (!columnShouldBePrefixed || prefix === void 0 || value === null) {
3379
+ return value;
3390
3380
  }
3391
- if (obj?.__isLong__) return convertLongTimeToDate(obj);
3392
- return obj;
3381
+ return `${prefix}${value}`;
3393
3382
  }
3383
+
3384
+ // src/lib/import-gtfs-realtime.ts
3394
3385
  async function fetchGtfsRealtimeData(urlConfig, task) {
3395
3386
  task.log(`Downloading GTFS-Realtime from ${urlConfig.url}`);
3396
3387
  const response = await fetch(urlConfig.url, {
@@ -3428,100 +3419,117 @@ function prepareRealtimeFieldValue(entity, column, task) {
3428
3419
  if (column.name === "expiration_timestamp") {
3429
3420
  return task.currentTimestamp + task.gtfsRealtimeExpirationSeconds;
3430
3421
  }
3431
- const value = getNestedProperty(entity, column.default, column.source);
3432
- if (column.type === "json") {
3433
- return sqlString2.escape(JSON.stringify(value));
3434
- }
3435
- return sqlString2.escape(value);
3422
+ const baseValue = column.source === void 0 ? column.default : get(entity, column.source, column.default);
3423
+ const timeAdjustedValue = baseValue?.__isLong__ ? convertLongTimeToDate(baseValue) : baseValue;
3424
+ const prefixedValue = applyPrefixToValue(
3425
+ timeAdjustedValue,
3426
+ column.prefix,
3427
+ task.prefix
3428
+ );
3429
+ return column.type === "json" ? JSON.stringify(prefixedValue) : prefixedValue;
3436
3430
  }
3437
3431
  async function processRealtimeAlerts(db, gtfsRealtimeData, task) {
3438
- task.log(`Download successful`);
3432
+ const alertStmt = db.prepare(
3433
+ `REPLACE INTO ${serviceAlerts.filenameBase} (${serviceAlerts.schema.map((column) => column.name).join(
3434
+ ", "
3435
+ )}) VALUES (${serviceAlerts.schema.map(() => "?").join(", ")})`
3436
+ );
3437
+ const informedEntityStmt = db.prepare(
3438
+ `REPLACE INTO ${serviceAlertInformedEntities.filenameBase} (${serviceAlertInformedEntities.schema.map((column) => column.name).join(
3439
+ ", "
3440
+ )}) VALUES (${serviceAlertInformedEntities.schema.map(() => "?").join(", ")})`
3441
+ );
3439
3442
  let totalLineCount = 0;
3440
- for (const entity of gtfsRealtimeData.entity) {
3441
- const fieldValues = serviceAlerts.schema.map(
3442
- (column) => prepareRealtimeFieldValue(entity, column, task)
3443
- );
3444
- try {
3445
- db.prepare(
3446
- `REPLACE INTO ${serviceAlerts.filenameBase} (${serviceAlerts.schema.map((column) => column.name).join(", ")}) VALUES (${fieldValues.join(", ")})`
3447
- ).run();
3448
- } catch (error) {
3449
- task.logWarning(`Import error: ${error.message}`);
3450
- }
3451
- if (!entity.alert.informedEntity || entity.alert.informedEntity.length === 0) {
3452
- task.logWarning(
3453
- `Import error: No informed entities found for alert id=${entity.id}`
3443
+ db.transaction(() => {
3444
+ for (const entity of gtfsRealtimeData.entity) {
3445
+ const fieldValues = serviceAlerts.schema.map(
3446
+ (column) => prepareRealtimeFieldValue(entity, column, task)
3454
3447
  );
3455
- } else {
3456
- const informedEntities = [];
3457
- for (const informedEntity of entity.alert.informedEntity) {
3458
- informedEntity.parent = entity;
3459
- const subValues = serviceAlertInformedEntities.schema.map(
3460
- (column) => prepareRealtimeFieldValue(informedEntity, column, task)
3461
- );
3462
- informedEntities.push(`(${subValues.join(", ")})`);
3463
- totalLineCount++;
3464
- }
3465
3448
  try {
3466
- db.prepare(
3467
- `REPLACE INTO ${serviceAlertInformedEntities.filenameBase} (${serviceAlertInformedEntities.schema.map((column) => column.name).join(", ")}) VALUES ${informedEntities.join(", ")}`
3468
- ).run();
3449
+ alertStmt.run(fieldValues);
3450
+ if (entity.alert.informedEntity?.length) {
3451
+ const informedEntities = entity.alert.informedEntity.map(
3452
+ (informedEntity) => {
3453
+ informedEntity.parent = entity;
3454
+ return serviceAlertInformedEntities.schema.map(
3455
+ (column) => prepareRealtimeFieldValue(informedEntity, column, task)
3456
+ );
3457
+ }
3458
+ );
3459
+ for (const values of informedEntities) {
3460
+ informedEntityStmt.run(values);
3461
+ }
3462
+ }
3463
+ totalLineCount++;
3469
3464
  } catch (error) {
3470
3465
  task.logWarning(`Import error: ${error.message}`);
3471
3466
  }
3472
3467
  }
3473
- task.log(`Importing - ${totalLineCount++} entries imported\r`, true);
3474
- }
3468
+ task.log(
3469
+ `Importing - GTFS-Realtime service alerts - ${totalLineCount} entries imported\r`,
3470
+ true
3471
+ );
3472
+ })();
3475
3473
  }
3476
3474
  async function processRealtimeTripUpdates(db, gtfsRealtimeData, task) {
3477
- task.log(`Download successful`);
3478
3475
  let totalLineCount = 0;
3479
- for (const entity of gtfsRealtimeData.entity) {
3480
- const fieldValues = tripUpdates.schema.map(
3481
- (column) => prepareRealtimeFieldValue(entity, column, task)
3482
- );
3483
- try {
3484
- db.prepare(
3485
- `REPLACE INTO ${tripUpdates.filenameBase} (${tripUpdates.schema.map((column) => column.name).join(", ")}) VALUES (${fieldValues.join(", ")})`
3486
- ).run();
3487
- } catch (error) {
3488
- task.logWarning(`Import error: ${error.message}`);
3489
- }
3490
- const stopTimeUpdateArray = [];
3491
- for (const stopTimeUpdate of entity.tripUpdate.stopTimeUpdate) {
3492
- stopTimeUpdate.parent = entity;
3493
- const subValues = stopTimeUpdates.schema.map(
3494
- (column) => prepareRealtimeFieldValue(stopTimeUpdate, column, task)
3495
- );
3496
- stopTimeUpdateArray.push(`(${subValues.join(", ")})`);
3497
- totalLineCount++;
3498
- }
3499
- try {
3500
- db.prepare(
3501
- `REPLACE INTO ${stopTimeUpdates.filenameBase} (${stopTimeUpdates.schema.map((column) => column.name).join(", ")}) VALUES ${stopTimeUpdateArray.join(", ")}`
3502
- ).run();
3503
- } catch (error) {
3504
- task.logWarning(`Import error: ${error.message}`);
3476
+ const tripUpdateStmt = db.prepare(
3477
+ `REPLACE INTO ${tripUpdates.filenameBase} (${tripUpdates.schema.map((column) => column.name).join(
3478
+ ", "
3479
+ )}) VALUES (${tripUpdates.schema.map(() => "?").join(", ")})`
3480
+ );
3481
+ const stopTimeStmt = db.prepare(
3482
+ `REPLACE INTO ${stopTimeUpdates.filenameBase} (${stopTimeUpdates.schema.map((column) => column.name).join(
3483
+ ", "
3484
+ )}) VALUES (${stopTimeUpdates.schema.map(() => "?").join(", ")})`
3485
+ );
3486
+ db.transaction(() => {
3487
+ for (const entity of gtfsRealtimeData.entity) {
3488
+ try {
3489
+ const fieldValues = tripUpdates.schema.map(
3490
+ (column) => prepareRealtimeFieldValue(entity, column, task)
3491
+ );
3492
+ tripUpdateStmt.run(fieldValues);
3493
+ for (const stopTimeUpdate of entity.tripUpdate.stopTimeUpdate) {
3494
+ stopTimeUpdate.parent = entity;
3495
+ const values = stopTimeUpdates.schema.map(
3496
+ (column) => prepareRealtimeFieldValue(stopTimeUpdate, column, task)
3497
+ );
3498
+ stopTimeStmt.run(values);
3499
+ }
3500
+ totalLineCount++;
3501
+ } catch (error) {
3502
+ task.logWarning(`Import error: ${error.message}`);
3503
+ }
3505
3504
  }
3506
- task.log(`Importing - ${totalLineCount++} entries imported\r`, true);
3507
- }
3505
+ task.log(
3506
+ `Importing - GTFS-Realtime trip updates - ${totalLineCount} entries imported\r`,
3507
+ true
3508
+ );
3509
+ })();
3508
3510
  }
3509
3511
  async function processRealtimeVehiclePositions(db, gtfsRealtimeData, task) {
3510
- task.log(`Download successful`);
3511
3512
  let totalLineCount = 0;
3512
- for (const entity of gtfsRealtimeData.entity) {
3513
- const fieldValues = vehiclePositions.schema.map(
3514
- (column) => prepareRealtimeFieldValue(entity, column, task)
3515
- );
3516
- try {
3517
- db.prepare(
3518
- `REPLACE INTO ${vehiclePositions.filenameBase} (${vehiclePositions.schema.map((column) => column.name).join(", ")}) VALUES (${fieldValues.join(", ")})`
3519
- ).run();
3520
- } catch (error) {
3521
- task.logWarning(`Import error: ${error.message}`);
3513
+ const vehiclePositionStmt = db.prepare(
3514
+ `REPLACE INTO ${vehiclePositions.filenameBase} (${vehiclePositions.schema.map((column) => column.name).join(
3515
+ ", "
3516
+ )}) VALUES (${vehiclePositions.schema.map(() => "?").join(", ")})`
3517
+ );
3518
+ db.transaction(() => {
3519
+ for (const entity of gtfsRealtimeData.entity) {
3520
+ try {
3521
+ const fieldValues = vehiclePositions.schema.map((column) => prepareRealtimeFieldValue(entity, column, task));
3522
+ vehiclePositionStmt.run(fieldValues);
3523
+ totalLineCount++;
3524
+ } catch (error) {
3525
+ task.logWarning(`Import error: ${error.message}`);
3526
+ }
3522
3527
  }
3523
- task.log(`Importing - ${totalLineCount++} entries imported\r`, true);
3524
- }
3528
+ task.log(
3529
+ `Importing - GTFS-Realtime vehicle positions - ${totalLineCount} entries imported\r`,
3530
+ true
3531
+ );
3532
+ })();
3525
3533
  }
3526
3534
  async function updateGtfsRealtimeData(task) {
3527
3535
  if (task.realtimeAlerts === void 0 && task.realtimeTripUpdates === void 0 && task.realtimeVehiclePositions === void 0) {
@@ -3830,7 +3838,11 @@ var importGtfsFiles = (db, task) => mapSeries2(
3830
3838
  line
3831
3839
  ).map(([columnName, value]) => [
3832
3840
  columnName,
3833
- prefixedColumns.has(columnName) && value !== null ? `${task.prefix}${value}` : value
3841
+ applyPrefixToValue(
3842
+ value,
3843
+ prefixedColumns.has(columnName),
3844
+ task.prefix
3845
+ )
3834
3846
  ])
3835
3847
  );
3836
3848
  insert.run(prefixedLine);
@@ -3997,12 +4009,12 @@ async function importGtfs(initialConfig) {
3997
4009
  import { without, compact as compact2 } from "lodash-es";
3998
4010
  import pluralize3 from "pluralize";
3999
4011
  import { stringify } from "csv-stringify";
4000
- import sqlString3 from "sqlstring-sqlite";
4012
+ import sqlString2 from "sqlstring-sqlite";
4001
4013
  import mapSeries3 from "promise-map-series";
4002
4014
  import untildify4 from "untildify";
4003
4015
 
4004
4016
  // src/lib/advancedQuery.ts
4005
- import sqlString4 from "sqlstring-sqlite";
4017
+ import sqlString3 from "sqlstring-sqlite";
4006
4018
 
4007
4019
  // src/lib/gtfs/routes.ts
4008
4020
  import { omit as omit3, pick } from "lodash-es";
@@ -4016,7 +4028,7 @@ import { omit as omit5, orderBy, pick as pick3 } from "lodash-es";
4016
4028
 
4017
4029
  // src/lib/gtfs/stop-times.ts
4018
4030
  import { omit as omit6 } from "lodash-es";
4019
- import sqlString5 from "sqlstring-sqlite";
4031
+ import sqlString4 from "sqlstring-sqlite";
4020
4032
 
4021
4033
  // src/bin/gtfs-import.ts
4022
4034
  var pe = new PrettyError();