diff --git a/api/src/channel/channel.service.ts b/api/src/channel/channel.service.ts index 66745c97..49af6016 100644 --- a/api/src/channel/channel.service.ts +++ b/api/src/channel/channel.service.ts @@ -161,7 +161,6 @@ export class ChannelService { foreign_id: req.session.passport.user.id, }, { - id: req.session.passport.user.id, foreign_id: req.session.passport.user.id, first_name: req.session.passport.user.first_name, last_name: req.session.passport.user.last_name, diff --git a/api/src/chat/dto/block.dto.ts b/api/src/chat/dto/block.dto.ts index 7892f424..3b2da43e 100644 --- a/api/src/chat/dto/block.dto.ts +++ b/api/src/chat/dto/block.dto.ts @@ -21,6 +21,7 @@ import { IsString, } from 'class-validator'; +import { DtoConfig } from '@/utils/types/dto.types'; import { IsObjectId } from '@/utils/validation-rules/is-object-id'; import { CaptureVar } from '../schemas/types/capture-var'; @@ -146,3 +147,7 @@ export class BlockUpdateDto extends PartialType( @IsOptional() trigger_channels?: string[]; } + +export type BlockDto = DtoConfig<{ + create: BlockCreateDto; +}>; diff --git a/api/src/chat/dto/category.dto.ts b/api/src/chat/dto/category.dto.ts index ca896e22..487483a4 100644 --- a/api/src/chat/dto/category.dto.ts +++ b/api/src/chat/dto/category.dto.ts @@ -8,14 +8,16 @@ import { ApiProperty, ApiPropertyOptional, PartialType } from '@nestjs/swagger'; import { + IsArray, IsBoolean, IsNotEmpty, + IsNumber, IsOptional, IsString, - IsNumber, - IsArray, } from 'class-validator'; +import { DtoConfig } from '@/utils/types/dto.types'; + export class CategoryCreateDto { @ApiProperty({ description: 'Category label', type: String }) @IsNotEmpty() @@ -39,3 +41,7 @@ export class CategoryCreateDto { } export class CategoryUpdateDto extends PartialType(CategoryCreateDto) {} + +export type CategoryDto = DtoConfig<{ + create: CategoryCreateDto; +}>; diff --git a/api/src/chat/dto/context-var.dto.ts b/api/src/chat/dto/context-var.dto.ts index 421f6b72..37ec6440 100644 --- a/api/src/chat/dto/context-var.dto.ts +++ b/api/src/chat/dto/context-var.dto.ts @@ -9,6 +9,8 @@ import { ApiProperty, PartialType } from '@nestjs/swagger'; import { IsBoolean, IsNotEmpty, IsOptional, IsString } from 'class-validator'; +import { DtoConfig } from '@/utils/types/dto.types'; + export class ContextVarCreateDto { @ApiProperty({ description: 'Context var label', type: String }) @IsNotEmpty() @@ -27,3 +29,7 @@ export class ContextVarCreateDto { } export class ContextVarUpdateDto extends PartialType(ContextVarCreateDto) {} + +export type ContextVarDto = DtoConfig<{ + create: ContextVarCreateDto; +}>; diff --git a/api/src/chat/dto/conversation.dto.ts b/api/src/chat/dto/conversation.dto.ts index 81d978f9..cd8d4670 100644 --- a/api/src/chat/dto/conversation.dto.ts +++ b/api/src/chat/dto/conversation.dto.ts @@ -16,6 +16,7 @@ import { IsString, } from 'class-validator'; +import { DtoConfig } from '@/utils/types/dto.types'; import { IsObjectId } from '@/utils/validation-rules/is-object-id'; import { Context } from './../schemas/types/context'; @@ -45,7 +46,7 @@ export class ConversationCreateDto { @IsObjectId({ message: 'Current must be a valid objectId', }) - current: string; + current?: string | null; @ApiProperty({ description: 'next conversation', type: Array }) @IsOptional() @@ -54,5 +55,9 @@ export class ConversationCreateDto { each: true, message: 'next must be a valid objectId', }) - next: string[]; + next?: string[]; } + +export type ConversationDto = DtoConfig<{ + create: ConversationCreateDto; +}>; diff --git a/api/src/chat/dto/label.dto.ts b/api/src/chat/dto/label.dto.ts index 50107959..b6c5d3c4 100644 --- a/api/src/chat/dto/label.dto.ts +++ b/api/src/chat/dto/label.dto.ts @@ -9,12 +9,14 @@ import { ApiProperty, ApiPropertyOptional, PartialType } from '@nestjs/swagger'; import { IsNotEmpty, + IsObject, IsOptional, IsString, Matches, - IsObject, } from 'class-validator'; +import { DtoConfig } from '@/utils/types/dto.types'; + export class LabelCreateDto { @ApiProperty({ description: 'Label title', type: String }) @IsNotEmpty() @@ -39,3 +41,7 @@ export class LabelCreateDto { } export class LabelUpdateDto extends PartialType(LabelCreateDto) {} + +export type LabelDto = DtoConfig<{ + create: LabelCreateDto; +}>; diff --git a/api/src/chat/dto/subscriber.dto.ts b/api/src/chat/dto/subscriber.dto.ts index 82148f96..02e0e2fe 100644 --- a/api/src/chat/dto/subscriber.dto.ts +++ b/api/src/chat/dto/subscriber.dto.ts @@ -17,6 +17,7 @@ import { } from 'class-validator'; import { ChannelName } from '@/channel/types'; +import { DtoConfig } from '@/utils/types/dto.types'; import { IsObjectId } from '@/utils/validation-rules/is-object-id'; import { SubscriberChannelData } from '../schemas/types/channel'; @@ -36,7 +37,7 @@ export class SubscriberCreateDto { @ApiPropertyOptional({ description: 'Subscriber locale', type: String }) @IsOptional() @IsString() - locale: string; + locale?: string; @ApiPropertyOptional({ description: 'Subscriber timezone', type: Number }) @IsOptional() @@ -51,17 +52,17 @@ export class SubscriberCreateDto { @ApiPropertyOptional({ description: 'Subscriber gender', type: String }) @IsOptional() @IsString() - gender: string; + gender?: string; @ApiPropertyOptional({ description: 'Subscriber country', type: String }) @IsOptional() @IsString() - country: string; + country?: string; @ApiPropertyOptional({ description: 'Subscriber foreign id', type: String }) @IsOptional() @IsString() - foreign_id: string; + foreign_id?: string; @ApiProperty({ description: 'Subscriber labels', type: Array }) @IsNotEmpty() @@ -114,3 +115,7 @@ export class SubscriberCreateDto { } export class SubscriberUpdateDto extends PartialType(SubscriberCreateDto) {} + +export type SubscriberDto = DtoConfig<{ + create: SubscriberCreateDto; +}>; diff --git a/api/src/chat/repositories/block.repository.ts b/api/src/chat/repositories/block.repository.ts index 31b0bacd..14cf333f 100644 --- a/api/src/chat/repositories/block.repository.ts +++ b/api/src/chat/repositories/block.repository.ts @@ -22,7 +22,7 @@ import { LoggerService } from '@/logger/logger.service'; import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository'; import { TFilterQuery } from '@/utils/types/filter.types'; -import { BlockCreateDto, BlockUpdateDto } from '../dto/block.dto'; +import { BlockCreateDto, BlockDto, BlockUpdateDto } from '../dto/block.dto'; import { Block, BLOCK_POPULATE, @@ -34,7 +34,8 @@ import { export class BlockRepository extends BaseRepository< Block, BlockPopulate, - BlockFull + BlockFull, + BlockDto > { constructor( readonly eventEmitter: EventEmitter2, diff --git a/api/src/chat/repositories/category.repository.ts b/api/src/chat/repositories/category.repository.ts index 45170306..3188352d 100644 --- a/api/src/chat/repositories/category.repository.ts +++ b/api/src/chat/repositories/category.repository.ts @@ -14,11 +14,17 @@ import { Document, Model, Query } from 'mongoose'; import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository'; import { TFilterQuery } from '@/utils/types/filter.types'; +import { CategoryDto } from '../dto/category.dto'; import { Category } from '../schemas/category.schema'; import { BlockService } from '../services/block.service'; @Injectable() -export class CategoryRepository extends BaseRepository { +export class CategoryRepository extends BaseRepository< + Category, + never, + never, + CategoryDto +> { private readonly blockService: BlockService; constructor( diff --git a/api/src/chat/repositories/context-var.repository.ts b/api/src/chat/repositories/context-var.repository.ts index f2125252..20ea8640 100644 --- a/api/src/chat/repositories/context-var.repository.ts +++ b/api/src/chat/repositories/context-var.repository.ts @@ -19,11 +19,17 @@ import { Document, Model, Query } from 'mongoose'; import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository'; import { TFilterQuery } from '@/utils/types/filter.types'; +import { ContextVarDto } from '../dto/context-var.dto'; import { ContextVar } from '../schemas/context-var.schema'; import { BlockService } from '../services/block.service'; @Injectable() -export class ContextVarRepository extends BaseRepository { +export class ContextVarRepository extends BaseRepository< + ContextVar, + never, + never, + ContextVarDto +> { private readonly blockService: BlockService; constructor( diff --git a/api/src/chat/repositories/conversation.repository.ts b/api/src/chat/repositories/conversation.repository.ts index 0cde3eeb..52995fb7 100644 --- a/api/src/chat/repositories/conversation.repository.ts +++ b/api/src/chat/repositories/conversation.repository.ts @@ -13,6 +13,7 @@ import { Model } from 'mongoose'; import { BaseRepository } from '@/utils/generics/base-repository'; +import { ConversationDto } from '../dto/conversation.dto'; import { Conversation, CONVERSATION_POPULATE, @@ -24,7 +25,8 @@ import { export class ConversationRepository extends BaseRepository< Conversation, ConversationPopulate, - ConversationFull + ConversationFull, + ConversationDto > { constructor( readonly eventEmitter: EventEmitter2, diff --git a/api/src/chat/repositories/label.repository.ts b/api/src/chat/repositories/label.repository.ts index 5794c9d3..655ec6d0 100644 --- a/api/src/chat/repositories/label.repository.ts +++ b/api/src/chat/repositories/label.repository.ts @@ -14,6 +14,7 @@ import { Document, Model, Query } from 'mongoose'; import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository'; import { TFilterQuery } from '@/utils/types/filter.types'; +import { LabelDto } from '../dto/label.dto'; import { Label, LABEL_POPULATE, @@ -26,7 +27,8 @@ import { export class LabelRepository extends BaseRepository< Label, LabelPopulate, - LabelFull + LabelFull, + LabelDto > { constructor( readonly eventEmitter: EventEmitter2, diff --git a/api/src/chat/repositories/subscriber.repository.ts b/api/src/chat/repositories/subscriber.repository.ts index a3ee6cd1..be088bf1 100644 --- a/api/src/chat/repositories/subscriber.repository.ts +++ b/api/src/chat/repositories/subscriber.repository.ts @@ -20,7 +20,7 @@ import { import { BaseRepository } from '@/utils/generics/base-repository'; import { TFilterQuery } from '@/utils/types/filter.types'; -import { SubscriberUpdateDto } from '../dto/subscriber.dto'; +import { SubscriberDto, SubscriberUpdateDto } from '../dto/subscriber.dto'; import { Subscriber, SUBSCRIBER_POPULATE, @@ -33,7 +33,8 @@ import { export class SubscriberRepository extends BaseRepository< Subscriber, SubscriberPopulate, - SubscriberFull + SubscriberFull, + SubscriberDto > { constructor( readonly eventEmitter: EventEmitter2, diff --git a/api/src/chat/schemas/block.schema.ts b/api/src/chat/schemas/block.schema.ts index ab9a0b7a..88d7c0bf 100644 --- a/api/src/chat/schemas/block.schema.ts +++ b/api/src/chat/schemas/block.schema.ts @@ -43,7 +43,7 @@ export class BlockStub extends BaseSchema { validate: isPatternList, default: [], }) - patterns?: Pattern[]; + patterns: Pattern[]; @Prop([ { @@ -52,7 +52,7 @@ export class BlockStub extends BaseSchema { default: [], }, ]) - trigger_labels?: unknown; + trigger_labels: unknown; @Prop([ { @@ -61,19 +61,19 @@ export class BlockStub extends BaseSchema { default: [], }, ]) - assign_labels?: unknown; + assign_labels: unknown; @Prop({ type: Object, default: [], }) - trigger_channels?: string[]; + trigger_channels: string[]; @Prop({ type: Object, default: {}, }) - options?: BlockOptions; + options: BlockOptions; @Prop({ type: Object, @@ -88,13 +88,13 @@ export class BlockStub extends BaseSchema { default: [], }, ]) - nextBlocks?: unknown; + nextBlocks: unknown; @Prop({ type: MongooseSchema.Types.ObjectId, ref: 'Block', }) - attachedBlock?: unknown; + attachedBlock: unknown; @Prop({ type: MongooseSchema.Types.ObjectId, @@ -106,14 +106,14 @@ export class BlockStub extends BaseSchema { type: Boolean, default: false, }) - starts_conversation?: boolean; + starts_conversation: boolean; @Prop({ type: Object, validate: isValidVarCapture, default: [], }) - capture_vars?: CaptureVar[]; + capture_vars: CaptureVar[]; @Prop({ type: Object, @@ -125,22 +125,22 @@ export class BlockStub extends BaseSchema { type: Boolean, default: false, }) - builtin?: boolean; + builtin: boolean; } @Schema({ timestamps: true }) export class Block extends BlockStub { - @Transform(({ obj }) => obj.trigger_labels?.map((elem) => elem.toString())) - trigger_labels?: string[]; + @Transform(({ obj }) => obj.trigger_labels.map((elem) => elem.toString())) + trigger_labels: string[]; - @Transform(({ obj }) => obj.assign_labels?.map((elem) => elem.toString())) - assign_labels?: string[]; + @Transform(({ obj }) => obj.assign_labels.map((elem) => elem.toString())) + assign_labels: string[]; - @Transform(({ obj }) => obj.nextBlocks?.map((elem) => elem.toString())) - nextBlocks?: string[]; + @Transform(({ obj }) => obj.nextBlocks.map((elem) => elem.toString())) + nextBlocks: string[]; @Transform(({ obj }) => obj.attachedBlock?.toString() || null) - attachedBlock?: string; + attachedBlock: string; @Transform(({ obj }) => obj.category.toString()) category: string; @@ -161,16 +161,16 @@ export class BlockFull extends BlockStub { assign_labels: Label[]; @Type(() => Block) - nextBlocks?: Block[]; + nextBlocks: Block[]; @Type(() => Block) - attachedBlock?: Block; + attachedBlock: Block; @Type(() => Category) category: Category; @Type(() => Block) - previousBlocks: Block[]; + previousBlocks?: Block[]; @Type(() => Block) attachedToBlock?: Block; diff --git a/api/src/chat/schemas/category.schema.ts b/api/src/chat/schemas/category.schema.ts index 7ed8cdf3..bc7b8cfd 100644 --- a/api/src/chat/schemas/category.schema.ts +++ b/api/src/chat/schemas/category.schema.ts @@ -25,19 +25,19 @@ export class Category extends BaseSchema { type: Boolean, default: false, }) - builtin?: boolean; + builtin: boolean; @Prop({ type: Number, default: 100, }) - zoom?: number; + zoom: number; @Prop({ type: [Number, Number], default: [0, 0], }) - offset?: [number, number]; + offset: [number, number]; } export const CategoryModel: ModelDefinition = LifecycleHookManager.attach({ diff --git a/api/src/chat/schemas/context-var.schema.ts b/api/src/chat/schemas/context-var.schema.ts index eb1b77ad..f97e9af9 100644 --- a/api/src/chat/schemas/context-var.schema.ts +++ b/api/src/chat/schemas/context-var.schema.ts @@ -38,7 +38,7 @@ export class ContextVar extends BaseSchema { type: Boolean, default: false, }) - permanent?: boolean; + permanent: boolean; } export const ContextVarModel: ModelDefinition = LifecycleHookManager.attach({ diff --git a/api/src/chat/schemas/conversation.schema.ts b/api/src/chat/schemas/conversation.schema.ts index 7880c0c6..e019ba15 100644 --- a/api/src/chat/schemas/conversation.schema.ts +++ b/api/src/chat/schemas/conversation.schema.ts @@ -51,19 +51,19 @@ class ConversationStub extends BaseSchema { type: Boolean, default: true, }) - active?: boolean; + active: boolean; @Prop({ type: Object, default: getDefaultConversationContext(), }) - context?: Context; + context: Context; @Prop({ type: MongooseSchema.Types.ObjectId, ref: 'Block', }) - current?: unknown; + current: unknown; @Prop([ { @@ -72,7 +72,7 @@ class ConversationStub extends BaseSchema { default: [], }, ]) - next?: unknown; + next: unknown; } @Schema({ timestamps: true }) @@ -80,11 +80,11 @@ export class Conversation extends ConversationStub { @Transform(({ obj }) => obj.sender.toString()) sender: string; - @Transform(({ obj }) => obj.current.toString()) - current?: string; + @Transform(({ obj }) => (obj.current ? obj.current.toString() : null)) + current: string | null; @Transform(({ obj }) => obj.next.map((elem) => elem.toString())) - next?: string[]; + next: string[]; } @Schema({ timestamps: true }) diff --git a/api/src/chat/schemas/label.schema.ts b/api/src/chat/schemas/label.schema.ts index 592d99e2..41709703 100644 --- a/api/src/chat/schemas/label.schema.ts +++ b/api/src/chat/schemas/label.schema.ts @@ -43,13 +43,13 @@ export class LabelStub extends BaseSchema { @Prop({ type: String, }) - description?: string; + description: string; @Prop({ type: Boolean, default: false, }) - builtin?: boolean; + builtin: boolean; } @Schema({ timestamps: true }) diff --git a/api/src/chat/seeds/category.seed.ts b/api/src/chat/seeds/category.seed.ts index d1917309..5134fc4c 100644 --- a/api/src/chat/seeds/category.seed.ts +++ b/api/src/chat/seeds/category.seed.ts @@ -10,11 +10,17 @@ import { Injectable } from '@nestjs/common'; import { BaseSeeder } from '@/utils/generics/base-seeder'; +import { CategoryDto } from '../dto/category.dto'; import { CategoryRepository } from '../repositories/category.repository'; import { Category } from '../schemas/category.schema'; @Injectable() -export class CategorySeeder extends BaseSeeder { +export class CategorySeeder extends BaseSeeder< + Category, + never, + never, + CategoryDto +> { constructor(private readonly categoryRepository: CategoryRepository) { super(categoryRepository); } diff --git a/api/src/chat/seeds/context-var.seed.ts b/api/src/chat/seeds/context-var.seed.ts index 965cc571..813581ef 100644 --- a/api/src/chat/seeds/context-var.seed.ts +++ b/api/src/chat/seeds/context-var.seed.ts @@ -10,11 +10,17 @@ import { Injectable } from '@nestjs/common'; import { BaseSeeder } from '@/utils/generics/base-seeder'; +import { ContextVarDto } from '../dto/context-var.dto'; import { ContextVarRepository } from '../repositories/context-var.repository'; import { ContextVar } from '../schemas/context-var.schema'; @Injectable() -export class ContextVarSeeder extends BaseSeeder { +export class ContextVarSeeder extends BaseSeeder< + ContextVar, + never, + never, + ContextVarDto +> { constructor(private readonly contextVarRepository: ContextVarRepository) { super(contextVarRepository); } diff --git a/api/src/chat/services/block.service.ts b/api/src/chat/services/block.service.ts index 131f45f5..44ebb732 100644 --- a/api/src/chat/services/block.service.ts +++ b/api/src/chat/services/block.service.ts @@ -22,6 +22,7 @@ import { SettingService } from '@/setting/services/setting.service'; import { BaseService } from '@/utils/generics/base-service'; import { getRandom } from '@/utils/helpers/safeRandom'; +import { BlockDto } from '../dto/block.dto'; import { BlockRepository } from '../repositories/block.repository'; import { Block, BlockFull, BlockPopulate } from '../schemas/block.schema'; import { Context } from '../schemas/types/context'; @@ -35,7 +36,12 @@ import { Payload, StdQuickReply } from '../schemas/types/quick-reply'; import { SubscriberContext } from '../schemas/types/subscriberContext'; @Injectable() -export class BlockService extends BaseService { +export class BlockService extends BaseService< + Block, + BlockPopulate, + BlockFull, + BlockDto +> { constructor( readonly repository: BlockRepository, private readonly contentService: ContentService, diff --git a/api/src/chat/services/category.service.ts b/api/src/chat/services/category.service.ts index 079a3a7e..85ceca21 100644 --- a/api/src/chat/services/category.service.ts +++ b/api/src/chat/services/category.service.ts @@ -10,11 +10,17 @@ import { Injectable } from '@nestjs/common'; import { BaseService } from '@/utils/generics/base-service'; +import { CategoryDto } from '../dto/category.dto'; import { CategoryRepository } from '../repositories/category.repository'; import { Category } from '../schemas/category.schema'; @Injectable() -export class CategoryService extends BaseService { +export class CategoryService extends BaseService< + Category, + never, + never, + CategoryDto +> { constructor(readonly repository: CategoryRepository) { super(repository); } diff --git a/api/src/chat/services/context-var.service.ts b/api/src/chat/services/context-var.service.ts index dfcdd164..d93f96d5 100644 --- a/api/src/chat/services/context-var.service.ts +++ b/api/src/chat/services/context-var.service.ts @@ -10,12 +10,18 @@ import { Injectable } from '@nestjs/common'; import { BaseService } from '@/utils/generics/base-service'; +import { ContextVarDto } from '../dto/context-var.dto'; import { ContextVarRepository } from '../repositories/context-var.repository'; import { Block, BlockFull } from '../schemas/block.schema'; import { ContextVar } from '../schemas/context-var.schema'; @Injectable() -export class ContextVarService extends BaseService { +export class ContextVarService extends BaseService< + ContextVar, + never, + never, + ContextVarDto +> { constructor(readonly repository: ContextVarRepository) { super(repository); } diff --git a/api/src/chat/services/conversation.service.ts b/api/src/chat/services/conversation.service.ts index fdd65cd2..035c54fc 100644 --- a/api/src/chat/services/conversation.service.ts +++ b/api/src/chat/services/conversation.service.ts @@ -12,6 +12,7 @@ import EventWrapper from '@/channel/lib/EventWrapper'; import { LoggerService } from '@/logger/logger.service'; import { BaseService } from '@/utils/generics/base-service'; +import { ConversationDto } from '../dto/conversation.dto'; import { VIEW_MORE_PAYLOAD } from '../helpers/constants'; import { ConversationRepository } from '../repositories/conversation.repository'; import { Block, BlockFull } from '../schemas/block.schema'; @@ -30,7 +31,8 @@ import { SubscriberService } from './subscriber.service'; export class ConversationService extends BaseService< Conversation, ConversationPopulate, - ConversationFull + ConversationFull, + ConversationDto > { constructor( readonly repository: ConversationRepository, diff --git a/api/src/chat/services/label.service.ts b/api/src/chat/services/label.service.ts index e5db9cef..976f273c 100644 --- a/api/src/chat/services/label.service.ts +++ b/api/src/chat/services/label.service.ts @@ -10,11 +10,17 @@ import { Injectable } from '@nestjs/common'; import { BaseService } from '@/utils/generics/base-service'; +import { LabelDto } from '../dto/label.dto'; import { LabelRepository } from '../repositories/label.repository'; import { Label, LabelFull, LabelPopulate } from '../schemas/label.schema'; @Injectable() -export class LabelService extends BaseService { +export class LabelService extends BaseService< + Label, + LabelPopulate, + LabelFull, + LabelDto +> { constructor(readonly repository: LabelRepository) { super(repository); } diff --git a/api/src/chat/services/subscriber.service.ts b/api/src/chat/services/subscriber.service.ts index d5b688a9..6af757e4 100644 --- a/api/src/chat/services/subscriber.service.ts +++ b/api/src/chat/services/subscriber.service.ts @@ -28,7 +28,7 @@ import { SocketRequest } from '@/websocket/utils/socket-request'; import { SocketResponse } from '@/websocket/utils/socket-response'; import { WebsocketGateway } from '@/websocket/websocket.gateway'; -import { SubscriberUpdateDto } from '../dto/subscriber.dto'; +import { SubscriberDto, SubscriberUpdateDto } from '../dto/subscriber.dto'; import { SubscriberRepository } from '../repositories/subscriber.repository'; import { Subscriber, @@ -40,7 +40,8 @@ import { export class SubscriberService extends BaseService< Subscriber, SubscriberPopulate, - SubscriberFull + SubscriberFull, + SubscriberDto > { private readonly gateway: WebsocketGateway; diff --git a/api/src/cms/dto/content.dto.ts b/api/src/cms/dto/content.dto.ts index ffa8dca9..4eb4dae4 100644 --- a/api/src/cms/dto/content.dto.ts +++ b/api/src/cms/dto/content.dto.ts @@ -9,6 +9,7 @@ import { ApiProperty, ApiPropertyOptional, PartialType } from '@nestjs/swagger'; import { IsBoolean, IsNotEmpty, IsOptional, IsString } from 'class-validator'; +import { DtoConfig } from '@/utils/types/dto.types'; import { IsObjectId } from '@/utils/validation-rules/is-object-id'; export class ContentCreateDto { @@ -34,3 +35,7 @@ export class ContentCreateDto { } export class ContentUpdateDto extends PartialType(ContentCreateDto) {} + +export type ContentDto = DtoConfig<{ + create: ContentCreateDto; +}>; diff --git a/api/src/cms/dto/contentType.dto.ts b/api/src/cms/dto/contentType.dto.ts index b4e6f036..f4f2ae25 100644 --- a/api/src/cms/dto/contentType.dto.ts +++ b/api/src/cms/dto/contentType.dto.ts @@ -9,16 +9,18 @@ import { ApiProperty, ApiPropertyOptional, PartialType } from '@nestjs/swagger'; import { Type } from 'class-transformer'; import { - IsString, IsArray, - ValidateNested, - IsOptional, IsEnum, - Matches, IsNotEmpty, + IsOptional, + IsString, + Matches, Validate, + ValidateNested, } from 'class-validator'; +import { DtoConfig } from '@/utils/types/dto.types'; + import { ValidateRequiredFields } from '../validators/validate-required-fields.validator'; export class FieldType { @@ -55,3 +57,7 @@ export class ContentTypeCreateDto { } export class ContentTypeUpdateDto extends PartialType(ContentTypeCreateDto) {} + +export type ContentTypeDto = DtoConfig<{ + create: ContentTypeCreateDto; +}>; diff --git a/api/src/cms/dto/menu.dto.ts b/api/src/cms/dto/menu.dto.ts index e346bad3..892acb18 100644 --- a/api/src/cms/dto/menu.dto.ts +++ b/api/src/cms/dto/menu.dto.ts @@ -16,6 +16,7 @@ import { ValidateIf, } from 'class-validator'; +import { DtoConfig } from '@/utils/types/dto.types'; import { IsObjectId } from '@/utils/validation-rules/is-object-id'; import { MenuType } from '../schemas/types/menu'; @@ -53,3 +54,7 @@ export class MenuCreateDto { } export class MenuQueryDto extends PartialType(MenuCreateDto) {} + +export type MenuDto = DtoConfig<{ + create: MenuCreateDto; +}>; diff --git a/api/src/cms/repositories/content-type.repository.ts b/api/src/cms/repositories/content-type.repository.ts index 9548e925..9ee6d510 100644 --- a/api/src/cms/repositories/content-type.repository.ts +++ b/api/src/cms/repositories/content-type.repository.ts @@ -15,11 +15,17 @@ import { BlockService } from '@/chat/services/block.service'; import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository'; import { TFilterQuery } from '@/utils/types/filter.types'; +import { ContentTypeDto } from '../dto/contentType.dto'; import { ContentType } from '../schemas/content-type.schema'; import { Content } from '../schemas/content.schema'; @Injectable() -export class ContentTypeRepository extends BaseRepository { +export class ContentTypeRepository extends BaseRepository< + ContentType, + never, + never, + ContentTypeDto +> { constructor( readonly eventEmitter: EventEmitter2, @InjectModel(ContentType.name) readonly model: Model, diff --git a/api/src/cms/repositories/content.repository.ts b/api/src/cms/repositories/content.repository.ts index 77403b08..5fd38905 100644 --- a/api/src/cms/repositories/content.repository.ts +++ b/api/src/cms/repositories/content.repository.ts @@ -21,6 +21,7 @@ import { import { BaseRepository } from '@/utils/generics/base-repository'; import { TFilterQuery } from '@/utils/types/filter.types'; +import { ContentDto } from '../dto/content.dto'; import { Content, CONTENT_POPULATE, @@ -32,7 +33,8 @@ import { export class ContentRepository extends BaseRepository< Content, ContentPopulate, - ContentFull + ContentFull, + ContentDto > { constructor( readonly eventEmitter: EventEmitter2, diff --git a/api/src/cms/repositories/menu.repository.ts b/api/src/cms/repositories/menu.repository.ts index d136610c..65408f50 100644 --- a/api/src/cms/repositories/menu.repository.ts +++ b/api/src/cms/repositories/menu.repository.ts @@ -13,6 +13,7 @@ import { Model } from 'mongoose'; import { BaseRepository } from '@/utils/generics/base-repository'; +import { MenuDto } from '../dto/menu.dto'; import { Menu, MENU_POPULATE, @@ -26,7 +27,8 @@ import { MenuType } from '../schemas/types/menu'; export class MenuRepository extends BaseRepository< Menu, MenuPopulate, - MenuFull + MenuFull, + MenuDto > { constructor( readonly eventEmitter: EventEmitter2, diff --git a/api/src/cms/schemas/content-type.schema.ts b/api/src/cms/schemas/content-type.schema.ts index d0fcb1fb..e1d95921 100644 --- a/api/src/cms/schemas/content-type.schema.ts +++ b/api/src/cms/schemas/content-type.schema.ts @@ -6,7 +6,7 @@ * 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file). */ -import { Prop, Schema, SchemaFactory, ModelDefinition } from '@nestjs/mongoose'; +import { ModelDefinition, Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; import mongoose from 'mongoose'; import { BaseSchema } from '@/utils/generics/base-schema'; @@ -39,7 +39,7 @@ export class ContentType extends BaseSchema { }, ], }) - fields?: { + fields: { name: string; label: string; type: string; diff --git a/api/src/cms/schemas/content.schema.ts b/api/src/cms/schemas/content.schema.ts index 97088bc8..bcfa7908 100644 --- a/api/src/cms/schemas/content.schema.ts +++ b/api/src/cms/schemas/content.schema.ts @@ -41,7 +41,7 @@ export class ContentStub extends BaseSchema { * Either of not this content is active. */ @Prop({ type: Boolean, default: true }) - status?: boolean; + status: boolean; @Prop({ type: mongoose.Schema.Types.Mixed }) dynamicFields: Record; diff --git a/api/src/cms/services/content-type.service.ts b/api/src/cms/services/content-type.service.ts index 907e7388..2c98d988 100644 --- a/api/src/cms/services/content-type.service.ts +++ b/api/src/cms/services/content-type.service.ts @@ -10,11 +10,17 @@ import { Injectable } from '@nestjs/common'; import { BaseService } from '@/utils/generics/base-service'; +import { ContentTypeDto } from '../dto/contentType.dto'; import { ContentTypeRepository } from '../repositories/content-type.repository'; import { ContentType } from '../schemas/content-type.schema'; @Injectable() -export class ContentTypeService extends BaseService { +export class ContentTypeService extends BaseService< + ContentType, + never, + never, + ContentTypeDto +> { constructor(readonly repository: ContentTypeRepository) { super(repository); } diff --git a/api/src/cms/services/content.service.ts b/api/src/cms/services/content.service.ts index 2a491a2b..7b78bbe5 100644 --- a/api/src/cms/services/content.service.ts +++ b/api/src/cms/services/content.service.ts @@ -19,6 +19,7 @@ import { LoggerService } from '@/logger/logger.service'; import { BaseService } from '@/utils/generics/base-service'; import { TFilterQuery } from '@/utils/types/filter.types'; +import { ContentDto } from '../dto/content.dto'; import { ContentRepository } from '../repositories/content.repository'; import { Content, @@ -30,7 +31,8 @@ import { export class ContentService extends BaseService< Content, ContentPopulate, - ContentFull + ContentFull, + ContentDto > { constructor( readonly repository: ContentRepository, diff --git a/api/src/cms/services/menu.service.ts b/api/src/cms/services/menu.service.ts index ba560d41..794ae22d 100644 --- a/api/src/cms/services/menu.service.ts +++ b/api/src/cms/services/menu.service.ts @@ -20,13 +20,18 @@ import { MENU_CACHE_KEY } from '@/utils/constants/cache'; import { Cacheable } from '@/utils/decorators/cacheable.decorator'; import { BaseService } from '@/utils/generics/base-service'; -import { MenuCreateDto } from '../dto/menu.dto'; +import { MenuCreateDto, MenuDto } from '../dto/menu.dto'; import { MenuRepository } from '../repositories/menu.repository'; import { Menu, MenuFull, MenuPopulate } from '../schemas/menu.schema'; import { AnyMenu, MenuTree, MenuType } from '../schemas/types/menu'; @Injectable() -export class MenuService extends BaseService { +export class MenuService extends BaseService< + Menu, + MenuPopulate, + MenuFull, + MenuDto +> { private RootSymbol: symbol = Symbol('RootMenu'); constructor( diff --git a/api/src/helper/lib/__test__/base-nlp-helper.spec.ts b/api/src/helper/lib/__test__/base-nlp-helper.spec.ts index fe547613..4f2f8ddb 100644 --- a/api/src/helper/lib/__test__/base-nlp-helper.spec.ts +++ b/api/src/helper/lib/__test__/base-nlp-helper.spec.ts @@ -137,12 +137,16 @@ describe('BaseNlpHelper', () => { name: 'intent', createdAt: new Date(), updatedAt: new Date(), + builtin: false, + lookups: [], }, entity2: { id: new ObjectId().toString(), name: 'test-entity', createdAt: new Date(), updatedAt: new Date(), + builtin: false, + lookups: [], }, }); jest.spyOn(NlpValue, 'getValueMap').mockReturnValue({ @@ -152,6 +156,9 @@ describe('BaseNlpHelper', () => { entity: 'entity1', // Add the required entity field createdAt: new Date(), updatedAt: new Date(), + builtin: false, + expressions: [], + metadata: [], }, value2: { id: new ObjectId().toString(), @@ -159,6 +166,9 @@ describe('BaseNlpHelper', () => { entity: 'entity2', // Add the required entity field createdAt: new Date(), updatedAt: new Date(), + builtin: false, + expressions: [], + metadata: [], }, }); @@ -195,6 +205,8 @@ describe('BaseNlpHelper', () => { name: 'test-entity', createdAt: new Date(), updatedAt: new Date(), + builtin: false, + lookups: [], }, }); diff --git a/api/src/i18n/dto/language.dto.ts b/api/src/i18n/dto/language.dto.ts index df6b8aa6..7f3f6325 100644 --- a/api/src/i18n/dto/language.dto.ts +++ b/api/src/i18n/dto/language.dto.ts @@ -7,9 +7,11 @@ */ import { PartialType } from '@nestjs/mapped-types'; -import { ApiProperty } from '@nestjs/swagger'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { IsBoolean, IsNotEmpty, IsOptional, IsString } from 'class-validator'; +import { DtoConfig } from '@/utils/types/dto.types'; + export class LanguageCreateDto { @ApiProperty({ description: 'Language Title', type: String }) @IsNotEmpty() @@ -25,10 +27,14 @@ export class LanguageCreateDto { @IsBoolean() isRTL: boolean; - @ApiProperty({ description: 'Is Default Language ?', type: Boolean }) + @ApiPropertyOptional({ description: 'Is Default Language ?', type: Boolean }) @IsOptional() @IsBoolean() isDefault?: boolean; } export class LanguageUpdateDto extends PartialType(LanguageCreateDto) {} + +export type LanguageDto = DtoConfig<{ + create: LanguageCreateDto; +}>; diff --git a/api/src/i18n/repositories/language.repository.ts b/api/src/i18n/repositories/language.repository.ts index 67799afd..a3d5cfd4 100644 --- a/api/src/i18n/repositories/language.repository.ts +++ b/api/src/i18n/repositories/language.repository.ts @@ -14,10 +14,16 @@ import { Document, Model, Query } from 'mongoose'; import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository'; import { TFilterQuery } from '@/utils/types/filter.types'; +import { LanguageDto } from '../dto/language.dto'; import { Language } from '../schemas/language.schema'; @Injectable() -export class LanguageRepository extends BaseRepository { +export class LanguageRepository extends BaseRepository< + Language, + never, + never, + LanguageDto +> { constructor( readonly eventEmitter: EventEmitter2, @InjectModel(Language.name) readonly model: Model, diff --git a/api/src/i18n/schemas/language.schema.ts b/api/src/i18n/schemas/language.schema.ts index 2581666b..77bc929b 100644 --- a/api/src/i18n/schemas/language.schema.ts +++ b/api/src/i18n/schemas/language.schema.ts @@ -32,13 +32,13 @@ export class Language extends BaseSchema { type: Boolean, default: false, }) - isDefault?: boolean; + isDefault: boolean; @Prop({ type: Boolean, default: false, }) - isRTL?: boolean; + isRTL: boolean; } export const LanguageModel: ModelDefinition = LifecycleHookManager.attach({ diff --git a/api/src/i18n/seeds/language.seed.ts b/api/src/i18n/seeds/language.seed.ts index 376c3130..b7ca63e3 100644 --- a/api/src/i18n/seeds/language.seed.ts +++ b/api/src/i18n/seeds/language.seed.ts @@ -10,11 +10,17 @@ import { Injectable } from '@nestjs/common'; import { BaseSeeder } from '@/utils/generics/base-seeder'; +import { LanguageDto } from '../dto/language.dto'; import { LanguageRepository } from '../repositories/language.repository'; import { Language } from '../schemas/language.schema'; @Injectable() -export class LanguageSeeder extends BaseSeeder { +export class LanguageSeeder extends BaseSeeder< + Language, + never, + never, + LanguageDto +> { constructor(private readonly languageRepository: LanguageRepository) { super(languageRepository); } diff --git a/api/src/i18n/services/language.service.ts b/api/src/i18n/services/language.service.ts index 774dbeee..0a7425d5 100644 --- a/api/src/i18n/services/language.service.ts +++ b/api/src/i18n/services/language.service.ts @@ -23,11 +23,17 @@ import { import { Cacheable } from '@/utils/decorators/cacheable.decorator'; import { BaseService } from '@/utils/generics/base-service'; +import { LanguageDto } from '../dto/language.dto'; import { LanguageRepository } from '../repositories/language.repository'; import { Language } from '../schemas/language.schema'; @Injectable() -export class LanguageService extends BaseService { +export class LanguageService extends BaseService< + Language, + never, + never, + LanguageDto +> { constructor( readonly repository: LanguageRepository, @Inject(CACHE_MANAGER) private readonly cacheManager: Cache, diff --git a/api/src/i18n/services/translation.service.spec.ts b/api/src/i18n/services/translation.service.spec.ts index 5f0d6bb4..1667a1e8 100644 --- a/api/src/i18n/services/translation.service.spec.ts +++ b/api/src/i18n/services/translation.service.spec.ts @@ -154,6 +154,7 @@ describe('TranslationService', () => { }, }, options: {}, + attachedBlock: null, }; const mockedPlugin: any = { diff --git a/api/src/nlp/dto/nlp-entity.dto.ts b/api/src/nlp/dto/nlp-entity.dto.ts index 5ef92d0a..009b1841 100644 --- a/api/src/nlp/dto/nlp-entity.dto.ts +++ b/api/src/nlp/dto/nlp-entity.dto.ts @@ -8,15 +8,17 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { - IsString, - IsOptional, - IsBoolean, IsArray, - Matches, + IsBoolean, IsIn, IsNotEmpty, + IsOptional, + IsString, + Matches, } from 'class-validator'; +import { DtoConfig } from '@/utils/types/dto.types'; + export type Lookup = 'keywords' | 'trait' | 'free-text'; export class NlpEntityCreateDto { @@ -46,3 +48,7 @@ export class NlpEntityCreateDto { @IsOptional() builtin?: boolean; } + +export type NlpEntityDto = DtoConfig<{ + create: NlpEntityCreateDto; +}>; diff --git a/api/src/nlp/dto/nlp-sample.dto.ts b/api/src/nlp/dto/nlp-sample.dto.ts index 762be371..2f88ed68 100644 --- a/api/src/nlp/dto/nlp-sample.dto.ts +++ b/api/src/nlp/dto/nlp-sample.dto.ts @@ -15,6 +15,7 @@ import { IsString, } from 'class-validator'; +import { DtoConfig } from '@/utils/types/dto.types'; import { IsObjectId } from '@/utils/validation-rules/is-object-id'; import { NlpSampleEntityValue, NlpSampleState } from '../schemas/types'; @@ -40,7 +41,7 @@ export class NlpSampleCreateDto { @IsString() @IsIn(Object.values(NlpSampleState)) @IsOptional() - type?: NlpSampleState; + type?: keyof typeof NlpSampleState; @ApiProperty({ description: 'NLP sample language id', type: String }) @IsString() @@ -63,3 +64,7 @@ export class NlpSampleDto extends NlpSampleCreateDto { } export class NlpSampleUpdateDto extends PartialType(NlpSampleCreateDto) {} + +export type TNlpSampleDto = DtoConfig<{ + create: NlpSampleCreateDto; +}>; diff --git a/api/src/nlp/dto/nlp-value.dto.ts b/api/src/nlp/dto/nlp-value.dto.ts index 215c5f1c..3848718c 100644 --- a/api/src/nlp/dto/nlp-value.dto.ts +++ b/api/src/nlp/dto/nlp-value.dto.ts @@ -9,14 +9,15 @@ import { PartialType } from '@nestjs/mapped-types'; import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { - IsString, - IsBoolean, IsArray, - IsObject, + IsBoolean, IsNotEmpty, + IsObject, IsOptional, + IsString, } from 'class-validator'; +import { DtoConfig } from '@/utils/types/dto.types'; import { IsObjectId } from '@/utils/validation-rules/is-object-id'; export class NlpValueCreateDto { @@ -52,3 +53,7 @@ export class NlpValueCreateDto { } export class NlpValueUpdateDto extends PartialType(NlpValueCreateDto) {} + +export type NlpValueDto = DtoConfig<{ + create: NlpValueCreateDto; +}>; diff --git a/api/src/nlp/repositories/nlp-entity.repository.ts b/api/src/nlp/repositories/nlp-entity.repository.ts index fdaac277..36b57bef 100644 --- a/api/src/nlp/repositories/nlp-entity.repository.ts +++ b/api/src/nlp/repositories/nlp-entity.repository.ts @@ -14,6 +14,7 @@ import { Document, Model, Query } from 'mongoose'; import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository'; import { TFilterQuery } from '@/utils/types/filter.types'; +import { NlpEntityDto } from '../dto/nlp-entity.dto'; import { NLP_ENTITY_POPULATE, NlpEntity, @@ -29,7 +30,8 @@ import { NlpValueRepository } from './nlp-value.repository'; export class NlpEntityRepository extends BaseRepository< NlpEntity, NlpEntityPopulate, - NlpEntityFull + NlpEntityFull, + NlpEntityDto > { constructor( readonly eventEmitter: EventEmitter2, diff --git a/api/src/nlp/repositories/nlp-sample.repository.ts b/api/src/nlp/repositories/nlp-sample.repository.ts index f5f953d1..0536bde6 100644 --- a/api/src/nlp/repositories/nlp-sample.repository.ts +++ b/api/src/nlp/repositories/nlp-sample.repository.ts @@ -14,6 +14,7 @@ import { Document, Model, Query } from 'mongoose'; import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository'; import { TFilterQuery } from '@/utils/types/filter.types'; +import { TNlpSampleDto } from '../dto/nlp-sample.dto'; import { NLP_SAMPLE_POPULATE, NlpSample, @@ -27,7 +28,8 @@ import { NlpSampleEntityRepository } from './nlp-sample-entity.repository'; export class NlpSampleRepository extends BaseRepository< NlpSample, NlpSamplePopulate, - NlpSampleFull + NlpSampleFull, + TNlpSampleDto > { constructor( readonly eventEmitter: EventEmitter2, diff --git a/api/src/nlp/repositories/nlp-value.repository.ts b/api/src/nlp/repositories/nlp-value.repository.ts index a09b7cde..e7839bf1 100644 --- a/api/src/nlp/repositories/nlp-value.repository.ts +++ b/api/src/nlp/repositories/nlp-value.repository.ts @@ -14,6 +14,7 @@ import { Document, Model, Query } from 'mongoose'; import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository'; import { TFilterQuery } from '@/utils/types/filter.types'; +import { NlpValueDto } from '../dto/nlp-value.dto'; import { NLP_VALUE_POPULATE, NlpValue, @@ -28,7 +29,8 @@ import { NlpSampleEntityRepository } from './nlp-sample-entity.repository'; export class NlpValueRepository extends BaseRepository< NlpValue, NlpValuePopulate, - NlpValueFull + NlpValueFull, + NlpValueDto > { constructor( readonly eventEmitter: EventEmitter2, diff --git a/api/src/nlp/schemas/nlp-entity.schema.ts b/api/src/nlp/schemas/nlp-entity.schema.ts index 77012174..86085d05 100644 --- a/api/src/nlp/schemas/nlp-entity.schema.ts +++ b/api/src/nlp/schemas/nlp-entity.schema.ts @@ -44,7 +44,7 @@ export class NlpEntityStub extends BaseSchema { * Lookup strategy can contain : keywords, trait, free-text */ @Prop({ type: [String], default: ['keywords'] }) - lookups?: Lookup[]; + lookups: Lookup[]; /** * Description of the entity purpose. @@ -56,7 +56,7 @@ export class NlpEntityStub extends BaseSchema { * Either or not this entity a built-in (either fixtures or shipped along with the 3rd party ai). */ @Prop({ type: Boolean, default: false }) - builtin?: boolean; + builtin: boolean; /** * Returns a map object for entities diff --git a/api/src/nlp/schemas/nlp-sample.schema.ts b/api/src/nlp/schemas/nlp-sample.schema.ts index 72d1900e..2a33ab96 100644 --- a/api/src/nlp/schemas/nlp-sample.schema.ts +++ b/api/src/nlp/schemas/nlp-sample.schema.ts @@ -33,7 +33,7 @@ export class NlpSampleStub extends BaseSchema { * Either or not this sample was used for traning already. */ @Prop({ type: Boolean, default: false }) - trained?: boolean; + trained: boolean; /** * From where this sample was provided. @@ -43,7 +43,7 @@ export class NlpSampleStub extends BaseSchema { enum: Object.values(NlpSampleState), default: NlpSampleState.train, }) - type?: keyof typeof NlpSampleState; + type: keyof typeof NlpSampleState; /** * The language of the sample. diff --git a/api/src/nlp/schemas/nlp-value.schema.ts b/api/src/nlp/schemas/nlp-value.schema.ts index 7469fc87..a5f2e4be 100644 --- a/api/src/nlp/schemas/nlp-value.schema.ts +++ b/api/src/nlp/schemas/nlp-value.schema.ts @@ -38,19 +38,19 @@ export class NlpValueStub extends BaseSchema { * An array of synonyms or equivalent words that fits this value. */ @Prop({ type: [String], default: [] }) - expressions?: string[]; + expressions: string[]; /** * Metadata are additional data that can be associated to this values, most of the time, the metadata contains system values or ids (e.g: value: "coffee", metadata: "item_11") . */ @Prop({ type: JSON, default: {} }) - metadata?: Record; + metadata: Record; /** * Either or not this value a built-in (either fixtures or shipped along with the 3rd party ai). */ @Prop({ type: Boolean, default: false }) - builtin?: boolean; + builtin: boolean; /** * The entity to which this value belongs to. diff --git a/api/src/nlp/seeds/nlp-entity.seed.ts b/api/src/nlp/seeds/nlp-entity.seed.ts index c5523c7a..f9be033f 100644 --- a/api/src/nlp/seeds/nlp-entity.seed.ts +++ b/api/src/nlp/seeds/nlp-entity.seed.ts @@ -10,6 +10,7 @@ import { Injectable } from '@nestjs/common'; import { BaseSeeder } from '@/utils/generics/base-seeder'; +import { NlpEntityDto } from '../dto/nlp-entity.dto'; import { NlpEntityRepository } from '../repositories/nlp-entity.repository'; import { NlpEntity, @@ -21,7 +22,8 @@ import { export class NlpEntitySeeder extends BaseSeeder< NlpEntity, NlpEntityPopulate, - NlpEntityFull + NlpEntityFull, + NlpEntityDto > { constructor(nlpEntityRepository: NlpEntityRepository) { super(nlpEntityRepository); diff --git a/api/src/nlp/seeds/nlp-value.seed.ts b/api/src/nlp/seeds/nlp-value.seed.ts index cc0856d1..d8fd5f7a 100644 --- a/api/src/nlp/seeds/nlp-value.seed.ts +++ b/api/src/nlp/seeds/nlp-value.seed.ts @@ -8,9 +8,9 @@ import { Injectable } from '@nestjs/common'; -import { BaseSchema } from '@/utils/generics/base-schema'; import { BaseSeeder } from '@/utils/generics/base-seeder'; +import { NlpValueCreateDto, NlpValueDto } from '../dto/nlp-value.dto'; import { NlpEntityRepository } from '../repositories/nlp-entity.repository'; import { NlpValueRepository } from '../repositories/nlp-value.repository'; import { @@ -23,7 +23,8 @@ import { export class NlpValueSeeder extends BaseSeeder< NlpValue, NlpValuePopulate, - NlpValueFull + NlpValueFull, + NlpValueDto > { constructor( nlpValueRepository: NlpValueRepository, @@ -32,7 +33,7 @@ export class NlpValueSeeder extends BaseSeeder< super(nlpValueRepository); } - async seed(models: Omit[]): Promise { + async seed(models: NlpValueCreateDto[]): Promise { if (await this.isEmpty()) { const entities = await this.nlpEntityRepository.findAll(); const modelDtos = models.map((v) => ({ diff --git a/api/src/nlp/services/nlp-entity.service.ts b/api/src/nlp/services/nlp-entity.service.ts index e119bf87..e8531e95 100644 --- a/api/src/nlp/services/nlp-entity.service.ts +++ b/api/src/nlp/services/nlp-entity.service.ts @@ -10,7 +10,7 @@ import { Injectable } from '@nestjs/common'; import { BaseService } from '@/utils/generics/base-service'; -import { Lookup } from '../dto/nlp-entity.dto'; +import { Lookup, NlpEntityDto } from '../dto/nlp-entity.dto'; import { NlpEntityRepository } from '../repositories/nlp-entity.repository'; import { NlpEntity, @@ -25,7 +25,8 @@ import { NlpValueService } from './nlp-value.service'; export class NlpEntityService extends BaseService< NlpEntity, NlpEntityPopulate, - NlpEntityFull + NlpEntityFull, + NlpEntityDto > { constructor( readonly repository: NlpEntityRepository, diff --git a/api/src/nlp/services/nlp-sample.service.ts b/api/src/nlp/services/nlp-sample.service.ts index ca7384b1..5392e934 100644 --- a/api/src/nlp/services/nlp-sample.service.ts +++ b/api/src/nlp/services/nlp-sample.service.ts @@ -21,7 +21,7 @@ import { LoggerService } from '@/logger/logger.service'; import { BaseService } from '@/utils/generics/base-service'; import { THydratedDocument } from '@/utils/types/filter.types'; -import { NlpSampleCreateDto } from '../dto/nlp-sample.dto'; +import { NlpSampleCreateDto, TNlpSampleDto } from '../dto/nlp-sample.dto'; import { NlpSampleRepository } from '../repositories/nlp-sample.repository'; import { NlpSample, @@ -37,7 +37,8 @@ import { NlpSampleEntityService } from './nlp-sample-entity.service'; export class NlpSampleService extends BaseService< NlpSample, NlpSamplePopulate, - NlpSampleFull + NlpSampleFull, + TNlpSampleDto > { constructor( readonly repository: NlpSampleRepository, diff --git a/api/src/nlp/services/nlp-value.service.ts b/api/src/nlp/services/nlp-value.service.ts index 4323881f..2d20bde5 100644 --- a/api/src/nlp/services/nlp-value.service.ts +++ b/api/src/nlp/services/nlp-value.service.ts @@ -11,7 +11,11 @@ import { forwardRef, Inject, Injectable } from '@nestjs/common'; import { DeleteResult } from '@/utils/generics/base-repository'; import { BaseService } from '@/utils/generics/base-service'; -import { NlpValueCreateDto, NlpValueUpdateDto } from '../dto/nlp-value.dto'; +import { + NlpValueCreateDto, + NlpValueDto, + NlpValueUpdateDto, +} from '../dto/nlp-value.dto'; import { NlpValueRepository } from '../repositories/nlp-value.repository'; import { NlpEntity } from '../schemas/nlp-entity.schema'; import { @@ -27,7 +31,8 @@ import { NlpEntityService } from './nlp-entity.service'; export class NlpValueService extends BaseService< NlpValue, NlpValuePopulate, - NlpValueFull + NlpValueFull, + NlpValueDto > { constructor( readonly repository: NlpValueRepository, diff --git a/api/src/user/dto/permission.dto.ts b/api/src/user/dto/permission.dto.ts index af4e7ce9..41966e99 100644 --- a/api/src/user/dto/permission.dto.ts +++ b/api/src/user/dto/permission.dto.ts @@ -7,8 +7,9 @@ */ import { ApiProperty } from '@nestjs/swagger'; -import { IsEnum, IsNotEmpty, IsString, IsOptional } from 'class-validator'; +import { IsEnum, IsNotEmpty, IsOptional, IsString } from 'class-validator'; +import { DtoConfig } from '@/utils/types/dto.types'; import { IsObjectId } from '@/utils/validation-rules/is-object-id'; import { Action } from '../types/action.type'; @@ -40,3 +41,7 @@ export class PermissionCreateDto { @IsOptional() relation?: TRelation; } + +export type PermissionDto = DtoConfig<{ + create: PermissionCreateDto; +}>; diff --git a/api/src/user/dto/role.dto.ts b/api/src/user/dto/role.dto.ts index bc3f33e1..a830dac7 100644 --- a/api/src/user/dto/role.dto.ts +++ b/api/src/user/dto/role.dto.ts @@ -9,6 +9,8 @@ import { ApiProperty, ApiPropertyOptional, PartialType } from '@nestjs/swagger'; import { IsBoolean, IsNotEmpty, IsOptional, IsString } from 'class-validator'; +import { DtoConfig } from '@/utils/types/dto.types'; + export class RoleCreateDto { @ApiProperty({ description: 'Name of the role', type: String }) @IsNotEmpty() @@ -26,3 +28,7 @@ export class RoleCreateDto { } export class RoleUpdateDto extends PartialType(RoleCreateDto) {} + +export type RoleDto = DtoConfig<{ + create: RoleCreateDto; +}>; diff --git a/api/src/user/dto/user.dto.ts b/api/src/user/dto/user.dto.ts index 2b082b6e..8ac4dada 100644 --- a/api/src/user/dto/user.dto.ts +++ b/api/src/user/dto/user.dto.ts @@ -22,6 +22,7 @@ import { IsString, } from 'class-validator'; +import { DtoConfig } from '@/utils/types/dto.types'; import { IsObjectId } from '@/utils/validation-rules/is-object-id'; export class UserCreateDto { @@ -61,12 +62,21 @@ export class UserCreateDto { @IsString() @IsObjectId({ message: 'Avatar must be a valid ObjectId' }) avatar: string | null = null; + + @ApiPropertyOptional({ + description: 'User state', + type: Boolean, + }) + @IsOptional() + @IsBoolean() + state?: boolean; } export class UserEditProfileDto extends OmitType(PartialType(UserCreateDto), [ 'username', 'roles', 'avatar', + 'state', ]) { @ApiPropertyOptional({ description: 'User language', type: String }) @IsOptional() @@ -98,3 +108,7 @@ export class UserResetPasswordDto extends PickType(UserCreateDto, [ ]) {} export class UserRequestResetDto extends PickType(UserCreateDto, ['email']) {} + +export type UserDto = DtoConfig<{ + create: UserCreateDto; +}>; diff --git a/api/src/user/repositories/permission.repository.ts b/api/src/user/repositories/permission.repository.ts index 692aa7fd..dff4f5d0 100644 --- a/api/src/user/repositories/permission.repository.ts +++ b/api/src/user/repositories/permission.repository.ts @@ -13,6 +13,7 @@ import { Model } from 'mongoose'; import { BaseRepository } from '@/utils/generics/base-repository'; +import { PermissionDto } from '../dto/permission.dto'; import { Permission, PERMISSION_POPULATE, @@ -24,7 +25,8 @@ import { export class PermissionRepository extends BaseRepository< Permission, PermissionPopulate, - PermissionFull + PermissionFull, + PermissionDto > { constructor( readonly eventEmitter: EventEmitter2, diff --git a/api/src/user/repositories/role.repository.ts b/api/src/user/repositories/role.repository.ts index 2208fa90..3d6c3668 100644 --- a/api/src/user/repositories/role.repository.ts +++ b/api/src/user/repositories/role.repository.ts @@ -13,6 +13,7 @@ import { Model } from 'mongoose'; import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository'; +import { RoleDto } from '../dto/role.dto'; import { Permission } from '../schemas/permission.schema'; import { Role, @@ -25,7 +26,8 @@ import { export class RoleRepository extends BaseRepository< Role, RolePopulate, - RoleFull + RoleFull, + RoleDto > { constructor( readonly eventEmitter: EventEmitter2, diff --git a/api/src/user/repositories/user.repository.ts b/api/src/user/repositories/user.repository.ts index e4a27f7b..4a361ee5 100644 --- a/api/src/user/repositories/user.repository.ts +++ b/api/src/user/repositories/user.repository.ts @@ -20,7 +20,7 @@ import { import { BaseRepository } from '@/utils/generics/base-repository'; import { TFilterQuery } from '@/utils/types/filter.types'; -import { UserEditProfileDto } from '../dto/user.dto'; +import { UserDto, UserEditProfileDto } from '../dto/user.dto'; import { User, USER_POPULATE, @@ -34,7 +34,8 @@ import { hash } from '../utilities/bcryptjs'; export class UserRepository extends BaseRepository< User, UserPopulate, - UserFull + UserFull, + UserDto > { constructor( readonly eventEmitter: EventEmitter2, diff --git a/api/src/user/schemas/permission.schema.ts b/api/src/user/schemas/permission.schema.ts index 9c87fe38..0af884aa 100644 --- a/api/src/user/schemas/permission.schema.ts +++ b/api/src/user/schemas/permission.schema.ts @@ -18,6 +18,7 @@ import { } from '@/utils/types/filter.types'; import { Action } from '../types/action.type'; +import { TRelation } from '../types/index.type'; import { Model } from './model.schema'; import { Role } from './role.schema'; @@ -41,7 +42,7 @@ export class PermissionStub extends BaseSchema { type: String, default: 'role', }) - relation?: string; + relation: TRelation; } @Schema({ timestamps: true }) diff --git a/api/src/user/schemas/role.schema.ts b/api/src/user/schemas/role.schema.ts index 64b8436f..81fcf8f8 100644 --- a/api/src/user/schemas/role.schema.ts +++ b/api/src/user/schemas/role.schema.ts @@ -31,7 +31,7 @@ export class RoleStub extends BaseSchema { name: string; @Prop({ type: Boolean, default: true }) - active?: boolean; + active: boolean; } @Schema({ timestamps: true }) diff --git a/api/src/user/schemas/user.schema.ts b/api/src/user/schemas/user.schema.ts index a97d2057..5d5755f0 100644 --- a/api/src/user/schemas/user.schema.ts +++ b/api/src/user/schemas/user.schema.ts @@ -50,6 +50,16 @@ export class UserStub extends BaseSchema { }) password: string; + @Prop([{ type: MongooseSchema.Types.ObjectId, ref: 'Role' }]) + roles: unknown; + + @Prop({ + type: MongooseSchema.Types.ObjectId, + ref: 'Attachment', + default: null, + }) + avatar: unknown; + @Prop({ type: Boolean, default: false, @@ -83,16 +93,6 @@ export class UserStub extends BaseSchema { }) resetCount?: number; - @Prop([{ type: MongooseSchema.Types.ObjectId, ref: 'Role' }]) - roles: unknown; - - @Prop({ - type: MongooseSchema.Types.ObjectId, - ref: 'Attachment', - default: null, - }) - avatar: unknown; - @Prop({ type: String, default: null, diff --git a/api/src/user/seeds/permission.seed.ts b/api/src/user/seeds/permission.seed.ts index 7492d2e8..f95da026 100644 --- a/api/src/user/seeds/permission.seed.ts +++ b/api/src/user/seeds/permission.seed.ts @@ -10,6 +10,7 @@ import { Injectable } from '@nestjs/common'; import { BaseSeeder } from '@/utils/generics/base-seeder'; +import { PermissionDto } from '../dto/permission.dto'; import { PermissionRepository } from '../repositories/permission.repository'; import { Permission, @@ -21,7 +22,8 @@ import { export class PermissionSeeder extends BaseSeeder< Permission, PermissionPopulate, - PermissionFull + PermissionFull, + PermissionDto > { constructor(private readonly permissionRepository: PermissionRepository) { super(permissionRepository); diff --git a/api/src/user/seeds/role.seed.ts b/api/src/user/seeds/role.seed.ts index d741c69a..4dd392c6 100644 --- a/api/src/user/seeds/role.seed.ts +++ b/api/src/user/seeds/role.seed.ts @@ -10,11 +10,17 @@ import { Injectable } from '@nestjs/common'; import { BaseSeeder } from '@/utils/generics/base-seeder'; +import { RoleDto } from '../dto/role.dto'; import { RoleRepository } from '../repositories/role.repository'; import { Role, RoleFull, RolePopulate } from '../schemas/role.schema'; @Injectable() -export class RoleSeeder extends BaseSeeder { +export class RoleSeeder extends BaseSeeder< + Role, + RolePopulate, + RoleFull, + RoleDto +> { constructor(private readonly roleRepository: RoleRepository) { super(roleRepository); } diff --git a/api/src/user/services/permission.service.ts b/api/src/user/services/permission.service.ts index 244c203f..f8b68349 100644 --- a/api/src/user/services/permission.service.ts +++ b/api/src/user/services/permission.service.ts @@ -15,6 +15,7 @@ import { PERMISSION_CACHE_KEY } from '@/utils/constants/cache'; import { Cacheable } from '@/utils/decorators/cacheable.decorator'; import { BaseService } from '@/utils/generics/base-service'; +import { PermissionDto } from '../dto/permission.dto'; import { PermissionRepository } from '../repositories/permission.repository'; import { Permission, @@ -27,7 +28,8 @@ import { PermissionsTree } from '../types/permission.type'; export class PermissionService extends BaseService< Permission, PermissionPopulate, - PermissionFull + PermissionFull, + PermissionDto > { constructor( readonly repository: PermissionRepository, diff --git a/api/src/user/services/role.service.ts b/api/src/user/services/role.service.ts index 16c4c70e..e6b16f79 100644 --- a/api/src/user/services/role.service.ts +++ b/api/src/user/services/role.service.ts @@ -10,11 +10,17 @@ import { Injectable } from '@nestjs/common'; import { BaseService } from '@/utils/generics/base-service'; +import { RoleDto } from '../dto/role.dto'; import { RoleRepository } from '../repositories/role.repository'; import { Role, RoleFull, RolePopulate } from '../schemas/role.schema'; @Injectable() -export class RoleService extends BaseService { +export class RoleService extends BaseService< + Role, + RolePopulate, + RoleFull, + RoleDto +> { constructor(readonly repository: RoleRepository) { super(repository); } diff --git a/api/src/user/services/user.service.ts b/api/src/user/services/user.service.ts index 39c2e57a..325479b4 100644 --- a/api/src/user/services/user.service.ts +++ b/api/src/user/services/user.service.ts @@ -10,11 +10,17 @@ import { Injectable } from '@nestjs/common'; import { BaseService } from '@/utils/generics/base-service'; +import { UserDto } from '../dto/user.dto'; import { UserRepository } from '../repositories/user.repository'; import { User, UserFull, UserPopulate } from '../schemas/user.schema'; @Injectable() -export class UserService extends BaseService { +export class UserService extends BaseService< + User, + UserPopulate, + UserFull, + UserDto +> { constructor(readonly repository: UserRepository) { super(repository); } diff --git a/api/src/utils/generics/base-controller.ts b/api/src/utils/generics/base-controller.ts index 13dfcbf2..b948d487 100644 --- a/api/src/utils/generics/base-controller.ts +++ b/api/src/utils/generics/base-controller.ts @@ -10,6 +10,7 @@ import { NotFoundException } from '@nestjs/common'; import { TFilterQuery } from '@/utils/types/filter.types'; +import { DtoConfig } from '../types/dto.types'; import { TValidateProps } from '../types/filter.types'; import { BaseSchema } from './base-schema'; @@ -20,8 +21,9 @@ export abstract class BaseController< TStub = never, P extends string = never, TFull extends Omit = never, + Dto extends DtoConfig = object, > { - constructor(protected readonly service: BaseService) {} + constructor(protected readonly service: BaseService) {} /** * Checks if the given populate fields are allowed based on the allowed fields list. diff --git a/api/src/utils/generics/base-repository.ts b/api/src/utils/generics/base-repository.ts index 65167f1f..e5137757 100644 --- a/api/src/utils/generics/base-repository.ts +++ b/api/src/utils/generics/base-repository.ts @@ -30,6 +30,7 @@ import { import { TFilterQuery } from '@/utils/types/filter.types'; import { PageQueryDto, QuerySortDto } from '../pagination/pagination-query.dto'; +import { DtoAction, DtoConfig, DtoInfer } from '../types/dto.types'; import { BaseSchema } from './base-schema'; import { LifecycleHookManager } from './lifecycle-hook-manager'; @@ -70,7 +71,8 @@ export abstract class BaseRepository< T extends FlattenMaps, P extends string = never, TFull extends Omit = never, - U = Omit, + Dto extends DtoConfig = object, + U extends Omit = Omit, D = Document, > { private readonly transformOpts = { excludePrefixes: ['_', 'password'] }; @@ -454,7 +456,7 @@ export abstract class BaseRepository< return await this.model.countDocuments(criteria).exec(); } - async create(dto: U): Promise { + async create(dto: DtoInfer): Promise { const doc = await this.model.create(dto); return plainToClass( @@ -464,7 +466,9 @@ export abstract class BaseRepository< ); } - async createMany(dtoArray: U[]): Promise { + async createMany( + dtoArray: DtoInfer[], + ): Promise { const docs = await this.model.create(dtoArray); return docs.map((doc) => diff --git a/api/src/utils/generics/base-seeder.ts b/api/src/utils/generics/base-seeder.ts index 139d1d2c..24e7315e 100644 --- a/api/src/utils/generics/base-seeder.ts +++ b/api/src/utils/generics/base-seeder.ts @@ -8,6 +8,8 @@ import { FlattenMaps } from 'mongoose'; +import { DtoAction, DtoConfig, DtoInfer } from '../types/dto.types'; + import { BaseRepository } from './base-repository'; import { BaseSchema } from './base-schema'; @@ -15,8 +17,12 @@ export abstract class BaseSeeder< T extends FlattenMaps, P extends string = never, TFull extends Omit = never, + Dto extends DtoConfig = object, + U extends Omit = Omit, > { - constructor(protected readonly repository: BaseRepository) {} + constructor( + protected readonly repository: BaseRepository, + ) {} async findAll(): Promise { return await this.repository.findAll(); @@ -27,7 +33,7 @@ export abstract class BaseSeeder< return count === 0; } - async seed(models: Omit[]): Promise { + async seed(models: DtoInfer[]): Promise { if (await this.isEmpty()) { await this.repository.createMany(models); return true; diff --git a/api/src/utils/generics/base-service.ts b/api/src/utils/generics/base-service.ts index 70ec686b..e0df7774 100644 --- a/api/src/utils/generics/base-service.ts +++ b/api/src/utils/generics/base-service.ts @@ -14,6 +14,7 @@ import { ProjectionType, QueryOptions } from 'mongoose'; import { TFilterQuery } from '@/utils/types/filter.types'; import { PageQueryDto, QuerySortDto } from '../pagination/pagination-query.dto'; +import { DtoAction, DtoConfig, DtoInfer } from '../types/dto.types'; import { BaseRepository } from './base-repository'; import { BaseSchema } from './base-schema'; @@ -22,8 +23,12 @@ export abstract class BaseService< T extends BaseSchema, P extends string = never, TFull extends Omit = never, + Dto extends DtoConfig = object, + U extends Omit = Omit, > { - constructor(protected readonly repository: BaseRepository) {} + constructor( + protected readonly repository: BaseRepository, + ) {} getRepository() { return this.repository; @@ -140,7 +145,7 @@ export abstract class BaseService< return await this.repository.count(criteria); } - async create>(dto: D): Promise { + async create(dto: DtoInfer): Promise { try { return await this.repository.create(dto); } catch (error) { @@ -153,9 +158,9 @@ export abstract class BaseService< } } - async findOneOrCreate>( + async findOneOrCreate( criteria: string | TFilterQuery, - dto: D, + dto: DtoInfer, ): Promise { const result = await this.findOne(criteria); if (!result) { @@ -164,24 +169,21 @@ export abstract class BaseService< return result; } - async createMany>( - dtoArray: D[], + async createMany( + dtoArray: DtoInfer[], ): Promise { return await this.repository.createMany(dtoArray); } - async updateOne>>( + async updateOne( criteria: string | TFilterQuery, - dto: D, - options?: QueryOptions | null, + dto: Partial, + options?: QueryOptions> | null, ): Promise { return await this.repository.updateOne(criteria, dto, options); } - async updateMany>>( - filter: TFilterQuery, - dto: D, - ) { + async updateMany(filter: TFilterQuery, dto: Partial) { return await this.repository.updateMany(filter, dto); } diff --git a/api/src/utils/test/fixtures/block.ts b/api/src/utils/test/fixtures/block.ts index b66611ce..0c124ab9 100644 --- a/api/src/utils/test/fixtures/block.ts +++ b/api/src/utils/test/fixtures/block.ts @@ -9,20 +9,34 @@ import mongoose from 'mongoose'; import { BlockCreateDto } from '@/chat/dto/block.dto'; -import { BlockModel, Block } from '@/chat/schemas/block.schema'; +import { Block, BlockModel } from '@/chat/schemas/block.schema'; import { CategoryModel } from '@/chat/schemas/category.schema'; import { FileType } from '@/chat/schemas/types/attachment'; import { ButtonType } from '@/chat/schemas/types/button'; import { QuickReplyType } from '@/chat/schemas/types/quick-reply'; import { getFixturesWithDefaultValues } from '../defaultValues'; -import { TFixturesDefaultValues } from '../types'; +import { FixturesTypeBuilder } from '../types'; -export const blocks: BlockCreateDto[] = [ +type TBlockFixtures = FixturesTypeBuilder; + +export const blockDefaultValues: TBlockFixtures['defaultValues'] = { + options: {}, + nextBlocks: [], + capture_vars: [], + assign_labels: [], + trigger_labels: [], + trigger_channels: [], + builtin: false, + starts_conversation: false, + attachedBlock: null, + attachedToBlock: null, +}; + +export const blocks: TBlockFixtures['values'][] = [ { name: 'hasNextBlocks', patterns: ['Hi'], - trigger_channels: [], category: null, options: { typing: 0, @@ -41,7 +55,6 @@ export const blocks: BlockCreateDto[] = [ { name: 'hasPreviousBlocks', patterns: ['colors'], - trigger_channels: [], category: null, options: { typing: 0, @@ -79,7 +92,6 @@ export const blocks: BlockCreateDto[] = [ { name: 'buttons', patterns: ['about'], - trigger_channels: [], category: null, options: { typing: 0, @@ -117,7 +129,6 @@ export const blocks: BlockCreateDto[] = [ { name: 'attachment', patterns: ['image'], - trigger_channels: [], category: null, options: { typing: 0, @@ -144,7 +155,6 @@ export const blocks: BlockCreateDto[] = [ { name: 'test', patterns: ['yes'], - trigger_channels: [], category: null, //to be verified options: { @@ -163,18 +173,9 @@ export const blocks: BlockCreateDto[] = [ }, ]; -export const blockDefaultValues: TFixturesDefaultValues = { - options: {}, - builtin: false, - nextBlocks: [], - capture_vars: [], - assign_labels: [], - trigger_labels: [], - starts_conversation: false, - attachedToBlock: null, -}; - -export const blockFixtures = getFixturesWithDefaultValues({ +export const blockFixtures = getFixturesWithDefaultValues< + TBlockFixtures['values'] +>({ fixtures: blocks, defaultValues: blockDefaultValues, }); diff --git a/api/src/utils/test/fixtures/category.ts b/api/src/utils/test/fixtures/category.ts index 2bb0f6c5..0c77070e 100644 --- a/api/src/utils/test/fixtures/category.ts +++ b/api/src/utils/test/fixtures/category.ts @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Hexastack. All rights reserved. + * Copyright © 2025 Hexastack. All rights reserved. * * Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms: * 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission. @@ -9,12 +9,23 @@ import mongoose from 'mongoose'; import { CategoryCreateDto } from '@/chat/dto/category.dto'; -import { CategoryModel, Category } from '@/chat/schemas/category.schema'; +import { Category, CategoryModel } from '@/chat/schemas/category.schema'; import { getFixturesWithDefaultValues } from '../defaultValues'; -import { TFixturesDefaultValues } from '../types'; +import { FixturesTypeBuilder } from '../types'; -export const categories: CategoryCreateDto[] = [ +export type TCategoryFixtures = FixturesTypeBuilder< + Category, + CategoryCreateDto +>; + +export const categoryDefaultValues: TCategoryFixtures['defaultValues'] = { + builtin: false, + zoom: 100, + offset: [0, 0], +}; + +export const categories: TCategoryFixtures['values'][] = [ { label: 'test category 1', }, @@ -23,13 +34,9 @@ export const categories: CategoryCreateDto[] = [ }, ]; -export const categoryDefaultValues: TFixturesDefaultValues = { - builtin: false, - zoom: 100, - offset: [0, 0], -}; - -export const categoryFixtures = getFixturesWithDefaultValues({ +export const categoryFixtures = getFixturesWithDefaultValues< + TCategoryFixtures['values'] +>({ fixtures: categories, defaultValues: categoryDefaultValues, }); diff --git a/api/src/utils/test/fixtures/content.ts b/api/src/utils/test/fixtures/content.ts index 33c3d379..ddf46a4d 100644 --- a/api/src/utils/test/fixtures/content.ts +++ b/api/src/utils/test/fixtures/content.ts @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Hexastack. All rights reserved. + * Copyright © 2025 Hexastack. All rights reserved. * * Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms: * 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission. @@ -12,12 +12,18 @@ import { ContentCreateDto } from '@/cms/dto/content.dto'; import { Content, ContentModel } from '@/cms/schemas/content.schema'; import { getFixturesWithDefaultValues } from '../defaultValues'; -import { TFixturesDefaultValues } from '../types'; +import { FixturesTypeBuilder } from '../types'; import { installAttachmentFixtures } from './attachment'; import { installContentTypeFixtures } from './contenttype'; -const contents: ContentCreateDto[] = [ +type TContentFixtures = FixturesTypeBuilder; + +export const contentDefaultValues: TContentFixtures['defaultValues'] = { + status: true, +}; + +const contents: TContentFixtures['values'][] = [ { title: 'Jean', dynamicFields: { @@ -131,14 +137,11 @@ const contents: ContentCreateDto[] = [ }, ]; -export const categoryDefaultValues: TFixturesDefaultValues = { - status: true, - createdAt: undefined, -}; - -export const contentFixtures = getFixturesWithDefaultValues({ +export const contentFixtures = getFixturesWithDefaultValues< + TContentFixtures['values'] +>({ fixtures: contents, - defaultValues: categoryDefaultValues, + defaultValues: contentDefaultValues, }); export const installContentFixtures = async () => { diff --git a/api/src/utils/test/fixtures/contenttype.ts b/api/src/utils/test/fixtures/contenttype.ts index 764e554f..8c295b05 100644 --- a/api/src/utils/test/fixtures/contenttype.ts +++ b/api/src/utils/test/fixtures/contenttype.ts @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Hexastack. All rights reserved. + * Copyright © 2025 Hexastack. All rights reserved. * * Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms: * 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission. @@ -15,9 +15,29 @@ import { } from '@/cms/schemas/content-type.schema'; import { getFixturesWithDefaultValues } from '../defaultValues'; -import { TFixturesDefaultValues } from '../types'; +import { FixturesTypeBuilder } from '../types'; -const contentTypes: ContentTypeCreateDto[] = [ +type TContentTypeFixtures = FixturesTypeBuilder< + ContentType, + ContentTypeCreateDto +>; + +export const contentTypeDefaultValues: TContentTypeFixtures['defaultValues'] = { + fields: [ + { + name: 'title', + label: 'Title', + type: 'text', + }, + { + name: 'status', + label: 'Status', + type: 'checkbox', + }, + ], +}; + +const contentTypes: TContentTypeFixtures['values'][] = [ { name: 'Product', fields: [ @@ -100,22 +120,9 @@ const contentTypes: ContentTypeCreateDto[] = [ }, ]; -export const contentTypeDefaultValues: TFixturesDefaultValues = { - fields: [ - { - name: 'title', - label: 'Title', - type: 'text', - }, - { - name: 'status', - label: 'Status', - type: 'checkbox', - }, - ], -}; - -export const contentTypeFixtures = getFixturesWithDefaultValues({ +export const contentTypeFixtures = getFixturesWithDefaultValues< + TContentTypeFixtures['values'] +>({ fixtures: contentTypes, defaultValues: contentTypeDefaultValues, }); diff --git a/api/src/utils/test/fixtures/contextvar.ts b/api/src/utils/test/fixtures/contextvar.ts index be325061..6cb188f9 100644 --- a/api/src/utils/test/fixtures/contextvar.ts +++ b/api/src/utils/test/fixtures/contextvar.ts @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Hexastack. All rights reserved. + * Copyright © 2025 Hexastack. All rights reserved. * * Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms: * 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission. @@ -9,25 +9,33 @@ import mongoose from 'mongoose'; import { ContextVarCreateDto } from '@/chat/dto/context-var.dto'; -import { ContextVarModel, ContextVar } from '@/chat/schemas/context-var.schema'; +import { ContextVar, ContextVarModel } from '@/chat/schemas/context-var.schema'; import { getFixturesWithDefaultValues } from '../defaultValues'; +import { FixturesTypeBuilder } from '../types'; -const contextVars: ContextVarCreateDto[] = [ +type TContentVarFixtures = FixturesTypeBuilder; + +export const contentVarDefaultValues: TContentVarFixtures['defaultValues'] = { + permanent: false, +}; + +const contextVars: TContentVarFixtures['values'][] = [ { label: 'test context var 1', name: 'test1', - permanent: false, }, { label: 'test context var 2', name: 'test2', - permanent: false, }, ]; -export const contextVarFixtures = getFixturesWithDefaultValues({ +export const contextVarFixtures = getFixturesWithDefaultValues< + TContentVarFixtures['values'] +>({ fixtures: contextVars, + defaultValues: contentVarDefaultValues, }); export const installContextVarFixtures = async () => { diff --git a/api/src/utils/test/fixtures/conversation.ts b/api/src/utils/test/fixtures/conversation.ts index 548a84b2..fca24ce1 100644 --- a/api/src/utils/test/fixtures/conversation.ts +++ b/api/src/utils/test/fixtures/conversation.ts @@ -9,10 +9,7 @@ import mongoose from 'mongoose'; import { ConversationCreateDto } from '@/chat/dto/conversation.dto'; -import { - Conversation, - ConversationModel, -} from '@/chat/schemas/conversation.schema'; +import { ConversationModel } from '@/chat/schemas/conversation.schema'; import { getFixturesWithDefaultValues } from '../defaultValues'; import { TFixturesDefaultValues } from '../types'; @@ -116,14 +113,16 @@ const conversations: ConversationCreateDto[] = [ }, ]; -export const conversationDefaultValues: TFixturesDefaultValues = { - active: false, -}; +export const conversationDefaultValues: TFixturesDefaultValues = + { + active: false, + }; -export const conversationFixtures = getFixturesWithDefaultValues({ - fixtures: conversations, - defaultValues: conversationDefaultValues, -}); +export const conversationFixtures = + getFixturesWithDefaultValues({ + fixtures: conversations, + defaultValues: conversationDefaultValues, + }); export const installConversationTypeFixtures = async () => { const subscribers = await installSubscriberFixtures(); diff --git a/api/src/utils/test/fixtures/label.ts b/api/src/utils/test/fixtures/label.ts index c38f5215..7621272a 100644 --- a/api/src/utils/test/fixtures/label.ts +++ b/api/src/utils/test/fixtures/label.ts @@ -1,5 +1,5 @@ /* - * Copyright © 2024 Hexastack. All rights reserved. + * Copyright © 2025 Hexastack. All rights reserved. * * Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms: * 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission. @@ -12,9 +12,15 @@ import { LabelCreateDto } from '@/chat/dto/label.dto'; import { Label, LabelModel } from '@/chat/schemas/label.schema'; import { getFixturesWithDefaultValues } from '../defaultValues'; -import { TFixturesDefaultValues } from '../types'; +import { FixturesTypeBuilder } from '../types'; -export const labels: LabelCreateDto[] = [ +type TLabelFixtures = FixturesTypeBuilder; + +export const contentLabelDefaultValues: TLabelFixtures['defaultValues'] = { + builtin: false, +}; + +export const labels: TLabelFixtures['values'][] = [ { description: 'test description 1', label_id: { @@ -39,13 +45,11 @@ export const labels: LabelCreateDto[] = [ }, ]; -export const labelDefaultValues: TFixturesDefaultValues