169 lines
5.1 KiB
TypeScript
169 lines
5.1 KiB
TypeScript
|
import { MailerModule } from '@nestjs-modules/mailer'
|
||
|
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo'
|
||
|
import { HttpModule } from '@nestjs/axios'
|
||
|
import { RequestMethod } from '@nestjs/common'
|
||
|
import { ConfigModule, ConfigService } from '@nestjs/config'
|
||
|
import { GraphQLModule } from '@nestjs/graphql'
|
||
|
import { JwtModule, JwtModuleOptions } from '@nestjs/jwt'
|
||
|
import { ServeStaticModule } from '@nestjs/serve-static'
|
||
|
import { TypeOrmModule, TypeOrmModuleOptions } from '@nestjs/typeorm'
|
||
|
import crypto from 'crypto'
|
||
|
import { Request } from 'express-serve-static-core'
|
||
|
import { IncomingHttpHeaders } from 'http'
|
||
|
import { ConsoleModule } from 'nestjs-console'
|
||
|
import { LoggerModule, Params as LoggerModuleParams } from 'nestjs-pino'
|
||
|
import { join } from 'path'
|
||
|
import { serializeError } from 'serialize-error'
|
||
|
import { entities } from './entity'
|
||
|
|
||
|
export const LoggerConfig: LoggerModuleParams = {
|
||
|
pinoHttp: {
|
||
|
level: process.env.CLI ? 'warn' : process.env.NODE_ENV !== 'production' ? 'debug' : 'info',
|
||
|
serializers: {
|
||
|
error: serializeError,
|
||
|
},
|
||
|
transport: process.env.NODE_ENV !== 'production' || process.env.CLI ? {
|
||
|
options: {
|
||
|
ignore: 'req,res,pid,hostname',
|
||
|
translateTime: true,
|
||
|
},
|
||
|
target: 'pino-pretty',
|
||
|
} : undefined,
|
||
|
},
|
||
|
exclude: [
|
||
|
{
|
||
|
method: RequestMethod.ALL,
|
||
|
path: '_health',
|
||
|
},
|
||
|
{
|
||
|
method: RequestMethod.ALL,
|
||
|
path: 'favicon.ico',
|
||
|
},
|
||
|
],
|
||
|
}
|
||
|
|
||
|
export const imports = [
|
||
|
ConsoleModule,
|
||
|
HttpModule.register({
|
||
|
timeout: 5000,
|
||
|
maxRedirects: 10,
|
||
|
}),
|
||
|
ServeStaticModule.forRoot({
|
||
|
rootPath: join(__dirname, '..', 'public'),
|
||
|
exclude: ['/graphql'],
|
||
|
}),
|
||
|
ConfigModule.forRoot({
|
||
|
load: [
|
||
|
() => {
|
||
|
return {
|
||
|
LOCALES_PATH: join(process.cwd(), 'locales'),
|
||
|
SECRET_KEY: process.env.SECRET_KEY || crypto.randomBytes(20).toString('hex'),
|
||
|
}
|
||
|
},
|
||
|
],
|
||
|
}),
|
||
|
JwtModule.registerAsync({
|
||
|
imports: [ConfigModule],
|
||
|
inject: [ConfigService],
|
||
|
useFactory: (configService: ConfigService): JwtModuleOptions => ({
|
||
|
secret: configService.get<string>('SECRET_KEY'),
|
||
|
signOptions: {
|
||
|
expiresIn: '4h',
|
||
|
},
|
||
|
}),
|
||
|
}),
|
||
|
LoggerModule.forRoot(LoggerConfig),
|
||
|
GraphQLModule.forRoot<ApolloDriverConfig>({
|
||
|
debug: process.env.NODE_ENV !== 'production',
|
||
|
definitions: {
|
||
|
outputAs: 'class',
|
||
|
},
|
||
|
driver: ApolloDriver,
|
||
|
sortSchema: true,
|
||
|
introspection: process.env.NODE_ENV !== 'production',
|
||
|
playground: process.env.NODE_ENV !== 'production',
|
||
|
installSubscriptionHandlers: true,
|
||
|
autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
|
||
|
// to allow guards on resolver props https://github.com/nestjs/graphql/issues/295
|
||
|
fieldResolverEnhancers: [
|
||
|
'guards',
|
||
|
'interceptors',
|
||
|
],
|
||
|
resolverValidationOptions: {
|
||
|
|
||
|
},
|
||
|
context: ({ req, connection }) => {
|
||
|
if (!req && connection) {
|
||
|
const headers: IncomingHttpHeaders = {}
|
||
|
|
||
|
Object.keys(connection.context).forEach(key => {
|
||
|
headers[key.toLowerCase()] = connection.context[key]
|
||
|
})
|
||
|
|
||
|
return {
|
||
|
req: {
|
||
|
headers,
|
||
|
} as Request,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return { req }
|
||
|
},
|
||
|
}),
|
||
|
TypeOrmModule.forRootAsync({
|
||
|
imports: [ConfigModule],
|
||
|
inject: [ConfigService],
|
||
|
useFactory: (configService: ConfigService): TypeOrmModuleOptions => {
|
||
|
const type: any = configService.get<string>('DATABASE_DRIVER', 'sqlite')
|
||
|
let migrationFolder: string
|
||
|
let migrationsTransactionMode: 'each' | 'none' | 'all' = 'each'
|
||
|
|
||
|
switch (type) {
|
||
|
case 'cockroachdb':
|
||
|
case 'postgres':
|
||
|
migrationFolder = 'postgres'
|
||
|
break
|
||
|
|
||
|
case 'mysql':
|
||
|
case 'mariadb':
|
||
|
migrationFolder = 'mariadb'
|
||
|
break
|
||
|
|
||
|
case 'sqlite':
|
||
|
migrationFolder = 'sqlite'
|
||
|
migrationsTransactionMode = 'none'
|
||
|
break
|
||
|
|
||
|
default:
|
||
|
throw new Error('unsupported driver')
|
||
|
}
|
||
|
|
||
|
return ({
|
||
|
name: 'ohmyform',
|
||
|
synchronize: false,
|
||
|
type,
|
||
|
url: configService.get<string>('DATABASE_URL'),
|
||
|
database: type === 'sqlite' ? configService.get<string>('DATABASE_URL', 'data.sqlite').replace('sqlite://', '') : undefined,
|
||
|
ssl: configService.get<string>('DATABASE_SSL', 'false') === 'true' ? { rejectUnauthorized: false } : false,
|
||
|
entityPrefix: configService.get<string>('DATABASE_TABLE_PREFIX', ''),
|
||
|
logging: configService.get<string>('DATABASE_LOGGING', 'false') === 'true',
|
||
|
entities,
|
||
|
migrations: [`${__dirname}/**/migrations/${migrationFolder}/**/*{.ts,.js}`],
|
||
|
migrationsRun: configService.get<boolean>('DATABASE_MIGRATE', true),
|
||
|
migrationsTransactionMode,
|
||
|
})
|
||
|
},
|
||
|
}),
|
||
|
TypeOrmModule.forFeature(entities),
|
||
|
MailerModule.forRootAsync({
|
||
|
imports: [ConfigModule],
|
||
|
inject: [ConfigService],
|
||
|
useFactory: (configService: ConfigService) => ({
|
||
|
transport: configService.get<string>('MAILER_URI', 'smtp://localhost:1025'),
|
||
|
defaults: {
|
||
|
from: configService.get<string>('MAILER_FROM', 'OhMyForm <no-reply@localhost>'),
|
||
|
},
|
||
|
}),
|
||
|
}),
|
||
|
]
|