Pull Reqwest Sprint 1 #3
23
app.js
23
app.js
@@ -1 +1,22 @@
|
|||||||
//builds
|
import express from "express";
|
||||||
|
import cors from "cors";
|
||||||
|
import vehiclesRouter from "./src/routes/vehicles.js";
|
||||||
|
import routesRouter from "./src/routes/routes.js";
|
||||||
|
|
||||||
|
const app = express();
|
||||||
|
app.use(cors());
|
||||||
|
app.use(express.json());
|
||||||
|
|
||||||
|
const base = "/api/v0";
|
||||||
|
|
||||||
|
app.get(`${base}/`, (req, res) => {
|
||||||
|
res.json({status: "ok", version: "v0", ts: new Date().toISOString()});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.use(`${base}/vehicles`, vehiclesRouter);
|
||||||
|
|
||||||
|
app.use(base, routesRouter);
|
||||||
|
|
||||||
|
app.get("/", (req, res) => res.redirect(`${base}/`));
|
||||||
|
|
||||||
|
export default app;
|
||||||
|
|||||||
23
package-lock.json
generated
23
package-lock.json
generated
@@ -9,6 +9,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"cors": "^2.8.5",
|
||||||
"express": "^5.1.0"
|
"express": "^5.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -123,6 +124,19 @@
|
|||||||
"node": ">=6.6.0"
|
"node": ">=6.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cors": {
|
||||||
|
"version": "2.8.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||||
|
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"object-assign": "^4",
|
||||||
|
"vary": "^1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.4.3",
|
"version": "4.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||||
@@ -506,6 +520,15 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/object-assign": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/object-inspect": {
|
"node_modules/object-inspect": {
|
||||||
"version": "1.13.4",
|
"version": "1.13.4",
|
||||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
||||||
|
|||||||
@@ -14,8 +14,9 @@
|
|||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"type": "commonjs",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"cors": "^2.8.5",
|
||||||
"express": "^5.1.0"
|
"express": "^5.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -3,6 +3,5 @@
|
|||||||
"route_id": "701",
|
"route_id": "701",
|
||||||
"start_location": "Draper City Center",
|
"start_location": "Draper City Center",
|
||||||
"end_location": "Salt Lake Central"
|
"end_location": "Salt Lake Central"
|
||||||
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,8 +1,106 @@
|
|||||||
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
vehicleData=require('./data/vehicles.json');
|
const dataDir = path.join(process.cwd(), "src", "dal", "data");
|
||||||
|
|
||||||
exports.DAL={
|
function readJSON(name) {
|
||||||
getVehicles:function() {
|
try {
|
||||||
return vehicleData;
|
const p = path.join(dataDir, name);
|
||||||
},
|
if (!fs.existsSync(p)) return null;
|
||||||
};
|
const raw = fs.readFileSync(p, "utf8");
|
||||||
|
return JSON.parse(raw);
|
||||||
|
} catch (err) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getVehicles() {
|
||||||
|
return readJSON("vehicles.json") || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getVehicleById(id) {
|
||||||
|
if (id == null) return null;
|
||||||
|
const vehicles = getVehicles();
|
||||||
|
|
||||||
|
return vehicles.find(v => String(v.vehicleId) === String(id)) || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRoutes() {
|
||||||
|
const explicit = readJSON("routes.json");
|
||||||
|
if (Array.isArray(explicit) && explicit.length) return explicit;
|
||||||
|
|
||||||
|
const vehicles = getVehicles();
|
||||||
|
const map = new Map();
|
||||||
|
vehicles.forEach(v => {
|
||||||
|
const key = String(v.routeNum ?? "");
|
||||||
|
if (!map.has(key)) {
|
||||||
|
map.set(key, {
|
||||||
|
routeId: key,
|
||||||
|
routeName: v.routeName ?? null,
|
||||||
|
startTime: null,
|
||||||
|
endTime: null,
|
||||||
|
trains: []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
map.get(key).trains.push(v.vehicleId);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return Array.from(map.values());
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRouteById(routeId) {
|
||||||
|
if (routeId == null) return null;
|
||||||
|
const routes = getRoutes();
|
||||||
|
|
||||||
|
return routes.find(r => String(r.routeId) === String(routeId)) || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRoutePathsMap() {
|
||||||
|
const raw = readJSON("routepaths.json");
|
||||||
|
|
||||||
|
return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRoutePath(routeId) {
|
||||||
|
if (routeId == null) return null;
|
||||||
|
const map = getRoutePathsMap();
|
||||||
|
const keys = Object.keys(map || {});
|
||||||
|
const foundKey = keys.find(k => String(k) === String(routeId));
|
||||||
|
|
||||||
|
return foundKey ? map[foundKey] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getStations() {
|
||||||
|
return readJSON("stations.json") || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getStopsByRoute(routeId) {
|
||||||
|
if (routeId == null) return [];
|
||||||
|
const stations = getStations();
|
||||||
|
|
||||||
|
if (!Array.isArray(stations)) return [];
|
||||||
|
return stations.filter(s => {
|
||||||
|
const lines = s.lines ?? s.lines_arr ?? s.line_ids ?? null;
|
||||||
|
if (!Array.isArray(lines)) return false;
|
||||||
|
|
||||||
|
return lines.map(String).includes(String(routeId));
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getStationById(stationId) {
|
||||||
|
if (stationId == null) return null;
|
||||||
|
const stations = getStations();
|
||||||
|
|
||||||
|
if (!Array.isArray(stations)) return null;
|
||||||
|
return stations.find(s => {
|
||||||
|
if (s.stop_id && String(s.stop_id) === String(stationId)) return true;
|
||||||
|
if (s.stationId && String(s.stationId) === String(stationId)) return true;
|
||||||
|
if (s.id && String(s.id) === String(stationId)) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}) || null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,52 @@
|
|||||||
// - /api/v0/routes
|
import express from "express";
|
||||||
// - /api/v0/route/:id
|
import * as dal from "../dal/staticDal.js";
|
||||||
// - /api/v0/stops/:id
|
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
router.get("/routes", (req, res) => {
|
||||||
|
const routes = dal.getRoutes();
|
||||||
|
|
||||||
|
res.json({meta: {returned: routes.length}, data: routes});
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get("/routes/:routeId", (req, res) => {
|
||||||
|
const routeId = req.params.routeId;
|
||||||
|
let route = dal.getRouteById(routeId) ?? null;
|
||||||
|
|
||||||
|
if (route === null) {
|
||||||
|
const all = dal.getRoutes();
|
||||||
|
route = all.find(r => {
|
||||||
|
const rid = r.route_id ?? r.routeId ?? r.route;
|
||||||
|
return rid != null && String(rid) === String(routeId);
|
||||||
|
}) ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const routePath = dal.getRoutePath(routeId) ?? null;
|
||||||
|
let stations = dal.getStopsByRoute(routeId) ?? [];
|
||||||
|
|
||||||
|
res.json({data: {route, routePath, stations}});
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get("/routes/:routeId/stations", (req, res) => {
|
||||||
|
const routeId = req.params.routeId;
|
||||||
|
const stations = dal.getStopsByRoute(routeId) ?? [];
|
||||||
|
|
||||||
|
res.json({meta: {routeId: String(routeId), returned: stations.length}, data: stations});
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get("/stations", (req, res) => {
|
||||||
|
const route = req.query.route;
|
||||||
|
const stations = route ? (dal.getStopsByRoute(route) ?? []) : (dal.getStations() ?? []);
|
||||||
|
|
||||||
|
res.json({meta: {returned: stations.length}, data: stations});
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get("/station/:stationId", (req, res) => {
|
||||||
|
const stationId = req.params.stationId;
|
||||||
|
const station = dal.getStationById(stationId);
|
||||||
|
if (!station) return res.status(404).json({error: "Station Was Not Found"});
|
||||||
|
|
||||||
|
res.json({data: station});
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
||||||
|
|||||||
@@ -1 +1,48 @@
|
|||||||
// - /api/v0/vehicles/:id
|
import express from "express";
|
||||||
|
import * as dal from "../dal/staticDal.js";
|
||||||
|
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
router.get("/", (req, res) => {
|
||||||
|
let vehicles = dal.getVehicles();
|
||||||
|
|
||||||
|
const {routeNum, routeName, destination, minLat, maxLat, minLng, maxLng, limit} = req.query;
|
||||||
|
|
||||||
|
if (routeNum) vehicles = vehicles.filter(v => String(v.routeNum) === String(routeNum));
|
||||||
|
if (routeName) vehicles = vehicles.filter(v => v.routeName && v.routeName.toLowerCase().includes(String(routeName).toLowerCase()));
|
||||||
|
if (destination) vehicles = vehicles.filter(v => v.destination && v.destination.toLowerCase().includes(String(destination).toLowerCase()));
|
||||||
|
|
||||||
|
if (minLat || maxLat || minLng || maxLng) {
|
||||||
|
const minLatN = parseFloat(minLat ?? -90);
|
||||||
|
const maxLatN = parseFloat(maxLat ?? 90);
|
||||||
|
const minLngN = parseFloat(minLng ?? -180);
|
||||||
|
const maxLngN = parseFloat(maxLng ?? 180);
|
||||||
|
|
||||||
|
vehicles = vehicles.filter(v => {
|
||||||
|
const lat = parseFloat(v.location?.latitude);
|
||||||
|
const lng = parseFloat(v.location?.longitude);
|
||||||
|
|
||||||
|
return lat >= minLatN && lat <= maxLatN && lng >= minLngN && lng <= maxLngN;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
let returned = vehicles.length;
|
||||||
|
if (limit) {
|
||||||
|
const lim = Math.max(1, Math.min(1000, parseInt(limit, 10) || 100));
|
||||||
|
|
||||||
|
vehicles = vehicles.slice(0, lim);
|
||||||
|
returned = vehicles.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.json({meta: {returned}, data: vehicles});
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get("/:id", (req, res) => {
|
||||||
|
const v = dal.getVehicleById(req.params.id);
|
||||||
|
if (!v) return res.status(404).json({error: "Vehicle Was Not Found"});
|
||||||
|
|
||||||
|
res.json({data: v});
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
||||||
|
|||||||
18
start.js
18
start.js
@@ -1,15 +1,7 @@
|
|||||||
//Starts
|
//Starts
|
||||||
const express = require('express')
|
import app from "./app.js";
|
||||||
const { DAL } = require('./src/dal/staticDal')
|
|
||||||
const app = express()
|
|
||||||
const port = 3000
|
|
||||||
|
|
||||||
app.get('/', (req, res) => {
|
|
||||||
res.json(DAL.getVehicles())
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
app.listen(port, () => {
|
|
||||||
console.log(`Example app listening on port ${port}`)
|
|
||||||
})
|
|
||||||
|
|
||||||
|
const PORT = process.env.PORT || 3000;
|
||||||
|
app.listen(PORT, () => {
|
||||||
|
console.log(`Transit API http://localhost:${PORT}`);
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user