@midwayjs/web
Version:
Midway Web Framework for Egg.js
287 lines • 12 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;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MidwayWebFramework = void 0;
const core_1 = require("@midwayjs/core");
const router_1 = require("@eggjs/router");
const logger_1 = require("@midwayjs/logger");
const path_1 = require("path");
const util_1 = require("util");
const net_1 = require("net");
const debug = (0, util_1.debuglog)('midway:debug');
class EggControllerGenerator extends core_1.WebControllerGenerator {
constructor(app, webRouterService) {
super(app, webRouterService);
this.app = app;
this.webRouterService = webRouterService;
}
createRouter(routerOptions) {
const router = new router_1.EggRouter(routerOptions, this.app);
router.prefix(routerOptions.prefix);
return router;
}
generateController(routeInfo) {
return this.generateKoaController(routeInfo);
}
}
let MidwayWebFramework = class MidwayWebFramework extends core_1.BaseFramework {
constructor() {
super(...arguments);
this.isClusterMode = false;
}
configure() {
process.env.EGG_TYPESCRIPT = 'true';
if (process.env['EGG_CLUSTER_MODE'] === 'true') {
this.isClusterMode = true;
}
return this.configService.getConfiguration('egg');
}
async initSingleProcessEgg() {
const opts = {
baseDir: this.appDir,
framework: (0, path_1.resolve)(__dirname, '../application'),
plugins: this.configurationOptions.plugins,
mode: 'single',
isTsMode: true,
applicationContext: this.applicationContext,
midwaySingleton: true,
};
debug('[egg]: init single process egg agent');
const Agent = require(opts.framework).Agent;
const Application = require(opts.framework).Application;
const agent = (this.agent = new Agent(Object.assign({}, opts)));
await agent.ready();
debug('[egg]: init single process egg application');
const application = (this.app = new Application(Object.assign({}, opts)));
application.agent = agent;
agent.application = application;
debug('[egg]: init single process egg end');
}
async applicationInitialize(options) {
if (!this.isClusterMode) {
await this.initSingleProcessEgg();
}
else {
// get app in cluster mode
this.app = options['application'];
}
// not found middleware
const midwayRouterNotFound = async (ctx, next) => {
await next();
if (!ctx._matchedRoute && ctx.body === undefined) {
throw new core_1.httpError.NotFoundError(`${ctx.path} Not Found`);
}
};
// insert error handler
const midwayRootMiddleware = async (ctx, next) => {
await (await this.applyMiddleware(midwayRouterNotFound))(ctx, next);
};
this.app.use(midwayRootMiddleware);
this.webRouterService = await this.applicationContext.getAsync(core_1.MidwayWebRouterService, [
{
globalPrefix: this.configurationOptions.globalPrefix,
},
]);
this.generator = new EggControllerGenerator(this.app, this.webRouterService);
this.overwriteApplication('app');
this.app.loader.loadOrigin();
// 这里拦截 app.use 方法,让他可以加到 midway 的 middlewareManager 中
this.app.originUse = this.app.use;
this.app.use = this.app.useMiddleware;
if (!this.isClusterMode) {
await new Promise(resolve => {
this.app.once('application-ready', () => {
debug('[egg]: web framework: init egg end');
resolve();
});
this.app.ready();
});
}
}
overwriteApplication(processType) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const self = this;
// 单进程下,先把egg的配置覆盖进来,有可能业务测没写 importConfigs
debug(`[egg]: overwrite egg config to configService in "${processType}"`);
this.configService.addObject(this.app.config);
Object.defineProperty(this.app, 'config', {
get() {
return self.getConfiguration();
},
});
debug(`[egg]: overwrite applicationContext config to "${processType}"`);
Object.defineProperty(this.app, 'applicationContext', {
get() {
return self.applicationContext;
},
});
debug(`[egg]: overwrite properties to "${processType}"`);
this.defineApplicationProperties({
generateController: (controllerMapping) => {
const [controllerId, methodName] = controllerMapping.split('.');
return this.generator.generateController({
id: controllerId,
method: methodName,
});
},
generateMiddleware: async (middlewareId) => {
return this.generateMiddleware(middlewareId);
},
getProcessType: () => {
if (processType === 'app') {
return core_1.MidwayProcessTypeEnum.APPLICATION;
}
if (processType === 'agent') {
return core_1.MidwayProcessTypeEnum.AGENT;
}
},
createContextLogger: (ctx, name) => {
return this.createContextLogger(ctx, name);
},
}, ['createAnonymousContext']);
// if use midway logger will be use midway custom context logger
debug(`[egg]: overwrite BaseContextLoggerClass to "${processType}"`);
this.setContextLoggerClass();
}
async loadMidwayController() {
// move egg router to last
this.app.getMiddleware().findAndInsertLast('eggRouterMiddleware');
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.useMiddleware(dispatchFn);
});
// restore use method
this.app.use = this.app.originUse;
debug(`[egg]: current middleware = ${this.middlewareManager.getNames()}`);
}
getFrameworkType() {
return core_1.MidwayFrameworkType.WEB;
}
async run() {
var _a;
// cluster 模式加载路由需在 run 之前,因为 run 需要在拿到 server 之后执行
if (!this.isClusterMode) {
// load controller
await this.loadMidwayController();
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());
}
}
// emit egg-ready message in agent and application
this.app.messenger.broadcast('egg-ready', undefined);
// emit `server` event in app
this.app.emit('server', this.server);
// register httpServer to applicationContext
this.getApplicationContext().registerObject(core_1.HTTP_SERVER_KEY, this.server);
const eggConfig = this.configService.getConfiguration('egg');
if (!this.isClusterMode && eggConfig) {
let customPort = (_a = process.env.MIDWAY_HTTP_PORT) !== null && _a !== void 0 ? _a : eggConfig.port;
if (customPort === 0) {
customPort = await getFreePort();
}
if (customPort) {
new Promise(resolve => {
const args = [customPort];
if (eggConfig.hostname) {
args.push(eggConfig.hostname);
}
args.push(() => {
resolve();
});
this.server.listen(...args);
process.env.MIDWAY_HTTP_PORT = String(customPort);
});
}
}
}
}
getLogger(name) {
if (name) {
return this.app.loggers[name] || logger_1.loggers.getLogger(name);
}
return this.appLogger;
}
setContextLoggerClass() {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const self = this;
class MidwayEggContextLogger extends logger_1.MidwayContextLogger {
constructor(ctx, appLogger) {
super(ctx, appLogger, {
contextFormat: self.contextLoggerFormat,
});
}
}
this.app.ContextLogger = MidwayEggContextLogger;
}
async generateMiddleware(middlewareId) {
const mwIns = await this.getApplicationContext().getAsync(middlewareId);
return mwIns.resolve();
}
async beforeStop() {
if (!this.isClusterMode) {
await new Promise(resolve => {
this.server.close(resolve);
});
await this.app.close();
await this.agent.close();
}
}
setServer(server) {
this.server = server;
}
};
__decorate([
(0, core_1.Inject)(),
__metadata("design:type", Object)
], MidwayWebFramework.prototype, "appDir", void 0);
MidwayWebFramework = __decorate([
(0, core_1.Framework)()
], MidwayWebFramework);
exports.MidwayWebFramework = MidwayWebFramework;
async function getFreePort() {
return new Promise((resolve, reject) => {
const server = (0, net_1.createServer)();
server.listen(0, () => {
try {
const port = server.address().port;
server.close();
resolve(port);
}
catch (err) {
reject(err);
}
});
});
}
//# sourceMappingURL=web.js.map