import type { Finding } from '../../core/gate/Finding'; import type { TddBddEnforcementResult } from '../tdd/enforcement'; import type { TddBddSnapshot } from '../tdd/types'; export type TddBddEnforcementMode = 'advisory' | 'strict'; export type TddBddEnforcementResolution = { mode: TddBddEnforcementMode; source: 'default' | 'env'; blocking: boolean; }; const TDD_BDD_ENFORCEMENT_ENV = 'PUMUKI_TDD_BDD_ENFORCEMENT'; const toTddBddEnforcementMode = ( value: string | undefined ): TddBddEnforcementMode | null => { if (typeof value !== 'string') { return null; } const normalized = value.trim().toLowerCase(); if ( normalized === 'strict' || normalized === '1' || normalized === 'true' || normalized === 'yes' || normalized === 'on' ) { return 'strict'; } if ( normalized === 'advisory' || normalized === 'warn' || normalized === 'warning' || normalized === '0' || normalized === 'false' || normalized === 'no' || normalized === 'off' ) { return 'advisory'; } return null; }; export const resolveTddBddEnforcement = (): TddBddEnforcementResolution => { const modeFromEnv = toTddBddEnforcementMode(process.env[TDD_BDD_ENFORCEMENT_ENV]); if (modeFromEnv) { return { mode: modeFromEnv, source: 'env', blocking: modeFromEnv === 'strict', }; } return { mode: 'strict', source: 'default', blocking: true, }; }; const applyTddBddFindingEnforcement = ( finding: Finding, resolution: TddBddEnforcementResolution ): Finding => { if (resolution.blocking) { return finding; } if (finding.severity !== 'ERROR' && finding.severity !== 'CRITICAL') { return finding; } return { ...finding, severity: 'WARN', blocking: false, }; }; const applyTddBddSnapshotEnforcement = ( snapshot: TddBddSnapshot, resolution: TddBddEnforcementResolution ): TddBddSnapshot => { if (resolution.blocking || snapshot.status !== 'blocked') { return snapshot; } return { ...snapshot, status: 'advisory', }; }; export const applyTddBddEnforcement = ( result: TddBddEnforcementResult, resolution: TddBddEnforcementResolution = resolveTddBddEnforcement() ): TddBddEnforcementResult => { if (resolution.blocking) { return result; } return { findings: result.findings.map((finding) => applyTddBddFindingEnforcement(finding, resolution) ), snapshot: applyTddBddSnapshotEnforcement(result.snapshot, resolution), }; };