gtfs 4.18.7 → 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",
@@ -2880,16 +2882,14 @@ var serviceAlerts = {
2880
2882
  {
2881
2883
  name: "start_time",
2882
2884
  type: "text",
2883
- required: true,
2884
2885
  source: "alert.activePeriod[0].start",
2885
- default: ""
2886
+ default: null
2886
2887
  },
2887
2888
  {
2888
2889
  name: "end_time",
2889
2890
  type: "text",
2890
- required: true,
2891
2891
  source: "alert.activePeriod[0].end",
2892
- default: ""
2892
+ default: null
2893
2893
  },
2894
2894
  {
2895
2895
  name: "header_text",
@@ -2949,7 +2949,7 @@ var serviceAlertInformedEntities = {
2949
2949
  {
2950
2950
  name: "stop_id",
2951
2951
  type: "text",
2952
- index: true,
2952
+ primary: true,
2953
2953
  source: "stopId",
2954
2954
  default: null,
2955
2955
  prefix: true
@@ -2957,7 +2957,7 @@ var serviceAlertInformedEntities = {
2957
2957
  {
2958
2958
  name: "route_id",
2959
2959
  type: "text",
2960
- index: true,
2960
+ primary: true,
2961
2961
  source: "routeId",
2962
2962
  default: null,
2963
2963
  prefix: true
@@ -2965,14 +2965,14 @@ var serviceAlertInformedEntities = {
2965
2965
  {
2966
2966
  name: "route_type",
2967
2967
  type: "integer",
2968
- index: true,
2968
+ primary: true,
2969
2969
  source: "routeType",
2970
2970
  default: null
2971
2971
  },
2972
2972
  {
2973
2973
  name: "trip_id",
2974
2974
  type: "text",
2975
- index: true,
2975
+ primary: true,
2976
2976
  source: "trip.tripId",
2977
2977
  default: null,
2978
2978
  prefix: true
@@ -2980,7 +2980,7 @@ var serviceAlertInformedEntities = {
2980
2980
  {
2981
2981
  name: "direction_id",
2982
2982
  type: "integer",
2983
- index: true,
2983
+ primary: true,
2984
2984
  source: "directionId",
2985
2985
  default: null
2986
2986
  },
@@ -3497,7 +3497,8 @@ var passengerEvents = {
3497
3497
  {
3498
3498
  name: "trip_stop_sequence",
3499
3499
  type: "integer",
3500
- min: 1
3500
+ min: 1,
3501
+ required: true
3501
3502
  },
3502
3503
  {
3503
3504
  name: "scheduled_stop_sequence",
@@ -3723,7 +3724,8 @@ var stopVisits = {
3723
3724
  },
3724
3725
  {
3725
3726
  name: "ramp_deployed_time",
3726
- type: "text"
3727
+ type: "real",
3728
+ min: 0
3727
3729
  },
3728
3730
  {
3729
3731
  name: "ramp_failure",
@@ -3731,12 +3733,12 @@ var stopVisits = {
3731
3733
  },
3732
3734
  {
3733
3735
  name: "kneel_deployed_time",
3734
- type: "integer",
3736
+ type: "real",
3735
3737
  min: 0
3736
3738
  },
3737
3739
  {
3738
3740
  name: "lift_deployed_time",
3739
- type: "integer",
3741
+ type: "real",
3740
3742
  min: 0
3741
3743
  },
3742
3744
  {
@@ -4336,7 +4338,7 @@ function getTimestampColumnName(columnName) {
4336
4338
  return columnName.endsWith("time") ? `${columnName}stamp` : `${columnName}_timestamp`;
4337
4339
  }
4338
4340
  function applyPrefixToValue(value, columnShouldBePrefixed, prefix) {
4339
- if (!columnShouldBePrefixed || prefix === void 0 || value === null) {
4341
+ if (!columnShouldBePrefixed || prefix === void 0 || value === null || value === void 0) {
4340
4342
  return value;
4341
4343
  }
4342
4344
  return `${prefix}${value}`;
@@ -4399,13 +4401,15 @@ async function fetchGtfsRealtimeData(type, task) {
4399
4401
  try {
4400
4402
  const response = await fetch(urlConfig.url, {
4401
4403
  method: "GET",
4404
+ redirect: "follow",
4402
4405
  headers: {
4406
+ "User-Agent": "node-gtfs",
4403
4407
  ...urlConfig.headers ?? {},
4404
4408
  "Accept-Encoding": "gzip"
4405
4409
  },
4406
4410
  signal: task.downloadTimeout ? AbortSignal.timeout(task.downloadTimeout) : void 0
4407
4411
  });
4408
- if (response.status !== 200) {
4412
+ if (!response.ok) {
4409
4413
  throw new GtfsError(`HTTP ${response.status}: ${response.statusText}`, {
4410
4414
  code: "GTFS_DOWNLOAD_HTTP" /* GTFS_DOWNLOAD_HTTP */,
4411
4415
  category: "download" /* DOWNLOAD */,
@@ -4478,12 +4482,17 @@ function createServiceAlertsProcessor(db, task) {
4478
4482
  db,
4479
4483
  serviceAlertInformedEntities
4480
4484
  );
4485
+ const deleteInformedEntitiesStmt = db.prepare(
4486
+ `DELETE FROM ${serviceAlertInformedEntities.filenameBase} WHERE alert_id = ?`
4487
+ );
4481
4488
  return async (batch) => {
4482
4489
  let recordCount = 0;
4483
4490
  let errorCount = 0;
4484
4491
  db.transaction(() => {
4485
4492
  for (const entity of batch) {
4486
4493
  try {
4494
+ const alertId = applyPrefixToValue(entity.id, true, task.prefix);
4495
+ deleteInformedEntitiesStmt.run(alertId);
4487
4496
  const alertValues = serviceAlerts.schema.map((column) => prepareRealtimeFieldValue(entity, column, task));
4488
4497
  alertStmt.run(alertValues);
4489
4498
  recordCount++;
@@ -4516,6 +4525,9 @@ function createTripUpdatesProcessor(db, task) {
4516
4525
  db,
4517
4526
  stopTimeUpdates
4518
4527
  );
4528
+ const deleteStopTimesByTripStmt = db.prepare(
4529
+ `DELETE FROM ${stopTimeUpdates.filenameBase} WHERE trip_id = ? AND trip_start_time IS ?`
4530
+ );
4519
4531
  return async (batch) => {
4520
4532
  let recordCount = 0;
4521
4533
  let errorCount = 0;
@@ -4526,6 +4538,15 @@ function createTripUpdatesProcessor(db, task) {
4526
4538
  tripUpdateStmt.run(tripUpdateValues);
4527
4539
  recordCount++;
4528
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
+ }
4529
4550
  for (const stopTimeUpdate of entity.tripUpdate.stopTimeUpdate) {
4530
4551
  stopTimeUpdate.parent = entity;
4531
4552
  const stopTimeValues = stopTimeUpdates.schema.map(
@@ -4586,41 +4607,30 @@ async function updateGtfsRealtimeData(task) {
4586
4607
  tripupdates: 0,
4587
4608
  vehiclepositions: 0
4588
4609
  };
4589
- const processingPromises = [];
4590
4610
  if (alertsData?.entity?.length) {
4591
- processingPromises.push(
4592
- processBatch(
4593
- alertsData.entity,
4594
- BATCH_SIZE,
4595
- createServiceAlertsProcessor(db, task)
4596
- ).then((result) => {
4597
- recordCounts.alerts = result.recordCount;
4598
- })
4611
+ const result = await processBatch(
4612
+ alertsData.entity,
4613
+ BATCH_SIZE,
4614
+ createServiceAlertsProcessor(db, task)
4599
4615
  );
4616
+ recordCounts.alerts = result.recordCount;
4600
4617
  }
4601
4618
  if (tripUpdatesData?.entity?.length) {
4602
- processingPromises.push(
4603
- processBatch(
4604
- tripUpdatesData.entity,
4605
- BATCH_SIZE,
4606
- createTripUpdatesProcessor(db, task)
4607
- ).then((result) => {
4608
- recordCounts.tripupdates = result.recordCount;
4609
- })
4619
+ const result = await processBatch(
4620
+ tripUpdatesData.entity,
4621
+ BATCH_SIZE,
4622
+ createTripUpdatesProcessor(db, task)
4610
4623
  );
4624
+ recordCounts.tripupdates = result.recordCount;
4611
4625
  }
4612
4626
  if (vehiclePositionsData?.entity?.length) {
4613
- processingPromises.push(
4614
- processBatch(
4615
- vehiclePositionsData.entity,
4616
- BATCH_SIZE,
4617
- createVehiclePositionsProcessor(db, task)
4618
- ).then((result) => {
4619
- recordCounts.vehiclepositions = result.recordCount;
4620
- })
4627
+ const result = await processBatch(
4628
+ vehiclePositionsData.entity,
4629
+ BATCH_SIZE,
4630
+ createVehiclePositionsProcessor(db, task)
4621
4631
  );
4632
+ recordCounts.vehiclepositions = result.recordCount;
4622
4633
  }
4623
- await Promise.all(processingPromises);
4624
4634
  task.log(
4625
4635
  `GTFS-Realtime import complete: ${recordCounts.alerts} alerts, ${recordCounts.tripupdates} trip updates, ${recordCounts.vehiclepositions} vehicle positions`
4626
4636
  );
@@ -4648,10 +4658,14 @@ var downloadGtfsFiles = async (task) => {
4648
4658
  try {
4649
4659
  const response = await fetch(task.url, {
4650
4660
  method: "GET",
4651
- headers: task.headers || {},
4661
+ redirect: "follow",
4662
+ headers: {
4663
+ "User-Agent": "node-gtfs",
4664
+ ...task.headers
4665
+ },
4652
4666
  signal: task.downloadTimeout ? AbortSignal.timeout(task.downloadTimeout) : void 0
4653
4667
  });
4654
- if (response.status !== 200) {
4668
+ if (!response.ok) {
4655
4669
  throw new GtfsError(
4656
4670
  `Unable to download GTFS from ${task.url}. Got status ${response.status}.`,
4657
4671
  {
@@ -4764,18 +4778,18 @@ var extractGtfsFiles = async (task) => {
4764
4778
  var createGtfsTables = (db) => {
4765
4779
  for (const model of Object.values(models_exports)) {
4766
4780
  if (!model.schema) {
4767
- return;
4781
+ continue;
4768
4782
  }
4769
4783
  const sqlColumnCreateStatements = [];
4770
4784
  for (const column of model.schema) {
4771
4785
  const checks = [];
4772
- if (column.min !== void 0 && column.max) {
4786
+ if (column.min !== void 0 && column.max !== void 0) {
4773
4787
  checks.push(
4774
4788
  `${column.name} >= ${column.min} AND ${column.name} <= ${column.max}`
4775
4789
  );
4776
- } else if (column.min) {
4790
+ } else if (column.min !== void 0) {
4777
4791
  checks.push(`${column.name} >= ${column.min}`);
4778
- } else if (column.max) {
4792
+ } else if (column.max !== void 0) {
4779
4793
  checks.push(`${column.name} <= ${column.max}`);
4780
4794
  }
4781
4795
  if (column.type === "integer") {
@@ -4824,7 +4838,7 @@ var createGtfsTables = (db) => {
4824
4838
  var createGtfsIndexes = (db) => {
4825
4839
  for (const model of Object.values(models_exports)) {
4826
4840
  if (!model.schema) {
4827
- return;
4841
+ continue;
4828
4842
  }
4829
4843
  for (const column of model.schema) {
4830
4844
  if (column.index) {