1
0
ohmyform/api/src/app.imports.ts

169 lines
5.1 KiB
TypeScript
Raw Permalink Normal View History

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>'),
},
}),
}),
]