Merge pull request #34 from yusufipk/fix/bigint-safe-success-response

fix(api): serialize BigInt in all API success responses
This commit is contained in:
Yusuf İpek
2026-07-25 11:15:27 +03:00
committed by GitHub
4 changed files with 25 additions and 8 deletions
+10 -1
View File
@@ -1,4 +1,5 @@
import { NextResponse } from 'next/server';
import { bigIntReplacer } from '@/lib/json-serialize';
/**
* Standardized API error response format
@@ -113,6 +114,11 @@ export function errorResponse(
* @param status - HTTP status code (default: 200)
* @param meta - Pagination or other metadata (optional)
*
* Serialized with bigIntReplacer rather than NextResponse.json(), because
* JSON.stringify throws on BigInt and Prisma returns BigInt for sizeBytes.
* Any payload carrying a VideoVersion or VideoAsset row would otherwise 500
* after its write had already committed. BigInt values render as strings.
*
* @example
* ```ts
* return successResponse({ projects: [] });
@@ -127,7 +133,10 @@ export function successResponse<T>(
const body: ApiSuccessResponse<T> = { data };
if (meta) body.meta = meta;
return NextResponse.json(body, { status });
return new NextResponse(JSON.stringify(body, bigIntReplacer), {
status,
headers: { 'content-type': 'application/json' },
}) as NextResponse<ApiSuccessResponse<T>>;
}
export function withCacheControl(response: Response, value: string): Response {
+13 -3
View File
@@ -1,8 +1,18 @@
/**
* JSON.stringify replacer that renders Prisma BigInt columns (sizeBytes) as
* strings. Without it, JSON.stringify throws on any payload carrying one.
*/
export function bigIntReplacer(_key: string, value: unknown): unknown {
return typeof value === 'bigint' ? value.toString() : value;
}
/**
* Converts values for JSON responses (e.g. Prisma BigInt fields).
*
* API routes do not need this — successResponse() serializes BigInt already.
* Use it for payloads that bypass that helper, such as data handed from a
* server component to a client component.
*/
export function toJsonSafe<T>(value: T): T {
return JSON.parse(
JSON.stringify(value, (_key, val) => (typeof val === 'bigint' ? val.toString() : val))
) as T;
return JSON.parse(JSON.stringify(value, bigIntReplacer)) as T;
}