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.
@@ -122,21 +122,24 @@ var tripUpdates = {
122
122
  required: true,
123
123
  primary: true,
124
124
  index: true,
125
- source: "id"
125
+ source: "id",
126
+ prefix: true
126
127
  },
127
128
  {
128
129
  name: "vehicle_id",
129
130
  type: "text",
130
131
  index: true,
131
132
  source: "tripUpdate.vehicle.id",
132
- default: null
133
+ default: null,
134
+ prefix: true
133
135
  },
134
136
  {
135
137
  name: "trip_id",
136
138
  type: "text",
137
139
  index: true,
138
140
  source: "tripUpdate.trip.tripId",
139
- default: null
141
+ default: null,
142
+ prefix: true
140
143
  },
141
144
  {
142
145
  name: "trip_start_time",
@@ -155,7 +158,8 @@ var tripUpdates = {
155
158
  type: "text",
156
159
  index: true,
157
160
  source: "tripUpdate.trip.routeId",
158
- default: null
161
+ default: null,
162
+ prefix: true
159
163
  },
160
164
  {
161
165
  name: "start_date",
@@ -198,7 +202,8 @@ var stopTimeUpdates = {
198
202
  type: "text",
199
203
  index: true,
200
204
  source: "parent.tripUpdate.trip.tripId",
201
- default: null
205
+ default: null,
206
+ prefix: true
202
207
  },
203
208
  {
204
209
  name: "trip_start_time",
@@ -217,14 +222,16 @@ var stopTimeUpdates = {
217
222
  type: "text",
218
223
  index: true,
219
224
  source: "parent.tripUpdate.trip.routeId",
220
- default: null
225
+ default: null,
226
+ prefix: true
221
227
  },
222
228
  {
223
229
  name: "stop_id",
224
230
  type: "text",
225
231
  index: true,
226
232
  source: "stopId",
227
- default: null
233
+ default: null,
234
+ prefix: true
228
235
  },
229
236
  {
230
237
  name: "stop_sequence",
@@ -286,7 +293,8 @@ var vehiclePositions = {
286
293
  required: true,
287
294
  primary: true,
288
295
  index: true,
289
- source: "id"
296
+ source: "id",
297
+ prefix: true
290
298
  },
291
299
  {
292
300
  name: "bearing",
@@ -328,7 +336,8 @@ var vehiclePositions = {
328
336
  type: "text",
329
337
  index: true,
330
338
  source: "vehicle.trip.tripId",
331
- default: null
339
+ default: null,
340
+ prefix: true
332
341
  },
333
342
  {
334
343
  name: "trip_start_date",
@@ -373,7 +382,8 @@ var vehiclePositions = {
373
382
  type: "text",
374
383
  index: true,
375
384
  source: "vehicle.vehicle.id",
376
- default: null
385
+ default: null,
386
+ prefix: true
377
387
  },
378
388
  {
379
389
  name: "vehicle_label",
@@ -423,7 +433,8 @@ var serviceAlerts = {
423
433
  required: true,
424
434
  primary: true,
425
435
  index: true,
426
- source: "id"
436
+ source: "id",
437
+ prefix: true
427
438
  },
428
439
  {
429
440
  name: "active_period",
@@ -512,21 +523,24 @@ var serviceAlertInformedEntities = {
512
523
  type: "text",
513
524
  required: true,
514
525
  primary: true,
515
- source: "parent.id"
526
+ source: "parent.id",
527
+ prefix: true
516
528
  },
517
529
  {
518
530
  name: "stop_id",
519
531
  type: "text",
520
532
  index: true,
521
533
  source: "stopId",
522
- default: null
534
+ default: null,
535
+ prefix: true
523
536
  },
524
537
  {
525
538
  name: "route_id",
526
539
  type: "text",
527
540
  index: true,
528
541
  source: "routeId",
529
- default: null
542
+ default: null,
543
+ prefix: true
530
544
  },
531
545
  {
532
546
  name: "route_type",
@@ -540,7 +554,8 @@ var serviceAlertInformedEntities = {
540
554
  type: "text",
541
555
  index: true,
542
556
  source: "trip.tripId",
543
- default: null
557
+ default: null,
558
+ prefix: true
544
559
  },
545
560
  {
546
561
  name: "direction_id",
@@ -616,8 +631,8 @@ import { feature, featureCollection } from "@turf/helpers";
616
631
  // src/lib/import-gtfs-realtime.ts
617
632
  import pluralize from "pluralize";
618
633
  import GtfsRealtimeBindings from "gtfs-realtime-bindings";
619
- import sqlString2 from "sqlstring-sqlite";
620
634
  import mapSeries from "promise-map-series";
635
+ import { get } from "lodash-es";
621
636
 
622
637
  // src/lib/utils.ts
623
638
  import sqlString from "sqlstring-sqlite";
@@ -654,39 +669,14 @@ function convertLongTimeToDate(longDate) {
654
669
  Long.fromBits(low, high, unsigned).toNumber() * 1e3
655
670
  ).toISOString();
656
671
  }
657
-
658
- // src/lib/import-gtfs-realtime.ts
659
- function getNestedProperty(obj, defaultValue, path2) {
660
- if (path2 === void 0) return defaultValue;
661
- const arr = path2.split(".");
662
- while (arr.length) {
663
- const nextKey = arr.shift();
664
- if (nextKey === void 0) {
665
- return defaultValue;
666
- } else if (obj == null) {
667
- return defaultValue;
668
- } else if (nextKey?.includes("[")) {
669
- const arrayKey = nextKey.match(/(\w*)\[(\d+)\]/);
670
- if (arrayKey === null) {
671
- return defaultValue;
672
- }
673
- if (obj[arrayKey[1]] === void 0) {
674
- return defaultValue;
675
- }
676
- if (obj[arrayKey[1]][arrayKey[2]] === void 0) {
677
- return defaultValue;
678
- }
679
- obj = obj[arrayKey[1]][arrayKey[2]];
680
- } else {
681
- if (obj[nextKey] === void 0) {
682
- return defaultValue;
683
- }
684
- obj = obj[nextKey];
685
- }
672
+ function applyPrefixToValue(value, columnShouldBePrefixed, prefix) {
673
+ if (!columnShouldBePrefixed || prefix === void 0 || value === null) {
674
+ return value;
686
675
  }
687
- if (obj?.__isLong__) return convertLongTimeToDate(obj);
688
- return obj;
676
+ return `${prefix}${value}`;
689
677
  }
678
+
679
+ // src/lib/import-gtfs-realtime.ts
690
680
  async function fetchGtfsRealtimeData(urlConfig, task) {
691
681
  task.log(`Downloading GTFS-Realtime from ${urlConfig.url}`);
692
682
  const response = await fetch(urlConfig.url, {
@@ -744,100 +734,117 @@ function prepareRealtimeFieldValue(entity, column, task) {
744
734
  if (column.name === "expiration_timestamp") {
745
735
  return task.currentTimestamp + task.gtfsRealtimeExpirationSeconds;
746
736
  }
747
- const value = getNestedProperty(entity, column.default, column.source);
748
- if (column.type === "json") {
749
- return sqlString2.escape(JSON.stringify(value));
750
- }
751
- return sqlString2.escape(value);
737
+ const baseValue = column.source === void 0 ? column.default : get(entity, column.source, column.default);
738
+ const timeAdjustedValue = baseValue?.__isLong__ ? convertLongTimeToDate(baseValue) : baseValue;
739
+ const prefixedValue = applyPrefixToValue(
740
+ timeAdjustedValue,
741
+ column.prefix,
742
+ task.prefix
743
+ );
744
+ return column.type === "json" ? JSON.stringify(prefixedValue) : prefixedValue;
752
745
  }
753
746
  async function processRealtimeAlerts(db, gtfsRealtimeData, task) {
754
- task.log(`Download successful`);
747
+ const alertStmt = db.prepare(
748
+ `REPLACE INTO ${serviceAlerts.filenameBase} (${serviceAlerts.schema.map((column) => column.name).join(
749
+ ", "
750
+ )}) VALUES (${serviceAlerts.schema.map(() => "?").join(", ")})`
751
+ );
752
+ const informedEntityStmt = db.prepare(
753
+ `REPLACE INTO ${serviceAlertInformedEntities.filenameBase} (${serviceAlertInformedEntities.schema.map((column) => column.name).join(
754
+ ", "
755
+ )}) VALUES (${serviceAlertInformedEntities.schema.map(() => "?").join(", ")})`
756
+ );
755
757
  let totalLineCount = 0;
756
- for (const entity of gtfsRealtimeData.entity) {
757
- const fieldValues = serviceAlerts.schema.map(
758
- (column) => prepareRealtimeFieldValue(entity, column, task)
759
- );
760
- try {
761
- db.prepare(
762
- `REPLACE INTO ${serviceAlerts.filenameBase} (${serviceAlerts.schema.map((column) => column.name).join(", ")}) VALUES (${fieldValues.join(", ")})`
763
- ).run();
764
- } catch (error) {
765
- task.logWarning(`Import error: ${error.message}`);
766
- }
767
- if (!entity.alert.informedEntity || entity.alert.informedEntity.length === 0) {
768
- task.logWarning(
769
- `Import error: No informed entities found for alert id=${entity.id}`
758
+ db.transaction(() => {
759
+ for (const entity of gtfsRealtimeData.entity) {
760
+ const fieldValues = serviceAlerts.schema.map(
761
+ (column) => prepareRealtimeFieldValue(entity, column, task)
770
762
  );
771
- } else {
772
- const informedEntities = [];
773
- for (const informedEntity of entity.alert.informedEntity) {
774
- informedEntity.parent = entity;
775
- const subValues = serviceAlertInformedEntities.schema.map(
776
- (column) => prepareRealtimeFieldValue(informedEntity, column, task)
777
- );
778
- informedEntities.push(`(${subValues.join(", ")})`);
779
- totalLineCount++;
780
- }
781
763
  try {
782
- db.prepare(
783
- `REPLACE INTO ${serviceAlertInformedEntities.filenameBase} (${serviceAlertInformedEntities.schema.map((column) => column.name).join(", ")}) VALUES ${informedEntities.join(", ")}`
784
- ).run();
764
+ alertStmt.run(fieldValues);
765
+ if (entity.alert.informedEntity?.length) {
766
+ const informedEntities = entity.alert.informedEntity.map(
767
+ (informedEntity) => {
768
+ informedEntity.parent = entity;
769
+ return serviceAlertInformedEntities.schema.map(
770
+ (column) => prepareRealtimeFieldValue(informedEntity, column, task)
771
+ );
772
+ }
773
+ );
774
+ for (const values of informedEntities) {
775
+ informedEntityStmt.run(values);
776
+ }
777
+ }
778
+ totalLineCount++;
785
779
  } catch (error) {
786
780
  task.logWarning(`Import error: ${error.message}`);
787
781
  }
788
782
  }
789
- task.log(`Importing - ${totalLineCount++} entries imported\r`, true);
790
- }
783
+ task.log(
784
+ `Importing - GTFS-Realtime service alerts - ${totalLineCount} entries imported\r`,
785
+ true
786
+ );
787
+ })();
791
788
  }
792
789
  async function processRealtimeTripUpdates(db, gtfsRealtimeData, task) {
793
- task.log(`Download successful`);
794
790
  let totalLineCount = 0;
795
- for (const entity of gtfsRealtimeData.entity) {
796
- const fieldValues = tripUpdates.schema.map(
797
- (column) => prepareRealtimeFieldValue(entity, column, task)
798
- );
799
- try {
800
- db.prepare(
801
- `REPLACE INTO ${tripUpdates.filenameBase} (${tripUpdates.schema.map((column) => column.name).join(", ")}) VALUES (${fieldValues.join(", ")})`
802
- ).run();
803
- } catch (error) {
804
- task.logWarning(`Import error: ${error.message}`);
805
- }
806
- const stopTimeUpdateArray = [];
807
- for (const stopTimeUpdate of entity.tripUpdate.stopTimeUpdate) {
808
- stopTimeUpdate.parent = entity;
809
- const subValues = stopTimeUpdates.schema.map(
810
- (column) => prepareRealtimeFieldValue(stopTimeUpdate, column, task)
811
- );
812
- stopTimeUpdateArray.push(`(${subValues.join(", ")})`);
813
- totalLineCount++;
814
- }
815
- try {
816
- db.prepare(
817
- `REPLACE INTO ${stopTimeUpdates.filenameBase} (${stopTimeUpdates.schema.map((column) => column.name).join(", ")}) VALUES ${stopTimeUpdateArray.join(", ")}`
818
- ).run();
819
- } catch (error) {
820
- task.logWarning(`Import error: ${error.message}`);
791
+ const tripUpdateStmt = db.prepare(
792
+ `REPLACE INTO ${tripUpdates.filenameBase} (${tripUpdates.schema.map((column) => column.name).join(
793
+ ", "
794
+ )}) VALUES (${tripUpdates.schema.map(() => "?").join(", ")})`
795
+ );
796
+ const stopTimeStmt = db.prepare(
797
+ `REPLACE INTO ${stopTimeUpdates.filenameBase} (${stopTimeUpdates.schema.map((column) => column.name).join(
798
+ ", "
799
+ )}) VALUES (${stopTimeUpdates.schema.map(() => "?").join(", ")})`
800
+ );
801
+ db.transaction(() => {
802
+ for (const entity of gtfsRealtimeData.entity) {
803
+ try {
804
+ const fieldValues = tripUpdates.schema.map(
805
+ (column) => prepareRealtimeFieldValue(entity, column, task)
806
+ );
807
+ tripUpdateStmt.run(fieldValues);
808
+ for (const stopTimeUpdate of entity.tripUpdate.stopTimeUpdate) {
809
+ stopTimeUpdate.parent = entity;
810
+ const values = stopTimeUpdates.schema.map(
811
+ (column) => prepareRealtimeFieldValue(stopTimeUpdate, column, task)
812
+ );
813
+ stopTimeStmt.run(values);
814
+ }
815
+ totalLineCount++;
816
+ } catch (error) {
817
+ task.logWarning(`Import error: ${error.message}`);
818
+ }
821
819
  }
822
- task.log(`Importing - ${totalLineCount++} entries imported\r`, true);
823
- }
820
+ task.log(
821
+ `Importing - GTFS-Realtime trip updates - ${totalLineCount} entries imported\r`,
822
+ true
823
+ );
824
+ })();
824
825
  }
825
826
  async function processRealtimeVehiclePositions(db, gtfsRealtimeData, task) {
826
- task.log(`Download successful`);
827
827
  let totalLineCount = 0;
828
- for (const entity of gtfsRealtimeData.entity) {
829
- const fieldValues = vehiclePositions.schema.map(
830
- (column) => prepareRealtimeFieldValue(entity, column, task)
831
- );
832
- try {
833
- db.prepare(
834
- `REPLACE INTO ${vehiclePositions.filenameBase} (${vehiclePositions.schema.map((column) => column.name).join(", ")}) VALUES (${fieldValues.join(", ")})`
835
- ).run();
836
- } catch (error) {
837
- task.logWarning(`Import error: ${error.message}`);
828
+ const vehiclePositionStmt = db.prepare(
829
+ `REPLACE INTO ${vehiclePositions.filenameBase} (${vehiclePositions.schema.map((column) => column.name).join(
830
+ ", "
831
+ )}) VALUES (${vehiclePositions.schema.map(() => "?").join(", ")})`
832
+ );
833
+ db.transaction(() => {
834
+ for (const entity of gtfsRealtimeData.entity) {
835
+ try {
836
+ const fieldValues = vehiclePositions.schema.map((column) => prepareRealtimeFieldValue(entity, column, task));
837
+ vehiclePositionStmt.run(fieldValues);
838
+ totalLineCount++;
839
+ } catch (error) {
840
+ task.logWarning(`Import error: ${error.message}`);
841
+ }
838
842
  }
839
- task.log(`Importing - ${totalLineCount++} entries imported\r`, true);
840
- }
843
+ task.log(
844
+ `Importing - GTFS-Realtime vehicle positions - ${totalLineCount} entries imported\r`,
845
+ true
846
+ );
847
+ })();
841
848
  }
842
849
  async function updateGtfsRealtimeData(task) {
843
850
  if (task.realtimeAlerts === void 0 && task.realtimeTripUpdates === void 0 && task.realtimeVehiclePositions === void 0) {
@@ -918,6 +925,7 @@ async function updateGtfsRealtime(initialConfig) {
918
925
  gtfsRealtimeExpirationSeconds: config.gtfsRealtimeExpirationSeconds,
919
926
  ignoreErrors: config.ignoreErrors,
920
927
  sqlitePath: config.sqlitePath,
928
+ prefix: agency2.prefix,
921
929
  currentTimestamp: Math.floor(Date.now() / 1e3),
922
930
  log: log(config),
923
931
  logWarning: logWarning(config),
@@ -954,12 +962,12 @@ async function updateGtfsRealtime(initialConfig) {
954
962
  import { without, compact as compact2 } from "lodash-es";
955
963
  import pluralize3 from "pluralize";
956
964
  import { stringify } from "csv-stringify";
957
- import sqlString3 from "sqlstring-sqlite";
965
+ import sqlString2 from "sqlstring-sqlite";
958
966
  import mapSeries3 from "promise-map-series";
959
967
  import untildify4 from "untildify";
960
968
 
961
969
  // src/lib/advancedQuery.ts
962
- import sqlString4 from "sqlstring-sqlite";
970
+ import sqlString3 from "sqlstring-sqlite";
963
971
 
964
972
  // src/lib/gtfs/routes.ts
965
973
  import { omit as omit3, pick } from "lodash-es";
@@ -973,7 +981,7 @@ import { omit as omit5, orderBy, pick as pick3 } from "lodash-es";
973
981
 
974
982
  // src/lib/gtfs/stop-times.ts
975
983
  import { omit as omit6 } from "lodash-es";
976
- import sqlString5 from "sqlstring-sqlite";
984
+ import sqlString4 from "sqlstring-sqlite";
977
985
 
978
986
  // src/bin/gtfsrealtime-update.ts
979
987
  var pe = new PrettyError();