gtfs-to-html 2.12.1 → 2.12.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 +102 -32
- package/dist/app/index.js.map +1 -1
- package/dist/bin/gtfs-to-html.js +113 -69
- package/dist/bin/gtfs-to-html.js.map +1 -1
- package/dist/frontend_libraries/anchorme.min.js +1 -0
- package/dist/frontend_libraries/gtfs-realtime.browser.proto.js +0 -0
- package/dist/frontend_libraries/maplibre-gl-geocoder.css +284 -0
- package/dist/frontend_libraries/maplibre-gl-geocoder.js +2790 -0
- package/dist/frontend_libraries/maplibre-gl.css +1 -0
- package/dist/frontend_libraries/maplibre-gl.js +59 -0
- package/dist/frontend_libraries/pbf.js +1 -0
- package/dist/index.js +113 -69
- package/dist/index.js.map +1 -1
- package/package.json +14 -11
- package/scripts/postinstall.js +115 -0
package/dist/bin/gtfs-to-html.js
CHANGED
|
@@ -25,7 +25,6 @@ import {
|
|
|
25
25
|
rm
|
|
26
26
|
} from "fs/promises";
|
|
27
27
|
import { homedir } from "os";
|
|
28
|
-
import { findPackageJSON } from "module";
|
|
29
28
|
import * as _ from "lodash-es";
|
|
30
29
|
import { uniqBy as uniqBy2 } from "lodash-es";
|
|
31
30
|
import archiver from "archiver";
|
|
@@ -62,11 +61,11 @@ function fromGTFSTime(timeString) {
|
|
|
62
61
|
function toGTFSTime(time) {
|
|
63
62
|
return time.format("HH:mm:ss");
|
|
64
63
|
}
|
|
65
|
-
function calendarToCalendarCode(
|
|
66
|
-
if (Object.values(
|
|
64
|
+
function calendarToCalendarCode(calendar) {
|
|
65
|
+
if (Object.values(calendar).every((value) => value === null)) {
|
|
67
66
|
return "";
|
|
68
67
|
}
|
|
69
|
-
return `${
|
|
68
|
+
return `${calendar.monday ?? "0"}${calendar.tuesday ?? "0"}${calendar.wednesday ?? "0"}${calendar.thursday ?? "0"}${calendar.friday ?? "0"}${calendar.saturday ?? "0"}${calendar.sunday ?? "0"}`;
|
|
70
69
|
}
|
|
71
70
|
function calendarCodeToCalendar(code) {
|
|
72
71
|
const days2 = [
|
|
@@ -84,6 +83,35 @@ function calendarCodeToCalendar(code) {
|
|
|
84
83
|
}
|
|
85
84
|
return calendar;
|
|
86
85
|
}
|
|
86
|
+
function calendarToDateList(calendar, startDate, endDate) {
|
|
87
|
+
if (!startDate || !endDate) {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
const activeWeekdays = [
|
|
91
|
+
calendar.monday === 1 ? 1 : null,
|
|
92
|
+
calendar.tuesday === 1 ? 2 : null,
|
|
93
|
+
calendar.wednesday === 1 ? 3 : null,
|
|
94
|
+
calendar.thursday === 1 ? 4 : null,
|
|
95
|
+
calendar.friday === 1 ? 5 : null,
|
|
96
|
+
calendar.saturday === 1 ? 6 : null,
|
|
97
|
+
calendar.sunday === 1 ? 7 : null
|
|
98
|
+
].filter((weekday) => weekday !== null);
|
|
99
|
+
if (activeWeekdays.length === 0) {
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
const activeWeekdaySet = new Set(activeWeekdays);
|
|
103
|
+
const dates = /* @__PURE__ */ new Set();
|
|
104
|
+
const date = moment(startDate.toString(), "YYYYMMDD");
|
|
105
|
+
const endDateMoment = moment(endDate.toString(), "YYYYMMDD");
|
|
106
|
+
while (date.isSameOrBefore(endDateMoment)) {
|
|
107
|
+
const isoWeekday = date.isoWeekday();
|
|
108
|
+
if (activeWeekdaySet.has(isoWeekday)) {
|
|
109
|
+
dates.add(parseInt(date.format("YYYYMMDD"), 10));
|
|
110
|
+
}
|
|
111
|
+
date.add(1, "day");
|
|
112
|
+
}
|
|
113
|
+
return Array.from(dates);
|
|
114
|
+
}
|
|
87
115
|
function secondsAfterMidnight(timeString) {
|
|
88
116
|
return moment.duration(timeString).asSeconds();
|
|
89
117
|
}
|
|
@@ -494,7 +522,7 @@ function formatTripNameForCSV(trip, timetable) {
|
|
|
494
522
|
// package.json
|
|
495
523
|
var package_default = {
|
|
496
524
|
name: "gtfs-to-html",
|
|
497
|
-
version: "2.12.
|
|
525
|
+
version: "2.12.3",
|
|
498
526
|
private: false,
|
|
499
527
|
description: "Build human readable transit timetables as HTML, PDF or CSV from GTFS",
|
|
500
528
|
keywords: [
|
|
@@ -529,6 +557,7 @@ var package_default = {
|
|
|
529
557
|
"dist",
|
|
530
558
|
"docker",
|
|
531
559
|
"examples",
|
|
560
|
+
"scripts",
|
|
532
561
|
"views/default",
|
|
533
562
|
"config-sample.json"
|
|
534
563
|
],
|
|
@@ -537,30 +566,32 @@ var package_default = {
|
|
|
537
566
|
},
|
|
538
567
|
scripts: {
|
|
539
568
|
build: "tsup",
|
|
569
|
+
postbuild: "node scripts/postinstall.js",
|
|
540
570
|
start: "node ./dist/app",
|
|
541
|
-
prepare: "husky"
|
|
571
|
+
prepare: "husky && npm run build",
|
|
572
|
+
postinstall: "node scripts/postinstall.js"
|
|
542
573
|
},
|
|
543
574
|
dependencies: {
|
|
544
575
|
"@maplibre/maplibre-gl-geocoder": "^1.9.1",
|
|
545
|
-
"@turf/helpers": "^7.3.
|
|
546
|
-
"@turf/simplify": "^7.3.
|
|
576
|
+
"@turf/helpers": "^7.3.1",
|
|
577
|
+
"@turf/simplify": "^7.3.1",
|
|
547
578
|
anchorme: "^3.0.8",
|
|
548
579
|
archiver: "^7.0.1",
|
|
549
580
|
"cli-table": "^0.3.11",
|
|
550
581
|
"css.escape": "^1.5.1",
|
|
551
582
|
"csv-stringify": "^6.6.0",
|
|
552
|
-
express: "^5.1
|
|
553
|
-
gtfs: "^4.18.
|
|
583
|
+
express: "^5.2.1",
|
|
584
|
+
gtfs: "^4.18.2",
|
|
554
585
|
"gtfs-realtime-pbf-js-module": "^1.0.0",
|
|
555
586
|
"js-beautify": "^1.15.4",
|
|
556
587
|
"lodash-es": "^4.17.21",
|
|
557
|
-
"maplibre-gl": "^5.
|
|
558
|
-
marked: "^17.0.
|
|
588
|
+
"maplibre-gl": "^5.14.0",
|
|
589
|
+
marked: "^17.0.1",
|
|
559
590
|
moment: "^2.30.1",
|
|
560
591
|
pbf: "^4.0.1",
|
|
561
592
|
"pretty-error": "^4.0.0",
|
|
562
593
|
pug: "^3.0.3",
|
|
563
|
-
puppeteer: "^24.
|
|
594
|
+
puppeteer: "^24.32.0",
|
|
564
595
|
"sanitize-filename": "^1.6.3",
|
|
565
596
|
"sanitize-html": "^2.17.0",
|
|
566
597
|
sqlstring: "^2.3.3",
|
|
@@ -571,7 +602,7 @@ var package_default = {
|
|
|
571
602
|
devDependencies: {
|
|
572
603
|
"@types/archiver": "^7.0.0",
|
|
573
604
|
"@types/cli-table": "^0.3.4",
|
|
574
|
-
"@types/express": "^5.0.
|
|
605
|
+
"@types/express": "^5.0.6",
|
|
575
606
|
"@types/insane": "^1.0.0",
|
|
576
607
|
"@types/js-beautify": "^1.14.3",
|
|
577
608
|
"@types/lodash-es": "^4.17.12",
|
|
@@ -584,7 +615,7 @@ var package_default = {
|
|
|
584
615
|
"@types/yargs": "^17.0.35",
|
|
585
616
|
husky: "^9.1.7",
|
|
586
617
|
"lint-staged": "^16.2.7",
|
|
587
|
-
prettier: "^3.
|
|
618
|
+
prettier: "^3.7.4",
|
|
588
619
|
tsup: "^8.5.1",
|
|
589
620
|
typescript: "^5.9.3"
|
|
590
621
|
},
|
|
@@ -1249,9 +1280,9 @@ var getCalendarsFromTimetable = (timetable) => {
|
|
|
1249
1280
|
}
|
|
1250
1281
|
return db.prepare(`SELECT * FROM calendar ${whereClause}`).all();
|
|
1251
1282
|
};
|
|
1252
|
-
var
|
|
1283
|
+
var getCalendarDatesForDateRange = (startDate, endDate) => {
|
|
1253
1284
|
const db = openDb();
|
|
1254
|
-
const whereClauses = [
|
|
1285
|
+
const whereClauses = [];
|
|
1255
1286
|
if (endDate) {
|
|
1256
1287
|
whereClauses.push(`date <= ${sqlString.escape(endDate)}`);
|
|
1257
1288
|
}
|
|
@@ -1259,11 +1290,11 @@ var getCalendarDatesServiceIds = (startDate, endDate) => {
|
|
|
1259
1290
|
whereClauses.push(`date >= ${sqlString.escape(startDate)}`);
|
|
1260
1291
|
}
|
|
1261
1292
|
const calendarDates = db.prepare(
|
|
1262
|
-
`SELECT
|
|
1293
|
+
`SELECT service_id, date, exception_type FROM calendar_dates WHERE ${whereClauses.join(
|
|
1263
1294
|
" AND "
|
|
1264
1295
|
)}`
|
|
1265
1296
|
).all();
|
|
1266
|
-
return calendarDates
|
|
1297
|
+
return calendarDates;
|
|
1267
1298
|
};
|
|
1268
1299
|
var getAllStationStopIds = (stopId) => {
|
|
1269
1300
|
const stops = getStops({
|
|
@@ -1474,13 +1505,49 @@ var formatTimetables = (timetables, config) => {
|
|
|
1474
1505
|
timetable.warnings = [];
|
|
1475
1506
|
const dayList = formatDays(timetable, config);
|
|
1476
1507
|
const calendars = getCalendarsFromTimetable(timetable);
|
|
1477
|
-
|
|
1508
|
+
const serviceIds = /* @__PURE__ */ new Set();
|
|
1509
|
+
for (const calendar of calendars) {
|
|
1510
|
+
serviceIds.add(calendar.service_id);
|
|
1511
|
+
}
|
|
1478
1512
|
if (timetable.include_exceptions === 1) {
|
|
1479
|
-
const
|
|
1513
|
+
const calendarDates = getCalendarDatesForDateRange(
|
|
1480
1514
|
timetable.start_date,
|
|
1481
1515
|
timetable.end_date
|
|
1482
1516
|
);
|
|
1483
|
-
|
|
1517
|
+
const calendarDateGroups = groupBy(calendarDates, "service_id");
|
|
1518
|
+
for (const [serviceId, calendarDateGroup] of Object.entries(
|
|
1519
|
+
calendarDateGroups
|
|
1520
|
+
)) {
|
|
1521
|
+
const calendar = calendars.find(
|
|
1522
|
+
(c) => c.service_id === serviceId
|
|
1523
|
+
);
|
|
1524
|
+
if (calendarDateGroup.some(
|
|
1525
|
+
(calendarDate) => calendarDate.exception_type === 1
|
|
1526
|
+
)) {
|
|
1527
|
+
serviceIds.add(serviceId);
|
|
1528
|
+
}
|
|
1529
|
+
const calendarDateGroupExceptionType2 = calendarDateGroup.filter(
|
|
1530
|
+
(calendarDate) => calendarDate.exception_type === 2
|
|
1531
|
+
);
|
|
1532
|
+
if (timetable.start_date && timetable.end_date && calendar && calendarDateGroupExceptionType2.length > 0) {
|
|
1533
|
+
const datesDuringDateRange = calendarToDateList(
|
|
1534
|
+
calendar,
|
|
1535
|
+
timetable.start_date,
|
|
1536
|
+
timetable.end_date
|
|
1537
|
+
);
|
|
1538
|
+
if (datesDuringDateRange.length === 0) {
|
|
1539
|
+
serviceIds.delete(serviceId);
|
|
1540
|
+
}
|
|
1541
|
+
const everyDateIsExcluded = datesDuringDateRange.every(
|
|
1542
|
+
(dateDuringDateRange) => calendarDateGroupExceptionType2.some(
|
|
1543
|
+
(calendarDate) => calendarDate.date === dateDuringDateRange
|
|
1544
|
+
)
|
|
1545
|
+
);
|
|
1546
|
+
if (everyDateIsExcluded) {
|
|
1547
|
+
serviceIds.delete(serviceId);
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1484
1551
|
}
|
|
1485
1552
|
Object.assign(timetable, {
|
|
1486
1553
|
noServiceSymbolUsed: false,
|
|
@@ -1498,7 +1565,7 @@ var formatTimetables = (timetables, config) => {
|
|
|
1498
1565
|
noPickupSymbol: config.noPickupSymbol,
|
|
1499
1566
|
interpolatedStopSymbol: config.interpolatedStopSymbol,
|
|
1500
1567
|
orientation: timetable.orientation || config.defaultOrientation,
|
|
1501
|
-
service_ids: serviceIds,
|
|
1568
|
+
service_ids: Array.from(serviceIds),
|
|
1502
1569
|
dayList,
|
|
1503
1570
|
dayListLong: formatDaysLong(dayList, config)
|
|
1504
1571
|
});
|
|
@@ -2319,20 +2386,23 @@ async function getConfig(argv2) {
|
|
|
2319
2386
|
}
|
|
2320
2387
|
return config;
|
|
2321
2388
|
}
|
|
2322
|
-
function
|
|
2323
|
-
if (config.templatePath) {
|
|
2324
|
-
return untildify(config.templatePath);
|
|
2325
|
-
}
|
|
2389
|
+
function getPathToThisModuleFolder() {
|
|
2326
2390
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
2327
|
-
let
|
|
2391
|
+
let distFolderPath;
|
|
2328
2392
|
if (__dirname.endsWith("/dist/bin") || __dirname.endsWith("/dist/app")) {
|
|
2329
|
-
|
|
2393
|
+
distFolderPath = resolve(__dirname, "../../");
|
|
2330
2394
|
} else if (__dirname.endsWith("/dist")) {
|
|
2331
|
-
|
|
2395
|
+
distFolderPath = resolve(__dirname, "../");
|
|
2332
2396
|
} else {
|
|
2333
|
-
|
|
2397
|
+
distFolderPath = resolve(__dirname, "../../");
|
|
2334
2398
|
}
|
|
2335
|
-
return
|
|
2399
|
+
return distFolderPath;
|
|
2400
|
+
}
|
|
2401
|
+
function getPathToViewsFolder(config) {
|
|
2402
|
+
if (config.templatePath) {
|
|
2403
|
+
return untildify(config.templatePath);
|
|
2404
|
+
}
|
|
2405
|
+
return join(getPathToThisModuleFolder(), "views/default");
|
|
2336
2406
|
}
|
|
2337
2407
|
function getPathToTemplateFile(templateFileName, config) {
|
|
2338
2408
|
const fullTemplateFileName = config.noHead !== true ? `${templateFileName}_full.pug` : `${templateFileName}.pug`;
|
|
@@ -2365,6 +2435,7 @@ async function prepDirectory(outputPath, config) {
|
|
|
2365
2435
|
}
|
|
2366
2436
|
async function copyStaticAssets(config, outputPath) {
|
|
2367
2437
|
const viewsFolderPath = getPathToViewsFolder(config);
|
|
2438
|
+
const thisModuleFolderPath = getPathToThisModuleFolder();
|
|
2368
2439
|
const foldersToCopy = ["css", "js", "img"];
|
|
2369
2440
|
for (const folder of foldersToCopy) {
|
|
2370
2441
|
if (await access(join(viewsFolderPath, folder)).then(() => true).catch(() => false)) {
|
|
@@ -2375,70 +2446,43 @@ async function copyStaticAssets(config, outputPath) {
|
|
|
2375
2446
|
}
|
|
2376
2447
|
if (config.hasGtfsRealtimeVehiclePositions || config.hasGtfsRealtimeTripUpdates || config.hasGtfsRealtimeAlerts) {
|
|
2377
2448
|
await copyFile(
|
|
2378
|
-
join(
|
|
2379
|
-
dirname(findPackageJSON("pbf", import.meta.url)),
|
|
2380
|
-
"dist/pbf.js"
|
|
2381
|
-
),
|
|
2449
|
+
join(thisModuleFolderPath, "dist/frontend_libraries/pbf.js"),
|
|
2382
2450
|
join(outputPath, "js/pbf.js")
|
|
2383
2451
|
);
|
|
2384
2452
|
await copyFile(
|
|
2385
2453
|
join(
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
"gtfs-realtime-pbf-js-module",
|
|
2389
|
-
import.meta.url
|
|
2390
|
-
)
|
|
2391
|
-
),
|
|
2392
|
-
"gtfs-realtime.browser.proto.js"
|
|
2454
|
+
thisModuleFolderPath,
|
|
2455
|
+
"dist/frontend_libraries/gtfs-realtime.browser.proto.js"
|
|
2393
2456
|
),
|
|
2394
2457
|
join(outputPath, "js/gtfs-realtime.browser.proto.js")
|
|
2395
2458
|
);
|
|
2396
2459
|
}
|
|
2397
2460
|
if (config.hasGtfsRealtimeAlerts) {
|
|
2398
2461
|
await copyFile(
|
|
2399
|
-
join(
|
|
2400
|
-
dirname(findPackageJSON("anchorme", import.meta.url)),
|
|
2401
|
-
"dist/browser/anchorme.min.js"
|
|
2402
|
-
),
|
|
2462
|
+
join(thisModuleFolderPath, "dist/frontend_libraries/anchorme.min.js"),
|
|
2403
2463
|
join(outputPath, "js/anchorme.min.js")
|
|
2404
2464
|
);
|
|
2405
2465
|
}
|
|
2406
2466
|
if (config.showMap) {
|
|
2407
2467
|
await copyFile(
|
|
2408
|
-
join(
|
|
2409
|
-
dirname(findPackageJSON("maplibre-gl", import.meta.url)),
|
|
2410
|
-
"dist/maplibre-gl.js"
|
|
2411
|
-
),
|
|
2468
|
+
join(thisModuleFolderPath, "dist/frontend_libraries/maplibre-gl.js"),
|
|
2412
2469
|
join(outputPath, "js/maplibre-gl.js")
|
|
2413
2470
|
);
|
|
2414
2471
|
await copyFile(
|
|
2415
|
-
join(
|
|
2416
|
-
dirname(findPackageJSON("maplibre-gl", import.meta.url)),
|
|
2417
|
-
"dist/maplibre-gl.css"
|
|
2418
|
-
),
|
|
2472
|
+
join(thisModuleFolderPath, "dist/frontend_libraries/maplibre-gl.css"),
|
|
2419
2473
|
join(outputPath, "css/maplibre-gl.css")
|
|
2420
2474
|
);
|
|
2421
2475
|
await copyFile(
|
|
2422
2476
|
join(
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
"@maplibre/maplibre-gl-geocoder",
|
|
2426
|
-
import.meta.url
|
|
2427
|
-
)
|
|
2428
|
-
),
|
|
2429
|
-
"dist/maplibre-gl-geocoder.js"
|
|
2477
|
+
thisModuleFolderPath,
|
|
2478
|
+
"dist/frontend_libraries/maplibre-gl-geocoder.js"
|
|
2430
2479
|
),
|
|
2431
2480
|
join(outputPath, "js/maplibre-gl-geocoder.js")
|
|
2432
2481
|
);
|
|
2433
2482
|
await copyFile(
|
|
2434
2483
|
join(
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
"@maplibre/maplibre-gl-geocoder",
|
|
2438
|
-
import.meta.url
|
|
2439
|
-
)
|
|
2440
|
-
),
|
|
2441
|
-
"dist/maplibre-gl-geocoder.css"
|
|
2484
|
+
thisModuleFolderPath,
|
|
2485
|
+
"dist/frontend_libraries/maplibre-gl-geocoder.css"
|
|
2442
2486
|
),
|
|
2443
2487
|
join(outputPath, "css/maplibre-gl-geocoder.css")
|
|
2444
2488
|
);
|