Skip to content

Commit fc139fa

Browse files
committed
refactor(elements): Create sign-up actors
1 parent 7b5f8f5 commit fc139fa

7 files changed

Lines changed: 126 additions & 3 deletions

File tree

packages/elements/src/internals/machines/sign-in/actors/start-attempt.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type { FormFields } from '../../form';
66
export type StartAttemptInput = { clerk: LoadedClerk; fields: FormFields };
77
export type StartAttemptOutput = SignInResource;
88

9-
export const startAttempt = fromPromise<SignInResource, StartAttemptInput>(({ input }) => {
9+
export const startAttempt = fromPromise<StartAttemptOutput, StartAttemptInput>(({ input }) => {
1010
const { clerk, fields } = input;
1111

1212
const password = fields.get('password');
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import type { LoadedClerk, SignUpResource, Web3Strategy } from '@clerk/types';
2+
import { fromPromise } from 'xstate';
3+
4+
import { ClerkElementsRuntimeError } from '~/internals/errors';
5+
6+
export type StartAttemptWeb3Input = { clerk: LoadedClerk; strategy: Web3Strategy };
7+
export type StartAttemptWeb3Output = SignUpResource;
8+
9+
export const startAttempt = fromPromise<StartAttemptWeb3Output, StartAttemptWeb3Input>(({ input }) => {
10+
const { clerk, strategy } = input;
11+
12+
if (strategy === 'web3_metamask_signature') {
13+
return clerk.client.signUp.authenticateWithMetamask();
14+
}
15+
16+
if (strategy === 'web3_coinbase_wallet_signature') {
17+
return clerk.client.signUp.authenticateWithCoinbaseWallet();
18+
}
19+
20+
throw new ClerkElementsRuntimeError(`Unsupported Web3 strategy: ${strategy}`);
21+
});
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import type { LoadedClerk, SignUpResource } from '@clerk/types';
2+
import { fromPromise } from 'xstate';
3+
4+
import { fieldsToSignUpParams } from '~/internals/machines/sign-up/utils/fields-to-params';
5+
6+
import type { FormFields } from '../../form';
7+
8+
export type StartAttemptParams = { strategy: 'ticket'; ticket: string } | { strategy?: never; ticket?: never };
9+
export type StartAttemptInput = { clerk: LoadedClerk; fields: FormFields; params?: StartAttemptParams };
10+
export type StartAttemptOutput = SignUpResource;
11+
12+
// TODO: Also used for continueAttempt
13+
export const startAttempt = fromPromise<StartAttemptOutput, StartAttemptInput>(({ input }) => {
14+
const { clerk, fields, params } = input;
15+
return clerk.client.signUp.create({ ...fieldsToSignUpParams(fields), ...params });
16+
});
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { Poller } from '@clerk/shared/poller';
2+
import type { LoadedClerk } from '@clerk/types';
3+
import { fromCallback } from 'xstate';
4+
5+
import { ClerkElementsError, ClerkElementsRuntimeError } from '~/internals/errors';
6+
7+
export type VerificationAttemptEmailLinkInput = { clerk: LoadedClerk };
8+
export type VerificationAttemptEmailLinkEvents = { type: 'STOP' };
9+
10+
export const verificationAttemptEmailLink = fromCallback<
11+
VerificationAttemptEmailLinkEvents,
12+
VerificationAttemptEmailLinkInput
13+
>(({ receive, sendBack, input: { clerk } }) => {
14+
const { run, stop } = Poller();
15+
16+
void run(async () =>
17+
clerk.client.signUp
18+
.reload()
19+
.then(resource => {
20+
const signInStatus = resource.status;
21+
const verificationStatus = resource.verifications.emailAddress.status;
22+
23+
// Short-circuit if the sign-up resource is already complete
24+
if (signInStatus === 'complete') {
25+
return sendBack({ type: 'EMAIL_LINK.VERIFIED', resource });
26+
}
27+
28+
switch (verificationStatus) {
29+
case 'verified':
30+
case 'transferable':
31+
case 'expired': {
32+
sendBack({ type: `EMAIL_LINK.${verificationStatus.toUpperCase()}`, resource });
33+
break;
34+
}
35+
case 'failed': {
36+
sendBack({
37+
type: 'EMAIL_LINK.FAILED',
38+
error: new ClerkElementsError('email-link-verification-failed', 'Email verification failed'),
39+
resource,
40+
});
41+
break;
42+
}
43+
// case 'unverified':
44+
default:
45+
return;
46+
}
47+
48+
stop();
49+
})
50+
.catch(error => {
51+
stop();
52+
new ClerkElementsRuntimeError(error);
53+
}),
54+
);
55+
56+
receive(event => {
57+
if (event.type === 'STOP') {
58+
stop();
59+
}
60+
});
61+
62+
return () => stop();
63+
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import type { AttemptVerificationParams, LoadedClerk, SignUpResource } from '@clerk/types';
2+
import { fromPromise } from 'xstate';
3+
4+
export type VerificationAttemptInput = { clerk: LoadedClerk; params: AttemptVerificationParams };
5+
export type VerificationAttemptOutput = SignUpResource;
6+
7+
export const verificationAttempt = fromPromise<VerificationAttemptOutput, VerificationAttemptInput>(({ input }) => {
8+
const { clerk, params } = input;
9+
return clerk.client.signUp.attemptVerification(params);
10+
});
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import type { LoadedClerk, PrepareVerificationParams, SignUpResource } from '@clerk/types';
2+
import { fromPromise } from 'xstate';
3+
4+
export type VerificationPrepareInput = { clerk: LoadedClerk; params: PrepareVerificationParams };
5+
export type VerificationPrepareOutput = SignUpResource;
6+
7+
export const verificationPrepare = fromPromise<VerificationPrepareOutput, VerificationPrepareInput>(({ input }) => {
8+
const { clerk, params } = input;
9+
10+
if (params.strategy === 'email_link' && params.redirectUrl) {
11+
params.redirectUrl = clerk.buildUrlWithAuth(params.redirectUrl);
12+
}
13+
14+
return clerk.client.signUp.prepareVerification(params);
15+
});

packages/elements/src/internals/machines/sign-up/start.machine.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { ClerkElementsRuntimeError } from '~/internals/errors';
66
import type { FormFields } from '~/internals/machines/form';
77
import { sendToLoading } from '~/internals/machines/shared';
88
import { fieldsToSignUpParams } from '~/internals/machines/sign-up/utils';
9-
import { ThirdPartyMachine } from '~/internals/machines/third-party';
109
import { assertActorEventError } from '~/internals/machines/utils/assert';
1110

1211
import type { SignInRouterMachineActorRef } from './router.types';
@@ -45,7 +44,6 @@ export const SignUpStartMachine = setup({
4544
throw new ClerkElementsRuntimeError(`Unsupported Web3 strategy: ${strategy}`);
4645
},
4746
),
48-
thirdParty: ThirdPartyMachine,
4947
},
5048
actions: {
5149
sendToNext: ({ context }) => context.parent.send({ type: 'NEXT' }),

0 commit comments

Comments
 (0)