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 for iOS via a new Expo hook; returns a startAppleAuthenticationFlow API. Requires expo-apple-authentication and a native build (EAS or local prebuild).
  • Types / API

    • SDK types extended to recognize Apple ID token sign-in strategy.
  • Chores

    • Added peer/dev dependencies for expo-apple-authentication and expo-crypto; added web module resolution support.
  • Tests

    • Comprehensive Apple sign-in tests (success, transfer, cancel, error).
  • Bug Fixes

    • Fixed a typo in the Expo web template header.

- 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: 8a30335

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 28, 2025 3:58pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 22, 2025

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Adds native Apple Sign-In to the Expo SDK via a new useSignInWithApple hook (iOS implementation and non‑iOS stub); introduces AppleIdTokenStrategy and related type changes; updates package deps for expo-apple-authentication and expo-crypto; adds tests and Metro/tsconfig adjustments.

Changes

Cohort / File(s) Summary
Changeset
.changeset/brave-apples-sign.md
Documents version bumps and introduces native Apple Sign-In requirement (expo-apple-authentication) and native build requirement.
Type System Updates
packages/types/src/strategies.ts, packages/types/src/signInCommon.ts, packages/types/src/signUpCommon.ts
Adds AppleIdTokenStrategy = 'oauth_token_apple' and extends SignInCreateParams and SignUpCreateParams to accept an Apple ID token-based strategy.
Hook Implementation
packages/expo/src/hooks/useSignInWithApple.ts, packages/expo/src/hooks/useSignInWithApple.ios.ts
Introduces useSignInWithApple with platform-specific behavior: iOS implementation orchestrates expo-apple-authentication, signIn.create and conditional signUp.create flows; non-iOS stub throws a platform-specific error. New public types for params/return included.
Hook Export
packages/expo/src/hooks/index.ts
Adds export * from './useSignInWithApple' to the hooks barrel.
Hook Testing
packages/expo/src/hooks/__tests__/useSignInWithApple.test.ts
Adds comprehensive tests covering success, transfer-to-signup, cancellation, missing token, unavailable Apple auth, and Clerk-unloaded scenarios.
Package Configuration
packages/expo/package.json
Adds dev/peer deps for expo-apple-authentication and expo-crypto (peerDep metadata optional); package version updated.
Module Resolution
packages/expo/tsconfig.json
Adds .web to moduleSuffixes for web-specific module resolution.
Build Configuration
integration/templates/expo-web/metro.config.js
Fixes typo, refactors config initialization, adds monorepo-aware watchFolders/nodeModules resolution, extraNodeModules mappings, expanded blockList, and a custom resolver to handle @clerk subpath exports; exports config directly.

Sequence Diagram(s)

