Skip to content

Commit a1f6714

Browse files
authored
feat(clerk-js,clerk-react,types): Add support for additional props (#6897)
1 parent cd27a2a commit a1f6714

File tree

7 files changed

+261
-5
lines changed

7 files changed

+261
-5
lines changed

.changeset/weak-deer-tie.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@clerk/clerk-js': minor
3+
'@clerk/clerk-react': minor
4+
'@clerk/types': minor
5+
---
6+
7+
[Experimental] Add support for additional properties to Signal SignIn/SignUp

integration/templates/custom-flows-react-vite/src/routes/SignIn.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export function SignIn({ className, ...props }: React.ComponentProps<'div'>) {
104104
</CardHeader>
105105
<CardContent>
106106
<div className='grid gap-6'>
107-
{signIn.availableStrategies
107+
{signIn.supportedFirstFactors
108108
.filter(({ strategy }) => strategy !== 'reset_password_email_code')
109109
.map(({ strategy }) => (
110110
<Button

packages/clerk-js/src/core/resources/SignIn.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,15 +608,35 @@ class SignInFuture implements SignInFutureResource {
608608

609609
constructor(readonly resource: SignIn) {}
610610

611+
get id() {
612+
return this.resource.id;
613+
}
614+
615+
get identifier() {
616+
return this.resource.identifier;
617+
}
618+
619+
get createdSessionId() {
620+
return this.resource.createdSessionId;
621+
}
622+
623+
get userData() {
624+
return this.resource.userData;
625+
}
626+
611627
get status() {
612628
// @TODO hooks-revamp: Consolidate this fallback val with stateProxy
613629
return this.resource.status || 'needs_identifier';
614630
}
615631

616-
get availableStrategies() {
632+
get supportedFirstFactors() {
617633
return this.resource.supportedFirstFactors ?? [];
618634
}
619635

636+
get supportedSecondFactors() {
637+
return this.resource.supportedSecondFactors ?? [];
638+
}
639+
620640
get isTransferable() {
621641
return this.resource.firstFactorVerification.status === 'transferable';
622642
}
@@ -637,6 +657,10 @@ class SignInFuture implements SignInFutureResource {
637657
return this.resource.firstFactorVerification;
638658
}
639659

660+
get secondFactorVerification() {
661+
return this.resource.secondFactorVerification;
662+
}
663+
640664
async sendResetPasswordEmailCode(): Promise<{ error: unknown }> {
641665
return runAsyncResourceTask(this.resource, async () => {
642666
if (!this.resource.id) {

packages/clerk-js/src/core/resources/SignUp.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,11 +551,75 @@ class SignUpFuture implements SignUpFutureResource {
551551

552552
constructor(readonly resource: SignUp) {}
553553

554+
get id() {
555+
return this.resource.id;
556+
}
557+
558+
get requiredFields() {
559+
return this.resource.requiredFields;
560+
}
561+
562+
get optionalFields() {
563+
return this.resource.optionalFields;
564+
}
565+
566+
get missingFields() {
567+
return this.resource.missingFields;
568+
}
569+
554570
get status() {
555571
// @TODO hooks-revamp: Consolidate this fallback val with stateProxy
556572
return this.resource.status || 'missing_requirements';
557573
}
558574

575+
get username() {
576+
return this.resource.username;
577+
}
578+
579+
get firstName() {
580+
return this.resource.firstName;
581+
}
582+
583+
get lastName() {
584+
return this.resource.lastName;
585+
}
586+
587+
get emailAddress() {
588+
return this.resource.emailAddress;
589+
}
590+
591+
get phoneNumber() {
592+
return this.resource.phoneNumber;
593+
}
594+
595+
get web3Wallet() {
596+
return this.resource.web3wallet;
597+
}
598+
599+
get hasPassword() {
600+
return this.resource.hasPassword;
601+
}
602+
603+
get unsafeMetadata() {
604+
return this.resource.unsafeMetadata;
605+
}
606+
607+
get createdSessionId() {
608+
return this.resource.createdSessionId;
609+
}
610+
611+
get createdUserId() {
612+
return this.resource.createdUserId;
613+
}
614+
615+
get abandonAt() {
616+
return this.resource.abandonAt;
617+
}
618+
619+
get legalAcceptedAt() {
620+
return this.resource.legalAcceptedAt;
621+
}
622+
559623
get unverifiedFields() {
560624
return this.resource.unverifiedFields;
561625
}

packages/react/src/stateProxy.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,45 @@ export class StateProxy implements State {
4545
status: 'needs_identifier' as const,
4646
availableStrategies: [],
4747
isTransferable: false,
48+
get id() {
49+
return gateProperty(target, 'id', undefined);
50+
},
51+
get supportedFirstFactors() {
52+
return gateProperty(target, 'supportedFirstFactors', []);
53+
},
54+
get supportedSecondFactors() {
55+
return gateProperty(target, 'supportedSecondFactors', []);
56+
},
57+
get secondFactorVerification() {
58+
return gateProperty(target, 'secondFactorVerification', {
59+
status: null,
60+
error: null,
61+
expireAt: null,
62+
externalVerificationRedirectURL: null,
63+
nonce: null,
64+
attempts: null,
65+
message: null,
66+
strategy: null,
67+
verifiedAtClient: null,
68+
verifiedFromTheSameClient: () => false,
69+
__internal_toSnapshot: () => {
70+
throw new Error('__internal_toSnapshot called before Clerk is loaded');
71+
},
72+
pathRoot: '',
73+
reload: () => {
74+
throw new Error('__internal_toSnapshot called before Clerk is loaded');
75+
},
76+
});
77+
},
78+
get identifier() {
79+
return gateProperty(target, 'identifier', null);
80+
},
81+
get createdSessionId() {
82+
return gateProperty(target, 'createdSessionId', null);
83+
},
84+
get userData() {
85+
return gateProperty(target, 'userData', {});
86+
},
4887
get firstFactorVerification() {
4988
return gateProperty(target, 'firstFactorVerification', {
5089
status: null,
@@ -107,6 +146,54 @@ export class StateProxy implements State {
107146
errors: defaultErrors(),
108147
fetchStatus: 'idle' as const,
109148
signUp: {
149+
get id() {
150+
return gateProperty(target, 'id', undefined);
151+
},
152+
get requiredFields() {
153+
return gateProperty(target, 'requiredFields', []);
154+
},
155+
get optionalFields() {
156+
return gateProperty(target, 'optionalFields', []);
157+
},
158+
get missingFields() {
159+
return gateProperty(target, 'missingFields', []);
160+
},
161+
get username() {
162+
return gateProperty(target, 'username', null);
163+
},
164+
get firstName() {
165+
return gateProperty(target, 'firstName', null);
166+
},
167+
get lastName() {
168+
return gateProperty(target, 'lastName', null);
169+
},
170+
get emailAddress() {
171+
return gateProperty(target, 'emailAddress', null);
172+
},
173+
get phoneNumber() {
174+
return gateProperty(target, 'phoneNumber', null);
175+
},
176+
get web3Wallet() {
177+
return gateProperty(target, 'web3Wallet', null);
178+
},
179+
get hasPassword() {
180+
return gateProperty(target, 'hasPassword', false);
181+
},
182+
get unsafeMetadata() {
183+
return gateProperty(target, 'unsafeMetadata', {});
184+
},
185+
get createdSessionId() {
186+
return gateProperty(target, 'createdSessionId', null);
187+
},
188+
get createdUserId() {
189+
return gateProperty(target, 'createdUserId', null);
190+
},
191+
get abandonAt() {
192+
return gateProperty(target, 'abandonAt', null);
193+
},
194+
get legalAcceptedAt() {
195+
return gateProperty(target, 'legalAcceptedAt', null);
196+
},
110197
get status() {
111198
return gateProperty(target, 'status', 'missing_requirements');
112199
},

packages/types/src/signInFuture.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { SetActiveNavigate } from './clerk';
22
import type { PhoneCodeChannel } from './phoneCodeChannel';
3-
import type { SignInFirstFactor, SignInStatus } from './signInCommon';
3+
import type { SignInFirstFactor, SignInSecondFactor, SignInStatus, UserData } from './signInCommon';
44
import type { OAuthStrategy, Web3Strategy } from './strategies';
55
import type { VerificationResource } from './verification';
66

@@ -127,10 +127,20 @@ export interface SignInFutureFinalizeParams {
127127
* The current active `SignIn` instance, for use in custom flows.
128128
*/
129129
export interface SignInFutureResource {
130+
/**
131+
* The unique identifier for the current sign-in attempt.
132+
*/
133+
readonly id?: string;
134+
130135
/**
131136
* The list of first-factor strategies that are available for the current sign-in attempt.
132137
*/
133-
readonly availableStrategies: SignInFirstFactor[];
138+
readonly supportedFirstFactors: SignInFirstFactor[];
139+
140+
/**
141+
* The list of second-factor strategies that are available for the current sign-in attempt.
142+
*/
143+
readonly supportedSecondFactors: SignInSecondFactor[];
134144

135145
/**
136146
* The status of the current sign-in attempt as a string (for example, `'needs_identifier'`, `'needs_first_factor'`,
@@ -148,6 +158,26 @@ export interface SignInFutureResource {
148158

149159
readonly firstFactorVerification: VerificationResource;
150160

161+
/**
162+
* The second-factor verification for the current sign-in attempt.
163+
*/
164+
readonly secondFactorVerification: VerificationResource;
165+
166+
/**
167+
* The identifier for the current sign-in attempt.
168+
*/
169+
readonly identifier: string | null;
170+
171+
/**
172+
* The created session ID for the current sign-in attempt.
173+
*/
174+
readonly createdSessionId: string | null;
175+
176+
/**
177+
* The user data for the current sign-in attempt.
178+
*/
179+
readonly userData: UserData;
180+
151181
/**
152182
* Used to supply an identifier for the sign-in attempt. Calling this method will populate data on the sign-in
153183
* attempt, such as `signIn.resource.supportedFirstFactors`.

packages/types/src/signUpFuture.ts

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { SetActiveNavigate } from './clerk';
22
import type { PhoneCodeChannel } from './phoneCodeChannel';
3-
import type { SignUpIdentificationField, SignUpStatus } from './signUpCommon';
3+
import type { SignUpField, SignUpIdentificationField, SignUpStatus } from './signUpCommon';
44
import type { Web3Strategy } from './strategies';
55

66
interface SignUpFutureAdditionalParams {
@@ -71,11 +71,31 @@ export interface SignUpFutureFinalizeParams {
7171
* The current active `SignUp` instance, for use in custom flows.
7272
*/
7373
export interface SignUpFutureResource {
74+
/**
75+
* The unique identifier for the current sign-up attempt.
76+
*/
77+
readonly id?: string;
78+
7479
/**
7580
* The status of the current sign-up attempt as a string (for example, `'missing_requirements'`, `'complete'`, `'abandoned'`, etc.)
7681
*/
7782
readonly status: SignUpStatus;
7883

84+
/**
85+
* The list of required fields for the current sign-up attempt.
86+
*/
87+
readonly requiredFields: SignUpField[];
88+
89+
/**
90+
* The list of optional fields for the current sign-up attempt.
91+
*/
92+
readonly optionalFields: SignUpField[];
93+
94+
/**
95+
* The list of missing fields for the current sign-up attempt.
96+
*/
97+
readonly missingFields: SignUpField[];
98+
7999
/**
80100
* An array of strings representing unverified fields such as `’email_address’`. Can be used to detect when verification is necessary.
81101
*/
@@ -89,6 +109,30 @@ export interface SignUpFutureResource {
89109

90110
readonly existingSession?: { sessionId: string };
91111

112+
readonly username: string | null;
113+
114+
readonly firstName: string | null;
115+
116+
readonly lastName: string | null;
117+
118+
readonly emailAddress: string | null;
119+
120+
readonly phoneNumber: string | null;
121+
122+
readonly web3Wallet: string | null;
123+
124+
readonly hasPassword: boolean;
125+
126+
readonly unsafeMetadata: SignUpUnsafeMetadata;
127+
128+
readonly createdSessionId: string | null;
129+
130+
readonly createdUserId: string | null;
131+
132+
readonly abandonAt: number | null;
133+
134+
readonly legalAcceptedAt: number | null;
135+
92136
create: (params: SignUpFutureCreateParams) => Promise<{ error: unknown }>;
93137

94138
update: (params: SignUpFutureUpdateParams) => Promise<{ error: unknown }>;

0 commit comments

Comments
 (0)