@veliseev93/clerk-react-native 0.0.1-dev.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/dist/index.mjs ADDED
@@ -0,0 +1,611 @@
1
+ // src/enums/api-error.ts
2
+ var ClerkApiError = /* @__PURE__ */ ((ClerkApiError2) => {
3
+ ClerkApiError2["SESSION_EXISTS"] = "session_exists";
4
+ ClerkApiError2["FORM_IDENTIFIER_EXIST"] = "form_identifier_exists";
5
+ ClerkApiError2["FORM_CODE_INCORRECT"] = "form_code_incorrect";
6
+ return ClerkApiError2;
7
+ })(ClerkApiError || {});
8
+
9
+ // src/hooks/use-clerk-resources.ts
10
+ import { getClerkInstance } from "@clerk/clerk-expo";
11
+ var useClerkResources = () => {
12
+ const clerk = getClerkInstance();
13
+ const signUp = clerk.client?.signUp;
14
+ const signIn = clerk.client?.signIn;
15
+ const signOut = clerk.signOut;
16
+ const setActive = clerk.setActive;
17
+ return { signUp, signIn, setActive, signOut };
18
+ };
19
+
20
+ // src/hooks/use-get-session-token.ts
21
+ import { getClerkInstance as getClerkInstance2 } from "@clerk/clerk-expo";
22
+ var useGetSessionToken = () => {
23
+ const clerk = getClerkInstance2();
24
+ const getSessionToken = async ({ tokenTemplate }) => {
25
+ try {
26
+ const token = await clerk.session?.getToken({ template: tokenTemplate });
27
+ const sessionToken = token || clerk.session?.lastActiveToken?.getRawString();
28
+ if (sessionToken) {
29
+ return {
30
+ sessionToken,
31
+ isSuccess: true
32
+ };
33
+ } else {
34
+ return {
35
+ sessionToken: null,
36
+ isSuccess: false
37
+ };
38
+ }
39
+ } catch (error) {
40
+ return {
41
+ sessionToken: null,
42
+ error,
43
+ isSuccess: false
44
+ };
45
+ }
46
+ };
47
+ return { getSessionToken };
48
+ };
49
+
50
+ // src/hooks/use-auth-with-sso.ts
51
+ import { useSSO } from "@clerk/clerk-expo";
52
+ import { useState } from "react";
53
+ function useAuthWithSSO() {
54
+ const { startSSOFlow: clerkStartSSOFlow } = useSSO();
55
+ const { getSessionToken } = useGetSessionToken();
56
+ const [isLoading, setIsLoading] = useState(false);
57
+ const startSSOFlow = async ({
58
+ strategy,
59
+ redirectUrl,
60
+ tokenTemplate
61
+ }) => {
62
+ try {
63
+ setIsLoading(true);
64
+ const { createdSessionId, setActive, signIn, signUp } = await clerkStartSSOFlow({
65
+ strategy,
66
+ redirectUrl
67
+ });
68
+ if (!createdSessionId) {
69
+ return { sessionToken: null };
70
+ }
71
+ await setActive?.({ session: createdSessionId });
72
+ const { sessionToken } = await getSessionToken({ tokenTemplate });
73
+ if (sessionToken) {
74
+ return {
75
+ sessionToken,
76
+ signIn,
77
+ signUp,
78
+ isSuccess: true
79
+ };
80
+ }
81
+ return {
82
+ signIn,
83
+ signUp,
84
+ isSuccess: false
85
+ };
86
+ } catch (error) {
87
+ return {
88
+ error,
89
+ isSuccess: false
90
+ };
91
+ } finally {
92
+ setIsLoading(false);
93
+ }
94
+ };
95
+ return { startSSOFlow, isLoading };
96
+ }
97
+
98
+ // src/hooks/use-auth-with-ticket.ts
99
+ import { useState as useState2 } from "react";
100
+ function useAuthWithTicket() {
101
+ const { signIn, setActive } = useClerkResources();
102
+ const { getSessionToken } = useGetSessionToken();
103
+ const [isLoading, setIsLoading] = useState2(false);
104
+ const startAuthorization = async ({ ticket, tokenTemplate }) => {
105
+ if (signIn) {
106
+ setIsLoading(true);
107
+ try {
108
+ const signInAttempt = await signIn.create({
109
+ strategy: "ticket",
110
+ ticket
111
+ });
112
+ if (signInAttempt.status === "complete") {
113
+ await setActive({
114
+ session: signInAttempt.createdSessionId
115
+ });
116
+ const { sessionToken, error } = await getSessionToken({ tokenTemplate });
117
+ if (sessionToken) {
118
+ return {
119
+ sessionToken,
120
+ signIn,
121
+ isSuccess: true
122
+ };
123
+ }
124
+ return {
125
+ signIn,
126
+ error,
127
+ isSuccess: false
128
+ };
129
+ }
130
+ } catch (error) {
131
+ return {
132
+ signIn,
133
+ error,
134
+ isSuccess: false
135
+ };
136
+ } finally {
137
+ setIsLoading(false);
138
+ }
139
+ }
140
+ return {
141
+ sessionToken: null,
142
+ signIn,
143
+ isSuccess: false
144
+ };
145
+ };
146
+ return {
147
+ startAuthorization,
148
+ isLoading
149
+ };
150
+ }
151
+
152
+ // src/hooks/use-otp-verification.ts
153
+ import { useState as useState3 } from "react";
154
+ function useOtpVerification() {
155
+ const { signUp, signIn, setActive } = useClerkResources();
156
+ const { getSessionToken } = useGetSessionToken();
157
+ const [isVerifying, setIsVerifying] = useState3(false);
158
+ const sendSignInOtpCode = async (strategy, isSecondFactor = false) => {
159
+ const codeFactors = isSecondFactor ? signIn?.supportedSecondFactors : signIn?.supportedFirstFactors;
160
+ const prepareFactor = isSecondFactor ? signIn?.prepareSecondFactor : signIn?.prepareFirstFactor;
161
+ const codeFactor = codeFactors?.find(
162
+ (factor) => factor.strategy === strategy
163
+ );
164
+ if (codeFactor && "emailAddressId" in codeFactor) {
165
+ await prepareFactor?.({ strategy: "email_code", emailAddressId: codeFactor.emailAddressId });
166
+ } else if (codeFactor && "phoneNumberId" in codeFactor) {
167
+ await prepareFactor?.({ strategy: "phone_code", phoneNumberId: codeFactor.phoneNumberId });
168
+ } else {
169
+ throw new Error(`No ${isSecondFactor ? "second " : ""}factor found for strategy: ${strategy}`);
170
+ }
171
+ };
172
+ const sendSignUpOtpCode = async (strategy) => {
173
+ if (!signUp) return;
174
+ await signUp.prepareVerification({ strategy });
175
+ };
176
+ const sendOtpCode = async ({ strategy, isSignUp, isSecondFactor }) => {
177
+ if (isSignUp) {
178
+ await sendSignUpOtpCode(strategy);
179
+ } else {
180
+ await sendSignInOtpCode(strategy, !!isSecondFactor);
181
+ }
182
+ };
183
+ const verifyCode = async ({
184
+ code,
185
+ strategy,
186
+ tokenTemplate,
187
+ isSignUp,
188
+ isSecondFactor
189
+ }) => {
190
+ try {
191
+ setIsVerifying(true);
192
+ if (isSignUp) {
193
+ const completeSignUp = await signUp?.attemptVerification({
194
+ strategy,
195
+ code
196
+ });
197
+ if (completeSignUp?.status === "complete") {
198
+ await setActive?.({ session: completeSignUp.createdSessionId });
199
+ const { sessionToken, error } = await getSessionToken({ tokenTemplate });
200
+ if (sessionToken) {
201
+ return {
202
+ sessionToken,
203
+ signIn,
204
+ signUp,
205
+ isSuccess: true
206
+ };
207
+ }
208
+ return {
209
+ signIn,
210
+ signUp,
211
+ error,
212
+ isSuccess: false
213
+ };
214
+ }
215
+ } else {
216
+ const attemptSignIn = isSecondFactor ? signIn?.attemptSecondFactor : signIn?.attemptFirstFactor;
217
+ const completeSignIn = await attemptSignIn?.({ strategy, code });
218
+ if (completeSignIn?.status === "complete") {
219
+ await setActive?.({ session: completeSignIn.createdSessionId });
220
+ const sessionToken = (await getSessionToken({ tokenTemplate })).sessionToken;
221
+ if (sessionToken) {
222
+ return { sessionToken, signIn, signUp, isSuccess: true };
223
+ }
224
+ return { sessionToken: null, signIn, signUp, isSuccess: false };
225
+ }
226
+ }
227
+ return {
228
+ signIn,
229
+ signUp,
230
+ isSuccess: false
231
+ };
232
+ } catch (error) {
233
+ return {
234
+ signIn,
235
+ signUp,
236
+ error,
237
+ isSuccess: false
238
+ };
239
+ } finally {
240
+ setIsVerifying(false);
241
+ }
242
+ };
243
+ return {
244
+ sendOtpCode,
245
+ verifyCode,
246
+ isVerifying
247
+ };
248
+ }
249
+
250
+ // src/hooks/use-auth-with-identifier.ts
251
+ import { isClerkAPIResponseError } from "@clerk/clerk-expo";
252
+ import { useState as useState4 } from "react";
253
+ function useAuthWithIdentifier(method, verifyBy) {
254
+ const { signUp, signIn, setActive } = useClerkResources();
255
+ const { sendOtpCode, verifyCode: verifyOtpCode, isVerifying } = useOtpVerification();
256
+ const { getSessionToken } = useGetSessionToken();
257
+ const [isAuthorizing, setIsAuthorizing] = useState4(false);
258
+ const [isLoading, setIsLoading] = useState4(false);
259
+ const strategy = method === "emailAddress" ? "email_code" : "phone_code";
260
+ const handleSessionToken = async (tokenTemplate) => {
261
+ const { sessionToken, error } = await getSessionToken({ tokenTemplate });
262
+ return { sessionToken: sessionToken || void 0, error };
263
+ };
264
+ const handleSignInWithPassword = async (signInAttempt, isSignUp, tokenTemplate) => {
265
+ await setActive?.({ session: signInAttempt.createdSessionId });
266
+ const { sessionToken, error } = await handleSessionToken(tokenTemplate);
267
+ if (isSignUp) {
268
+ return {
269
+ signUp,
270
+ error,
271
+ sessionToken,
272
+ isSuccess: !!sessionToken
273
+ };
274
+ }
275
+ return {
276
+ signIn,
277
+ error,
278
+ sessionToken,
279
+ isSuccess: !!sessionToken
280
+ };
281
+ };
282
+ const handleUsernameAuth = async (params, isSignUp) => {
283
+ const { identifier, password, tokenTemplate } = params;
284
+ const authMethod = isSignUp ? signUp : signIn;
285
+ const authAttempt = await authMethod?.create({ username: identifier, password });
286
+ if (authAttempt?.status === "complete" && "createdSessionId" in authAttempt) {
287
+ return handleSignInWithPassword(authAttempt, isSignUp, tokenTemplate);
288
+ }
289
+ return {
290
+ isSuccess: false,
291
+ [isSignUp ? "signUp" : "signIn"]: authMethod
292
+ };
293
+ };
294
+ const handleEmailPhoneAuth = async (params, isSignUp) => {
295
+ const { identifier } = params;
296
+ const authMethod = isSignUp ? signUp : signIn;
297
+ const identifierFieldName = isSignUp ? method : "identifier";
298
+ if (verifyBy === "password") {
299
+ try {
300
+ const { password, tokenTemplate } = params;
301
+ const authAttempt = await authMethod?.create({ [identifierFieldName]: identifier, password });
302
+ if (authAttempt?.status === "complete" && "createdSessionId" in authAttempt) {
303
+ return handleSignInWithPassword(authAttempt, isSignUp, tokenTemplate);
304
+ } else {
305
+ return { isSuccess: false, signIn, signUp, status: authAttempt?.status, error: null };
306
+ }
307
+ } catch (error) {
308
+ return { error, signIn, signUp };
309
+ }
310
+ } else if (verifyBy === "otp") {
311
+ try {
312
+ await authMethod?.create({ [identifierFieldName]: identifier });
313
+ await sendOtpCode({ strategy, isSignUp });
314
+ } catch (error) {
315
+ return { error, signIn, signUp };
316
+ }
317
+ }
318
+ return {
319
+ isSuccess: true,
320
+ [isSignUp ? "signUp" : "signIn"]: authMethod
321
+ };
322
+ };
323
+ const startSignUp = async (params) => {
324
+ try {
325
+ setIsLoading(true);
326
+ return method === "username" ? await handleUsernameAuth(params, true) : await handleEmailPhoneAuth(params, true);
327
+ } catch (error) {
328
+ return { error, signUp, isSuccess: false };
329
+ } finally {
330
+ setIsLoading(false);
331
+ }
332
+ };
333
+ const startSignIn = async (params) => {
334
+ try {
335
+ setIsLoading(true);
336
+ return method === "username" ? await handleUsernameAuth(params, false) : await handleEmailPhoneAuth(params, false);
337
+ } catch (error) {
338
+ return { error, signIn, isSuccess: false };
339
+ } finally {
340
+ setIsLoading(false);
341
+ }
342
+ };
343
+ const startAuthorization = async (params) => {
344
+ try {
345
+ setIsAuthorizing(true);
346
+ const result = await startSignUp(params);
347
+ if (result?.error && isClerkAPIResponseError(result.error)) {
348
+ const error = result.error.errors[0];
349
+ if (error?.code === "form_identifier_exists" /* FORM_IDENTIFIER_EXIST */) {
350
+ const signInResult = await startSignIn(params);
351
+ return { ...signInResult, isSignUp: false };
352
+ }
353
+ }
354
+ return { ...result, isSignUp: true };
355
+ } catch (error) {
356
+ return { error, signIn, signUp, isSuccess: false };
357
+ } finally {
358
+ setIsAuthorizing(false);
359
+ }
360
+ };
361
+ const verifyCode = async ({
362
+ code,
363
+ isSignUp,
364
+ tokenTemplate
365
+ }) => {
366
+ setIsLoading(true);
367
+ try {
368
+ return await verifyOtpCode({ code, strategy, tokenTemplate, isSignUp });
369
+ } finally {
370
+ setIsLoading(false);
371
+ }
372
+ };
373
+ if (method === "username") {
374
+ return {
375
+ startSignIn,
376
+ startSignUp,
377
+ startAuthorization,
378
+ isLoading: isAuthorizing || isLoading
379
+ };
380
+ } else {
381
+ return {
382
+ startSignIn,
383
+ startSignUp,
384
+ startAuthorization,
385
+ isLoading: isAuthorizing || isLoading,
386
+ verifyCode,
387
+ isVerifying
388
+ };
389
+ }
390
+ }
391
+
392
+ // src/hooks/use-add-identifier.ts
393
+ import { isClerkAPIResponseError as isClerkAPIResponseError2, useUser } from "@clerk/clerk-expo";
394
+ import { useState as useState5 } from "react";
395
+ function useAddIdentifier(type) {
396
+ const { user } = useUser();
397
+ const [isCreating, setIsCreating] = useState5(false);
398
+ const [isVerifying, setIsVerifying] = useState5(false);
399
+ const isEmail = type === "email";
400
+ const createIdentifier = async ({ identifier }) => {
401
+ setIsCreating(true);
402
+ try {
403
+ let resource = getIdentifierResource(identifier);
404
+ if (!resource) {
405
+ resource = isEmail ? await user?.createEmailAddress({ email: identifier }) : await user?.createPhoneNumber({ phoneNumber: identifier });
406
+ await user?.reload();
407
+ }
408
+ await prepareVerification({ isEmail, identifier });
409
+ return { isSuccess: true, user };
410
+ } catch (e) {
411
+ if (isClerkAPIResponseError2(e)) {
412
+ return { error: e, user };
413
+ }
414
+ return { isSuccess: false, user };
415
+ } finally {
416
+ setIsCreating(false);
417
+ }
418
+ };
419
+ const verifyCode = async ({ code, identifier }) => {
420
+ setIsVerifying(true);
421
+ try {
422
+ const resource = getIdentifierResource(identifier);
423
+ const verifyAttempt = await resource?.attemptVerification({ code });
424
+ if (verifyAttempt?.verification?.status === "verified") {
425
+ return { isSuccess: true, user };
426
+ } else {
427
+ return { isSuccess: false, verifyAttempt };
428
+ }
429
+ } catch (error) {
430
+ return { error, user };
431
+ } finally {
432
+ setIsVerifying(false);
433
+ }
434
+ };
435
+ const prepareVerification = async ({
436
+ isEmail: isEmail2,
437
+ identifier
438
+ }) => {
439
+ const phoneResource = user?.phoneNumbers?.find((a) => a.phoneNumber === identifier);
440
+ const emailResource = user?.emailAddresses?.find((a) => a.emailAddress === identifier);
441
+ await (isEmail2 ? emailResource?.prepareVerification({ strategy: "email_code" }) : phoneResource?.prepareVerification());
442
+ };
443
+ const getIdentifierResource = (identifier) => {
444
+ return isEmail ? user?.emailAddresses.find((a) => a.emailAddress === identifier) : user?.phoneNumbers.find((a) => a.phoneNumber === identifier);
445
+ };
446
+ return { createIdentifier, verifyCode, isCreating, isVerifying };
447
+ }
448
+
449
+ // src/hooks/use-reset-password.ts
450
+ import { useState as useState6 } from "react";
451
+ function useResetPassword({ method }) {
452
+ const { signIn, setActive } = useClerkResources();
453
+ const { getSessionToken } = useGetSessionToken();
454
+ const [isCodeSending, setIsCodeSending] = useState6(false);
455
+ const [isVerifying, setIsVerifying] = useState6(false);
456
+ const [isResetting, setIsResetting] = useState6(false);
457
+ const strategy = method === "emailAddress" ? "reset_password_email_code" : "reset_password_phone_code";
458
+ const startResetPassword = async ({ identifier }) => {
459
+ setIsCodeSending(true);
460
+ try {
461
+ await signIn?.create({
462
+ strategy,
463
+ identifier
464
+ });
465
+ return { isSuccess: true, signIn };
466
+ } catch (error) {
467
+ return { isSuccess: false, signIn, error };
468
+ } finally {
469
+ setIsCodeSending(false);
470
+ }
471
+ };
472
+ const verifyCode = async ({ code }) => {
473
+ setIsVerifying(true);
474
+ try {
475
+ await signIn?.attemptFirstFactor({
476
+ strategy,
477
+ code
478
+ });
479
+ return { isSuccess: true, signIn };
480
+ } catch (error) {
481
+ return { isSuccess: false, signIn, error };
482
+ } finally {
483
+ setIsVerifying(false);
484
+ }
485
+ };
486
+ const resetPassword = async ({ password, tokenTemplate }) => {
487
+ setIsResetting(true);
488
+ try {
489
+ const result = await signIn?.resetPassword({
490
+ password
491
+ });
492
+ await setActive({ session: result?.createdSessionId });
493
+ const { sessionToken, error } = await getSessionToken({ tokenTemplate });
494
+ if (sessionToken) {
495
+ return {
496
+ isSuccess: true,
497
+ signIn,
498
+ sessionToken
499
+ };
500
+ } else {
501
+ return {
502
+ signIn,
503
+ error,
504
+ isSuccess: false
505
+ };
506
+ }
507
+ } catch (error) {
508
+ return { isSuccess: false, signIn, error };
509
+ } finally {
510
+ setIsResetting(false);
511
+ }
512
+ };
513
+ return {
514
+ startResetPassword,
515
+ verifyCode,
516
+ resetPassword,
517
+ isCodeSending,
518
+ isVerifying,
519
+ isResetting
520
+ };
521
+ }
522
+
523
+ // src/hooks/use-update-password.ts
524
+ import { useUser as useUser2 } from "@clerk/clerk-expo";
525
+ import { useState as useState7 } from "react";
526
+ var useChangePassword = () => {
527
+ const { user } = useUser2();
528
+ const [isPasswordUpdating, setIsPasswordUpdating] = useState7(false);
529
+ const updatePassword = async (params) => {
530
+ const { newPassword, currentPassword } = params;
531
+ try {
532
+ setIsPasswordUpdating(true);
533
+ await user?.updatePassword({ newPassword, currentPassword });
534
+ return { isSuccess: true };
535
+ } catch (error) {
536
+ return { isSuccess: false, error };
537
+ } finally {
538
+ setIsPasswordUpdating(false);
539
+ }
540
+ };
541
+ return { updatePassword, isPasswordUpdating };
542
+ };
543
+
544
+ // src/hooks/use-update-identifier.ts
545
+ import { useUser as useUser3 } from "@clerk/clerk-expo";
546
+ import { useState as useState8 } from "react";
547
+ function useUpdateIdentifier(type) {
548
+ const { user } = useUser3();
549
+ const isEmail = type === "email";
550
+ const { createIdentifier, verifyCode: verifyAddIdentifierCode, isCreating, isVerifying } = useAddIdentifier(type);
551
+ const [isUpdating, setIsUpdating] = useState8(false);
552
+ const getIdentifierResource = (identifier) => {
553
+ return isEmail ? user?.emailAddresses?.find((a) => a.emailAddress === identifier) : user?.phoneNumbers?.find((a) => a.phoneNumber === identifier);
554
+ };
555
+ const swapPrimaryIdentifier = async (identifier) => {
556
+ const newResource = getIdentifierResource(identifier);
557
+ if (!newResource || newResource.verification?.status !== "verified") {
558
+ throw new Error("Identifier not found or not verified");
559
+ }
560
+ const currentPrimaryId = isEmail ? user?.primaryEmailAddressId : user?.primaryPhoneNumberId;
561
+ const resources = isEmail ? user?.emailAddresses : user?.phoneNumbers;
562
+ const oldPrimaryResource = resources?.find((r) => r.id === currentPrimaryId);
563
+ if (isEmail) {
564
+ await user?.update({ primaryEmailAddressId: newResource.id });
565
+ } else {
566
+ await user?.update({ primaryPhoneNumberId: newResource.id });
567
+ }
568
+ if (oldPrimaryResource && oldPrimaryResource.id !== newResource.id) {
569
+ await oldPrimaryResource.destroy();
570
+ }
571
+ await user?.reload();
572
+ };
573
+ const verifyCode = async ({ code, identifier }) => {
574
+ setIsUpdating(true);
575
+ const result = await verifyAddIdentifierCode({ code, identifier });
576
+ await user?.reload();
577
+ if (!result.isSuccess) {
578
+ setIsUpdating(false);
579
+ return result;
580
+ }
581
+ try {
582
+ await swapPrimaryIdentifier(identifier);
583
+ return { isSuccess: true, user };
584
+ } catch (error) {
585
+ return { isSuccess: false, error, user };
586
+ } finally {
587
+ setIsUpdating(false);
588
+ }
589
+ };
590
+ return {
591
+ createIdentifier,
592
+ verifyCode,
593
+ isCreating,
594
+ isVerifying,
595
+ isUpdating
596
+ };
597
+ }
598
+ export {
599
+ ClerkApiError,
600
+ useAddIdentifier,
601
+ useAuthWithIdentifier,
602
+ useAuthWithSSO,
603
+ useAuthWithTicket,
604
+ useChangePassword,
605
+ useClerkResources,
606
+ useGetSessionToken,
607
+ useOtpVerification,
608
+ useResetPassword,
609
+ useUpdateIdentifier
610
+ };
611
+ //# sourceMappingURL=index.mjs.map