refactor client methods

This commit is contained in:
srgooglo 2022-02-18 13:04:41 +01:00
parent 201dd00e91
commit e09664116e
4 changed files with 194 additions and 186 deletions

96
src/client/bridge.js Normal file
View File

@ -0,0 +1,96 @@
const generateRequestDispatcher = require("./generateRequestDispatcher")
const axios = require("axios")
const camalize = require("@corenode/utils/dist/camalize").default
const FixedMethods = {
"del": "delete"
}
module.exports = class Bridge {
constructor(params = {}) {
this.params = params
this.origin = this.params.origin
this.headers = { ...this.params.headers }
this.instance = axios.create({
baseURL: this.origin,
headers: this.headers
})
this.endpoints = {}
return this
}
initialize = async () => {
await this.updateEndpointsMap()
}
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
}
updateEndpointsMap = async () => {
const endpointsMap = await this.instance.get("/")
.then(res => res.data.endpointsMap)
.catch(err => {
console.error(err)
throw new Error(`Could not get endpoints map from server. [${err.message}]`)
})
for await (let HttpMethod of Object.keys(endpointsMap)) {
HttpMethod = HttpMethod.toLowerCase()
const fixedMethod = FixedMethods[HttpMethod] ?? HttpMethod
if (typeof this.endpoints[fixedMethod] !== "object") {
this.endpoints[fixedMethod] = {}
}
Object.keys(endpointsMap[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] = generateRequestDispatcher(
this.instance,
fixedMethod,
route,
this.handleRequestContext,
this.handleResponse
)
})
}
return this.endpoints
}
}

44
src/client/controller.js Normal file
View File

@ -0,0 +1,44 @@
// 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.")
}
}
}

View File

@ -0,0 +1,50 @@
module.exports = function generateRequestDispatcher(instance, method, route, 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,
}
if (typeof handleRequestContext === "function") {
const context = await handleRequestContext()
requestParams = { ...requestParams, ...context }
}
let result = {
response: null,
error: null,
}
const request = await instance(requestParams)
.then((response) => {
result.response = response
return response
})
.catch((error) => {
result.error = error.response.data.error ?? error.response.data
return error
})
if (typeof handleResponse === "function") {
await handleResponse(request)
}
if (requestParams.parseData) {
if (result.error) {
return reject(result.error)
}
return resolve(result.response.data)
}
return resolve(result)
})
}
}

View File

@ -1,191 +1,9 @@
const axios = require("axios")
const camalize = require("@corenode/utils/dist/camalize").default
const FixedMethods = {
"del": "delete"
}
// TODO: AutoConnection
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.")
}
}
}
class Bridge {
constructor(params = {}) {
this.params = params
this.origin = this.params.origin
this.headers = { ...this.params.headers }
this.instance = axios.create({
baseURL: this.origin,
headers: this.headers
})
this.map = null
this.endpoints = {}
return this
}
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
}
updateEndpointMap = async () => {
this.map = await this.getMap()
for await (let method of Object.keys(this.map)) {
method = method.toLowerCase()
const fixedMethod = FixedMethods[method] ?? method
if (typeof this.endpoints[fixedMethod] !== "object") {
this.endpoints[fixedMethod] = {}
}
this.map[method].forEach((endpoint) => {
const route = endpoint.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] = generateDispatcher(this.instance, fixedMethod, route, this.handleRequestContext, this.handleResponse)
})
}
return this.endpoints
}
getMap = async () => {
const req = await this.instance.get("/map")
return req.data
}
initialize = async () => {
await this.updateEndpointMap()
}
}
function generateDispatcher(instance, method, route, 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,
}
if (typeof handleRequestContext === "function") {
const context = await handleRequestContext()
requestParams = { ...requestParams, ...context }
}
let result = {
response: null,
error: null,
}
const request = await instance(requestParams)
.then((response) => {
result.response = response
return response
})
.catch((error) => {
result.error = error.response.data.error ?? error.response.data
return error
})
if (typeof handleResponse === "function") {
await handleResponse(request)
}
if (requestParams.parseData) {
if (result.error) {
return reject(result.error)
}
return resolve(result.response.data)
}
return resolve(result)
})
}
}
const Controller = require("./controller")
const Bridge = require("./bridge")
const generateRequestDispatcher = require("./generateRequestDispatcher")
module.exports = {
Bridge,
Controller,
generateRequestDispatcher,
}