UNPKG

4.17 kBPlain TextView Raw
1import { Interfaces, LogType } from '@lxdhub/common';
2import { IDatabaseSettings } from '@lxdhub/db';
3import { INestApplication } from '@nestjs/common';
4import { NestFactory } from '@nestjs/core';
5import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
6import { Type } from 'class-transformer';
7import { IsInt, IsString } from 'class-validator';
8
9import { AppModule } from './app.module';
10import { HttpExceptionFilter } from './exception';
11import { LogService } from './log';
12import { RequestLoggerInterceptor } from './log/request-logger.interceptor';
13import { Application } from 'express';
14import * as Chalk from 'chalk';
15import * as express from 'express';
16import * as cors from 'cors';
17import { IoAdapter } from '@nestjs/websockets';
18
19/**
20 * The LXDHub API settings
21 */
22export class LXDHubAPISettings {
23 @IsInt()
24 @Type(() => Number)
25 port?: number = 3000;
26 @IsString()
27 @Type(() => String)
28 hostUrl?: string = '0.0.0.0';
29 database: IDatabaseSettings;
30 lxd?: Interfaces.ILXDRemoteAuthentication;
31 logLevel?: LogType = 'silly';
32 docUrl: string = '/api/v1/doc';
33}
34
35/**
36 * The LXDHub API is the interface for the
37 * LXDHub Web user interface.
38 */
39export class LXDHubAPI implements Interfaces.ILXDHubHttpService {
40 private app: INestApplication;
41 private logger: LogService;
42 private url: string;
43
44 constructor(private settings: LXDHubAPISettings, private server?: Application) {
45 this.logger = new LogService('LXDHubAPI', settings.logLevel);
46 this.url = `http://${this.settings.hostUrl}:${this.settings.port}`;
47 }
48
49 /**
50 * Conigurates Swagger for Nest
51 */
52 private setupSwagger() {
53 const options = new DocumentBuilder()
54 .setTitle('LXDHub API')
55 .setDescription('Display, search and copy LXD images using a web interface.')
56 .setVersion('1.0')
57 .build();
58
59 const document = SwaggerModule.createDocument(this.app, options);
60 SwaggerModule.setup(this.settings.docUrl || '/api/v1/doc', this.app, document);
61 }
62
63 /**
64 * Creates the Nest App
65 */
66 private async createNestApp() {
67 const nestSettings = { logger: this.logger };
68
69 if (!this.server) {
70 this.server = express();
71 }
72
73 this.app = await NestFactory.create(AppModule.forRoot(this.settings), this.server, nestSettings);
74 this.app.useWebSocketAdapter(new IoAdapter(this.app.getHttpServer()));
75 }
76
77 /**
78 * Setup the middleware for LXDHub API
79 */
80 private setupMiddleware() {
81
82 // this.app.setGlobalPrefix('/api/v1');
83 // Global execution handler
84 this.app.useGlobalFilters(new HttpExceptionFilter());
85 // Global request logger
86 // @ts-ignore
87 this.app.useGlobalInterceptors(new RequestLoggerInterceptor());
88
89 // In development, allow any origin to access the website
90 if (process.env.NODE_ENV !== 'production') {
91 this.app.use(cors({
92 origin: true,
93 credentials: true
94 }));
95 }
96
97 this.app.use((req, res, next) => {
98 res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, DEVICE_ID, SSO_TOKEN');
99
100 next();
101 });
102 }
103
104 /**
105 * Bootstraps the LXDHub API and returns the
106 * Express instance
107 */
108 async bootstrap(): Promise<Application> {
109 await this.createNestApp();
110 this.setupSwagger();
111 this.setupMiddleware();
112
113 return this.server;
114 }
115
116 /**
117 * Bootstraps & starts LXDHub API with the given conifgurations
118 */
119 async run() {
120 this.logger.log('Bootstraping application');
121 try {
122 await this.bootstrap();
123 }
124 catch (err) {
125 err = err as Error;
126 this.logger.error(`An error occured while bootstraping the application`);
127 this.logger.error(err.message);
128 }
129
130 // Starts listening on the given port and host url
131 await this.app.listen(this.settings.port, this.settings.hostUrl);
132 this.logger.log(`Open on ${Chalk.default.blue(this.url)}`);
133 }
134}