@tsed/common
Version:
A TypeScript Framework on top of Express
219 lines • 7.29 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PlatformBuilder = void 0;
const core_1 = require("@tsed/core");
const di_1 = require("@tsed/di");
const platform_1 = require("../../platform");
const PlatformLogMiddleware_1 = require("../../platform/middlewares/PlatformLogMiddleware");
const utils_1 = require("../utils");
/**
* @platform
*/
class PlatformBuilder {
constructor() {
this.startedAt = new Date();
this.PLATFORM_NAME = "";
this.locals = new di_1.Container()
.add(platform_1.PlatformHandler)
.add(platform_1.PlatformResponse)
.add(platform_1.PlatformRequest)
.add(platform_1.PlatformRouter)
.add(platform_1.PlatformApplication)
.add(platform_1.Platform);
}
get name() {
return this.PLATFORM_NAME;
}
get injector() {
return this._injector;
}
get rootModule() {
return this._rootModule;
}
get app() {
return this.injector.get(platform_1.PlatformApplication);
}
get platform() {
return this.injector.get(platform_1.Platform);
}
/**
* Return the settings configured by the decorator @@Configuration@@.
*
* ```typescript
* @Configuration({
* rootDir: Path.resolve(__dirname),
* port: 8000,
* httpsPort: 8080,
* mount: {
* "/rest": "${rootDir}/controllers/**\/*.js"
* }
* })
* export class Server {
* $onInit(){
* console.log(this.settings); // {rootDir, port, httpsPort,...}
* }
* }
* ```
*
* @returns {PlatformConfiguration}
*/
get settings() {
return this.injector.settings;
}
get logger() {
return this.injector.logger;
}
static build(platformBuildClass) {
const platform = new platformBuildClass();
platform.PLATFORM_NAME = core_1.nameOf(platformBuildClass).replace("Platform", "").toLowerCase();
return platform.useProviders(platformBuildClass.providers || []);
}
/**
* Add classes to the components list
* @param classes
*/
addComponents(classes) {
this.settings.componentsScan = this.settings.componentsScan.concat(classes);
return this;
}
/**
* Add classes decorated by @@Controller@@ to components container.
*
* ### Example
*
* ```typescript
* @Controller('/ctrl')
* class MyController{
* }
*
* platform.addControllers('/rest', [MyController])
* ```
*
* ::: tip
* If the MyController class isn't decorated, the class will be ignored.
* :::
*
* @param {string} endpoint
* @param {any[]} controllers
*/
addControllers(endpoint, controllers) {
this.settings.mount[endpoint] = (this.settings.mount[endpoint] || []).concat(controllers);
}
async runLifecycle() {
di_1.setLoggerLevel(this.injector);
const routes = await utils_1.importRoutes(this.injector);
await this.loadInjector();
await this.loadRoutes(routes);
await this.logRoutes();
}
async loadInjector() {
const { injector, logger } = this;
await this.callHook("$beforeInit");
logger.info("Build providers");
await utils_1.loadInjector(injector, di_1.createContainer(core_1.constructorOf(this.rootModule)));
logger.debug("Settings and injector loaded");
await this.callHook("$afterInit");
}
async listen() {
await this.callHook("$beforeListen");
await this.listenServers();
await this.callHook("$afterListen");
await this.ready();
}
async stop() {
await this.callHook("$onDestroy");
return this.injector.destroy();
}
async ready() {
const { logger, startedAt } = this;
await this.callHook("$onReady");
await this.injector.emit("$onServerReady");
logger.info(`Started in ${new Date().getTime() - startedAt.getTime()} ms`);
}
callHook(key, ...args) {
return utils_1.callHook(this.injector, this.rootModule, key, ...args);
}
async loadStatics() {
const { settings } = this;
if (settings.statics) {
Object.entries(settings.statics).forEach(([path, items]) => {
[].concat(items).forEach((options) => {
const opts = typeof options === "string"
? {
root: options
}
: options;
this.platform.app.statics(path, opts);
});
});
}
}
useProvider(token, settings) {
if (this.locals.hasProvider(token)) {
Object.assign(this.locals.getProvider(token), settings);
}
else {
this.locals.addProvider(token, settings);
}
return this;
}
useProviders(providers) {
providers.forEach(({ provide, ...settings }) => {
this.useProvider(provide, settings);
});
return this;
}
async bootstrap(module, settings = {}) {
this.createInjector(module, {
...settings,
PLATFORM_NAME: this.PLATFORM_NAME
});
this.createRootModule(module);
await this.runLifecycle();
return this;
}
async listenServers() {
await Promise.all([utils_1.listenHttpServer(this.injector), utils_1.listenHttpsServer(this.injector)]);
}
logRoutes() {
const { logger, platform } = this;
if (!this.settings.logger.disableRoutesSummary) {
logger.info("Routes mounted :");
logger.info(utils_1.printRoutes(platform.getRoutes()));
}
}
async loadRoutes(routes) {
var _a;
const { logger, platform } = this;
// istanbul ignore next
if (this.settings.logger.level !== "off") {
this.app.use(PlatformLogMiddleware_1.PlatformLogMiddleware);
}
if ((_a = this.settings.acceptMimes) === null || _a === void 0 ? void 0 : _a.length) {
this.app.use(platform_1.GlobalAcceptMimesMiddleware);
}
logger.info("Load routes");
await this.callHook("$beforeRoutesInit"); // deprecated
platform.addRoutes(routes);
await this.callHook("$onRoutesInit");
await this.loadStatics();
await this.callHook("$afterRoutesInit");
}
createInjector(module, settings) {
this._injector = utils_1.createInjector(di_1.getConfiguration(module, settings));
// configure locals providers
this.locals.forEach((provider) => {
this.injector.addProvider(provider.token, provider);
});
utils_1.createPlatformApplication(this.injector);
utils_1.createHttpsServer(this.injector);
utils_1.createHttpServer(this.injector);
}
createRootModule(module) {
this._rootModule = this.injector.invoke(module);
this.injector.delete(core_1.constructorOf(this._rootModule));
this.injector.delete(core_1.classOf(this._rootModule));
}
}
exports.PlatformBuilder = PlatformBuilder;
//# sourceMappingURL=PlatformBuilder.js.map