diff --git a/src/app.module.ts b/src/app.module.ts deleted file mode 100644 index 82d42ba..0000000 --- a/src/app.module.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { APP_FILTER, APP_INTERCEPTOR, APP_PIPE } from '@nestjs/core'; - -import { AppInterceptor } from '@/modules/core/providers/app.interceptor'; - -import { MEILI_CONFIG } from '@/modules/meilisearch/meili.config'; -import { MeiliModule } from '@/modules/meilisearch/meili.module'; - -import { content, database } from './config'; - -import { DEFAULT_VALIDATION_CONFIG } from './modules/content/constants'; -import { ContentModule } from './modules/content/content.module'; -import { CoreModule } from './modules/core/core.module'; -import { AppFilter } from './modules/core/providers/app.filter'; -import { AppPipe } from './modules/core/providers/app.pipe'; -import { DatabaseModule } from './modules/database/database.module'; - -@Module({ - imports: [ - ContentModule.forRoot(content), - CoreModule.forRoot(), - DatabaseModule.forRoot(database), - MeiliModule.forRoot(MEILI_CONFIG), - ], - providers: [ - { - provide: APP_PIPE, - useValue: new AppPipe(DEFAULT_VALIDATION_CONFIG), - }, - { - provide: APP_INTERCEPTOR, - useClass: AppInterceptor, - }, - { - provide: APP_FILTER, - useClass: AppFilter, - }, - ], -}) -export class AppModule {} diff --git a/src/config/app.config.ts b/src/config/app.config.ts new file mode 100644 index 0000000..d17a997 --- /dev/null +++ b/src/config/app.config.ts @@ -0,0 +1,9 @@ +import { toNumber } from 'lodash'; + +import { createAppConfig } from '@/modules/core/config'; + +export const app = createAppConfig((configure) => ({ + port: configure.env.get('APP_PORT', (v) => toNumber(v), 3099), + prefix: 'api', + }); +}); diff --git a/src/config/content.config.ts b/src/config/content.config.ts index 266da1a..725a189 100644 --- a/src/config/content.config.ts +++ b/src/config/content.config.ts @@ -1,5 +1,6 @@ -import { ContentConfig } from '@/modules/content/types'; +import { createContentConfig } from '@/modules/content/config'; -export const content = (): ContentConfig => ({ - SearchType: 'meili', -}); +export const content = createContentConfig(() => ({ + searchType: 'meili', + htmlEnabled: false, +})); diff --git a/src/config/database.config.ts b/src/config/database.config.ts index 09688ee..1d38af8 100644 --- a/src/config/database.config.ts +++ b/src/config/database.config.ts @@ -1,15 +1,17 @@ -import { TypeOrmModuleOptions } from '@nestjs/typeorm'; +import { toNumber } from 'lodash'; -export const database = (): TypeOrmModuleOptions => ({ - charset: 'utf8mb4', - logging: ['error'], - type: 'mysql', - host: '192.168.50.26', - port: 3306, - username: '3r', - password: '12345678', - database: '3r', - synchronize: true, - autoLoadEntities: true, - timezone: '+08:00', -}); +import { createDBConfig } from '@/modules/database/config'; + +export const database = createDBConfig((configure) => ({ + common: { synchronize: true }, + connections: [ + { + type: 'mysql', + host: configure.env.get('DB_HOST', '127.0.0.1'), + port: configure.env.get('DB_PORT', (v) => toNumber(v), 3306), + username: configure.env.get('DB_USERNAME', 'root'), + password: configure.env.get('DB_PASSWORD', '12345678'), + database: configure.env.get('DB_NAME', '3r'), + }, + ], +})); diff --git a/src/config/index.ts b/src/config/index.ts index 0bb5dc2..5c4c60c 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,2 +1,4 @@ export * from './database.config'; export * from './content.config'; +export * from './app.config'; +export * from './meili.config'; diff --git a/src/config/meili.config.ts b/src/config/meili.config.ts new file mode 100644 index 0000000..689c166 --- /dev/null +++ b/src/config/meili.config.ts @@ -0,0 +1,8 @@ +import { createMeiliConfig } from '../modules/meilisearch/config'; + +export const MEILI_CONFIG = createMeiliConfig((configure) => [ + { + name: 'default', + host: 'http://192.168.50.26:7700', + }, +]); diff --git a/src/main.ts b/src/main.ts index 8d3fccd..deea31e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,21 +1,4 @@ -import { NestFactory } from '@nestjs/core'; +import { createApp, listened, startApp } from './modules/core/helpers/app'; +import { createOptions } from './options'; -import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify'; - -import { useContainer } from 'class-validator'; - -import { AppModule } from './app.module'; - -async function bootstrap() { - const app = await NestFactory.create(AppModule, new FastifyAdapter(), { - cors: true, - logger: ['error', 'warn'], - }); - app.setGlobalPrefix('api'); - useContainer(app.select(AppModule), { fallbackOnErrors: true }); - await app.listen(process.env.PORT ?? 3000, () => { - console.log('api: http://localhost:3000'); - }); -} - -bootstrap(); +startApp(createApp(createOptions), listened); diff --git a/src/modules/config/env.ts b/src/modules/config/env.ts index fd6a68c..1f322e5 100644 --- a/src/modules/config/env.ts +++ b/src/modules/config/env.ts @@ -46,6 +46,16 @@ export class Env { return this.run() === EnvironmentType.DEVELOPMENT || this.run() === EnvironmentType.DEV; } + get(): { [key: string]: string }; + + get(key: string): T; + + get(key: string, parseTo?: ParseType): T; + + get(key: string, defaultValue?: T): T; + + get(key: string, parseTo?: ParseType, defaultValue?: T): T; + get(key?: string, parseTo?: ParseType | T, defaultValue?: T) { if (!key) { return process.env; diff --git a/src/modules/config/utils.ts b/src/modules/config/utils.ts new file mode 100644 index 0000000..3978013 --- /dev/null +++ b/src/modules/config/utils.ts @@ -0,0 +1,27 @@ +import { isNil } from 'lodash'; + +import { ConnectionOption, ConnectionRst } from './types'; + +export const createConnectionOptions = ( + config: ConnectionOption | ConnectionOption[], +) => { + const options = ( + Array.isArray(config) ? config : [{ ...config, name: 'default' }] + ) as ConnectionRst; + + if (options.length <= 0) { + return undefined; + } + + const names = options.map(({ name }) => name); + if (!names.includes('default')) { + options[0].name = 'default'; + } + + return options + .filter(({ name }) => !isNil(name)) + .reduce((o, n) => { + const oldNames = o.map(({ name }) => name) as string[]; + return oldNames.includes(n.name) ? o : [...o, n]; + }, []); +}; diff --git a/src/modules/content/config.ts b/src/modules/content/config.ts new file mode 100644 index 0000000..dedad14 --- /dev/null +++ b/src/modules/content/config.ts @@ -0,0 +1,12 @@ +import { ConfigureFactory, ConfigureRegister } from '../config/types'; + +import { ContentConfig } from './types'; + +export const defauleContentConfig: ContentConfig = { searchType: 'mysql', htmlEnabled: false }; + +export const createContentConfig: ( + register: ConfigureRegister>, +) => ConfigureFactory = (register) => ({ + register, + defaultRegister: () => defauleContentConfig, +}); diff --git a/src/modules/content/content.module.ts b/src/modules/content/content.module.ts index cf8d2cf..4864060 100644 --- a/src/modules/content/content.module.ts +++ b/src/modules/content/content.module.ts @@ -11,19 +11,19 @@ import { SanitizeService } from '@/modules/content/services/SanitizeService'; import { PostService } from '@/modules/content/services/post.service'; import { PostSubscriber } from '@/modules/content/subscribers/post.subscriber'; -import { ContentConfig } from '@/modules/content/types'; import { DatabaseModule } from '@/modules/database/database.module'; +import { Configure } from '../config/configure'; + +import { defauleContentConfig } from './config'; +import { ContentConfig } from './types'; + @Module({}) export class ContentModule { - static forRoot(configRegister?: () => ContentConfig): DynamicModule { - const config: Required = { - SearchType: 'mysql', - ...(configRegister ? configRegister() : {}), - }; + static async forRoot(configure: Configure): Promise { + const config = await configure.get('content', defauleContentConfig); const providers: ModuleMetadata['providers'] = [ ...Object.values(services), - SanitizeService, PostSubscriber, { provide: PostService, @@ -47,13 +47,23 @@ export class ContentModule { categoryService, tagRepository, searchService, - config.SearchType, + config.searchType, ); }, }, ]; - if (config.SearchType === 'meili') { + const exports: ModuleMetadata['exports'] = [ + ...Object.values(services), + PostService, + DatabaseModule.forRepository(Object.values(repositories)), + ]; + if (config.searchType === 'meili') { providers.push(services.SearchService); + exports.push(SearchService); + } + if (config.htmlEnabled) { + providers.push(SanitizeService); + exports.push(SanitizeService); } return { module: ContentModule, @@ -63,11 +73,7 @@ export class ContentModule { ], controllers: Object.values(controllers), providers, - exports: [ - ...Object.values(services), - PostService, - DatabaseModule.forRepository(Object.values(repositories)), - ], + exports, }; } } diff --git a/src/modules/content/subscribers/post.subscriber.ts b/src/modules/content/subscribers/post.subscriber.ts index 43746c9..0a5ebd5 100644 --- a/src/modules/content/subscribers/post.subscriber.ts +++ b/src/modules/content/subscribers/post.subscriber.ts @@ -1,5 +1,8 @@ +import { Optional } from '@nestjs/common'; +import { isNil } from 'lodash'; import { DataSource, EventSubscriber, ObjectType } from 'typeorm'; +import { Configure } from '@/modules/config/configure'; import { PostBodyType } from '@/modules/content/constants'; import { PostEntity } from '@/modules/content/entities/post.entity'; import { PostRepository } from '@/modules/content/repositories/post.repository'; @@ -11,14 +14,19 @@ export class PostSubscriber extends BaseSubscriber { protected entity: ObjectType = PostEntity; constructor( protected dataSource: DataSource, - protected sanitizeService: SanitizeService, protected postRepository: PostRepository, + protected configure: Configure, + @Optional() protected sanitizeService: SanitizeService, ) { super(dataSource); } async afterLoad(entity: PostEntity) { - if (entity.type === PostBodyType.HTML) { + if ( + (await this.configure.get('content.htmlEnabled')) && + !isNil(this.sanitizeService) && + entity.type === PostBodyType.HTML + ) { entity.body = this.sanitizeService.sanitize(entity.body); } } diff --git a/src/modules/content/types.ts b/src/modules/content/types.ts index d8595e7..9b48807 100644 --- a/src/modules/content/types.ts +++ b/src/modules/content/types.ts @@ -3,7 +3,8 @@ import { SelectTrashMode } from '@/modules/database/constants'; export type SearchType = 'mysql' | 'meili'; export interface ContentConfig { - SearchType?: SearchType; + searchType: SearchType; + htmlEnabled: boolean; } export interface SearchOption { diff --git a/src/modules/core/config.ts b/src/modules/core/config.ts new file mode 100644 index 0000000..51105a9 --- /dev/null +++ b/src/modules/core/config.ts @@ -0,0 +1,30 @@ +import { isNil, toNumber } from 'lodash'; + +import { Configure } from '../config/configure'; + +import { ConfigureFactory, ConfigureRegister } from '../config/types'; + +import { getRandomString, toBoolean } from './helpers'; +import { AppConfig } from './types'; + +export const getDefaultAppConfig = (configure: Configure) => ({ + name: configure.env.get('APP_NAME', getRandomString()), + host: configure.env.get('APP_HOST', '127.0.0.1'), + port: configure.env.get('APP_PORT', (v) => toNumber(v), 3000), + https: configure.env.get('APP_SSL', (v) => toBoolean(v), false), + locale: configure.env.get('APP_LOCALE', 'zh_CN'), + fallbackLocale: configure.env.get('APP_FALLBACK_LOCALE', 'en'), +}); + +export const createAppConfig: ( + register: ConfigureRegister>, +) => ConfigureFactory = (register) => ({ + register, + defaultRegister: (configure) => getDefaultAppConfig(configure), + hook: (configure: Configure, value) => { + if (isNil(value.url)) { + value.url = `${value.https ? 'https' : 'http'}//${value.host}:${value.port}`; + } + return value; + }, +}); diff --git a/src/modules/core/helpers/app.ts b/src/modules/core/helpers/app.ts index 971cf47..30bdb37 100644 --- a/src/modules/core/helpers/app.ts +++ b/src/modules/core/helpers/app.ts @@ -1,9 +1,11 @@ import { BadGatewayException, Global, Module, ModuleMetadata, Type } from '@nestjs/common'; import { APP_FILTER, APP_INTERCEPTOR, APP_PIPE } from '@nestjs/core'; +import { NestFastifyApplication } from '@nestjs/platform-fastify'; +import chalk from 'chalk'; import { useContainer } from 'class-validator'; -import { omit } from 'lodash'; +import { isNil, omit } from 'lodash'; import { ConfigModule } from '@/modules/config/config.module'; import { Configure } from '@/modules/config/configure'; @@ -14,7 +16,7 @@ import { CoreModule } from '../core.module'; import { AppFilter } from '../providers/app.filter'; import { AppInterceptor } from '../providers/app.interceptor'; import { AppPipe } from '../providers/app.pipe'; -import { App, CreateOptions } from '../types'; +import { App, AppConfig, CreateOptions } from '../types'; import { CreateModule } from './utils'; @@ -90,3 +92,32 @@ export async function createBootModule( providers, })); } + +export async function startApp( + creater: () => Promise, + listened: (app: App, startTime: Date) => () => Promise, +) { + const startTime = new Date(); + const { container, configure } = await creater(); + app.container = container; + app.configure = configure; + const { port, host } = await configure.get('app'); + await container.listen(port, host, listened(app, startTime)); +} + +export async function echoApi(configure: Configure, container: NestFastifyApplication) { + const appUrl = await configure.get('app.url'); + const urlPrefix = await configure.get('api.prefix', undefined); + const apiUrl = isNil(urlPrefix) + ? appUrl + : `${appUrl}${urlPrefix.length > 0 ? `/${urlPrefix}` : urlPrefix}`; + console.log(`- RestAPI: ${chalk.green.underline(apiUrl)}`); +} + +export const listened: (app: App, startyTime: Date) => () => Promise = + ({ configure, container }, startTime) => + async () => { + console.log(); + await echoApi(configure, container); + console.log('used time: ', chalk.cyan(`${new Date().getTime() - startTime.getTime()}`)); + }; diff --git a/src/modules/core/helpers/utils.ts b/src/modules/core/helpers/utils.ts index 83fcc67..a759828 100644 --- a/src/modules/core/helpers/utils.ts +++ b/src/modules/core/helpers/utils.ts @@ -1,7 +1,10 @@ import { Module, ModuleMetadata, Type } from '@nestjs/common'; +import chalk from 'chalk'; import deepmerge from 'deepmerge'; import { isNil } from 'lodash'; +import { PanicOption } from '../types'; + export function toBoolean(value?: string | boolean): boolean { if (isNil(value)) { return false; @@ -55,3 +58,27 @@ export function CreateModule( Module(metaSetter())(ModuleClass); return ModuleClass; } + +export const getRandomString = (length = 10) => { + let result = ''; + const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; + const totalLength = characters.length; + + for (let index = 0; index < length; index++) { + result += characters.charAt(Math.floor(Math.random() * totalLength)); + } + return result; +}; + +export async function panic(option: PanicOption | string) { + console.log(); + if (typeof option === 'string') { + console.log(chalk.red(`\n❌ ${option}`)); + process.exit(1); + } + const { error, message, exit = true } = option; + isNil(error) ? console.log(chalk.red(`\n❌ ${message}`)) : console.log(chalk.red(error)); + if (exit) { + process.exit(1); + } +} diff --git a/src/modules/core/types.ts b/src/modules/core/types.ts index d9240cb..86b8944 100644 --- a/src/modules/core/types.ts +++ b/src/modules/core/types.ts @@ -35,3 +35,29 @@ export interface CreateOptions { export interface ContainerBuilder { (params: { configure: Configure; BootModule: Type }): Promise; } + +export interface AppConfig { + name: string; + + host: string; + + port: number; + + https: boolean; + + locale: string; + + fallbackLocale: string; + + url?: string; + + prefix?: string; +} + +export interface PanicOption { + message: string; + + error?: any; + + exit?: boolean; +} diff --git a/src/modules/database/config.ts b/src/modules/database/config.ts new file mode 100644 index 0000000..01d25ba --- /dev/null +++ b/src/modules/database/config.ts @@ -0,0 +1,37 @@ +import { ConfigureFactory, ConfigureRegister } from '../config/types'; +import { createConnectionOptions } from '../config/utils'; +import { deepMerge } from '../core/helpers'; + +import { DBConfig, DBOptions, TypeormOption } from './types'; + +export const createDBConfig: ( + register: ConfigureRegister>, +) => ConfigureFactory = (register) => ({ + register, + hook: (configure, value) => createDBOptions(value), + defaultRegister: () => ({ + common: { charset: 'utf8mb4', logging: ['error'] }, + connections: [], + }), +}); + +export const createDBOptions = (options: DBConfig) => { + const newOptions: DBOptions = { + common: deepMerge( + { charset: 'utf8mb4', logging: ['error'] }, + options.common ?? {}, + 'replace', + ), + connections: createConnectionOptions(options.connections ?? []), + }; + newOptions.connections = newOptions.connections.map((connection) => { + const entities = connection.entities ?? []; + const newOption = { ...connection, entities }; + return deepMerge( + newOptions.common, + { ...newOption, autoLoadEntities: true } as any, + 'replace', + ) as TypeormOption; + }); + return newOptions; +}; diff --git a/src/modules/database/database.module.ts b/src/modules/database/database.module.ts index d3baf66..2c29f72 100644 --- a/src/modules/database/database.module.ts +++ b/src/modules/database/database.module.ts @@ -1,10 +1,14 @@ -import { DynamicModule, Module, Provider, Type } from '@nestjs/common'; +import { DynamicModule, Module, ModuleMetadata, Provider, Type } from '@nestjs/common'; import { getDataSourceToken, TypeOrmModule, TypeOrmModuleOptions } from '@nestjs/typeorm'; import { DataSource, ObjectType } from 'typeorm'; import { CUSTOM_REPOSITORY_METADATA } from '@/modules/database/constants'; +import { Configure } from '../config/configure'; + +import { panic } from '../core/helpers'; + import { DataExistConstraint, TreeUniqueConstraint, @@ -12,21 +16,31 @@ import { UniqueConstraint, UniqueExistConstraint, } from './constraints'; +import { DBOptions } from './types'; @Module({}) export class DatabaseModule { - static forRoot(configRegister: () => TypeOrmModuleOptions): DynamicModule { + static async forRoot(configure: Configure): Promise { + if (!configure.has('database')) { + panic({ message: 'Database config not exists' }); + } + const { connections } = await configure.get('database'); + const imports: ModuleMetadata['imports'] = []; + for (const connection of connections) { + imports.push(TypeOrmModule.forRoot(connection as TypeOrmModuleOptions)); + } + const providers: ModuleMetadata['providers'] = [ + DataExistConstraint, + UniqueConstraint, + UniqueExistConstraint, + TreeUniqueConstraint, + TreeUniqueExistContraint, + ]; return { global: true, module: DatabaseModule, - imports: [TypeOrmModule.forRoot(configRegister())], - providers: [ - DataExistConstraint, - UniqueConstraint, - UniqueExistConstraint, - TreeUniqueConstraint, - TreeUniqueExistContraint, - ], + imports, + providers, }; } static forRepository>( diff --git a/src/modules/database/types.ts b/src/modules/database/types.ts index ace6c80..a121c00 100644 --- a/src/modules/database/types.ts +++ b/src/modules/database/types.ts @@ -1,3 +1,4 @@ +import { TypeOrmModuleOptions } from '@nestjs/typeorm'; import { FindTreeOptions, ObjectLiteral, @@ -67,3 +68,15 @@ export type RepositoryType = | TreeRepository | BaseRepository | BaseTreeRepository; + +export type DBConfig = { + common: RecordAny; + connections: Array; +}; + +export type TypeormOption = Omit & { name: string }; + +export type DBOptions = RecordAny & { + common: RecordAny; + connections: TypeormOption[]; +}; diff --git a/src/modules/meilisearch/config.ts b/src/modules/meilisearch/config.ts new file mode 100644 index 0000000..aee1c8c --- /dev/null +++ b/src/modules/meilisearch/config.ts @@ -0,0 +1,11 @@ +import { ConfigureFactory, ConfigureRegister } from '../config/types'; +import { createConnectionOptions } from '../config/utils'; + +import { MeiliConfig } from './types'; + +export const createMeiliConfig: ( + registre: ConfigureRegister>, +) => ConfigureFactory = (register) => ({ + register, + hook: (configure, value) => createConnectionOptions(value), +}); diff --git a/src/modules/meilisearch/meili.config.ts b/src/modules/meilisearch/meili.config.ts deleted file mode 100644 index a5b05ae..0000000 --- a/src/modules/meilisearch/meili.config.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { MeiliConfig } from '@/modules/meilisearch/types'; - -export const MEILI_CONFIG = (): MeiliConfig => [ - { - name: 'default', - host: 'http://localhost:7700', - apiKey: 'masterKey', - }, -]; diff --git a/src/modules/meilisearch/meili.module.ts b/src/modules/meilisearch/meili.module.ts index 49202ea..53eae74 100644 --- a/src/modules/meilisearch/meili.module.ts +++ b/src/modules/meilisearch/meili.module.ts @@ -1,12 +1,16 @@ import { DynamicModule, Module } from '@nestjs/common'; import { MeiliService } from '@/modules/meilisearch/meili.service'; -import { MeiliConfig } from '@/modules/meilisearch/types'; -import { createMeiliOptions } from '@/modules/meilisearch/utils'; + +import { Configure } from '../config/configure'; +import { panic } from '../core/helpers'; @Module({}) export class MeiliModule { - static forRoot(configRegister: () => MeiliConfig): DynamicModule { + static forRoot(configure: Configure): DynamicModule { + if (!configure.has('meili')) { + panic({ message: 'MeilliSearch config not exists' }); + } return { global: true, module: MeiliModule, @@ -14,9 +18,7 @@ export class MeiliModule { { provide: MeiliService, useFactory: async () => { - const service = new MeiliService( - await createMeiliOptions(configRegister()), - ); + const service = new MeiliService(await configure.get('meili')); await service.createClients(); return service; }, diff --git a/src/modules/meilisearch/utils.ts b/src/modules/meilisearch/utils.ts deleted file mode 100644 index 282425d..0000000 --- a/src/modules/meilisearch/utils.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { MeiliConfig } from '@/modules/meilisearch/types'; - -export const createMeiliOptions = async (config: MeiliConfig): Promise => { - if (config.length < 0) { - return config; - } - let options: MeiliConfig = [...config]; - const names = options.map(({ name }) => name); - if (!names.includes('default')) { - options[0].name = 'default'; - } else if (names.filter((name) => name === 'default').length > 0) { - options = options.reduce( - (o, n) => (o.map(({ name }) => name).includes('default') ? o : [...o, n]), - [], - ); - } - return options; -}; diff --git a/src/options.ts b/src/options.ts new file mode 100644 index 0000000..708b638 --- /dev/null +++ b/src/options.ts @@ -0,0 +1,32 @@ +import { NestFactory } from '@nestjs/core'; + +import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify'; + +import * as configs from './config'; +import { ContentModule } from './modules/content/content.module'; +import { CoreModule } from './modules/core/core.module'; +import { CreateOptions } from './modules/core/types'; +import { DatabaseModule } from './modules/database/database.module'; +import { MeiliModule } from './modules/meilisearch/meili.module'; + +export const createOptions: CreateOptions = { + config: { factories: configs as any, storage: { enable: true } }, + modules: async (configure) => [ + DatabaseModule.forRoot(configure), + MeiliModule.forRoot(configure), + ContentModule.forRoot(configure), + CoreModule.forRoot(configure), + ], + globals: {}, + builder: async ({ configure, BootModule }) => { + const container = await NestFactory.create( + BootModule, + new FastifyAdapter(), + { + cors: true, + logger: ['error', 'warn'], + }, + ); + return container; + }, +}; diff --git a/test/all-case.test.ts b/test/all-case.test.ts index be43b26..ecbca45 100644 --- a/test/all-case.test.ts +++ b/test/all-case.test.ts @@ -7,7 +7,6 @@ import { useContainer } from 'class-validator'; import { isNil, pick } from 'lodash'; import { DataSource } from 'typeorm'; -import { AppModule } from '@/app.module'; import { CategoryEntity, CommentEntity, PostEntity, TagEntity } from '@/modules/content/entities'; import { CategoryRepository, @@ -16,6 +15,7 @@ import { TagRepository, } from '@/modules/content/repositories'; +import { CoreModule } from '@/modules/core/core.module'; import { MeiliService } from '@/modules/meilisearch/meili.service'; import { generateRandomNumber, generateUniqueRandomNumbers } from './generate-mock-data'; @@ -37,10 +37,10 @@ describe('nest app test', () => { beforeAll(async () => { const module: TestingModule = await Test.createTestingModule({ - imports: [AppModule], + imports: [CoreModule], }).compile(); app = module.createNestApplication(new FastifyAdapter()); - useContainer(app.select(AppModule), { fallbackOnErrors: true }); + useContainer(app.select(CoreModule), { fallbackOnErrors: true }); await app.init(); await app.getHttpAdapter().getInstance().ready(); diff --git a/test/app.e2e-spec.ts b/test/app.e2e-spec.ts index 50cda62..505d8d1 100644 --- a/test/app.e2e-spec.ts +++ b/test/app.e2e-spec.ts @@ -1,24 +1,22 @@ -import { Test, TestingModule } from '@nestjs/testing'; import { INestApplication } from '@nestjs/common'; -import * as request from 'supertest'; -import { AppModule } from './../src/app.module'; +import { Test, TestingModule } from '@nestjs/testing'; +import request from 'supertest'; + +import { CoreModule } from '@/modules/core/core.module'; describe('AppController (e2e)', () => { - let app: INestApplication; + let app: INestApplication; - beforeEach(async () => { - const moduleFixture: TestingModule = await Test.createTestingModule({ - imports: [AppModule], - }).compile(); + beforeEach(async () => { + const moduleFixture: TestingModule = await Test.createTestingModule({ + imports: [CoreModule], + }).compile(); - app = moduleFixture.createNestApplication(); - await app.init(); - }); + app = moduleFixture.createNestApplication(); + await app.init(); + }); - it('/ (GET)', () => { - return request(app.getHttpServer()) - .get('/') - .expect(200) - .expect('Hello World!'); - }); + it('/ (GET)', () => { + return request(app.getHttpServer()).get('/').expect(200).expect('Hello World!'); + }); });