mirror of
https://github.com/ragestudio/linebridge.git
synced 2025-06-09 10:34:17 +00:00
merge from local
This commit is contained in:
parent
e7af64983d
commit
94fd5dd523
121
README.md
121
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
|
||||||
|
<!-- For more information, please visit the [documentation](https://docs.linebridge.com). -->
|
||||||
|
11
package.json
11
package.json
@ -1,10 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "linebridge",
|
"name": "linebridge",
|
||||||
"version": "0.21.4",
|
"version": "0.22.0",
|
||||||
"description": "API Framework for RageStudio backends",
|
"description": "Multiproposal framework to build fast, scalable, and secure servers.",
|
||||||
"author": "RageStudio",
|
"author": "RageStudio <support@ragestudio.net>",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/ragestudio/linebridge/issues"
|
||||||
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/client/index.js",
|
"main": "./dist/index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
"linebridge-boot": "./bin/boot.js"
|
"linebridge-boot": "./bin/boot.js"
|
||||||
},
|
},
|
||||||
|
@ -9,12 +9,10 @@ export default class MainEndpoint extends Endpoint {
|
|||||||
route = "/"
|
route = "/"
|
||||||
|
|
||||||
get = async (req, res) => {
|
get = async (req, res) => {
|
||||||
const { params } = this.ctx
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: params.name ?? "unknown",
|
name: globalThis._linebridge.name ?? "unknown",
|
||||||
version: projectPkg.version ?? "unknown",
|
version: projectPkg.version ?? "unknown",
|
||||||
engine: params.useEngine ?? "unknown",
|
engine: globalThis._linebridge.useEngine ?? "unknown",
|
||||||
request_time: new Date().getTime(),
|
request_time: new Date().getTime(),
|
||||||
lb_version: defaults.version ?? "unknown",
|
lb_version: defaults.version ?? "unknown",
|
||||||
experimental: defaults.isExperimental.toString() ?? "unknown",
|
experimental: defaults.isExperimental.toString() ?? "unknown",
|
@ -4,7 +4,7 @@ export default class MainEndpoint extends Endpoint {
|
|||||||
route = "/_map"
|
route = "/_map"
|
||||||
|
|
||||||
get = async (req, res) => {
|
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]) {
|
if (!acc[method]) {
|
||||||
acc[method] = []
|
acc[method] = []
|
||||||
}
|
}
|
@ -1,10 +1,15 @@
|
|||||||
export default class Endpoint {
|
export default class Endpoint {
|
||||||
constructor(ctx, params = {}) {
|
constructor(server, params = {}, ctx = {}) {
|
||||||
this.ctx = ctx
|
this.server = server
|
||||||
this.params = params
|
this.params = params
|
||||||
|
this.ctx = ctx
|
||||||
|
|
||||||
this.route = this.constructor.route ?? this.params.route
|
if (!server) {
|
||||||
this.enabled = this.constructor.enabled ?? this.params.enabled ?? true
|
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 = [
|
||||||
...this.middlewares ?? [],
|
...this.middlewares ?? [],
|
||||||
@ -12,7 +17,7 @@ export default class Endpoint {
|
|||||||
]
|
]
|
||||||
|
|
||||||
if (this.params.handlers) {
|
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") {
|
if (typeof this.params.handlers[method] === "function") {
|
||||||
this[method] = this.params.handlers[method]
|
this[method] = this.params.handlers[method]
|
||||||
}
|
}
|
||||||
@ -21,13 +26,23 @@ export default class Endpoint {
|
|||||||
|
|
||||||
this.selfRegister()
|
this.selfRegister()
|
||||||
|
|
||||||
|
if (Array.isArray(this.params.useContexts)) {
|
||||||
|
for (const contextRef of this.params.useContexts) {
|
||||||
|
this.endpointContext[contextRef] = this.server.contexts[contextRef]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
endpointContext = {}
|
||||||
|
|
||||||
createHandler(fn) {
|
createHandler(fn) {
|
||||||
|
fn = fn.bind(this.server)
|
||||||
|
|
||||||
return async (req, res) => {
|
return async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const result = await fn(req, res)
|
const result = await fn(req, res, this.endpointContext)
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
return res.json(result)
|
return res.json(result)
|
||||||
@ -52,15 +67,13 @@ export default class Endpoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
selfRegister = async () => {
|
selfRegister = async () => {
|
||||||
const validMethods = this.ctx.valid_http_methods
|
for await (const method of globalThis._linebridge.validHttpMethods) {
|
||||||
|
|
||||||
for await (const method of validMethods) {
|
|
||||||
const methodHandler = this[method]
|
const methodHandler = this[method]
|
||||||
|
|
||||||
if (typeof methodHandler !== "undefined") {
|
if (typeof methodHandler !== "undefined") {
|
||||||
const fn = this.createHandler(this[method].fn ?? this[method])
|
const fn = this.createHandler(this[method].fn ?? this[method])
|
||||||
|
|
||||||
this.ctx.register.http(
|
this.server.register.http(
|
||||||
{
|
{
|
||||||
method,
|
method,
|
||||||
route: this.route,
|
route: this.route,
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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
|
|
@ -1,3 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
WSInterface: require("./WSInterface"),
|
|
||||||
}
|
|
@ -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.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
const Controller = require("./controller")
|
|
||||||
const Bridge = require("./bridge")
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
Bridge,
|
|
||||||
Controller,
|
|
||||||
version: require("../../package.json").version,
|
|
||||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -1,4 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
generateHTTPRequestDispatcher: require("./generateHTTPRequestDispatcher"),
|
|
||||||
generateWSRequestDispatcher: require("./generateWSRequestDispatcher"),
|
|
||||||
}
|
|
@ -1,7 +1,7 @@
|
|||||||
const path = require("path")
|
const path = require("path")
|
||||||
const fs = require("fs")
|
const fs = require("fs")
|
||||||
const os = require("os")
|
const os = require("os")
|
||||||
const packageJSON = require(path.resolve(module.path, "../../package.json"))
|
const packageJSON = require(path.resolve(module.path, "../package.json"))
|
||||||
|
|
||||||
function getHostAddress() {
|
function getHostAddress() {
|
||||||
const interfaces = os.networkInterfaces()
|
const interfaces = os.networkInterfaces()
|
||||||
@ -22,7 +22,7 @@ function getHostAddress() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
isExperimental: fs.existsSync(path.resolve(module.path, "../../.experimental")),
|
isExperimental: fs.existsSync(path.resolve(module.path, "../.experimental")),
|
||||||
version: packageJSON.version,
|
version: packageJSON.version,
|
||||||
localhost_address: getHostAddress() ?? "localhost",
|
localhost_address: getHostAddress() ?? "localhost",
|
||||||
params: {
|
params: {
|
@ -11,11 +11,16 @@ export default class Engine {
|
|||||||
ws = null
|
ws = null
|
||||||
|
|
||||||
initialize = async (params) => {
|
initialize = async (params) => {
|
||||||
this.app = new he.Server({
|
const serverParams = {
|
||||||
max_body_length: 50 * 1024 * 1024, //50MB in bytes,
|
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()
|
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({
|
this.ws = global.websocket = new rtengine({
|
||||||
...params,
|
...params,
|
||||||
handleAuth: params.handleWsAuth,
|
handleAuth: params.handleWsAuth,
|
||||||
@ -83,7 +88,7 @@ export default class Engine {
|
|||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!params.disableWebSockets) {
|
if (params.enableWebsockets) {
|
||||||
process.send({
|
process.send({
|
||||||
type: "router:ws:register",
|
type: "router:ws:register",
|
||||||
id: process.env.lb_service.id,
|
id: process.env.lb_service.id,
|
@ -2,5 +2,5 @@ module.exports = {
|
|||||||
Server: require("./server.js"),
|
Server: require("./server.js"),
|
||||||
Endpoint: require("./classes/endpoint"),
|
Endpoint: require("./classes/endpoint"),
|
||||||
registerBaseAliases: require("./registerAliases"),
|
registerBaseAliases: require("./registerAliases"),
|
||||||
version: require("../../package.json").version,
|
version: require("../package.json").version,
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import fs from "node:fs"
|
import fs from "node:fs"
|
||||||
import path from "node:path"
|
import path from "node:path"
|
||||||
|
|
||||||
export default async (ctx) => {
|
export default async (server) => {
|
||||||
const scanPath = path.join(__dirname, "../../", "baseEndpoints")
|
const scanPath = path.join(__dirname, "../../", "baseEndpoints")
|
||||||
const files = fs.readdirSync(scanPath)
|
const files = fs.readdirSync(scanPath)
|
||||||
|
|
||||||
@ -12,6 +12,6 @@ export default async (ctx) => {
|
|||||||
|
|
||||||
let endpoint = require(path.join(scanPath, file)).default
|
let endpoint = require(path.join(scanPath, file)).default
|
||||||
|
|
||||||
new endpoint(ctx)
|
new endpoint(server)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,7 +5,7 @@ import RecursiveRegister from "../../lib/recursiveRegister"
|
|||||||
|
|
||||||
const parametersRegex = /\[([a-zA-Z0-9_]+)\]/g
|
const parametersRegex = /\[([a-zA-Z0-9_]+)\]/g
|
||||||
|
|
||||||
export default async (startDir, engine, ctx) => {
|
export default async (startDir, engine, server) => {
|
||||||
if (!fs.existsSync(startDir)) {
|
if (!fs.existsSync(startDir)) {
|
||||||
return engine
|
return engine
|
||||||
}
|
}
|
||||||
@ -52,7 +52,7 @@ export default async (startDir, engine, ctx) => {
|
|||||||
let contexts = {}
|
let contexts = {}
|
||||||
|
|
||||||
for (const context of fn.useContext) {
|
for (const context of fn.useContext) {
|
||||||
contexts[context] = ctx.contexts[context]
|
contexts[context] = server.contexts[context]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn.contexts = contexts
|
fn.contexts = contexts
|
||||||
@ -62,7 +62,7 @@ export default async (startDir, engine, ctx) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
new Endpoint(
|
new Endpoint(
|
||||||
ctx,
|
server,
|
||||||
{
|
{
|
||||||
route: route,
|
route: route,
|
||||||
enabled: true,
|
enabled: true,
|
@ -7,6 +7,7 @@ import { EventEmitter } from "@foxify/events"
|
|||||||
import defaults from "./defaults"
|
import defaults from "./defaults"
|
||||||
|
|
||||||
import IPCClient from "./classes/IPCClient"
|
import IPCClient from "./classes/IPCClient"
|
||||||
|
import Endpoint from "./classes/endpoint"
|
||||||
|
|
||||||
import registerBaseEndpoints from "./initializators/registerBaseEndpoints"
|
import registerBaseEndpoints from "./initializators/registerBaseEndpoints"
|
||||||
import registerWebsocketsEvents from "./initializators/registerWebsocketsEvents"
|
import registerWebsocketsEvents from "./initializators/registerWebsocketsEvents"
|
||||||
@ -51,8 +52,6 @@ class Server {
|
|||||||
...headers.default ?? headers,
|
...headers.default ?? headers,
|
||||||
}
|
}
|
||||||
|
|
||||||
this.valid_http_methods = defaults.valid_http_methods
|
|
||||||
|
|
||||||
// fix and fulfill params
|
// fix and fulfill params
|
||||||
this.params.useMiddlewares = this.params.useMiddlewares ?? []
|
this.params.useMiddlewares = this.params.useMiddlewares ?? []
|
||||||
this.params.name = this.constructor.refName ?? this.params.refName
|
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.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_protocol = this.params.http_protocol ?? "http"
|
||||||
this.params.http_address = `${this.params.http_protocol}://${defaults.localhost_address}:${this.params.listen_port}`
|
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.ignoreCors = this.constructor.ignoreCors ?? this.params.ignoreCors ?? true
|
||||||
|
|
||||||
this.params.routesPath = this.constructor.routesPath ?? this.params.routesPath ?? path.resolve(process.cwd(), "routes")
|
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")
|
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
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +112,7 @@ class Server {
|
|||||||
handleAuth: this.handleHttpAuth,
|
handleAuth: this.handleHttpAuth,
|
||||||
requireAuth: this.constructor.requireHttpAuth,
|
requireAuth: this.constructor.requireHttpAuth,
|
||||||
refName: this.constructor.refName ?? this.params.refName,
|
refName: this.constructor.refName ?? this.params.refName,
|
||||||
ssl: this.ssl ?? {},
|
ssl: this.ssl,
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize engine
|
// initialize engine
|
||||||
@ -138,6 +150,21 @@ class Server {
|
|||||||
this.useDefaultHeaders()
|
this.useDefaultHeaders()
|
||||||
this.useDefaultMiddlewares()
|
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
|
// register http & ws routes
|
||||||
this.engine = await registerHttpRoutes(this.params.routesPath, this.engine, this)
|
this.engine = await registerHttpRoutes(this.params.routesPath, this.engine, this)
|
||||||
this.engine = await registerWebsocketsEvents(this.params.wsRoutesPath, this.engine)
|
this.engine = await registerWebsocketsEvents(this.params.wsRoutesPath, this.engine)
|
Loading…
x
Reference in New Issue
Block a user