Files
Paul NicolasandGitHub 979b040d94 feat(psu): add payment service user entity (#424)
* chore(storage): remove errors.Wrap deprecated

* feat: add psu models

* feat(storage): add psu migrations and functions

* feat(*): add payment service users entity

* feat(tests): update sdks and add psu integration tests

* feat(validation): add validation on email and phone number
2025-04-29 10:24:09 +02:00

81 lines
2.5 KiB
Go

package validation
import (
"fmt"
"github.com/go-playground/locales"
"github.com/go-playground/locales/en"
"github.com/go-playground/validator/v10"
ut "github.com/go-playground/universal-translator"
en_translations "github.com/go-playground/validator/v10/translations/en"
)
var (
defaultLocale locales.Translator
supportedLocales []locales.Translator
)
func init() {
defaultLocale = en.New()
supportedLocales = []locales.Translator{defaultLocale}
}
type Validator struct {
internal *validator.Validate
translator ut.Translator
}
func NewValidator() *Validator {
uni := ut.New(defaultLocale, supportedLocales...)
// TODO: non-default locale could be configured for a stack if we have non-english clients who need it
translator, _ := uni.GetTranslator(defaultLocale.Locale())
validate := validator.New(validator.WithRequiredStructEnabled())
en_translations.RegisterDefaultTranslations(validate, translator) //nolint:errcheck
registerCustomChecker("accountID", IsAccountID, "", validate, translator)
registerCustomChecker("accountType", IsAccountType, "", validate, translator)
registerCustomChecker("connectorID", IsConnectorID, "", validate, translator)
registerCustomChecker("paymentType", IsPaymentType, "", validate, translator)
registerCustomChecker("paymentScheme", IsPaymentScheme, "", validate, translator)
registerCustomChecker("paymentStatus", IsPaymentStatus, "", validate, translator)
registerCustomChecker("paymentInitiationType", IsPaymentInitiationType, "", validate, translator)
registerCustomChecker("asset", IsAsset, "", validate, translator)
registerCustomChecker("phoneNumber", IsPhoneNumber, "", validate, translator)
registerCustomChecker("email", IsEmail, "", validate, translator)
return &Validator{
internal: validate,
translator: translator,
}
}
func (v *Validator) Validate(payload any) (fieldErrors validator.ValidationErrors, err error) {
rawErr := v.internal.Struct(payload)
if rawErr == nil {
return fieldErrors, nil
}
fieldErrors, ok := rawErr.(validator.ValidationErrors)
if !ok {
return fieldErrors, rawErr
}
if len(fieldErrors) > 0 {
return fieldErrors, fmt.Errorf("%s", fieldErrors[0].Translate(v.translator))
}
return fieldErrors, rawErr
}
func fieldLevelToString(fl validator.FieldLevel) (str string, err error) {
switch v := fl.Field().Interface().(type) {
case *string:
str = *fl.Field().Interface().(*string)
case string:
str = fl.Field().Interface().(string)
default:
return str, fmt.Errorf("unsupported type %T", v)
}
return str, nil
}