• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

teableio / teable / 8387093605

22 Mar 2024 07:48AM CUT coverage: 28.027% (-0.2%) from 28.222%
8387093605

Pull #484

github

web-flow
Merge 174ef76f7 into a06c6afb1
Pull Request #484: feat: support increment import

2099 of 3218 branches covered (65.23%)

24 of 703 new or added lines in 18 files covered. (3.41%)

49 existing lines in 6 files now uncovered.

25815 of 92109 relevant lines covered (28.03%)

5.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/apps/nestjs-backend/src/bootstrap.ts
1
import 'dayjs/plugin/timezone';
×
2
import 'dayjs/plugin/utc';
×
3
import fs from 'fs';
×
4
import path from 'path';
×
5
import type { INestApplication } from '@nestjs/common';
×
6
import { ValidationPipe } from '@nestjs/common';
×
7
import { ConfigService } from '@nestjs/config';
×
8
import { NestFactory } from '@nestjs/core';
×
9
import { WsAdapter } from '@nestjs/platform-ws';
×
10
import { SwaggerModule } from '@nestjs/swagger';
×
11
import { getOpenApiDocumentation } from '@teable/openapi';
×
12
import { json, urlencoded } from 'express';
×
13
import helmet from 'helmet';
×
14
import isPortReachable from 'is-port-reachable';
×
15
import { Logger } from 'nestjs-pino';
×
16
import type { RedocOptions } from 'nestjs-redoc';
×
17
import { RedocModule } from 'nestjs-redoc';
×
18
import { AppModule } from './app.module';
×
19
import type { IBaseConfig } from './configs/base.config';
×
20
import type { ISecurityWebConfig, IApiDocConfig } from './configs/bootstrap.config';
×
21
import { GlobalExceptionFilter } from './filter/global-exception.filter';
×
22
import otelSDK from './tracing';
×
23

×
24
// eslint-disable-next-line @typescript-eslint/no-explicit-any
×
25
declare const module: any;
×
26

×
27
const host = 'localhost';
×
28

×
29
export async function setUpAppMiddleware(app: INestApplication, configService: ConfigService) {
×
30
  app.useWebSocketAdapter(new WsAdapter(app));
×
31
  app.useGlobalFilters(new GlobalExceptionFilter(configService));
×
32
  app.useGlobalPipes(
×
33
    new ValidationPipe({ transform: true, stopAtFirstError: true, forbidUnknownValues: false })
×
34
  );
×
35
  app.use(helmet());
×
36
  app.use(json({ limit: '50mb' }));
×
37
  app.use(urlencoded({ limit: '50mb', extended: true }));
×
38

×
39
  const apiDocConfig = configService.get<IApiDocConfig>('apiDoc');
×
40
  const securityWebConfig = configService.get<ISecurityWebConfig>('security.web');
×
41
  const baseConfig = configService.get<IBaseConfig>('base');
×
42
  if (!apiDocConfig?.disabled) {
×
43
    const openApiDocumentation = await getOpenApiDocumentation({
×
44
      origin: baseConfig?.publicOrigin,
×
45
      snippet: apiDocConfig?.enabledSnippet,
×
46
    });
×
47

×
48
    const jsonString = JSON.stringify(openApiDocumentation);
×
49
    fs.writeFileSync(path.join(__dirname, '/openapi.json'), jsonString);
×
50
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
×
51
    SwaggerModule.setup('/docs', app, openApiDocumentation as any);
×
52

×
53
    // Instead of using SwaggerModule.setup() you call this module
×
54
    const redocOptions: RedocOptions = {
×
55
      logo: {
×
56
        backgroundColor: '#F0F0F0',
×
57
        altText: 'Teable logo',
×
58
      },
×
59
    };
×
60
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
×
61
    await RedocModule.setup('/redocs', app, openApiDocumentation as any, redocOptions);
×
62
  }
×
63

×
64
  if (securityWebConfig?.cors.enabled) {
×
65
    app.enableCors();
×
66
  }
×
67
}
×
68

×
69
export async function bootstrap() {
×
70
  otelSDK.start();
×
71

×
72
  const app = await NestFactory.create(AppModule, { bufferLogs: true });
×
73
  const configService = app.get(ConfigService);
×
74

×
75
  if (module.hot) {
×
76
    module.hot.accept();
×
77
    module.hot.dispose(() => app.close());
×
78
  }
×
79

×
80
  const logger = app.get(Logger);
×
81
  app.useLogger(logger);
×
82
  app.flushLogs();
×
83

×
84
  app.enableShutdownHooks();
×
85

×
86
  await setUpAppMiddleware(app, configService);
×
87

×
88
  // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
×
89
  // app.getHttpServer().on('upgrade', async function (req: any, socket: any, head: any) {
×
90
  //   if (req.url.startsWith('/_next')) {
×
91
  //     console.log('upgrade: ', req.url);
×
92
  //     const server = app.get(NextService).server;
×
93
  //     return server.getUpgradeHandler()(req, socket, head);
×
94
  //   }
×
95
  // });
×
96

×
97
  const port = await getAvailablePort(configService.get<string>('PORT') as string);
×
98
  process.env.PORT = port.toString();
×
99

×
100
  await app.listen(port);
×
101

×
102
  const now = new Date();
×
103
  const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
×
104
  logger.log(`> NODE_ENV is ${process.env.NODE_ENV}`);
×
105
  logger.log(`> Ready on http://${host}:${port}`);
×
106
  logger.log(`> System Time Zone: ${timeZone}`);
×
107
  logger.log(`> Current System Time: ${now.toString()}`);
×
108

×
109
  process.on('unhandledRejection', (reason: string, promise: Promise<unknown>) => {
×
110
    logger.error(`Unhandled Rejection at: ${promise}, reason: ${reason}`);
×
111
    throw reason;
×
112
  });
×
113

×
114
  process.on('uncaughtException', (error) => {
×
115
    logger.error(error);
×
116
  });
×
117
  return app;
×
118
}
×
119

×
120
async function getAvailablePort(dPort: number | string): Promise<number> {
×
121
  let port = Number(dPort);
×
122
  while (await isPortReachable(port, { host })) {
×
123
    console.log(`> Fail on http://${host}:${port} Trying on ${port + 1}`);
×
124
    port++;
×
125
  }
×
126
  return port;
×
127
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc