UNPKG

@midwayjs/koa

Version:

Midway Web Framework for KOA

267 lines 11.1 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MidwayKoaFramework = void 0; const core_1 = require("@midwayjs/core"); const cookies_1 = require("@midwayjs/cookies"); const Router = require("@koa/router"); const koa = require("koa"); const onerror_1 = require("./onerror"); const qs = require("qs"); const querystring = require("querystring"); const COOKIES = Symbol('context#cookies'); class KoaControllerGenerator extends core_1.WebControllerGenerator { constructor(app, webRouterService) { super(app, webRouterService); this.app = app; this.webRouterService = webRouterService; } createRouter(routerOptions) { const router = new Router(routerOptions); router.prefix(routerOptions.prefix); return router; } generateController(routeInfo) { return this.generateKoaController(routeInfo); } } let MidwayKoaFramework = class MidwayKoaFramework extends core_1.BaseFramework { configure() { return this.configService.getConfiguration('koa'); } async applicationInitialize(options) { const appKeys = this.configService.getConfiguration('keys') || this.configurationOptions['keys']; if (!appKeys) { throw new core_1.MidwayConfigMissingError('config.keys'); } const cookieOptions = this.configService.getConfiguration('cookies'); const cookieGetOptions = this.configService.getConfiguration('cookiesExtra.defaultGetOptions'); this.app = new koa({ keys: [].concat(appKeys), proxy: this.configurationOptions.proxy, proxyIpHeader: this.configurationOptions.proxyIpHeader, subdomainOffset: this.configurationOptions.subdomainOffset, maxIpsCount: this.configurationOptions.maxIpsCount, }); Object.defineProperty(this.app.context, 'cookies', { get() { if (!this[COOKIES]) { this[COOKIES] = new cookies_1.Cookies(this, this.app.keys, cookieOptions, cookieGetOptions); } return this[COOKIES]; }, enumerable: true, }); Object.defineProperty(this.app.context, 'locals', { get() { return this.state; }, set(value) { this.state = value; }, }); Object.defineProperty(this.app.context, 'forward', { get() { return async function (url) { const routerService = this.requestContext.get(core_1.MidwayWebRouterService); const matchedUrlRouteInfo = await routerService.getMatchedRouterInfo(url, this.method); if (matchedUrlRouteInfo) { if (matchedUrlRouteInfo.controllerClz) { // normal class controller router const controllerInstance = await this.requestContext.getAsync(matchedUrlRouteInfo.controllerClz); return controllerInstance[matchedUrlRouteInfo.method](this); } else if (typeof matchedUrlRouteInfo.method === 'function') { // dynamic router return matchedUrlRouteInfo.method(this); } } else { throw new core_1.httpError.NotFoundError(`Forward url ${url} Not Found`); } }; }, }); const converter = this.configurationOptions.queryParseMode === 'strict' ? function (value) { return !Array.isArray(value) ? [value] : value; } : this.configurationOptions.queryParseMode === 'first' ? function (value) { return Array.isArray(value) ? value[0] : value; } : undefined; // eslint-disable-next-line @typescript-eslint/no-this-alias const self = this; // fix query with array params Object.defineProperty(this.app.request, 'query', { get() { const str = this.querystring; const c = (this._querycache = this._querycache || {}); // find cache if (c[str]) return c[str]; if (self.configurationOptions.queryParseMode) { // use qs module to parse query c[str] = qs.parse(str, self.configurationOptions.queryParseOptions || {}); } else { // use querystring to parse query by default c[str] = querystring.parse(str); } if (converter) { for (const key in c[str]) { c[str][key] = converter(c[str][key]); } } return c[str]; }, set(value) { this._querycache = this._querycache || {}; this._querycache[this.querystring] = value; }, }); const onerrorConfig = this.configService.getConfiguration('onerror'); (0, onerror_1.setupOnError)(this.app, onerrorConfig, this.logger); // not found middleware const notFound = async (ctx, next) => { await next(); if (!ctx._matchedRoute && ctx.body === undefined) { throw new core_1.httpError.NotFoundError(`${ctx.path} Not Found`); } }; // root middleware const midwayRootMiddleware = async (ctx, next) => { this.app.createAnonymousContext(ctx); await (await this.applyMiddleware(notFound))(ctx, next); if (ctx.body === undefined && !ctx.response._explicitStatus && ctx._matchedRoute) { // 如果进了路由,重新赋值,防止 404 ctx.body = undefined; } }; this.app.use(midwayRootMiddleware); this.webRouterService = await this.applicationContext.getAsync(core_1.MidwayWebRouterService, [ { globalPrefix: this.configurationOptions.globalPrefix, }, ]); this.generator = new KoaControllerGenerator(this.app, this.webRouterService); this.defineApplicationProperties(); // hack use method this.app.originUse = this.app.use; this.app.use = this.app.useMiddleware; } async loadMidwayController() { await this.generator.loadMidwayController(newRouter => { var _a; const dispatchFn = newRouter.middleware(); dispatchFn._name = `midwayController(${((_a = newRouter === null || newRouter === void 0 ? void 0 : newRouter.opts) === null || _a === void 0 ? void 0 : _a.prefix) || '/'})`; this.app.use(dispatchFn); }); } /** * wrap controller string to middleware function */ generateController(routeInfo) { return this.generator.generateKoaController(routeInfo); } /** * @deprecated * @param middlewareId */ async generateMiddleware(middlewareId) { const mwIns = await this.getApplicationContext().getAsync(middlewareId); return mwIns.resolve(); } async run() { var _a; // load controller await this.loadMidwayController(); // restore use method this.app.use = this.app.originUse; const serverOptions = { ...this.configurationOptions, ...this.configurationOptions.serverOptions, }; // https config if (serverOptions.key && serverOptions.cert) { serverOptions.key = core_1.PathFileUtil.getFileContentSync(serverOptions.key); serverOptions.cert = core_1.PathFileUtil.getFileContentSync(serverOptions.cert); serverOptions.ca = core_1.PathFileUtil.getFileContentSync(serverOptions.ca); process.env.MIDWAY_HTTP_SSL = 'true'; if (serverOptions.http2) { this.server = require('http2').createSecureServer(serverOptions, this.app.callback()); } else { this.server = require('https').createServer(serverOptions, this.app.callback()); } } else { if (serverOptions.http2) { this.server = require('http2').createServer(serverOptions, this.app.callback()); } else { this.server = require('http').createServer(serverOptions, this.app.callback()); } } // register httpServer to applicationContext this.applicationContext.registerObject(core_1.HTTP_SERVER_KEY, this.server); // server timeout if (core_1.Types.isNumber(this.configurationOptions.serverTimeout)) { this.server.setTimeout(this.configurationOptions.serverTimeout); } // set port and listen server const customPort = (_a = process.env.MIDWAY_HTTP_PORT) !== null && _a !== void 0 ? _a : this.configurationOptions.port; if (customPort) { new Promise(resolve => { const args = [customPort]; if (this.configurationOptions.hostname) { args.push(this.configurationOptions.hostname); } args.push(() => { resolve(); }); this.server.listen(...args); process.env.MIDWAY_HTTP_PORT = String(customPort); }); } } async beforeStop() { if (this.server) { new Promise(resolve => { this.server.close(resolve); }); } } getFrameworkType() { return core_1.MidwayFrameworkType.WEB_KOA; } getFrameworkName() { return 'web:koa'; } getServer() { return this.server; } getPort() { return process.env.MIDWAY_HTTP_PORT; } useMiddleware(Middleware) { this.middlewareManager.insertLast(Middleware); } useFilter(Filter) { this.filterManager.useFilter(Filter); } }; MidwayKoaFramework = __decorate([ (0, core_1.Framework)() ], MidwayKoaFramework); exports.MidwayKoaFramework = MidwayKoaFramework; //# sourceMappingURL=framework.js.map