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.
- package/README.md +65 -8
- package/dist/bin/gtfs-export.js +16 -14
- package/dist/bin/gtfs-export.js.map +1 -1
- package/dist/bin/gtfs-import.js +63 -49
- package/dist/bin/gtfs-import.js.map +1 -1
- package/dist/bin/gtfsrealtime-update.js +43 -37
- package/dist/bin/gtfsrealtime-update.js.map +1 -1
- package/dist/index.d.ts +34 -4
- package/dist/index.js +120 -52
- package/dist/index.js.map +1 -1
- package/dist/models/models.d.ts +48 -10
- package/dist/models/models.js +16 -14
- package/dist/models/models.js.map +1 -1
- package/package.json +8 -6
package/dist/bin/gtfs-import.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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: "
|
|
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: "
|
|
3736
|
+
type: "real",
|
|
3735
3737
|
min: 0
|
|
3736
3738
|
},
|
|
3737
3739
|
{
|
|
3738
3740
|
name: "lift_deployed_time",
|
|
3739
|
-
type: "
|
|
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.
|
|
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
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
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
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
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
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
4841
|
+
continue;
|
|
4828
4842
|
}
|
|
4829
4843
|
for (const column of model.schema) {
|
|
4830
4844
|
if (column.index) {
|