Bump dependencies and account for breaking changes. --------- Co-authored-by: James George <25279263+jamesgeorge007@users.noreply.github.com>
123 lines
3.5 KiB
TypeScript
123 lines
3.5 KiB
TypeScript
import { NestFactory } from '@nestjs/core';
|
|
import { json } from 'express';
|
|
import { AppModule } from './app.module';
|
|
import cookieParser from 'cookie-parser';
|
|
import { ValidationPipe, VersioningType } from '@nestjs/common';
|
|
import session from 'express-session';
|
|
import { emitGQLSchemaFile } from './gql-schema';
|
|
import * as crypto from 'crypto';
|
|
import morgan from 'morgan';
|
|
import { ConfigService } from '@nestjs/config';
|
|
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
|
import { InfraTokenModule } from './infra-token/infra-token.module';
|
|
import { NestExpressApplication } from '@nestjs/platform-express';
|
|
|
|
function setupSwagger(
|
|
app: NestExpressApplication,
|
|
isProduction: boolean,
|
|
): void {
|
|
const swaggerDocPath = '/api-docs';
|
|
|
|
const config = new DocumentBuilder()
|
|
.setTitle('Hoppscotch API Documentation')
|
|
.setDescription('APIs for external integration')
|
|
.addApiKey(
|
|
{
|
|
type: 'apiKey',
|
|
name: 'Authorization',
|
|
in: 'header',
|
|
scheme: 'bearer',
|
|
bearerFormat: 'Bearer',
|
|
},
|
|
'infra-token',
|
|
)
|
|
.build();
|
|
|
|
const document = SwaggerModule.createDocument(app, config, {
|
|
include: isProduction ? [InfraTokenModule] : [],
|
|
});
|
|
SwaggerModule.setup(swaggerDocPath, app, document, {
|
|
swaggerOptions: { persistAuthorization: true, ignoreGlobalPrefix: true },
|
|
});
|
|
}
|
|
|
|
async function bootstrap() {
|
|
const app = await NestFactory.create<NestExpressApplication>(AppModule);
|
|
|
|
const configService = app.get(ConfigService);
|
|
const isProduction = configService.get('PRODUCTION') === 'true';
|
|
|
|
console.log(`Running in production: ${isProduction}`);
|
|
console.log(`Port: ${configService.get('PORT')}`);
|
|
|
|
app.use(
|
|
session({
|
|
// Allow overriding the default cookie name 'connect.sid' (which contains a dot).
|
|
// Some proxies/load balancers (like older Kong versions) cannot hash cookie names with dots,
|
|
// so we allow setting an alternative name via the INFRA.SESSION_COOKIE_NAME configuration.
|
|
name:
|
|
configService.get<string>('INFRA.SESSION_COOKIE_NAME') || 'connect.sid',
|
|
secret:
|
|
configService.get<string>('INFRA.SESSION_SECRET') ||
|
|
crypto.randomBytes(16).toString('hex'),
|
|
resave: false,
|
|
saveUninitialized: false,
|
|
}),
|
|
);
|
|
|
|
// Increase file upload limit to 100MB
|
|
app.use(
|
|
json({
|
|
limit: '100mb',
|
|
}),
|
|
);
|
|
|
|
if (isProduction) {
|
|
console.log('Enabling CORS with production settings');
|
|
app.enableCors({
|
|
origin: configService.get('WHITELISTED_ORIGINS').split(','),
|
|
credentials: true,
|
|
});
|
|
} else {
|
|
console.log('Enabling CORS with development settings');
|
|
app.enableCors({
|
|
origin: true,
|
|
credentials: true,
|
|
});
|
|
}
|
|
|
|
app.enableVersioning({
|
|
type: VersioningType.URI,
|
|
});
|
|
app.use(cookieParser());
|
|
app.useGlobalPipes(
|
|
new ValidationPipe({
|
|
transform: true,
|
|
}),
|
|
);
|
|
|
|
if (configService.get('TRUST_PROXY') === 'true') {
|
|
console.log('Enabling trust proxy');
|
|
app.set('trust proxy', true);
|
|
}
|
|
|
|
app.use(morgan(':remote-addr :method :url :status - :response-time ms'));
|
|
|
|
await setupSwagger(app, isProduction);
|
|
|
|
await app.listen(configService.get('PORT') || 3170);
|
|
|
|
// Graceful shutdown
|
|
process.on('SIGTERM', async () => {
|
|
console.info('SIGTERM signal received, initiating graceful shutdown...');
|
|
await app.close();
|
|
console.info('Application closed successfully');
|
|
process.exit(0);
|
|
});
|
|
}
|
|
|
|
if (!process.env.GENERATE_GQL_SCHEMA) {
|
|
bootstrap();
|
|
} else {
|
|
emitGQLSchemaFile();
|
|
}
|