diff --git a/api.js b/api.js deleted file mode 100644 index d4622f9..0000000 --- a/api.js +++ /dev/null @@ -1,61 +0,0 @@ -'use strict' - -const express = require('express') -const hsts = require('hsts') -const morgan = require('morgan') -const shorthash = require('shorthash').unique -const corser = require('corser') -const compression = require('compression') -const nocache = require('nocache') - -const pkg = require('./package.json') -const departures = require('./lib/departures') -const journeys = require('./lib/journeys') -const stations = require('./lib/stations') -const allStations = require('./lib/all-stations') - - - -const api = express() -module.exports = api - -api.use(hsts({maxAge: 24 * 60 * 60 * 1000})) - -morgan.token('id', (req, res) => req.headers['x-identifier'] || shorthash(req.ip)) -api.use(morgan(':date[iso] :id :method :url :status :response-time ms')) - -const allowed = corser.simpleRequestHeaders.concat(['User-Agent', 'X-Identifier']) -api.use(corser.create({requestHeaders: allowed})) // CORS - -api.use(compression()) - -api.use((req, res, next) => { - if (!res.headersSent) - res.setHeader('X-Powered-By', pkg.name + ' ' + pkg.homepage) - next() -}) - - - -const noCache = nocache() - -api.get('/stations/:id/departures', noCache, departures) -api.get('/journeys', noCache, journeys) -api.get('/stations', stations) -api.get('/stations/all', allStations) - - - -api.use((err, req, res, next) => { - if (process.env.NODE_ENV === 'dev') console.error(err) - if (res.headersSent) return next(err) - - let msg = err.message - let code = err.statusCode - if (err.isHafasError) { - msg = 'DB error: ' + msg - code = 502 - } - res.status(code).json({error: true, msg}) - next() -}) diff --git a/index.js b/index.js index c4d96ad..be32e8d 100644 --- a/index.js +++ b/index.js @@ -1,18 +1,37 @@ 'use strict' -const http = require('http') +const hafas = require('hafas-client') +const dbProfile = require('hafas-client/p/db') +const createApi = require('hafas-rest-api') +const createLogging = require('hafas-rest-api/logging') +const hsts = require('hsts') -const api = require('./api') -const server = http.createServer(api) +const pkg = require('./package.json') +const stations = require('./lib/stations') +const allStations = require('./lib/all-stations') -const port = process.env.PORT || 3000 -const hostname = process.env.HOSTNAME || '' +const config = { + hostname: process.env.HOSTNAME || '1.db.transport.rest', + port: process.env.PORT || 3000, + name: pkg.name, + homepage: pkg.homepage +} -server.listen(port, (err) => { +const client = hafas(dbProfile) +const api = createApi(client, config) + +api.use(createLogging()) + +api.get('/stations', stations) +api.get('/stations/all', allStations) + +module.exports = api + +api.listen(config.port, (err) => { if (err) { console.error(err) - process.exit(1) + process.exitCode = 1 } else { - console.info(`Listening on ${hostname}:${port}.`) + console.info(`Listening on ${config.hostname}:${config.port}.`) } }) diff --git a/lib/departures.js b/lib/departures.js deleted file mode 100644 index 4a15d10..0000000 --- a/lib/departures.js +++ /dev/null @@ -1,59 +0,0 @@ -'use strict' - -const parse = require('parse-messy-time') -const hafas = require('db-hafas') -const createDepsInDirection = require('hafas-departures-in-direction') - -const depsInDirection = createDepsInDirection(hafas.departures, hafas.journeyPart) - -const err400 = (msg) => { - const err = new Error(msg) - err.statusCode = 400 - return err -} - -const isNumber = /^\d+$/ - -const departures = (req, res, next) => { - const id = req.params.id.trim() - if (!isNumber.test(id)) return next(err400('Invalid station id.')) - - const opt = {} - if ('when' in req.query) { - opt.when = isNumber.test(req.query.when) - ? new Date(req.query.when * 1000) - : parse(req.query.when) - } - - let task - if ('nextStation' in req.query) { - const nS = req.query.nextStation - if (!isNumber.test(nS)) return next(err400('Invalid nextStation parameter.')) - - if ('results' in req.query) { - const r = +req.query.results - if (Number.isNaN(r)) return next(err400('Invalid results parameter.')) - opt.results = Math.max(0, Math.min(r, 20)) - } - if ('maxQueries' in req.query) { - const mQ = +req.query.maxQueries - if (Number.isNaN(mQ)) return next(err400('Invalid maxQueries parameter.')) - opt.maxQueries = Math.max(0, Math.min(mQ, 30)) - } - - task = depsInDirection(id, nS, opt) - } else { - if ('direction' in req.query) opt.direction = req.query.direction - if ('duration' in req.query) opt.duration = +req.query.duration - task = hafas.departures(id, opt) - } - - task - .then((deps) => { - res.json(deps) - next() - }) - .catch(next) -} - -module.exports = departures diff --git a/lib/journeys.js b/lib/journeys.js deleted file mode 100644 index b4a78a5..0000000 --- a/lib/journeys.js +++ /dev/null @@ -1,84 +0,0 @@ -'use strict' - -const time = require('parse-messy-time') -const parse = require('cli-native').to -const hafas = require('db-hafas') - -const err400 = (msg) => { - const err = new Error(msg) - err.statusCode = 400 - return err -} - -const location = (q, t) => { - if (q[t]) return q[t] // station id - else if (q[t + '.latitude'] && q[t + '.longitude']) { - const l = { - type: 'address', - name: 'foo bar', // todo - latitude: +q[t + `.latitude`], - longitude: +q[t + `.longitude`] - } - if (q[t + '.name']) l.name = q[t + '.name'] - if (q[t + '.id']) { - l.type = 'poi' - l.id = q[t + '.id'] - } - return l - } - else return null -} - -const isNumber = /^\d+$/ - -const journeys = (req, res, next) => { - const from = location(req.query, 'from') - if (!from) return next(err400('Missing origin.')) - const to = location(req.query, 'to') - if (!to) return next(err400('Missing destination.')) - - const opt = {} - if ('when' in req.query) { - opt.when = isNumber.test(req.query.when) - ? new Date(req.query.when * 1000) - : time(req.query.when) - } - if ('results' in req.query) { - opt.results = +req.query.results - } - if ('via' in req.query) { - opt.via = req.query.via - } - if ('passedStations' in req.query) { - opt.passedStations = parse(req.query.passedStations) - } - if ('transfers' in req.query) { - opt.transfers = +req.query.transfers - } - if ('transferTime' in req.query) { - opt.transferTime = +req.query.transferTime - } - if ('accessibility' in req.query) { - opt.accessibility = req.query.accessibility - } - if ('bike' in req.query) { - opt.bike = parse(req.query.bike) - } - // todo: loyaltyCard - - const products = [ - 'suburban', 'subway', 'tram', 'bus', 'ferry', 'express', 'regional' - ].reduce((acc, type) => { - if (type in req.query) acc[type] = parse(req.query[type]) - return acc - }, {}) - if (Object.keys(products)) opt.products = products - - hafas.journeys(from, to, opt) - .then((journeys) => { - res.json(journeys) - next() - }, (err) => next(err)) -} - -module.exports = journeys diff --git a/package.json b/package.json index 1bafcd4..ce7b3d2 100644 --- a/package.json +++ b/package.json @@ -28,19 +28,12 @@ }, "dependencies": { "cli-native": "^1.0.0", - "compression": "^1.7.1", - "corser": "^2.0.1", - "db-hafas": "^1.1.0", "db-stations": "^1.24.0", "db-stations-autocomplete": "^1.0.0", - "express": "^4.16.2", - "hafas-departures-in-direction": "^0.1.0", + "hafas-client": "^2.0.0-alpha.3", + "hafas-rest-api": "0.1.0-alpha.2", "hsts": "^2.1.0", - "morgan": "^1.9.0", - "ndjson": "^1.5.0", - "nocache": "^2.0.0", - "parse-messy-time": "^2.1.0", - "shorthash": "^0.0.2" + "ndjson": "^1.5.0" }, "scripts": { "start": "node index.js"