Skip to content

Conversation

@chriscanin
Copy link

@chriscanin chriscanin commented Oct 22, 2025

Description

  • Introduced useAppleSignIn hook for native Apple Sign-In on iOS using expo-apple-authentication.
  • Implemented flow to handle sign-in and sign-up using Clerk's backend.
  • Added type definitions for parameters and return types of the hook.
  • Modified strategies.ts to include 'oauth_token_apple' strategy type.
  • Altered expo package metro config to allow local CI runs to pass.
  • Fixed CI on github actions, these are now passing.

Fixes: https://linear.app/clerk/project/native-apple-login-flow-in-expo-f94b4842afd2

Checklist

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

  • New Features

    • Native Apple Sign-In support for iOS via a new hook and web-safe fallback.
    • Apple ID token-based authentication strategy added.
  • Improvements

    • Metro bundler updated for improved monorepo compatibility.
    • TypeScript resolution expanded to prefer web-specific modules when available.
  • Chores

    • Optional runtime support added for Apple Authentication and crypto helpers (native builds required).

- Introduced `useAppleSignIn` hook for native Apple Sign-In on iOS using expo-apple-authentication.
- Implemented flow to handle sign-in and sign-up using Clerk's backend.
- Added type definitions for parameters and return types of the hook.
- Updated `pnpm-lock.yaml` to include expo-apple-authentication as a dependency.
- Modified strategies.ts to include 'oauth_token_apple' strategy type.
@changeset-bot
Copy link

changeset-bot bot commented Oct 22, 2025

🦋 Changeset detected

Latest commit: bed16e5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
Name Type
@clerk/clerk-expo Minor
@clerk/types Patch
@clerk/agent-toolkit Patch
@clerk/astro Patch
@clerk/backend Patch
@clerk/clerk-js Patch
@clerk/elements Patch
@clerk/expo-passkeys Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/localizations Patch
@clerk/nextjs Patch
@clerk/nuxt Patch
@clerk/react-router Patch
@clerk/clerk-react Patch
@clerk/remix Patch
@clerk/shared Patch
@clerk/tanstack-react-start Patch
@clerk/testing Patch
@clerk/themes Patch
@clerk/vue Patch
@clerk/chrome-extension Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented Oct 22, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
clerk-js-sandbox Ready Ready Preview Comment Oct 24, 2025 7:57pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 22, 2025

Walkthrough

Adds native iOS Apple Sign-In to the Expo package via a new useAppleSignIn() hook, updates types to support an Apple ID token strategy, adds tests, adjusts Expo package deps and TypeScript resolution, and introduces monorepo-aware Metro config and a changeset documenting the release bumps.

Changes

Cohort / File(s) Change Summary
Apple Sign-In Hook
packages/expo/src/hooks/useAppleSignIn.ts, packages/expo/src/hooks/useAppleSignIn.web.ts, packages/expo/src/hooks/index.ts
New useAppleSignIn() exported; iOS implementation performs nonce generation, calls expo-apple-authentication, exchanges identity token with Clerk (oauth_token_apple), handles transfer sign-up flow, and exposes startAppleSignInFlow(); web stub throws an iOS-only guidance error.
Type Definitions
packages/types/src/strategies.ts, packages/types/src/signInCommon.ts, packages/types/src/signUpCommon.ts
Added AppleIdTokenStrategy = 'oauth_token_apple' and extended SignInCreateParams/SignUpCreateParams to accept the Apple ID token strategy and token payload.
Tests
packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts
New comprehensive test suite mocking Clerk, Expo Apple Authentication, Expo Crypto, and Platform; covers success, transfer, cancellation, unavailable auth, missing token, and not-loaded Clerk cases.
Package manifest & TS config
packages/expo/package.json, packages/expo/tsconfig.json
Added expo-apple-authentication and expo-crypto as peer/dev deps (optional in peerDependenciesMeta); added .web to TypeScript moduleSuffixes.
Metro (Expo web template)
integration/templates/expo-web/metro.config.js
Fixed typo, added handling for clerkExpoPath link:, introduced monorepo-aware watchFolders/nodeModulesPaths/extraNodeModules/blockList and a custom resolver for @clerk subpaths; export now returns config directly.
Changeset
.changeset/brave-apples-sign.md
Documents minor bump for @clerk/clerk-expo and patch bump for @clerk/types, notes native iOS Apple Sign-In hook and EAS/local prebuild requirement.

Sequence Diagram(s)

sequenceDiagram
    participant App as Expo App
    participant Hook as useAppleSignIn
    participant AppleAuth as expo-apple-authentication
    participant Crypto as expo-crypto
    participant Clerk as Clerk SDK

    App->>Hook: startAppleSignInFlow()
    Hook->>Hook: Validate platform (iOS)
    Hook->>Crypto: Generate nonce
    Hook->>AppleAuth: requestAsync (FULL_NAME, EMAIL)
    
    alt User Cancels
        AppleAuth-->>Hook: ERR_REQUEST_CANCELED
        Hook-->>App: { createdSessionId: null }
    else Apple Auth Success
        AppleAuth-->>Hook: identityToken
        Hook->>Clerk: signIn with oauth_token_apple
        
        alt Existing User
            Clerk-->>Hook: signIn verified
            Hook->>Clerk: setActive
            Hook-->>App: { createdSessionId, signIn }
        else New User (Transfer)
            Clerk-->>Hook: signIn.firstFactorVerification.status = 'transferable'
            Hook->>Clerk: signUp with transfer
            Clerk-->>Hook: signUp verified
            Hook->>Clerk: setActive
            Hook-->>App: { createdSessionId, signIn, signUp }
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I hopped to the code with a twitch and a grin,
Apple tokens clutched like a crunchy red pin.
Nonces and transfers, a smooth little dance,
iOS gates open—give sign-in a chance!
This rabbit applauds the new Expo expanse. 🍎✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "feat(clerk-expo): Add native Apple Sign-In support for iOS" is fully related to the primary change in the changeset. The title clearly and specifically summarizes the main feature being introduced: a new native Apple Sign-In capability for iOS within the Clerk Expo package. The changes comprehensively implement this feature, including the useAppleSignIn hook, type definitions, strategy updates, and configuration modifications—all of which directly support the stated objective. The title is concise, well-formatted using conventional commit conventions, and contains no vague terms or noise.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chris/mobile-279-expo-sign-in-with-apple

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d1a4d70 and bed16e5.

