mirror of
https://github.com/ragestudio/linebridge.git
synced 2025-06-09 10:34:17 +00:00
refactor names
This commit is contained in:
parent
3d1513d2ca
commit
ba42538c1d
@ -1,18 +1,13 @@
|
||||
const fs = require("fs")
|
||||
|
||||
const http = require("http")
|
||||
const https = require("https")
|
||||
|
||||
const io = require("socket.io")
|
||||
|
||||
const tokenizer = require("corenode/libs/tokenizer")
|
||||
const { randomWord } = require("@corenode/utils")
|
||||
|
||||
const { serverManifest, outputServerError, internalConsole } = require("./lib")
|
||||
const InternalConsole = global.InternalInternalConsole = internalConsole
|
||||
|
||||
const builtInMiddlewares = []
|
||||
|
||||
const HTTPProtocolsInstances = {
|
||||
http: http,
|
||||
https: https,
|
||||
@ -30,70 +25,56 @@ const HTTPEngines = {
|
||||
},
|
||||
}
|
||||
|
||||
const linebridge_ascii = require("./linebridge_ascii.js")
|
||||
|
||||
class Server {
|
||||
constructor(params = {}, controllers = [], middlewares = {}) {
|
||||
constructor(params = {}, controllers = {}, middlewares = {}, headers = {}) {
|
||||
// register aliases
|
||||
this.params = {
|
||||
...global.DEFAULT_SERVER_PARAMS,
|
||||
...params
|
||||
}
|
||||
this.controllers = [
|
||||
|
||||
this.controllers = {
|
||||
...controllers
|
||||
]
|
||||
}
|
||||
this.middlewares = {
|
||||
...middlewares
|
||||
...middlewares.default ?? middlewares,
|
||||
}
|
||||
this.headers = {
|
||||
...global.DEFAULT_HEADERS,
|
||||
...this.params.headers
|
||||
...global.DEFAULT_SERVER_HEADERS,
|
||||
...headers
|
||||
}
|
||||
this.endpointsMap = {}
|
||||
|
||||
this.listenPort = this.params.port ?? 3010
|
||||
this.endpoints_map = {}
|
||||
|
||||
// TODO: Handle HTTPS and WSS
|
||||
this.HTTPAddress = `${this.params.protocol}://${global.LOCALHOST_ADDRESS}:${this.listenPort}`
|
||||
this.WSAddress = `${this.params.wsProtocol}://${global.LOCALHOST_ADDRESS}:${this.listenPort}`
|
||||
// fix and fulfill params
|
||||
this.params.listen_port = this.params.listen_port ?? 3000
|
||||
this.params.http_protocol = this.params.http_protocol ?? "http"
|
||||
this.params.ws_protocol = this.params.ws_protocol ?? "ws"
|
||||
|
||||
this.params.http_address = `${this.params.http_protocol}://${global.LOCALHOST_ADDRESS}:${this.params.listen_port}`
|
||||
this.params.ws_address = `${this.params.ws_protocol}://${global.LOCALHOST_ADDRESS}:${this.params.listen_port}`
|
||||
|
||||
//* set server basics
|
||||
// check if engine is supported
|
||||
if (typeof HTTPProtocolsInstances[this.params.protocol].createServer !== "function") {
|
||||
if (typeof HTTPProtocolsInstances[this.params.http_protocol]?.createServer !== "function") {
|
||||
throw new Error("Invalid HTTP protocol (Missing createServer function)")
|
||||
}
|
||||
|
||||
this.engineInstance = global.engineInstance = HTTPEngines[this.params.httpEngine]()
|
||||
this.httpInstance = global.httpInstance = HTTPProtocolsInstances[this.params.protocol].createServer({
|
||||
// create instances the 3 main instances of the server (Engine, HTTP, WebSocket)
|
||||
this.engine_instance = global.engine_instance = HTTPEngines[this.params.engine]()
|
||||
|
||||
this.http_instance = global.http_instance = HTTPProtocolsInstances[this.params.http_protocol].createServer({
|
||||
...this.params.httpOptions ?? {},
|
||||
}, this.engineInstance)
|
||||
this.wsInterface = global.wsInterface = {
|
||||
io: new io.Server(this.httpInstance),
|
||||
}, this.engine_instance)
|
||||
|
||||
this.websocket_instance = global.websocket_instance = {
|
||||
io: new io.Server(this.http_instance),
|
||||
map: {},
|
||||
eventsChannels: [],
|
||||
}
|
||||
|
||||
//? check if origin.server exists
|
||||
if (!fs.existsSync(serverManifest.filepath)) {
|
||||
serverManifest.create()
|
||||
}
|
||||
|
||||
//? check origin.server integrity
|
||||
const MANIFEST_DATA = global.MANIFEST_DATA = serverManifest.get()
|
||||
const MANIFEST_STAT = global.MANIFEST_STAT = serverManifest.stat()
|
||||
|
||||
if (typeof MANIFEST_DATA.created === "undefined") {
|
||||
InternalConsole.warn("Server generation file not contains an creation date")
|
||||
serverManifest.write({ created: Date.parse(MANIFEST_STAT.birthtime) })
|
||||
}
|
||||
|
||||
if (typeof MANIFEST_DATA.serverToken === "undefined") {
|
||||
InternalConsole.warn("Missing server token!")
|
||||
serverManifest.create()
|
||||
}
|
||||
|
||||
this.id = this.params.id ?? randomWord.generate() ?? "unavailable"
|
||||
this.usid = tokenizer.generateUSID()
|
||||
this.oskid = serverManifest.get("serverToken")
|
||||
|
||||
serverManifest.write({ lastStart: Date.now() })
|
||||
this.initializeManifest()
|
||||
|
||||
// handle silent mode
|
||||
global.consoleSilent = this.params.silent
|
||||
@ -107,39 +88,67 @@ class Server {
|
||||
}
|
||||
}
|
||||
|
||||
// handle exit events
|
||||
process.on("SIGTERM", this.cleanupProcess)
|
||||
process.on("SIGINT", this.cleanupProcess)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
initializeManifest = () => {
|
||||
// check if origin.server exists
|
||||
if (!fs.existsSync(serverManifest.filepath)) {
|
||||
serverManifest.create()
|
||||
}
|
||||
|
||||
// check origin.server integrity
|
||||
const MANIFEST_DATA = global.MANIFEST_DATA = serverManifest.get()
|
||||
const MANIFEST_STAT = global.MANIFEST_STAT = serverManifest.stat()
|
||||
|
||||
if (typeof MANIFEST_DATA.created === "undefined") {
|
||||
InternalConsole.warn("Server generation file not contains an creation date")
|
||||
serverManifest.write({ created: Date.parse(MANIFEST_STAT.birthtime) })
|
||||
}
|
||||
|
||||
if (typeof MANIFEST_DATA.server_token === "undefined") {
|
||||
InternalConsole.warn("Missing server token!")
|
||||
serverManifest.create()
|
||||
}
|
||||
|
||||
this.usid = tokenizer.generateUSID()
|
||||
this.server_token = serverManifest.get("server_token")
|
||||
|
||||
serverManifest.write({ last_start: Date.now() })
|
||||
}
|
||||
|
||||
initialize = async () => {
|
||||
InternalConsole.log(linebridge_ascii)
|
||||
InternalConsole.info(`🚀 Starting server...`)
|
||||
|
||||
//* set server defined headers
|
||||
this.initializeHeaders()
|
||||
|
||||
//* set server defined middlewares
|
||||
this.initializeMiddlewares()
|
||||
|
||||
//* register main index endpoint `/`
|
||||
await this.registerBaseEndpoints()
|
||||
this.initializeRequiredMiddlewares()
|
||||
|
||||
//* register controllers
|
||||
await this.initializeControllers()
|
||||
|
||||
//* register main index endpoint `/`
|
||||
await this.registerBaseEndpoints()
|
||||
|
||||
// initialize main socket
|
||||
this.wsInterface.io.on("connection", this.handleWSClientConnection)
|
||||
this.websocket_instance.io.on("connection", this.handleWSClientConnection)
|
||||
|
||||
// initialize http server
|
||||
await this.httpInstance.listen(this.listenPort, this.params.listen ?? "0.0.0.0")
|
||||
|
||||
await this.http_instance.listen(this.params.listen_port, this.params.listen_ip ?? "0.0.0.0", () => {
|
||||
// output server info
|
||||
InternalConsole.log(`✅ Server is up and running!`)
|
||||
this.OutputServerInfo()
|
||||
|
||||
// handle exit events
|
||||
process.on("SIGTERM", this.cleanupProcess)
|
||||
process.on("SIGINT", this.cleanupProcess)
|
||||
this.outputServerInfo()
|
||||
})
|
||||
}
|
||||
|
||||
initializeHeaders = () => {
|
||||
this.engineInstance.use((req, res, next) => {
|
||||
this.engine_instance.use((req, res, next) => {
|
||||
Object.keys(this.headers).forEach((key) => {
|
||||
res.setHeader(key, this.headers[key])
|
||||
})
|
||||
@ -148,18 +157,20 @@ class Server {
|
||||
})
|
||||
}
|
||||
|
||||
initializeMiddlewares = () => {
|
||||
const useMiddlewares = [...builtInMiddlewares, ...global.DEFAULT_MIDDLEWARES, ...(this.params.middlewares ?? [])]
|
||||
initializeRequiredMiddlewares = () => {
|
||||
const useMiddlewares = [...this.params.useMiddlewares ?? [], ...global.DEFAULT_MIDDLEWARES]
|
||||
|
||||
useMiddlewares.forEach((middleware) => {
|
||||
if (typeof middleware === "function") {
|
||||
this.engineInstance.use(middleware)
|
||||
this.engine_instance.use(middleware)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
initializeControllers = async () => {
|
||||
for await (let controller of this.controllers) {
|
||||
const controllers = Object.entries(this.controllers)
|
||||
|
||||
for await (let [key, controller] of controllers) {
|
||||
if (typeof controller !== "function") {
|
||||
throw new Error(`Controller must use the controller class!`)
|
||||
}
|
||||
@ -173,8 +184,8 @@ class Server {
|
||||
const ControllerInstance = new controller()
|
||||
|
||||
// get endpoints from controller (ComplexController)
|
||||
const HTTPEndpoints = ControllerInstance.getEndpoints()
|
||||
const WSEndpoints = ControllerInstance.getWSEndpoints()
|
||||
const HTTPEndpoints = ControllerInstance.__get_http_endpoints()
|
||||
const WSEndpoints = ControllerInstance.__get_ws_endpoints()
|
||||
|
||||
HTTPEndpoints.forEach((endpoint) => {
|
||||
this.registerHTTPEndpoint(endpoint, ...this.resolveMiddlewares(controller.useMiddlewares))
|
||||
@ -204,7 +215,7 @@ class Server {
|
||||
}
|
||||
|
||||
// check if method is supported
|
||||
if (typeof this.engineInstance[endpoint.method] !== "function") {
|
||||
if (typeof this.engine_instance[endpoint.method] !== "function") {
|
||||
throw new Error(`Method [${endpoint.method}] is not supported!`)
|
||||
}
|
||||
|
||||
@ -216,19 +227,19 @@ class Server {
|
||||
}
|
||||
|
||||
// make sure method has root object on endpointsMap
|
||||
if (typeof this.endpointsMap[endpoint.method] !== "object") {
|
||||
this.endpointsMap[endpoint.method] = {}
|
||||
if (typeof this.endpoints_map[endpoint.method] !== "object") {
|
||||
this.endpoints_map[endpoint.method] = {}
|
||||
}
|
||||
|
||||
// create model for http interface router
|
||||
const routeModel = [endpoint.route, ...middlewares, this.createHTTPRequestHandler(endpoint)]
|
||||
|
||||
// register endpoint to http interface router
|
||||
this.engineInstance[endpoint.method](...routeModel)
|
||||
this.engine_instance[endpoint.method](...routeModel)
|
||||
|
||||
// extend to map
|
||||
this.endpointsMap[endpoint.method] = {
|
||||
...this.endpointsMap[endpoint.method],
|
||||
this.endpoints_map[endpoint.method] = {
|
||||
...this.endpoints_map[endpoint.method],
|
||||
[endpoint.route]: {
|
||||
route: endpoint.route,
|
||||
enabled: endpoint.enabled ?? true,
|
||||
@ -239,9 +250,9 @@ class Server {
|
||||
registerWSEndpoint = (endpoint, ...execs) => {
|
||||
endpoint.nsp = endpoint.nsp ?? "/main"
|
||||
|
||||
this.wsInterface.eventsChannels.push([endpoint.nsp, endpoint.on, endpoint.dispatch])
|
||||
this.websocket_instance.eventsChannels.push([endpoint.nsp, endpoint.on, endpoint.dispatch])
|
||||
|
||||
this.wsInterface.map[endpoint.on] = {
|
||||
this.websocket_instance.map[endpoint.on] = {
|
||||
nsp: endpoint.nsp,
|
||||
channel: endpoint.on,
|
||||
}
|
||||
@ -261,53 +272,47 @@ class Server {
|
||||
fn: (req, res) => {
|
||||
return res.json({
|
||||
LINEBRIDGE_SERVER_VERSION: LINEBRIDGE_SERVER_VERSION,
|
||||
id: this.id,
|
||||
usid: this.usid,
|
||||
oskid: this.oskid,
|
||||
requestTime: new Date().getTime(),
|
||||
endpointsMap: this.endpointsMap,
|
||||
wsEndpointsMap: this.wsInterface.map,
|
||||
endpointsMap: this.endpoints_map,
|
||||
wsEndpointsMap: this.websocket_instance.map,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//* resolvers
|
||||
resolveMiddlewares = (middlewares) => {
|
||||
middlewares = Array.isArray(middlewares) ? middlewares : [middlewares]
|
||||
const middlewaresArray = []
|
||||
resolveMiddlewares = (requestedMiddlewares) => {
|
||||
requestedMiddlewares = Array.isArray(requestedMiddlewares) ? requestedMiddlewares : [requestedMiddlewares]
|
||||
|
||||
middlewares.forEach((middleware) => {
|
||||
if (typeof middleware === "string") {
|
||||
if (typeof this.middlewares[middleware] !== "function") {
|
||||
throw new Error(`Middleware ${middleware} not found!`)
|
||||
const execs = []
|
||||
|
||||
requestedMiddlewares.forEach((middlewareKey) => {
|
||||
if (typeof middlewareKey === "string") {
|
||||
if (typeof this.middlewares[middlewareKey] !== "function") {
|
||||
throw new Error(`Middleware ${middlewareKey} not found!`)
|
||||
}
|
||||
|
||||
middlewaresArray.push(this.middlewares[middleware])
|
||||
execs.push(this.middlewares[middlewareKey])
|
||||
}
|
||||
|
||||
if (typeof middleware === "function") {
|
||||
middlewaresArray.push(middleware)
|
||||
if (typeof middlewareKey === "function") {
|
||||
execs.push(middlewareKey)
|
||||
}
|
||||
})
|
||||
|
||||
return middlewaresArray
|
||||
return execs
|
||||
}
|
||||
|
||||
log = (...args) => {
|
||||
if (!this.params.silent) {
|
||||
InternalConsole.log(...args)
|
||||
}
|
||||
}
|
||||
|
||||
cleanupProcess = () => {
|
||||
this.log("🛑 Stopping server...")
|
||||
InternalConsole.log("🛑 Stopping server...")
|
||||
|
||||
if (typeof this.engineInstance.close === "function") {
|
||||
this.engineInstance.close()
|
||||
if (typeof this.engine_instance.close === "function") {
|
||||
this.engine_instance.close()
|
||||
}
|
||||
|
||||
this.wsInterface.io.close()
|
||||
this.websocket_instance.io.close()
|
||||
|
||||
process.exit(1)
|
||||
}
|
||||
@ -317,7 +322,7 @@ class Server {
|
||||
return async (req, res) => {
|
||||
try {
|
||||
// check if endpoint is disabled
|
||||
if (!this.endpointsMap[endpoint.method][endpoint.route].enabled) {
|
||||
if (!this.endpoints_map[endpoint.method][endpoint.route].enabled) {
|
||||
throw new Error("Endpoint is disabled!")
|
||||
}
|
||||
|
||||
@ -355,7 +360,7 @@ class Server {
|
||||
await this.params.onWSClientConnection(client)
|
||||
}
|
||||
|
||||
for await (const [nsp, on, dispatch] of this.wsInterface.eventsChannels) {
|
||||
for await (const [nsp, on, dispatch] of this.websocket_instance.eventsChannels) {
|
||||
client.on(on, async (...args) => {
|
||||
try {
|
||||
await dispatch(client, ...args).catch((error) => {
|
||||
@ -383,30 +388,28 @@ class Server {
|
||||
}
|
||||
|
||||
// public methods
|
||||
OutputServerInfo = () => {
|
||||
InternalConsole.log(`🌐 Server info:`)
|
||||
outputServerInfo = () => {
|
||||
InternalConsole.log("✅ Ready !")
|
||||
|
||||
InternalConsole.table({
|
||||
"ID": this.id,
|
||||
"HTTPEngine": this.params.httpEngine,
|
||||
"Version": LINEBRIDGE_SERVER_VERSION,
|
||||
"WS Protocol": this.params.wsProtocol,
|
||||
"Protocol": this.params.protocol,
|
||||
"HTTP address": this.HTTPAddress,
|
||||
"WS address": this.WSAddress,
|
||||
"Listen port": this.listenPort,
|
||||
"linebridge_version": LINEBRIDGE_SERVER_VERSION,
|
||||
"engine": this.params.engine,
|
||||
"http_address": this.params.http_address,
|
||||
"websocket_address": this.params.ws_address,
|
||||
"listen_port": this.params.listen_port,
|
||||
})
|
||||
}
|
||||
|
||||
toogleEndpointReachability = (method, route, enabled) => {
|
||||
if (typeof this.endpointsMap[method] !== "object") {
|
||||
if (typeof this.endpoints_map[method] !== "object") {
|
||||
throw new Error(`Cannot toogle endpoint, method [${method}] not set!`)
|
||||
}
|
||||
|
||||
if (typeof this.endpointsMap[method][route] !== "object") {
|
||||
if (typeof this.endpoints_map[method][route] !== "object") {
|
||||
throw new Error(`Cannot toogle endpoint [${route}], is not registered!`)
|
||||
}
|
||||
|
||||
this.endpointsMap[method][route].enabled = enabled ?? !this.endpointsMap[method][route].enabled
|
||||
this.endpoints_map[method][route].enabled = enabled ?? !this.endpoints_map[method][route].enabled
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user