|
import * as path from "path"; |
|
|
|
import { staticPlugin } from "@elysiajs/static"; |
|
import ejs from "ejs"; |
|
import { Context, Elysia, HTTPMethod as ElysiaMethod } from "elysia"; |
|
import { |
|
AppControllerRoute, |
|
AppViewRoute, |
|
BullBoardQueues, |
|
ControllerHandlerReturnType, |
|
FavIcon, |
|
IMiscLink, |
|
IServerAdapter, |
|
UIConfig, |
|
HTTPMethod, |
|
} from "@bull-board/api/dist/typings/app.js"; |
|
|
|
export class ElysiaAdapter implements IServerAdapter { |
|
private basePath = ""; |
|
private bullBoardQueues: BullBoardQueues | undefined; |
|
private errorHandler: ((error: Error) => ControllerHandlerReturnType) | undefined; |
|
private statics: { path: string; route: string } | undefined; |
|
private apiRoutes: AppControllerRoute[] | undefined; |
|
private entryRoute: AppViewRoute | undefined; |
|
private viewPath: string | undefined; |
|
private uiConfig: UIConfig = {}; |
|
|
|
setQueues(bullBoardQueues: BullBoardQueues): IServerAdapter { |
|
this.bullBoardQueues = bullBoardQueues; |
|
|
|
return this; |
|
} |
|
setViewsPath(viewPath: string): IServerAdapter { |
|
this.viewPath = viewPath; |
|
|
|
return this; |
|
} |
|
setStaticPath(staticsRoute: string, staticsPath: string): IServerAdapter { |
|
this.statics = { route: staticsRoute, path: staticsPath }; |
|
|
|
return this; |
|
} |
|
setErrorHandler( |
|
handler: (error: Error) => ControllerHandlerReturnType, |
|
): IServerAdapter { |
|
this.errorHandler = handler; |
|
|
|
return this; |
|
} |
|
setEntryRoute(route: AppViewRoute): IServerAdapter { |
|
this.entryRoute = route; |
|
|
|
return this; |
|
} |
|
setApiRoutes(routes: AppControllerRoute[]): IServerAdapter { |
|
this.apiRoutes = routes; |
|
|
|
return this; |
|
} |
|
setUIConfig( |
|
config: Partial<{ |
|
boardTitle: string; |
|
boardLogo: { |
|
path: string; |
|
width?: string | number; |
|
height?: string | number; |
|
}; |
|
miscLinks: IMiscLink[]; |
|
favIcon: FavIcon; |
|
}>, |
|
): IServerAdapter { |
|
this.uiConfig = config; |
|
|
|
return this; |
|
} |
|
|
|
parseMethod(method: HTTPMethod): ElysiaMethod { |
|
switch (method) { |
|
case "get": |
|
case "post": |
|
case "put": |
|
return method.toUpperCase() as ElysiaMethod; |
|
} |
|
} |
|
|
|
public plugin() { |
|
if (!this.statics) { |
|
throw new Error(`Please call 'setStaticPath' before using 'registerPlugin'`); |
|
} else if (!this.entryRoute) { |
|
throw new Error(`Please call 'setEntryRoute' before using 'registerPlugin'`); |
|
} else if (!this.viewPath) { |
|
throw new Error(`Please call 'setViewsPath' before using 'registerPlugin'`); |
|
} else if (!this.apiRoutes) { |
|
throw new Error(`Please call 'setApiRoutes' before using 'registerPlugin'`); |
|
} else if (!this.bullBoardQueues) { |
|
throw new Error(`Please call 'setQueues' before using 'registerPlugin'`); |
|
} else if (!this.errorHandler) { |
|
throw new Error( |
|
`Please call 'setErrorHandler' before using 'registerPlugin'`, |
|
); |
|
} |
|
|
|
return (app: Elysia): Elysia => { |
|
const queues = this.bullBoardQueues; |
|
|
|
function handler(handler: any) { |
|
return async (context: Context): Promise<Response> => { |
|
const response = await handler({ |
|
queues: queues as any, |
|
params: context.params, |
|
query: context.query, |
|
}); |
|
|
|
return new Response(JSON.stringify(response.body), { |
|
status: response.status || 200, |
|
}); |
|
}; |
|
} |
|
|
|
app.use( |
|
staticPlugin({ |
|
prefix: this.statics?.route, |
|
assets: this.statics?.path, |
|
}), |
|
); |
|
|
|
const { method, route, handler: viewHandler } = this.entryRoute!; |
|
const viewRoutes = Array.isArray(route) ? route : [route]; |
|
viewRoutes.forEach((localPath) => { |
|
app.route(this.parseMethod(method), localPath, async (context) => { |
|
const { name, params } = viewHandler({ |
|
basePath: this.basePath, |
|
uiConfig: this.uiConfig, |
|
}); |
|
|
|
const template = Bun.file(path.join(this.viewPath!, name)); |
|
const render = await ejs.compile(await template.text())(params); |
|
|
|
return new Response(render, { |
|
headers: { |
|
"Content-Type": "text/html", |
|
}, |
|
status: 200, |
|
}); |
|
}); |
|
}); |
|
|
|
this.apiRoutes?.forEach((route) => { |
|
const methods = Array.isArray(route.method) |
|
? route.method |
|
: [route.method]; |
|
|
|
methods.forEach((method) => { |
|
const paths = Array.isArray(route.route) |
|
? route.route |
|
: [route.route]; |
|
paths.forEach((path) => { |
|
app.route(this.parseMethod(method), path, handler(route.handler)); |
|
}); |
|
}); |
|
}); |
|
|
|
return app; |
|
}; |
|
} |
|
} |
|
|