import { Context, Inject } from '@nuxt/types/app' import mongodb from 'mongodb' import camelcase from 'camelcase' import qs from 'qs' import { QRequestController } from './../../server/modules/RequestController' import { QRequest, QRequestControllerConstructorData, } from './../../types/server.d' import config from '~/config.js' interface Router { routes: { [index: string]: Promise<{ default: QRequestController }> } } class ServerApiClass { db: mongodb.Db session?: any Router: Router constructor(db: mongodb.Db, Router: Router, session?: any) { this.session = session this.db = db this.Router = Router } async $get(url: string) { return await importController( url, 'GET', this.db, this.Router, undefined, this.session ) } async $post(url: string, body?: any) { return await importController( url, 'POST', this.db, this.Router, body, this.session ) } } export default function (context: Context, inject: Inject) { const req = context.req const DB = req.DB const Router: Router = req.Router const ServerApi = new ServerApiClass(DB.db, Router, req.session) inject('api', ServerApi) } async function importController( url: string, method: string, db: mongodb.Db, Router: Router, body?: any, session?: any ) { url = url.slice(4) if (url.includes('/v2/')) { url = url.replace('/v2/', '/') } const parsedURL = url.split('?') const pathName = parsedURL[0] const splittedURL = pathName.split('/').filter((v) => v) const controllerName = splittedURL[0] const functionName = camelcase(splittedURL[1] || 'index') const query = qs.parse(String(parsedURL[1] || '')) const ControllerModule = await Router.routes[controllerName] const Controller = ControllerModule?.default if (Controller) { const requestData: QRequestControllerConstructorData = { method, db, body, session, query, url, splittedURL, config, } const controller = new Controller(requestData) let answer let methodFunctionName = `_${functionName}_${method}` if (controller[methodFunctionName]) { answer = await controller[methodFunctionName]() } else if (controller._param) { methodFunctionName = `__param_${method}` answer = await controller[methodFunctionName](functionName) } else { throw new Error('error') } if (answer === undefined) { return false } return answer } }