-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
api.js
113 lines (97 loc) · 3.39 KB
/
api.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// todo: use import assertions once they're supported by Node.js & ESLint
// https://github.com/tc39/proposal-import-assertions
import {createRequire} from 'node:module'
const require = createRequire(import.meta.url)
import {dirname, join as pathJoin} from 'path'
import {fileURLToPath} from 'node:url'
import {
createBvgHafas,
defaults as bvgHafasDefaults,
} from 'bvg-hafas'
import {createWriteStream} from 'node:fs'
import createHealthCheck from 'hafas-client-health-check'
import Redis from 'ioredis'
import {createCachedHafasClient as withCache} from 'cached-hafas-client'
import {createRedisStore as redisStore} from 'cached-hafas-client/stores/redis.js'
import {createHafasRestApi as createApi} from 'hafas-rest-api'
import serveStatic from 'serve-static'
const pkg = require('./package.json')
import {createRoute as stops} from './routes/stops.js'
const __dirname = dirname(fileURLToPath(import.meta.url))
const docsRoot = pathJoin(__dirname, 'docs')
const berlinFriedrichstr = '900100001'
const customBvgProfile = {
...bvgHafasDefaults.profile,
}
// todo: DRY env var check with localaddress-agent/random-from-env.js
// Currently, this is impossible: localaddress-agent is an optional dependencies, so we rely on it to check the env var.
if (process.env.RANDOM_LOCAL_ADDRESSES_RANGE) {
const {randomLocalAddressAgent} = await import('localaddress-agent/random-from-env.js')
customBvgProfile.transformReq = (_, req) => {
req.agent = randomLocalAddressAgent
return req
}
}
if (process.env.HAFAS_REQ_RES_LOG_FILE) {
const hafasLogPath = process.env.HAFAS_REQ_RES_LOG_FILE
const hafasLog = createWriteStream(hafasLogPath, {flags: 'a'}) // append-only
hafasLog.on('error', (err) => console.error('hafasLog error', err))
customBvgProfile.logRequest = (ctx, req, reqId) => {
console.error(reqId, 'req', req.body + '') // todo: remove
hafasLog.write(JSON.stringify([reqId, 'req', req.body + '']) + '\n')
}
customBvgProfile.logResponse = (ctx, res, body, reqId) => {
console.error(reqId, 'res', body + '') // todo: remove
hafasLog.write(JSON.stringify([reqId, 'res', body + '']) + '\n')
}
}
const modifyRoutes = (routes, hafas, config) => ({
...routes,
'/stops': stops(hafas, config),
})
let hafas = createBvgHafas(pkg.name, {
profile: customBvgProfile,
})
let healthCheck = createHealthCheck(hafas, berlinFriedrichstr)
if (process.env.REDIS_URL) {
const redis = new Redis(process.env.REDIS_URL || null)
hafas = withCache(hafas, redisStore(redis))
const checkHafas = healthCheck
const checkRedis = () => new Promise((resolve, reject) => {
setTimeout(reject, 1000, new Error('didn\'t receive a PONG'))
redis.ping().then(
res => resolve(res === 'PONG'),
reject,
)
})
healthCheck = async () => (
(await checkHafas()) === true &&
(await checkRedis()) === true
)
}
const config = {
hostname: process.env.HOSTNAME || 'localhost',
port: process.env.PORT ? parseInt(process.env.PORT) : 3000,
name: pkg.name,
description: pkg.description,
version: pkg.version,
homepage: pkg.homepage,
docsLink: 'https://github.com/derhuerst/bvg-rest/blob/6/docs/readme.md',
openapiSpec: true,
logging: true,
aboutPage: false,
etags: 'strong',
csp: `default-src 'none' style-src 'self' 'unsafe-inline' img-src https:`,
healthCheck,
modifyRoutes,
}
const api = await createApi(hafas, config, (api) => {
api.use('/', serveStatic(docsRoot, {
extensions: ['html', 'htm'],
}))
})
export {
hafas,
config,
api,
}