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.
package/dist/index.d.ts CHANGED
@@ -619,13 +619,24 @@ interface RunPiece {
619
619
  end_trip_id: string;
620
620
  end_trip_position: number | null;
621
621
  }
622
+ interface ServiceAlertInformedEntity {
623
+ alert_id: string;
624
+ stop_id: string | null;
625
+ route_id: string | null;
626
+ route_type: number | null;
627
+ trip_id: string | null;
628
+ direction_id: number | null;
629
+ created_timestamp: UnixTimestamp;
630
+ expiration_timestamp: UnixTimestamp;
631
+ }
622
632
  interface ServiceAlert {
623
633
  id: string;
634
+ active_period: string | null;
624
635
  cause: string | null;
625
636
  effect: string | null;
626
637
  url: string | null;
627
- start_time: string;
628
- end_time: string;
638
+ start_time: string | null;
639
+ end_time: string | null;
629
640
  header_text: string;
630
641
  description_text: string;
631
642
  tts_header_text: string | null;
@@ -633,6 +644,7 @@ interface ServiceAlert {
633
644
  severity_level: string | null;
634
645
  created_timestamp: UnixTimestamp;
635
646
  expiration_timestamp: UnixTimestamp;
647
+ informed_entities: ServiceAlertInformedEntity[];
636
648
  }
637
649
  interface StopTimeUpdate {
638
650
  trip_id: string | null;
@@ -965,7 +977,25 @@ declare function getTripUpdates<Fields extends keyof TripUpdate>(query?: SqlWher
965
977
 
966
978
  declare function getVehiclePositions<Fields extends keyof VehiclePosition>(query?: SqlWhere, fields?: Fields[], orderBy?: SqlOrderBy, options?: QueryOptions): QueryResult<VehiclePosition, Fields>[];
967
979
 
968
- declare function getServiceAlerts<Fields extends keyof ServiceAlert>(query?: SqlWhere, fields?: Fields[], orderBy?: SqlOrderBy, options?: QueryOptions): QueryResult<ServiceAlert, Fields>[];
980
+ declare function getServiceAlerts<Fields extends keyof ServiceAlert>(query?: SqlWhere, fields?: Fields[], orderBy?: SqlOrderBy, options?: QueryOptions): {
981
+ informed_entities: ServiceAlertInformedEntity[];
982
+ start_time: string | null;
983
+ end_time: string | null;
984
+ id: string;
985
+ created_timestamp: UnixTimestamp;
986
+ expiration_timestamp: UnixTimestamp;
987
+ active_period: string | null;
988
+ cause: string | null;
989
+ effect: string | null;
990
+ url: string | null;
991
+ header_text: string;
992
+ description_text: string;
993
+ tts_header_text: string | null;
994
+ tts_description_text: string | null;
995
+ severity_level: string | null;
996
+ }[];
997
+
998
+ declare function getServiceAlertInformedEntities<Fields extends keyof ServiceAlertInformedEntity>(query?: SqlWhere, fields?: Fields[], orderBy?: SqlOrderBy, options?: QueryOptions): QueryResult<ServiceAlertInformedEntity, Fields>[];
969
999
 
970
1000
  declare function getDeadheads<Fields extends keyof Deadhead>(query?: SqlWhere, fields?: Fields[], orderBy?: SqlOrderBy, options?: QueryOptions): QueryResult<Deadhead, Fields>[];
971
1001
 
@@ -977,4 +1007,4 @@ declare function getRunEvents<Fields extends keyof RunEvent>(query?: SqlWhere, f
977
1007
 
978
1008
  declare function getRunsPieces<Fields extends keyof RunPiece>(query?: SqlWhere, fields?: Fields[], orderBy?: SqlOrderBy, options?: QueryOptions): QueryResult<RunPiece, Fields>[];
979
1009
 
980
- export { type Agency, type Area, type Attribution, type BoardAlight, type BookingRule, type Calendar, type CalendarAttribute, type CalendarDate, type Config, type ConfigAgency, type Deadhead, type DeadheadTime, type Direction, type FareAttribute, type FareLegRule, type FareMedia, type FareProduct, type FareRule, type FareTransferRule, type FeedInfo, type Frequency, GtfsError, GtfsErrorCategory, GtfsErrorCode, type GtfsWarning, GtfsWarningCode, type ImportReport, type JoinOptions, type Level, type Location, type LocationGroup, type LocationGroupStop, type Model, type ModelColumn, type Network, type OpsLocation, type Pathway, type QueryOptions, type QueryResult, type RideFeedInfo, type RiderCategory, type RiderTrip, type Ridership, type Route, type RouteAttribute, type RouteNetwork, type RunEvent, type RunPiece, type ServiceAlert, type Shape, type SqlOrderBy, type SqlValue, type SqlWhere, type Stop, type StopArea, type StopAttribute, type StopTime, type StopTimeUpdate, type TableNames, type Timeframe, type Timetable, type TimetableNote, type TimetableNotesReference, type TimetablePage, type TimetableStopOrder, type Transfer, type Translation, type Trip, type TripCapacity, type TripUpdate, type TripsDatedVehicleJourney, type UnixTimestamp, type VehiclePosition, advancedQuery, closeDb, deleteDb, exportGtfs, formatGtfsError, generateFolderName, getAgencies, getAreas, getAttributions, getBoardAlights, getBookingRules, getCalendarAttributes, getCalendarDates, getCalendars, getDeadheadTimes, getDeadheads, getDirections, getFareAttributes, getFareLegRules, getFareMedia, getFareProducts, getFareRules, getFareTransferRules, getFeedInfo, getFrequencies, getLevels, getLocationGroupStops, getLocationGroups, getLocations, getNetworks, getOpsLocations, getPathways, getRideFeedInfo, getRiderCategories, getRiderTrips, getRidership, getRouteAttributes, getRouteNetworks, getRoutes, getRunEvents, getRunsPieces, getServiceAlerts, getServiceIdsByDate, getShapes, getShapesAsGeoJSON, getStopAreas, getStopAttributes, getStopTimeUpdates, getStops, getStopsAsGeoJSON, getStoptimes, getTimeframes, getTimetableNotes, getTimetableNotesReferences, getTimetablePages, getTimetableStopOrders, getTimetables, getTransfers, getTranslations, getTripCapacities, getTripUpdates, getTrips, getTripsDatedVehicleJourneys, getVehiclePositions, importGtfs, isGtfsError, isGtfsValidationError, openDb, prepDirectory, untildify, unzip, updateGtfsRealtime };
1010
+ export { type Agency, type Area, type Attribution, type BoardAlight, type BookingRule, type Calendar, type CalendarAttribute, type CalendarDate, type Config, type ConfigAgency, type Deadhead, type DeadheadTime, type Direction, type FareAttribute, type FareLegRule, type FareMedia, type FareProduct, type FareRule, type FareTransferRule, type FeedInfo, type Frequency, GtfsError, GtfsErrorCategory, GtfsErrorCode, type GtfsWarning, GtfsWarningCode, type ImportReport, type JoinOptions, type Level, type Location, type LocationGroup, type LocationGroupStop, type Model, type ModelColumn, type Network, type OpsLocation, type Pathway, type QueryOptions, type QueryResult, type RideFeedInfo, type RiderCategory, type RiderTrip, type Ridership, type Route, type RouteAttribute, type RouteNetwork, type RunEvent, type RunPiece, type ServiceAlert, type ServiceAlertInformedEntity, type Shape, type SqlOrderBy, type SqlValue, type SqlWhere, type Stop, type StopArea, type StopAttribute, type StopTime, type StopTimeUpdate, type TableNames, type Timeframe, type Timetable, type TimetableNote, type TimetableNotesReference, type TimetablePage, type TimetableStopOrder, type Transfer, type Translation, type Trip, type TripCapacity, type TripUpdate, type TripsDatedVehicleJourney, type UnixTimestamp, type VehiclePosition, advancedQuery, closeDb, deleteDb, exportGtfs, formatGtfsError, generateFolderName, getAgencies, getAreas, getAttributions, getBoardAlights, getBookingRules, getCalendarAttributes, getCalendarDates, getCalendars, getDeadheadTimes, getDeadheads, getDirections, getFareAttributes, getFareLegRules, getFareMedia, getFareProducts, getFareRules, getFareTransferRules, getFeedInfo, getFrequencies, getLevels, getLocationGroupStops, getLocationGroups, getLocations, getNetworks, getOpsLocations, getPathways, getRideFeedInfo, getRiderCategories, getRiderTrips, getRidership, getRouteAttributes, getRouteNetworks, getRoutes, getRunEvents, getRunsPieces, getServiceAlertInformedEntities, getServiceAlerts, getServiceIdsByDate, getShapes, getShapesAsGeoJSON, getStopAreas, getStopAttributes, getStopTimeUpdates, getStops, getStopsAsGeoJSON, getStoptimes, getTimeframes, getTimetableNotes, getTimetableNotesReferences, getTimetablePages, getTimetableStopOrders, getTimetables, getTransfers, getTranslations, getTripCapacities, getTripUpdates, getTrips, getTripsDatedVehicleJourneys, getVehiclePositions, importGtfs, isGtfsError, isGtfsValidationError, openDb, prepDirectory, untildify, unzip, updateGtfsRealtime };
package/dist/index.js CHANGED
@@ -1006,6 +1006,7 @@ var routes = {
1006
1006
  {
1007
1007
  name: "agency_id",
1008
1008
  type: "text",
1009
+ index: true,
1009
1010
  prefix: true
1010
1011
  },
1011
1012
  {
@@ -1258,7 +1259,8 @@ var stops = {
1258
1259
  },
1259
1260
  {
1260
1261
  name: "stop_code",
1261
- type: "text"
1262
+ type: "text",
1263
+ index: true
1262
1264
  },
1263
1265
  {
1264
1266
  name: "stop_name",
@@ -1544,6 +1546,14 @@ var trips = {
1544
1546
  type: "integer",
1545
1547
  min: 0,
1546
1548
  max: 2
1549
+ },
1550
+ {
1551
+ name: "safe_duration_factor",
1552
+ type: "real"
1553
+ },
1554
+ {
1555
+ name: "safe_duration_offset",
1556
+ type: "real"
1547
1557
  }
1548
1558
  ]
1549
1559
  };
@@ -2752,16 +2762,14 @@ var serviceAlerts = {
2752
2762
  {
2753
2763
  name: "start_time",
2754
2764
  type: "text",
2755
- required: true,
2756
2765
  source: "alert.activePeriod[0].start",
2757
- default: ""
2766
+ default: null
2758
2767
  },
2759
2768
  {
2760
2769
  name: "end_time",
2761
2770
  type: "text",
2762
- required: true,
2763
2771
  source: "alert.activePeriod[0].end",
2764
- default: ""
2772
+ default: null
2765
2773
  },
2766
2774
  {
2767
2775
  name: "header_text",
@@ -2821,7 +2829,7 @@ var serviceAlertInformedEntities = {
2821
2829
  {
2822
2830
  name: "stop_id",
2823
2831
  type: "text",
2824
- index: true,
2832
+ primary: true,
2825
2833
  source: "stopId",
2826
2834
  default: null,
2827
2835
  prefix: true
@@ -2829,7 +2837,7 @@ var serviceAlertInformedEntities = {
2829
2837
  {
2830
2838
  name: "route_id",
2831
2839
  type: "text",
2832
- index: true,
2840
+ primary: true,
2833
2841
  source: "routeId",
2834
2842
  default: null,
2835
2843
  prefix: true
@@ -2837,14 +2845,14 @@ var serviceAlertInformedEntities = {
2837
2845
  {
2838
2846
  name: "route_type",
2839
2847
  type: "integer",
2840
- index: true,
2848
+ primary: true,
2841
2849
  source: "routeType",
2842
2850
  default: null
2843
2851
  },
2844
2852
  {
2845
2853
  name: "trip_id",
2846
2854
  type: "text",
2847
- index: true,
2855
+ primary: true,
2848
2856
  source: "trip.tripId",
2849
2857
  default: null,
2850
2858
  prefix: true
@@ -2852,7 +2860,7 @@ var serviceAlertInformedEntities = {
2852
2860
  {
2853
2861
  name: "direction_id",
2854
2862
  type: "integer",
2855
- index: true,
2863
+ primary: true,
2856
2864
  source: "directionId",
2857
2865
  default: null
2858
2866
  },
@@ -3369,7 +3377,8 @@ var passengerEvents = {
3369
3377
  {
3370
3378
  name: "trip_stop_sequence",
3371
3379
  type: "integer",
3372
- min: 1
3380
+ min: 1,
3381
+ required: true
3373
3382
  },
3374
3383
  {
3375
3384
  name: "scheduled_stop_sequence",
@@ -3595,7 +3604,8 @@ var stopVisits = {
3595
3604
  },
3596
3605
  {
3597
3606
  name: "ramp_deployed_time",
3598
- type: "text"
3607
+ type: "real",
3608
+ min: 0
3599
3609
  },
3600
3610
  {
3601
3611
  name: "ramp_failure",
@@ -3603,12 +3613,12 @@ var stopVisits = {
3603
3613
  },
3604
3614
  {
3605
3615
  name: "kneel_deployed_time",
3606
- type: "integer",
3616
+ type: "real",
3607
3617
  min: 0
3608
3618
  },
3609
3619
  {
3610
3620
  name: "lift_deployed_time",
3611
- type: "integer",
3621
+ type: "real",
3612
3622
  min: 0
3613
3623
  },
3614
3624
  {
@@ -4270,7 +4280,9 @@ function deleteDb(db = null) {
4270
4280
  db = dbs[Object.keys(dbs)[0]];
4271
4281
  }
4272
4282
  db.close();
4273
- fs.unlinkSync(db.name);
4283
+ if (db.name !== ":memory:") {
4284
+ fs.unlinkSync(db.name);
4285
+ }
4274
4286
  delete dbs[db.name];
4275
4287
  }
4276
4288
 
@@ -4580,7 +4592,7 @@ function getTimestampColumnName(columnName) {
4580
4592
  return columnName.endsWith("time") ? `${columnName}stamp` : `${columnName}_timestamp`;
4581
4593
  }
4582
4594
  function applyPrefixToValue(value, columnShouldBePrefixed, prefix) {
4583
- if (!columnShouldBePrefixed || prefix === void 0 || value === null) {
4595
+ if (!columnShouldBePrefixed || prefix === void 0 || value === null || value === void 0) {
4584
4596
  return value;
4585
4597
  }
4586
4598
  return `${prefix}${value}`;
@@ -4643,13 +4655,15 @@ async function fetchGtfsRealtimeData(type, task) {
4643
4655
  try {
4644
4656
  const response = await fetch(urlConfig.url, {
4645
4657
  method: "GET",
4658
+ redirect: "follow",
4646
4659
  headers: {
4660
+ "User-Agent": "node-gtfs",
4647
4661
  ...urlConfig.headers ?? {},
4648
4662
  "Accept-Encoding": "gzip"
4649
4663
  },
4650
4664
  signal: task.downloadTimeout ? AbortSignal.timeout(task.downloadTimeout) : void 0
4651
4665
  });
4652
- if (response.status !== 200) {
4666
+ if (!response.ok) {
4653
4667
  throw new GtfsError(`HTTP ${response.status}: ${response.statusText}`, {
4654
4668
  code: "GTFS_DOWNLOAD_HTTP" /* GTFS_DOWNLOAD_HTTP */,
4655
4669
  category: "download" /* DOWNLOAD */,
@@ -4722,12 +4736,17 @@ function createServiceAlertsProcessor(db, task) {
4722
4736
  db,
4723
4737
  serviceAlertInformedEntities
4724
4738
  );
4739
+ const deleteInformedEntitiesStmt = db.prepare(
4740
+ `DELETE FROM ${serviceAlertInformedEntities.filenameBase} WHERE alert_id = ?`
4741
+ );
4725
4742
  return async (batch) => {
4726
4743
  let recordCount = 0;
4727
4744
  let errorCount = 0;
4728
4745
  db.transaction(() => {
4729
4746
  for (const entity of batch) {
4730
4747
  try {
4748
+ const alertId = applyPrefixToValue(entity.id, true, task.prefix);
4749
+ deleteInformedEntitiesStmt.run(alertId);
4731
4750
  const alertValues = serviceAlerts.schema.map((column) => prepareRealtimeFieldValue(entity, column, task));
4732
4751
  alertStmt.run(alertValues);
4733
4752
  recordCount++;
@@ -4760,6 +4779,9 @@ function createTripUpdatesProcessor(db, task) {
4760
4779
  db,
4761
4780
  stopTimeUpdates
4762
4781
  );
4782
+ const deleteStopTimesByTripStmt = db.prepare(
4783
+ `DELETE FROM ${stopTimeUpdates.filenameBase} WHERE trip_id = ? AND trip_start_time IS ?`
4784
+ );
4763
4785
  return async (batch) => {
4764
4786
  let recordCount = 0;
4765
4787
  let errorCount = 0;
@@ -4770,6 +4792,15 @@ function createTripUpdatesProcessor(db, task) {
4770
4792
  tripUpdateStmt.run(tripUpdateValues);
4771
4793
  recordCount++;
4772
4794
  if (entity.tripUpdate?.stopTimeUpdate?.length) {
4795
+ const tripId = applyPrefixToValue(
4796
+ entity.tripUpdate?.trip?.tripId ?? null,
4797
+ true,
4798
+ task.prefix
4799
+ );
4800
+ const tripStartTime = entity.tripUpdate?.trip?.startTime ?? null;
4801
+ if (tripId !== null) {
4802
+ deleteStopTimesByTripStmt.run(tripId, tripStartTime);
4803
+ }
4773
4804
  for (const stopTimeUpdate of entity.tripUpdate.stopTimeUpdate) {
4774
4805
  stopTimeUpdate.parent = entity;
4775
4806
  const stopTimeValues = stopTimeUpdates.schema.map(
@@ -4849,41 +4880,30 @@ async function updateGtfsRealtimeData(task) {
4849
4880
  tripupdates: 0,
4850
4881
  vehiclepositions: 0
4851
4882
  };
4852
- const processingPromises = [];
4853
4883
  if (alertsData?.entity?.length) {
4854
- processingPromises.push(
4855
- processBatch(
4856
- alertsData.entity,
4857
- BATCH_SIZE,
4858
- createServiceAlertsProcessor(db, task)
4859
- ).then((result) => {
4860
- recordCounts.alerts = result.recordCount;
4861
- })
4884
+ const result = await processBatch(
4885
+ alertsData.entity,
4886
+ BATCH_SIZE,
4887
+ createServiceAlertsProcessor(db, task)
4862
4888
  );
4889
+ recordCounts.alerts = result.recordCount;
4863
4890
  }
4864
4891
  if (tripUpdatesData?.entity?.length) {
4865
- processingPromises.push(
4866
- processBatch(
4867
- tripUpdatesData.entity,
4868
- BATCH_SIZE,
4869
- createTripUpdatesProcessor(db, task)
4870
- ).then((result) => {
4871
- recordCounts.tripupdates = result.recordCount;
4872
- })
4892
+ const result = await processBatch(
4893
+ tripUpdatesData.entity,
4894
+ BATCH_SIZE,
4895
+ createTripUpdatesProcessor(db, task)
4873
4896
  );
4897
+ recordCounts.tripupdates = result.recordCount;
4874
4898
  }
4875
4899
  if (vehiclePositionsData?.entity?.length) {
4876
- processingPromises.push(
4877
- processBatch(
4878
- vehiclePositionsData.entity,
4879
- BATCH_SIZE,
4880
- createVehiclePositionsProcessor(db, task)
4881
- ).then((result) => {
4882
- recordCounts.vehiclepositions = result.recordCount;
4883
- })
4900
+ const result = await processBatch(
4901
+ vehiclePositionsData.entity,
4902
+ BATCH_SIZE,
4903
+ createVehiclePositionsProcessor(db, task)
4884
4904
  );
4905
+ recordCounts.vehiclepositions = result.recordCount;
4885
4906
  }
4886
- await Promise.all(processingPromises);
4887
4907
  task.log(
4888
4908
  `GTFS-Realtime import complete: ${recordCounts.alerts} alerts, ${recordCounts.tripupdates} trip updates, ${recordCounts.vehiclepositions} vehicle positions`
4889
4909
  );
@@ -4992,10 +5012,14 @@ var downloadGtfsFiles = async (task) => {
4992
5012
  try {
4993
5013
  const response = await fetch(task.url, {
4994
5014
  method: "GET",
4995
- headers: task.headers || {},
5015
+ redirect: "follow",
5016
+ headers: {
5017
+ "User-Agent": "node-gtfs",
5018
+ ...task.headers
5019
+ },
4996
5020
  signal: task.downloadTimeout ? AbortSignal.timeout(task.downloadTimeout) : void 0
4997
5021
  });
4998
- if (response.status !== 200) {
5022
+ if (!response.ok) {
4999
5023
  throw new GtfsError(
5000
5024
  `Unable to download GTFS from ${task.url}. Got status ${response.status}.`,
5001
5025
  {
@@ -5108,18 +5132,18 @@ var extractGtfsFiles = async (task) => {
5108
5132
  var createGtfsTables = (db) => {
5109
5133
  for (const model of Object.values(models_exports)) {
5110
5134
  if (!model.schema) {
5111
- return;
5135
+ continue;
5112
5136
  }
5113
5137
  const sqlColumnCreateStatements = [];
5114
5138
  for (const column of model.schema) {
5115
5139
  const checks = [];
5116
- if (column.min !== void 0 && column.max) {
5140
+ if (column.min !== void 0 && column.max !== void 0) {
5117
5141
  checks.push(
5118
5142
  `${column.name} >= ${column.min} AND ${column.name} <= ${column.max}`
5119
5143
  );
5120
- } else if (column.min) {
5144
+ } else if (column.min !== void 0) {
5121
5145
  checks.push(`${column.name} >= ${column.min}`);
5122
- } else if (column.max) {
5146
+ } else if (column.max !== void 0) {
5123
5147
  checks.push(`${column.name} <= ${column.max}`);
5124
5148
  }
5125
5149
  if (column.type === "integer") {
@@ -5168,7 +5192,7 @@ var createGtfsTables = (db) => {
5168
5192
  var createGtfsIndexes = (db) => {
5169
5193
  for (const model of Object.values(models_exports)) {
5170
5194
  if (!model.schema) {
5171
- return;
5195
+ continue;
5172
5196
  }
5173
5197
  for (const column of model.schema) {
5174
5198
  if (column.index) {
@@ -6300,7 +6324,7 @@ function getStopsAsGeoJSON(query = {}, options = {}) {
6300
6324
  routes2,
6301
6325
  (route) => route?.route_short_name ? Number.parseInt(route.route_short_name, 10) : 0
6302
6326
  ),
6303
- agency_name: agencies[0].agency_name
6327
+ agency_name: agencies[0]?.agency_name ?? null
6304
6328
  };
6305
6329
  });
6306
6330
  const filteredStops = preparedStops.filter((stop) => stop.routes.length > 0);
@@ -6629,15 +6653,66 @@ function getVehiclePositions(query = {}, fields = [], orderBy2 = [], options = {
6629
6653
  }
6630
6654
 
6631
6655
  // src/lib/gtfs-realtime/service-alerts.ts
6656
+ var ENTITY_COLUMNS = /* @__PURE__ */ new Set([
6657
+ "alert_id",
6658
+ "stop_id",
6659
+ "route_id",
6660
+ "route_type",
6661
+ "trip_id",
6662
+ "direction_id"
6663
+ ]);
6632
6664
  function getServiceAlerts(query = {}, fields = [], orderBy2 = [], options = {}) {
6633
6665
  const db = options.db ?? openDb();
6634
6666
  const tableName = "service_alerts";
6635
6667
  const joinTableName = "service_alert_informed_entities";
6636
6668
  const selectClause = formatSelectClause(fields);
6669
+ const orderByClause = formatOrderByClause(orderBy2);
6670
+ const alertQuery = {};
6671
+ const entityQuery = {};
6672
+ for (const [key, value] of Object.entries(query)) {
6673
+ if (ENTITY_COLUMNS.has(key)) {
6674
+ entityQuery[key] = value;
6675
+ } else {
6676
+ alertQuery[key] = value;
6677
+ }
6678
+ }
6679
+ const whereClause = formatWhereClauses(alertQuery);
6680
+ const alerts = db.prepare(
6681
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
6682
+ ).all();
6683
+ const alertIds = alerts.map((alert) => alert.id);
6684
+ if (alertIds.length === 0) {
6685
+ return [];
6686
+ }
6687
+ const alertIdPlaceholders = alertIds.map(() => "?").join(", ");
6688
+ const entityFilterClause = formatWhereClauses(entityQuery);
6689
+ const entityWhereClause = entityFilterClause ? `${entityFilterClause} AND alert_id IN (${alertIdPlaceholders})` : `WHERE alert_id IN (${alertIdPlaceholders})`;
6690
+ const entities = db.prepare(`SELECT * FROM ${joinTableName} ${entityWhereClause};`).all(...alertIds);
6691
+ const entitiesByAlertId = /* @__PURE__ */ new Map();
6692
+ for (const entity of entities) {
6693
+ const group = entitiesByAlertId.get(entity.alert_id);
6694
+ if (group) {
6695
+ group.push(entity);
6696
+ } else {
6697
+ entitiesByAlertId.set(entity.alert_id, [entity]);
6698
+ }
6699
+ }
6700
+ const matchedAlerts = Object.keys(entityQuery).length > 0 ? alerts.filter((alert) => entitiesByAlertId.has(alert.id)) : alerts;
6701
+ return matchedAlerts.map((alert) => ({
6702
+ ...alert,
6703
+ informed_entities: entitiesByAlertId.get(alert.id) ?? []
6704
+ }));
6705
+ }
6706
+
6707
+ // src/lib/gtfs-realtime/service-alert-informed-entities.ts
6708
+ function getServiceAlertInformedEntities(query = {}, fields = [], orderBy2 = [], options = {}) {
6709
+ const db = options.db ?? openDb();
6710
+ const tableName = "service_alert_informed_entities";
6711
+ const selectClause = formatSelectClause(fields);
6637
6712
  const whereClause = formatWhereClauses(query);
6638
6713
  const orderByClause = formatOrderByClause(orderBy2);
6639
6714
  return db.prepare(
6640
- `${selectClause} FROM ${tableName} INNER JOIN ${joinTableName} ON ${tableName}.id=${joinTableName}.alert_id ${whereClause} ${orderByClause};`
6715
+ `${selectClause} FROM ${tableName} ${whereClause} ${orderByClause};`
6641
6716
  ).all();
6642
6717
  }
6643
6718
 
@@ -6746,6 +6821,7 @@ export {
6746
6821
  getRoutes,
6747
6822
  getRunEvents,
6748
6823
  getRunsPieces,
6824
+ getServiceAlertInformedEntities,
6749
6825
  getServiceAlerts,
6750
6826
  getServiceIdsByDate,
6751
6827
  getShapes,