From bbac2e358c1143a59b0050ed255f4db2433b0c0c Mon Sep 17 00:00:00 2001 From: wangdl Date: Sun, 21 Jun 2026 12:16:40 +0800 Subject: [PATCH] fix: use useFactory returning array + Array.isArray guard for RESULT_PROJECTORS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two changes to fix 'projectors is not iterable' TypeError: 1. ai-job.module.ts: Replace useClass+multi:true with useFactory that explicitly returns [p] — avoids NestJS multi-provider array-wrapping ambiguity. SyntheticResultProjector back as standalone provider. 2. projection-executor.service.ts: Replace truthiness check with Array.isArray() guard for defense-in-depth. Co-Authored-By: Claude --- src/modules/ai-job/ai-job.module.ts | 3 ++- src/modules/ai-job/projection-executor.service.ts | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/modules/ai-job/ai-job.module.ts b/src/modules/ai-job/ai-job.module.ts index 108f818..cb36490 100644 --- a/src/modules/ai-job/ai-job.module.ts +++ b/src/modules/ai-job/ai-job.module.ts @@ -30,7 +30,8 @@ import { SyntheticRegistrationService } from './synthetic-registration.service'; AiJobExecutionEngineImpl, ProjectionExecutor, SyntheticRegistrationService, - { provide: RESULT_PROJECTORS, useClass: SyntheticResultProjector, multi: true } as any, + SyntheticResultProjector, + { provide: RESULT_PROJECTORS, useFactory: (p: SyntheticResultProjector) => [p], inject: [SyntheticResultProjector] } as any, { provide: AI_JOB_EXECUTION_ENGINE, useExisting: AiJobExecutionEngineImpl }, ], exports: [ diff --git a/src/modules/ai-job/projection-executor.service.ts b/src/modules/ai-job/projection-executor.service.ts index 49e48a3..1c6c22d 100644 --- a/src/modules/ai-job/projection-executor.service.ts +++ b/src/modules/ai-job/projection-executor.service.ts @@ -28,13 +28,12 @@ export class ProjectionExecutor { @Inject(RESULT_PROJECTORS) projectors?: ResultProjector[], ) { - if (projectors) { - for (const p of projectors) { + const projectorList = Array.isArray(projectors) ? projectors : []; + for (const p of projectorList) { if (this.projectorMap.has(p.key)) { this.logger.warn(`Duplicate projector key "${p.key}" — overwriting`); } this.projectorMap.set(p.key, p); - } } this.logger.log( `ProjectionExecutor initialized with ${this.projectorMap.size} projector(s): ` +