-
Couldn't load subscription status.
- Fork 79
Remove json-bigint dependency #1305
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR removes the json-bigint dependency by implementing native JSON parsing with big integer support. The change consolidates JSON parsing logic into a reusable utility function that uses Node.js 21+ native capabilities when available, and falls back to regex preprocessing for older versions.
Key Changes:
- Implemented
parseJSONWithBigIntutility function to replacejson-bigintpackage - Removed
json-bigintdependency from package.json - Refactored rosidl_parser.js to use the new utility function
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| lib/utils.js | Added parseJSONWithBigInt function with comprehensive documentation to handle large integers in JSON parsing |
| rosidl_parser/rosidl_parser.js | Removed local _parseJSONObject method and version checking logic, replaced with imported parseJSONWithBigInt utility |
| package.json | Removed json-bigint dependency from dependencies list |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
lib/utils.js
Outdated
| function parseJSONWithBigInt(str) { | ||
| const contextSupportedVersion = '21.0.0.0'; | ||
| const currentVersion = process.version; | ||
| const isContextSupported = compareVersions( | ||
| currentVersion.substring(1, currentVersion.length), | ||
| contextSupportedVersion, | ||
| '>=' | ||
| ); |
Copilot
AI
Oct 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The version comparison is executed on every call to parseJSONWithBigInt. Consider caching isContextSupported as a module-level constant to avoid repeated comparisons, similar to how it was implemented in the original code.
| const processed = str.replace( | ||
| /:\s*(-?\d+)(?=\s*[,}\]])/g, | ||
| (match, number) => { | ||
| const num = Number(number); | ||
| // If the number is not safe, keep it as a string | ||
| if (!Number.isSafeInteger(num)) { | ||
| return `: "${number}"`; | ||
| } | ||
| return match; | ||
| } | ||
| ); | ||
|
|
||
| return JSON.parse(processed); |
Copilot
AI
Oct 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The regex pattern may incorrectly match numbers in JSON string values. For example, in {\"key\": \"value: 123\"}, the number inside the string value could be mistakenly converted. The pattern should account for proper JSON structure to avoid matching numbers within string literals.
| const processed = str.replace( | |
| /:\s*(-?\d+)(?=\s*[,}\]])/g, | |
| (match, number) => { | |
| const num = Number(number); | |
| // If the number is not safe, keep it as a string | |
| if (!Number.isSafeInteger(num)) { | |
| return `: "${number}"`; | |
| } | |
| return match; | |
| } | |
| ); | |
| return JSON.parse(processed); | |
| // Use a reviver to convert unsafe integers to strings | |
| return JSON.parse(str, (key, value) => { | |
| if (typeof value === 'number' && Number.isInteger(value) && !Number.isSafeInteger(value)) { | |
| return value.toString(); | |
| } | |
| return value; | |
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| /(?:[:,[])\s*(-?\d+)(?=\s*[,}\]])/g, | ||
| (match, number) => { | ||
| const num = Number(number); | ||
| // If the number is not safe, convert it to a string | ||
| if (!Number.isSafeInteger(num)) { | ||
| // Preserve the prefix character (: or , or [) | ||
| const prefix = match.charAt(0); | ||
| return `${prefix} "${number}"`; | ||
| } | ||
| return match; |
Copilot
AI
Oct 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The regex pattern requires a preceding character (:, ,, or [) which means it won't match integers at the start of the JSON string or after an opening brace {. For example, {\"value\": 9007199254740992} would match, but [9007199254740992] or {9007199254740992} (if this were valid JSON) would not match the integer at the start. Consider using a lookbehind assertion or adjust the logic to handle integers that appear immediately after {.
| /(?:[:,[])\s*(-?\d+)(?=\s*[,}\]])/g, | |
| (match, number) => { | |
| const num = Number(number); | |
| // If the number is not safe, convert it to a string | |
| if (!Number.isSafeInteger(num)) { | |
| // Preserve the prefix character (: or , or [) | |
| const prefix = match.charAt(0); | |
| return `${prefix} "${number}"`; | |
| } | |
| return match; | |
| /(?<=^|[:,\[{])\s*(-?\d+)(?=\s*[,}\]])/g, | |
| (numberMatch, number, offset, string) => { | |
| const num = Number(number); | |
| // If the number is not safe, convert it to a string | |
| if (!Number.isSafeInteger(num)) { | |
| // Find the prefix character (if any) | |
| const prefixMatch = string.slice(Math.max(0, offset - 1), offset); | |
| const prefix = /[:,\[{]/.test(prefixMatch) ? prefixMatch : ''; | |
| return `${prefix} "${number}"`; | |
| } | |
| return numberMatch; |
lib/utils.js
Outdated
| const num = Number(number); | ||
| // If the number is not safe, convert it to a string | ||
| if (!Number.isSafeInteger(num)) { |
Copilot
AI
Oct 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Converting the string to Number before checking if it's safe defeats the purpose of the check. For integers beyond Number.MAX_SAFE_INTEGER, Number(number) will lose precision during conversion (e.g., Number('9007199254740993') becomes 9007199254740992), making the subsequent safety check unreliable. Instead, compare the absolute value of the integer string against Number.MAX_SAFE_INTEGER without conversion, or use BigInt for comparison.
| const num = Number(number); | |
| // If the number is not safe, convert it to a string | |
| if (!Number.isSafeInteger(num)) { | |
| // Use BigInt to check if the integer is outside the safe range | |
| const absBigInt = BigInt(number.startsWith('-') ? number.slice(1) : number); | |
| if (absBigInt > BigInt(Number.MAX_SAFE_INTEGER)) { |
This PR removes the
json-bigintdependency by implementing native JSON parsing with big integer support. The change consolidates JSON parsing logic into a reusable utility function that uses Node.js 21+ native capabilities when available, and falls back to regex preprocessing for older versions.Key Changes:
parseJSONWithBigIntutility function to replacejson-bigintpackagejson-bigintdependency from package.jsonFix: #1304