gtfs-to-html 2.11.1 → 2.11.3
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 +1 -0
- package/dist/app/index.js +48 -16
- package/dist/app/index.js.map +1 -1
- package/dist/bin/gtfs-to-html.js +48 -16
- package/dist/bin/gtfs-to-html.js.map +1 -1
- package/dist/index.d.ts +18 -2
- package/dist/index.js +48 -16
- package/dist/index.js.map +1 -1
- package/docker/Dockerfile +2 -1
- package/package.json +6 -5
- package/views/default/formatting_functions.pug +1 -1
package/README.md
CHANGED
|
@@ -83,6 +83,7 @@ Many transit agencies use `gtfs-to-html` to generate the schedule pages used on
|
|
|
83
83
|
| [MVgo](https://mvgo.org) | Mountain View, California |
|
|
84
84
|
| [Petaluma Transit](https://transit.cityofpetaluma.net) | Petaluma, California |
|
|
85
85
|
| [rabbittransit](https://www.rabbittransit.org) | York and Adams County, Pennsylvania |
|
|
86
|
+
| [River Valley Transit](https://rivervalleytransit.com) | Middletown, Connecticut |
|
|
86
87
|
| [Rogue Valley Transportation District](https://rvtd.org) | Medford, Oregon |
|
|
87
88
|
| [RTC Washoe](https://www.rtcwashoe.com) | Reno, Nevada |
|
|
88
89
|
| [Santa Barbara Metropolitan Transit District](https://sbmtd.gov) | Santa Barbara, California |
|
package/dist/app/index.js
CHANGED
|
@@ -40,6 +40,9 @@ function toGTFSTime(time) {
|
|
|
40
40
|
return time.format("HH:mm:ss");
|
|
41
41
|
}
|
|
42
42
|
function calendarToCalendarCode(c) {
|
|
43
|
+
if (Object.values(c).every((value) => value === null)) {
|
|
44
|
+
return "";
|
|
45
|
+
}
|
|
43
46
|
return `${c.monday}${c.tuesday}${c.wednesday}${c.thursday}${c.friday}${c.saturday}${c.sunday}`;
|
|
44
47
|
}
|
|
45
48
|
function calendarCodeToCalendar(code) {
|
|
@@ -287,7 +290,12 @@ function generateTimetablePageFileName(timetablePage, config2) {
|
|
|
287
290
|
return sanitize(`${formatRouteNameForFilename(route).toLowerCase()}.html`);
|
|
288
291
|
}
|
|
289
292
|
const timetable = timetablePage.timetables[0];
|
|
290
|
-
|
|
293
|
+
if (timetable.timetable_id) {
|
|
294
|
+
return sanitize(
|
|
295
|
+
`${timetable.timetable_id.replace(/\|/g, "_").toLowerCase()}.html`
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
let filename = "";
|
|
291
299
|
for (const route of timetable.routes) {
|
|
292
300
|
filename += `_${formatRouteNameForFilename(route)}`;
|
|
293
301
|
}
|
|
@@ -422,7 +430,7 @@ function getAgencyGeoJSON(config2) {
|
|
|
422
430
|
// package.json
|
|
423
431
|
var package_default = {
|
|
424
432
|
name: "gtfs-to-html",
|
|
425
|
-
version: "2.11.
|
|
433
|
+
version: "2.11.3",
|
|
426
434
|
private: false,
|
|
427
435
|
description: "Build human readable transit timetables as HTML, PDF or CSV from GTFS",
|
|
428
436
|
keywords: [
|
|
@@ -484,7 +492,7 @@ var package_default = {
|
|
|
484
492
|
pbf: "^4.0.1",
|
|
485
493
|
"pretty-error": "^4.0.0",
|
|
486
494
|
pug: "^3.0.3",
|
|
487
|
-
puppeteer: "^24.
|
|
495
|
+
puppeteer: "^24.23.0",
|
|
488
496
|
"sanitize-filename": "^1.6.3",
|
|
489
497
|
"sanitize-html": "^2.17.0",
|
|
490
498
|
sqlstring: "^2.3.3",
|
|
@@ -494,22 +502,23 @@ var package_default = {
|
|
|
494
502
|
},
|
|
495
503
|
devDependencies: {
|
|
496
504
|
"@types/archiver": "^6.0.3",
|
|
505
|
+
"@types/cli-table": "^0.3.4",
|
|
497
506
|
"@types/express": "^5.0.3",
|
|
498
507
|
"@types/insane": "^1.0.0",
|
|
499
508
|
"@types/js-beautify": "^1.14.3",
|
|
500
509
|
"@types/lodash-es": "^4.17.12",
|
|
501
510
|
"@types/morgan": "^1.9.10",
|
|
502
|
-
"@types/node": "^
|
|
511
|
+
"@types/node": "^24",
|
|
503
512
|
"@types/pug": "^2.0.10",
|
|
504
513
|
"@types/sanitize-html": "^2.16.0",
|
|
505
514
|
"@types/sqlstring": "^2.3.2",
|
|
506
515
|
"@types/toposort": "^2.0.7",
|
|
507
516
|
"@types/yargs": "^17.0.33",
|
|
508
517
|
husky: "^9.1.7",
|
|
509
|
-
"lint-staged": "^16.
|
|
518
|
+
"lint-staged": "^16.2.3",
|
|
510
519
|
prettier: "^3.6.2",
|
|
511
520
|
tsup: "^8.5.0",
|
|
512
|
-
typescript: "^5.9.
|
|
521
|
+
typescript: "^5.9.3"
|
|
513
522
|
},
|
|
514
523
|
engines: {
|
|
515
524
|
node: ">= 22"
|
|
@@ -636,9 +645,6 @@ var sortTrips = (trips, config2) => {
|
|
|
636
645
|
const lastStopId = last(longestTripStoptimes).stop_id;
|
|
637
646
|
sortedTrips = sortTripsByStoptimeAtStop(trips, lastStopId);
|
|
638
647
|
}
|
|
639
|
-
if (config2.showDuplicateTrips === false) {
|
|
640
|
-
return deduplicateTrips(sortedTrips ?? []);
|
|
641
|
-
}
|
|
642
648
|
return sortedTrips ?? [];
|
|
643
649
|
};
|
|
644
650
|
var sortTripsByStoptimeAtStop = (trips, stopId) => sortBy(trips, (trip) => {
|
|
@@ -814,7 +820,15 @@ var createTimetable = ({
|
|
|
814
820
|
...calendars?.map((calendar) => calendar.service_id) ?? [],
|
|
815
821
|
...calendarDates?.map((calendarDate) => calendarDate.service_id) ?? []
|
|
816
822
|
]);
|
|
817
|
-
const days2 = {
|
|
823
|
+
const days2 = {
|
|
824
|
+
monday: null,
|
|
825
|
+
tuesday: null,
|
|
826
|
+
wednesday: null,
|
|
827
|
+
thursday: null,
|
|
828
|
+
friday: null,
|
|
829
|
+
saturday: null,
|
|
830
|
+
sunday: null
|
|
831
|
+
};
|
|
818
832
|
let startDate = null;
|
|
819
833
|
let endDate = null;
|
|
820
834
|
if (calendars && calendars.length > 0) {
|
|
@@ -833,7 +847,8 @@ var createTimetable = ({
|
|
|
833
847
|
const timetableId = formatTimetableId({
|
|
834
848
|
routeIds: [route.route_id],
|
|
835
849
|
directionId,
|
|
836
|
-
days: days2
|
|
850
|
+
days: days2,
|
|
851
|
+
dates: calendarDates?.map((calendarDate) => calendarDate.date)
|
|
837
852
|
});
|
|
838
853
|
return {
|
|
839
854
|
timetable_id: timetableId,
|
|
@@ -906,6 +921,9 @@ var convertRoutesToTimetablePages = (config2) => {
|
|
|
906
921
|
}
|
|
907
922
|
}
|
|
908
923
|
}
|
|
924
|
+
if (timetables.length === 0) {
|
|
925
|
+
continue;
|
|
926
|
+
}
|
|
909
927
|
if (config2.groupTimetablesIntoPages === true) {
|
|
910
928
|
timetablePages.push(
|
|
911
929
|
createTimetablePage({
|
|
@@ -1255,7 +1273,7 @@ var addTripContinuation = (trip, timetable) => {
|
|
|
1255
1273
|
trip.continues_as_route = nextTrip;
|
|
1256
1274
|
}
|
|
1257
1275
|
};
|
|
1258
|
-
var filterTrips = (timetable) => {
|
|
1276
|
+
var filterTrips = (timetable, config2) => {
|
|
1259
1277
|
let filteredTrips = timetable.orderedTrips;
|
|
1260
1278
|
for (const trip of filteredTrips) {
|
|
1261
1279
|
const combinedStoptimes = [];
|
|
@@ -1279,6 +1297,9 @@ var filterTrips = (timetable) => {
|
|
|
1279
1297
|
filteredTrips = filteredTrips.filter(
|
|
1280
1298
|
(trip) => trip.stoptimes.length > 1
|
|
1281
1299
|
);
|
|
1300
|
+
if (config2.showDuplicateTrips === false) {
|
|
1301
|
+
filteredTrips = deduplicateTrips(filteredTrips);
|
|
1302
|
+
}
|
|
1282
1303
|
return filteredTrips;
|
|
1283
1304
|
};
|
|
1284
1305
|
var getTripsForTimetable = (timetable, calendars, config2) => {
|
|
@@ -1416,7 +1437,10 @@ var formatTimetables = (timetables, config2) => {
|
|
|
1416
1437
|
if (config2.showMap) {
|
|
1417
1438
|
timetable.geojson = getTimetableGeoJSON(timetable, config2);
|
|
1418
1439
|
}
|
|
1419
|
-
timetable.
|
|
1440
|
+
timetable.trip_ids = uniq(
|
|
1441
|
+
timetable.orderedTrips.map((trip) => trip.trip_id)
|
|
1442
|
+
);
|
|
1443
|
+
timetable.orderedTrips = filterTrips(timetable, config2);
|
|
1420
1444
|
timetable.stops = formatStops(timetable, config2);
|
|
1421
1445
|
return timetable;
|
|
1422
1446
|
});
|
|
@@ -1521,7 +1545,9 @@ var getTimetablePageById = (timetablePageId, config2) => {
|
|
|
1521
1545
|
const timetablePages = getTimetablePages({
|
|
1522
1546
|
timetable_page_id: timetablePageId
|
|
1523
1547
|
});
|
|
1524
|
-
const timetables = mergeTimetablesWithSameId(
|
|
1548
|
+
const timetables = mergeTimetablesWithSameId(
|
|
1549
|
+
getTimetables()
|
|
1550
|
+
);
|
|
1525
1551
|
if (timetablePages.length > 1) {
|
|
1526
1552
|
throw new Error(
|
|
1527
1553
|
`Multiple timetable_pages found for timetable_page_id=${timetablePageId}`
|
|
@@ -1942,9 +1968,15 @@ function formatFrequency(frequency, config2) {
|
|
|
1942
1968
|
function formatTimetableId({
|
|
1943
1969
|
routeIds,
|
|
1944
1970
|
directionId,
|
|
1945
|
-
days: days2
|
|
1971
|
+
days: days2,
|
|
1972
|
+
dates
|
|
1946
1973
|
}) {
|
|
1947
|
-
let timetableId =
|
|
1974
|
+
let timetableId = routeIds.join("_");
|
|
1975
|
+
if (calendarToCalendarCode(days2)) {
|
|
1976
|
+
timetableId += `|${calendarToCalendarCode(days2)}`;
|
|
1977
|
+
} else if (dates && dates.length > 0) {
|
|
1978
|
+
timetableId += `|${dates.join("_")}`;
|
|
1979
|
+
}
|
|
1948
1980
|
if (!isNullOrEmpty(directionId)) {
|
|
1949
1981
|
timetableId += `|${directionId}`;
|
|
1950
1982
|
}
|