mirror of
https://github.com/ragestudio/linebridge.git
synced 2025-06-09 10:34:17 +00:00
165 lines
5.1 KiB
JavaScript
165 lines
5.1 KiB
JavaScript
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.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
|
|
})
|
|
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 () => {
|
|
if (typeof this.params.onRequest === "function") {
|
|
return await this.params.onRequest()
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
handleResponse = async (response) => {
|
|
if (typeof this.params.onResponse === "function") {
|
|
return await this.params.onResponse(response)
|
|
}
|
|
|
|
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(
|
|
this.httpInterface,
|
|
fixedMethod,
|
|
route,
|
|
this.handleRequestContext,
|
|
this.handleResponse,
|
|
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)
|
|
}
|
|
}
|
|
} |