@midwayjs/koa
Version:
Midway Web Framework for KOA
267 lines • 11.1 kB
JavaScript
"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