diff --git a/README.md b/README.md index 6b850fe..2775ed3 100755 --- a/README.md +++ b/README.md @@ -1 +1,120 @@ -# linebridge | API Interface library +# linebridge +A multiproposal framework to build fast, scalable, and secure servers. + +Currently used on RageStudio's services backends, like [Comty](https://github.com/ragestudio/comty) + +## Getting Started +### Installation +```bash +npm install linebridge +``` +> Note: Use of Yarn can cause some issues to install the package. + +### Example +Create a http server +```js +// index.js +import { Server } from "./linebridge/src" + +class MyAPI extends Server { + // set a id for the server + static refName = "my-api" + // define a file based router + static routesPath = `${__dirname}/routes` + // define custom listen port + static listenPort = 3000 + + // set manual routes + routes = { + // basic route + "/hi": { + method: "get", + fn: async (req, res) => { + return { + message: "Hello world" + } + } + }, + // use custom middleware + "/middleware-custom": { + method: "get", + middlewares: [ + "custom-middleware" + ], + fn: async (req, res) => { + return { + message: "The middleware is working!" + } + } + }, + // get from context + "/db": { + method: "get", + useContexts: [ + "db" + ], + fn: async (req, res, ctx) => { + console.log(ctx) + return ctx.db.data + } + }, + // use parameters + "/sum/:value1/:value2": { + method: "get", + fn: async (req, res) => { + return { + result: parseInt(req.params.value1) + parseInt(req.params.value2) + } + } + } + } + + // define default middlewares to use on every request + useMiddlewares = [ + async (req, res) => { + console.log("Im executed every request") + } + ] + + // you can also define custom middlewares to use on endpoints + middlewares = { + "custom-middleware": async (req, res) => { + console.log("Im a custom middleware") + } + } + + // define custom contexts to use on endpoints + contexts = { + db: { + data: [ + { + id: 1, + name: "John Doe" + }, + { + id: 2, + name: "Jane Doe" + } + ] + } + } + + async onInitialize() { + console.log("Server initialized") + } + + async onClose() { + console.log("Server closed") + } +} + +Boot(MyAPI) +``` +Run the server +```bash +linebridge-boot index.js +``` + +## Documentation +> On the way + diff --git a/package.json b/package.json index 36dd379..5ad190b 100755 --- a/package.json +++ b/package.json @@ -1,10 +1,13 @@ { "name": "linebridge", - "version": "0.21.4", - "description": "API Framework for RageStudio backends", - "author": "RageStudio", + "version": "0.22.0", + "description": "Multiproposal framework to build fast, scalable, and secure servers.", + "author": "RageStudio ", + "bugs": { + "url": "https://github.com/ragestudio/linebridge/issues" + }, "license": "MIT", - "main": "./dist/client/index.js", + "main": "./dist/index.js", "bin": { "linebridge-boot": "./bin/boot.js" }, @@ -48,4 +51,4 @@ "@ragestudio/hermes": "^0.1.0", "mocha": "^9.1.3" } -} +} \ No newline at end of file diff --git a/src/server/baseEndpoints/main.js b/src/baseEndpoints/main.js similarity index 80% rename from src/server/baseEndpoints/main.js rename to src/baseEndpoints/main.js index 74e0032..fc5f044 100644 --- a/src/server/baseEndpoints/main.js +++ b/src/baseEndpoints/main.js @@ -9,12 +9,10 @@ export default class MainEndpoint extends Endpoint { route = "/" get = async (req, res) => { - const { params } = this.ctx - return { - name: params.name ?? "unknown", + name: globalThis._linebridge.name ?? "unknown", version: projectPkg.version ?? "unknown", - engine: params.useEngine ?? "unknown", + engine: globalThis._linebridge.useEngine ?? "unknown", request_time: new Date().getTime(), lb_version: defaults.version ?? "unknown", experimental: defaults.isExperimental.toString() ?? "unknown", diff --git a/src/server/baseEndpoints/map.js b/src/baseEndpoints/map.js similarity index 79% rename from src/server/baseEndpoints/map.js rename to src/baseEndpoints/map.js index 85cb96e..13ce787 100644 --- a/src/server/baseEndpoints/map.js +++ b/src/baseEndpoints/map.js @@ -4,7 +4,7 @@ export default class MainEndpoint extends Endpoint { route = "/_map" get = async (req, res) => { - const httpMap = Object.entries(this.ctx.engine.router.map).reduce((acc, [route, { method, path }]) => { + const httpMap = Object.entries(this.server.engine.router.map).reduce((acc, [route, { method, path }]) => { if (!acc[method]) { acc[method] = [] } diff --git a/src/server/classes/IPCClient/index.js b/src/classes/IPCClient/index.js similarity index 100% rename from src/server/classes/IPCClient/index.js rename to src/classes/IPCClient/index.js diff --git a/src/server/classes/IPCRouter/index.js b/src/classes/IPCRouter/index.js similarity index 100% rename from src/server/classes/IPCRouter/index.js rename to src/classes/IPCRouter/index.js diff --git a/src/server/classes/endpoint/index.js b/src/classes/endpoint/index.js similarity index 64% rename from src/server/classes/endpoint/index.js rename to src/classes/endpoint/index.js index 8d2899b..eefedaf 100755 --- a/src/server/classes/endpoint/index.js +++ b/src/classes/endpoint/index.js @@ -1,10 +1,15 @@ export default class Endpoint { - constructor(ctx, params = {}) { - this.ctx = ctx + constructor(server, params = {}, ctx = {}) { + this.server = server this.params = params + this.ctx = ctx - this.route = this.constructor.route ?? this.params.route - this.enabled = this.constructor.enabled ?? this.params.enabled ?? true + if (!server) { + throw new Error("Server is not defined") + } + + this.route = this.route ?? this.constructor.route ?? this.params.route + this.enabled = this.enabled ?? this.constructor.enabled ?? this.params.enabled ?? true this.middlewares = [ ...this.middlewares ?? [], @@ -12,7 +17,7 @@ export default class Endpoint { ] if (this.params.handlers) { - for (const method of this.ctx.valid_http_methods) { + for (const method of globalThis._linebridge.validHttpMethods) { if (typeof this.params.handlers[method] === "function") { this[method] = this.params.handlers[method] } @@ -21,13 +26,23 @@ export default class Endpoint { this.selfRegister() + if (Array.isArray(this.params.useContexts)) { + for (const contextRef of this.params.useContexts) { + this.endpointContext[contextRef] = this.server.contexts[contextRef] + } + } + return this } + endpointContext = {} + createHandler(fn) { + fn = fn.bind(this.server) + return async (req, res) => { try { - const result = await fn(req, res) + const result = await fn(req, res, this.endpointContext) if (result) { return res.json(result) @@ -52,15 +67,13 @@ export default class Endpoint { } selfRegister = async () => { - const validMethods = this.ctx.valid_http_methods - - for await (const method of validMethods) { + for await (const method of globalThis._linebridge.validHttpMethods) { const methodHandler = this[method] if (typeof methodHandler !== "undefined") { const fn = this.createHandler(this[method].fn ?? this[method]) - this.ctx.register.http( + this.server.register.http( { method, route: this.route, diff --git a/src/server/classes/index.js b/src/classes/index.js similarity index 100% rename from src/server/classes/index.js rename to src/classes/index.js diff --git a/src/server/classes/operation_error/index.js b/src/classes/operation_error/index.js similarity index 100% rename from src/server/classes/operation_error/index.js rename to src/classes/operation_error/index.js diff --git a/src/server/classes/rtengine/index.js b/src/classes/rtengine/index.js similarity index 100% rename from src/server/classes/rtengine/index.js rename to src/classes/rtengine/index.js diff --git a/src/client/bridge.js b/src/client/bridge.js deleted file mode 100755 index dcda38f..0000000 --- a/src/client/bridge.js +++ /dev/null @@ -1,177 +0,0 @@ -const axios = require("axios") -const axiosRetry = require("axios-retry") -const camalize = require("@corenode/utils/dist/camalize").default - -const { WSInterface } = require("./classes") -const { generateHTTPRequestDispatcher, generateWSRequestDispatcher } = require("./lib") - -const FixedMethods = { - "del": "delete" -} - -module.exports = class Bridge { - constructor(params = {}, events = {}) { - this.params = params - this.events = events - this.internalAbortController = new AbortController() - - this.origin = this.params.origin - this.wsOrigin = this.origin.replace(/^http/, "ws") - this.wsOrigin = this.wsOrigin.replace(/^https/, "wss") - - this.headers = { - ...this.params.headers, - } - - this.httpInterface = axios.create({ - baseURL: this.origin, - headers: this.headers, - signal: this.params.signal ?? this.internalAbortController.signal - }) - - this.wsInterface = new WSInterface({ - origin: this.wsOrigin, - managerOptions: this.params.wsOptions, - mainSocketOptions: this.params.wsMainSocketOptions, - }) - - this.endpoints = {} - this.wsEndpoints = {} - - this.wsInterface.sockets.main.on("disconnect", async (...args) => { - if (typeof this.events.onDisconnect === "function") { - await this.events.onDisconnect(...args) - } - }) - - this.wsInterface.sockets.main.on("unauthorized", async (...args) => { - if (typeof this.events.onUnauthorized === "function") { - await this.events.onUnauthorized(...args) - } - }) - - if (this.params.enableRetry) { - axiosRetry(this.httpInterface, { - retries: this.params.onFailRetries ?? 1, - retryDelay: this.params.retryDelay ?? 0, - }) - } - - return this - } - - initialize = async () => { - const instanceManifest = await this.httpInterface.get("/") - .then((res) => res.data) - .catch((err) => { - console.error(err) - throw new Error(`Could not get endpoints map from server. [${err.message}]`) - }) - - const httpMap = instanceManifest.endpointsMap - const wsMap = instanceManifest.wsEndpointsMap - - await this.registerHTTPDispatchers(httpMap) - await this.registerWSDispatchers(wsMap) - - this.wsInterface.manager.open((err) => { - if (err) { - console.error(err) - throw new Error(`Could not open socket manager. [${err.message}]`) - } - - this.wsInterface.sockets.main.connect() - }) - } - - handleRequestContext = async (...args) => { - if (typeof this.params.onRequest === "function") { - return await this.params.onRequest(...args) - } - - return false - } - - handleResponse = async (...args) => { - if (typeof this.params.onResponse === "function") { - return await this.params.onResponse(...args) - } - - return false - } - - handleBeforeRequest = async (...args) => { - if (typeof this.params.onBeforeRequest === "function") { - return await this.params.onBeforeRequest(...args) - } - - return false - } - - registerHTTPDispatchers = async (map) => { - if (typeof map !== "object") { - console.error("[Bridge] > createHTTPDispatchers > map is not an object") - return false - } - - for await (let HttpMethod of Object.keys(map)) { - HttpMethod = HttpMethod.toLowerCase() - - const fixedMethod = FixedMethods[HttpMethod] ?? HttpMethod - - if (typeof this.endpoints[fixedMethod] !== "object") { - this.endpoints[fixedMethod] = {} - } - - Object.keys(map[HttpMethod]).forEach((route) => { - const tree = route.split("/") - const hasTree = tree.length >= 1 - - let nameKey = route - - // check if has tree - if (hasTree) { - // remove first whitespace item in route index[0] - if (tree[0] == "") { - tree.shift() - } - - nameKey = camalize(tree.join("_")) - } - - // if is an blank route, set as index - if (nameKey == "") { - nameKey = "index" - } - - this.endpoints[fixedMethod][nameKey] = generateHTTPRequestDispatcher({ - instance: this.httpInterface, - method: fixedMethod, - route: route, - beforeRequest: this.handleBeforeRequest, - handleRequestContext: this.handleRequestContext, - handleResponse: this.handleResponse, - requestHeaders: this.params.requestHeaders, - }) - }) - } - - return this.endpoints - } - - registerWSDispatchers = async (map) => { - if (typeof map !== "object") { - console.error("[Bridge] > createWSDispatchers > map is not an object") - return false - } - - for await (let wsChannel of Object.keys(map)) { - const endpoint = map[wsChannel] - - endpoint.nsp[0] == "/" ? endpoint.nsp = endpoint.nsp.slice(1) : null - endpoint.method = endpoint.channel[0] == "/" ? endpoint.channel.slice(1) : endpoint.channel - - this.wsEndpoints[endpoint.method] = generateWSRequestDispatcher(this.wsInterface.sockets[endpoint.nsp ?? "main"], endpoint.channel) - } - } -} \ No newline at end of file diff --git a/src/client/classes/WSInterface/index.js b/src/client/classes/WSInterface/index.js deleted file mode 100755 index 1d4b71c..0000000 --- a/src/client/classes/WSInterface/index.js +++ /dev/null @@ -1,45 +0,0 @@ -const io = require("socket.io-client") - -class WSInterface { - constructor(params = {}) { - this.params = params - this.manager = new io.Manager(this.params.origin, { - autoConnect: false, - transports: ["websocket"], - ...this.params.managerOptions, - }) - this.sockets = {} - - this.attach("/", "main", this.params.mainSocketOptions) - } - - attach = (socket, as, options) => { - if (typeof socket !== "string") { - console.error("socket must be string") - return false - } - - socket = this.manager.socket(socket, options) - - return this.sockets[as ?? socket] = socket - } - - detach = (socketName) => { - if (typeof socketName !== "string") { - console.error("socketName must be string") - return false - } - if (typeof this.sockets[socketName] === "undefined") { - console.error("socket not found") - return false - } - - if (this.sockets[socketName].connected) { - this.sockets[socketName].disconnect() - } - - delete this.sockets[socketName] - } -} - -module.exports = WSInterface \ No newline at end of file diff --git a/src/client/classes/index.js b/src/client/classes/index.js deleted file mode 100755 index b69e5fd..0000000 --- a/src/client/classes/index.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - WSInterface: require("./WSInterface"), -} \ No newline at end of file diff --git a/src/client/controller.js b/src/client/controller.js deleted file mode 100755 index a5f21f7..0000000 --- a/src/client/controller.js +++ /dev/null @@ -1,44 +0,0 @@ -// TODO: AutoConnection -module.exports = class Controller { - constructor(params = {}) { - console.warn("[Linebridge] Controller is not finished yet. Please use regular bridges instead.") - - this.params = params - this.pool = [] - } - - async initialize() { - if (typeof this.params.servers !== "undefined" && Array.isArray(this.params.servers)) { - for await (let server of this.params.servers) { - await this.appendServer(server) - } - } - - for await (let server of this.pool) { - await this.connect(server) - } - } - - async appendServer(server) { - if (typeof server === "string") { - server = new Bridge({ - origin: server, - }) - } else if (typeof server === "object" && server instanceof Bridge) { - server = new Bridge(...server) - } - - this.pool.push(server) - } - - // async disconnect() { - // } - - async connect(server) { - if (server instanceof Bridge) { - await server.initialize() - } else { - throw new Error("Invalid server. Expected Bridge instance.") - } - } -} \ No newline at end of file diff --git a/src/client/index.js b/src/client/index.js deleted file mode 100755 index 4905816..0000000 --- a/src/client/index.js +++ /dev/null @@ -1,8 +0,0 @@ -const Controller = require("./controller") -const Bridge = require("./bridge") - -module.exports = { - Bridge, - Controller, - version: require("../../package.json").version, -} \ No newline at end of file diff --git a/src/client/lib/generateHTTPRequestDispatcher/index.js b/src/client/lib/generateHTTPRequestDispatcher/index.js deleted file mode 100755 index f0e733b..0000000 --- a/src/client/lib/generateHTTPRequestDispatcher/index.js +++ /dev/null @@ -1,69 +0,0 @@ -export default function generateHTTPRequestDispatcher({ - instance, - method, - route, - beforeRequest, - handleRequestContext, - handleResponse, -}) { - return function (body, query, options) { - return new Promise(async (resolve, reject) => { - let requestParams = { - parseData: true, - ...options, - method: method, - url: route, - data: body, - params: query, - } - - let result = {} - - const makeRequest = async () => { - result = { - response: null, - error: null, - } - - if (typeof beforeRequest === "function") { - await beforeRequest(requestParams) - } - - if (typeof handleRequestContext === "function") { - const context = await handleRequestContext() - requestParams = { ...requestParams, ...context } - } - - return await instance(requestParams) - .then((response) => { - result.response = response - - return response - }) - .catch((error) => { - result.error = error.response.data.error ?? error.response.data - - return error - }) - } - - const request = await makeRequest() - - if (typeof handleResponse === "function") { - await handleResponse(request, makeRequest) - } - - if (requestParams.parseData) { - if (result.error) { - return reject(result.error) - } - - return resolve(result.response.data) - } - - return resolve(result) - }) - } -} - -module.exports = generateHTTPRequestDispatcher \ No newline at end of file diff --git a/src/client/lib/generateWSRequestDispatcher/index.js b/src/client/lib/generateWSRequestDispatcher/index.js deleted file mode 100755 index 3188735..0000000 --- a/src/client/lib/generateWSRequestDispatcher/index.js +++ /dev/null @@ -1,17 +0,0 @@ -function generateWSRequestDispatcher(instance, channel) { - return function (...payload) { - return new Promise(async (resolve, reject) => { - const req = instance.emit(channel, ...payload) - - req.on("response", (...args) => { - return resolve(...args) - }) - - req.on("responseError", (...args) => { - return reject(...args) - }) - }) - } -} - -module.exports = generateWSRequestDispatcher \ No newline at end of file diff --git a/src/client/lib/index.js b/src/client/lib/index.js deleted file mode 100755 index 13273a8..0000000 --- a/src/client/lib/index.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - generateHTTPRequestDispatcher: require("./generateHTTPRequestDispatcher"), - generateWSRequestDispatcher: require("./generateWSRequestDispatcher"), -} \ No newline at end of file diff --git a/src/server/defaults.js b/src/defaults.js similarity index 94% rename from src/server/defaults.js rename to src/defaults.js index 8a63c62..11a2ba2 100644 --- a/src/server/defaults.js +++ b/src/defaults.js @@ -1,7 +1,7 @@ const path = require("path") const fs = require("fs") const os = require("os") -const packageJSON = require(path.resolve(module.path, "../../package.json")) +const packageJSON = require(path.resolve(module.path, "../package.json")) function getHostAddress() { const interfaces = os.networkInterfaces() @@ -22,7 +22,7 @@ function getHostAddress() { } export default { - isExperimental: fs.existsSync(path.resolve(module.path, "../../.experimental")), + isExperimental: fs.existsSync(path.resolve(module.path, "../.experimental")), version: packageJSON.version, localhost_address: getHostAddress() ?? "localhost", params: { diff --git a/src/server/engines/hyper-express/index.js b/src/engines/hyper-express/index.js similarity index 91% rename from src/server/engines/hyper-express/index.js rename to src/engines/hyper-express/index.js index d1dd0f5..26dea2e 100644 --- a/src/server/engines/hyper-express/index.js +++ b/src/engines/hyper-express/index.js @@ -11,11 +11,16 @@ export default class Engine { ws = null initialize = async (params) => { - this.app = new he.Server({ + const serverParams = { max_body_length: 50 * 1024 * 1024, //50MB in bytes, - key_file_name: params.ssl?.key ?? null, - cert_file_name: params.ssl?.cert ?? null, - }) + } + + 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() @@ -52,7 +57,7 @@ export default class Engine { } }) - if (!params.disableWebSockets) { + if (params.enableWebsockets) { this.ws = global.websocket = new rtengine({ ...params, handleAuth: params.handleWsAuth, @@ -83,7 +88,7 @@ export default class Engine { return true }) - if (!params.disableWebSockets) { + if (params.enableWebsockets) { process.send({ type: "router:ws:register", id: process.env.lb_service.id, diff --git a/src/server/engines/worker/index.js b/src/engines/worker/index.js similarity index 100% rename from src/server/engines/worker/index.js rename to src/engines/worker/index.js diff --git a/src/server/index.js b/src/index.js similarity index 75% rename from src/server/index.js rename to src/index.js index 0c02a03..5978cf8 100755 --- a/src/server/index.js +++ b/src/index.js @@ -2,5 +2,5 @@ module.exports = { Server: require("./server.js"), Endpoint: require("./classes/endpoint"), registerBaseAliases: require("./registerAliases"), - version: require("../../package.json").version, + version: require("../package.json").version, } diff --git a/src/server/initializators/registerBaseEndpoints/index.js b/src/initializators/registerBaseEndpoints/index.js similarity index 84% rename from src/server/initializators/registerBaseEndpoints/index.js rename to src/initializators/registerBaseEndpoints/index.js index 10ec3ca..a2c0bca 100644 --- a/src/server/initializators/registerBaseEndpoints/index.js +++ b/src/initializators/registerBaseEndpoints/index.js @@ -1,7 +1,7 @@ import fs from "node:fs" import path from "node:path" -export default async (ctx) => { +export default async (server) => { const scanPath = path.join(__dirname, "../../", "baseEndpoints") const files = fs.readdirSync(scanPath) @@ -12,6 +12,6 @@ export default async (ctx) => { let endpoint = require(path.join(scanPath, file)).default - new endpoint(ctx) + new endpoint(server) } } \ No newline at end of file diff --git a/src/server/initializators/registerHttpRoutes/index.js b/src/initializators/registerHttpRoutes/index.js similarity index 93% rename from src/server/initializators/registerHttpRoutes/index.js rename to src/initializators/registerHttpRoutes/index.js index 5069332..193c2bb 100644 --- a/src/server/initializators/registerHttpRoutes/index.js +++ b/src/initializators/registerHttpRoutes/index.js @@ -5,7 +5,7 @@ import RecursiveRegister from "../../lib/recursiveRegister" const parametersRegex = /\[([a-zA-Z0-9_]+)\]/g -export default async (startDir, engine, ctx) => { +export default async (startDir, engine, server) => { if (!fs.existsSync(startDir)) { return engine } @@ -52,7 +52,7 @@ export default async (startDir, engine, ctx) => { let contexts = {} for (const context of fn.useContext) { - contexts[context] = ctx.contexts[context] + contexts[context] = server.contexts[context] } fn.contexts = contexts @@ -62,7 +62,7 @@ export default async (startDir, engine, ctx) => { } new Endpoint( - ctx, + server, { route: route, enabled: true, diff --git a/src/server/initializators/registerWebsocketsEvents/index.js b/src/initializators/registerWebsocketsEvents/index.js similarity index 100% rename from src/server/initializators/registerWebsocketsEvents/index.js rename to src/initializators/registerWebsocketsEvents/index.js diff --git a/src/server/lib/generateController/index.js b/src/lib/generateController/index.js similarity index 100% rename from src/server/lib/generateController/index.js rename to src/lib/generateController/index.js diff --git a/src/server/lib/generateEndpointsFromDir/index.js b/src/lib/generateEndpointsFromDir/index.js similarity index 100% rename from src/server/lib/generateEndpointsFromDir/index.js rename to src/lib/generateEndpointsFromDir/index.js diff --git a/src/server/lib/loadEndpointsFromDir/index.js b/src/lib/loadEndpointsFromDir/index.js similarity index 100% rename from src/server/lib/loadEndpointsFromDir/index.js rename to src/lib/loadEndpointsFromDir/index.js diff --git a/src/server/lib/recursiveRegister/index.js b/src/lib/recursiveRegister/index.js similarity index 100% rename from src/server/lib/recursiveRegister/index.js rename to src/lib/recursiveRegister/index.js diff --git a/src/server/lib/redis_map/index.js b/src/lib/redis_map/index.js similarity index 100% rename from src/server/lib/redis_map/index.js rename to src/lib/redis_map/index.js diff --git a/src/server/middlewares/cors/index.js b/src/middlewares/cors/index.js similarity index 100% rename from src/server/middlewares/cors/index.js rename to src/middlewares/cors/index.js diff --git a/src/server/middlewares/logger/index.js b/src/middlewares/logger/index.js similarity index 100% rename from src/server/middlewares/logger/index.js rename to src/middlewares/logger/index.js diff --git a/src/server/patches.js b/src/patches.js similarity index 100% rename from src/server/patches.js rename to src/patches.js diff --git a/src/server/registerAliases.js b/src/registerAliases.js similarity index 100% rename from src/server/registerAliases.js rename to src/registerAliases.js diff --git a/src/server/server.js b/src/server.js similarity index 87% rename from src/server/server.js rename to src/server.js index 3b68ddc..411c3b3 100755 --- a/src/server/server.js +++ b/src/server.js @@ -7,6 +7,7 @@ import { EventEmitter } from "@foxify/events" import defaults from "./defaults" import IPCClient from "./classes/IPCClient" +import Endpoint from "./classes/endpoint" import registerBaseEndpoints from "./initializators/registerBaseEndpoints" import registerWebsocketsEvents from "./initializators/registerWebsocketsEvents" @@ -51,8 +52,6 @@ class Server { ...headers.default ?? headers, } - this.valid_http_methods = defaults.valid_http_methods - // fix and fulfill params this.params.useMiddlewares = this.params.useMiddlewares ?? [] this.params.name = this.constructor.refName ?? this.params.refName @@ -61,12 +60,25 @@ class Server { this.params.listen_port = this.constructor.listenPort ?? this.constructor.listen_port ?? this.params.listen_port ?? 3000 this.params.http_protocol = this.params.http_protocol ?? "http" this.params.http_address = `${this.params.http_protocol}://${defaults.localhost_address}:${this.params.listen_port}` - this.params.disableWebSockets = this.constructor.disableWebSockets ?? this.params.disableWebSockets ?? false + this.params.enableWebsockets = this.constructor.enableWebsockets ?? this.params.enableWebsockets ?? false this.params.ignoreCors = this.constructor.ignoreCors ?? this.params.ignoreCors ?? true this.params.routesPath = this.constructor.routesPath ?? this.params.routesPath ?? path.resolve(process.cwd(), "routes") this.params.wsRoutesPath = this.constructor.wsRoutesPath ?? this.params.wsRoutesPath ?? path.resolve(process.cwd(), "routes_ws") + globalThis._linebridge = { + name: this.params.name, + useEngine: this.params.useEngine, + listenIp: this.params.listen_ip, + listenPort: this.params.listen_port, + httpProtocol: this.params.http_protocol, + httpAddress: this.params.http_address, + enableWebsockets: this.params.enableWebsockets, + ignoreCors: this.params.ignoreCors, + routesPath: this.params.routesPath, + validHttpMethods: defaults.valid_http_methods, + } + return this } @@ -100,7 +112,7 @@ class Server { handleAuth: this.handleHttpAuth, requireAuth: this.constructor.requireHttpAuth, refName: this.constructor.refName ?? this.params.refName, - ssl: this.ssl ?? {}, + ssl: this.ssl, } // initialize engine @@ -138,6 +150,21 @@ class Server { this.useDefaultHeaders() this.useDefaultMiddlewares() + if (this.routes) { + for (const [route, endpoint] of Object.entries(this.routes)) { + this.engine.router.map[route] = new Endpoint( + this, + { + ...endpoint, + route: route, + handlers: { + [endpoint.method]: endpoint.fn, + }, + } + ) + } + } + // register http & ws routes this.engine = await registerHttpRoutes(this.params.routesPath, this.engine, this) this.engine = await registerWebsocketsEvents(this.params.wsRoutesPath, this.engine)