gtfs-to-html 2.12.8 → 2.12.10

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
@@ -61,6 +61,7 @@ Many transit agencies use `gtfs-to-html` to generate the schedule pages used on
61
61
 
62
62
  | Agency | Location |
63
63
  | ----------------------------------------------------------------------------- | ----------------------------------- |
64
+ | [Asheville Rides Transit (ART)](https://www.ridetheart.com) | Asheville, North Carolina |
64
65
  | [Basin Transit](https://basin-transit.com) | Morongo Basin, California |
65
66
  | [Bayway Transit](https://www.baywaytransit.org) | Panama City, Florida |
66
67
  | [Brockton Area Transit Authority](https://ridebat.com) | Brockton, Massachusetts |
@@ -120,6 +121,13 @@ Are you using `gtfs-to-html`? Let us know via email [gtfs@blinktag.com](mailto:g
120
121
 
121
122
  Pull requests are welcome, as well as [feedback and reporting issues](https://github.com/blinktaginc/gtfs-to-html/issues).
122
123
 
124
+ ### Development Setup
125
+
126
+ pnpm install
127
+ pnpm run build
128
+
129
+ `pnpm install` installs dependencies. `pnpm run build` compiles TypeScript and vendors browser-compatible libraries (maplibre-gl, pbf, anchorme, etc.) from devDependencies into `dist/browser` via `scripts/copy-browser-assets.js`. These vendored files are included in the published npm package so consumers don't need to run any postinstall steps.
130
+
123
131
  ## Tests
124
132
 
125
133
  npm test
package/dist/app/index.js CHANGED
@@ -188,7 +188,7 @@ import {
188
188
  import { homedir } from "os";
189
189
  import * as _ from "lodash-es";
190
190
  import { uniqBy } from "lodash-es";
191
- import archiver from "archiver";
191
+ import { ZipArchive } from "archiver";
192
192
  import beautify from "js-beautify";
193
193
  import sanitizeHtml from "sanitize-html";
194
194
  import { renderFile } from "pug";
@@ -330,27 +330,6 @@ 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
-
354
333
  // src/lib/file-utils.ts
355
334
  var homeDirectory = homedir();
356
335
  function getPathToThisModuleFolder() {
@@ -426,6 +405,27 @@ import { getShapesAsGeoJSON, getStopsAsGeoJSON } from "gtfs";
426
405
  import simplify from "@turf/simplify";
427
406
  import { featureCollection, round } from "@turf/helpers";
428
407
 
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
+ }
428
+
429
429
  // src/lib/trip-id-utils.ts
430
430
  var getBaseTripId = (tripId) => tripId.replace(/_freq_\d+$/, "");
431
431
  var getBaseTripIds = (trips) => Array.from(new Set(trips.map((trip) => getBaseTripId(trip.trip_id))));
@@ -509,7 +509,7 @@ function getAgencyGeoJSON(config2) {
509
509
  // package.json
510
510
  var package_default = {
511
511
  name: "gtfs-to-html",
512
- version: "2.12.8",
512
+ version: "2.12.10",
513
513
  private: false,
514
514
  description: "Build human readable transit timetables as HTML, PDF or CSV from GTFS",
515
515
  keywords: [
@@ -552,41 +552,36 @@ var package_default = {
552
552
  "gtfs-to-html": "dist/bin/gtfs-to-html.js"
553
553
  },
554
554
  scripts: {
555
- build: "tsup",
556
- postbuild: "node scripts/postinstall.js",
555
+ build: "tsup && node scripts/copy-browser-assets.js",
557
556
  start: "node ./dist/app",
558
- prepare: "husky && npm run build",
559
- postinstall: "node scripts/postinstall.js"
557
+ prepare: "husky && pnpm run build",
558
+ prepack: "husky && pnpm run build"
560
559
  },
561
560
  dependencies: {
562
- "@maplibre/maplibre-gl-geocoder": "^1.9.4",
563
- "@turf/helpers": "^7.3.4",
564
- "@turf/simplify": "^7.3.4",
565
- anchorme: "^3.0.8",
566
- archiver: "^7.0.1",
561
+ "@turf/helpers": "^7.3.5",
562
+ "@turf/simplify": "^7.3.5",
563
+ archiver: "^8.0.0",
567
564
  "cli-table": "^0.3.11",
568
565
  "css.escape": "^1.5.1",
569
566
  "csv-stringify": "^6.7.0",
570
567
  express: "^5.2.1",
571
568
  gtfs: "^4.18.5",
572
- "gtfs-realtime-pbf-js-module": "^1.0.0",
573
569
  "js-beautify": "^1.15.4",
574
570
  "lodash-es": "^4.18.1",
575
- "maplibre-gl": "^5.23.0",
576
- marked: "^18.0.0",
571
+ marked: "^18.0.3",
577
572
  moment: "^2.30.1",
578
- pbf: "^4.0.1",
579
573
  "pretty-error": "^4.0.0",
580
574
  pug: "^3.0.4",
581
- puppeteer: "^24.40.0",
575
+ puppeteer: "^24.43.1",
582
576
  "sanitize-filename": "^1.6.4",
583
- "sanitize-html": "^2.17.2",
577
+ "sanitize-html": "^2.17.4",
584
578
  sqlstring: "^2.3.3",
585
579
  toposort: "^2.0.2",
586
580
  yargs: "^18.0.0",
587
581
  yoctocolors: "^2.1.2"
588
582
  },
589
583
  devDependencies: {
584
+ "@maplibre/maplibre-gl-geocoder": "^1.9.4",
590
585
  "@types/archiver": "^7.0.0",
591
586
  "@types/cli-table": "^0.3.4",
592
587
  "@types/express": "^5.0.6",
@@ -598,15 +593,20 @@ var package_default = {
598
593
  "@types/sqlstring": "^2.3.2",
599
594
  "@types/toposort": "^2.0.7",
600
595
  "@types/yargs": "^17.0.35",
596
+ anchorme: "^3.0.8",
597
+ "gtfs-realtime-pbf-js-module": "^1.0.0",
601
598
  husky: "^9.1.7",
602
- "lint-staged": "^16.4.0",
603
- prettier: "^3.8.2",
599
+ "lint-staged": "^17.0.5",
600
+ "maplibre-gl": "^5.24.0",
601
+ pbf: "^4.0.1",
602
+ prettier: "^3.8.3",
604
603
  tsup: "^8.5.1",
605
- typescript: "^6.0.2"
604
+ typescript: "^6.0.3"
606
605
  },
607
606
  engines: {
608
607
  node: ">= 22"
609
608
  },
609
+ packageManager: "pnpm@11.1.3",
610
610
  "release-it": {
611
611
  github: {
612
612
  release: true
@@ -617,7 +617,7 @@ var package_default = {
617
617
  }
618
618
  },
619
619
  hooks: {
620
- "after:bump": "npm run build"
620
+ "after:bump": "pnpm run build"
621
621
  }
622
622
  },
623
623
  prettier: {
@@ -625,12 +625,6 @@ var package_default = {
625
625
  },
626
626
  "lint-staged": {
627
627
  "*.{js,ts,json}": "prettier --write"
628
- },
629
- pnpm: {
630
- onlyBuiltDependencies: [
631
- "better-sqlite3",
632
- "puppeteer"
633
- ]
634
628
  }
635
629
  };
636
630
 
@@ -1451,6 +1445,46 @@ var filterTrips = (timetable, calendars, config2) => {
1451
1445
  if (config2.showDuplicateTrips === false) {
1452
1446
  filteredTrips = deduplicateTrips(filteredTrips);
1453
1447
  }
1448
+ const dayNames = [
1449
+ "monday",
1450
+ "tuesday",
1451
+ "wednesday",
1452
+ "thursday",
1453
+ "friday",
1454
+ "saturday",
1455
+ "sunday"
1456
+ ];
1457
+ const timetableDays = dayNames.filter((day) => timetable[day] === 1);
1458
+ if (timetableDays.length > 1) {
1459
+ const warnedServiceIds = /* @__PURE__ */ new Set();
1460
+ for (const trip of filteredTrips) {
1461
+ const tripServiceIds = [
1462
+ trip.service_id,
1463
+ ...trip.additional_service_ids ?? []
1464
+ ];
1465
+ const tripCalendars = calendars.filter(
1466
+ (c) => tripServiceIds.includes(c.service_id)
1467
+ );
1468
+ if (tripCalendars.length === 0) {
1469
+ continue;
1470
+ }
1471
+ const tripDays = getDaysFromCalendars(tripCalendars);
1472
+ const missingDays = timetableDays.filter(
1473
+ (day) => (tripDays[day] ?? 0) !== 1
1474
+ );
1475
+ if (missingDays.length > 0) {
1476
+ const serviceIdKey = tripServiceIds.sort().join("|");
1477
+ if (!warnedServiceIds.has(serviceIdKey)) {
1478
+ warnedServiceIds.add(serviceIdKey);
1479
+ const tripDayList = formatDays(tripDays, config2);
1480
+ const timetableDayList = formatDays(timetable, config2);
1481
+ timetable.warnings.push(
1482
+ `Timetable ${timetable.timetable_id} (Routes: ${timetable.routes.map((route) => route.route_short_name).join(", ")}) covers ${timetableDayList} but some trips (service_id=${tripServiceIds.join(", ")}) only run on ${tripDayList}. This may indicate a data issue in the GTFS or that you should generate separate timetables for different days of the week.`
1483
+ );
1484
+ }
1485
+ }
1486
+ }
1487
+ }
1454
1488
  const formattedTrips = filteredTrips.map((trip) => {
1455
1489
  const tripCalendars = calendars.filter((calendar) => {
1456
1490
  return [
@@ -2411,30 +2445,12 @@ app.use((req, res, next) => {
2411
2445
  });
2412
2446
  var staticAssetPath = config.templatePath === void 0 ? getPathToViewsFolder(config) : untildify(config.templatePath);
2413
2447
  app.use(express.static(staticAssetPath));
2414
- var frontendLibraryPaths = [
2415
- { route: "/js", package: "pbf", subPath: "dist" },
2416
- { route: "/js", package: "gtfs-realtime-pbf-js-module", subPath: "" },
2417
- { route: "/js", package: "anchorme", subPath: "../../dist/browser" },
2418
- { route: "/js", package: "maplibre-gl", subPath: "../dist" },
2419
- {
2420
- route: "/js",
2421
- package: "@maplibre/maplibre-gl-geocoder",
2422
- subPath: "../dist"
2423
- },
2424
- { route: "/css", package: "maplibre-gl", subPath: "../dist" },
2425
- {
2426
- route: "/css",
2427
- package: "@maplibre/maplibre-gl-geocoder",
2428
- subPath: "../dist"
2429
- }
2430
- ];
2431
- var resolvePackagePath = (packageName, subPath) => {
2432
- const packagePath = dirname2(fileURLToPath2(import.meta.resolve(packageName)));
2433
- return subPath ? join2(packagePath, subPath) : packagePath;
2434
- };
2435
- for (const { route, package: pkg, subPath } of frontendLibraryPaths) {
2436
- app.use(route, express.static(resolvePackagePath(pkg, subPath)));
2437
- }
2448
+ var browserAssetsPath = join2(
2449
+ dirname2(fileURLToPath2(import.meta.url)),
2450
+ "../browser"
2451
+ );
2452
+ app.use("/js", express.static(browserAssetsPath));
2453
+ app.use("/css", express.static(browserAssetsPath));
2438
2454
  app.get("/", async (req, res, next) => {
2439
2455
  try {
2440
2456
  const timetablePages = [];