📒 Files selected for processing (1)
  • integration/templates/expo-web/metro.config.js (2 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.{js,jsx,ts,tsx}: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels

Files:

  • integration/templates/expo-web/metro.config.js
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • integration/templates/expo-web/metro.config.js
integration/**

📄 CodeRabbit inference engine (.cursor/rules/global.mdc)

Framework integration templates and E2E tests should be placed under the integration/ directory

Files:

  • integration/templates/expo-web/metro.config.js
integration/**/*

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

End-to-end tests and integration templates must be located in the 'integration/' directory.

Files:

  • integration/templates/expo-web/metro.config.js
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.

Files:

  • integration/templates/expo-web/metro.config.js
⏰ 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). (29)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (nextjs, chrome, 14)
  • GitHub Check: Integration Tests (billing, chrome)
  • GitHub Check: Integration Tests (handshake:staging, chrome)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (handshake, chrome)
  • GitHub Check: Integration Tests (sessions:staging, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome)
  • GitHub Check: Integration Tests (custom, chrome)
  • GitHub Check: Integration Tests (machine, chrome)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Integration Tests (localhost, chrome)
  • GitHub Check: Integration Tests (expo-web, chrome)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (elements, chrome)
  • GitHub Check: Integration Tests (generic, chrome)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Unit Tests (18, --filter=@clerk/astro --filter=@clerk/backend --filter=@clerk/express --filter=@c...
  • GitHub Check: Publish with pkg-pr-new
  • GitHub Check: Static analysis
  • GitHub Check: Unit Tests (22, **)
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (5)
integration/templates/expo-web/metro.config.js (5)

1-7: LGTM!

The header warning and imports are appropriate for this integration test configuration file.


9-27: LGTM!

The function is now correctly declared before usage, fixing the previous ReferenceError. The addition of link: prefix handling (lines 22-24) properly supports linked dependencies in the monorepo setup.


29-33: LGTM!

The initialization logic is clean and correct. The function call order issue has been resolved.


48-87: LGTM!

The node modules path prioritization and blockList configuration are comprehensive and correct. The regex patterns properly handle multiple React instances across monorepo root, pnpm store, and package node_modules while avoiding false matches with clerk-react.


89-122: LGTM!

The custom resolver correctly handles subpath exports for @clerk packages in the monorepo setup. The fallback logic and error handling are appropriate, and the direct export is clean.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

🧹 Nitpick comments (2)
packages/expo/src/hooks/useAppleSignIn.ts (2)

86-87: Consider using cryptographically secure nonce generation.

The current nonce generation using Math.random() is not cryptographically secure. While this may be acceptable if Clerk's backend validates the identity token independently, consider using a more secure random source.

Consider using expo-crypto for secure random generation:

+import * as Crypto from 'expo-crypto';
+
 // Generate a nonce for the Apple Sign-In request (required by Clerk)
-const nonce = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
+const nonce = Crypto.randomUUID();

Note: This would require adding expo-crypto as a dependency. Verify with the Clerk backend team whether the current approach meets security requirements.


105-109: Consider removing type assertions once types are fully propagated.

The as any casts on lines 107 and 109 bypass TypeScript's type checking. While this is acceptable during the rollout of new types, consider:

  1. Add a comment explaining why the casts are temporarily needed:
 // Create a SignIn with the Apple ID token strategy
+// Note: Type assertions needed until @clerk/clerk-react types are updated
 await signIn.create({
   strategy: 'oauth_token_apple' as any,
   token: identityToken,
 } as any);
  1. Alternatively, if the types in @clerk/types are now properly defined, verify whether these casts can be removed entirely by ensuring @clerk/clerk-react has the updated types.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ca00881 and f78267e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (8)
  • .changeset/brave-apples-sign.md (1 hunks)
  • packages/expo/package.json (3 hunks)
  • packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts (1 hunks)
  • packages/expo/src/hooks/index.ts (1 hunks)
  • packages/expo/src/hooks/useAppleSignIn.ts (1 hunks)
  • packages/types/src/signInCommon.ts (2 hunks)
  • packages/types/src/signUpCommon.ts (2 hunks)
  • packages/types/src/strategies.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.{js,jsx,ts,tsx}: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels

Files:

  • packages/types/src/strategies.ts
  • packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts
  • packages/expo/src/hooks/index.ts
  • packages/expo/src/hooks/useAppleSignIn.ts
  • packages/types/src/signUpCommon.ts
  • packages/types/src/signInCommon.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/types/src/strategies.ts
  • packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts
  • packages/expo/src/hooks/index.ts
  • packages/expo/src/hooks/useAppleSignIn.ts
  • packages/expo/package.json
  • packages/types/src/signUpCommon.ts
  • packages/types/src/signInCommon.ts
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

TypeScript is required for all packages

Files:

  • packages/types/src/strategies.ts
  • packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts
  • packages/expo/src/hooks/index.ts
  • packages/expo/src/hooks/useAppleSignIn.ts
  • packages/types/src/signUpCommon.ts
  • packages/types/src/signInCommon.ts
packages/**/*.{ts,tsx,d.ts}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Packages should export TypeScript types alongside runtime code

Files:

  • packages/types/src/strategies.ts
  • packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts
  • packages/expo/src/hooks/index.ts
  • packages/expo/src/hooks/useAppleSignIn.ts
  • packages/types/src/signUpCommon.ts
  • packages/types/src/signInCommon.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Prefer readonly for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Use const assertions for literal types: as const
Use satisfies operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports: import type { ... } from ...
No any types without justification
Proper error handling with typed errors
Consistent use of readonly for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)

Files:

  • packages/types/src/strategies.ts
  • packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts
  • packages/expo/src/hooks/index.ts
  • packages/expo/src/hooks/useAppleSignIn.ts
  • packages/types/src/signUpCommon.ts
  • packages/types/src/signInCommon.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.

Files:

  • packages/types/src/strategies.ts
  • packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts
  • packages/expo/src/hooks/index.ts
  • packages/expo/src/hooks/useAppleSignIn.ts
  • packages/types/src/signUpCommon.ts
  • packages/types/src/signInCommon.ts
packages/**/*.{test,spec}.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Unit tests should use Jest or Vitest as the test runner.

Files:

  • packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts
**/__tests__/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/typescript.mdc)

**/__tests__/**/*.{ts,tsx}: Create type-safe test builders/factories
Use branded types for test isolation
Implement proper mock types that match interfaces

Files:

  • packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts
