gtfs 4.18.6 → 4.19.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.
@@ -1126,6 +1126,7 @@ var routes = {
1126
1126
  {
1127
1127
  name: "agency_id",
1128
1128
  type: "text",
1129
+ index: true,
1129
1130
  prefix: true
1130
1131
  },
1131
1132
  {
@@ -1378,7 +1379,8 @@ var stops = {
1378
1379
  },
1379
1380
  {
1380
1381
  name: "stop_code",
1381
- type: "text"
1382
+ type: "text",
1383
+ index: true
1382
1384
  },
1383
1385
  {
1384
1386
  name: "stop_name",
@@ -1664,6 +1666,14 @@ var trips = {
1664
1666
  type: "integer",
1665
1667
  min: 0,
1666
1668
  max: 2
1669
+ },
1670
+ {
1671
+ name: "safe_duration_factor",
1672
+ type: "real"
1673
+ },
1674
+ {
1675
+ name: "safe_duration_offset",
1676
+ type: "real"
1667
1677
  }
1668
1678
  ]
1669
1679
  };
@@ -2872,16 +2882,14 @@ var serviceAlerts = {
2872
2882
  {
2873
2883
  name: "start_time",
2874
2884
  type: "text",
2875
- required: true,
2876
2885
  source: "alert.activePeriod[0].start",
2877
- default: ""
2886
+ default: null
2878
2887
  },
2879
2888
  {
2880
2889
  name: "end_time",
2881
2890
  type: "text",
2882
- required: true,
2883
2891
  source: "alert.activePeriod[0].end",
2884
- default: ""
2892
+ default: null
2885
2893
  },
2886
2894
  {
2887
2895
  name: "header_text",
@@ -2941,7 +2949,7 @@ var serviceAlertInformedEntities = {
2941
2949
  {
2942
2950
  name: "stop_id",
2943
2951
  type: "text",
2944
- index: true,
2952
+ primary: true,
2945
2953
  source: "stopId",
2946
2954
  default: null,
2947
2955
  prefix: true
@@ -2949,7 +2957,7 @@ var serviceAlertInformedEntities = {
2949
2957
  {
2950
2958
  name: "route_id",
2951
2959
  type: "text",
2952
- index: true,
2960
+ primary: true,
2953
2961
  source: "routeId",
2954
2962
  default: null,
2955
2963
  prefix: true
@@ -2957,14 +2965,14 @@ var serviceAlertInformedEntities = {
2957
2965
  {
2958
2966
  name: "route_type",
2959
2967
  type: "integer",
2960
- index: true,
2968
+ primary: true,
2961
2969
  source: "routeType",
2962
2970
  default: null
2963
2971
  },
2964
2972
  {
2965
2973
  name: "trip_id",
2966
2974
  type: "text",
2967
- index: true,
2975
+ primary: true,
2968
2976
  source: "trip.tripId",
2969
2977
  default: null,
2970
2978
  prefix: true
@@ -2972,7 +2980,7 @@ var serviceAlertInformedEntities = {
2972
2980
  {
2973
2981
  name: "direction_id",
2974
2982
  type: "integer",
2975
- index: true,
2983
+ primary: true,
2976
2984
  source: "directionId",
2977
2985
  default: null
2978
2986
  },
@@ -3489,7 +3497,8 @@ var passengerEvents = {
3489
3497
  {
3490
3498
  name: "trip_stop_sequence",
3491
3499
  type: "integer",
3492
- min: 1
3500
+ min: 1,
3501
+ required: true
3493
3502
  },
3494
3503
  {
3495
3504
  name: "scheduled_stop_sequence",
@@ -3715,7 +3724,8 @@ var stopVisits = {
3715
3724
  },
3716
3725
  {
3717
3726
  name: "ramp_deployed_time",
3718
- type: "text"
3727
+ type: "real",
3728
+ min: 0
3719
3729
  },
3720
3730
  {
3721
3731
  name: "ramp_failure",
@@ -3723,12 +3733,12 @@ var stopVisits = {
3723
3733
  },
3724
3734
  {
3725
3735
  name: "kneel_deployed_time",
3726
- type: "integer",
3736
+ type: "real",
3727
3737
  min: 0
3728
3738
  },
3729
3739
  {
3730
3740
  name: "lift_deployed_time",
3731
- type: "integer",
3741
+ type: "real",
3732
3742
  min: 0
3733
3743
  },
3734
3744
  {
@@ -4328,7 +4338,7 @@ function getTimestampColumnName(columnName) {
4328
4338
  return columnName.endsWith("time") ? `${columnName}stamp` : `${columnName}_timestamp`;
4329
4339
  }
4330
4340
  function applyPrefixToValue(value, columnShouldBePrefixed, prefix) {
4331
- if (!columnShouldBePrefixed || prefix === void 0 || value === null) {
4341
+ if (!columnShouldBePrefixed || prefix === void 0 || value === null || value === void 0) {
4332
4342
  return value;
4333
4343
  }
4334
4344
  return `${prefix}${value}`;
@@ -4391,13 +4401,15 @@ async function fetchGtfsRealtimeData(type, task) {
4391
4401
  try {
4392
4402
  const response = await fetch(urlConfig.url, {
4393
4403
  method: "GET",
4404
+ redirect: "follow",
4394
4405
  headers: {
4406
+ "User-Agent": "node-gtfs",
4395
4407
  ...urlConfig.headers ?? {},
4396
4408
  "Accept-Encoding": "gzip"
4397
4409
  },
4398
4410
  signal: task.downloadTimeout ? AbortSignal.timeout(task.downloadTimeout) : void 0
4399
4411
  });
4400
- if (response.status !== 200) {
4412
+ if (!response.ok) {
4401
4413
  throw new GtfsError(`HTTP ${response.status}: ${response.statusText}`, {
4402
4414
  code: "GTFS_DOWNLOAD_HTTP" /* GTFS_DOWNLOAD_HTTP */,
4403
4415
  category: "download" /* DOWNLOAD */,
@@ -4470,12 +4482,17 @@ function createServiceAlertsProcessor(db, task) {
4470
4482
  db,
4471
4483
  serviceAlertInformedEntities
4472
4484
  );
4485
+ const deleteInformedEntitiesStmt = db.prepare(
4486
+ `DELETE FROM ${serviceAlertInformedEntities.filenameBase} WHERE alert_id = ?`
4487
+ );
4473
4488
  return async (batch) => {
4474
4489
  let recordCount = 0;
4475
4490
  let errorCount = 0;
4476
4491
  db.transaction(() => {
4477
4492
  for (const entity of batch) {
4478
4493
  try {
4494
+ const alertId = applyPrefixToValue(entity.id, true, task.prefix);
4495
+ deleteInformedEntitiesStmt.run(alertId);
4479
4496
  const alertValues = serviceAlerts.schema.map((column) => prepareRealtimeFieldValue(entity, column, task));
4480
4497
  alertStmt.run(alertValues);
4481
4498
  recordCount++;
@@ -4508,6 +4525,9 @@ function createTripUpdatesProcessor(db, task) {
4508
4525
  db,
4509
4526
  stopTimeUpdates
4510
4527
  );
4528
+ const deleteStopTimesByTripStmt = db.prepare(
4529
+ `DELETE FROM ${stopTimeUpdates.filenameBase} WHERE trip_id = ? AND trip_start_time IS ?`
4530
+ );
4511
4531
  return async (batch) => {
4512
4532
  let recordCount = 0;
4513
4533
  let errorCount = 0;
@@ -4518,6 +4538,15 @@ function createTripUpdatesProcessor(db, task) {
4518
4538
  tripUpdateStmt.run(tripUpdateValues);
4519
4539
  recordCount++;
4520
4540
  if (entity.tripUpdate?.stopTimeUpdate?.length) {
4541
+ const tripId = applyPrefixToValue(
4542
+ entity.tripUpdate?.trip?.tripId ?? null,
4543
+ true,
4544
+ task.prefix
4545
+ );
4546
+ const tripStartTime = entity.tripUpdate?.trip?.startTime ?? null;
4547
+ if (tripId !== null) {
4548
+ deleteStopTimesByTripStmt.run(tripId, tripStartTime);
4549
+ }
4521
4550
  for (const stopTimeUpdate of entity.tripUpdate.stopTimeUpdate) {
4522
4551
  stopTimeUpdate.parent = entity;
4523
4552
  const stopTimeValues = stopTimeUpdates.schema.map(
@@ -4578,41 +4607,30 @@ async function updateGtfsRealtimeData(task) {
4578
4607
  tripupdates: 0,
4579
4608
  vehiclepositions: 0
4580
4609
  };
4581
- const processingPromises = [];
4582
4610
  if (alertsData?.entity?.length) {
4583
- processingPromises.push(
4584
- processBatch(
4585
- alertsData.entity,
4586
- BATCH_SIZE,
4587
- createServiceAlertsProcessor(db, task)
4588
- ).then((result) => {
4589
- recordCounts.alerts = result.recordCount;
4590
- })
4611
+ const result = await processBatch(
4612
+ alertsData.entity,
4613
+ BATCH_SIZE,
4614
+ createServiceAlertsProcessor(db, task)
4591
4615
  );
4616
+ recordCounts.alerts = result.recordCount;
4592
4617
  }
4593
4618
  if (tripUpdatesData?.entity?.length) {
4594
- processingPromises.push(
4595
- processBatch(
4596
- tripUpdatesData.entity,
4597
- BATCH_SIZE,
4598
- createTripUpdatesProcessor(db, task)
4599
- ).then((result) => {
4600
- recordCounts.tripupdates = result.recordCount;
4601
- })
4619
+ const result = await processBatch(
4620
+ tripUpdatesData.entity,
4621
+ BATCH_SIZE,
4622
+ createTripUpdatesProcessor(db, task)
4602
4623
  );
4624
+ recordCounts.tripupdates = result.recordCount;
4603
4625
  }
4604
4626
  if (vehiclePositionsData?.entity?.length) {
4605
- processingPromises.push(
4606
- processBatch(
4607
- vehiclePositionsData.entity,
4608
- BATCH_SIZE,
4609
- createVehiclePositionsProcessor(db, task)
4610
- ).then((result) => {
4611
- recordCounts.vehiclepositions = result.recordCount;
4612
- })
4627
+ const result = await processBatch(
4628
+ vehiclePositionsData.entity,
4629
+ BATCH_SIZE,
4630
+ createVehiclePositionsProcessor(db, task)
4613
4631
  );
4632
+ recordCounts.vehiclepositions = result.recordCount;
4614
4633
  }
4615
- await Promise.all(processingPromises);
4616
4634
  task.log(
4617
4635
  `GTFS-Realtime import complete: ${recordCounts.alerts} alerts, ${recordCounts.tripupdates} trip updates, ${recordCounts.vehiclepositions} vehicle positions`
4618
4636
  );
@@ -4640,10 +4658,14 @@ var downloadGtfsFiles = async (task) => {
4640
4658
  try {
4641
4659
  const response = await fetch(task.url, {
4642
4660
  method: "GET",
4643
- headers: task.headers || {},
4661
+ redirect: "follow",
4662
+ headers: {
4663
+ "User-Agent": "node-gtfs",
4664
+ ...task.headers
4665
+ },
4644
4666
  signal: task.downloadTimeout ? AbortSignal.timeout(task.downloadTimeout) : void 0
4645
4667
  });
4646
- if (response.status !== 200) {
4668
+ if (!response.ok) {
4647
4669
  throw new GtfsError(
4648
4670
  `Unable to download GTFS from ${task.url}. Got status ${response.status}.`,
4649
4671
  {
@@ -4756,18 +4778,18 @@ var extractGtfsFiles = async (task) => {
4756
4778
  var createGtfsTables = (db) => {
4757
4779
  for (const model of Object.values(models_exports)) {
4758
4780
  if (!model.schema) {
4759
- return;
4781
+ continue;
4760
4782
  }
4761
4783
  const sqlColumnCreateStatements = [];
4762
4784
  for (const column of model.schema) {
4763
4785
  const checks = [];
4764
- if (column.min !== void 0 && column.max) {
4786
+ if (column.min !== void 0 && column.max !== void 0) {
4765
4787
  checks.push(
4766
4788
  `${column.name} >= ${column.min} AND ${column.name} <= ${column.max}`
4767
4789
  );
4768
- } else if (column.min) {
4790
+ } else if (column.min !== void 0) {
4769
4791
  checks.push(`${column.name} >= ${column.min}`);
4770
- } else if (column.max) {
4792
+ } else if (column.max !== void 0) {
4771
4793
  checks.push(`${column.name} <= ${column.max}`);
4772
4794
  }
4773
4795
  if (column.type === "integer") {
@@ -4816,7 +4838,7 @@ var createGtfsTables = (db) => {
4816
4838
  var createGtfsIndexes = (db) => {
4817
4839
  for (const model of Object.values(models_exports)) {
4818
4840
  if (!model.schema) {
4819
- return;
4841
+ continue;
4820
4842
  }
4821
4843
  for (const column of model.schema) {
4822
4844
  if (column.index) {