Skip to content

Commit 1189f71

Browse files
authoredSep 11, 2024··
chore(clerk-js,types,localizations): Add translation keys for organizations API errors (#4123)
1 parent 46fc758 commit 1189f71

39 files changed

+2148
-76
lines changed
 

‎.changeset/silly-carrots-repeat.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@clerk/localizations": patch
3+
"@clerk/clerk-js": patch
4+
"@clerk/types": patch
5+
---
6+
7+
Adds translation keys for error messages from the [organizations API](https://clerk.com/docs/references/api/organizations#errors).

‎packages/clerk-js/bundlewatch.config.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"files": [
33
{ "path": "./dist/clerk.browser.js", "maxSize": "64kB" },
44
{ "path": "./dist/clerk.headless.js", "maxSize": "43kB" },
5-
{ "path": "./dist/ui-common*.js", "maxSize": "85KB" },
5+
{ "path": "./dist/ui-common*.js", "maxSize": "86KB" },
66
{ "path": "./dist/vendors*.js", "maxSize": "70KB" },
77
{ "path": "./dist/coinbase*.js", "maxSize": "58KB" },
88
{ "path": "./dist/createorganization*.js", "maxSize": "5KB" },

‎packages/clerk-js/src/ui/components/OrganizationProfile/InviteMembersForm.tsx

+46-17
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export const InviteMembersForm = (props: InviteMembersFormProps) => {
3131
},
3232
});
3333
const card = useCardState();
34-
const { t, locale, translateError } = useLocalizations();
34+
const { t, locale } = useLocalizations();
3535
const [isValidUnsubmittedEmail, setIsValidUnsubmittedEmail] = useState(false);
3636

3737
const validateUnsubmittedEmail = (value: string) => setIsValidUnsubmittedEmail(isEmail(value));
@@ -85,24 +85,53 @@ export const InviteMembersForm = (props: InviteMembersFormProps) => {
8585
return onSuccess?.();
8686
})
8787
.catch(err => {
88-
if (isClerkAPIResponseError(err)) {
89-
removeInvalidEmails(err.errors[0]);
88+
if (!isClerkAPIResponseError(err)) {
89+
handleError(err, [], card.setError);
90+
return;
9091
}
9192

92-
if (isClerkAPIResponseError(err) && err.errors?.[0]?.code === 'duplicate_record') {
93-
const unlocalizedEmailsList = err.errors[0].meta?.emailAddresses || [];
94-
card.setError(
95-
t(
96-
localizationKeys('organizationProfile.invitePage.detailsTitle__inviteFailed', {
97-
// Create a localized list of email addresses
98-
email_addresses: createListFormat(unlocalizedEmailsList, locale),
99-
}),
100-
),
101-
);
102-
} else if (isClerkAPIResponseError(err) && err.errors?.[0]?.code === 'form_param_format_invalid') {
103-
card.setError(translateError(err.errors[0]));
104-
} else {
105-
handleError(err, [], card.setError);
93+
removeInvalidEmails(err.errors[0]);
94+
95+
switch (err.errors?.[0]?.code) {
96+
case 'duplicate_record': {
97+
const unlocalizedEmailsList = err.errors[0].meta?.emailAddresses || [];
98+
card.setError(
99+
t(
100+
localizationKeys('organizationProfile.invitePage.detailsTitle__inviteFailed', {
101+
// Create a localized list of email addresses
102+
email_addresses: createListFormat(unlocalizedEmailsList, locale),
103+
}),
104+
),
105+
);
106+
break;
107+
}
108+
case 'already_a_member_in_organization': {
109+
/**
110+
* Extracts email from the error message since it's not provided in the error response
111+
*/
112+
const longMessage = err.errors[0].longMessage ?? '';
113+
const email = longMessage.match(/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/)?.[0];
114+
115+
handleError(err, [], err =>
116+
email
117+
? /**
118+
* Fallbacks to original error message in case the email cannot be extracted
119+
*/
120+
card.setError(
121+
t(
122+
localizationKeys('unstable__errors.already_a_member_in_organization', {
123+
email,
124+
}),
125+
),
126+
)
127+
: card.setError(err),
128+
);
129+
130+
break;
131+
}
132+
default: {
133+
handleError(err, [], card.setError);
134+
}
106135
}
107136
});
108137
};

‎packages/clerk-js/src/ui/localization/makeLocalizable.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ export const useLocalizations = () => {
7171
return localizedStringFromKey(localizationKey, parsedResource, globalTokens);
7272
};
7373

74+
/**
75+
* Translates a Clerk error message based on its code.
76+
*
77+
* @remarks
78+
* - For `ClerkRuntimeError`, it attempts to find a localized message using the error code.
79+
* - For `ClerkAPIError`, it tries to find a localized message using the error code and parameter name.
80+
* - If no localized message is found, it falls back to the original error message.
81+
*/
7482
const translateError = (error: ClerkRuntimeError | ClerkAPIError | string | undefined) => {
7583
if (!error || typeof error === 'string') {
7684
return t(error);

‎packages/localizations/src/ar-SA.ts

+61
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,61 @@ import type { LocalizationResource } from '@clerk/types';
1414

1515
export const arSA: LocalizationResource = {
1616
locale: 'ar-SA',
17+
__experimental_userVerification: {
18+
alternativeMethods: {
19+
actionLink: undefined,
20+
actionText: undefined,
21+
blockButton__backupCode: undefined,
22+
blockButton__emailCode: undefined,
23+
blockButton__password: undefined,
24+
blockButton__phoneCode: undefined,
25+
blockButton__totp: undefined,
26+
getHelp: {
27+
blockButton__emailSupport: undefined,
28+
content: undefined,
29+
title: undefined,
30+
},
31+
subtitle: undefined,
32+
title: undefined,
33+
},
34+
backupCodeMfa: {
35+
subtitle: undefined,
36+
title: undefined,
37+
},
38+
emailCode: {
39+
formTitle: undefined,
40+
resendButton: undefined,
41+
subtitle: undefined,
42+
title: undefined,
43+
},
44+
noAvailableMethods: {
45+
message: undefined,
46+
subtitle: undefined,
47+
title: undefined,
48+
},
49+
password: {
50+
actionLink: undefined,
51+
subtitle: undefined,
52+
title: undefined,
53+
},
54+
phoneCode: {
55+
formTitle: undefined,
56+
resendButton: undefined,
57+
subtitle: undefined,
58+
title: undefined,
59+
},
60+
phoneCodeMfa: {
61+
formTitle: undefined,
62+
resendButton: undefined,
63+
subtitle: undefined,
64+
title: undefined,
65+
},
66+
totpMfa: {
67+
formTitle: undefined,
68+
subtitle: undefined,
69+
title: undefined,
70+
},
71+
},
1772
backButton: 'الرجوع',
1873
badge__default: 'الأفتراضي',
1974
badge__otherImpersonatorDevice: 'جهاز منتحل آخر',
@@ -466,6 +521,7 @@ export const arSA: LocalizationResource = {
466521
socialButtonsBlockButton: 'للمتابعة مع {{provider|titleize}}',
467522
socialButtonsBlockButtonManyInView: '{{provider|titleize}}',
468523
unstable__errors: {
524+
already_a_member_in_organization: undefined,
469525
captcha_invalid:
470526
'لا يمكن تسجيل الحساب بسبب مشاكل تحقق أمنية. الرجاء تحديث الصفحة للمحاولة مرة أخرى أو تواصل معنا للمزيد من المساعدة',
471527
captcha_unavailable:
@@ -495,6 +551,10 @@ export const arSA: LocalizationResource = {
495551
form_username_invalid_length: '',
496552
identification_deletion_failed: 'لا يمكن حذف هويتك الآخيرة ',
497553
not_allowed_access: '',
554+
organization_domain_blocked: undefined,
555+
organization_domain_common: undefined,
556+
organization_membership_quota_exceeded: undefined,
557+
organization_minimum_permissions_needed: undefined,
498558
passkey_already_exists: 'تم تسجيل مفتاح المرور مسبقاً مع هذا الجهاز',
499559
passkey_not_supported: 'مفاتيح المرور غير مدعومة على هذا الجهاز',
500560
passkey_pa_not_supported: 'يتطلب التسجيل أداة مصادقة النظام الأساسي ولكن الجهاز لا يدعمها',
@@ -815,6 +875,7 @@ export const arSA: LocalizationResource = {
815875
subtitle__unavailableWallets: 'لا توجد اي محفظة web3 متاحة',
816876
successMessage: 'تمت إضافة المحفظة الى حسابك.',
817877
title: 'إضافة محفظة web3',
878+
web3WalletButtonsBlockButton: undefined,
818879
},
819880
},
820881
} as const;

‎packages/localizations/src/bg-BG.ts

+61
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,61 @@ import type { LocalizationResource } from '@clerk/types';
1414

1515
export const bgBG: LocalizationResource = {
1616
locale: 'bg-BG',
17+
__experimental_userVerification: {
18+
alternativeMethods: {
19+
actionLink: undefined,
20+
actionText: undefined,
21+
blockButton__backupCode: undefined,
22+
blockButton__emailCode: undefined,
23+
blockButton__password: undefined,
24+
blockButton__phoneCode: undefined,
25+
blockButton__totp: undefined,
26+
getHelp: {
27+
blockButton__emailSupport: undefined,
28+
content: undefined,
29+
title: undefined,
30+
},
31+
subtitle: undefined,
32+
title: undefined,
33+
},
34+
backupCodeMfa: {
35+
subtitle: undefined,
36+
title: undefined,
37+
},
38+
emailCode: {
39+
formTitle: undefined,
40+
resendButton: undefined,
41+
subtitle: undefined,
42+
title: undefined,
43+
},
44+
noAvailableMethods: {
45+
message: undefined,
46+
subtitle: undefined,
47+
title: undefined,
48+
},
49+
password: {
50+
actionLink: undefined,
51+
subtitle: undefined,
52+
title: undefined,
53+
},
54+
phoneCode: {
55+
formTitle: undefined,
56+
resendButton: undefined,
57+
subtitle: undefined,
58+
title: undefined,
59+
},
60+
phoneCodeMfa: {
61+
formTitle: undefined,
62+
resendButton: undefined,
63+
subtitle: undefined,
64+
title: undefined,
65+
},
66+
totpMfa: {
67+
formTitle: undefined,
68+
subtitle: undefined,
69+
title: undefined,
70+
},
71+
},
1772
backButton: 'Назад',
1873
badge__default: 'По подразбиране',
1974
badge__otherImpersonatorDevice: 'Друго устройство за имитация',
@@ -467,6 +522,7 @@ export const bgBG: LocalizationResource = {
467522
socialButtonsBlockButton: 'Продължи с {{provider|titleize}}',
468523
socialButtonsBlockButtonManyInView: undefined,
469524
unstable__errors: {
525+
already_a_member_in_organization: undefined,
470526
captcha_invalid:
471527
'Регистрацията неуспешна поради неуспешни проверки за сигурност. Моля, презаредете страницата, за да опитате отново, или се свържете с поддръжката за повече помощ.',
472528
captcha_unavailable:
@@ -496,6 +552,10 @@ export const bgBG: LocalizationResource = {
496552
form_username_invalid_length: '',
497553
identification_deletion_failed: 'Не можете да изтриете последната си идентификация.',
498554
not_allowed_access: '',
555+
organization_domain_blocked: undefined,
556+
organization_domain_common: undefined,
557+
organization_membership_quota_exceeded: undefined,
558+
organization_minimum_permissions_needed: undefined,
499559
passkey_already_exists: undefined,
500560
passkey_not_supported: undefined,
501561
passkey_pa_not_supported: undefined,
@@ -822,6 +882,7 @@ export const bgBG: LocalizationResource = {
822882
subtitle__unavailableWallets: 'Няма налични web3 портфейли.',
823883
successMessage: 'Портфейлът беше добавен към вашия профил.',
824884
title: 'Добави web3 портфейл',
885+
web3WalletButtonsBlockButton: undefined,
825886
},
826887
},
827888
} as const;

‎packages/localizations/src/cs-CZ.ts

+61
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,61 @@ import type { LocalizationResource } from '@clerk/types';
1414

1515
export const csCZ: LocalizationResource = {
1616
locale: 'cs-CZ',
17+
__experimental_userVerification: {
18+
alternativeMethods: {
19+
actionLink: undefined,
20+
actionText: undefined,
21+
blockButton__backupCode: undefined,
22+
blockButton__emailCode: undefined,
23+
blockButton__password: undefined,
24+
blockButton__phoneCode: undefined,
25+
blockButton__totp: undefined,
26+
getHelp: {
27+
blockButton__emailSupport: undefined,
28+
content: undefined,
29+
title: undefined,
30+
},
31+
subtitle: undefined,
32+
title: undefined,
33+
},
34+
backupCodeMfa: {
35+
subtitle: undefined,
36+
title: undefined,
37+
},
38+
emailCode: {
39+
formTitle: undefined,
40+
resendButton: undefined,
41+
subtitle: undefined,
42+
title: undefined,
43+
},
44+
noAvailableMethods: {
45+
message: undefined,
46+
subtitle: undefined,
47+
title: undefined,
48+
},
49+
password: {
50+
actionLink: undefined,
51+
subtitle: undefined,
52+
title: undefined,
53+
},
54+
phoneCode: {
55+
formTitle: undefined,
56+
resendButton: undefined,
57+
subtitle: undefined,
58+
title: undefined,
59+
},
60+
phoneCodeMfa: {
61+
formTitle: undefined,
62+
resendButton: undefined,
63+
subtitle: undefined,
64+
title: undefined,
65+
},
66+
totpMfa: {
67+
formTitle: undefined,
68+
subtitle: undefined,
69+
title: undefined,
70+
},
71+
},
1772
backButton: 'Zpět',
1873
badge__default: 'Výchozí',
1974
badge__otherImpersonatorDevice: 'Jiné zařízení představitele',
@@ -465,6 +520,7 @@ export const csCZ: LocalizationResource = {
465520
socialButtonsBlockButton: 'Pokračovat s {{provider|titleize}}',
466521
socialButtonsBlockButtonManyInView: undefined,
467522
unstable__errors: {
523+
already_a_member_in_organization: undefined,
468524
captcha_invalid:
469525
'Sign up unsuccessful due to failed security validations. Please refresh the page to try again or reach out to support for more assistance.',
470526
captcha_unavailable:
@@ -494,6 +550,10 @@ export const csCZ: LocalizationResource = {
494550
form_username_invalid_length: '',
495551
identification_deletion_failed: 'You cannot delete your last identification.',
496552
not_allowed_access: '',
553+
organization_domain_blocked: undefined,
554+
organization_domain_common: undefined,
555+
organization_membership_quota_exceeded: undefined,
556+
organization_minimum_permissions_needed: undefined,
497557
passkey_already_exists: undefined,
498558
passkey_not_supported: undefined,
499559
passkey_pa_not_supported: undefined,
@@ -818,6 +878,7 @@ export const csCZ: LocalizationResource = {
818878
subtitle__unavailableWallets: 'Nejsou k dispozici žádné dostupné web3 peněženky.',
819879
successMessage: 'Peněženka byla přidána k vašemu účtu.',
820880
title: 'Přidat web3 peněženku',
881+
web3WalletButtonsBlockButton: undefined,
821882
},
822883
},
823884
} as const;

0 commit comments

Comments
 (0)
Please sign in to comment.