sequenceDiagram
    participant App as App/Component
    participant Hook as useSignInWithApple
    participant ExpoAuth as expo-apple-authentication
    participant Clerk as Clerk SignIn/SignUp

    App->>Hook: startAppleAuthenticationFlow()
    Hook->>Hook: Ensure Clerk hooks loaded
    alt Clerk not loaded
        Hook-->>App: { createdSessionId: null }
    else
        Hook->>ExpoAuth: isAvailableAsync()
        alt Not available
            Hook-->>App: throw error
        else Available
            Hook->>Hook: generate nonce
            Hook->>ExpoAuth: signInAsync(nonce, scopes)
            alt User cancels
                Hook-->>App: { createdSessionId: null }
            else Authorized
                ExpoAuth-->>Hook: identityToken
                alt No identityToken
                    Hook-->>App: throw error
                else Has identityToken
                    Hook->>Clerk: signIn.create({ strategy: oauth_token_apple, token })
                    Clerk-->>Hook: signIn response
                    alt transferable -> signUp
                        Hook->>Clerk: signUp.create({ transfer: true, unsafeMetadata? })
                        Clerk-->>Hook: signUp response with session
                        Hook->>Clerk: setActive({ session })
                        Hook-->>App: { createdSessionId, setActive, signUp }
                    else existing user
                        Hook->>Clerk: setActive({ session })
                        Hook-->>App: { createdSessionId, setActive, signIn }
                    end
                end
            end
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Attention points:
    • packages/expo/src/hooks/useSignInWithApple.ios.ts — branching for transfer-to-signup, nonce handling, error paths.
    • integration/templates/expo-web/metro.config.js — custom resolver and monorepo node resolution logic.
    • packages/types/* — ensure new strategy propagates correctly and doesn't break existing unions.
    • tests — verify mocks faithfully represent runtime behavior and cover edge cases.

"I hopped into code with a twitchy nose,
Apple tokens sparkling where the cool breeze blows,
iOS paths twined with a careful nonce,
Sessions settled, no need to sconce,
A happy rabbit, nibbling new auth prose."

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" directly and accurately captures the primary change in the changeset. The title clearly indicates that a native Apple Sign-In feature is being added to the clerk-expo package specifically for iOS, which aligns with the main objective of introducing a useSignInWithApple hook that leverages expo-apple-authentication. The title is concise, specific, and avoids generic terms; a developer scanning commit history would immediately understand that this PR introduces Apple authentication support for iOS in the Expo library. The title is neither overly broad nor misleading, as all the supporting changes (type definitions, dependencies, Metro config updates) serve the central feature addition described.

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: 8a30335

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/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.

feat(hooks): implement useAppleAuthentication hook for iOS and remove useAppleSignIn.web stub
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: 3

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

98-106: Remove any casts and use the returned SignIn resource to avoid stale reads.

Types now include the oauth_token_apple strategy; we can avoid any and rely on the return of create(). This also prevents reading stale fields from the pre-create signIn object.

-      // 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);
-
-      // Check if we need to transfer to SignUp (user doesn't exist yet)
-      const userNeedsToBeCreated = signIn.firstFactorVerification.status === 'transferable';
+      // Create a SignIn with the Apple ID token strategy
+      const updatedSignIn = await signIn.create({
+        strategy: 'oauth_token_apple',
+        token: identityToken,
+      } as Parameters<typeof signIn.create>[0]);
+
+      // Check if we need to transfer to SignUp (user doesn't exist yet)
+      const userNeedsToBeCreated = updatedSignIn.firstFactorVerification.status === 'transferable';
@@
-      return {
-        createdSessionId: signIn.createdSessionId,
+      return {
+        createdSessionId: updatedSignIn.createdSessionId,
         setActive,
-        signIn,
+        signIn: updatedSignIn,
         signUp,
       };

Also applies to: 123-129

🧹 Nitpick comments (3)
packages/expo/package.json (1)

97-100: Optional peerDeps + static imports can break consumers; consider dynamic import or require peers on iOS.

The iOS hook imports expo-apple-authentication/expo-crypto at module top-level. If a consumer doesn’t install these optional peers, Metro will fail to resolve before runtime checks. Either:

  • Keep them optional and switch to dynamic imports inside startAppleAuthenticationFlow, or
  • Mark them as required peers (remove peerDependenciesMeta optional).

Given our guidelines (“Use dynamic imports for optional features”), I recommend dynamic imports. I’ve included a suggested diff in the iOS file comment.

Also applies to: 107-110, 121-126

packages/expo/src/hooks/useAppleAuthentication.ios.ts (2)

130-140: Handle alternate cancel error codes for robustness.

Expo modules sometimes use ERR_CANCELED; include it to avoid leaking cancellations as errors.

-      if (error && typeof error === 'object' && 'code' in error && error.code === 'ERR_REQUEST_CANCELED') {
+      if (
+        error &&
+        typeof error === 'object' &&
+        'code' in error &&
+        (error as any).code &&
+        ((error as any).code === 'ERR_REQUEST_CANCELED' || (error as any).code === 'ERR_CANCELED')
+      ) {

3-4: Optional: switch to dynamic imports to honor optional peers and reduce startup cost.

If we intend expo-apple-authentication/expo-crypto to be optional, move imports inside the function. This avoids bundle-time resolution failures and loads only when needed.

-import * as AppleAuthentication from 'expo-apple-authentication';
-import * as Crypto from 'expo-crypto';
+// Defer optional peer resolution to call-site
+type AppleAuthMod = typeof import('expo-apple-authentication');
+type CryptoMod = typeof import('expo-crypto');
@@
-    // Check if Apple Authentication is available on the device
-    const isAvailable = await AppleAuthentication.isAvailableAsync();
+    // Lazy-load optional peers
+    const [AppleAuthentication, Crypto] = await Promise.all([
+      import('expo-apple-authentication') as Promise<AppleAuthMod>,
+      import('expo-crypto') as Promise<CryptoMod>,
+    ]);
+
+    // Check if Apple Authentication is available on the device
+    const isAvailable = await AppleAuthentication.isAvailableAsync();
@@
-      const credential = await AppleAuthentication.signInAsync({
+      const credential = await AppleAuthentication.signInAsync({
         requestedScopes: [
           AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
           AppleAuthentication.AppleAuthenticationScope.EMAIL,
         ],
         nonce,
       });

Also applies to: 60-90

📜 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 bed16e5 and ea5e36a.

📒 Files selected for processing (5)
  • packages/expo/package.json (3 hunks)
  • packages/expo/src/hooks/__tests__/useAppleAuthentication.test.ts (1 hunks)
  • packages/expo/src/hooks/index.ts (1 hunks)
  • packages/expo/src/hooks/useAppleAuthentication.ios.ts (1 hunks)
  • packages/expo/src/hooks/useAppleAuthentication.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{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/useAppleAuthentication.ts
  • packages/expo/src/hooks/index.ts
  • packages/expo/src/hooks/__tests__/useAppleAuthentication.test.ts
  • packages/expo/src/hooks/useAppleAuthentication.ios.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/useAppleAuthentication.ts
  • packages/expo/package.json
  • packages/expo/src/hooks/index.ts
  • packages/expo/src/hooks/__tests__/useAppleAuthentication.test.ts
  • packages/expo/src/hooks/useAppleAuthentication.ios.ts
packages/**/*.{ts,tsx}

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

