UNPKG

gtfs-to-html

Version:

Build human readable transit timetables as HTML, PDF or CSV from GTFS

121 lines (119 loc) 4.66 kB
import { A as isGtfsToHtmlError, D as GtfsToHtmlErrorCode, E as GtfsToHtmlErrorCategory, T as GtfsToHtmlError, _ as setDefaultConfig, a as getPathToViewsFolder, c as untildify, d as generateOverviewHTML, g as getTimetablePagesForAgency, h as getFormattedTimetablePage, m as generateTimetableHTML, u as formatTimetableLabel } from "../file-utils-CTeUEN3B.js"; import { dirname, join } from "node:path"; import { openDb } from "gtfs"; import { readFileSync } from "node:fs"; import { fileURLToPath } from "node:url"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; import express from "express"; //#region src/app/index.ts const argv = yargs(hideBin(process.argv)).option("c", { alias: "configPath", describe: "Path to config file", default: "./config.json", type: "string" }).parseSync(); const app = express(); const configPath = argv.configPath || join(process.cwd(), "config.json"); const config = setDefaultConfig(JSON.parse(readFileSync(configPath, "utf8"))); config.noHead = false; config.assetPath = "/"; config.logFunction = console.log; try { openDb(config); } catch (error) { console.error(`Unable to open sqlite database "${config.sqlitePath}" defined as \`sqlitePath\` config.json. Ensure the parent directory exists and run gtfs-to-html to import GTFS before running this app.`); throw new GtfsToHtmlError(`Unable to open sqlite database "${config.sqlitePath}"`, { code: "GTFS_TO_HTML_DATABASE_OPEN_FAILED", category: "database", details: { sqlitePath: config.sqlitePath, dbCode: error?.code }, cause: error }); } app.set("views", getPathToViewsFolder(config)); app.set("view engine", "pug"); app.use((req, res, next) => { console.log(`${req.method} ${req.url}`); next(); }); const staticAssetPath = config.templatePath === void 0 ? getPathToViewsFolder(config) : untildify(config.templatePath); app.use(express.static(staticAssetPath)); const browserAssetsPath = join(dirname(fileURLToPath(import.meta.url)), "../browser"); app.use("/js", express.static(browserAssetsPath)); app.use("/css", express.static(browserAssetsPath)); app.get("/", async (req, res, next) => { try { const timetablePages = []; const timetablePageIds = getTimetablePagesForAgency(config).map((timetablePage) => timetablePage.timetable_page_id); for (const timetablePageId of timetablePageIds) { if (!timetablePageId) continue; const timetablePage = await getFormattedTimetablePage(timetablePageId, config); if (!timetablePage.consolidatedTimetables || timetablePage.consolidatedTimetables.length === 0) { console.error(`No timetables found for timetable_page_id=${timetablePage.timetable_page_id}`); continue; } timetablePage.relativePath = `/timetables/${timetablePage.timetable_page_id}`; for (const timetable of timetablePage.consolidatedTimetables) timetable.timetable_label = formatTimetableLabel(timetable); timetablePages.push(timetablePage); } const html = await generateOverviewHTML(timetablePages, config); res.send(html); } catch (error) { next(error); } }); app.get("/timetables/:timetablePageId", async (req, res, next) => { const { timetablePageId } = req.params; if (!timetablePageId) { res.status(400).send("No timetablePageId provided"); return; } try { const timetablePage = await getFormattedTimetablePage(timetablePageId, config); if (!timetablePage || !timetablePage.consolidatedTimetables || timetablePage.consolidatedTimetables.length === 0) { res.status(404).send("Timetable page not found"); return; } const html = await generateTimetableHTML(timetablePage, config); res.send(html); } catch (error) { if (isGtfsToHtmlError(error) && error.code === "GTFS_TO_HTML_QUERY_RESULT_NOT_FOUND") { res.status(404).send("Timetable page not found"); return; } next(error); } }); app.use((req, res) => { res.status(404).send("Not Found"); }); app.use((err, req, res, next) => { console.error(err.stack); res.status(500).send("Something broke!"); }); const startServer = async (port) => { try { await new Promise((resolve, reject) => { const server = app.listen(port).once("listening", () => { console.log(`Express server listening on port ${port}`); resolve(); }).once("error", (err) => { if (err.code === "EADDRINUSE") { console.log(`Port ${port} is in use, trying ${port + 1}`); server.close(); resolve(startServer(port + 1)); } else reject(err); }); }); } catch (err) { console.error("Failed to start server:", err); process.exit(1); } }; startServer(process.env.PORT ? parseInt(process.env.PORT, 10) : 3e3); //#endregion export { }; //# sourceMappingURL=index.js.map