Skip to content

Commit 2860041

Browse files
committed
fix(client): handle top-level large integer JSON values
Address review feedback: - Add TOP_LEVEL_LARGE_INT pattern for bare scalar integers - Return string directly when JSON is just a large integer - Add regression test for top-level large integers This handles edge cases like JSON columns storing numeric scalars.
1 parent 65dbafa commit 2860041

2 files changed

Lines changed: 18 additions & 0 deletions

File tree

packages/client-engine-runtime/src/utils.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ describe('safeJsonParse', () => {
1515
})
1616
})
1717

18+
test('handles top-level large integer JSON values', () => {
19+
// JSON can be a bare scalar value (e.g., JSON columns storing numeric scalars)
20+
expect(safeJsonParse('312590077454712834')).toBe('312590077454712834')
21+
expect(safeJsonParse('-312590077454712834')).toBe('-312590077454712834')
22+
})
23+
1824
test('preserves 15-digit integers as numbers (safe)', () => {
1925
// 15-digit integers are always safe
2026
expect(safeJsonParse('{"id":123456789012345}')).toEqual({ id: 123456789012345 })

packages/client-engine-runtime/src/utils.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,12 @@ const LARGE_INT_PATTERN = /("(?:[^"\\]|\\.)*")|(:\s*|[,\[]\s*)(-?\d{16,})(?=\s*[
149149
*/
150150
const HAS_LARGE_INT = /\d{16}/
151151

152+
/**
153+
* Pattern to match a top-level large integer (JSON can be a bare scalar value).
154+
* Handles cases like JSON columns storing numeric scalars.
155+
*/
156+
const TOP_LEVEL_LARGE_INT = /^-?\d{16,}$/
157+
152158
/**
153159
* `JSON.parse` wrapper that preserves precision for large integer values.
154160
*
@@ -170,6 +176,12 @@ export function safeJsonParse(json: string): unknown {
170176
return JSON.parse(json)
171177
}
172178

179+
// Handle top-level large integers (JSON can be a bare scalar value).
180+
// The main regex only matches integers after :, ,, or [ so this case needs special handling.
181+
if (TOP_LEVEL_LARGE_INT.test(json)) {
182+
return json
183+
}
184+
173185
// Slow path: replace large integers with quoted strings to preserve precision.
174186
// Numbers with 16+ digits may exceed MAX_SAFE_INTEGER and lose precision.
175187
// The regex has two alternatives: string literals (group 1) and integers (groups 2-3).

0 commit comments

Comments
 (0)