packages/**/index.{js,ts}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use tree-shaking friendly exports

Files:

  • packages/expo/src/hooks/index.ts
**/index.ts

📄 CodeRabbit inference engine (.cursor/rules/react.mdc)

Use index.ts files for clean imports but avoid deep barrel exports

Avoid barrel files (index.ts re-exports) as they can cause circular dependencies

Files:

  • packages/expo/src/hooks/index.ts
packages/*/package.json

📄 CodeRabbit inference engine (.cursor/rules/global.mdc)

All publishable packages should be placed under the packages/ directory

packages/*/package.json: All publishable packages must be located in the 'packages/' directory.
All packages must be published under the @clerk namespace on npm.
Semantic versioning must be used across all packages.

Files:

  • packages/expo/package.json
.changeset/**

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Automated releases must use Changesets.

Files:

  • .changeset/brave-apples-sign.md
🧬 Code graph analysis (4)
packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts (1)
packages/expo/src/hooks/useAppleSignIn.ts (1)
  • useAppleSignIn (56-156)
packages/expo/src/hooks/useAppleSignIn.ts (3)
packages/types/src/clerk.ts (1)
  • SetActive (1268-1268)
packages/types/src/signIn.ts (1)
  • SignInResource (34-91)
packages/types/src/signUp.ts (1)
  • SignUpResource (40-121)
packages/types/src/signUpCommon.ts (1)
packages/types/src/strategies.ts (1)
  • AppleIdTokenStrategy (5-5)
packages/types/src/signInCommon.ts (1)
packages/types/src/strategies.ts (1)
  • AppleIdTokenStrategy (5-5)
⏰ 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: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (21)
packages/expo/package.json (1)

97-97: LGTM! Dependency configuration follows established patterns.

The expo-apple-authentication package is correctly configured across devDependencies, peerDependencies, and peerDependenciesMeta, following the same pattern as other optional Expo packages like expo-local-authentication and expo-secure-store.

Also applies to: 106-106, 119-121

.changeset/brave-apples-sign.md (1)

1-6: LGTM! Changeset properly documents the new feature.

The version bumps are appropriate: minor for @clerk/clerk-expo (new feature) and patch for @clerk/types (type additions). The description clearly states the feature and requirements.

packages/types/src/signUpCommon.ts (1)

12-12: LGTM! Type extension properly supports Apple ID token-based signup.

The AppleIdTokenStrategy is correctly imported and added to the SignUpCreateParams strategy union, enabling the new Apple Sign-In flow during user registration.

Also applies to: 93-93

packages/expo/src/hooks/index.ts (1)

14-14: LGTM! Export follows established barrel pattern.

The useAppleSignIn hook is correctly exported alongside other Expo-specific hooks.

packages/types/src/strategies.ts (1)

5-5: LGTM! Strategy type follows naming conventions.

The AppleIdTokenStrategy type is correctly defined with the 'oauth_token_apple' literal, following the established pattern for token-based strategies.

packages/types/src/signInCommon.ts (1)

43-43: LGTM! Type extension correctly supports Apple ID token-based sign-in.

The AppleIdTokenStrategy is properly imported and added to SignInCreateParams as a discriminated union variant with the required token field, following the same pattern as GoogleOneTapStrategy.

Also applies to: 141-144

packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts (6)

6-39: LGTM! Test mocks are properly configured.

The test setup correctly mocks all dependencies (@clerk/clerk-react, expo-apple-authentication, react-native) using vitest's hoisting pattern, ensuring isolated and reliable tests.


41-76: LGTM! Test fixtures and lifecycle hooks are well-structured.

The mock objects correctly represent Clerk's SignIn and SignUp resources, and the beforeEach/afterEach hooks properly initialize and clean up the test state.


79-84: LGTM! Basic hook structure test is appropriate.

The test verifies the hook returns the expected API surface.


86-157: LGTM! Sign-in flow tests comprehensively cover main scenarios.

The tests effectively verify:

  • Successful sign-in for existing users with proper token exchange
  • Transfer flow for new users requiring sign-up
  • Graceful handling of user cancellation

All assertions validate the correct behavior and return values.


159-179: LGTM! Error handling tests validate proper error conditions.

The tests correctly verify that appropriate errors are thrown when:

  • Apple Authentication is unavailable on the device
  • No identity token is received from Apple

181-195: LGTM! Early return test validates defensive loading check.

The test correctly verifies that when Clerk isn't fully loaded, the hook returns early without attempting Apple Authentication, preventing potential runtime errors.

packages/expo/src/hooks/useAppleSignIn.ts (9)

19-55: LGTM! Excellent documentation with practical example.

The JSDoc provides comprehensive documentation including a realistic usage example, platform requirements, and peer dependency information.


56-58: LGTM! Hook initialization correctly uses Clerk hooks.

Both useSignIn and useSignUp are properly called to obtain the necessary resources and loading states.


64-68: LGTM! Platform check with helpful error message.

The iOS-only restriction is correctly enforced with a clear error message that guides developers to use the alternative OAuth flow on other platforms.


70-77: LGTM! Proper defensive check for Clerk loading state.

The early return when Clerk isn't loaded prevents potential runtime errors and returns a consistent structure for callers to handle.


79-83: LGTM! Device capability check is appropriate.

The availability check ensures Apple Authentication is supported before proceeding, with a clear error message for unsupported devices.


98-103: LGTM! Identity token validation is appropriate.

The code correctly validates that an identity token was received from Apple before proceeding.


111-127: LGTM! Transfer flow correctly handles new user sign-up.

The code properly detects when a user doesn't exist (transferable status) and creates a SignUp with the transfer flag, preserving any unsafe metadata provided by the caller.


129-150: LGTM! Error handling gracefully manages cancellation and propagates other errors.

The code correctly:

  • Returns the sign-in session ID for existing users
  • Handles user cancellation gracefully by returning null without throwing
  • Propagates other errors for proper error handling upstream

153-155: LGTM! Hook return follows React conventions.

The hook cleanly returns an object with the startAppleSignInFlow function.

@chriscanin
Copy link
Author

🦋 Changeset detected

Latest commit: f78267e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
Name Type
@clerk/clerk-expo Minor
@clerk/types Patch
@clerk/agent-toolkit Patch
@clerk/astro Patch
@clerk/backend Patch
@clerk/clerk-js Patch
@clerk/elements Patch
@clerk/expo-passkeys Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/localizations Patch
@clerk/nextjs Patch
@clerk/nuxt Patch
@clerk/react-router Patch
@clerk/clerk-react Patch
@clerk/remix Patch
@clerk/shared Patch
@clerk/tanstack-react-start Patch
@clerk/testing Patch
@clerk/themes Patch
@clerk/vue Patch
@clerk/chrome-extension Patch
Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

What!? I will fix this... I don't think thats correct.

@chriscanin
Copy link
Author

🦋 Changeset detected

Latest commit: f78267e
The changes in this PR will be included in the next version bump.
This PR includes changesets to release 22 packages
Name Type
@clerk/clerk-expo Minor
@clerk/types Patch
@clerk/agent-toolkit Patch
@clerk/astro Patch
@clerk/backend Patch
@clerk/clerk-js Patch
@clerk/elements Patch
@clerk/expo-passkeys Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/localizations Patch
@clerk/nextjs Patch
@clerk/nuxt Patch
@clerk/react-router Patch
@clerk/clerk-react Patch
@clerk/remix Patch
@clerk/shared Patch
@clerk/tanstack-react-start Patch
@clerk/testing Patch
@clerk/themes Patch
@clerk/vue Patch
@clerk/chrome-extension Patch
Not sure what this means? Click here to learn what changesets are.
Click here if you're a maintainer who wants to add another changeset to this PR

What!? I will fix this... I don't think thats correct.

Ahhh... This is everyone elses changes since my branch was created. Only two of my packages will be updated.
'@clerk/clerk-expo': minor
'@clerk/types': patch

@pkg-pr-new
Copy link

pkg-pr-new bot commented Oct 22, 2025

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7053

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7053

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7053

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7053

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7053

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7053

@clerk/elements

npm i https://pkg.pr.new/@clerk/elements@7053

@clerk/clerk-expo

npm i https://pkg.pr.new/@clerk/clerk-expo@7053

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7053

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7053

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7053

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7053

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7053

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7053

@clerk/clerk-react

npm i https://pkg.pr.new/@clerk/clerk-react@7053

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7053

@clerk/remix

npm i https://pkg.pr.new/@clerk/remix@7053

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7053

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7053

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7053

@clerk/themes

npm i https://pkg.pr.new/@clerk/themes@7053

@clerk/types

npm i https://pkg.pr.new/@clerk/types@7053

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7053

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7053

commit: bed16e5

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f643dfe and a3d83bd.

📒 Files selected for processing (1)
  • packages/expo/src/hooks/useAppleSignIn.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.{js,jsx,ts,tsx}: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels

Files:

  • packages/expo/src/hooks/useAppleSignIn.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/expo/src/hooks/useAppleSignIn.ts
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

TypeScript is required for all packages

Files:

  • packages/expo/src/hooks/useAppleSignIn.ts
packages/**/*.{ts,tsx,d.ts}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Packages should export TypeScript types alongside runtime code