TypeScript is required for all packages

Files:

  • packages/expo/src/hooks/useAppleAuthentication.ts
  • packages/expo/src/hooks/index.ts
  • packages/expo/src/hooks/__tests__/useAppleAuthentication.test.ts
  • packages/expo/src/hooks/useAppleAuthentication.ios.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/useAppleAuthentication.ts
  • packages/expo/src/hooks/index.ts
  • packages/expo/src/hooks/__tests__/useAppleAuthentication.test.ts
  • packages/expo/src/hooks/useAppleAuthentication.ios.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/useAppleAuthentication.ts
  • packages/expo/src/hooks/index.ts
  • packages/expo/src/hooks/__tests__/useAppleAuthentication.test.ts
  • packages/expo/src/hooks/useAppleAuthentication.ios.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/useAppleAuthentication.ts
  • packages/expo/src/hooks/index.ts
  • packages/expo/src/hooks/__tests__/useAppleAuthentication.test.ts
  • packages/expo/src/hooks/useAppleAuthentication.ios.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
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/**/*.{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__/useAppleAuthentication.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__/useAppleAuthentication.test.ts
🧬 Code graph analysis (3)
packages/expo/src/hooks/useAppleAuthentication.ts (4)
packages/expo/src/hooks/useAppleAuthentication.ios.ts (3)
  • StartAppleAuthenticationFlowParams (8-10)
  • StartAppleAuthenticationFlowReturnType (12-17)
  • useAppleAuthentication (56-150)
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__/useAppleAuthentication.test.ts (2)
packages/expo/src/hooks/useAppleAuthentication.ios.ts (1)
  • useAppleAuthentication (56-150)
packages/expo/src/hooks/useAppleAuthentication.ts (1)
  • useAppleAuthentication (52-69)
packages/expo/src/hooks/useAppleAuthentication.ios.ts (4)
packages/expo/src/hooks/useAppleAuthentication.ts (3)
  • StartAppleAuthenticationFlowParams (5-7)
  • StartAppleAuthenticationFlowReturnType (9-14)
  • useAppleAuthentication (52-69)
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). (3)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (2)
packages/expo/package.json (1)

