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/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ConfigAgency } from 'gtfs';
1
+ import { ConfigAgency, Timetable, Route, TimetablePage } from 'gtfs';
2
2
 
3
3
  interface Config {
4
4
  agencies: ConfigAgency[];
@@ -55,6 +55,22 @@ interface Config {
55
55
  logFunction?: (text: string) => void;
56
56
  }
57
57
 
58
+ interface FormattedTimetable extends Timetable {
59
+ route_ids: string[];
60
+ trip_ids: string[];
61
+ routes: Route[];
62
+ service_ids?: string[];
63
+ warnings?: string[];
64
+ has_continues_as_route?: boolean;
65
+ has_continues_from_route?: boolean;
66
+ }
67
+
68
+ interface FormattedTimetablePage extends TimetablePage {
69
+ timetables: FormattedTimetable[];
70
+ routes: Route[];
71
+ relativePath?: string;
72
+ }
73
+
58
74
  declare const gtfsToHtml: (initialConfig: Config) => Promise<string>;
59
75
 
60
- export { gtfsToHtml as default };
76
+ export { type Config, type FormattedTimetable, type FormattedTimetablePage, gtfsToHtml as default };
package/dist/index.js CHANGED
@@ -62,6 +62,9 @@ function toGTFSTime(time) {
62
62
  return time.format("HH:mm:ss");
63
63
  }
64
64
  function calendarToCalendarCode(c) {
65
+ if (Object.values(c).every((value) => value === null)) {
66
+ return "";
67
+ }
65
68
  return `${c.monday}${c.tuesday}${c.wednesday}${c.thursday}${c.friday}${c.saturday}${c.sunday}`;
66
69
  }
67
70
  function calendarCodeToCalendar(code) {
@@ -494,7 +497,7 @@ function formatTripNameForCSV(trip, timetable) {
494
497
  // package.json
495
498
  var package_default = {
496
499
  name: "gtfs-to-html",
497
- version: "2.11.1",
500
+ version: "2.11.3",
498
501
  private: false,
499
502
  description: "Build human readable transit timetables as HTML, PDF or CSV from GTFS",
500
503
  keywords: [
@@ -556,7 +559,7 @@ var package_default = {
556
559
  pbf: "^4.0.1",
557
560
  "pretty-error": "^4.0.0",
558
561
  pug: "^3.0.3",
559
- puppeteer: "^24.21.0",
562
+ puppeteer: "^24.23.0",
560
563
  "sanitize-filename": "^1.6.3",
561
564
  "sanitize-html": "^2.17.0",
562
565
  sqlstring: "^2.3.3",
@@ -566,22 +569,23 @@ var package_default = {
566
569
  },
567
570
  devDependencies: {
568
571
  "@types/archiver": "^6.0.3",
572
+ "@types/cli-table": "^0.3.4",
569
573
  "@types/express": "^5.0.3",
570
574
  "@types/insane": "^1.0.0",
571
575
  "@types/js-beautify": "^1.14.3",
572
576
  "@types/lodash-es": "^4.17.12",
573
577
  "@types/morgan": "^1.9.10",
574
- "@types/node": "^22",
578
+ "@types/node": "^24",
575
579
  "@types/pug": "^2.0.10",
576
580
  "@types/sanitize-html": "^2.16.0",
577
581
  "@types/sqlstring": "^2.3.2",
578
582
  "@types/toposort": "^2.0.7",
579
583
  "@types/yargs": "^17.0.33",
580
584
  husky: "^9.1.7",
581
- "lint-staged": "^16.1.6",
585
+ "lint-staged": "^16.2.3",
582
586
  prettier: "^3.6.2",
583
587
  tsup: "^8.5.0",
584
- typescript: "^5.9.2"
588
+ typescript: "^5.9.3"
585
589
  },
586
590
  engines: {
587
591
  node: ">= 22"
@@ -708,9 +712,6 @@ var sortTrips = (trips, config) => {
708
712
  const lastStopId = last(longestTripStoptimes).stop_id;
709
713
  sortedTrips = sortTripsByStoptimeAtStop(trips, lastStopId);
710
714
  }
711
- if (config.showDuplicateTrips === false) {
712
- return deduplicateTrips(sortedTrips ?? []);
713
- }
714
715
  return sortedTrips ?? [];
715
716
  };
716
717
  var sortTripsByStoptimeAtStop = (trips, stopId) => sortBy(trips, (trip) => {
@@ -886,7 +887,15 @@ var createTimetable = ({
886
887
  ...calendars?.map((calendar) => calendar.service_id) ?? [],
887
888
  ...calendarDates?.map((calendarDate) => calendarDate.service_id) ?? []
888
889
  ]);
889
- const days2 = {};
890
+ const days2 = {
891
+ monday: null,
892
+ tuesday: null,
893
+ wednesday: null,
894
+ thursday: null,
895
+ friday: null,
896
+ saturday: null,
897
+ sunday: null
898
+ };
890
899
  let startDate = null;
891
900
  let endDate = null;
892
901
  if (calendars && calendars.length > 0) {
@@ -905,7 +914,8 @@ var createTimetable = ({
905
914
  const timetableId = formatTimetableId({
906
915
  routeIds: [route.route_id],
907
916
  directionId,
908
- days: days2
917
+ days: days2,
918
+ dates: calendarDates?.map((calendarDate) => calendarDate.date)
909
919
  });
910
920
  return {
911
921
  timetable_id: timetableId,
@@ -978,6 +988,9 @@ var convertRoutesToTimetablePages = (config) => {
978
988
  }
979
989
  }
980
990
  }
991
+ if (timetables.length === 0) {
992
+ continue;
993
+ }
981
994
  if (config.groupTimetablesIntoPages === true) {
982
995
  timetablePages.push(
983
996
  createTimetablePage({
@@ -1327,7 +1340,7 @@ var addTripContinuation = (trip, timetable) => {
1327
1340
  trip.continues_as_route = nextTrip;
1328
1341
  }
1329
1342
  };
1330
- var filterTrips = (timetable) => {
1343
+ var filterTrips = (timetable, config) => {
1331
1344
  let filteredTrips = timetable.orderedTrips;
1332
1345
  for (const trip of filteredTrips) {
1333
1346
  const combinedStoptimes = [];
@@ -1351,6 +1364,9 @@ var filterTrips = (timetable) => {
1351
1364
  filteredTrips = filteredTrips.filter(
1352
1365
  (trip) => trip.stoptimes.length > 1
1353
1366
  );
1367
+ if (config.showDuplicateTrips === false) {
1368
+ filteredTrips = deduplicateTrips(filteredTrips);
1369
+ }
1354
1370
  return filteredTrips;
1355
1371
  };
1356
1372
  var getTripsForTimetable = (timetable, calendars, config) => {
@@ -1488,7 +1504,10 @@ var formatTimetables = (timetables, config) => {
1488
1504
  if (config.showMap) {
1489
1505
  timetable.geojson = getTimetableGeoJSON(timetable, config);
1490
1506
  }
1491
- timetable.orderedTrips = filterTrips(timetable);
1507
+ timetable.trip_ids = uniq(
1508
+ timetable.orderedTrips.map((trip) => trip.trip_id)
1509
+ );
1510
+ timetable.orderedTrips = filterTrips(timetable, config);
1492
1511
  timetable.stops = formatStops(timetable, config);
1493
1512
  return timetable;
1494
1513
  });
@@ -1593,7 +1612,9 @@ var getTimetablePageById = (timetablePageId, config) => {
1593
1612
  const timetablePages = getTimetablePages({
1594
1613
  timetable_page_id: timetablePageId
1595
1614
  });
1596
- const timetables = mergeTimetablesWithSameId(getTimetables());
1615
+ const timetables = mergeTimetablesWithSameId(
1616
+ getTimetables()
1617
+ );
1597
1618
  if (timetablePages.length > 1) {
1598
1619
  throw new Error(
1599
1620
  `Multiple timetable_pages found for timetable_page_id=${timetablePageId}`
@@ -2068,9 +2089,15 @@ function formatFrequency(frequency, config) {
2068
2089
  function formatTimetableId({
2069
2090
  routeIds,
2070
2091
  directionId,
2071
- days: days2
2092
+ days: days2,
2093
+ dates
2072
2094
  }) {
2073
- let timetableId = `${routeIds.join("_")}|${calendarToCalendarCode(days2)}`;
2095
+ let timetableId = routeIds.join("_");
2096
+ if (calendarToCalendarCode(days2)) {
2097
+ timetableId += `|${calendarToCalendarCode(days2)}`;
2098
+ } else if (dates && dates.length > 0) {
2099
+ timetableId += `|${dates.join("_")}`;
2100
+ }
2074
2101
  if (!isNullOrEmpty(directionId)) {
2075
2102
  timetableId += `|${directionId}`;
2076
2103
  }
@@ -2367,7 +2394,12 @@ function generateTimetablePageFileName(timetablePage, config) {
2367
2394
  return sanitize(`${formatRouteNameForFilename(route).toLowerCase()}.html`);
2368
2395
  }
2369
2396
  const timetable = timetablePage.timetables[0];
2370
- let filename = timetable.timetable_id ?? "";
2397
+ if (timetable.timetable_id) {
2398
+ return sanitize(
2399
+ `${timetable.timetable_id.replace(/\|/g, "_").toLowerCase()}.html`
2400
+ );
2401
+ }
2402
+ let filename = "";
2371
2403
  for (const route of timetable.routes) {
2372
2404
  filename += `_${formatRouteNameForFilename(route)}`;
2373
2405
  }