From bbb2f8599323a0d188ba30be6ec41e95de794cb6 Mon Sep 17 00:00:00 2001 From: simeng-li Date: Tue, 21 Feb 2023 10:59:40 +0800 Subject: [PATCH] refactor(ui): clean up the field validation file (#3167) --- .../ui/src/containers/SetPassword/index.tsx | 2 +- packages/ui/src/utils/field-validations.ts | 73 ----------------- packages/ui/src/utils/form.ts | 79 ++++++++++++++----- 3 files changed, 60 insertions(+), 94 deletions(-) delete mode 100644 packages/ui/src/utils/field-validations.ts diff --git a/packages/ui/src/containers/SetPassword/index.tsx b/packages/ui/src/containers/SetPassword/index.tsx index 9c69a7d0c..37362cf89 100644 --- a/packages/ui/src/containers/SetPassword/index.tsx +++ b/packages/ui/src/containers/SetPassword/index.tsx @@ -80,7 +80,7 @@ const SetPassword = ({ required: t('error.password_required'), minLength: { value: 6, - message: t('error.password_min_length', { length: 6 }), + message: t('error.password_min_length', { min: 6 }), }, })} isSuffixFocusVisible={!!watch('newPassword')} diff --git a/packages/ui/src/utils/field-validations.ts b/packages/ui/src/utils/field-validations.ts deleted file mode 100644 index 627b2eb1f..000000000 --- a/packages/ui/src/utils/field-validations.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { parsePhoneNumberWithError, ParseError } from 'libphonenumber-js/mobile'; - -import type { ErrorType } from '@/components/ErrorMessage'; -import { parseE164Number } from '@/utils/country-code'; - -// TODO: clean up this file and merge to form utils - -export const usernameRegex = /^[A-Z_a-z-][\w-]*$/; -export const emailRegex = /^\S+@\S+\.\S+$/; - -export const requiredValidation = ( - type: 'username' | 'password', - value: string -): ErrorType | undefined => { - if (!value) { - return type === 'username' ? 'username_required' : 'password_required'; - } -}; - -export const validateUsername = (username: string): ErrorType | undefined => { - if (!username) { - return 'username_required'; - } - - if (/^\d/.test(username)) { - return 'username_should_not_start_with_number'; - } - - if (!usernameRegex.test(username)) { - return 'username_invalid_charset'; - } -}; - -export const validateEmail = (email: string): ErrorType | undefined => { - if (!emailRegex.test(email)) { - return 'invalid_email'; - } -}; - -export const validatePhone = (value: string): ErrorType | undefined => { - try { - const phoneNumber = parsePhoneNumberWithError(parseE164Number(value)); - - if (!phoneNumber.isValid()) { - return 'invalid_phone'; - } - } catch (error: unknown) { - if (error instanceof ParseError) { - return 'invalid_phone'; - } - - throw error; - } -}; - -export const passwordValidation = (password: string): ErrorType | undefined => { - if (!password) { - return 'password_required'; - } - - if (password.length < 6) { - return { code: 'password_min_length', data: { min: 6 } }; - } -}; - -export const confirmPasswordValidation = ( - password: string, - confirmPassword: string -): ErrorType | undefined => { - if (password !== confirmPassword) { - return { code: 'passwords_do_not_match' }; - } -}; diff --git a/packages/ui/src/utils/form.ts b/packages/ui/src/utils/form.ts index ebac8e852..62d5357a0 100644 --- a/packages/ui/src/utils/form.ts +++ b/packages/ui/src/utils/form.ts @@ -1,14 +1,70 @@ import { SignInIdentifier } from '@logto/schemas'; import i18next from 'i18next'; +import { parsePhoneNumberWithError, ParseError } from 'libphonenumber-js/mobile'; import type { TFuncKey } from 'react-i18next'; +import type { ErrorType } from '@/components/ErrorMessage'; import type { IdentifierInputType } from '@/components/InputFields/SmartInputField'; - -import { parsePhoneNumber } from './country-code'; -import { validateUsername, validateEmail, validatePhone } from './field-validations'; +import { parseE164Number, parsePhoneNumber } from '@/utils/country-code'; const { t } = i18next; +const usernameRegex = /^[A-Z_a-z-][\w-]*$/; +const emailRegex = /^\S+@\S+\.\S+$/; + +export const validateUsername = (username: string): ErrorType | undefined => { + if (!username) { + return 'username_required'; + } + + if (/^\d/.test(username)) { + return 'username_should_not_start_with_number'; + } + + if (!usernameRegex.test(username)) { + return 'username_invalid_charset'; + } +}; + +export const validateEmail = (email: string): ErrorType | undefined => { + if (!emailRegex.test(email)) { + return 'invalid_email'; + } +}; + +export const validatePhone = (value: string): ErrorType | undefined => { + try { + const phoneNumber = parsePhoneNumberWithError(parseE164Number(value)); + + if (!phoneNumber.isValid()) { + return 'invalid_phone'; + } + } catch (error: unknown) { + if (error instanceof ParseError) { + return 'invalid_phone'; + } + + throw error; + } +}; + +export const validateIdentifierField = (type: IdentifierInputType, value: string) => { + switch (type) { + case SignInIdentifier.Username: { + return validateUsername(value); + } + + case SignInIdentifier.Email: { + return validateEmail(value); + } + + case SignInIdentifier.Phone: { + return validatePhone(value); + } + default: + } +}; + export const identifierInputPlaceholderMap: { [K in IdentifierInputType]: TFuncKey } = { [SignInIdentifier.Phone]: 'input.phone_number', [SignInIdentifier.Email]: 'input.email', @@ -36,23 +92,6 @@ export const getGeneralIdentifierErrorMessage = ( return t<'translation', TFuncKey>(code, data); }; -export const validateIdentifierField = (type: IdentifierInputType, value: string) => { - switch (type) { - case SignInIdentifier.Username: { - return validateUsername(value); - } - - case SignInIdentifier.Email: { - return validateEmail(value); - } - - case SignInIdentifier.Phone: { - return validatePhone(value); - } - default: - } -}; - export const parseIdentifierValue = (type?: IdentifierInputType, value?: string) => { if (type === SignInIdentifier.Phone && value) { const validPhoneNumber = parsePhoneNumber(value);