gtfs-to-html 2.12.6 → 2.12.8

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 CHANGED
@@ -66,6 +66,7 @@ Many transit agencies use `gtfs-to-html` to generate the schedule pages used on
66
66
  | [Brockton Area Transit Authority](https://ridebat.com) | Brockton, Massachusetts |
67
67
  | [Cape Ann Transportation Authority](https://canntran.com) | Gloucester, Massachusetts |
68
68
  | [Capital Transit](https://juneaucapitaltransit.org) | Juneau, Alaska |
69
+ | [Cascades East Transit](https://cascadeseasttransit.com) | Bend, Oregon |
69
70
  | [Central Transit](https://centraltransit.org) | Ellensburg, Washington |
70
71
  | [Citibus](https://citibus.com) | Lubbock, Texas |
71
72
  | [Commute.org](https://commute.org) | San Mateo County, California |
@@ -77,7 +78,7 @@ Many transit agencies use `gtfs-to-html` to generate the schedule pages used on
77
78
  | [Kings Area Rural Transit (KART)](https://www.kartbus.org) | Kings County, California |
78
79
  | [Lowell Regional Transit Authority](https://lrta.com) | Lowell, Massachusetts |
79
80
  | [Madera County Connection](https://mcctransit.com) | Madera County, California |
80
- | [Marin Transit](https://marintransit.org) | Marin County, California |
81
+ | [Marin Transit](https://marintransit.gov) | Marin County, California |
81
82
  | [Morongo Basin Transit Authority](https://mbtabus.com) | Morongo Basin, California |
82
83
  | [Mountain Transit](https://mountaintransit.org) | Big Bear Valley, California |
83
84
  | [Mountain View Community Shuttle](https://mvcommunityshuttle.com) | Mountain View, California |
@@ -2,15 +2,15 @@
2
2
  "agencies": [
3
3
  {
4
4
  "agencyKey": "marintransit",
5
- "url": "https://marintransit.org/data/google_transit.zip",
5
+ "url": "https://marintransit.gov/data/google_transit.zip",
6
6
  "realtimeAlerts": {
7
- "url": "https://api.marintransit.org/alerts"
7
+ "url": "https://api.marintransit.gov/alerts"
8
8
  },
9
9
  "realtimeTripUpdates": {
10
- "url": "https://api.marintransit.org/tripupdates"
10
+ "url": "https://api.marintransit.gov/tripupdates"
11
11
  },
12
12
  "realtimeVehiclePositions": {
13
- "url": "https://api.marintransit.org/vehiclepositions"
13
+ "url": "https://api.marintransit.gov/vehiclepositions"
14
14
  }
15
15
  }
16
16
  ],
package/dist/app/index.js CHANGED
@@ -330,6 +330,27 @@ function isGtfsToHtmlError(error) {
330
330
  return candidate.name === "GtfsToHtmlError" && typeof candidate.message === "string" && typeof candidate.code === "string" && typeof candidate.category === "string" && typeof candidate.isOperational === "boolean";
331
331
  }
332
332
 
333
+ // src/lib/log-utils.ts
334
+ import { clearLine, cursorTo } from "readline";
335
+ import { noop } from "lodash-es";
336
+ import * as colors from "yoctocolors";
337
+ import { getAgencies, getFeedInfo, isGtfsError as isGtfsError2, formatGtfsError } from "gtfs";
338
+ import Table from "cli-table";
339
+ function logWarning(config2) {
340
+ if (config2.logFunction) {
341
+ return config2.logFunction;
342
+ }
343
+ return (text) => {
344
+ process.stdout.write(`
345
+ ${formatWarning(text)}
346
+ `);
347
+ };
348
+ }
349
+ function formatWarning(text) {
350
+ const warningMessage = `${colors.underline("Warning")}: ${text}`;
351
+ return colors.yellow(warningMessage);
352
+ }
353
+
333
354
  // src/lib/file-utils.ts
334
355
  var homeDirectory = homedir();
335
356
  function getPathToThisModuleFolder() {
@@ -405,26 +426,9 @@ import { getShapesAsGeoJSON, getStopsAsGeoJSON } from "gtfs";
405
426
  import simplify from "@turf/simplify";
406
427
  import { featureCollection, round } from "@turf/helpers";
407
428
 
408
- // src/lib/log-utils.ts
409
- import { clearLine, cursorTo } from "readline";
410
- import { noop } from "lodash-es";
411
- import * as colors from "yoctocolors";
412
- import { getAgencies, getFeedInfo, isGtfsError as isGtfsError2, formatGtfsError } from "gtfs";
413
- import Table from "cli-table";
414
- function logWarning(config2) {
415
- if (config2.logFunction) {
416
- return config2.logFunction;
417
- }
418
- return (text) => {
419
- process.stdout.write(`
420
- ${formatWarning(text)}
421
- `);
422
- };
423
- }
424
- function formatWarning(text) {
425
- const warningMessage = `${colors.underline("Warning")}: ${text}`;
426
- return colors.yellow(warningMessage);
427
- }
429
+ // src/lib/trip-id-utils.ts
430
+ var getBaseTripId = (tripId) => tripId.replace(/_freq_\d+$/, "");
431
+ var getBaseTripIds = (trips) => Array.from(new Set(trips.map((trip) => getBaseTripId(trip.trip_id))));
428
432
 
429
433
  // src/lib/geojson-utils.ts
430
434
  var mergeGeojson = (...geojsons) => featureCollection(geojsons.flatMap((geojson) => geojson.features));
@@ -455,18 +459,19 @@ var truncateGeoJSONDecimals = (geojson, config2) => {
455
459
  return geojson;
456
460
  };
457
461
  function getTimetableGeoJSON(timetable, config2) {
462
+ const tripIds = getBaseTripIds(timetable.orderedTrips);
458
463
  const shapesGeojsons = timetable.route_ids.map(
459
464
  (routeId) => getShapesAsGeoJSON({
460
465
  route_id: routeId,
461
466
  direction_id: timetable.direction_id,
462
- trip_id: timetable.orderedTrips.map((trip) => trip.trip_id)
467
+ trip_id: tripIds
463
468
  })
464
469
  );
465
470
  const stopsGeojsons = timetable.route_ids.map(
466
471
  (routeId) => getStopsAsGeoJSON({
467
472
  route_id: routeId,
468
473
  direction_id: timetable.direction_id,
469
- trip_id: timetable.orderedTrips.map((trip) => trip.trip_id)
474
+ trip_id: tripIds
470
475
  })
471
476
  );
472
477
  const geojson = mergeGeojson(...shapesGeojsons, ...stopsGeojsons);
@@ -504,7 +509,7 @@ function getAgencyGeoJSON(config2) {
504
509
  // package.json
505
510
  var package_default = {
506
511
  name: "gtfs-to-html",
507
- version: "2.12.6",
512
+ version: "2.12.8",
508
513
  private: false,
509
514
  description: "Build human readable transit timetables as HTML, PDF or CSV from GTFS",
510
515
  keywords: [
@@ -563,12 +568,12 @@ var package_default = {
563
568
  "css.escape": "^1.5.1",
564
569
  "csv-stringify": "^6.7.0",
565
570
  express: "^5.2.1",
566
- gtfs: "^4.18.4",
571
+ gtfs: "^4.18.5",
567
572
  "gtfs-realtime-pbf-js-module": "^1.0.0",
568
573
  "js-beautify": "^1.15.4",
569
- "lodash-es": "^4.17.23",
570
- "maplibre-gl": "^5.21.0",
571
- marked: "^17.0.5",
574
+ "lodash-es": "^4.18.1",
575
+ "maplibre-gl": "^5.23.0",
576
+ marked: "^18.0.0",
572
577
  moment: "^2.30.1",
573
578
  pbf: "^4.0.1",
574
579
  "pretty-error": "^4.0.0",
@@ -595,9 +600,9 @@ var package_default = {
595
600
  "@types/yargs": "^17.0.35",
596
601
  husky: "^9.1.7",
597
602
  "lint-staged": "^16.4.0",
598
- prettier: "^3.8.1",
603
+ prettier: "^3.8.2",
599
604
  tsup: "^8.5.1",
600
- typescript: "^5.9.3"
605
+ typescript: "^6.0.2"
601
606
  },
602
607
  engines: {
603
608
  node: ">= 22"
@@ -619,9 +624,13 @@ var package_default = {
619
624
  singleQuote: true
620
625
  },
621
626
  "lint-staged": {
622
- "*.js": "prettier --write",
623
- "*.ts": "prettier --write",
624
- "*.json": "prettier --write"
627
+ "*.{js,ts,json}": "prettier --write"
628
+ },
629
+ pnpm: {
630
+ onlyBuiltDependencies: [
631
+ "better-sqlite3",
632
+ "puppeteer"
633
+ ]
625
634
  }
626
635
  };
627
636
 
@@ -827,7 +836,7 @@ var getTimetableNotesForTimetable = (timetable, config2) => {
827
836
  }),
828
837
  // Get all notes for all trips in this timetable.
829
838
  ...getTimetableNotesReferences({
830
- trip_id: timetable.orderedTrips.map((trip) => trip.trip_id)
839
+ trip_id: getBaseTripIds(timetable.orderedTrips)
831
840
  }),
832
841
  // Get all notes for all stops in this timetable.
833
842
  ...getTimetableNotesReferences({
@@ -1021,7 +1030,7 @@ var convertRoutesToTimetablePages = (config2) => {
1021
1030
  if (config2.groupTimetablesIntoPages === true) {
1022
1031
  timetablePages.push(
1023
1032
  createTimetablePage({
1024
- timetablePageId: `route_${route.route_short_name ?? route.route_long_name}`,
1033
+ timetablePageId: `route_${route.route_id}`,
1025
1034
  timetables,
1026
1035
  config: config2
1027
1036
  })
@@ -1246,9 +1255,8 @@ var getCalendarsFromConfig = (config2) => {
1246
1255
  }
1247
1256
  const calendars = db.prepare(`SELECT * FROM calendar ${whereClause}`).all();
1248
1257
  const serviceIds = calendars.map((calendar) => calendar.service_id);
1249
- const calendarDates = db.prepare(
1250
- `SELECT * FROM calendar_dates WHERE exception_type = 1 AND service_id NOT IN (${serviceIds.map((serviceId) => `'${serviceId}'`).join(", ")})`
1251
- ).all();
1258
+ const calendarDatesQuery = serviceIds.length > 0 ? `SELECT * FROM calendar_dates WHERE exception_type = 1 AND service_id NOT IN (${serviceIds.map((serviceId) => sqlString.escape(serviceId)).join(", ")})` : "SELECT * FROM calendar_dates WHERE exception_type = 1";
1259
+ const calendarDates = db.prepare(calendarDatesQuery).all();
1252
1260
  return {
1253
1261
  calendars,
1254
1262
  calendarDates
@@ -1320,10 +1328,9 @@ var getCalendarDatesForDateRange = (startDate, endDate) => {
1320
1328
  if (startDate) {
1321
1329
  whereClauses.push(`date >= ${sqlString.escape(startDate)}`);
1322
1330
  }
1331
+ const whereClause = whereClauses.length > 0 ? ` WHERE ${whereClauses.join(" AND ")}` : "";
1323
1332
  const calendarDates = db.prepare(
1324
- `SELECT service_id, date, exception_type FROM calendar_dates WHERE ${whereClauses.join(
1325
- " AND "
1326
- )}`
1333
+ `SELECT service_id, date, exception_type FROM calendar_dates${whereClause}`
1327
1334
  ).all();
1328
1335
  return calendarDates;
1329
1336
  };
@@ -1636,9 +1643,7 @@ var formatTimetables = (timetables, config2) => {
1636
1643
  if (config2.showMap) {
1637
1644
  timetable.geojson = getTimetableGeoJSON(timetable, config2);
1638
1645
  }
1639
- timetable.trip_ids = uniq(
1640
- timetable.orderedTrips.map((trip) => trip.trip_id)
1641
- );
1646
+ timetable.trip_ids = uniq(getBaseTripIds(timetable.orderedTrips));
1642
1647
  timetable.orderedTrips = filterTrips(timetable, calendars, config2);
1643
1648
  timetable.stops = formatStops(timetable, config2);
1644
1649
  return timetable;
@@ -1804,7 +1809,7 @@ var getTimetablePageById = (timetablePageId, config2) => {
1804
1809
  }
1805
1810
  if (timetablePageId.startsWith("route_")) {
1806
1811
  const routes = getRoutes({
1807
- route_short_name: timetablePageId.split("_")[1]
1812
+ route_id: timetablePageId.slice("route_".length)
1808
1813
  });
1809
1814
  if (routes.length === 0) {
1810
1815
  throw new GtfsToHtmlError(