3-3: Confirm versioning aligns with changeset plan.

Version is "2.17.0". Since the PR introduces a new public hook, ensure the changeset promotes @clerk/clerk-expo with a minor bump on release (no manual bump here if changesets control versioning). Please verify the changeset reflects this.

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

14-14: Expose hook via barrel looks good.

Public surface aligned; tree-shaking remains intact given named exports.

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 (3)
packages/expo/src/hooks/__tests__/useAppleAuthentication.test.ts (1)

142-147: Fix incorrect hook and method names in tests.

Three tests call non-existent useAppleSignIn and startAppleSignInFlow. Update to useSignInWithApple and startAppleAuthenticationFlow to match the actual implementation and other tests in this file.

Apply this diff:

-      const { result } = renderHook(() => useAppleSignIn());
+      const { result } = renderHook(() => useSignInWithApple());

-      const response = await result.current.startAppleSignInFlow({
+      const response = await result.current.startAppleAuthenticationFlow({
         unsafeMetadata: { source: 'test' },
       });
-      const { result } = renderHook(() => useAppleSignIn());
+      const { result } = renderHook(() => useSignInWithApple());

-      await expect(result.current.startAppleSignInFlow()).rejects.toThrow(
+      await expect(result.current.startAppleAuthenticationFlow()).rejects.toThrow(
         'Apple Authentication is not available on this device.',
       );
-      const { result } = renderHook(() => useAppleSignIn());
+      const { result } = renderHook(() => useSignInWithApple());

-      await expect(result.current.startAppleSignInFlow()).rejects.toThrow(
+      await expect(result.current.startAppleAuthenticationFlow()).rejects.toThrow(
         'No identity token received from Apple Sign-In.',
       );

Also applies to: 174-179, 186-191

packages/expo/src/hooks/useAppleAuthentication.ios.ts (1)

2-2: Missing type import for SignUpUnsafeMetadata.

SignUpUnsafeMetadata is referenced in StartAppleAuthenticationFlowParams (line 9) but not imported, causing a TypeScript error.

Apply this diff:

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

1-1: Missing type import for SignUpUnsafeMetadata.

SignUpUnsafeMetadata is referenced in StartAppleAuthenticationFlowParams (line 6) but not imported, causing a TypeScript error.

Apply this diff:

-import type { SetActive, SignInResource, SignUpResource } from '@clerk/types';
+import type { SetActive, SignInResource, SignUpResource, SignUpUnsafeMetadata } from '@clerk/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 ea5e36a and ecd27ad.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (4)
  • packages/expo/src/hooks/__tests__/useAppleAuthentication.test.ts (1 hunks)
  • packages/expo/src/hooks/index.ts (1 hunks)
  • packages/expo/src/hooks/useAppleAuthentication.ios.ts (1 hunks)
  • packages/expo/src/hooks/useAppleAuthentication.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{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/index.ts
  • packages/expo/src/hooks/__tests__/useAppleAuthentication.test.ts
  • packages/expo/src/hooks/useAppleAuthentication.ts
  • packages/expo/src/hooks/useAppleAuthentication.ios.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/index.ts
  • packages/expo/src/hooks/__tests__/useAppleAuthentication.test.ts
  • packages/expo/src/hooks/useAppleAuthentication.ts
  • packages/expo/src/hooks/useAppleAuthentication.ios.ts
packages/**/*.{ts,tsx}

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

TypeScript is required for all packages

Files:

  • packages/expo/src/hooks/index.ts
  • packages/expo/src/hooks/__tests__/useAppleAuthentication.test.ts
  • packages/expo/src/hooks/useAppleAuthentication.ts
  • packages/expo/src/hooks/useAppleAuthentication.ios.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/index.ts
  • packages/expo/src/hooks/__tests__/useAppleAuthentication.test.ts
  • packages/expo/src/hooks/useAppleAuthentication.ts
  • packages/expo/src/hooks/useAppleAuthentication.ios.ts
packages/**/index.{js,ts}

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

Use tree-shaking friendly exports

Files:

  • packages/expo/src/hooks/index.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/index.ts
  • packages/expo/src/hooks/__tests__/useAppleAuthentication.test.ts
  • packages/expo/src/hooks/useAppleAuthentication.ts
  • packages/expo/src/hooks/useAppleAuthentication.ios.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/index.ts
  • packages/expo/src/hooks/__tests__/useAppleAuthentication.test.ts
  • packages/expo/src/hooks/useAppleAuthentication.ts
  • packages/expo/src/hooks/useAppleAuthentication.ios.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/**/*.{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__/useAppleAuthentication.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__/useAppleAuthentication.test.ts
🧬 Code graph analysis (3)
packages/expo/src/hooks/__tests__/useAppleAuthentication.test.ts (2)
packages/expo/src/hooks/useAppleAuthentication.ios.ts (1)
  • useSignInWithApple (56-150)
packages/expo/src/hooks/useAppleAuthentication.ts (1)
  • useSignInWithApple (52-69)
packages/expo/src/hooks/useAppleAuthentication.ts (4)
packages/expo/src/hooks/useAppleAuthentication.ios.ts (3)
  • StartAppleAuthenticationFlowParams (8-10)
  • StartAppleAuthenticationFlowReturnType (12-17)
  • useSignInWithApple (56-150)
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/useAppleAuthentication.ios.ts (4)
packages/expo/src/hooks/useAppleAuthentication.ts (3)
  • StartAppleAuthenticationFlowParams (5-7)
  • StartAppleAuthenticationFlowReturnType (9-14)
  • useSignInWithApple (52-69)
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 (1)
packages/expo/src/hooks/index.ts (1)

14-14: LGTM! Clean export addition.

The new export follows the established pattern in this barrel file and properly exposes the useSignInWithApple hook.

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 (4)
packages/expo/src/hooks/useSignInWithApple.ios.ts (2)

98-129: Drop any casts and use returned resources to avoid stale reads.

Remove the as any and rely on updated types. Also use the return value from signIn.create (and signUp.create) instead of reading the pre-call signIn object.

As per coding guidelines.

-      // 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);
-
-      // Check if we need to transfer to SignUp (user doesn't exist yet)
-      const userNeedsToBeCreated = signIn.firstFactorVerification.status === 'transferable';
+      // Create a SignIn with the Apple ID token strategy
+      const updatedSignIn = await signIn.create({
+        strategy: 'oauth_token_apple',
+        token: identityToken,
+      });
+
+      // Check if we need to transfer to SignUp (user doesn't exist yet)
+      const userNeedsToBeCreated = updatedSignIn.firstFactorVerification.status === 'transferable';
@@
-        await signUp.create({
+        const updatedSignUp = await signUp.create({
           transfer: true,
           unsafeMetadata: startAppleAuthenticationFlowParams?.unsafeMetadata,
         });
 
         return {
-          createdSessionId: signUp.createdSessionId,
+          createdSessionId: updatedSignUp.createdSessionId,
           setActive,
-          signIn,
-          signUp,
+          signIn: updatedSignIn,
+          signUp: updatedSignUp,
         };
       }
 
       // User exists - return the SignIn session
       return {
-        createdSessionId: signIn.createdSessionId,
+        createdSessionId: updatedSignIn.createdSessionId,
         setActive,
-        signIn,
+        signIn: updatedSignIn,
         signUp,
       };

1-10: Import missing SignUpUnsafeMetadata type.

The params type uses SignUpUnsafeMetadata but it’s not imported; TS will fail.

As per coding guidelines.

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

1-7: Import missing SignUpUnsafeMetadata type.

StartAppleAuthenticationFlowParams references SignUpUnsafeMetadata but it’s not imported; this breaks type-checking. Add it to the type-only import.

As per coding guidelines.

-import type { SetActive, SignInResource, SignUpResource } from '@clerk/types';
+import type { SetActive, SignInResource, SignUpResource, SignUpUnsafeMetadata } from '@clerk/types';
packages/expo/src/hooks/__tests__/useSignInWithApple.test.ts (1)

142-147: Fix misnamed hook and method in tests.

Rename to the actual exported names: useSignInWithApple and startAppleAuthenticationFlow.

-      const { result } = renderHook(() => useAppleSignIn());
+      const { result } = renderHook(() => useSignInWithApple());
@@
-      const response = await result.current.startAppleSignInFlow({
+      const response = await result.current.startAppleAuthenticationFlow({
         unsafeMetadata: { source: 'test' },
       });
-      const { result } = renderHook(() => useAppleSignIn());
-      await expect(result.current.startAppleSignInFlow()).rejects.toThrow(
+      const { result } = renderHook(() => useSignInWithApple());
+      await expect(result.current.startAppleAuthenticationFlow()).rejects.toThrow(
         'Apple Authentication is not available on this device.',
       );
-      const { result } = renderHook(() => useAppleSignIn());
-      await expect(result.current.startAppleSignInFlow()).rejects.toThrow(
+      const { result } = renderHook(() => useSignInWithApple());
+      await expect(result.current.startAppleAuthenticationFlow()).rejects.toThrow(
         'No identity token received from Apple Sign-In.',
       );

Also applies to: 174-179, 186-191

📜 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 ecd27ad and b4c317b.

📒 Files selected for processing (3)
  • packages/expo/src/hooks/__tests__/useSignInWithApple.test.ts (1 hunks)
  • packages/expo/src/hooks/useSignInWithApple.ios.ts (1 hunks)
  • packages/expo/src/hooks/useSignInWithApple.ts (1 hunks)
🧰 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/useSignInWithApple.ts
  • packages/expo/src/hooks/__tests__/useSignInWithApple.test.ts
  • packages/expo/src/hooks/useSignInWithApple.ios.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/useSignInWithApple.ts
  • packages/expo/src/hooks/__tests__/useSignInWithApple.test.ts
  • packages/expo/src/hooks/useSignInWithApple.ios.ts
packages/**/*.{ts,tsx}

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

TypeScript is required for all packages

Files:

  • packages/expo/src/hooks/useSignInWithApple.ts
  • packages/expo/src/hooks/__tests__/useSignInWithApple.test.ts
  • packages/expo/src/hooks/useSignInWithApple.ios.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/useSignInWithApple.ts
  • packages/expo/src/hooks/__tests__/useSignInWithApple.test.ts
  • packages/expo/src/hooks/useSignInWithApple.ios.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/useSignInWithApple.ts
  • packages/expo/src/hooks/__tests__/useSignInWithApple.test.ts
  • packages/expo/src/hooks/useSignInWithApple.ios.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/useSignInWithApple.ts
  • packages/expo/src/hooks/__tests__/useSignInWithApple.test.ts
  • packages/expo/src/hooks/useSignInWithApple.ios.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__/useSignInWithApple.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__/useSignInWithApple.test.ts
🧬 Code graph analysis (3)
packages/expo/src/hooks/useSignInWithApple.ts (4)
packages/expo/src/hooks/useSignInWithApple.ios.ts (3)
  • StartAppleAuthenticationFlowParams (8-10)
  • StartAppleAuthenticationFlowReturnType (12-17)
  • useSignInWithApple (56-150)
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__/useSignInWithApple.test.ts (2)
packages/expo/src/hooks/useSignInWithApple.ios.ts (1)
  • useSignInWithApple (56-150)
packages/expo/src/hooks/useSignInWithApple.ts (1)
  • useSignInWithApple (52-69)
packages/expo/src/hooks/useSignInWithApple.ios.ts (4)
packages/expo/src/hooks/useSignInWithApple.ts (3)
  • StartAppleAuthenticationFlowParams (5-7)
  • StartAppleAuthenticationFlowReturnType (9-14)
  • useSignInWithApple (52-69)
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 (machine, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (custom, chrome)
  • GitHub Check: Integration Tests (billing, chrome)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 14)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (handshake:staging, chrome)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (elements, chrome)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (localhost, chrome)
  • GitHub Check: Integration Tests (expo-web, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome)
  • GitHub Check: Integration Tests (handshake, chrome)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Integration Tests (sessions:staging, chrome)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Integration Tests (generic, chrome)
  • 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: Publish with pkg-pr-new
  • GitHub Check: Formatting | Dedupe | Changeset
  • 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: 0

🧹 Nitpick comments (8)
packages/expo/src/hooks/__tests__/useSignInWithApple.test.ts (8)

23-32: Harden mock shape for expo-apple-authentication.

Support both star and default import patterns to avoid brittle module resolution issues.

Apply:

-vi.mock('expo-apple-authentication', () => {
-  return {
-    signInAsync: mocks.signInAsync,
-    isAvailableAsync: mocks.isAvailableAsync,
-    AppleAuthenticationScope: {
-      FULL_NAME: 0,
-      EMAIL: 1,
-    },
-  };
-});
+vi.mock('expo-apple-authentication', () => {
+  const AppleAuthenticationScope = { FULL_NAME: 0, EMAIL: 1 };
+  const mod = {
+    signInAsync: mocks.signInAsync,
+    isAvailableAsync: mocks.isAvailableAsync,
+    AppleAuthenticationScope,
+  };
+  return { __esModule: true, ...mod, default: mod };
+});

52-83: Avoid cross-test state leakage; re-initialize per test.

mockSignIn.firstFactorVerification.status is mutated across tests. Re-create fresh objects in beforeEach to remove order coupling.

Apply:

-  const mockSignIn = {
-    create: vi.fn(),
-    createdSessionId: 'test-session-id',
-    firstFactorVerification: {
-      status: 'verified',
-    },
-  };
-
-  const mockSignUp = {
-    create: vi.fn(),
-    createdSessionId: null,
-  };
-
-  const mockSetActive = vi.fn();
+  let mockSignIn: {
+    create: ReturnType<typeof vi.fn>;
+    createdSessionId: string | null;
+    firstFactorVerification: { status: 'verified' | 'transferable' };
+  };
+  let mockSignUp: { create: ReturnType<typeof vi.fn>; createdSessionId: string | null };
+  let mockSetActive: ReturnType<typeof vi.fn>;
@@
-  beforeEach(() => {
-    vi.clearAllMocks();
-
-    mocks.useSignIn.mockReturnValue({
-      signIn: mockSignIn,
-      setActive: mockSetActive,
-      isLoaded: true,
-    });
-
-    mocks.useSignUp.mockReturnValue({
-      signUp: mockSignUp,
-      isLoaded: true,
-    });
+  beforeEach(() => {
+    vi.clearAllMocks();
+
+    mockSignIn = {
+      create: vi.fn(),
+      createdSessionId: 'test-session-id',
+      firstFactorVerification: { status: 'verified' },
+    };
+    mockSignUp = {
+      create: vi.fn(),
+      createdSessionId: null,
+    };
+    mockSetActive = vi.fn();
+
+    mocks.useSignIn.mockReturnValue({ signIn: mockSignIn, setActive: mockSetActive, isLoaded: true });
+    mocks.useSignUp.mockReturnValue({ signUp: mockSignUp, isLoaded: true });

85-88: Prefer clear/reset over restore for hoisted module mocks.

restoreAllMocks mainly affects spies; with hoisted vi.mock, prefer clearAllMocks (already in beforeEach) or resetAllMocks in afterEach to avoid accidentally restoring implementations.

Apply one of:

-  afterEach(() => {
-    vi.restoreAllMocks();
-  });
+  afterEach(() => {
+    vi.clearAllMocks();
+  });

or

-  afterEach(() => {
-    vi.restoreAllMocks();
-  });
+  afterEach(() => {
+    vi.resetAllMocks();
+  });

97-125: Strengthen assertions for Apple scopes and call shape.

Verify requested scopes exactly match FULL_NAME and EMAIL to catch regressions.

Apply:

       expect(mocks.signInAsync).toHaveBeenCalledWith(
         expect.objectContaining({
-          requestedScopes: expect.any(Array),
+          requestedScopes: expect.any(Array),
           nonce: 'test-nonce-uuid',
         }),
       );
+      const callArg = mocks.signInAsync.mock.calls[0][0];
+      expect(callArg.requestedScopes).toEqual([0, 1]); // FULL_NAME, EMAIL

127-157: Also assert setActive is forwarded in transfer flow.

Confirms parity with existing-user path.

Apply:

       expect(response.createdSessionId).toBe('new-user-session-id');
+      expect(response.setActive).toBe(mockSetActive);

171-179: Assert no downstream calls when Apple is unavailable.

Ensure we short-circuit before attempting sign-in or generating nonce.

Apply:

       await expect(result.current.startAppleAuthenticationFlow()).rejects.toThrow(
         'Apple Authentication is not available on this device.',
       );
+      expect(mocks.randomUUID).not.toHaveBeenCalled();
+      expect(mocks.signInAsync).not.toHaveBeenCalled();

181-191: Assert no signIn.create when identity token is missing.

Guards against accidental backend calls without a token.

Apply:

       await expect(result.current.startAppleAuthenticationFlow()).rejects.toThrow(
         'No identity token received from Apple Sign-In.',
       );
+      expect(mockSignIn.create).not.toHaveBeenCalled();

193-207: Add coverage for signUp not loaded and assert nonce/signIn are skipped.

Completes early-return matrix and tightens guarantees.

Apply:

   test('should return early when clerk is not loaded', async () => {
@@
       expect(mocks.signInAsync).not.toHaveBeenCalled();
       expect(response.createdSessionId).toBe(null);
     });
+
+    test('should return early when signUp is not loaded', async () => {
+      mocks.useSignUp.mockReturnValue({
+        signUp: mockSignUp,
+        isLoaded: false,
+      });
+
+      const { result } = renderHook(() => useSignInWithApple());
+      const response = await result.current.startAppleAuthenticationFlow();
+
+      expect(mocks.isAvailableAsync).not.toHaveBeenCalled();
+      expect(mocks.randomUUID).not.toHaveBeenCalled();
+      expect(mocks.signInAsync).not.toHaveBeenCalled();
+      expect(response.createdSessionId).toBe(null);
+    });
📜 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 6839fde and 884ba62.

📒 Files selected for processing (1)
  • packages/expo/src/hooks/__tests__/useSignInWithApple.test.ts (1 hunks)
🧰 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/__tests__/useSignInWithApple.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/__tests__/useSignInWithApple.test.ts
packages/**/*.{ts,tsx}

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

TypeScript is required for all packages

Files:

  • packages/expo/src/hooks/__tests__/useSignInWithApple.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/__tests__/useSignInWithApple.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/__tests__/useSignInWithApple.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__/useSignInWithApple.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/__tests__/useSignInWithApple.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__/useSignInWithApple.test.ts
🧬 Code graph analysis (1)
packages/expo/src/hooks/__tests__/useSignInWithApple.test.ts (1)
packages/expo/src/hooks/useSignInWithApple.ios.ts (1)
  • useSignInWithApple (56-149)
⏰ 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 (billing, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 14)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (localhost, chrome)
  • GitHub Check: Integration Tests (elements, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (expo-web, chrome)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (machine, chrome)
  • GitHub Check: Integration Tests (custom, chrome)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Integration Tests (handshake, chrome)
  • GitHub Check: Integration Tests (handshake:staging, chrome)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Integration Tests (generic, chrome)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Integration Tests (sessions:staging, 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: Static analysis
  • GitHub Check: Unit Tests (22, **)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (2)
packages/expo/src/hooks/__tests__/useSignInWithApple.test.ts (2)

34-41: LGTM on expo-crypto mocking.

Covering both default and named exports avoids import-mode pitfalls.


16-21: Import source verified—mocks will apply correctly.

The implementation imports useSignIn and useSignUp from @clerk/clerk-react (line 1 of useSignInWithApple.ios.ts), which matches the test mock target. The test mocks are correctly configured and will apply as intended.

@chriscanin chriscanin requested a review from dstaley October 28, 2025 15:57
@chriscanin
Copy link
Author

Hi @dstaley & @mikepitre , this PR is ready for review, and the docs and quickstart repo have been updated as well:
clerk/clerk-expo-quickstart#15
clerk/clerk-docs#2732

PS: I realize now with the github enterprise "draft" commits can be made, I will make sure to draft this next time, to not spam inbox and such!

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.

4 participants