Skip to content

Commit 2f08c8b

Browse files
committed
Merge branch 'refs/heads/main' into elef/improve-cache-key-construction
2 parents 9e2f4e7 + 6da8819 commit 2f08c8b

File tree

17 files changed

+381
-238
lines changed

17 files changed

+381
-238
lines changed

.changeset/deep-wombats-retire.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@clerk/clerk-js': patch
3+
---
4+
5+
[Experimental] Type method returns using ClerkError

.changeset/fruity-rivers-say.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@clerk/clerk-js': minor
3+
'@clerk/shared': minor
4+
---
5+
6+
[Experimental] Add support for sign-up via modal in signals implementation

.changeset/many-pants-pump.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
---

.changeset/wide-walls-sneeze.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
---

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@
166166
"jest": "29.7.0",
167167
"jest-snapshot-prettier": "npm:prettier@^3.5.3",
168168
"react": "catalog:react",
169-
"react-dom": "catalog:react"
169+
"react-dom": "catalog:react",
170+
"rolldown": "catalog:repo"
170171
}
171172
}
172173
}

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

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { inBrowser } from '@clerk/shared/browser';
2-
import { ClerkWebAuthnError } from '@clerk/shared/error';
2+
import { type ClerkError, ClerkRuntimeError, ClerkWebAuthnError } from '@clerk/shared/error';
33
import { Poller } from '@clerk/shared/poller';
44
import type {
55
AttemptFirstFactorParams,
@@ -686,18 +686,19 @@ class SignInFuture implements SignInFutureResource {
686686
return this.resource.secondFactorVerification;
687687
}
688688

689-
async sendResetPasswordEmailCode(): Promise<{ error: unknown }> {
689+
async sendResetPasswordEmailCode(): Promise<{ error: ClerkError | null }> {
690+
if (!this.resource.id) {
691+
throw new Error('Cannot reset password without a sign in.');
692+
}
690693
return runAsyncResourceTask(this.resource, async () => {
691-
if (!this.resource.id) {
692-
throw new Error('Cannot reset password without a sign in.');
693-
}
694-
695694
const resetPasswordEmailCodeFactor = this.resource.supportedFirstFactors?.find(
696695
f => f.strategy === 'reset_password_email_code',
697696
);
698697

699698
if (!resetPasswordEmailCodeFactor) {
700-
throw new Error('Reset password email code factor not found');
699+
throw new ClerkRuntimeError('Reset password email code factor not found', {
700+
code: 'factor_not_found',
701+
});
701702
}
702703

703704
const { emailAddressId } = resetPasswordEmailCodeFactor;
@@ -708,7 +709,7 @@ class SignInFuture implements SignInFutureResource {
708709
});
709710
}
710711

711-
async verifyResetPasswordEmailCode(params: SignInFutureEmailCodeVerifyParams): Promise<{ error: unknown }> {
712+
async verifyResetPasswordEmailCode(params: SignInFutureEmailCodeVerifyParams): Promise<{ error: ClerkError | null }> {
712713
const { code } = params;
713714
return runAsyncResourceTask(this.resource, async () => {
714715
await this.resource.__internal_basePost({
@@ -718,7 +719,7 @@ class SignInFuture implements SignInFutureResource {
718719
});
719720
}
720721

721-
async submitResetPassword(params: SignInFutureResetPasswordSubmitParams): Promise<{ error: unknown }> {
722+
async submitResetPassword(params: SignInFutureResetPasswordSubmitParams): Promise<{ error: ClerkError | null }> {
722723
const { password, signOutOfOtherSessions = true } = params;
723724
return runAsyncResourceTask(this.resource, async () => {
724725
await this.resource.__internal_basePost({
@@ -736,13 +737,13 @@ class SignInFuture implements SignInFutureResource {
736737
});
737738
}
738739

739-
async create(params: SignInFutureCreateParams): Promise<{ error: unknown }> {
740+
async create(params: SignInFutureCreateParams): Promise<{ error: ClerkError | null }> {
740741
return runAsyncResourceTask(this.resource, async () => {
741742
await this._create(params);
742743
});
743744
}
744745

745-
async password(params: SignInFuturePasswordParams): Promise<{ error: unknown }> {
746+
async password(params: SignInFuturePasswordParams): Promise<{ error: ClerkError | null }> {
746747
if ([params.identifier, params.emailAddress, params.phoneNumber].filter(Boolean).length > 1) {
747748
throw new Error('Only one of identifier, emailAddress, or phoneNumber can be provided');
748749
}
@@ -763,7 +764,7 @@ class SignInFuture implements SignInFutureResource {
763764
});
764765
}
765766

766-
async sendEmailCode(params: SignInFutureEmailCodeSendParams = {}): Promise<{ error: unknown }> {
767+
async sendEmailCode(params: SignInFutureEmailCodeSendParams = {}): Promise<{ error: ClerkError | null }> {
767768
const { emailAddress, emailAddressId } = params;
768769
if (!this.resource.id && emailAddressId) {
769770
throw new Error(
@@ -784,7 +785,7 @@ class SignInFuture implements SignInFutureResource {
784785

785786
const emailCodeFactor = this.selectFirstFactor({ strategy: 'email_code', emailAddressId });
786787
if (!emailCodeFactor) {
787-
throw new Error('Email code factor not found');
788+
throw new ClerkRuntimeError('Email code factor not found', { code: 'factor_not_found' });
788789
}
789790

790791
await this.resource.__internal_basePost({
@@ -794,7 +795,7 @@ class SignInFuture implements SignInFutureResource {
794795
});
795796
}
796797

797-
async verifyEmailCode(params: SignInFutureEmailCodeVerifyParams): Promise<{ error: unknown }> {
798+
async verifyEmailCode(params: SignInFutureEmailCodeVerifyParams): Promise<{ error: ClerkError | null }> {
798799
const { code } = params;
799800
return runAsyncResourceTask(this.resource, async () => {
800801
await this.resource.__internal_basePost({
@@ -804,7 +805,7 @@ class SignInFuture implements SignInFutureResource {
804805
});
805806
}
806807

807-
async sendEmailLink(params: SignInFutureEmailLinkSendParams): Promise<{ error: unknown }> {
808+
async sendEmailLink(params: SignInFutureEmailLinkSendParams): Promise<{ error: ClerkError | null }> {
808809
const { emailAddress, verificationUrl, emailAddressId } = params;
809810
if (!this.resource.id && emailAddressId) {
810811
throw new Error(
@@ -825,7 +826,7 @@ class SignInFuture implements SignInFutureResource {
825826

826827
const emailLinkFactor = this.selectFirstFactor({ strategy: 'email_link', emailAddressId });
827828
if (!emailLinkFactor) {
828-
throw new Error('Email link factor not found');
829+
throw new ClerkRuntimeError('Email link factor not found', { code: 'factor_not_found' });
829830
}
830831

831832
let absoluteVerificationUrl = verificationUrl;
@@ -846,7 +847,7 @@ class SignInFuture implements SignInFutureResource {
846847
});
847848
}
848849

849-
async waitForEmailLinkVerification(): Promise<{ error: unknown }> {
850+
async waitForEmailLinkVerification(): Promise<{ error: ClerkError | null }> {
850851
return runAsyncResourceTask(this.resource, async () => {
851852
const { run, stop } = Poller();
852853
await new Promise((resolve, reject) => {
@@ -867,7 +868,7 @@ class SignInFuture implements SignInFutureResource {
867868
});
868869
}
869870

870-
async sendPhoneCode(params: SignInFuturePhoneCodeSendParams = {}): Promise<{ error: unknown }> {
871+
async sendPhoneCode(params: SignInFuturePhoneCodeSendParams = {}): Promise<{ error: ClerkError | null }> {
871872
const { phoneNumber, phoneNumberId, channel = 'sms' } = params;
872873
if (!this.resource.id && phoneNumberId) {
873874
throw new Error(
@@ -888,7 +889,7 @@ class SignInFuture implements SignInFutureResource {
888889

889890
const phoneCodeFactor = this.selectFirstFactor({ strategy: 'phone_code', phoneNumberId });
890891
if (!phoneCodeFactor) {
891-
throw new Error('Phone code factor not found');
892+
throw new ClerkRuntimeError('Phone code factor not found', { code: 'factor_not_found' });
892893
}
893894

894895
await this.resource.__internal_basePost({
@@ -898,7 +899,7 @@ class SignInFuture implements SignInFutureResource {
898899
});
899900
}
900901

901-
async verifyPhoneCode(params: SignInFuturePhoneCodeVerifyParams): Promise<{ error: unknown }> {
902+
async verifyPhoneCode(params: SignInFuturePhoneCodeVerifyParams): Promise<{ error: ClerkError | null }> {
902903
const { code } = params;
903904
return runAsyncResourceTask(this.resource, async () => {
904905
await this.resource.__internal_basePost({
@@ -908,8 +909,9 @@ class SignInFuture implements SignInFutureResource {
908909
});
909910
}
910911

911-
async sso(params: SignInFutureSSOParams): Promise<{ error: unknown }> {
912-
const { strategy, redirectUrl, redirectCallbackUrl, popup, oidcPrompt, enterpriseConnectionId } = params;
912+
async sso(params: SignInFutureSSOParams): Promise<{ error: ClerkError | null }> {
913+
const { strategy, redirectUrl, redirectCallbackUrl, popup, oidcPrompt, enterpriseConnectionId, identifier } =
914+
params;
913915
return runAsyncResourceTask(this.resource, async () => {
914916
let actionCompleteRedirectUrl = redirectUrl;
915917
try {
@@ -931,6 +933,7 @@ class SignInFuture implements SignInFutureResource {
931933
await this._create({
932934
strategy,
933935
...routes,
936+
identifier,
934937
});
935938

936939
if (strategy === 'enterprise_sso') {
@@ -959,7 +962,7 @@ class SignInFuture implements SignInFutureResource {
959962
});
960963
}
961964

962-
async web3(params: SignInFutureWeb3Params): Promise<{ error: unknown }> {
965+
async web3(params: SignInFutureWeb3Params): Promise<{ error: ClerkError | null }> {
963966
const { strategy } = params;
964967
const provider = strategy.replace('web3_', '').replace('_signature', '') as Web3Provider;
965968

@@ -993,7 +996,7 @@ class SignInFuture implements SignInFutureResource {
993996
f => f.strategy === strategy,
994997
) as Web3SignatureFactor;
995998
if (!web3FirstFactor) {
996-
throw new Error('Web3 first factor not found');
999+
throw new ClerkRuntimeError('Web3 first factor not found', { code: 'factor_not_found' });
9971000
}
9981001

9991002
await this.resource.__internal_basePost({
@@ -1003,7 +1006,7 @@ class SignInFuture implements SignInFutureResource {
10031006

10041007
const { message } = this.firstFactorVerification;
10051008
if (!message) {
1006-
throw new Error('Web3 nonce not found');
1009+
throw new ClerkRuntimeError('Web3 nonce not found', { code: 'web3_nonce_not_found' });
10071010
}
10081011

10091012
let signature: string;
@@ -1030,7 +1033,7 @@ class SignInFuture implements SignInFutureResource {
10301033
});
10311034
}
10321035

1033-
async passkey(params?: SignInFuturePasskeyParams): Promise<{ error: unknown }> {
1036+
async passkey(params?: SignInFuturePasskeyParams): Promise<{ error: ClerkError | null }> {
10341037
const { flow } = params || {};
10351038

10361039
/**
@@ -1056,7 +1059,7 @@ class SignInFuture implements SignInFutureResource {
10561059
const passKeyFactor = this.supportedFirstFactors.find(f => f.strategy === 'passkey') as PasskeyFactor;
10571060

10581061
if (!passKeyFactor) {
1059-
clerkVerifyPasskeyCalledBeforeCreate();
1062+
throw new ClerkRuntimeError('Passkey factor not found', { code: 'factor_not_found' });
10601063
}
10611064
await this.resource.__internal_basePost({
10621065
body: { strategy: 'passkey' },
@@ -1068,7 +1071,7 @@ class SignInFuture implements SignInFutureResource {
10681071
const publicKeyOptions = nonce ? convertJSONToPublicKeyRequestOptions(JSON.parse(nonce)) : null;
10691072

10701073
if (!publicKeyOptions) {
1071-
clerkMissingWebAuthnPublicKeyOptions('get');
1074+
throw new ClerkRuntimeError('Missing public key options', { code: 'missing_public_key_options' });
10721075
}
10731076

10741077
let canUseConditionalUI = false;
@@ -1088,7 +1091,7 @@ class SignInFuture implements SignInFutureResource {
10881091
});
10891092

10901093
if (!publicKeyCredential) {
1091-
throw error;
1094+
throw new ClerkWebAuthnError(error.message, { code: 'passkey_retrieval_failed' });
10921095
}
10931096

10941097
await this.resource.__internal_basePost({
@@ -1101,12 +1104,12 @@ class SignInFuture implements SignInFutureResource {
11011104
});
11021105
}
11031106

1104-
async sendMFAPhoneCode(): Promise<{ error: unknown }> {
1107+
async sendMFAPhoneCode(): Promise<{ error: ClerkError | null }> {
11051108
return runAsyncResourceTask(this.resource, async () => {
11061109
const phoneCodeFactor = this.resource.supportedSecondFactors?.find(f => f.strategy === 'phone_code');
11071110

11081111
if (!phoneCodeFactor) {
1109-
throw new Error('Phone code factor not found');
1112+
throw new ClerkRuntimeError('Phone code factor not found', { code: 'factor_not_found' });
11101113
}
11111114

11121115
const { phoneNumberId } = phoneCodeFactor;
@@ -1117,7 +1120,7 @@ class SignInFuture implements SignInFutureResource {
11171120
});
11181121
}
11191122

1120-
async verifyMFAPhoneCode(params: SignInFutureMFAPhoneCodeVerifyParams): Promise<{ error: unknown }> {
1123+
async verifyMFAPhoneCode(params: SignInFutureMFAPhoneCodeVerifyParams): Promise<{ error: ClerkError | null }> {
11211124
const { code } = params;
11221125
return runAsyncResourceTask(this.resource, async () => {
11231126
await this.resource.__internal_basePost({
@@ -1127,7 +1130,7 @@ class SignInFuture implements SignInFutureResource {
11271130
});
11281131
}
11291132

1130-
async verifyTOTP(params: SignInFutureTOTPVerifyParams): Promise<{ error: unknown }> {
1133+
async verifyTOTP(params: SignInFutureTOTPVerifyParams): Promise<{ error: ClerkError | null }> {
11311134
const { code } = params;
11321135
return runAsyncResourceTask(this.resource, async () => {
11331136
await this.resource.__internal_basePost({
@@ -1137,7 +1140,7 @@ class SignInFuture implements SignInFutureResource {
11371140
});
11381141
}
11391142

1140-
async verifyBackupCode(params: SignInFutureBackupCodeVerifyParams): Promise<{ error: unknown }> {
1143+
async verifyBackupCode(params: SignInFutureBackupCodeVerifyParams): Promise<{ error: ClerkError | null }> {
11411144
const { code } = params;
11421145
return runAsyncResourceTask(this.resource, async () => {
11431146
await this.resource.__internal_basePost({
@@ -1147,18 +1150,19 @@ class SignInFuture implements SignInFutureResource {
11471150
});
11481151
}
11491152

1150-
async ticket(params?: SignInFutureTicketParams): Promise<{ error: unknown }> {
1153+
async ticket(params?: SignInFutureTicketParams): Promise<{ error: ClerkError | null }> {
11511154
const ticket = params?.ticket ?? getClerkQueryParam('__clerk_ticket');
11521155
return this.create({ ticket: ticket ?? undefined });
11531156
}
11541157

1155-
async finalize(params?: SignInFutureFinalizeParams): Promise<{ error: unknown }> {
1158+
async finalize(params?: SignInFutureFinalizeParams): Promise<{ error: ClerkError | null }> {
11561159
const { navigate } = params || {};
1157-
return runAsyncResourceTask(this.resource, async () => {
1158-
if (!this.resource.createdSessionId) {
1159-
throw new Error('Cannot finalize sign-in without a created session.');
1160-
}
11611160

1161+
if (!this.resource.createdSessionId) {
1162+
throw new Error('Cannot finalize sign-in without a created session.');
1163+
}
1164+
1165+
return runAsyncResourceTask(this.resource, async () => {
11621166
// Reload the client to prevent an issue where the created session is not picked up.
11631167
await SignIn.clerk.client?.reload();
11641168

0 commit comments

Comments
 (0)