@@ -298,6 +298,67 @@ function compareVersions(version1, version2, operator) {
298298 }
299299}
300300
301+ /**
302+ * Parse JSON string with support for large integers (beyond Number.MAX_SAFE_INTEGER).
303+ * Large integers are automatically converted to strings to preserve precision.
304+ *
305+ * For Node.js >= 21.0.0, uses native JSON.parse() with context parameter.
306+ * For older versions, preprocesses the JSON string with regex to convert unsafe integers.
307+ *
308+ * Replaces: json-bigint package
309+ *
310+ * @param {string } str - JSON string to parse
311+ * @returns {any } Parsed JSON object with unsafe integers as strings
312+ *
313+ * @example
314+ * parseJSONWithBigInt('{"value": 9007199254740992}')
315+ * // Returns: { value: '9007199254740992' }
316+ *
317+ * parseJSONWithBigInt('{"value": 100}')
318+ * // Returns: { value: 100 }
319+ */
320+ function parseJSONWithBigInt ( str ) {
321+ const contextSupportedVersion = '21.0.0.0' ;
322+ const currentVersion = process . version ;
323+ const isContextSupported = compareVersions (
324+ currentVersion . substring ( 1 , currentVersion . length ) ,
325+ contextSupportedVersion ,
326+ '>='
327+ ) ;
328+
329+ // For nodejs >= 21.0.0, we leverage context parameter to
330+ // convert unsafe integer to string.
331+ // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
332+ if ( isContextSupported ) {
333+ return JSON . parse ( str , ( key , value , context ) => {
334+ if (
335+ Number . isInteger ( value ) &&
336+ ! Number . isSafeInteger ( Number ( context . source ) )
337+ ) {
338+ return context . source ;
339+ }
340+ return value ;
341+ } ) ;
342+ }
343+
344+ // For older Node.js versions, preprocess the JSON string to convert
345+ // large integers (outside the safe integer range) to strings before parsing.
346+ // This replaces the functionality of json-bigint package.
347+ const processed = str . replace (
348+ / : \s * ( - ? \d + ) (? = \s * [ , } \] ] ) / g,
349+ ( match , number ) => {
350+ const num = Number ( number ) ;
351+ // If the number is not safe, keep it as a string
352+ if ( ! Number . isSafeInteger ( num ) ) {
353+ return `: "${ number } "` ;
354+ }
355+ return match ;
356+ }
357+ ) ;
358+
359+ return JSON . parse ( processed ) ;
360+ }
361+
301362module . exports = {
302363 // General utilities
303364 detectUbuntuCodename,
@@ -320,5 +381,7 @@ module.exports = {
320381 removeSync,
321382 readJsonSync,
322383
384+ // Version and JSON utilities
323385 compareVersions,
386+ parseJSONWithBigInt,
324387} ;
0 commit comments