Files:

  • packages/expo/src/hooks/useAppleSignIn.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Prefer readonly for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Use const assertions for literal types: as const
Use satisfies operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports: import type { ... } from ...
No any types without justification
Proper error handling with typed errors
Consistent use of readonly for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)

Files:

  • packages/expo/src/hooks/useAppleSignIn.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.

Files:

  • packages/expo/src/hooks/useAppleSignIn.ts
🧬 Code graph analysis (1)
packages/expo/src/hooks/useAppleSignIn.ts (3)
packages/types/src/clerk.ts (1)
  • SetActive (1268-1268)
packages/types/src/signIn.ts (1)
  • SignInResource (34-91)
packages/types/src/signUp.ts (1)
  • SignUpResource (40-121)
⏰ 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). (5)
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: Build Packages
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (7)
packages/expo/src/hooks/useAppleSignIn.ts (7)

2-2: Past review issue resolved.

The missing SignUpUnsafeMetadata import flagged in the previous review has been correctly added.


19-55: Excellent documentation.

The JSDoc is comprehensive, includes a practical example, and clearly documents platform restrictions and peer dependencies.


64-68: Good platform enforcement.

The iOS-only check with a descriptive error message guiding users to the web OAuth alternative is well-implemented.


113-129: Transfer flow logic is well-implemented.

The conditional handling of the transferable status correctly routes new users through the SignUp flow while preserving optional metadata.


138-152: Robust error handling.

The distinction between user cancellation (ERR_REQUEST_CANCELED) and other errors is appropriate. Returning gracefully on cancellation allows the UI to handle the flow without treating it as an error.


155-157: Clean hook interface.

The return structure follows React hook conventions and provides a clear API surface.


108-111: The review comment is based on flawed assumptions about type availability.

The AppleIdTokenStrategy type does exist in @clerk/types, but it's not included in the strategy parameter union of SignInFutureCreateParams. The strategy field accepts OAuthStrategy | 'saml' | 'enterprise_sso' | PasskeyStrategy, and AppleIdTokenStrategy ('oauth_token_apple') is not part of this union.

Using as AppleIdTokenStrategy (as suggested) would not eliminate the type assertion problem—TypeScript would still reject it since AppleIdTokenStrategy is not an accepted strategy type. The current as any approach is a reasonable temporary workaround until the type definition in SignInFutureCreateParams is updated to include AppleIdTokenStrategy in its union.

Likely an incorrect or invalid review comment.

@chriscanin chriscanin changed the title Chris/mobile 279 expo sign in with apple feat(expo): add native Apple Sign-In support for iOS Oct 22, 2025
@chriscanin chriscanin changed the title feat(expo): add native Apple Sign-In support for iOS feat(expo): Add native Apple Sign-In support for iOS Oct 22, 2025
@chriscanin chriscanin changed the title feat(expo): Add native Apple Sign-In support for iOS feat(clerk-expo): Add native Apple Sign-In support for iOS Oct 22, 2025
…eneration in useAppleSignIn hook

- Added expo-crypto as a dependency in package.json.
- Updated useAppleSignIn hook to use Crypto.randomUUID() for generating a cryptographically secure nonce instead of Math.random().
- Mocked expo-crypto in useAppleSignIn tests to return a fixed UUID for consistent testing.
- Updated tests to verify that randomUUID is called and the correct nonce is used in the sign-in flow.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/expo/src/hooks/useAppleSignIn.ts (1)

138-152: Consider using unknown for caught errors.

The error handling logic is correct, but the error parameter uses any which goes against TypeScript best practices.

Apply this diff to improve type safety:

