-
-
Notifications
You must be signed in to change notification settings - Fork 600
fix: crypto.randomUUID causes React-Native build failures
#2858
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: alpha
Are you sure you want to change the base?
Conversation
|
🚀 Thanks for opening this pull request! |
📝 WalkthroughWalkthroughThe PR simplifies UUID generation by consolidating environment-specific branching logic into a single implementation using Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## alpha #2858 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 64 64
Lines 6222 6212 -10
Branches 1473 1487 +14
=========================================
- Hits 6222 6212 -10 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
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.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In @README.md:
- Line 10: The Node.js version badge excludes v18 while the compatibility table
(lines ~54–57) still lists v18; update the badge string in README.md to include
18 (e.g., change "20,_22,_24" to "18,_20,_22,_24") and verify the compatibility
table and any other references now match the badge; alternatively, if you intend
to drop v18 support, remove it from the compatibility table instead—ensure both
the badge and table are consistent.
- Around line 97-99: Replace the ES6 import of the polyfill with the same
CommonJS style used elsewhere: change the line that imports
'react-native-random-uuid' so it uses require() rather than import, ensuring the
polyfill still provides crypto.randomUUID() globally; keep the surrounding
comment about Parse version comparison as-is until the exact version is
confirmed.
In @src/uuid.ts:
- Line 1: The uuid helper currently calls crypto.randomUUID() directly which
throws a cryptic ReferenceError when crypto or crypto.randomUUID is missing;
update the uuid function to perform a runtime check (typeof crypto !==
'undefined' && typeof crypto.randomUUID === 'function') and throw a clear,
actionable Error if unavailable that explains how to polyfill in React Native
(mention importing "react-native-random-uuid" after Parse.setAsyncStorage() and
link to the README), otherwise return crypto.randomUUID(); reference the
existing uuid function in src/uuid.ts to locate and replace the direct call.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
README.mdsrc/uuid.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build (Node 20, 20.19.0)
- GitHub Check: build (Node 24, 24.1.0)
- GitHub Check: build (Node 22, 22.12.0)
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.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @types/uuid.d.ts:
- Line 1: The current uuid implementation relies on crypto.randomUUID() which
will crash in React Native; update the module used by the declared function uuid
to provide a RN-safe implementation by either adding a React Native specific
file (e.g., create uuid.react-native.ts or lib/react-native/uuid.js) that
returns the same `${string}-${string}-...` format using a RN-friendly polyfill
(like react-native-uuid or the uuid package), or modify src/uuid.ts to detect
React Native at runtime and fall back to the polyfill when crypto.randomUUID is
unavailable; ensure InstallationController.currentInstallationId() and other
callers import the unified uuid symbol so RN builds pick up the RN variant or
the runtime fallback.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
types/AnonymousUtils.d.tstypes/Parse.d.tstypes/uuid.d.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build (Node 24, 24.1.0)
- GitHub Check: build (Node 20, 20.19.0)
- GitHub Check: build (Node 22, 22.12.0)
🔇 Additional comments (2)
types/AnonymousUtils.d.ts (1)
79-79: LGTM! Type narrowing accurately represents UUID format.The template literal type
${string}-${string}-${string}-${string}-${string}correctly represents the standard UUID format. Since this is within the_getAuthProvider()method (indicated by the_prefix as a private API), the type narrowing has minimal breaking change risk.types/Parse.d.ts (1)
36-36: LGTM! Consistent type narrowing across Parse namespace.The type change for
authData.idis consistent with the same change intypes/AnonymousUtils.d.ts, maintaining type consistency across the Parse namespace declarations.
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.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @README.md:
- Line 10: The README badge was updated to list Node 20, 22, 24 but the
compatibility table still lists Node 18; update the README to be consistent by
either removing Node 18 from the compatibility table to match the badge, or keep
Node 18 and add an explicit note that Node 18 requires a polyfill for global
crypto.randomUUID (requirement: Node >=19 provides it natively); reference the
badge token "[![Node Version]...]" and the compatibility table section and
ensure the README clearly states the native requirement (Node ≥19) or documents
how to provide the polyfill for Node 18 users.
🧹 Nitpick comments (3)
README.md (1)
89-97: Consider documenting the crypto polyfill requirement for React Native.React Native users will now need to polyfill
crypto.randomUUIDsince this PR removes the Node crypto import. Consider adding a note here to guide users, for example:**Note:** React Native environments require a crypto polyfill. Install and import `react-native-random-uuid` or similar before initializing Parse.src/__tests__/browser-test.js (1)
165-176: Improve cleanup reliability with try-finally.The test correctly validates the error path, but if
uuidv4()unexpectedly succeeds (line 171 fails),global.cryptowon't be restored. Use afinallyblock to guarantee cleanup:♻️ Suggested refactor
it('throw error if randomUUID is not available', () => { const tmp = global.crypto; delete global.crypto; try { const uuidv4 = require('../uuid').default; uuidv4(); expect(true).toBe(false); } catch (e) { expect(e.message).toBe('crypto.randomUUID is not available. For React Native, import "react-native-random-uuid"'); + } finally { + global.crypto = tmp; } - global.crypto = tmp; });src/uuid.ts (1)
3-6: Consider a more generic error message for broader environment coverage.The error message specifically guides React Native users but this check applies to any environment without
crypto.randomUUID(e.g., older Node.js versions, older browsers). Consider a more inclusive message:💬 Suggested alternative
throw new Error( - 'crypto.randomUUID is not available. ' + - 'For React Native, import "react-native-random-uuid"' + 'crypto.randomUUID is not available. ' + + 'Please provide a polyfill (e.g., "react-native-random-uuid" for React Native)' );
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
README.mdsrc/__tests__/browser-test.jssrc/uuid.ts
🧰 Additional context used
🧬 Code graph analysis (1)
src/__tests__/browser-test.js (1)
integration/test/ParseUserTest.js (2)
uuidv4(5-5)require(6-6)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build (Node 24, 24.1.0)
- GitHub Check: build (Node 20, 20.19.0)
- GitHub Check: build (Node 22, 22.12.0)
🔇 Additional comments (1)
src/uuid.ts (1)
1-9: No changes needed. The implementation correctly assumescrypto.randomUUIDis available globally in Node.js 20+ (introduced without experimental flag in v19.0.0). The error handling appropriately guards against environments where it's unavailable, such as React Native, making this a robust solution for both Node.js and React Native use cases.
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 pull request addresses React Native build failures caused by the use of node:crypto module by migrating to the global crypto object available in modern JavaScript environments. The change allows users to polyfill crypto.randomUUID in environments where it's not natively available.
Changes:
- Simplified UUID implementation to use global
crypto.randomUUID()with runtime availability check - Removed environment-specific UUID generation logic (weapp, browser, Node.js)
- Added error handling with guidance for React Native users when crypto.randomUUID is unavailable
- Changed type definition from
lettoconstfor consistency
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| types/uuid.d.ts | Updated type declaration from let to const to match the new implementation |
| src/uuid.ts | Replaced environment-specific UUID implementations with a single implementation using global crypto object, throws error if unavailable |
| src/tests/browser-test.js | Added test case to verify error handling when crypto.randomUUID is not available |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (typeof crypto === 'undefined' || typeof crypto.randomUUID !== 'function') { | ||
| throw new Error( | ||
| 'crypto.randomUUID is not available. ' + | ||
| 'For React Native, import "react-native-random-uuid"' | ||
| ); | ||
| } | ||
| return crypto.randomUUID(); |
Copilot
AI
Jan 12, 2026
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 new uuid implementation relies on the global crypto object being available. However, the WeChat mini-program (weapp) environment may not have the crypto object or crypto.randomUUID available. The previous implementation had a custom fallback UUID generation for weapp. This change could break the existing weapp test that expects uuid to work in that environment (see src/tests/weapp-test.js line 58-62). Consider adding a fallback implementation for environments where crypto.randomUUID is not available, or verify that weapp does indeed support crypto.randomUUID.
| if (typeof crypto === 'undefined' || typeof crypto.randomUUID !== 'function') { | |
| throw new Error( | |
| 'crypto.randomUUID is not available. ' + | |
| 'For React Native, import "react-native-random-uuid"' | |
| ); | |
| } | |
| return crypto.randomUUID(); | |
| // Prefer native crypto.randomUUID when available | |
| if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') { | |
| return crypto.randomUUID(); | |
| } | |
| // Fallback implementation for environments without crypto.randomUUID | |
| // (e.g., WeChat mini-program, older browsers, some React Native setups) | |
| let d = Date.now(); | |
| let d2 = | |
| typeof performance !== 'undefined' && typeof performance.now === 'function' | |
| ? performance.now() * 1000 | |
| : 0; | |
| return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { | |
| let r = Math.random() * 16; | |
| if (d > 0) { | |
| r = (d + r) % 16 | 0; | |
| d = Math.floor(d / 16); | |
| } else { | |
| r = (d2 + r) % 16 | 0; | |
| d2 = Math.floor(d2 / 16); | |
| } | |
| const v = c === 'x' ? r : (r & 0x3) | 0x8; | |
| return v.toString(16); | |
| }); |
| 'crypto.randomUUID is not available. ' + | ||
| 'For React Native, import "react-native-random-uuid"' |
Copilot
AI
Jan 12, 2026
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 error message specifically mentions React Native and suggests importing "react-native-random-uuid", but this error will be thrown in any environment where crypto.randomUUID is not available, including WeChat mini-programs (weapp). The error message should be more generic to cover all unsupported environments, or provide environment-specific guidance.
| 'crypto.randomUUID is not available. ' + | |
| 'For React Native, import "react-native-random-uuid"' | |
| 'crypto.randomUUID is not available in this environment. ' + | |
| 'Use a UUID polyfill or environment-specific implementation (for example, in React Native you can import "react-native-random-uuid").' |
| } | ||
| global.crypto = tmp; |
Copilot
AI
Jan 12, 2026
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.
This test doesn't have proper cleanup if the test fails before global.crypto is restored. If the uuidv4() call doesn't throw an error as expected, global.crypto will remain deleted, potentially affecting other tests. Consider using a finally block or Jest's afterEach/beforeEach hooks to ensure proper cleanup.
| } | |
| global.crypto = tmp; | |
| } finally { | |
| global.crypto = tmp; | |
| } |
Pull Request
Issue
Using
node:cryptoprevented users from polyfillingrandomUUIDCloses: #2856
Approach
As of Node 18 Web Crypto API is now a global object, this global object is also included in the browser. For any other runtime it will need to be polyfilled if not supported.
Summary by CodeRabbit
Bug Fixes
Tests
✏️ Tip: You can customize this high-level summary in your review settings.