150 lines
3.3 KiB
JavaScript

import he from "hyper-express"
import rtengineng from "../../classes/rtengineng"
import getRouteredFunctions from "../../utils/getRouteredFunctions"
import flatRouteredFunctions from "../../utils/flatRouteredFunctions"
export default class HyperExpressEngineNG {
constructor(params, ctx) {
this.params = params
this.ctx = ctx
}
app = null
ws = null
router = null
initialize = async (params) => {
console.warn(
`hyper-express-ng is a experimental engine, some features may not be available or work properly!`,
)
const serverParams = {
max_body_length: 50 * 1024 * 1024, //50MB in bytes,
}
if (params.ssl) {
serverParams.key_file_name = params.ssl?.key ?? null
serverParams.cert_file_name = params.ssl?.cert ?? null
}
this.app = new he.Server(serverParams)
this.router = new he.Router()
// create a router map
if (typeof this.router.map !== "object") {
this.router.map = {}
}
await this.router.any("*", (req, res) => {
return res.status(404).json({
code: 404,
message: "Not found",
})
})
await this.app.use(async (req, res, next) => {
if (req.method === "OPTIONS") {
// handle cors
if (params.ignoreCors) {
res.setHeader("Access-Control-Allow-Methods", "*")
res.setHeader("Access-Control-Allow-Origin", "*")
res.setHeader("Access-Control-Allow-Headers", "*")
}
return res.status(204).end()
}
// register body parser
if (req.headers["content-type"]) {
if (
!req.headers["content-type"].startsWith(
"multipart/form-data",
)
) {
req.body = await req.urlencoded()
req.body = await req.json(req.body)
}
}
})
if (params.enableWebsockets) {
this.ws = new rtengineng({
onUpgrade: params.handleWsUpgrade,
onConnection: params.handleWsConnection,
onDisconnect: params.handleWsDisconnect,
})
await this.ws.attach(this)
}
}
listen = async (params) => {
if (process.env.lb_service) {
let pathOverrides = Object.keys(this.router.map).map((key) => {
return key.split("/")[1]
})
// remove duplicates
pathOverrides = [...new Set(pathOverrides)]
// remove "" and _map
pathOverrides = pathOverrides.filter((key) => {
if (key === "" || key === "_map") {
return false
}
return true
})
if (params.enableWebsockets) {
process.send({
type: "router:ws:register",
id: process.env.lb_service.id,
index: process.env.lb_service.index,
data: {
namespace: params.refName,
listen_port: this.params.listen_port,
ws_path: params.wsPath ?? "/",
},
})
}
if (process.send) {
// try to send router map to host
process.send({
type: "router:register",
id: process.env.lb_service.id,
index: process.env.lb_service.index,
data: {
router_map: this.router.map,
path_overrides: pathOverrides,
listen: {
ip: this.params.listen_ip,
port: this.params.listen_port,
},
},
})
}
}
await this.app.listen(this.params.listen_port)
}
// close must be synchronous
close = () => {
if (this.ws && typeof this.ws.close === "function") {
this.ws.close()
}
if (typeof this.app.close === "function") {
this.app.close()
}
if (typeof this.ctx.onClose === "function") {
this.ctx.onClose()
}
}
}