-    } catch (error: any) {
+    } catch (error: unknown) {
       // Handle Apple Authentication errors
-      if (error?.code === 'ERR_REQUEST_CANCELED') {
+      if (error && typeof error === 'object' && 'code' in error && error.code === 'ERR_REQUEST_CANCELED') {
         // User canceled the sign-in flow

Alternatively, define a type guard:

function isAppleAuthError(error: unknown): error is { code: string } {
  return typeof error === 'object' && error !== null && 'code' in error;
}

// Then use:
if (isAppleAuthError(error) && error.code === 'ERR_REQUEST_CANCELED') {
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a3d83bd and 03235ee.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • packages/expo/package.json (2 hunks)
  • packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts (1 hunks)
  • packages/expo/src/hooks/useAppleSignIn.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/expo/package.json
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.{js,jsx,ts,tsx}: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels

Files:

  • packages/expo/src/hooks/useAppleSignIn.ts
  • packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/expo/src/hooks/useAppleSignIn.ts
  • packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

TypeScript is required for all packages

Files:

  • packages/expo/src/hooks/useAppleSignIn.ts
  • packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts
packages/**/*.{ts,tsx,d.ts}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Packages should export TypeScript types alongside runtime code

Files:

  • packages/expo/src/hooks/useAppleSignIn.ts
  • packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Prefer readonly for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Use const assertions for literal types: as const
Use satisfies operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports: import type { ... } from ...
No any types without justification
Proper error handling with typed errors
Consistent use of readonly for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)

Files:

  • packages/expo/src/hooks/useAppleSignIn.ts
  • packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.

Files:

  • packages/expo/src/hooks/useAppleSignIn.ts
  • packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts
packages/**/*.{test,spec}.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Unit tests should use Jest or Vitest as the test runner.

Files:

  • packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts
**/__tests__/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/typescript.mdc)

**/__tests__/**/*.{ts,tsx}: Create type-safe test builders/factories
Use branded types for test isolation
Implement proper mock types that match interfaces

Files:

  • packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts
🧬 Code graph analysis (2)
packages/expo/src/hooks/useAppleSignIn.ts (3)
packages/types/src/clerk.ts (1)
  • SetActive (1268-1268)
packages/types/src/signIn.ts (1)
  • SignInResource (34-91)
packages/types/src/signUp.ts (1)
  • SignUpResource (40-121)
packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts (1)
packages/expo/src/hooks/useAppleSignIn.ts (1)
  • useAppleSignIn (57-158)
⏰ 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). (5)
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: Build Packages
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (8)
packages/expo/src/hooks/__tests__/useAppleSignIn.test.ts (3)

1-46: LGTM! Well-structured test setup.

The mock setup is comprehensive and properly uses vi.hoisted() for hoisting. All dependencies are appropriately mocked with realistic API surfaces.


48-84: LGTM! Proper test lifecycle management.

The test fixtures and lifecycle hooks are well-organized. Mocks are properly reset before each test and restored after, ensuring test isolation.


86-205: LGTM! Comprehensive test coverage.

The test suite thoroughly covers all critical paths:

  • ✅ Happy path for existing users with session creation
  • ✅ Transfer flow for new user sign-up
  • ✅ Graceful handling of user cancellation
  • ✅ Error cases (unavailable authentication, missing token)
  • ✅ Early return when Clerk is not loaded

All assertions properly verify function calls, parameters, and return values.

packages/expo/src/hooks/useAppleSignIn.ts (5)

1-18: LGTM! Clean imports and type definitions.

The type definitions are well-structured and properly exported. The import of SignUpUnsafeMetadata from a previous review has been correctly addressed.


20-56: LGTM! Excellent documentation.

The JSDoc is comprehensive and follows best practices. The example is clear and demonstrates the complete flow including session activation.


57-78: LGTM! Proper hook initialization and guards.

The hook correctly uses Clerk hooks at the top level and implements appropriate guards for platform compatibility and loaded state. The error message for non-iOS platforms helpfully suggests an alternative approach.


80-137: LGTM! Authentication flow correctly implemented.

The flow properly handles:

  • Device capability checking
  • Cryptographically secure nonce generation (addressed from previous review)
  • Identity token validation
  • Transfer flow for new users vs. existing user sign-in

The as any type assertions on lines 109 and 111 are acceptable given the inline comment explaining they're temporary until the new oauth_token_apple strategy type propagates through the type system.


155-158: LGTM! Clean hook interface.

The hook properly returns an object with the startAppleSignInFlow function, following React hook conventions.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

♻️ Duplicate comments (1)
integration/models/application.ts (1)

108-114: This issue was already flagged in a previous review.

The exit code logic and missing return type annotation have already been identified in a previous review comment. Please address the feedback provided there.

🧹 Nitpick comments (1)
integration/models/application.ts (1)

116-120: Consider extracting magic numbers to named constants.

The timeout values are hardcoded. While the inline comments are helpful, extracting these to named constants would improve maintainability and make them easier to adjust if needed.

+  const DEV_SERVER_STARTUP_TIMEOUT_MS = 60000;
+  const DEV_SERVER_POLL_INTERVAL_MS = 1000;
+
-  // Use a finite timeout to avoid hanging forever
-  const maxWaitTimeMs = 60000; // 60 seconds
-  const pollIntervalMs = 1000;
-  const maxAttempts = Math.floor(maxWaitTimeMs / pollIntervalMs);
+  // Use a finite timeout to avoid hanging forever
+  const maxAttempts = Math.floor(DEV_SERVER_STARTUP_TIMEOUT_MS / DEV_SERVER_POLL_INTERVAL_MS);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ff0a778 and b4fdde7.

📒 Files selected for processing (1)
  • integration/models/application.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.{js,jsx,ts,tsx}: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels

Files:

  • integration/models/application.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • integration/models/application.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Prefer readonly for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Use const assertions for literal types: as const
Use satisfies operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports: import type { ... } from ...
No any types without justification
Proper error handling with typed errors
Consistent use of readonly for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)

Files:

  • integration/models/application.ts
integration/**

📄 CodeRabbit inference engine (.cursor/rules/global.mdc)

Framework integration templates and E2E tests should be placed under the integration/ directory

Files:

  • integration/models/application.ts
integration/**/*

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

End-to-end tests and integration templates must be located in the 'integration/' directory.

Files:

  • integration/models/application.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.

Files:

  • integration/models/application.ts
🧬 Code graph analysis (1)
integration/models/application.ts (1)
integration/models/applicationConfig.ts (1)
  • name (133-135)
