Расширение модулей
Несмотря на то, что Steroids Nest модули предоставляют богатую функциональность, которая может быть использована "из коробки", в некоторых случаях может возникать необходимость в её расширении или переопределении. В таком случае библиотекой предусмотрены механизмы расширения и переопределения различных компонентов модуля, таких как модели, репозитории, сервисы и т.д.
Основной инструмент для расширения функциональности модуля - декоратор @Module из @steroidsjs/nest. Переданные в него объект конфигурации с интерфейсом IModule из @steroidsjs/nest позволяет расширить или переопределить различные его части. В ключе module лежит конфигурация для декоратора @Module из @nestjs/common, с определенными в ней массивами imports, controllers, providers и exports.
Рассмотрим расширение функциональности на примере модуля @steroidsjs/nest-notifier.
import {Module} from '@steroidsjs/nest/infrastructure/decorators/Module';
// Импортируем базовый конфиг
import coreModule from '@steroidsjs/nest-notifier';
@Module({
...coreModule,
// При необходимости можно переопределить настройки для module функции,
// которые будут переданы первым аргументом в функцию ниже
config: () => ({
...coreModule.config(),
}),
// Переопределяем фукнцию module из базового конфига
// Аргумент config будет передан из фукнции config выше
module: (config) => {
// Получаем настройки для NestJS модуля из библиотеки (imports, controllers, providers и exports)
const module = coreModule.module(config);
// Переопределяем настройки для NestJS модуля
// Тут можно добавить кастомные провайдеры, импорты и тд
return {
imports: [...module.imports],
controllers: [...module.controllers],
providers: [...module.providers],
exports: [...module.exports]
};
},
})
export class NotifierModule {}Расширение и переопределение сущностей модуля
Ниже приведены примеры расширения и переопределения различных сущностей модуля.
Модель
import {NotifierSendLogModel as BaseNotifierSendLogModel} from '@steroidsjs/nest-notifier/domain/models/NotifierSendLogModel';
import {StringField} from '@steroidsjs/nest/infrastructure/decorators/fields';
export class NotifierSendLogModel extends BaseNotifierSendLogModel {
@StringField({
label: 'Custom string field',
nullable: true,
})
customStringField: string;
}ORM-сущность
import {TypeOrmTableFromModel} from '@steroidsjs/nest/infrastructure/decorators/typeorm/TypeOrmTableFromModel';
import {NotifierSendLogModel} from '../../domain/models/NotifierSendLogModel';
@TypeOrmTableFromModel(NotifierSendLogModel, 'notifier_send_log')
export class NotifierSendLogTable extends NotifierSendLogModel {}Репозиторий
import {NotifierSendLogRepository as BaseNotifierSendLogRepository} from '@steroidsjs/nest-notifier/infrastructure/repositories/NotifierSendLogRepository';
import {InjectRepository} from '@steroidsjs/nest-typeorm';
import {Repository} from '@steroidsjs/typeorm';
import {Injectable} from '@nestjs/common';
import {NotifierSendLogTable} from '../tables/NotifierSendLogTable';
import {NotifierSendLogModel} from '../../domain/models/NotifierSendLogModel';
@Injectable()
export class NotifierSendLogRepository extends BaseNotifierSendLogRepository {
constructor(
@InjectRepository(NotifierSendLogTable)
readonly dbRepository: Repository<NotifierSendLogTable>,
) {
super(dbRepository);
}
protected modelClass = NotifierSendLogModel;
}Интерфейс репозитория при расширении модели
import {ICrudRepository} from '@steroidsjs/nest/usecases/interfaces/ICrudRepository';
import {INotifierSendLogRepository as BaseINotifierSendLogRepository} from '@steroidsjs/nest-notifier/domain/interfaces/INotifierSendLogRepository';
import {NotifierSendLogModel} from '../models/NotifierSendLogModel';
export const INotifierSendLogRepository = BaseINotifierSendLogRepository;
export type INotifierSendLogRepository = ICrudRepository<NotifierSendLogModel>;CRUD-сервис
import {NotifierSendLogService as BaseNotifierSendLogService} from '@steroidsjs/nest-notifier/domain/services/NotifierSendLogService';
import {INotifierSendLogRepository} from '../interfaces/INotifierSendLogRepository';
import {Inject, Injectable} from '@nestjs/common';
import {NotifierSendLogModel} from '../models/NotifierSendLogModel';
@Injectable()
export class NotifierSendLogService extends BaseNotifierSendLogService {
constructor(
@Inject(INotifierSendLogRepository)
readonly repository: INotifierSendLogRepository,
) {
super(repository);
}
protected modelClass = NotifierSendLogModel;
}Сервис
import {NotifierSendLogService as BaseNotifierSendLogService} from '@steroidsjs/nest-notifier/domain/services/NotifierSendLogService';
import {NotifierSendLogModel} from '@steroidsjs/nest-notifier/domain/models/NotifierSendLogModel';
import {INotifierSendLogRepository} from '@steroidsjs/nest-notifier/domain/interfaces/INotifierSendLogRepository';
import {Inject, Injectable} from '@nestjs/common';
import {ContextDto} from '../../../auth/domain/dtos/ContextDto';
@Injectable()
export class NotifierSendLogService extends BaseNotifierSendLogService {
constructor(
@Inject(INotifierSendLogRepository)
readonly repository: INotifierSendLogRepository,
) {
super(repository);
}
// Переопределение метода
findById(id: number | string, context?: ContextDto | null): Promise<NotifierSendLogModel> {
return super.findById(id, context);
}
// Новый метод
doSomething() {
console.log('something');
}
}Подключение переопределённых сущностей
import {join} from 'path';
import {Module} from '@steroidsjs/nest/infrastructure/decorators/Module';
import coreModule from '@steroidsjs/nest-notifier';
import {ModuleHelper} from '@steroidsjs/nest/infrastructure/helpers/ModuleHelper';
import {INotifierModuleConfig} from '@steroidsjs/nest-notifier/infrastructure/config';
import {NotifierSendLogService as BaseNotifierSendLogService} from '@steroidsjs/nest-notifier/domain/services/NotifierSendLogService';
import {INotifierSendLogRepository} from '../domain/interfaces/INotifierSendLogRepository';
import {NotifierSendLogRepository} from './repositories/NotifierSendLogRepository';
import {NotifierSendLogService} from '../domain/services/NotifierSendLogService';
@Module({
...coreModule,
tables: [
...coreModule.tables,
...ModuleHelper.importDir(join(__dirname, '/tables')),
],
module: (config: INotifierModuleConfig) => {
const module = coreModule.module(config);
return {
...module,
providers: [
...module.providers,
{
provide: INotifierSendLogRepository,
useClass: NotifierSendLogRepository,
},
{
provide: BaseNotifierSendLogService,
useClass: NotifierSendLogService,
},
],
};
},
})
export class NotifierModule {}