From dedc1659c75065ef40c5425e779fbb9dc9169222 Mon Sep 17 00:00:00 2001 From: toir-bot Date: Tue, 28 Apr 2026 08:00:19 +0000 Subject: [PATCH] chore: initial project scaffold: backend/src/common/normalize-dates.interceptor.ts --- .../src/common/normalize-dates.interceptor.ts | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 backend/src/common/normalize-dates.interceptor.ts diff --git a/backend/src/common/normalize-dates.interceptor.ts b/backend/src/common/normalize-dates.interceptor.ts new file mode 100644 index 0000000..eb2a47b --- /dev/null +++ b/backend/src/common/normalize-dates.interceptor.ts @@ -0,0 +1,39 @@ +import { + CallHandler, + ExecutionContext, + Injectable, + NestInterceptor, +} from '@nestjs/common'; +import { Observable } from 'rxjs'; + +const DATE_ONLY = /^\d{4}-\d{2}-\d{2}$/; +const DATETIME_NO_TZ = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2}(\.\d+)?)?$/; + +const normalize = (value: unknown): unknown => { + if (value === null || value === undefined) return value; + if (typeof value === 'string') { + if (DATE_ONLY.test(value)) return `${value}T00:00:00.000Z`; + if (DATETIME_NO_TZ.test(value)) return `${value}Z`; + return value; + } + if (Array.isArray(value)) return value.map(normalize); + if (typeof value === 'object') { + const out: Record = {}; + for (const [k, v] of Object.entries(value as Record)) { + out[k] = normalize(v); + } + return out; + } + return value; +}; + +@Injectable() +export class NormalizeDatesInterceptor implements NestInterceptor { + intercept(ctx: ExecutionContext, next: CallHandler): Observable { + const req = ctx.switchToHttp().getRequest<{ body?: unknown }>(); + if (req.body && typeof req.body === 'object') { + req.body = normalize(req.body); + } + return next.handle(); + } +}