⏰ 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). (27)
  • GitHub Check: Integration Tests (custom, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 14)
  • GitHub Check: Integration Tests (billing, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (machine, chrome)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (sessions:staging, chrome)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome)
  • GitHub Check: Integration Tests (handshake, chrome)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (expo-web, chrome)
  • GitHub Check: Integration Tests (handshake:staging, chrome)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Integration Tests (generic, chrome)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Publish with pkg-pr-new
  • GitHub Check: Unit Tests (18, --filter=@clerk/astro --filter=@clerk/backend --filter=@clerk/express --filter=@c...
  • GitHub Check: Unit Tests (22, **)
  • GitHub Check: Static analysis
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (1)
integration/models/application.ts (1)

121-146: Good error handling structure for server startup.

The finite timeout-based startup with detailed error logging and log dumping on failure provides good observability for debugging startup issues. The structure correctly handles both detached and non-detached modes.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
integration/models/application.ts (2)

88-126: Extract duplicated log-dumping logic and use proper error types.

The log-dumping code is repeated multiple times (early stdout, early stderr, late stdout, late stderr, and again on failure below) with untyped catch blocks using e.message directly, violating DRY and TypeScript coding guidelines.

Extract into a reusable helper:

+  const dumpLogFile = async (filePath: string, label: string): Promise<void> => {
+    try {
+      const content = await fs.readFile(filePath, 'utf-8');
+      console.log(`[${name}:dev] ===== ${label} (${content.length} bytes) =====`);
+      console.log(content || '(empty)');
+      console.log(`[${name}:dev] ===== END ${label} =====`);
+    } catch (error) {
+      const message = error instanceof Error ? error.message : String(error);
+      console.log(`[${name}:dev] Could not read ${label}: ${message}`);
+    }
+  };

Then replace the repeated blocks:

-    // Dump logs early to help diagnose startup issues
-    try {
-      const stdoutContent = await fs.readFile(stdoutFilePath, 'utf-8');
-      console.log(`[${name}:dev] ===== EARLY STDOUT @5s (${stdoutContent.length} bytes) =====`);
-      console.log(stdoutContent || '(empty)');
-      console.log(`[${name}:dev] ===== END EARLY STDOUT =====`);
-    } catch (e) {
-      console.log(`[${name}:dev] No stdout yet: ${e.message}`);
-    }
-
-    try {
-      const stderrContent = await fs.readFile(stderrFilePath, 'utf-8');
-      console.log(`[${name}:dev] ===== EARLY STDERR @5s (${stderrContent.length} bytes) =====`);
-      console.log(stderrContent || '(empty)');
-      console.log(`[${name}:dev] ===== END EARLY STDERR =====`);
-    } catch (e) {
-      console.log(`[${name}:dev] No stderr yet: ${e.message}`);
-    }
+    await dumpLogFile(stdoutFilePath, 'EARLY STDOUT @5s');
+    await dumpLogFile(stderrFilePath, 'EARLY STDERR @5s');

Apply similar changes to the late dumps (lines 109-125) and failure dumps (lines 149-164).

Based on coding guidelines.


129-135: Fix exit code logic and add explicit return type.

Two critical issues:

  1. Exit code logic: The condition !!proc.exitCode && proc.exitCode !== 0 only detects non-zero exits. If the dev server exits with code 0 before being ready, this returns false and continues waiting until timeout—treating a premature successful exit as if the process is still running.

  2. Missing return type: Violates TypeScript coding guidelines requiring explicit return types for functions.

Apply this diff:

-      const shouldExit = () => {
-        const hasExited = !!proc.exitCode && proc.exitCode !== 0;
+      const shouldExit = (): boolean => {
+        const hasExited = proc.exitCode != null;
         if (hasExited) {
           console.log(`[${name}:dev] Process ${proc.pid} exited with code ${proc.exitCode}`);
         }
         return hasExited;
       };

This treats any process exit (zero or non-zero) before server readiness as an error condition.

Based on coding guidelines.

🧹 Nitpick comments (1)
integration/models/application.ts (1)

137-143: Consider adding a clarifying comment for the timeout strategy.

The finite timeout configuration is clear, but a brief comment explaining the strategy would improve maintainability.

+      // Wait up to 60 seconds for server to become ready, checking every second
       const maxWaitTimeMs = 60000; // 60 seconds
       const pollIntervalMs = 1000;
       const maxAttempts = Math.floor(maxWaitTimeMs / pollIntervalMs);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between b4fdde7 and 62f9e55.

📒 Files selected for processing (1)
  • integration/models/application.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.{js,jsx,ts,tsx}: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels

Files:

  • integration/models/application.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • integration/models/application.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Prefer readonly for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Use const assertions for literal types: as const
Use satisfies operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports: import type { ... } from ...
No any types without justification
Proper error handling with typed errors
Consistent use of readonly for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)

Files:

  • integration/models/application.ts
integration/**

📄 CodeRabbit inference engine (.cursor/rules/global.mdc)

Framework integration templates and E2E tests should be placed under the integration/ directory

Files:

  • integration/models/application.ts
integration/**/*

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

End-to-end tests and integration templates must be located in the 'integration/' directory.

Files:

  • integration/models/application.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.

Files:

  • integration/models/application.ts
🧬 Code graph analysis (1)
integration/models/application.ts (1)
integration/models/applicationConfig.ts (1)
  • name (133-135)
⏰ 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). (28)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (billing, chrome)
  • GitHub Check: Integration Tests (custom, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (machine, chrome)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 14)
  • GitHub Check: Integration Tests (handshake, chrome)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (handshake:staging, chrome)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Integration Tests (generic, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Integration Tests (expo-web, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome)
  • GitHub Check: Integration Tests (sessions:staging, chrome)
  • GitHub Check: Integration Tests (elements, chrome)
  • GitHub Check: Integration Tests (localhost, chrome)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Static analysis
  • GitHub Check: Publish with pkg-pr-new
  • GitHub Check: Unit Tests (22, **)
  • GitHub Check: Unit Tests (18, --filter=@clerk/astro --filter=@clerk/backend --filter=@clerk/express --filter=@c...
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

♻️ Duplicate comments (1)
packages/expo/src/hooks/useAppleSignIn.ts (1)

7-9: CRITICAL: Missing import for SignUpUnsafeMetadata.

SignUpUnsafeMetadata is used in the type definition but is not imported. This will cause a TypeScript compilation error.

Apply this diff to add the missing import:

-import type { SetActive, SignInResource, SignUpResource } from '@clerk/types';
+import type { SetActive, SignInResource, SignUpResource, SignUpUnsafeMetadata } from '@clerk/types';
🧹 Nitpick comments (1)
packages/expo/src/hooks/useAppleSignIn.ts (1)

141-155: Consider a type guard for error handling.

The error type narrowing is functional but could be more maintainable with a type guard.

// Add before the function
type AppleAuthError = {
  code: string;
  message?: string;
};

function isAppleAuthError(error: unknown): error is AppleAuthError {
  return typeof error === 'object' && error !== null && 'code' in error;
}

// Then in the catch block:
if (isAppleAuthError(error) && error.code === 'ERR_REQUEST_CANCELED') {
  // User canceled the sign-in flow
  return {
    createdSessionId: null,
    setActive,
    signIn,
    signUp,
  };
}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 62f9e55 and ff8d018.

📒 Files selected for processing (1)
  • packages/expo/src/hooks/useAppleSignIn.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.{js,jsx,ts,tsx}: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels

Files:

  • packages/expo/src/hooks/useAppleSignIn.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/expo/src/hooks/useAppleSignIn.ts
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

TypeScript is required for all packages

Files:

  • packages/expo/src/hooks/useAppleSignIn.ts
packages/**/*.{ts,tsx,d.ts}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Packages should export TypeScript types alongside runtime code

Files:

  • packages/expo/src/hooks/useAppleSignIn.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Prefer readonly for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Use const assertions for literal types: as const
Use satisfies operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports: import type { ... } from ...
No any types without justification
Proper error handling with typed errors
Consistent use of readonly for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)

Files:

  • packages/expo/src/hooks/useAppleSignIn.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.

Files:

  • packages/expo/src/hooks/useAppleSignIn.ts
🧬 Code graph analysis (1)
packages/expo/src/hooks/useAppleSignIn.ts (3)
packages/types/src/clerk.ts (1)
  • SetActive (1268-1268)
packages/types/src/signIn.ts (1)
  • SignInResource (34-91)
packages/types/src/signUp.ts (1)
  • SignUpResource (40-121)
⏰ 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). (29)
  • GitHub Check: Integration Tests (nextjs, chrome, 14)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (machine, chrome)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (custom, chrome)
  • GitHub Check: Integration Tests (billing, chrome)
  • GitHub Check: Integration Tests (handshake, chrome)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Integration Tests (expo-web, chrome)
  • GitHub Check: Integration Tests (handshake:staging, chrome)
  • GitHub Check: Integration Tests (generic, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome)
  • GitHub Check: Integration Tests (sessions:staging, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (elements, chrome)
  • GitHub Check: Integration Tests (localhost, chrome)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Publish with pkg-pr-new
  • GitHub Check: Unit Tests (22, **)
  • GitHub Check: Unit Tests (18, --filter=@clerk/astro --filter=@clerk/backend --filter=@clerk/express --filter=@c...
  • GitHub Check: Static analysis
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (4)
packages/expo/src/hooks/useAppleSignIn.ts (4)

18-54: Excellent documentation.

The JSDoc is comprehensive, includes a working example, and clearly states platform restrictions and dependencies.


69-76: Consider the early return behavior.

When Clerk hasn't loaded, the function returns potentially undefined signIn, signUp, and setActive values. While type-safe (these are optional in the return type), callers should be aware they may receive undefined references rather than initialized objects.


78-86: Good lazy loading pattern.

Dynamically importing expo-apple-authentication prevents issues on non-iOS platforms and web. The availability check is appropriate.


87-107: Secure nonce generation and proper token extraction.

Using Crypto.randomUUID() ensures cryptographically secure nonce generation. The identity token validation is appropriate.

Comment on lines +109 to +115
// Create a SignIn with the Apple ID token strategy
// Note: Type assertions needed until @clerk/clerk-react propagates the new oauth_token_apple strategy type
await signIn.create({
strategy: 'oauth_token_apple' as any,
token: identityToken,
} as any);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Improve type safety for the new oauth_token_apple strategy.

The double as any assertions bypass all type checking. While the comment explains this is temporary, consider creating a more precise type assertion or augmenting the module locally.

Consider this alternative that maintains some type safety:

-      // Create a SignIn with the Apple ID token strategy
-      // Note: Type assertions needed until @clerk/clerk-react propagates the new oauth_token_apple strategy type
-      await signIn.create({
-        strategy: 'oauth_token_apple' as any,
-        token: identityToken,
-      } as any);
+      // Create a SignIn with the Apple ID token strategy
+      // Note: Type assertion needed until @clerk/clerk-react propagates the new oauth_token_apple strategy type
+      await signIn.create({
+        strategy: 'oauth_token_apple',
+        token: identityToken,
+      } as Parameters<typeof signIn.create>[0]);

This reduces the scope of the type assertion while still allowing the new strategy.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In packages/expo/src/hooks/useAppleSignIn.ts around lines 109 to 115, the code
uses broad "as any" casts for the signIn.create call which disables type
checking; replace the double any with a minimal, precise type assertion or local
type augmentation: define a narrow interface/type that extends the existing
Clerk sign-in params to include strategy: 'oauth_token_apple' and token: string
(or optional fields as needed), then cast only the object literal to that new
type when calling signIn.create; alternatively add a module augmentation for
@clerk/clerk-react to add the 'oauth_token_apple' strategy to the existing type
definitions and remove the any casts entirely.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ff8d018 and 1ea2d40.

📒 Files selected for processing (2)
  • packages/expo/src/hooks/useAppleSignIn.ts (1 hunks)
  • packages/expo/src/hooks/useAppleSignIn.web.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/expo/src/hooks/useAppleSignIn.ts
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.{js,jsx,ts,tsx}: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels

Files:

  • packages/expo/src/hooks/useAppleSignIn.web.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/expo/src/hooks/useAppleSignIn.web.ts
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

TypeScript is required for all packages

Files:

  • packages/expo/src/hooks/useAppleSignIn.web.ts
packages/**/*.{ts,tsx,d.ts}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Packages should export TypeScript types alongside runtime code

Files:

  • packages/expo/src/hooks/useAppleSignIn.web.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Prefer readonly for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Use const assertions for literal types: as const
Use satisfies operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports: import type { ... } from ...
No any types without justification
Proper error handling with typed errors
Consistent use of readonly for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)

Files:

  • packages/expo/src/hooks/useAppleSignIn.web.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.

Files:

  • packages/expo/src/hooks/useAppleSignIn.web.ts
🧬 Code graph analysis (1)
packages/expo/src/hooks/useAppleSignIn.web.ts (4)
packages/expo/src/hooks/useAppleSignIn.ts (3)
  • StartAppleSignInFlowParams (8-10)
  • StartAppleSignInFlowReturnType (12-17)
  • useAppleSignIn (56-159)
packages/types/src/clerk.ts (1)
  • SetActive (1268-1268)
packages/types/src/signIn.ts (1)
  • SignInResource (34-91)
packages/types/src/signUp.ts (1)
  • SignUpResource (40-121)
⏰ 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). (29)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (billing, chrome)
  • GitHub Check: Integration Tests (machine, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 14)
  • GitHub Check: Integration Tests (handshake:staging, chrome)
  • GitHub Check: Integration Tests (handshake, chrome)
  • GitHub Check: Integration Tests (sessions:staging, chrome)
  • GitHub Check: Integration Tests (expo-web, chrome)
  • GitHub Check: Integration Tests (custom, chrome)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome)
  • GitHub Check: Integration Tests (localhost, chrome)
  • GitHub Check: Integration Tests (elements, chrome)
  • GitHub Check: Integration Tests (generic, chrome)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Static analysis
  • GitHub Check: Unit Tests (18, --filter=@clerk/astro --filter=@clerk/backend --filter=@clerk/express --filter=@c...
  • GitHub Check: Publish with pkg-pr-new
  • GitHub Check: Unit Tests (22, **)
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (2)
packages/expo/src/hooks/useAppleSignIn.web.ts (2)

5-14: LGTM: Type definitions are well-structured.

The type definitions correctly mirror the native implementation's API surface, ensuring consistency across platforms. The use of optional properties and nullable types appropriately models the return scenarios.


16-51: LGTM: Excellent documentation with actionable guidance.

The JSDoc provides comprehensive guidance with a practical example showing developers the correct OAuth-based alternative for web platforms. The platform tag and error path are clearly documented.

…ax attempts

fix(longRunningApplication): remove redundant logging during initialization
Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

♻️ Duplicate comments (1)
integration/templates/expo-web/metro.config.js (1)

37-45: Remove duplicate config.watchFolders assignment.

Lines 37 and 40 both assign config.watchFolders = [clerkMonorepoPath]. This issue was previously flagged and marked as addressed in commit 676621b, but the duplicate still exists. Remove line 37 to eliminate the redundancy.

Apply this diff:

 // Only customize Metro config when running from monorepo
 if (clerkMonorepoPath) {
   console.log('[Metro Config] Applying monorepo customizations');
-  config.watchFolders = [clerkMonorepoPath];
 
   // Disable file watching to prevent infinite reload loops in integration tests
   config.watchFolders = [clerkMonorepoPath];
   config.watcher = {
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 676621b and d1a4d70.

📒 Files selected for processing (1)
  • integration/templates/expo-web/metro.config.js (2 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.{js,jsx,ts,tsx}: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels

Files:

  • integration/templates/expo-web/metro.config.js
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • integration/templates/expo-web/metro.config.js
integration/**

📄 CodeRabbit inference engine (.cursor/rules/global.mdc)

Framework integration templates and E2E tests should be placed under the integration/ directory

Files:

  • integration/templates/expo-web/metro.config.js
integration/**/*

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

End-to-end tests and integration templates must be located in the 'integration/' directory.

Files:

  • integration/templates/expo-web/metro.config.js
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.

Files:

  • integration/templates/expo-web/metro.config.js
🪛 Biome (2.1.2)
integration/templates/expo-web/metro.config.js

[error] 8-8: This variable is used before its declaration.

The variable is declared here:

(lint/correctness/noInvalidUseBeforeDeclaration)

⏰ 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). (5)
  • GitHub Check: Build Packages
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (5)
integration/templates/expo-web/metro.config.js (5)

27-29: LGTM! Support for link: protocol added.

The addition of link: protocol handling is consistent with the existing file: protocol handling and properly supports pnpm workspaces.


47-57: LGTM! Node module resolution properly configured.

The prioritization of local node_modules over monorepo node_modules and the explicit package mappings are correctly configured to handle the monorepo setup.


59-86: LGTM! Comprehensive blockList prevents duplicate React versions.

The blockList implementation is thorough and well-structured. Proper path escaping, word boundaries, and coverage of all potential duplicate locations (monorepo root, pnpm store, package node_modules) ensure React/React-Native version conflicts are prevented.


88-118: LGTM! Custom resolver correctly handles subpath exports.

The custom resolver implementation properly handles @clerk package subpath exports (e.g., @clerk/clerk-react/internal) by:

  • Matching the pattern and extracting package name and subpath
  • Attempting resolution via the subpath directory's package.json main field
  • Gracefully falling back to default resolution when subpath directories don't exist
  • Preserving the original resolver if it exists

The broad catch block on line 107 is acceptable here since the fallback behavior is appropriate for any resolution failure.


121-121: LGTM! Direct export is appropriate.

Exporting config directly (instead of spreading it) is the correct approach since the config object is mutated in place throughout the file.

startAppleSignInFlowParams?: StartAppleSignInFlowParams,
): Promise<StartAppleSignInFlowReturnType> {
// Check platform compatibility
if (Platform.OS !== 'ios') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to rename this file to useAppleSignIn.ios.ts and make useAppleSignIn.ts throw an error when it's imported?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that would make sense, and I believe that would eliminate the need for the useAppleSignIn.web.ts stub. I'll give that a try.

try {
// Generate a cryptographically secure nonce for the Apple Sign-In request (required by Clerk)
// Lazy load expo-crypto to avoid import issues on web
const Crypto = await import('expo-crypto');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stuff like this is why I think it might be better to write this as a platform-specific file

*
* @returns An object containing the `startAppleSignInFlow` function
*/
export function useAppleSignIn() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you think about renaming this to useAppleAuthentication? Would be easier to make it work for dedicated sign-ups (outside of the sign-in to sign-up transfer that it already supports).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually after reading more about this feature, I think the best name is likely useSignInWithApple since "Sign in with Apple" is the official name of the platform-level feature.

}

// Create a SignIn with the Apple ID token strategy
// Note: Type assertions needed until @clerk/clerk-react propagates the new oauth_token_apple strategy type
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you updated the types package we don't need the as any cast anymore right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants