gtfs 4.17.0 → 4.17.2

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