mirror of
https://github.com/hexastack/hexabot
synced 2025-06-26 18:27:28 +00:00
feat: implement dynamic create DTO in the BaseSeeder
This commit is contained in:
parent
ffc260bba2
commit
21b2f46f4c
@ -148,6 +148,6 @@ export class BlockUpdateDto extends PartialType(
|
|||||||
trigger_channels?: string[];
|
trigger_channels?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type BlockDTOMap = DtoConfig<{
|
export type BlockDTOMapActions = DtoConfig<{
|
||||||
create: BlockCreateDto;
|
create: BlockCreateDto;
|
||||||
}>;
|
}>;
|
||||||
|
|||||||
@ -9,6 +9,8 @@
|
|||||||
import { ApiProperty, PartialType } from '@nestjs/swagger';
|
import { ApiProperty, PartialType } from '@nestjs/swagger';
|
||||||
import { IsBoolean, IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
import { IsBoolean, IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
||||||
|
|
||||||
|
import { DtoConfig } from '@/utils/types/dto.types';
|
||||||
|
|
||||||
export class ContextVarCreateDto {
|
export class ContextVarCreateDto {
|
||||||
@ApiProperty({ description: 'Context var label', type: String })
|
@ApiProperty({ description: 'Context var label', type: String })
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@ -27,3 +29,7 @@ export class ContextVarCreateDto {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class ContextVarUpdateDto extends PartialType(ContextVarCreateDto) {}
|
export class ContextVarUpdateDto extends PartialType(ContextVarCreateDto) {}
|
||||||
|
|
||||||
|
export type ContextVarDTOMapActions = DtoConfig<{
|
||||||
|
create: ContextVarCreateDto;
|
||||||
|
}>;
|
||||||
|
|||||||
@ -22,7 +22,11 @@ import { LoggerService } from '@/logger/logger.service';
|
|||||||
import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository';
|
import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository';
|
||||||
import { TFilterQuery } from '@/utils/types/filter.types';
|
import { TFilterQuery } from '@/utils/types/filter.types';
|
||||||
|
|
||||||
import { BlockCreateDto, BlockDTOMap, BlockUpdateDto } from '../dto/block.dto';
|
import {
|
||||||
|
BlockCreateDto,
|
||||||
|
BlockDTOMapActions,
|
||||||
|
BlockUpdateDto,
|
||||||
|
} from '../dto/block.dto';
|
||||||
import {
|
import {
|
||||||
Block,
|
Block,
|
||||||
BLOCK_POPULATE,
|
BLOCK_POPULATE,
|
||||||
@ -35,7 +39,7 @@ export class BlockRepository extends BaseRepository<
|
|||||||
Block,
|
Block,
|
||||||
BlockPopulate,
|
BlockPopulate,
|
||||||
BlockFull,
|
BlockFull,
|
||||||
BlockDTOMap
|
BlockDTOMapActions
|
||||||
> {
|
> {
|
||||||
constructor(
|
constructor(
|
||||||
readonly eventEmitter: EventEmitter2,
|
readonly eventEmitter: EventEmitter2,
|
||||||
|
|||||||
@ -19,11 +19,17 @@ import { Document, Model, Query } from 'mongoose';
|
|||||||
import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository';
|
import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository';
|
||||||
import { TFilterQuery } from '@/utils/types/filter.types';
|
import { TFilterQuery } from '@/utils/types/filter.types';
|
||||||
|
|
||||||
|
import { ContextVarDTOMapActions } from '../dto/context-var.dto';
|
||||||
import { ContextVar } from '../schemas/context-var.schema';
|
import { ContextVar } from '../schemas/context-var.schema';
|
||||||
import { BlockService } from '../services/block.service';
|
import { BlockService } from '../services/block.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ContextVarRepository extends BaseRepository<ContextVar> {
|
export class ContextVarRepository extends BaseRepository<
|
||||||
|
ContextVar,
|
||||||
|
never,
|
||||||
|
never,
|
||||||
|
ContextVarDTOMapActions
|
||||||
|
> {
|
||||||
private readonly blockService: BlockService;
|
private readonly blockService: BlockService;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@ -38,7 +38,7 @@ export class ContextVar extends BaseSchema {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
})
|
})
|
||||||
permanent?: boolean;
|
permanent: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ContextVarModel: ModelDefinition = LifecycleHookManager.attach({
|
export const ContextVarModel: ModelDefinition = LifecycleHookManager.attach({
|
||||||
|
|||||||
@ -10,11 +10,17 @@ import { Injectable } from '@nestjs/common';
|
|||||||
|
|
||||||
import { BaseSeeder } from '@/utils/generics/base-seeder';
|
import { BaseSeeder } from '@/utils/generics/base-seeder';
|
||||||
|
|
||||||
|
import { ContextVarDTOMapActions } from '../dto/context-var.dto';
|
||||||
import { ContextVarRepository } from '../repositories/context-var.repository';
|
import { ContextVarRepository } from '../repositories/context-var.repository';
|
||||||
import { ContextVar } from '../schemas/context-var.schema';
|
import { ContextVar } from '../schemas/context-var.schema';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ContextVarSeeder extends BaseSeeder<ContextVar> {
|
export class ContextVarSeeder extends BaseSeeder<
|
||||||
|
ContextVar,
|
||||||
|
never,
|
||||||
|
never,
|
||||||
|
ContextVarDTOMapActions
|
||||||
|
> {
|
||||||
constructor(private readonly contextVarRepository: ContextVarRepository) {
|
constructor(private readonly contextVarRepository: ContextVarRepository) {
|
||||||
super(contextVarRepository);
|
super(contextVarRepository);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,7 @@ import { SettingService } from '@/setting/services/setting.service';
|
|||||||
import { BaseService } from '@/utils/generics/base-service';
|
import { BaseService } from '@/utils/generics/base-service';
|
||||||
import { getRandom } from '@/utils/helpers/safeRandom';
|
import { getRandom } from '@/utils/helpers/safeRandom';
|
||||||
|
|
||||||
import { BlockDTOMap } from '../dto/block.dto';
|
import { BlockDTOMapActions } from '../dto/block.dto';
|
||||||
import { BlockRepository } from '../repositories/block.repository';
|
import { BlockRepository } from '../repositories/block.repository';
|
||||||
import { Block, BlockFull, BlockPopulate } from '../schemas/block.schema';
|
import { Block, BlockFull, BlockPopulate } from '../schemas/block.schema';
|
||||||
import { Context } from '../schemas/types/context';
|
import { Context } from '../schemas/types/context';
|
||||||
@ -40,7 +40,7 @@ export class BlockService extends BaseService<
|
|||||||
Block,
|
Block,
|
||||||
BlockPopulate,
|
BlockPopulate,
|
||||||
BlockFull,
|
BlockFull,
|
||||||
BlockDTOMap
|
BlockDTOMapActions
|
||||||
> {
|
> {
|
||||||
constructor(
|
constructor(
|
||||||
readonly repository: BlockRepository,
|
readonly repository: BlockRepository,
|
||||||
|
|||||||
@ -10,12 +10,18 @@ import { Injectable } from '@nestjs/common';
|
|||||||
|
|
||||||
import { BaseService } from '@/utils/generics/base-service';
|
import { BaseService } from '@/utils/generics/base-service';
|
||||||
|
|
||||||
|
import { ContextVarDTOMapActions } from '../dto/context-var.dto';
|
||||||
import { ContextVarRepository } from '../repositories/context-var.repository';
|
import { ContextVarRepository } from '../repositories/context-var.repository';
|
||||||
import { Block, BlockFull } from '../schemas/block.schema';
|
import { Block, BlockFull } from '../schemas/block.schema';
|
||||||
import { ContextVar } from '../schemas/context-var.schema';
|
import { ContextVar } from '../schemas/context-var.schema';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ContextVarService extends BaseService<ContextVar> {
|
export class ContextVarService extends BaseService<
|
||||||
|
ContextVar,
|
||||||
|
never,
|
||||||
|
never,
|
||||||
|
ContextVarDTOMapActions
|
||||||
|
> {
|
||||||
constructor(readonly repository: ContextVarRepository) {
|
constructor(readonly repository: ContextVarRepository) {
|
||||||
super(repository);
|
super(repository);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,8 @@
|
|||||||
|
|
||||||
import { FlattenMaps } from 'mongoose';
|
import { FlattenMaps } from 'mongoose';
|
||||||
|
|
||||||
|
import { DtoActions, DtoInfer, DtoProps } from '../types/dto.types';
|
||||||
|
|
||||||
import { BaseRepository } from './base-repository';
|
import { BaseRepository } from './base-repository';
|
||||||
import { BaseSchema } from './base-schema';
|
import { BaseSchema } from './base-schema';
|
||||||
|
|
||||||
@ -15,6 +17,7 @@ export abstract class BaseSeeder<
|
|||||||
T extends FlattenMaps<unknown>,
|
T extends FlattenMaps<unknown>,
|
||||||
P extends string = never,
|
P extends string = never,
|
||||||
TFull extends Omit<T, P> = never,
|
TFull extends Omit<T, P> = never,
|
||||||
|
DTOCruds extends DtoProps<any> = unknown,
|
||||||
> {
|
> {
|
||||||
constructor(protected readonly repository: BaseRepository<T, P, TFull>) {}
|
constructor(protected readonly repository: BaseRepository<T, P, TFull>) {}
|
||||||
|
|
||||||
@ -27,7 +30,9 @@ export abstract class BaseSeeder<
|
|||||||
return count === 0;
|
return count === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
async seed(models: Omit<T, keyof BaseSchema>[]): Promise<boolean> {
|
async seed<D extends Omit<T, keyof BaseSchema>>(
|
||||||
|
models: DtoInfer<DtoActions.Create, DTOCruds, D>[],
|
||||||
|
): Promise<boolean> {
|
||||||
if (await this.isEmpty()) {
|
if (await this.isEmpty()) {
|
||||||
await this.repository.createMany(models);
|
await this.repository.createMany(models);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
22
api/src/utils/test/fixtures/contextvar.ts
vendored
22
api/src/utils/test/fixtures/contextvar.ts
vendored
@ -8,26 +8,36 @@
|
|||||||
|
|
||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
|
|
||||||
import { ContextVarCreateDto } from '@/chat/dto/context-var.dto';
|
import { ContextVar, ContextVarModel } from '@/chat/schemas/context-var.schema';
|
||||||
import { ContextVarModel, ContextVar } from '@/chat/schemas/context-var.schema';
|
import { BaseSchema } from '@/utils/generics/base-schema';
|
||||||
|
|
||||||
import { getFixturesWithDefaultValues } from '../defaultValues';
|
import { getFixturesWithDefaultValues } from '../defaultValues';
|
||||||
|
|
||||||
const contextVars: ContextVarCreateDto[] = [
|
export const fieldsWithDefaultValues = {
|
||||||
|
permanent: false,
|
||||||
|
} satisfies Partial<ContextVar>;
|
||||||
|
|
||||||
|
type TFieldWithDefaultValues =
|
||||||
|
| keyof typeof fieldsWithDefaultValues
|
||||||
|
| keyof BaseSchema;
|
||||||
|
type TTransformedField<T> = Omit<T, TFieldWithDefaultValues> &
|
||||||
|
Partial<Pick<ContextVar, TFieldWithDefaultValues>>;
|
||||||
|
type TContextVar = TTransformedField<ContextVar>;
|
||||||
|
|
||||||
|
const contextVars: TContextVar[] = [
|
||||||
{
|
{
|
||||||
label: 'test context var 1',
|
label: 'test context var 1',
|
||||||
name: 'test1',
|
name: 'test1',
|
||||||
permanent: false,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'test context var 2',
|
label: 'test context var 2',
|
||||||
name: 'test2',
|
name: 'test2',
|
||||||
permanent: false,
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const contextVarFixtures = getFixturesWithDefaultValues<ContextVar>({
|
export const contextVarFixtures = getFixturesWithDefaultValues<TContextVar>({
|
||||||
fixtures: contextVars,
|
fixtures: contextVars,
|
||||||
|
defaultValues: fieldsWithDefaultValues,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const installContextVarFixtures = async () => {
|
export const installContextVarFixtures = async () => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user