Files
Express_developer_docs/server.js
2026-05-22 11:08:17 +05:30

80 lines
2.5 KiB
JavaScript

// Production server for the Xpress developer docs.
//
// What this does:
// 1. Reads HASURA_ADMIN_SECRET from .env.local (server-side, never bundled).
// 2. Proxies /api/* requests to https://api.workolik.com/api/*, injecting
// the x-hasura-admin-secret header on the way out.
// 3. Serves the built React app from dist/ (SPA fallback to index.html).
//
// The browser never receives the secret. To run:
// npm run build # builds dist/
// npm start # starts this server on PORT (default 3000)
import express from 'express'
import { createProxyMiddleware } from 'http-proxy-middleware'
import { fileURLToPath } from 'node:url'
import path from 'node:path'
import 'dotenv/config'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const PORT = Number(process.env.PORT) || 3000
const SECRET = (process.env.HASURA_ADMIN_SECRET || 'nearle-admin-secret').trim()
const TARGET_LEGACY = 'https://api.workolik.com'
const TARGET_REST = 'https://jupiter.nearle.app'
if (!SECRET) {
console.warn('[xpress-docs] WARNING: HASURA_ADMIN_SECRET is not set. Proxied API calls will be sent without auth.')
}
const app = express()
const commonProxyOptions = {
changeOrigin: true,
secure: true,
on: {
proxyReq: (proxyReq) => {
if (SECRET) proxyReq.setHeader('x-hasura-admin-secret', SECRET)
},
error: (err, _req, res) => {
console.error('[xpress-docs] proxy error:', err.message)
if (!res.headersSent) {
res.writeHead(502, { 'Content-Type': 'application/json' })
}
res.end(JSON.stringify({ error: 'proxy_error', message: err.message }))
}
}
}
app.use('/api', createProxyMiddleware({
...commonProxyOptions,
target: TARGET_LEGACY,
pathRewrite: (p) => '/api' + p
}))
app.use('/live', createProxyMiddleware({
...commonProxyOptions,
target: TARGET_REST,
pathRewrite: (p) => '/live' + p
}))
app.use('/v1', createProxyMiddleware({
...commonProxyOptions,
target: TARGET_LEGACY,
pathRewrite: (p) => '/v1' + p
}))
// Built React app
const distDir = path.join(__dirname, 'dist')
app.use(express.static(distDir))
app.get('*', (_req, res) => {
res.sendFile(path.join(distDir, 'index.html'))
})
app.listen(PORT, () => {
console.log(`[xpress-docs] listening on http://localhost:${PORT}`)
console.log(`[xpress-docs] proxying /api/* -> ${TARGET_LEGACY}/api/*`)
console.log(`[xpress-docs] proxying /live/* -> ${TARGET_REST}/live/*`)
console.log(`[xpress-docs] proxying /v1/* -> ${TARGET_LEGACY}/v1/*`)
console.log(`[xpress-docs] admin secret: ${SECRET ? 'loaded' : 'NOT SET'}`)
})