stack/packages/stack-shared/src/utils/country-codes.ts
Mantra 998b3662a5
Enhance error handling and logging in Emailable response validation (#1292)
- Updated `validateVerifyResponse` to capture errors for invalid or
unexpected responses.
- Improved handling of malformed responses in `checkEmailWithEmailable`,
ensuring a consistent return structure.
- Refactored `getDerivedSignUpCountryCode` to log errors for non-ISO
country codes.
- Simplified country code determination logic in
`createOrUpgradeAnonymousUserWithRules`.

<!--

Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md

-->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Replaced country code dropdown selection with a direct text input
field for simpler data entry.
* Updated country code validation to accept any 2-letter code format,
improving flexibility.

* **Bug Fixes**
* Refined country code normalization logic across sign-up rules and user
profile pages for consistency.

* **Documentation**
* Clarified country code field messaging from "ISO code" to "2-letter
country code" terminology for better user guidance.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-01 09:21:43 -07:00

40 lines
1.5 KiB
TypeScript

export function normalizeCountryCode(countryCode: string): string {
return countryCode.trim().toUpperCase();
}
export function isValidCountryCode(countryCode: string): boolean {
const normalized = normalizeCountryCode(countryCode);
return /^[A-Z]{2}$/.test(normalized);
}
/**
* Validates and normalizes a country code value (single string or array).
* Returns null if valid, or an error message string if invalid.
*/
export function validateCountryCode(value: string | string[]): string | null {
const values = Array.isArray(value) ? value : [value];
if (values.length === 0) {
return "At least one country code is required";
}
return values.every(v => isValidCountryCode(v))
? null
: "Country code must be a 2-letter code";
}
import.meta.vitest?.test("country codes", ({ expect }) => {
expect(normalizeCountryCode(" us ")).toBe("US");
expect(isValidCountryCode("us")).toBe(true);
expect(isValidCountryCode("US")).toBe(true);
expect(isValidCountryCode("ZZ")).toBe(true);
expect(isValidCountryCode("usa")).toBe(false);
expect(isValidCountryCode("a")).toBe(false);
expect(isValidCountryCode("")).toBe(false);
expect(isValidCountryCode("12")).toBe(false);
expect(validateCountryCode("US")).toBeNull();
expect(validateCountryCode("zz")).toBeNull();
expect(validateCountryCode(["US", "CA"])).toBeNull();
expect(validateCountryCode([])).toBe("At least one country code is required");
expect(validateCountryCode(["US", "123"])).toBe("Country code must be a 2-letter code");
});