@trainon-inc/capacitor-clerk-native 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 TrainOn Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
package/README.md ADDED
@@ -0,0 +1,416 @@
1
+ # capacitor-clerk-native
2
+
3
+ A Capacitor plugin for native Clerk authentication on iOS and Android using the bridge pattern to seamlessly integrate Clerk's native SDKs with CocoaPods/Gradle-based Capacitor plugins.
4
+
5
+ ## The Problem This Solves
6
+
7
+ When using Clerk authentication in Capacitor iOS apps, WebView cookie limitations cause authentication failures with the error:
8
+
9
+ ```
10
+ Browser unauthenticated (dev_browser_unauthenticated)
11
+ ```
12
+
13
+ Additionally, Clerk's iOS SDK is only available via Swift Package Manager (SPM), but Capacitor plugins use CocoaPods, creating a dependency conflict.
14
+
15
+ ## The Solution
16
+
17
+ This plugin uses a **bridge pattern** to resolve the CocoaPods ↔ SPM conflict:
18
+
19
+ 1. **Plugin (CocoaPods)**: Defines a protocol interface without depending on Clerk
20
+ 2. **App Target (SPM)**: Implements the bridge using Clerk's native SDK
21
+ 3. **AppDelegate**: Connects them at runtime
22
+
23
+ This allows your Capacitor app to use Clerk's native iOS/Android SDKs (following the official [Clerk iOS Quickstart](https://clerk.com/docs/ios/getting-started/quickstart)), avoiding WebView cookie issues entirely.
24
+
25
+ ### Why This Approach?
26
+
27
+ - ✅ Uses **official Clerk iOS SDK** - same as native Swift apps
28
+ - ✅ Follows **Clerk's best practices** for iOS integration
29
+ - ✅ **No WebView limitations** - native authentication flows
30
+ - ✅ **CocoaPods compatible** - works with Capacitor's build system
31
+ - ✅ **Reusable** - bridge pattern can be adapted for other native SDKs
32
+
33
+ ## Installation
34
+
35
+ ### From GitHub Packages (Recommended)
36
+
37
+ 1. Create a `.npmrc` file in your project root:
38
+ ```
39
+ @trainon-inc:registry=https://npm.pkg.github.com
40
+ //npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN
41
+ ```
42
+
43
+ 2. Install the package:
44
+ ```bash
45
+ npm install @trainon-inc/capacitor-clerk-native
46
+ # or
47
+ pnpm add @trainon-inc/capacitor-clerk-native
48
+ # or
49
+ yarn add @trainon-inc/capacitor-clerk-native
50
+ ```
51
+
52
+ > **Note**: You'll need a GitHub Personal Access Token with `read:packages` permission. [Create one here](https://github.com/settings/tokens/new?scopes=read:packages)
53
+
54
+ ### From NPM (Future)
55
+
56
+ Once published to npm:
57
+ ```bash
58
+ npm install capacitor-clerk-native
59
+ ```
60
+
61
+ ## iOS Setup
62
+
63
+ ### Prerequisites
64
+
65
+ Before starting, ensure you have:
66
+ - ✅ A [Clerk account](https://dashboard.clerk.com/sign-up)
67
+ - ✅ A Clerk application set up in the dashboard
68
+ - ✅ **Native API enabled** in Clerk Dashboard → Settings → Native Applications
69
+
70
+ > **Important**: You must enable the Native API in your Clerk Dashboard before proceeding. This is required for native iOS integration.
71
+
72
+ ### 1. Register Your iOS App with Clerk
73
+
74
+ 1. Go to the [**Native Applications**](https://dashboard.clerk.com/last-active?path=native-applications) page in Clerk Dashboard
75
+ 2. Click **"Add Application"**
76
+ 3. Enter your iOS app details:
77
+ - **App ID Prefix**: Found in your Apple Developer account or Xcode (Team ID)
78
+ - **Bundle ID**: Your app's bundle identifier (e.g., `com.trainon.member`)
79
+ 4. Note down your **Frontend API URL** (you'll need this for associated domains)
80
+
81
+ ### 2. Add Associated Domain Capability
82
+
83
+ This is required for seamless authentication flows:
84
+
85
+ 1. In Xcode, select your project → Select your **App** target
86
+ 2. Go to **"Signing & Capabilities"** tab
87
+ 3. Click **"+ Capability"** → Add **"Associated Domains"**
88
+ 4. Under Associated Domains, add: `webcredentials:{YOUR_FRONTEND_API_URL}`
89
+ - Example: `webcredentials:guiding-serval-42.clerk.accounts.dev`
90
+ - Get your Frontend API URL from the Native Applications page in Clerk Dashboard
91
+
92
+ ### 3. Add Clerk iOS SDK to Your App Target
93
+
94
+ 1. Open your iOS project in Xcode
95
+ 2. Select your **App** target
96
+ 3. Go to **"Package Dependencies"** tab
97
+ 4. Click **"+"** → **"Add Package Dependency"**
98
+ 5. Enter: `https://github.com/clerk/clerk-ios`
99
+ 6. Select version `0.69.0` or later
100
+ 7. Link to your **App** target
101
+
102
+ ### 4. Create the Bridge Implementation
103
+
104
+ Create a file `ClerkBridgeImpl.swift` in your app's directory:
105
+
106
+ ```swift
107
+ import Foundation
108
+ import Clerk
109
+ import capacitor_clerk_native
110
+
111
+ @MainActor
112
+ class ClerkBridgeImpl: NSObject, ClerkBridge {
113
+ private let clerk = Clerk.shared
114
+
115
+ func signIn(withEmail email: String, password: String, completion: @escaping (String?, Error?) -> Void) {
116
+ Task { @MainActor in
117
+ do {
118
+ let signIn = try await SignIn.create(strategy: .identifier(email))
119
+ let result = try await signIn.attemptFirstFactor(strategy: .password(password: password))
120
+
121
+ if result.status == .complete {
122
+ if let user = clerk.user {
123
+ completion(user.id, nil)
124
+ } else {
125
+ completion(nil, NSError(domain: "ClerkBridge", code: -1, userInfo: [NSLocalizedDescriptionKey: "Sign in completed but no user found"]))
126
+ }
127
+ } else {
128
+ completion(nil, NSError(domain: "ClerkBridge", code: -1, userInfo: [NSLocalizedDescriptionKey: "Sign in not complete"]))
129
+ }
130
+ } catch {
131
+ completion(nil, error)
132
+ }
133
+ }
134
+ }
135
+
136
+ func signUp(withEmail email: String, password: String, completion: @escaping (String?, Error?) -> Void) {
137
+ Task { @MainActor in
138
+ do {
139
+ let signUp = try await SignUp.create(
140
+ strategy: .standard(emailAddress: email, password: password)
141
+ )
142
+
143
+ if let user = clerk.user {
144
+ completion(user.id, nil)
145
+ } else {
146
+ completion(nil, NSError(domain: "ClerkBridge", code: -1, userInfo: [NSLocalizedDescriptionKey: "Sign up completed but no user found"]))
147
+ }
148
+ } catch {
149
+ completion(nil, error)
150
+ }
151
+ }
152
+ }
153
+
154
+ func signOut(completion: @escaping (Error?) -> Void) {
155
+ Task { @MainActor in
156
+ do {
157
+ try await clerk.signOut()
158
+ completion(nil)
159
+ } catch {
160
+ completion(error)
161
+ }
162
+ }
163
+ }
164
+
165
+ func getToken(completion: @escaping (String?, Error?) -> Void) {
166
+ Task { @MainActor in
167
+ do {
168
+ if let session = clerk.session {
169
+ if let token = try await session.getToken() {
170
+ completion(token.jwt, nil)
171
+ } else {
172
+ completion(nil, NSError(domain: "ClerkBridge", code: -1, userInfo: [NSLocalizedDescriptionKey: "No token available"]))
173
+ }
174
+ } else {
175
+ completion(nil, NSError(domain: "ClerkBridge", code: -1, userInfo: [NSLocalizedDescriptionKey: "No active session"]))
176
+ }
177
+ } catch {
178
+ completion(nil, error)
179
+ }
180
+ }
181
+ }
182
+
183
+ func getUser(completion: @escaping ([String: Any]?, Error?) -> Void) {
184
+ Task { @MainActor in
185
+ if let user = clerk.user {
186
+ let userDict: [String: Any] = [
187
+ "id": user.id,
188
+ "firstName": user.firstName ?? NSNull(),
189
+ "lastName": user.lastName ?? NSNull(),
190
+ "emailAddress": user.primaryEmailAddress?.emailAddress ?? NSNull(),
191
+ "imageUrl": user.imageUrl ?? NSNull(),
192
+ "username": user.username ?? NSNull()
193
+ ]
194
+ completion(userDict, nil)
195
+ } else {
196
+ completion(nil, nil)
197
+ }
198
+ }
199
+ }
200
+
201
+ func isSignedIn(completion: @escaping (Bool, Error?) -> Void) {
202
+ Task { @MainActor in
203
+ completion(clerk.user != nil, nil)
204
+ }
205
+ }
206
+ }
207
+ ```
208
+
209
+ ### 5. Update AppDelegate
210
+
211
+ > **Note**: Your AppDelegate should configure Clerk when the app launches, just like in the [Clerk iOS Quickstart](https://clerk.com/docs/ios/getting-started/quickstart).
212
+
213
+ ```swift
214
+ import UIKit
215
+ import Capacitor
216
+ import Clerk
217
+ import capacitor_clerk_native
218
+
219
+ @UIApplicationMain
220
+ class AppDelegate: UIResponder, UIApplicationDelegate {
221
+
222
+ var window: UIWindow?
223
+ private let clerkBridge = ClerkBridgeImpl()
224
+
225
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
226
+ // Configure Clerk
227
+ if let publishableKey = ProcessInfo.processInfo.environment["CLERK_PUBLISHABLE_KEY"] ?? Bundle.main.infoDictionary?["ClerkPublishableKey"] as? String {
228
+ Clerk.shared.configure(publishableKey: publishableKey)
229
+ }
230
+
231
+ // Set up the Clerk bridge for the Capacitor plugin
232
+ ClerkNativePlugin.setClerkBridge(clerkBridge)
233
+
234
+ return true
235
+ }
236
+
237
+ // ... rest of AppDelegate methods
238
+ }
239
+ ```
240
+
241
+ ### 6. Add ClerkBridgeImpl.swift to Xcode Project
242
+
243
+ 1. In Xcode, right-click your **"App"** folder
244
+ 2. Select **"Add Files to 'App'..."**
245
+ 3. Select `ClerkBridgeImpl.swift`
246
+ 4. **Uncheck** "Copy items if needed"
247
+ 5. **Check** the "App" target
248
+ 6. Click **"Add"**
249
+
250
+ ### 7. Configure Clerk Publishable Key
251
+
252
+ > **Important**: Get your Publishable Key from the [**API Keys**](https://dashboard.clerk.com/last-active?path=api-keys) page in Clerk Dashboard.
253
+
254
+ **Option A: Build Settings**
255
+ 1. Select the **App** target → **Build Settings**
256
+ 2. Click **"+"** → **"Add User-Defined Setting"**
257
+ 3. Name: `CLERK_PUBLISHABLE_KEY`
258
+ 4. Value: Your Clerk publishable key
259
+
260
+ **Option B: xcconfig File** (Recommended)
261
+ 1. Create `Config.xcconfig` in your App folder:
262
+ ```
263
+ CLERK_PUBLISHABLE_KEY = pk_test_your_clerk_key_here
264
+ ```
265
+ 2. Add it to Xcode project
266
+ 3. Set it for both Debug and Release configurations in Project Info
267
+
268
+ ### 8. Update Info.plist
269
+
270
+ Add your Clerk publishable key:
271
+
272
+ ```xml
273
+ <key>ClerkPublishableKey</key>
274
+ <string>$(CLERK_PUBLISHABLE_KEY)</string>
275
+ ```
276
+
277
+ ## React/JavaScript Usage
278
+
279
+ ```typescript
280
+ import { ClerkProvider, useAuth, useUser, useSignIn, useSignUp } from '@trainon-inc/capacitor-clerk-native';
281
+
282
+ // Wrap your app
283
+ function App() {
284
+ return (
285
+ <ClerkProvider publishableKey="pk_test_...">
286
+ <YourApp />
287
+ </ClerkProvider>
288
+ );
289
+ }
290
+
291
+ // Use in components
292
+ function LoginPage() {
293
+ const { signIn } = useSignIn();
294
+
295
+ const handleLogin = async () => {
296
+ const result = await signIn.create({
297
+ identifier: email,
298
+ password: password
299
+ });
300
+
301
+ if (result.status === 'complete') {
302
+ // Navigate to app
303
+ }
304
+ };
305
+ }
306
+
307
+ // Get auth state
308
+ function Profile() {
309
+ const { user } = useUser();
310
+ const { getToken } = useAuth();
311
+
312
+ const token = await getToken();
313
+ }
314
+ ```
315
+
316
+ ## Architecture
317
+
318
+ ```
319
+ ┌─────────────────────────────────────────────────┐
320
+ │ JavaScript/React (Capacitor WebView) │
321
+ │ - Uses capacitor-clerk-native hooks │
322
+ └─────────────────┬───────────────────────────────┘
323
+ │ Capacitor Bridge
324
+ ┌─────────────────▼───────────────────────────────┐
325
+ │ ClerkNativePlugin (CocoaPods Pod) │
326
+ │ - Defines ClerkBridge protocol │
327
+ │ - Receives calls from JavaScript │
328
+ │ - Delegates to bridge implementation │
329
+ └─────────────────┬───────────────────────────────┘
330
+ │ Protocol/Delegate
331
+ ┌─────────────────▼───────────────────────────────┐
332
+ │ ClerkBridgeImpl (App Target, SPM) │
333
+ │ - Implements ClerkBridge protocol │
334
+ │ - Uses Clerk iOS SDK directly │
335
+ │ - Handles all Clerk authentication │
336
+ └─────────────────────────────────────────────────┘
337
+ ```
338
+
339
+ ## API
340
+
341
+ ### Methods
342
+
343
+ - `signInWithPassword(email: string, password: string)` - Sign in with email/password
344
+ - `signUp(email: string, password: string)` - Create a new account
345
+ - `signOut()` - Sign out current user
346
+ - `getToken()` - Get the authentication token
347
+ - `getUser()` - Get current user data
348
+ - `isSignedIn()` - Check if user is signed in
349
+
350
+ ### React Hooks
351
+
352
+ - `useAuth()` - Authentication state and methods
353
+ - `useUser()` - Current user data
354
+ - `useSignIn()` - Sign in methods
355
+ - `useSignUp()` - Sign up methods
356
+ - `useClerk()` - Full Clerk context
357
+
358
+ ## Troubleshooting
359
+
360
+ ### Common Issues
361
+
362
+ #### "Browser unauthenticated" error in WebView
363
+ ✅ **Solved!** This plugin uses native SDKs instead of WebView, eliminating this issue entirely.
364
+
365
+ #### "Native API not enabled"
366
+ - Go to Clerk Dashboard → Settings → Native Applications
367
+ - Enable the Native API toggle
368
+ - Refresh your app
369
+
370
+ #### Associated Domain not working
371
+ - Verify you added `webcredentials:{YOUR_FRONTEND_API_URL}` correctly
372
+ - Get the exact URL from Clerk Dashboard → Native Applications
373
+ - Clean build folder and rebuild (Shift+Cmd+K in Xcode)
374
+
375
+ #### "No such module 'Clerk'" in ClerkBridgeImpl
376
+ - Ensure Clerk iOS SDK is added to your App target (not just the project)
377
+ - Check Package Dependencies tab shows Clerk linked to your target
378
+ - Clean and rebuild
379
+
380
+ #### Plugin not found or not responding
381
+ - Run `npx cap sync` to sync the plugin
382
+ - Verify plugin is in node_modules: `@trainon-inc/capacitor-clerk-native`
383
+ - Check Podfile includes the plugin after running cap sync
384
+
385
+ #### Authentication not persisting
386
+ - Clerk handles session persistence automatically
387
+ - Verify `clerk.load()` is called in AppDelegate
388
+ - Check Clerk SDK is properly configured with your publishable key
389
+
390
+ ### Getting Help
391
+
392
+ - 📖 [Clerk iOS Documentation](https://clerk.com/docs/ios)
393
+ - 💬 [Clerk Discord Community](https://clerk.com/discord)
394
+ - 🐛 [Report Issues](https://github.com/TrainOn-Inc/capacitor-clerk-native/issues)
395
+
396
+ ## Android Support
397
+
398
+ Android support is planned. The bridge pattern will work similarly with Gradle and the Clerk Android SDK.
399
+
400
+ ## Contributing
401
+
402
+ Contributions are welcome! This plugin was created to solve a real problem we encountered, and we'd love to make it better.
403
+
404
+ ## License
405
+
406
+ MIT
407
+
408
+ ## Credits
409
+
410
+ Created by the TrainOn Team to solve CocoaPods ↔ SPM conflicts when integrating Clerk authentication in Capacitor iOS apps.
411
+
412
+ ## Support
413
+
414
+ - [GitHub Issues](https://github.com/Trainon-Inc/capacitor-clerk-native/issues)
415
+ - [Clerk Documentation](https://clerk.com/docs)
416
+ - [Capacitor Documentation](https://capacitorjs.com/docs)
@@ -0,0 +1,18 @@
1
+ require 'json'
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = 'TrainonIncCapacitorClerkNative'
7
+ s.version = package['version']
8
+ s.summary = package['description']
9
+ s.license = package['license']
10
+ s.homepage = package['repository']['url']
11
+ s.author = package['author']
12
+ s.source = { :git => package['repository']['url'], :tag => "v#{s.version}" }
13
+ s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
14
+ s.ios.deployment_target = '13.0'
15
+ s.dependency 'Capacitor'
16
+ s.swift_version = '5.1'
17
+ end
18
+
@@ -0,0 +1,66 @@
1
+ package com.trainon.capacitor.clerk;
2
+
3
+ import com.getcapacitor.Plugin;
4
+ import com.getcapacitor.PluginCall;
5
+ import com.getcapacitor.PluginMethod;
6
+ import com.getcapacitor.annotation.CapacitorPlugin;
7
+
8
+ @CapacitorPlugin(name = "ClerkNative")
9
+ public class ClerkNativePlugin extends Plugin {
10
+
11
+ @PluginMethod
12
+ public void configure(PluginCall call) {
13
+ call.reject("Android not yet implemented");
14
+ }
15
+
16
+ @PluginMethod
17
+ public void load(PluginCall call) {
18
+ call.reject("Android not yet implemented");
19
+ }
20
+
21
+ @PluginMethod
22
+ public void signInWithEmail(PluginCall call) {
23
+ call.reject("Android not yet implemented");
24
+ }
25
+
26
+ @PluginMethod
27
+ public void verifyEmailCode(PluginCall call) {
28
+ call.reject("Android not yet implemented");
29
+ }
30
+
31
+ @PluginMethod
32
+ public void signInWithPassword(PluginCall call) {
33
+ call.reject("Android not yet implemented");
34
+ }
35
+
36
+ @PluginMethod
37
+ public void signUp(PluginCall call) {
38
+ call.reject("Android not yet implemented");
39
+ }
40
+
41
+ @PluginMethod
42
+ public void verifySignUpEmail(PluginCall call) {
43
+ call.reject("Android not yet implemented");
44
+ }
45
+
46
+ @PluginMethod
47
+ public void getUser(PluginCall call) {
48
+ call.reject("Android not yet implemented");
49
+ }
50
+
51
+ @PluginMethod
52
+ public void getToken(PluginCall call) {
53
+ call.reject("Android not yet implemented");
54
+ }
55
+
56
+ @PluginMethod
57
+ public void signOut(PluginCall call) {
58
+ call.reject("Android not yet implemented");
59
+ }
60
+
61
+ @PluginMethod
62
+ public void updateUser(PluginCall call) {
63
+ call.reject("Android not yet implemented");
64
+ }
65
+ }
66
+
@@ -0,0 +1,93 @@
1
+ export interface ClerkNativePlugin {
2
+ /**
3
+ * Configure Clerk with publishable key
4
+ */
5
+ configure(options: {
6
+ publishableKey: string;
7
+ }): Promise<void>;
8
+ /**
9
+ * Load Clerk and check for existing session
10
+ */
11
+ load(): Promise<{
12
+ user: ClerkUser | null;
13
+ }>;
14
+ /**
15
+ * Sign in with email code
16
+ */
17
+ signInWithEmail(options: {
18
+ email: string;
19
+ }): Promise<{
20
+ requiresCode: boolean;
21
+ }>;
22
+ /**
23
+ * Verify email code
24
+ */
25
+ verifyEmailCode(options: {
26
+ code: string;
27
+ }): Promise<{
28
+ user: ClerkUser;
29
+ }>;
30
+ /**
31
+ * Sign in with email and password
32
+ */
33
+ signInWithPassword(options: {
34
+ email: string;
35
+ password: string;
36
+ }): Promise<{
37
+ user: ClerkUser;
38
+ }>;
39
+ /**
40
+ * Sign up with email and password
41
+ */
42
+ signUp(options: {
43
+ emailAddress: string;
44
+ password: string;
45
+ firstName?: string;
46
+ lastName?: string;
47
+ }): Promise<{
48
+ user: ClerkUser;
49
+ requiresVerification: boolean;
50
+ }>;
51
+ /**
52
+ * Verify email for sign up
53
+ */
54
+ verifySignUpEmail(options: {
55
+ code: string;
56
+ }): Promise<{
57
+ user: ClerkUser;
58
+ }>;
59
+ /**
60
+ * Get current user
61
+ */
62
+ getUser(): Promise<{
63
+ user: ClerkUser | null;
64
+ }>;
65
+ /**
66
+ * Get authentication token
67
+ */
68
+ getToken(): Promise<{
69
+ token: string | null;
70
+ }>;
71
+ /**
72
+ * Sign out current user
73
+ */
74
+ signOut(): Promise<void>;
75
+ /**
76
+ * Update user profile
77
+ */
78
+ updateUser(options: {
79
+ firstName?: string;
80
+ lastName?: string;
81
+ }): Promise<{
82
+ user: ClerkUser;
83
+ }>;
84
+ }
85
+ export interface ClerkUser {
86
+ id: string;
87
+ firstName: string | null;
88
+ lastName: string | null;
89
+ emailAddress: string | null;
90
+ imageUrl: string | null;
91
+ username: string | null;
92
+ }
93
+ //# sourceMappingURL=definitions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../src/definitions.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE;QAAE,cAAc,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9D;;OAEG;IACH,IAAI,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IAE5C;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,YAAY,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAEhF;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAEzE;;OAEG;IACH,kBAAkB,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAE/F;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE;QACd,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,oBAAoB,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAEhE;;OAEG;IACH,iBAAiB,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAE3E;;OAEG;IACH,OAAO,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IAE/C;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IAE9C;;OAEG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzB;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE;QAClB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=definitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../src/definitions.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import type { ClerkNativePlugin } from './definitions';
2
+ declare const ClerkNative: ClerkNativePlugin;
3
+ export * from './definitions';
4
+ export * from './react';
5
+ export { ClerkNative };
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD,QAAA,MAAM,WAAW,mBAEf,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ import { registerPlugin } from '@capacitor/core';
2
+ const ClerkNative = registerPlugin('ClerkNative', {
3
+ web: () => import('./web').then(m => new m.ClerkNativeWeb()),
4
+ });
5
+ export * from './definitions';
6
+ export * from './react';
7
+ export { ClerkNative };
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,WAAW,GAAG,cAAc,CAAoB,aAAa,EAAE;IACnE,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,CAAC;CAC7D,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,65 @@
1
+ import React from 'react';
2
+ export interface ClerkProviderProps {
3
+ publishableKey: string;
4
+ children: React.ReactNode;
5
+ }
6
+ export declare function ClerkProvider({ publishableKey, children }: ClerkProviderProps): any;
7
+ export declare function useClerk(): any;
8
+ export declare function useUser(): {
9
+ user: any;
10
+ isLoaded: any;
11
+ isSignedIn: any;
12
+ };
13
+ export declare function useAuth(): {
14
+ isSignedIn: any;
15
+ isLoaded: any;
16
+ signOut: any;
17
+ getToken: any;
18
+ };
19
+ export declare function useSignIn(): {
20
+ isLoaded: any;
21
+ signIn: {
22
+ create: ({ identifier, password }: {
23
+ identifier: string;
24
+ password?: string;
25
+ }) => Promise<any>;
26
+ prepareFirstFactor: () => Promise<void>;
27
+ attemptFirstFactor: ({ strategy, code }: {
28
+ strategy: string;
29
+ code?: string;
30
+ }) => Promise<{
31
+ status: string;
32
+ createdSessionId: string;
33
+ } | {
34
+ status: string;
35
+ createdSessionId?: undefined;
36
+ }>;
37
+ };
38
+ setActive: () => Promise<void>;
39
+ };
40
+ export declare function useSignUp(): {
41
+ isLoaded: any;
42
+ signUp: {
43
+ create: (options: {
44
+ emailAddress: string;
45
+ password: string;
46
+ firstName?: string;
47
+ lastName?: string;
48
+ }) => Promise<{
49
+ status: string;
50
+ }>;
51
+ prepareVerification: () => Promise<void>;
52
+ attemptVerification: ({ strategy, code }: {
53
+ strategy: string;
54
+ code: string;
55
+ }) => Promise<{
56
+ status: string;
57
+ createdSessionId: string;
58
+ } | {
59
+ status: string;
60
+ createdSessionId?: undefined;
61
+ }>;
62
+ };
63
+ setActive: () => Promise<void>;
64
+ };
65
+ //# sourceMappingURL=react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsE,MAAM,OAAO,CAAC;AAyB3F,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,aAAa,CAAC,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,kBAAkB,OAyF7E;AAED,wBAAgB,QAAQ,QAMvB;AAED,wBAAgB,OAAO;;;;EAGtB;AAED,wBAAgB,OAAO;;;;;EAGtB;AAED,wBAAgB,SAAS;;;2CAKsB;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;SAAE;;iDAYnC;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,CAAA;SAAE;;;;;;;;;EAYvF;AAED,wBAAgB,SAAS;;;0BAKK;YACtB,YAAY,EAAE,MAAM,CAAC;YACrB,QAAQ,EAAE,MAAM,CAAC;YACjB,SAAS,CAAC,EAAE,MAAM,CAAC;YACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB;;;;kDAO+C;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE;;;;;;;;;EAYvF"}
package/dist/react.js ADDED
@@ -0,0 +1,142 @@
1
+ import React, { createContext, useContext, useEffect, useState, useCallback } from 'react';
2
+ import { ClerkNative } from './index';
3
+ const ClerkContext = createContext(null);
4
+ export function ClerkProvider({ publishableKey, children }) {
5
+ const [isLoaded, setIsLoaded] = useState(false);
6
+ const [user, setUser] = useState(null);
7
+ useEffect(() => {
8
+ const initClerk = async () => {
9
+ try {
10
+ await ClerkNative.configure({ publishableKey });
11
+ const result = await ClerkNative.load();
12
+ setUser(result.user);
13
+ setIsLoaded(true);
14
+ }
15
+ catch (error) {
16
+ console.error('Failed to initialize Clerk:', error);
17
+ setIsLoaded(true);
18
+ }
19
+ };
20
+ initClerk();
21
+ }, [publishableKey]);
22
+ const signInWithEmail = useCallback(async (email) => {
23
+ const result = await ClerkNative.signInWithEmail({ email });
24
+ return result;
25
+ }, []);
26
+ const verifyEmailCode = useCallback(async (code) => {
27
+ const result = await ClerkNative.verifyEmailCode({ code });
28
+ setUser(result.user);
29
+ }, []);
30
+ const signInWithPassword = useCallback(async (email, password) => {
31
+ const result = await ClerkNative.signInWithPassword({ email, password });
32
+ setUser(result.user);
33
+ }, []);
34
+ const signUp = useCallback(async (options) => {
35
+ const result = await ClerkNative.signUp(options);
36
+ if (!result.requiresVerification) {
37
+ setUser(result.user);
38
+ }
39
+ return result;
40
+ }, []);
41
+ const verifySignUpEmail = useCallback(async (code) => {
42
+ const result = await ClerkNative.verifySignUpEmail({ code });
43
+ setUser(result.user);
44
+ }, []);
45
+ const signOut = useCallback(async () => {
46
+ await ClerkNative.signOut();
47
+ setUser(null);
48
+ }, []);
49
+ const getToken = useCallback(async () => {
50
+ const result = await ClerkNative.getToken();
51
+ return result.token;
52
+ }, []);
53
+ const updateUser = useCallback(async (options) => {
54
+ const result = await ClerkNative.updateUser(options);
55
+ setUser(result.user);
56
+ }, []);
57
+ const value = {
58
+ isLoaded,
59
+ isSignedIn: user !== null,
60
+ user,
61
+ signInWithEmail,
62
+ verifyEmailCode,
63
+ signInWithPassword,
64
+ signUp,
65
+ verifySignUpEmail,
66
+ signOut,
67
+ getToken,
68
+ updateUser,
69
+ };
70
+ return React.createElement(ClerkContext.Provider, { value: value }, children);
71
+ }
72
+ export function useClerk() {
73
+ const context = useContext(ClerkContext);
74
+ if (!context) {
75
+ throw new Error('useClerk must be used within a ClerkProvider');
76
+ }
77
+ return context;
78
+ }
79
+ export function useUser() {
80
+ const { user, isLoaded, isSignedIn } = useClerk();
81
+ return { user, isLoaded, isSignedIn };
82
+ }
83
+ export function useAuth() {
84
+ const { isSignedIn, isLoaded, signOut, getToken } = useClerk();
85
+ return { isSignedIn, isLoaded, signOut, getToken };
86
+ }
87
+ export function useSignIn() {
88
+ const { signInWithEmail, verifyEmailCode, signInWithPassword, isLoaded } = useClerk();
89
+ return {
90
+ isLoaded,
91
+ signIn: {
92
+ create: async ({ identifier, password }) => {
93
+ // If password is provided, sign in directly with password
94
+ if (password) {
95
+ await signInWithPassword(identifier, password);
96
+ return { status: 'complete', createdSessionId: 'session' };
97
+ }
98
+ // Otherwise, use email code flow
99
+ return signInWithEmail(identifier);
100
+ },
101
+ prepareFirstFactor: async () => {
102
+ // Already handled in signInWithEmail
103
+ },
104
+ attemptFirstFactor: async ({ strategy, code }) => {
105
+ if (strategy === 'email_code' && code) {
106
+ await verifyEmailCode(code);
107
+ return { status: 'complete', createdSessionId: 'session' };
108
+ }
109
+ return { status: 'needs_verification' };
110
+ },
111
+ },
112
+ setActive: async () => {
113
+ // Session is automatically set in native plugin
114
+ },
115
+ };
116
+ }
117
+ export function useSignUp() {
118
+ const { signUp, verifySignUpEmail, isLoaded } = useClerk();
119
+ return {
120
+ isLoaded,
121
+ signUp: {
122
+ create: async (options) => {
123
+ await signUp(options);
124
+ return { status: 'needs_verification' };
125
+ },
126
+ prepareVerification: async () => {
127
+ // Already handled in signUp
128
+ },
129
+ attemptVerification: async ({ strategy, code }) => {
130
+ if (strategy === 'email_code') {
131
+ await verifySignUpEmail(code);
132
+ return { status: 'complete', createdSessionId: 'session' };
133
+ }
134
+ return { status: 'needs_verification' };
135
+ },
136
+ },
137
+ setActive: async () => {
138
+ // Session is automatically set in native plugin
139
+ },
140
+ };
141
+ }
142
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.tsx"],"names":[],"mappings":"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"}
package/dist/web.d.ts ADDED
@@ -0,0 +1,54 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ import type { ClerkNativePlugin, ClerkUser } from './definitions';
3
+ export declare class ClerkNativeWeb extends WebPlugin implements ClerkNativePlugin {
4
+ configure(_options: {
5
+ publishableKey: string;
6
+ }): Promise<void>;
7
+ load(): Promise<{
8
+ user: ClerkUser | null;
9
+ }>;
10
+ signInWithEmail(_options: {
11
+ email: string;
12
+ }): Promise<{
13
+ requiresCode: boolean;
14
+ }>;
15
+ verifyEmailCode(_options: {
16
+ code: string;
17
+ }): Promise<{
18
+ user: ClerkUser;
19
+ }>;
20
+ signInWithPassword(_options: {
21
+ email: string;
22
+ password: string;
23
+ }): Promise<{
24
+ user: ClerkUser;
25
+ }>;
26
+ signUp(_options: {
27
+ emailAddress: string;
28
+ password: string;
29
+ firstName?: string;
30
+ lastName?: string;
31
+ }): Promise<{
32
+ user: ClerkUser;
33
+ requiresVerification: boolean;
34
+ }>;
35
+ verifySignUpEmail(_options: {
36
+ code: string;
37
+ }): Promise<{
38
+ user: ClerkUser;
39
+ }>;
40
+ getUser(): Promise<{
41
+ user: ClerkUser | null;
42
+ }>;
43
+ getToken(): Promise<{
44
+ token: string | null;
45
+ }>;
46
+ signOut(): Promise<void>;
47
+ updateUser(_options: {
48
+ firstName?: string;
49
+ lastName?: string;
50
+ }): Promise<{
51
+ user: ClerkUser;
52
+ }>;
53
+ }
54
+ //# sourceMappingURL=web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAElE,qBAAa,cAAe,SAAQ,SAAU,YAAW,iBAAiB;IAClE,SAAS,CAAC,QAAQ,EAAE;QAAE,cAAc,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9D,IAAI,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAAA;KAAE,CAAC;IAI3C,eAAe,CAAC,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,YAAY,EAAE,OAAO,CAAA;KAAE,CAAC;IAIhF,eAAe,CAAC,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC;IAIzE,kBAAkB,CAAC,QAAQ,EAAE;QACjC,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC;IAI1B,MAAM,CAAC,QAAQ,EAAE;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,SAAS,CAAC;QAAC,oBAAoB,EAAE,OAAO,CAAA;KAAE,CAAC;IAIzD,iBAAiB,CAAC,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC;IAI3E,OAAO,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAAA;KAAE,CAAC;IAI9C,QAAQ,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAI7C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,UAAU,CAAC,QAAQ,EAAE;QACzB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,SAAS,CAAA;KAAE,CAAC;CAGjC"}
package/dist/web.js ADDED
@@ -0,0 +1,37 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ export class ClerkNativeWeb extends WebPlugin {
3
+ async configure(_options) {
4
+ throw this.unimplemented('Clerk Native is only available on iOS and Android');
5
+ }
6
+ async load() {
7
+ throw this.unimplemented('Clerk Native is only available on iOS and Android');
8
+ }
9
+ async signInWithEmail(_options) {
10
+ throw this.unimplemented('Clerk Native is only available on iOS and Android');
11
+ }
12
+ async verifyEmailCode(_options) {
13
+ throw this.unimplemented('Clerk Native is only available on iOS and Android');
14
+ }
15
+ async signInWithPassword(_options) {
16
+ throw this.unimplemented('Clerk Native is only available on iOS and Android');
17
+ }
18
+ async signUp(_options) {
19
+ throw this.unimplemented('Clerk Native is only available on iOS and Android');
20
+ }
21
+ async verifySignUpEmail(_options) {
22
+ throw this.unimplemented('Clerk Native is only available on iOS and Android');
23
+ }
24
+ async getUser() {
25
+ throw this.unimplemented('Clerk Native is only available on iOS and Android');
26
+ }
27
+ async getToken() {
28
+ throw this.unimplemented('Clerk Native is only available on iOS and Android');
29
+ }
30
+ async signOut() {
31
+ throw this.unimplemented('Clerk Native is only available on iOS and Android');
32
+ }
33
+ async updateUser(_options) {
34
+ throw this.unimplemented('Clerk Native is only available on iOS and Android');
35
+ }
36
+ }
37
+ //# sourceMappingURL=web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,MAAM,OAAO,cAAe,SAAQ,SAAS;IAC3C,KAAK,CAAC,SAAS,CAAC,QAAoC;QAClD,MAAM,IAAI,CAAC,aAAa,CAAC,mDAAmD,CAAC,CAAC;IAChF,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,CAAC,aAAa,CAAC,mDAAmD,CAAC,CAAC;IAChF,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,QAA2B;QAC/C,MAAM,IAAI,CAAC,aAAa,CAAC,mDAAmD,CAAC,CAAC;IAChF,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,QAA0B;QAC9C,MAAM,IAAI,CAAC,aAAa,CAAC,mDAAmD,CAAC,CAAC;IAChF,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,QAGxB;QACC,MAAM,IAAI,CAAC,aAAa,CAAC,mDAAmD,CAAC,CAAC;IAChF,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,QAKZ;QACC,MAAM,IAAI,CAAC,aAAa,CAAC,mDAAmD,CAAC,CAAC;IAChF,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,QAA0B;QAChD,MAAM,IAAI,CAAC,aAAa,CAAC,mDAAmD,CAAC,CAAC;IAChF,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,IAAI,CAAC,aAAa,CAAC,mDAAmD,CAAC,CAAC;IAChF,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,IAAI,CAAC,aAAa,CAAC,mDAAmD,CAAC,CAAC;IAChF,CAAC;IAED,KAAK,CAAC,OAAO;QACX,MAAM,IAAI,CAAC,aAAa,CAAC,mDAAmD,CAAC,CAAC;IAChF,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,QAGhB;QACC,MAAM,IAAI,CAAC,aAAa,CAAC,mDAAmD,CAAC,CAAC;IAChF,CAAC;CACF"}
@@ -0,0 +1,17 @@
1
+ #import <Foundation/Foundation.h>
2
+ #import <Capacitor/Capacitor.h>
3
+
4
+ CAP_PLUGIN(ClerkNativePlugin, "ClerkNative",
5
+ CAP_PLUGIN_METHOD(configure, CAPPluginReturnPromise);
6
+ CAP_PLUGIN_METHOD(load, CAPPluginReturnPromise);
7
+ CAP_PLUGIN_METHOD(signInWithEmail, CAPPluginReturnPromise);
8
+ CAP_PLUGIN_METHOD(verifyEmailCode, CAPPluginReturnPromise);
9
+ CAP_PLUGIN_METHOD(signInWithPassword, CAPPluginReturnPromise);
10
+ CAP_PLUGIN_METHOD(signUp, CAPPluginReturnPromise);
11
+ CAP_PLUGIN_METHOD(verifySignUpEmail, CAPPluginReturnPromise);
12
+ CAP_PLUGIN_METHOD(getUser, CAPPluginReturnPromise);
13
+ CAP_PLUGIN_METHOD(getToken, CAPPluginReturnPromise);
14
+ CAP_PLUGIN_METHOD(signOut, CAPPluginReturnPromise);
15
+ CAP_PLUGIN_METHOD(updateUser, CAPPluginReturnPromise);
16
+ )
17
+
@@ -0,0 +1,171 @@
1
+ import Foundation
2
+ import Capacitor
3
+
4
+ // Protocol for Clerk bridge - the App target will implement this
5
+ @objc public protocol ClerkBridge: AnyObject {
6
+ func signIn(withEmail email: String, password: String, completion: @escaping (String?, Error?) -> Void)
7
+ func signUp(withEmail email: String, password: String, completion: @escaping (String?, Error?) -> Void)
8
+ func signOut(completion: @escaping (Error?) -> Void)
9
+ func getToken(completion: @escaping (String?, Error?) -> Void)
10
+ func getUser(completion: @escaping ([String: Any]?, Error?) -> Void)
11
+ func isSignedIn(completion: @escaping (Bool, Error?) -> Void)
12
+ }
13
+
14
+ @objc(ClerkNativePlugin)
15
+ public class ClerkNativePlugin: CAPPlugin {
16
+ private weak var clerkBridge: ClerkBridge?
17
+
18
+ @objc public static func setClerkBridge(_ bridge: ClerkBridge) {
19
+ // Store bridge in a static property accessible to all plugin instances
20
+ ClerkNativePlugin.sharedBridge = bridge
21
+ }
22
+
23
+ private static var sharedBridge: ClerkBridge?
24
+
25
+ public override func load() {
26
+ super.load()
27
+ clerkBridge = ClerkNativePlugin.sharedBridge
28
+ }
29
+
30
+ @objc func configure(_ call: CAPPluginCall) {
31
+ // Configuration is now handled by the bridge in AppDelegate
32
+ call.resolve()
33
+ }
34
+
35
+ @objc func load(_ call: CAPPluginCall) {
36
+ guard let bridge = clerkBridge else {
37
+ call.reject("Clerk bridge not configured")
38
+ return
39
+ }
40
+
41
+ bridge.getUser { user, error in
42
+ if let error = error {
43
+ call.reject("Failed to load Clerk: \(error.localizedDescription)")
44
+ } else {
45
+ call.resolve(["user": user ?? NSNull()])
46
+ }
47
+ }
48
+ }
49
+
50
+ @objc func signInWithPassword(_ call: CAPPluginCall) {
51
+ guard let bridge = clerkBridge else {
52
+ call.reject("Clerk bridge not configured")
53
+ return
54
+ }
55
+
56
+ guard let email = call.getString("email"),
57
+ let password = call.getString("password") else {
58
+ call.reject("Must provide email and password")
59
+ return
60
+ }
61
+
62
+ bridge.signIn(withEmail: email, password: password) { userId, error in
63
+ if let error = error {
64
+ call.reject("Sign in failed: \(error.localizedDescription)")
65
+ } else {
66
+ // Get the full user after sign in
67
+ bridge.getUser { user, getUserError in
68
+ if let getUserError = getUserError {
69
+ call.reject("Sign in succeeded but failed to get user: \(getUserError.localizedDescription)")
70
+ } else {
71
+ call.resolve(["user": user ?? NSNull()])
72
+ }
73
+ }
74
+ }
75
+ }
76
+ }
77
+
78
+ @objc func signUp(_ call: CAPPluginCall) {
79
+ guard let bridge = clerkBridge else {
80
+ call.reject("Clerk bridge not configured")
81
+ return
82
+ }
83
+
84
+ guard let email = call.getString("emailAddress"),
85
+ let password = call.getString("password") else {
86
+ call.reject("Must provide emailAddress and password")
87
+ return
88
+ }
89
+
90
+ bridge.signUp(withEmail: email, password: password) { userId, error in
91
+ if let error = error {
92
+ call.reject("Sign up failed: \(error.localizedDescription)")
93
+ } else {
94
+ // Get the full user after sign up
95
+ bridge.getUser { user, getUserError in
96
+ if let getUserError = getUserError {
97
+ call.reject("Sign up succeeded but failed to get user: \(getUserError.localizedDescription)")
98
+ } else {
99
+ call.resolve(["user": user ?? NSNull(), "requiresVerification": false])
100
+ }
101
+ }
102
+ }
103
+ }
104
+ }
105
+
106
+ @objc func getUser(_ call: CAPPluginCall) {
107
+ guard let bridge = clerkBridge else {
108
+ call.reject("Clerk bridge not configured")
109
+ return
110
+ }
111
+
112
+ bridge.getUser { user, error in
113
+ if let error = error {
114
+ call.reject("Failed to get user: \(error.localizedDescription)")
115
+ } else {
116
+ call.resolve(["user": user ?? NSNull()])
117
+ }
118
+ }
119
+ }
120
+
121
+ @objc func getToken(_ call: CAPPluginCall) {
122
+ guard let bridge = clerkBridge else {
123
+ call.reject("Clerk bridge not configured")
124
+ return
125
+ }
126
+
127
+ bridge.getToken { token, error in
128
+ if let error = error {
129
+ call.reject("Failed to get token: \(error.localizedDescription)")
130
+ } else {
131
+ call.resolve(["token": token ?? NSNull()])
132
+ }
133
+ }
134
+ }
135
+
136
+ @objc func signOut(_ call: CAPPluginCall) {
137
+ guard let bridge = clerkBridge else {
138
+ call.reject("Clerk bridge not configured")
139
+ return
140
+ }
141
+
142
+ bridge.signOut { error in
143
+ if let error = error {
144
+ call.reject("Sign out failed: \(error.localizedDescription)")
145
+ } else {
146
+ call.resolve()
147
+ }
148
+ }
149
+ }
150
+
151
+ @objc func signInWithEmail(_ call: CAPPluginCall) {
152
+ // For now, this just indicates that email code is required
153
+ // The actual sign-in happens with signInWithPassword
154
+ call.resolve(["requiresCode": false])
155
+ }
156
+
157
+ @objc func verifyEmailCode(_ call: CAPPluginCall) {
158
+ // Email code verification - not implemented in simplified bridge
159
+ call.reject("Email code verification not implemented")
160
+ }
161
+
162
+ @objc func verifySignUpEmail(_ call: CAPPluginCall) {
163
+ // Sign up email verification - not implemented in simplified bridge
164
+ call.reject("Sign up email verification not implemented")
165
+ }
166
+
167
+ @objc func updateUser(_ call: CAPPluginCall) {
168
+ // User update - not implemented in simplified bridge
169
+ call.reject("Update user not implemented")
170
+ }
171
+ }
package/package.json ADDED
@@ -0,0 +1,81 @@
1
+ {
2
+ "name": "@trainon-inc/capacitor-clerk-native",
3
+ "version": "1.10.0",
4
+ "description": "Capacitor plugin for Clerk native authentication using bridge pattern to integrate Clerk iOS/Android SDKs with CocoaPods/Gradle",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "import": "./dist/index.js",
14
+ "require": "./dist/index.js",
15
+ "types": "./dist/index.d.ts"
16
+ }
17
+ },
18
+ "files": [
19
+ "android/src/main/",
20
+ "android/build.gradle",
21
+ "dist/",
22
+ "ios/Plugin/",
23
+ "TrainonIncCapacitorClerkNative.podspec",
24
+ "README.md",
25
+ "LICENSE"
26
+ ],
27
+ "author": "TrainOn Team",
28
+ "license": "MIT",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/TrainOn-Inc/capacitor-clerk-native.git"
32
+ },
33
+ "bugs": {
34
+ "url": "https://github.com/TrainOn-Inc/capacitor-clerk-native/issues"
35
+ },
36
+ "homepage": "https://github.com/TrainOn-Inc/capacitor-clerk-native#readme",
37
+ "keywords": [
38
+ "capacitor",
39
+ "capacitor-plugin",
40
+ "plugin",
41
+ "native",
42
+ "clerk",
43
+ "clerk-auth",
44
+ "authentication",
45
+ "ios",
46
+ "android",
47
+ "cocoapods",
48
+ "swift-package-manager",
49
+ "bridge-pattern"
50
+ ],
51
+ "scripts": {
52
+ "build": "tsc",
53
+ "clean": "rm -rf ./dist",
54
+ "watch": "tsc --watch",
55
+ "prepublishOnly": "npm run clean && npm run build",
56
+ "version": "npm run build",
57
+ "postversion": "git push && git push --tags"
58
+ },
59
+ "devDependencies": {
60
+ "@capacitor/android": "^6.0.0",
61
+ "@capacitor/core": "^6.0.0",
62
+ "@capacitor/ios": "^6.0.0",
63
+ "react": "^19.0.0",
64
+ "typescript": "5.9.3"
65
+ },
66
+ "peerDependencies": {
67
+ "@capacitor/core": "^6.0.0 || ^7.0.0"
68
+ },
69
+ "prettier": "@ionic/prettier-config",
70
+ "eslintConfig": {
71
+ "extends": "@ionic/eslint-config/recommended"
72
+ },
73
+ "capacitor": {
74
+ "ios": {
75
+ "src": "ios"
76
+ },
77
+ "android": {
78
+ "src": "android"
79
+ }
80
+ }
81
+ }