diff --git a/package.json b/package.json index 2a22522..04423c3 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,6 @@ "@fastify/multipart": "^8.3.0", "@fastify/static": "^7.0.4", "@fastify/swagger": "^8.14.0", - "class-transformer": "^0.5.1", "deep-equal": "^2.2.3", "fastest-validator": "^1.18.0", "fastify": "^4.28.0", @@ -103,7 +102,7 @@ "tslib": "^2.6.3" }, "devDependencies": { - "@hexancore/common": "0.16.1", + "@hexancore/common": "0.16.2", "@hexancore/mocker": "^1.1.2", "@nestjs/cli": "^10.3.2", "@nestjs/common": "^10.3.9", diff --git a/src/Application/DefaultGeneralBus.ts b/src/Application/DefaultGeneralBus.ts index 45a58fe..f122d26 100644 --- a/src/Application/DefaultGeneralBus.ts +++ b/src/Application/DefaultGeneralBus.ts @@ -1,7 +1,15 @@ -import { AR, ARW, OKA, AnyHCommand, AnyHQuery, AnyHEvent } from '@hexancore/common'; +import { + type AR, + ARW, + type AnyHCommand, + type AnyHQuery, + type HEvent, + type HCommandAsyncResultType, + type HQueryAsyncResultType +} from '@hexancore/common'; import { Injectable } from '@nestjs/common'; import { CommandBus, EventBus, QueryBus } from '@nestjs/cqrs'; -import { GeneralBus, type HCommandHandleResult, type HQueryHandleResult } from './GeneralBus'; +import { GeneralBus } from './GeneralBus'; @Injectable() export class DefaultGeneralBus extends GeneralBus { @@ -16,15 +24,15 @@ export class DefaultGeneralBus extends GeneralBus { this.queryBus = queryBus; } - public handleCommand(command: T): HCommandHandleResult { + public handleCommand(command: T): HCommandAsyncResultType { return ARW(this.commandBus.execute(command)) as any; } - public handleEvent(event: AnyHEvent): AR { + public handleEvent(event: HEvent): AR { return ARW(this.eventBus.publish(event)).mapToTrue(); } - public handleQuery(query: T): HQueryHandleResult { + public handleQuery(query: T): HQueryAsyncResultType { return ARW(this.queryBus.execute(query)) as any; } } diff --git a/src/Application/GeneralBus.ts b/src/Application/GeneralBus.ts index f5cdd7a..81d6e0b 100644 --- a/src/Application/GeneralBus.ts +++ b/src/Application/GeneralBus.ts @@ -1,18 +1,15 @@ import { - AR, - AnyHCommand, - ExtractHCommandResultValueType, - AnyHQuery, - ExtractHQueryResultValueType, - AnyHEvent + type AR, + type AnyHCommand, + type HEvent, + type AnyHQuery, + type HCommandAsyncResultType, + type HQueryAsyncResultType } from '@hexancore/common'; -export type HCommandHandleResult = AR>; -export type HQueryHandleResult = AR>; - export abstract class GeneralBus { - public abstract handleCommand(command: T): HCommandHandleResult; - public abstract handleEvent(event: AnyHEvent): AR; - public abstract handleQuery(query: T): HQueryHandleResult; + public abstract handleCommand(command: T): HCommandAsyncResultType; + public abstract handleEvent(event: HEvent): AR; + public abstract handleQuery(query: T): HQueryAsyncResultType; } diff --git a/src/Application/HCommandHandler.ts b/src/Application/HCommandHandler.ts new file mode 100644 index 0000000..7f7743d --- /dev/null +++ b/src/Application/HCommandHandler.ts @@ -0,0 +1,10 @@ +import { ICommandHandler } from "@nestjs/cqrs"; +import { type AnyHCommand, type HCommandResultType, type HCommandAsyncResultType, type HCommandAsyncResultPromiseType } from "@hexancore/common"; + +export abstract class HCommandHandler implements ICommandHandler> { + public execute(command: T): HCommandAsyncResultPromiseType { + return this.handle(command).p; + } + + protected abstract handle(command: T): HCommandAsyncResultType; +} \ No newline at end of file diff --git a/src/Application/HEventHandler.ts b/src/Application/HEventHandler.ts new file mode 100644 index 0000000..3ac597b --- /dev/null +++ b/src/Application/HEventHandler.ts @@ -0,0 +1,6 @@ +import { type IEventHandler } from "@nestjs/cqrs"; +import { type HEvent, type AR } from "@hexancore/common"; + +export abstract class HEventHandler implements IEventHandler { + public abstract handle(event: T): AR; +} \ No newline at end of file diff --git a/src/Application/HQueryHandler.ts b/src/Application/HQueryHandler.ts new file mode 100644 index 0000000..00caaca --- /dev/null +++ b/src/Application/HQueryHandler.ts @@ -0,0 +1,10 @@ +import { type AnyHQuery, HQueryResultType, HQueryAsyncResultType } from "@hexancore/common"; +import { type IQueryHandler } from "@nestjs/cqrs"; + +export abstract class HQueryHandler implements IQueryHandler> { + public execute(query: T): Promise> { + return this.handle(query).p; + } + + protected abstract handle(query: T): HQueryAsyncResultType; +} \ No newline at end of file diff --git a/src/Compiler/Transformer/Feature/HObject/HObjectParseTsFactory.ts b/src/Compiler/Transformer/Feature/HObject/HObjectParseTsFactory.ts index 17c762c..c17238d 100644 --- a/src/Compiler/Transformer/Feature/HObject/HObjectParseTsFactory.ts +++ b/src/Compiler/Transformer/Feature/HObject/HObjectParseTsFactory.ts @@ -1,5 +1,5 @@ -import ts, { type Identifier } from "typescript"; +import ts from "typescript"; import type { HObjectPropertyTsMeta } from "./HObjectPropertyTsMeta"; import type { ImportDeclarationWrapper } from "../../Helper/ImportDeclarationWrapper"; diff --git a/src/Domain/Entity/AbstractAggregateRoot.ts b/src/Domain/Entity/AbstractAggregateRoot.ts index 06a13e2..0ec2eca 100644 --- a/src/Domain/Entity/AbstractAggregateRoot.ts +++ b/src/Domain/Entity/AbstractAggregateRoot.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/ban-types */ -import { AbstractValueObject } from '@hexancore/common'; +import { HValueObject } from '@hexancore/common'; import { AbstractEntityCommon } from './AbstractEntityCommon'; import { AbstractEntity } from './AbstractEntity'; @@ -10,4 +10,4 @@ export type AggregateRootConstructor> extends AbstractEntityCommon {} +export abstract class AbstractAggregateRoot extends AbstractEntityCommon {} diff --git a/src/Domain/Entity/AbstractEntity.ts b/src/Domain/Entity/AbstractEntity.ts index 56a77af..dc868e0 100644 --- a/src/Domain/Entity/AbstractEntity.ts +++ b/src/Domain/Entity/AbstractEntity.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/ban-types */ -import { AbstractValueObject } from '@hexancore/common'; +import { HValueObject } from '@hexancore/common'; import { AbstractAggregateRoot, AggregateRootConstructor } from './AbstractAggregateRoot'; import { AbstractEntityCommon, EntityIdTypeOf } from './AbstractEntityCommon'; import { ENTITY_META_PROPERTY } from './EntityDecorator'; @@ -21,7 +21,7 @@ export type EntityConstructor = new (...args: a /** * Base for create Entity attached to selected AggregateRoot type in domain. */ -export abstract class AbstractEntity, ART extends AbstractAggregateRoot> extends AbstractEntityCommon { +export abstract class AbstractEntity> extends AbstractEntityCommon { public getAggregateRootClass(): AggregateRootConstructor { return this.constructor[ENTITY_META_PROPERTY].aggregateRoot; } diff --git a/src/Domain/Entity/AbstractEntityCommon.ts b/src/Domain/Entity/AbstractEntityCommon.ts index 4989260..33ac614 100644 --- a/src/Domain/Entity/AbstractEntityCommon.ts +++ b/src/Domain/Entity/AbstractEntityCommon.ts @@ -1,4 +1,4 @@ -import { AbstractValueObject } from '@hexancore/common'; +import { HValueObject } from '@hexancore/common'; /** * Entity Id type alias @@ -9,7 +9,7 @@ export type EntityIdTypeOf> = T extends Abst * Common base of Entity and AggregateRoot * Can track changes in entity for use in persistance libs */ -export abstract class AbstractEntityCommon> { +export abstract class AbstractEntityCommon { /** * Entity id */ diff --git a/src/Infrastructure/Http/Controller/AbstractAppController.ts b/src/Infrastructure/Http/Controller/AbstractAppController.ts index 3c330a6..ea61ec3 100644 --- a/src/Infrastructure/Http/Controller/AbstractAppController.ts +++ b/src/Infrastructure/Http/Controller/AbstractAppController.ts @@ -1,5 +1,10 @@ -import { AnyHCommand, AnyHQuery } from '@hexancore/common'; -import { GeneralBus, type HCommandHandleResult, type HQueryHandleResult } from '../../../Application'; +import { + type AnyHCommand, + type AnyHQuery, + type HCommandAsyncResultType, + type HQueryAsyncResultType +} from '@hexancore/common'; +import { GeneralBus } from '../../../Application'; import { Inject } from '@nestjs/common'; import { AbstractController } from './AbstractController'; @@ -8,11 +13,11 @@ export abstract class AbstractAppController extends AbstractController { super(); } - protected handleCommand(command: T): HCommandHandleResult { + protected handleCommand(command: T): HCommandAsyncResultType { return this.gb.handleCommand(command); } - protected handleQuery(query: T): HQueryHandleResult { + protected handleQuery(query: T): HQueryAsyncResultType { return this.gb.handleQuery(query); } } diff --git a/src/Infrastructure/Http/Controller/AbstractController.ts b/src/Infrastructure/Http/Controller/AbstractController.ts index bd7b47f..94998a3 100644 --- a/src/Infrastructure/Http/Controller/AbstractController.ts +++ b/src/Infrastructure/Http/Controller/AbstractController.ts @@ -2,7 +2,7 @@ import { OK, type R } from "@hexancore/common"; import { HttpStatus } from "@nestjs/common"; import { RedirectResult } from "../RedirectResult"; -export class AbstractController { +export abstract class AbstractController { protected redirect(url: string, statusCode: HttpStatus = HttpStatus.FOUND): R { return OK(RedirectResult.create(url, statusCode)); diff --git a/src/Infrastructure/Persistence/Domain/Memory/MemoryEntityPersister.ts b/src/Infrastructure/Persistence/Domain/Memory/MemoryEntityPersister.ts index cb9d18a..cc15ad8 100644 --- a/src/Infrastructure/Persistence/Domain/Memory/MemoryEntityPersister.ts +++ b/src/Infrastructure/Persistence/Domain/Memory/MemoryEntityPersister.ts @@ -1,5 +1,5 @@ import { AbstractEntityCommon, EntityMetaCommon, EntityIdTypeOf } from '@/Domain'; -import { AR, AbstractValueObject, AsyncResult, CurrentTime, OK, OKA, wrapToArray } from '@hexancore/common'; +import { AR, HValueObject, AsyncResult, CurrentTime, OK, OKA, wrapToArray } from '@hexancore/common'; import { AbstractEntityPersister, AbstractEntityRepositoryCommon } from '../Generic'; export const MEMORY_PERSISTER_TYPE = "memory"; @@ -88,7 +88,7 @@ export class MemoryEntityPersister, M extend public getBy(criteria: Record): AR { const result = this.persisted.filter((e) => { for (const prop in criteria) { - if (criteria[prop] instanceof AbstractValueObject) { + if (criteria[prop] instanceof HValueObject) { if (!criteria[prop].equals(e[prop])) { return false; } diff --git a/src/Test/Application/MockGeneralBus.ts b/src/Test/Application/MockGeneralBus.ts index c1b485e..fcffd72 100644 --- a/src/Test/Application/MockGeneralBus.ts +++ b/src/Test/Application/MockGeneralBus.ts @@ -1,8 +1,15 @@ -import { AR, OKA, AnyHCommand, AnyHQuery, AnyHEvent } from '@hexancore/common'; +import { + AR, + OKA, + AnyHCommand, + AnyHQuery, + HEvent, + type HCommandAsyncResultType, + type HQueryAsyncResultType +} from '@hexancore/common'; import { Injectable } from '@nestjs/common'; import { IEvent } from '@nestjs/cqrs'; import deepEqual from 'deep-equal'; -import type { HCommandHandleResult, HQueryHandleResult } from "../../Application"; import { GeneralBus } from '../../Application/GeneralBus'; interface HandleExpectation { @@ -23,28 +30,28 @@ export class MockGeneralBus extends GeneralBus { this.queriesToHandle = []; } - public expectHandleCommand(command: T, result: HCommandHandleResult): void { + public expectHandleCommand(command: T, result: HCommandAsyncResultType): void { this.commandsToHandle.unshift({ message: command as any, result }); } - public expectHandleEvent(event: AnyHEvent | ((event: AnyHEvent) => boolean)): void { + public expectHandleEvent(event: HEvent | ((event: HEvent) => boolean)): void { this.eventsToHandle.unshift(event); } - public expectHandleQuery(query: T, result: HQueryHandleResult): void { + public expectHandleQuery(query: T, result: HQueryAsyncResultType): void { this.queriesToHandle.unshift({ message: query as any, result }); } - public handleCommand(command: T): HCommandHandleResult { + public handleCommand(command: T): HCommandAsyncResultType { const expectation = this.commandsToHandle.pop(); if (expectation && deepEqual(expectation.message, command)) { - return expectation.result; + return expectation.result as any; } throw new Error('Unexpected command to handle: ' + command.constructor.name + ' ' + JSON.stringify(command, null, 1)); } - public handleEvent(event: AnyHEvent): AR { + public handleEvent(event: HEvent): AR { const expectation = this.eventsToHandle.pop(); if (typeof expectation == 'function') { if (!expectation(event)) { @@ -57,10 +64,10 @@ export class MockGeneralBus extends GeneralBus { return OKA(true); } - public handleQuery(query: T): HQueryHandleResult { + public handleQuery(query: T): HQueryAsyncResultType { const expectation = this.queriesToHandle.pop(); if (expectation && deepEqual(expectation.message, query)) { - return expectation.result; + return expectation.result as any; } throw new Error('Unexpected query to handle: ' + query.constructor.name + ' ' + JSON.stringify(query, null, 1)); diff --git a/test/helper/libs/test-lib/src/Book/Application/Book/Command/Create/BookCreateCommand.ts b/test/helper/libs/test-lib/src/Book/Application/Book/Command/Create/BookCreateCommand.ts index 631d6f2..4a9fa76 100644 --- a/test/helper/libs/test-lib/src/Book/Application/Book/Command/Create/BookCreateCommand.ts +++ b/test/helper/libs/test-lib/src/Book/Application/Book/Command/Create/BookCreateCommand.ts @@ -1,5 +1,7 @@ import { HCommand } from "@hexancore/common"; +import { BookDto } from "../../Dto/BookDto"; -export class BookCreateCommand extends HCommand { +export class BookCreateCommand extends HCommand { public title!: string; -} + +} \ No newline at end of file diff --git a/test/helper/libs/test-lib/src/Book/Application/Book/Command/Create/BookCreateCommandHandler.ts b/test/helper/libs/test-lib/src/Book/Application/Book/Command/Create/BookCreateCommandHandler.ts index a36882d..c996641 100644 --- a/test/helper/libs/test-lib/src/Book/Application/Book/Command/Create/BookCreateCommandHandler.ts +++ b/test/helper/libs/test-lib/src/Book/Application/Book/Command/Create/BookCreateCommandHandler.ts @@ -1,14 +1,18 @@ -import { CommandHandler, type ICommandHandler } from "@nestjs/cqrs"; -import { BookCreateCommand } from "./BookCreateCommand"; -import { OKAP, type ARP } from "@hexancore/common"; +import { HCommandHandler } from "@/Application/HCommandHandler"; +import { OKA, ERRA, type HCommandAsyncResultType } from "@hexancore/common"; import { BookDto } from "../../Dto/BookDto"; +import { BookCreateCommand } from "./BookCreateCommand"; +import { CommandHandler } from "@nestjs/cqrs"; @CommandHandler(BookCreateCommand) -export class BookCreateCommandHandler implements ICommandHandler { - public execute(command: BookCreateCommand): ARP { - return OKAP(BookDto.cs({ - title: command.title, +export class BookCreateCommandHandler extends HCommandHandler { + protected handle(command: BookCreateCommand): HCommandAsyncResultType { + if (command.title === "error") { + return ERRA("error"); + } + return OKA(BookDto.cs({ + title: command.title, })); } } \ No newline at end of file diff --git a/test/helper/libs/test-lib/src/Book/Application/Book/Dto/ArrayItemsTestDto.ts b/test/helper/libs/test-lib/src/Book/Application/Book/Dto/ArrayItemsTestDto.ts index a761f4c..c43728b 100644 --- a/test/helper/libs/test-lib/src/Book/Application/Book/Dto/ArrayItemsTestDto.ts +++ b/test/helper/libs/test-lib/src/Book/Application/Book/Dto/ArrayItemsTestDto.ts @@ -1,11 +1,11 @@ import { Dto, v } from '@hexancore/common'; -export class ArrayItemsTestDto extends Dto { +export class ArrayItemsTestDto extends Dto { public arrayMinItemsField!: v.int[] & v.items.min<2>; public arrayMaxItemsField!: v.int[] & v.items.max<2>; public arrayExaclyItemsField!: v.int[] & v.items.exactly<2>; public arrayBetweenItemsField!: v.int[] & v.items.between<0, 2>; - + public optionalArrayItemsField?: v.int[] & v.items.min<2>; } \ No newline at end of file diff --git a/test/helper/libs/test-lib/src/Book/Application/Book/Dto/BookDto.ts b/test/helper/libs/test-lib/src/Book/Application/Book/Dto/BookDto.ts index e43ee9f..fdc93e6 100644 --- a/test/helper/libs/test-lib/src/Book/Application/Book/Dto/BookDto.ts +++ b/test/helper/libs/test-lib/src/Book/Application/Book/Dto/BookDto.ts @@ -1,5 +1,5 @@ import { Dto } from "@hexancore/common"; -export class BookDto extends Dto { +export class BookDto extends Dto { public title?: string; } \ No newline at end of file diff --git a/test/helper/libs/test-lib/src/Book/Application/Book/Dto/FloatTestDto.ts b/test/helper/libs/test-lib/src/Book/Application/Book/Dto/FloatTestDto.ts index ffc67e5..22c7ea0 100644 --- a/test/helper/libs/test-lib/src/Book/Application/Book/Dto/FloatTestDto.ts +++ b/test/helper/libs/test-lib/src/Book/Application/Book/Dto/FloatTestDto.ts @@ -1,6 +1,6 @@ import { Dto, v } from '@hexancore/common'; -export class FloatTestDto extends Dto { +export class FloatTestDto extends Dto { public field!: v.float; public optionalField?: v.float; diff --git a/test/helper/libs/test-lib/src/Book/Application/Book/Dto/IntTestDto.ts b/test/helper/libs/test-lib/src/Book/Application/Book/Dto/IntTestDto.ts index ba1b6dc..995efbc 100644 --- a/test/helper/libs/test-lib/src/Book/Application/Book/Dto/IntTestDto.ts +++ b/test/helper/libs/test-lib/src/Book/Application/Book/Dto/IntTestDto.ts @@ -1,6 +1,6 @@ import { Dto, v } from '@hexancore/common'; -export class IntTestDto extends Dto { +export class IntTestDto extends Dto { public field!: v.int; public optionalField?: v.int; diff --git a/test/helper/libs/test-lib/src/Book/Application/Book/Dto/StringTestDto.ts b/test/helper/libs/test-lib/src/Book/Application/Book/Dto/StringTestDto.ts index c62aebc..0b368a0 100644 --- a/test/helper/libs/test-lib/src/Book/Application/Book/Dto/StringTestDto.ts +++ b/test/helper/libs/test-lib/src/Book/Application/Book/Dto/StringTestDto.ts @@ -1,6 +1,6 @@ import { Dto, v } from '@hexancore/common'; -export class StringTestDto extends Dto { +export class StringTestDto extends Dto { public field!: string; public optionalField?: string; diff --git a/test/helper/libs/test-lib/src/Book/Application/Book/Dto/TestTransformDto.ts b/test/helper/libs/test-lib/src/Book/Application/Book/Dto/TestTransformDto.ts index ff6f6ae..e8fc11c 100644 --- a/test/helper/libs/test-lib/src/Book/Application/Book/Dto/TestTransformDto.ts +++ b/test/helper/libs/test-lib/src/Book/Application/Book/Dto/TestTransformDto.ts @@ -1,6 +1,6 @@ import { Dto, v, RefId } from '@hexancore/common'; -export class TestTransformDto extends Dto { +export class TestTransformDto extends Dto { public optionalStringField?: string; diff --git a/test/helper/libs/test-lib/src/Book/Application/Book/Dto/UIntTestDto.ts b/test/helper/libs/test-lib/src/Book/Application/Book/Dto/UIntTestDto.ts index cd29b36..a6a6abd 100644 --- a/test/helper/libs/test-lib/src/Book/Application/Book/Dto/UIntTestDto.ts +++ b/test/helper/libs/test-lib/src/Book/Application/Book/Dto/UIntTestDto.ts @@ -1,6 +1,6 @@ import { Dto, v } from '@hexancore/common'; -export class UIntTestDto extends Dto { +export class UIntTestDto extends Dto { public field!: v.uint; public optionalField?: v.uint; diff --git a/test/helper/libs/test-lib/src/Book/Application/Book/Query/GetById/BookGetByIdQuery.ts b/test/helper/libs/test-lib/src/Book/Application/Book/Query/GetById/BookGetByIdQuery.ts index 672ab61..e2cb9f3 100644 --- a/test/helper/libs/test-lib/src/Book/Application/Book/Query/GetById/BookGetByIdQuery.ts +++ b/test/helper/libs/test-lib/src/Book/Application/Book/Query/GetById/BookGetByIdQuery.ts @@ -1,6 +1,6 @@ import { HQuery } from "@hexancore/common"; import type { BookDto } from "../../Dto/BookDto"; -export class BookGetByIdQuery extends HQuery { +export class BookGetByIdQuery extends HQuery { public title!: string; } diff --git a/test/helper/libs/test-lib/src/Book/Application/Book/Query/GetById/BookGetByIdQueryHandler.ts b/test/helper/libs/test-lib/src/Book/Application/Book/Query/GetById/BookGetByIdQueryHandler.ts index 63d4e48..c72dd33 100644 --- a/test/helper/libs/test-lib/src/Book/Application/Book/Query/GetById/BookGetByIdQueryHandler.ts +++ b/test/helper/libs/test-lib/src/Book/Application/Book/Query/GetById/BookGetByIdQueryHandler.ts @@ -1,13 +1,18 @@ -import { OKAP, type ARP } from "@hexancore/common"; -import { CommandHandler, type IQueryHandler } from "@nestjs/cqrs"; +import { OKA, ERRA, type HQueryAsyncResultType } from "@hexancore/common"; +import { QueryHandler } from "@nestjs/cqrs"; import { BookGetByIdQuery } from "./BookGetByIdQuery"; import { BookDto } from "../../Dto/BookDto"; +import { HQueryHandler } from "@/Application/HQueryHandler"; -@CommandHandler(BookGetByIdQuery) -export class BookGetByIdQueryHandler implements IQueryHandler { - public execute(command: BookGetByIdQuery): ARP { - return OKAP(BookDto.cs({ - title: command.title +@QueryHandler(BookGetByIdQuery) +export class BookGetByIdQueryHandler extends HQueryHandler { + protected handle(query: BookGetByIdQuery): HQueryAsyncResultType { + if (query.title === "error") { + return ERRA("error"); + } + + return OKA(BookDto.cs({ + title: query.title, })); } } \ No newline at end of file diff --git a/test/helper/libs/test-lib/src/Book/BookModule.ts b/test/helper/libs/test-lib/src/Book/BookModule.ts index 9957dbe..491337f 100644 --- a/test/helper/libs/test-lib/src/Book/BookModule.ts +++ b/test/helper/libs/test-lib/src/Book/BookModule.ts @@ -5,10 +5,8 @@ import { BookInfraModule } from "./Infrastructure/BookInfraModule"; export const SOME_ASSIGMENT_NOISE = 10; - - @Module({ - imports: [BookInfraModule] + imports: [BookInfraModule], }) export class BookModule { } \ No newline at end of file diff --git a/test/helper/libs/test-lib/src/Book/Infrastructure/BookInfraModule.ts b/test/helper/libs/test-lib/src/Book/Infrastructure/BookInfraModule.ts index 7086786..254a240 100644 --- a/test/helper/libs/test-lib/src/Book/Infrastructure/BookInfraModule.ts +++ b/test/helper/libs/test-lib/src/Book/Infrastructure/BookInfraModule.ts @@ -11,7 +11,7 @@ export const BookInfraPortProvider = { @Module({ imports: [BookDomainInfraModule], providers: [ - BookInfraPortProvider + BookInfraPortProvider, ], exports: [BookInfraPortProvider, BookDomainInfraModule] }) diff --git a/test/integration/Application/DefaultGeneralBus.test.ts b/test/integration/Application/DefaultGeneralBus.test.ts new file mode 100644 index 0000000..a0ae64a --- /dev/null +++ b/test/integration/Application/DefaultGeneralBus.test.ts @@ -0,0 +1,121 @@ +/** + * @group unit/core + */ + +import { Email, HCommand, HEvent, HQuery, type JsonObjectType } from '@hexancore/common'; +import { GeneralBus } from '@/Application/GeneralBus'; +import { Test, TestingModule } from "@nestjs/testing"; +import { BookCreateCommand, BookGetByIdQuery, TestLibModule } from "@test/libs/test-lib/src"; +import { BookDto } from "@test/libs/test-lib/src/Book/Application/Book/Dto/BookDto"; +import { HcModule } from "@/HcModule"; +import { HcMemoryDomainInfraModule } from "@"; + +class TestCommand extends HCommand { + public constructor(public readonly email: Email) { + super(); + } + + public toJSON(): JsonObjectType { + return { + email: this.email.toJSON(), + } as any; + } +} + +class TestEvent extends HEvent { + public constructor(public readonly email: Email) { + super(); + } + + public toJSON(): JsonObjectType { + return { + email: this.email.toJSON(), + } as any; + } +} + +class TestQuery extends HQuery { + public constructor(public readonly email: Email) { + super(); + } + + public toJSON(): JsonObjectType { + return { + email: this.email.toJSON(), + } as any; + } +} + +describe("DefaultGeneralBus", () => { + let gb: GeneralBus; + let module: TestingModule; + + beforeAll(async () => { + module = await Test.createTestingModule({ + imports: [ + HcModule.forRoot(), + HcMemoryDomainInfraModule, + TestLibModule + ], + }).compile(); + await module.init(); + gb = module.get(GeneralBus); + }); + + afterAll(() => { + module?.close(); + }); + + describe('Command', () => { + test('when sucess', async () => { + const current = await gb.handleCommand(BookCreateCommand.cs({ title: "test" })); + + expect(current).toMatchSuccessResult(BookDto.cs({ title: "test" })); + }); + + test('when error', async () => { + const current = await gb.handleCommand(BookCreateCommand.cs({ title: "error" })); + + expect(current).toMatchAppError({ type: "error" }); + + }); + }); + + describe('Query', () => { + test('when sucess', async () => { + const current = await gb.handleQuery(BookGetByIdQuery.cs({ title: "test" })); + + expect(current).toMatchSuccessResult(BookDto.cs({ title: "test" })); + }); + + test('when error', async () => { + const current = await gb.handleQuery(BookGetByIdQuery.cs({ title: "error" })); + + expect(current).toMatchAppError({ type: "error" }); + + }); + }); + /* + describe('handleEvent', () => { + const event: TestEvent = new TestEvent(Email.cs('test@test.com')); + + test('when ok', async () => { + eventBus.expects('publish', event).andReturn(Promise.resolve()); + + const current = await gb.handleEvent(event); + + expect(current).toEqual(OK(true)); + }); + + test('when error', async () => { + eventBus.expects('publish', event).andReturnWith(async () => { throw new Error("test"); }); + + const current = await gb.handleEvent(event); + + expect(current).toEqual(INTERNAL_ERR(new Error("test"))); + }); + }); + + + */ +}); diff --git a/test/integration/Compiler/Transformer/HObject/__snapshots__/ArrayItemsRulesHObjectAOT.test.ts.snap b/test/integration/Compiler/Transformer/HObject/__snapshots__/ArrayItemsRulesHObjectAOT.test.ts.snap index e3d9383..d75e369 100644 --- a/test/integration/Compiler/Transformer/HObject/__snapshots__/ArrayItemsRulesHObjectAOT.test.ts.snap +++ b/test/integration/Compiler/Transformer/HObject/__snapshots__/ArrayItemsRulesHObjectAOT.test.ts.snap @@ -114,7 +114,7 @@ exports[`HObject.Rules.ArrayItems toJSON 1`] = ` exports[`HObject.Rules.ArrayItems transform 1`] = ` "import { Dto, v, R, OK, PlainParseHelper, IntegerPlainParseHelper, ArrayPlainParseHelper, StringPlainParseHelper, NumberPlainParseHelper, HObjectTypeMeta, type JsonObjectType, type PlainParseError, type PlainParseIssue, type AnyDto, type DtoType } from '@hexancore/common'; -export class ArrayItemsTestDto extends Dto { +export class ArrayItemsTestDto extends Dto { public static HOBJ_META = HObjectTypeMeta.application("Book", "Book", "Dto", "ArrayItemsTestDto", ArrayItemsTestDto); public arrayMinItemsField!: v.int[] & v.items.min<2>; public arrayMaxItemsField!: v.int[] & v.items.max<2>; diff --git a/test/integration/Compiler/Transformer/HObject/__snapshots__/HCommandAOT.test.ts.snap b/test/integration/Compiler/Transformer/HObject/__snapshots__/HCommandAOT.test.ts.snap index c792f80..d860ba2 100644 --- a/test/integration/Compiler/Transformer/HObject/__snapshots__/HCommandAOT.test.ts.snap +++ b/test/integration/Compiler/Transformer/HObject/__snapshots__/HCommandAOT.test.ts.snap @@ -46,7 +46,8 @@ exports[`HObject.HCommand toJSON 1`] = ` exports[`HObject.HCommand transform 1`] = ` "import { HCommand, R, OK, PlainParseHelper, IntegerPlainParseHelper, ArrayPlainParseHelper, StringPlainParseHelper, NumberPlainParseHelper, HObjectTypeMeta, type JsonObjectType, type PlainParseError, type PlainParseIssue, type AnyCommand, type CommandType } from "@hexancore/common"; -export class BookCreateCommand extends HCommand { +import { BookDto } from "../../Dto/BookDto"; +export class BookCreateCommand extends HCommand { public static HOBJ_META = HObjectTypeMeta.application("Book", "Book", "Command", "Create", BookCreateCommand); public title!: string; public constructor(title: any) { diff --git a/test/integration/Compiler/Transformer/HObject/__snapshots__/HQueryAOT.test.ts.snap b/test/integration/Compiler/Transformer/HObject/__snapshots__/HQueryAOT.test.ts.snap index a71f28e..2ba85c9 100644 --- a/test/integration/Compiler/Transformer/HObject/__snapshots__/HQueryAOT.test.ts.snap +++ b/test/integration/Compiler/Transformer/HObject/__snapshots__/HQueryAOT.test.ts.snap @@ -47,7 +47,7 @@ exports[`HObject.HQuery toJSON 1`] = ` exports[`HObject.HQuery transform 1`] = ` "import { HQuery, R, OK, PlainParseHelper, IntegerPlainParseHelper, ArrayPlainParseHelper, StringPlainParseHelper, NumberPlainParseHelper, HObjectTypeMeta, type JsonObjectType, type PlainParseError, type PlainParseIssue, type AnyQuery, type QueryType } from "@hexancore/common"; import type { BookDto } from "../../Dto/BookDto"; -export class BookGetByIdQuery extends HQuery { +export class BookGetByIdQuery extends HQuery { public static HOBJ_META = HObjectTypeMeta.application("Book", "Book", "Query", "GetById", BookGetByIdQuery); public title!: string; public constructor(title: any) { diff --git a/test/integration/Compiler/Transformer/HObject/__snapshots__/IntRulesHObjectAOT.test.ts.snap b/test/integration/Compiler/Transformer/HObject/__snapshots__/IntRulesHObjectAOT.test.ts.snap index a76a575..f18464b 100644 --- a/test/integration/Compiler/Transformer/HObject/__snapshots__/IntRulesHObjectAOT.test.ts.snap +++ b/test/integration/Compiler/Transformer/HObject/__snapshots__/IntRulesHObjectAOT.test.ts.snap @@ -170,7 +170,7 @@ exports[`HObject.Rules.Int toJSON 1`] = ` exports[`HObject.Rules.Int transform 1`] = ` "import { Dto, v, R, OK, PlainParseHelper, IntegerPlainParseHelper, ArrayPlainParseHelper, StringPlainParseHelper, NumberPlainParseHelper, HObjectTypeMeta, type JsonObjectType, type PlainParseError, type PlainParseIssue, type AnyDto, type DtoType } from '@hexancore/common'; -export class IntTestDto extends Dto { +export class IntTestDto extends Dto { public static HOBJ_META = HObjectTypeMeta.application("Book", "Book", "Dto", "IntTestDto", IntTestDto); public field!: v.int; public optionalField?: v.int; diff --git a/test/integration/Compiler/Transformer/HObject/__snapshots__/StringRulesHObjectAOT.test.ts.snap b/test/integration/Compiler/Transformer/HObject/__snapshots__/StringRulesHObjectAOT.test.ts.snap index 901d2b0..84f592a 100644 --- a/test/integration/Compiler/Transformer/HObject/__snapshots__/StringRulesHObjectAOT.test.ts.snap +++ b/test/integration/Compiler/Transformer/HObject/__snapshots__/StringRulesHObjectAOT.test.ts.snap @@ -146,7 +146,7 @@ exports[`HObject.Rules.String toJSON 1`] = ` exports[`HObject.Rules.String transform 1`] = ` "import { Dto, v, R, OK, PlainParseHelper, IntegerPlainParseHelper, ArrayPlainParseHelper, StringPlainParseHelper, NumberPlainParseHelper, HObjectTypeMeta, type JsonObjectType, type PlainParseError, type PlainParseIssue, type AnyDto, type DtoType } from '@hexancore/common'; -export class StringTestDto extends Dto { +export class StringTestDto extends Dto { public static HOBJ_META = HObjectTypeMeta.application("Book", "Book", "Dto", "StringTestDto", StringTestDto); public field!: string; public optionalField?: string; diff --git a/test/integration/Compiler/Transformer/HObject/__snapshots__/UIntRulesHObjectAOT.test.ts.snap b/test/integration/Compiler/Transformer/HObject/__snapshots__/UIntRulesHObjectAOT.test.ts.snap index 1d07769..035e285 100644 --- a/test/integration/Compiler/Transformer/HObject/__snapshots__/UIntRulesHObjectAOT.test.ts.snap +++ b/test/integration/Compiler/Transformer/HObject/__snapshots__/UIntRulesHObjectAOT.test.ts.snap @@ -171,7 +171,7 @@ exports[`HObject.Rules.UInt toJSON 1`] = ` exports[`HObject.Rules.UInt transform 1`] = ` "import { Dto, v, R, OK, PlainParseHelper, IntegerPlainParseHelper, ArrayPlainParseHelper, StringPlainParseHelper, NumberPlainParseHelper, HObjectTypeMeta, type JsonObjectType, type PlainParseError, type PlainParseIssue, type AnyDto, type DtoType } from '@hexancore/common'; -export class UIntTestDto extends Dto { +export class UIntTestDto extends Dto { public static HOBJ_META = HObjectTypeMeta.application("Book", "Book", "Dto", "UIntTestDto", UIntTestDto); public field!: v.uint; public optionalField?: v.uint; diff --git a/test/unit/Application/MockGeneralBus.test.ts b/test/unit/Application/MockGeneralBus.test.ts index d792629..3155472 100644 --- a/test/unit/Application/MockGeneralBus.test.ts +++ b/test/unit/Application/MockGeneralBus.test.ts @@ -5,32 +5,32 @@ import { Email, OK, OKA, JsonObjectType, HCommand,HQuery, HEvent } from '@hexancore/common'; import { MockGeneralBus } from '@/Test/Application/MockGeneralBus'; -class TestCommand extends HCommand { +class TestCommand extends HCommand { public readonly email!: Email; - public toJSON(): JsonObjectType { + public toJSON(): JsonObjectType { return { email: this.email.toJSON(), - }; + } as any; } } -class TestEvent extends HEvent { +class TestEvent extends HEvent { public readonly email!: Email; - public toJSON(): JsonObjectType { + public toJSON(): JsonObjectType { return { email: this.email.toJSON(), - }; + } as any; } } -class TestQuery extends HQuery { +class TestQuery extends HQuery { public readonly email!: Email; - public toJSON(): JsonObjectType { + public toJSON(): JsonObjectType { return { email: this.email.toJSON(), - }; + } as any; } } @@ -89,7 +89,7 @@ describe('MockGeneralBus', () => { }); test('handleEvent() when use function matcher and expected is correct', () => { - generalBus.expectHandleEvent((event: IEvent) => event instanceof TestEvent && event.email.v === 'test@test.com'); + generalBus.expectHandleEvent((event) => event instanceof TestEvent && event.email.v === 'test@test.com'); expect(() => generalBus.handleEvent(TestEvent.cs({ email: email }))).not.toThrow(); }); diff --git a/yarn.lock b/yarn.lock index 6455895..0d9ee4c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -671,21 +671,20 @@ __metadata: languageName: node linkType: hard -"@hexancore/common@npm:0.16.1": - version: 0.16.1 - resolution: "@hexancore/common@npm:0.16.1" +"@hexancore/common@npm:0.16.2": + version: 0.16.2 + resolution: "@hexancore/common@npm:0.16.2" dependencies: "@js-joda/core": "npm:^5.6.1" - class-transformer: "npm:^0.5.1" lambda-log: "npm:^3.1.0" nanoid: "npm:3" tslib: "npm:^2.6.3" peerDependencies: - axios: ^1.7.2 + axios: ^1.7.7 peerDependenciesMeta: axios: optional: true - checksum: 10c0/d628db6daa7573a797a0d5510ed332d28400cb1554f2e04656ad3e7b1aec87a028f13342e4cdf8e54591360f4894e2cbe5b252d644da0405228ae2f5a37481bf + checksum: 10c0/094dca106cd36d82e1b2c43da8bb4b817acc898ef68f1b58c2fe007ca0c50ad134140b0b0ec0bcb07a6f36c0f27b0f935dca24110cae0538578ffe2e8d46a6a4 languageName: node linkType: hard @@ -699,7 +698,7 @@ __metadata: "@fastify/multipart": "npm:^8.3.0" "@fastify/static": "npm:^7.0.4" "@fastify/swagger": "npm:^8.14.0" - "@hexancore/common": "npm:0.16.1" + "@hexancore/common": "npm:0.16.2" "@hexancore/mocker": "npm:^1.1.2" "@nestjs/cli": "npm:^10.3.2" "@nestjs/common": "npm:^10.3.9"