diff --git a/jest.config.ts b/jest.config.ts index 8fe5177..9177f96 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -15,6 +15,7 @@ const jestConfig: JestConfigWithTsJest = { rootDir, tsconfig: compilerOptions, diagnostics: false, + isolatedModules: true, }] }, testMatch: ["/test/**/*.test.ts"], diff --git a/src/Compiler/Jest/HcJestTransformer.ts b/src/Compiler/Jest/HcJestTransformer.ts index 7d70486..a9eb9a4 100644 --- a/src/Compiler/Jest/HcJestTransformer.ts +++ b/src/Compiler/Jest/HcJestTransformer.ts @@ -107,7 +107,7 @@ export class HcJestTransformer implements AsyncTransformer ts.isStatement(node) + ) + ]); + + return transformed; + } + + private visitSourceStatement(visitContext: VisitContext, node: ts.Statement) { + if (ts.isClassDeclaration(node)) { + const handlerDecorator = ts.factory.createDecorator(ts.factory.createCallExpression( + visitContext.cqrsImport.get(visitContext.handlerDecoratorName), + undefined, + [ts.factory.createIdentifier(visitContext.meta.className)] + )); + return ts.factory.updateClassDeclaration( + node, + [handlerDecorator, ...node.modifiers ?? []], + node.name, + node.typeParameters, + node.heritageClauses, + node.members + ); + } + + return node; + } +} \ No newline at end of file diff --git a/src/Compiler/Transformer/Feature/FeatureTransformContext.ts b/src/Compiler/Transformer/Feature/FeatureTransformContext.ts index 922da09..3066cb8 100644 --- a/src/Compiler/Transformer/Feature/FeatureTransformContext.ts +++ b/src/Compiler/Transformer/Feature/FeatureTransformContext.ts @@ -3,6 +3,7 @@ import type { FeatureMeta } from "../../../Util/Feature/Meta/FeatureMeta"; import type { FeatureSourcePath } from "../../../Util/Feature/FeatureModuleDiscoverer"; export interface FeatureTransformContext { + source: ts.SourceFile; featureSourcePath: FeatureSourcePath; feature: FeatureMeta; tsContext: ts.TransformationContext; diff --git a/src/Compiler/Transformer/Feature/FeatureTsTransformer.ts b/src/Compiler/Transformer/Feature/FeatureTsTransformer.ts index 6d895d1..503891b 100644 --- a/src/Compiler/Transformer/Feature/FeatureTsTransformer.ts +++ b/src/Compiler/Transformer/Feature/FeatureTsTransformer.ts @@ -12,6 +12,7 @@ import { TsImportHelper } from "../TsImportHelper"; import { ModuleClassTsTransformer } from "../ModuleClassTsTransformer"; import type { FeatureTransformContext } from "./FeatureTransformContext"; import { HObjectTsTransformer } from "./HObject/HObjectTsTransformer"; +import { FeatureApplicationMessageHandlerTsTransformer } from "./FeatureApplicationMessageHandlerTsTransformer"; /** @@ -37,6 +38,7 @@ export class FeatureTsTransformer { new FeatureInfraDomainModuleTsTransformer(helpers), new FeatureModuleTsTransformer(helpers), new HObjectTsTransformer(helpers), + new FeatureApplicationMessageHandlerTsTransformer(helpers) ]; } @@ -89,6 +91,7 @@ export class FeatureTsTransformer { const feature = this.features.get(featureSourcePath.featureName)!; return { + source, feature, featureSourcePath, tsContext: context, diff --git a/src/Compiler/Transformer/Feature/HObject/HObjectTsTransformer.ts b/src/Compiler/Transformer/Feature/HObject/HObjectTsTransformer.ts index 886a80f..03fd82e 100644 --- a/src/Compiler/Transformer/Feature/HObject/HObjectTsTransformer.ts +++ b/src/Compiler/Transformer/Feature/HObject/HObjectTsTransformer.ts @@ -8,7 +8,7 @@ import { HObjectToJSONTsFactory } from "./HObjectToJSONTsFactory"; import type { FeatureSourcePath } from "../../../../Util/Feature/FeatureModuleDiscoverer"; import { HObjectToConstructorTsFactory } from "./HObjectConstructorTsFactory"; import { ImportDeclarationWrapper } from "../../Helper/ImportDeclarationWrapper"; -import { HObjectKind, type FeatureHObjectMeta } from "@/Util/Feature/Meta"; +import { HObjectKind, type FeatureHObjectMeta } from "../../../../Util/Feature/Meta"; interface VisitContext extends FeatureTransformContext { source: ts.SourceFile; diff --git a/src/Util/Feature/Meta/FeatureApplicationMeta.ts b/src/Util/Feature/Meta/FeatureApplicationMeta.ts index c877b42..8a3062d 100644 --- a/src/Util/Feature/Meta/FeatureApplicationMeta.ts +++ b/src/Util/Feature/Meta/FeatureApplicationMeta.ts @@ -28,6 +28,10 @@ export class FeatureApplicationCommandMeta implements FeatureApplicationMessageM return this.path + '/' + this.className + '.ts'; } + public get handlerFilePath(): string { + return this.path + '/' + this.handlerClass + '.ts'; + } + public get kind(): HObjectKind.Command { return HObjectKind.Command; } @@ -73,6 +77,10 @@ export class FeatureApplicationQueryMeta implements FeatureApplicationMessageMet return this.path + '/' + this.className + '.ts'; } + public get handlerFilePath(): string { + return this.path + '/' + this.handlerClass + '.ts'; + } + public get kind(): HObjectKind.Query { return HObjectKind.Query; } @@ -126,6 +134,8 @@ export class FeatureApplicationServiceMeta implements FeatureClassMeta { } } +export type FeatureApplicationCqrsHandlerMap = Map; + export class FeatureApplicationMeta implements JsonSerialize { public constructor( @@ -151,13 +161,15 @@ export class FeatureApplicationMeta implements JsonSerialize { return new this(commands, queries, dtos, services); } - public collectHObjects(map: FeatureHObjectMap): void { + public collectHObjects(map: FeatureHObjectMap, handlerMap: FeatureApplicationCqrsHandlerMap): void { for (const i of this.commands) { map.set(i.filePath, i); + handlerMap.set(i.handlerFilePath, i); } for (const i of this.queries) { map.set(i.filePath, i); + handlerMap.set(i.handlerFilePath, i); } for (const i of this.dtos) { diff --git a/src/Util/Feature/Meta/FeatureMeta.ts b/src/Util/Feature/Meta/FeatureMeta.ts index 4b1671e..c5c4b9d 100644 --- a/src/Util/Feature/Meta/FeatureMeta.ts +++ b/src/Util/Feature/Meta/FeatureMeta.ts @@ -1,7 +1,7 @@ -import { type JsonSerialize, LogicError } from '@hexancore/common'; +import { LogicError, type JsonSerialize } from '@hexancore/common'; import { hash } from "node:crypto"; -import type { FeatureHObjectMap, FeatureHObjectMeta } from './CommonFeatureMeta'; -import { FeatureApplicationMeta } from './FeatureApplicationMeta'; +import type { FeatureHObjectMeta } from './CommonFeatureMeta'; +import { FeatureApplicationMeta, type FeatureApplicationCqrsHandlerMap } from './FeatureApplicationMeta'; import { FeatureDomainMeta } from './FeatureDomainMeta'; import { FeatureInfrastructureMeta } from './FeatureInfrastructureMeta'; @@ -9,6 +9,7 @@ export type FeatureMap = Map; export class FeatureMeta implements JsonSerialize { private _hObjectMap!: Map; + private _applicationCqrsHandlerMap!: FeatureApplicationCqrsHandlerMap; public cacheKey!: string; public constructor( @@ -50,19 +51,25 @@ export class FeatureMeta implements JsonSerialize { } public get hObjectMap(): Map { - if (!this._hObjectMap) { - this._hObjectMap = this.createHObjectMap(); - } - + this.initHObjectMaps(); return this._hObjectMap; } - private createHObjectMap(): FeatureHObjectMap { - const map = new Map(); - this.application.collectHObjects(map); - this.domain.collectHObjects(map); + public get applicationCqrsHandlerMap(): FeatureApplicationCqrsHandlerMap { + this.initHObjectMaps(); + return this._applicationCqrsHandlerMap; + } + + private initHObjectMaps(): void { + if (this._hObjectMap) { + return; + } + + this._hObjectMap = new Map(); + this._applicationCqrsHandlerMap = new Map(); - return map; + this.application.collectHObjects(this._hObjectMap, this._applicationCqrsHandlerMap); + this.domain.collectHObjects(this._hObjectMap); } public toJSON(): any { diff --git a/src/Util/Feature/index.ts b/src/Util/Feature/index.ts new file mode 100644 index 0000000..9636887 --- /dev/null +++ b/src/Util/Feature/index.ts @@ -0,0 +1 @@ +export * from "./Meta"; \ 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 c996641..c4433c4 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 @@ -2,9 +2,7 @@ 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 extends HCommandHandler { protected handle(command: BookCreateCommand): HCommandAsyncResultType { if (command.title === "error") { 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 c72dd33..806d8b9 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,10 +1,8 @@ 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"; -@QueryHandler(BookGetByIdQuery) export class BookGetByIdQueryHandler extends HQueryHandler { protected handle(query: BookGetByIdQuery): HQueryAsyncResultType { if (query.title === "error") {