diff options
author | 2022-05-02 14:05:18 +0100 | |
---|---|---|
committer | 2022-05-02 15:05:18 +0200 | |
commit | b56dae8120d43b9acd3d3ed4d40100ffab7b972a (patch) | |
tree | d55d30589d8a8499ed3d5eecba163abc9fa78c27 /vendor/github.com/go-playground | |
parent | add extra indexes as a migration (#527) (diff) | |
download | gotosocial-b56dae8120d43b9acd3d3ed4d40100ffab7b972a.tar.xz |
[chore] Update all but bun libraries (#526)
* update all but bun libraries
Signed-off-by: kim <grufwub@gmail.com>
* remove my personal build script changes
Signed-off-by: kim <grufwub@gmail.com>
Diffstat (limited to 'vendor/github.com/go-playground')
8 files changed, 448 insertions, 181 deletions
diff --git a/vendor/github.com/go-playground/validator/v10/README.md b/vendor/github.com/go-playground/validator/v10/README.md index f56cff15d..8b730b6d3 100644 --- a/vendor/github.com/go-playground/validator/v10/README.md +++ b/vendor/github.com/go-playground/validator/v10/README.md @@ -1,7 +1,7 @@ Package validator ================= <img align="right" src="https://raw.githubusercontent.com/go-playground/validator/v9/logo.png">[](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - + [](https://travis-ci.org/go-playground/validator) [](https://coveralls.io/github/go-playground/validator?branch=master) [](https://goreportcard.com/report/github.com/go-playground/validator) @@ -130,7 +130,7 @@ Baked-in Validations | contains | Contains | | containsany | Contains Any | | containsrune | Contains Rune | -| endsnotwith | Ends With | +| endsnotwith | Ends Not With | | endswith | Ends With | | excludes | Excludes | | excludesall | Excludes All | @@ -153,6 +153,7 @@ Baked-in Validations | bcp47_language_tag | Language tag (BCP 47) | | btc_addr | Bitcoin Address | | btc_addr_bech32 | Bitcoin Bech32 Address (segwit) | +| credit_card | Credit Card Number | | datetime | Datetime | | e164 | e164 formatted phone number | | email | E-mail String @@ -189,6 +190,18 @@ Baked-in Validations | uuid5 | Universally Unique Identifier UUID v5 | | uuid5_rfc4122 | Universally Unique Identifier UUID v5 RFC4122 | | uuid_rfc4122 | Universally Unique Identifier UUID RFC4122 | +| md4 | MD4 hash | +| md5 | MD5 hash | +| sha256 | SHA256 hash | +| sha384 | SHA384 hash | +| sha512 | SHA512 hash | +| ripemd128 | RIPEMD-128 hash | +| ripemd128 | RIPEMD-160 hash | +| tiger128 | TIGER128 hash | +| tiger160 | TIGER160 hash | +| tiger192 | TIGER192 hash | +| semver | Semantic Versioning 2.0.0 | +| ulid | Universally Unique Lexicographically Sortable Identifier ULID | ### Comparisons: | Tag | Description | @@ -217,6 +230,8 @@ Baked-in Validations | required_with_all | Required With All | | required_without | Required Without | | required_without_all | Required Without All | +| excluded_if | Excluded If | +| excluded_unless | Excluded Unless | | excluded_with | Excluded With | | excluded_with_all | Excluded With All | | excluded_without | Excluded Without | diff --git a/vendor/github.com/go-playground/validator/v10/baked_in.go b/vendor/github.com/go-playground/validator/v10/baked_in.go index f5fd2391d..f2f0939cf 100644 --- a/vendor/github.com/go-playground/validator/v10/baked_in.go +++ b/vendor/github.com/go-playground/validator/v10/baked_in.go @@ -75,6 +75,8 @@ var ( "required_with_all": requiredWithAll, "required_without": requiredWithout, "required_without_all": requiredWithoutAll, + "excluded_if": excludedIf, + "excluded_unless": excludedUnless, "excluded_with": excludedWith, "excluded_with_all": excludedWithAll, "excluded_without": excludedWithout, @@ -148,6 +150,17 @@ var ( "uuid3_rfc4122": isUUID3RFC4122, "uuid4_rfc4122": isUUID4RFC4122, "uuid5_rfc4122": isUUID5RFC4122, + "ulid": isULID, + "md4": isMD4, + "md5": isMD5, + "sha256": isSHA256, + "sha384": isSHA384, + "sha512": isSHA512, + "ripemd128": isRIPEMD128, + "ripemd160": isRIPEMD160, + "tiger128": isTIGER128, + "tiger160": isTIGER160, + "tiger192": isTIGER192, "ascii": isASCII, "printascii": isPrintableASCII, "multibyte": hasMultiByteCharacter, @@ -198,11 +211,16 @@ var ( "postcode_iso3166_alpha2": isPostcodeByIso3166Alpha2, "postcode_iso3166_alpha2_field": isPostcodeByIso3166Alpha2Field, "bic": isIsoBicFormat, + "semver": isSemverFormat, + "dns_rfc1035_label": isDnsRFC1035LabelFormat, + "credit_card": isCreditCard, } ) -var oneofValsCache = map[string][]string{} -var oneofValsCacheRWLock = sync.RWMutex{} +var ( + oneofValsCache = map[string][]string{} + oneofValsCacheRWLock = sync.RWMutex{} +) func parseOneOfParam2(s string) []string { oneofValsCacheRWLock.RLock() @@ -258,7 +276,6 @@ func isOneOf(fl FieldLevel) bool { // isUnique is the validation function for validating if each array|slice|map value is unique func isUnique(fl FieldLevel) bool { - field := fl.Field() param := fl.Param() v := reflect.ValueOf(struct{}{}) @@ -308,7 +325,6 @@ func isUnique(fl FieldLevel) bool { // isMAC is the validation function for validating if the field's value is a valid MAC address. func isMAC(fl FieldLevel) bool { - _, err := net.ParseMAC(fl.Field().String()) return err == nil @@ -316,7 +332,6 @@ func isMAC(fl FieldLevel) bool { // isCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address. func isCIDRv4(fl FieldLevel) bool { - ip, _, err := net.ParseCIDR(fl.Field().String()) return err == nil && ip.To4() != nil @@ -324,7 +339,6 @@ func isCIDRv4(fl FieldLevel) bool { // isCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address. func isCIDRv6(fl FieldLevel) bool { - ip, _, err := net.ParseCIDR(fl.Field().String()) return err == nil && ip.To4() == nil @@ -332,7 +346,6 @@ func isCIDRv6(fl FieldLevel) bool { // isCIDR is the validation function for validating if the field's value is a valid v4 or v6 CIDR address. func isCIDR(fl FieldLevel) bool { - _, _, err := net.ParseCIDR(fl.Field().String()) return err == nil @@ -340,7 +353,6 @@ func isCIDR(fl FieldLevel) bool { // isIPv4 is the validation function for validating if a value is a valid v4 IP address. func isIPv4(fl FieldLevel) bool { - ip := net.ParseIP(fl.Field().String()) return ip != nil && ip.To4() != nil @@ -348,7 +360,6 @@ func isIPv4(fl FieldLevel) bool { // isIPv6 is the validation function for validating if the field's value is a valid v6 IP address. func isIPv6(fl FieldLevel) bool { - ip := net.ParseIP(fl.Field().String()) return ip != nil && ip.To4() == nil @@ -356,7 +367,6 @@ func isIPv6(fl FieldLevel) bool { // isIP is the validation function for validating if the field's value is a valid v4 or v6 IP address. func isIP(fl FieldLevel) bool { - ip := net.ParseIP(fl.Field().String()) return ip != nil @@ -364,7 +374,6 @@ func isIP(fl FieldLevel) bool { // isSSN is the validation function for validating if the field's value is a valid SSN. func isSSN(fl FieldLevel) bool { - field := fl.Field() if field.Len() != 11 { @@ -422,7 +431,6 @@ func isLatitude(fl FieldLevel) bool { // isDataURI is the validation function for validating if the field's value is a valid data URI. func isDataURI(fl FieldLevel) bool { - uri := strings.SplitN(fl.Field().String(), ",", 2) if len(uri) != 2 { @@ -438,7 +446,6 @@ func isDataURI(fl FieldLevel) bool { // hasMultiByteCharacter is the validation function for validating if the field's value has a multi byte character. func hasMultiByteCharacter(fl FieldLevel) bool { - field := fl.Field() if field.Len() == 0 { @@ -498,6 +505,61 @@ func isUUIDRFC4122(fl FieldLevel) bool { return uUIDRFC4122Regex.MatchString(fl.Field().String()) } +// isULID is the validation function for validating if the field's value is a valid ULID. +func isULID(fl FieldLevel) bool { + return uLIDRegex.MatchString(fl.Field().String()) +} + +// isMD4 is the validation function for validating if the field's value is a valid MD4. +func isMD4(fl FieldLevel) bool { + return md4Regex.MatchString(fl.Field().String()) +} + +// isMD5 is the validation function for validating if the field's value is a valid MD5. +func isMD5(fl FieldLevel) bool { + return md5Regex.MatchString(fl.Field().String()) +} + +// isSHA256 is the validation function for validating if the field's value is a valid SHA256. +func isSHA256(fl FieldLevel) bool { + return sha256Regex.MatchString(fl.Field().String()) +} + +// isSHA384 is the validation function for validating if the field's value is a valid SHA384. +func isSHA384(fl FieldLevel) bool { + return sha384Regex.MatchString(fl.Field().String()) +} + +// isSHA512 is the validation function for validating if the field's value is a valid SHA512. +func isSHA512(fl FieldLevel) bool { + return sha512Regex.MatchString(fl.Field().String()) +} + +// isRIPEMD128 is the validation function for validating if the field's value is a valid PIPEMD128. +func isRIPEMD128(fl FieldLevel) bool { + return ripemd128Regex.MatchString(fl.Field().String()) +} + +// isRIPEMD160 is the validation function for validating if the field's value is a valid PIPEMD160. +func isRIPEMD160(fl FieldLevel) bool { + return ripemd160Regex.MatchString(fl.Field().String()) +} + +// isTIGER128 is the validation function for validating if the field's value is a valid TIGER128. +func isTIGER128(fl FieldLevel) bool { + return tiger128Regex.MatchString(fl.Field().String()) +} + +// isTIGER160 is the validation function for validating if the field's value is a valid TIGER160. +func isTIGER160(fl FieldLevel) bool { + return tiger160Regex.MatchString(fl.Field().String()) +} + +// isTIGER192 is the validation function for validating if the field's value is a valid isTIGER192. +func isTIGER192(fl FieldLevel) bool { + return tiger192Regex.MatchString(fl.Field().String()) +} + // isISBN is the validation function for validating if the field's value is a valid v10 or v13 ISBN. func isISBN(fl FieldLevel) bool { return isISBN10(fl) || isISBN13(fl) @@ -505,7 +567,6 @@ func isISBN(fl FieldLevel) bool { // isISBN13 is the validation function for validating if the field's value is a valid v13 ISBN. func isISBN13(fl FieldLevel) bool { - s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 4), " ", "", 4) if !iSBN13Regex.MatchString(s) { @@ -526,7 +587,6 @@ func isISBN13(fl FieldLevel) bool { // isISBN10 is the validation function for validating if the field's value is a valid v10 ISBN. func isISBN10(fl FieldLevel) bool { - s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 3), " ", "", 3) if !iSBN10Regex.MatchString(s) { @@ -714,7 +774,6 @@ func excludes(fl FieldLevel) bool { // containsRune is the validation function for validating that the field's value contains the rune specified within the param. func containsRune(fl FieldLevel) bool { - r, _ := utf8.DecodeRuneInString(fl.Param()) return strings.ContainsRune(fl.Field().String(), r) @@ -777,7 +836,6 @@ func fieldExcludes(fl FieldLevel) bool { // isNeField is the validation function for validating if the current field's value is not equal to the field specified by the param's value. func isNeField(fl FieldLevel) bool { - field := fl.Field() kind := field.Kind() @@ -808,12 +866,7 @@ func isNeField(fl FieldLevel) bool { fieldType := field.Type() - // Not Same underlying type i.e. struct and time - if fieldType != currentField.Type() { - return true - } - - if fieldType == timeType { + if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) { t := currentField.Interface().(time.Time) fieldTime := field.Interface().(time.Time) @@ -821,6 +874,10 @@ func isNeField(fl FieldLevel) bool { return !fieldTime.Equal(t) } + // Not Same underlying type i.e. struct and time + if fieldType != currentField.Type() { + return true + } } // default reflect.String: @@ -834,7 +891,6 @@ func isNe(fl FieldLevel) bool { // isLteCrossStructField is the validation function for validating if the current field's value is less than or equal to the field, within a separate struct, specified by the param's value. func isLteCrossStructField(fl FieldLevel) bool { - field := fl.Field() kind := field.Kind() @@ -861,18 +917,18 @@ func isLteCrossStructField(fl FieldLevel) bool { fieldType := field.Type() - // Not Same underlying type i.e. struct and time - if fieldType != topField.Type() { - return false - } - - if fieldType == timeType { + if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) { - fieldTime := field.Interface().(time.Time) - topTime := topField.Interface().(time.Time) + fieldTime := field.Convert(timeType).Interface().(time.Time) + topTime := topField.Convert(timeType).Interface().(time.Time) return fieldTime.Before(topTime) || fieldTime.Equal(topTime) } + + // Not Same underlying type i.e. struct and time + if fieldType != topField.Type() { + return false + } } // default reflect.String: @@ -882,7 +938,6 @@ func isLteCrossStructField(fl FieldLevel) bool { // isLtCrossStructField is the validation function for validating if the current field's value is less than the field, within a separate struct, specified by the param's value. // NOTE: This is exposed for use within your own custom functions and not intended to be called directly. func isLtCrossStructField(fl FieldLevel) bool { - field := fl.Field() kind := field.Kind() @@ -909,18 +964,18 @@ func isLtCrossStructField(fl FieldLevel) bool { fieldType := field.Type() - // Not Same underlying type i.e. struct and time - if fieldType != topField.Type() { - return false - } - - if fieldType == timeType { + if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) { - fieldTime := field.Interface().(time.Time) - topTime := topField.Interface().(time.Time) + fieldTime := field.Convert(timeType).Interface().(time.Time) + topTime := topField.Convert(timeType).Interface().(time.Time) return fieldTime.Before(topTime) } + + // Not Same underlying type i.e. struct and time + if fieldType != topField.Type() { + return false + } } // default reflect.String: @@ -929,7 +984,6 @@ func isLtCrossStructField(fl FieldLevel) bool { // isGteCrossStructField is the validation function for validating if the current field's value is greater than or equal to the field, within a separate struct, specified by the param's value. func isGteCrossStructField(fl FieldLevel) bool { - field := fl.Field() kind := field.Kind() @@ -956,18 +1010,18 @@ func isGteCrossStructField(fl FieldLevel) bool { fieldType := field.Type() - // Not Same underlying type i.e. struct and time - if fieldType != topField.Type() { - return false - } - - if fieldType == timeType { + if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) { - fieldTime := field.Interface().(time.Time) - topTime := topField.Interface().(time.Time) + fieldTime := field.Convert(timeType).Interface().(time.Time) + topTime := topField.Convert(timeType).Interface().(time.Time) return fieldTime.After(topTime) || fieldTime.Equal(topTime) } + + // Not Same underlying type i.e. struct and time + if fieldType != topField.Type() { + return false + } } // default reflect.String: @@ -976,7 +1030,6 @@ func isGteCrossStructField(fl FieldLevel) bool { // isGtCrossStructField is the validation function for validating if the current field's value is greater than the field, within a separate struct, specified by the param's value. func isGtCrossStructField(fl FieldLevel) bool { - field := fl.Field() kind := field.Kind() @@ -1003,18 +1056,18 @@ func isGtCrossStructField(fl FieldLevel) bool { fieldType := field.Type() - // Not Same underlying type i.e. struct and time - if fieldType != topField.Type() { - return false - } - - if fieldType == timeType { + if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) { - fieldTime := field.Interface().(time.Time) - topTime := topField.Interface().(time.Time) + fieldTime := field.Convert(timeType).Interface().(time.Time) + topTime := topField.Convert(timeType).Interface().(time.Time) return fieldTime.After(topTime) } + + // Not Same underlying type i.e. struct and time + if fieldType != topField.Type() { + return false + } } // default reflect.String: @@ -1023,7 +1076,6 @@ func isGtCrossStructField(fl FieldLevel) bool { // isNeCrossStructField is the validation function for validating that the current field's value is not equal to the field, within a separate struct, specified by the param's value. func isNeCrossStructField(fl FieldLevel) bool { - field := fl.Field() kind := field.Kind() @@ -1053,18 +1105,18 @@ func isNeCrossStructField(fl FieldLevel) bool { fieldType := field.Type() - // Not Same underlying type i.e. struct and time - if fieldType != topField.Type() { - return true - } - - if fieldType == timeType { + if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) { - t := field.Interface().(time.Time) - fieldTime := topField.Interface().(time.Time) + t := field.Convert(timeType).Interface().(time.Time) + fieldTime := topField.Convert(timeType).Interface().(time.Time) return !fieldTime.Equal(t) } + + // Not Same underlying type i.e. struct and time + if fieldType != topField.Type() { + return true + } } // default reflect.String: @@ -1073,7 +1125,6 @@ func isNeCrossStructField(fl FieldLevel) bool { // isEqCrossStructField is the validation function for validating that the current field's value is equal to the field, within a separate struct, specified by the param's value. func isEqCrossStructField(fl FieldLevel) bool { - field := fl.Field() kind := field.Kind() @@ -1103,18 +1154,18 @@ func isEqCrossStructField(fl FieldLevel) bool { fieldType := field.Type() - // Not Same underlying type i.e. struct and time - if fieldType != topField.Type() { - return false - } + if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) { - if fieldType == timeType { - - t := field.Interface().(time.Time) - fieldTime := topField.Interface().(time.Time) + t := field.Convert(timeType).Interface().(time.Time) + fieldTime := topField.Convert(timeType).Interface().(time.Time) return fieldTime.Equal(t) } + + // Not Same underlying type i.e. struct and time + if fieldType != topField.Type() { + return false + } } // default reflect.String: @@ -1123,7 +1174,6 @@ func isEqCrossStructField(fl FieldLevel) bool { // isEqField is the validation function for validating if the current field's value is equal to the field specified by the param's value. func isEqField(fl FieldLevel) bool { - field := fl.Field() kind := field.Kind() @@ -1153,19 +1203,18 @@ func isEqField(fl FieldLevel) bool { fieldType := field.Type() - // Not Same underlying type i.e. struct and time - if fieldType != currentField.Type() { - return false - } + if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) { - if fieldType == timeType { - - t := currentField.Interface().(time.Time) - fieldTime := field.Interface().(time.Time) + t := currentField.Convert(timeType).Interface().(time.Time) + fieldTime := field.Convert(timeType).Interface().(time.Time) return fieldTime.Equal(t) } + // Not Same underlying type i.e. struct and time + if fieldType != currentField.Type() { + return false + } } // default reflect.String: @@ -1174,7 +1223,6 @@ func isEqField(fl FieldLevel) bool { // isEq is the validation function for validating if the current field's value is equal to the param's value. func isEq(fl FieldLevel) bool { - field := fl.Field() param := fl.Param() @@ -1226,7 +1274,7 @@ func isPostcodeByIso3166Alpha2(fl FieldLevel) bool { return reg.MatchString(field.String()) } -// isPostcodeByIso3166Alpha2 validates by field which represents for a value of country code in iso 3166 alpha 2 +// isPostcodeByIso3166Alpha2Field validates by field which represents for a value of country code in iso 3166 alpha 2 // example: `postcode_iso3166_alpha2_field=CountryCode` func isPostcodeByIso3166Alpha2Field(fl FieldLevel) bool { field := fl.Field() @@ -1265,11 +1313,9 @@ func isBase64URL(fl FieldLevel) bool { // isURI is the validation function for validating if the current field's value is a valid URI. func isURI(fl FieldLevel) bool { - field := fl.Field() switch field.Kind() { - case reflect.String: s := field.String() @@ -1294,11 +1340,9 @@ func isURI(fl FieldLevel) bool { // isURL is the validation function for validating if the current field's value is a valid URL. func isURL(fl FieldLevel) bool { - field := fl.Field() switch field.Kind() { - case reflect.String: var i int @@ -1331,7 +1375,6 @@ func isUrnRFC2141(fl FieldLevel) bool { field := fl.Field() switch field.Kind() { - case reflect.String: str := field.String() @@ -1534,6 +1577,22 @@ func requiredIf(fl FieldLevel) bool { return hasValue(fl) } +// excludedIf is the validation function +// The field under validation must not be present or is empty only if all the other specified fields are equal to the value following with the specified field. +func excludedIf(fl FieldLevel) bool { + params := parseOneOfParam2(fl.Param()) + if len(params)%2 != 0 { + panic(fmt.Sprintf("Bad param number for excluded_if %s", fl.FieldName())) + } + + for i := 0; i < len(params); i += 2 { + if !requireCheckFieldValue(fl, params[i], params[i+1], false) { + return false + } + } + return true +} + // requiredUnless is the validation function // The field under validation must be present and not empty only unless all the other specified fields are equal to the value following with the specified field. func requiredUnless(fl FieldLevel) bool { @@ -1550,6 +1609,21 @@ func requiredUnless(fl FieldLevel) bool { return hasValue(fl) } +// excludedUnless is the validation function +// The field under validation must not be present or is empty unless all the other specified fields are equal to the value following with the specified field. +func excludedUnless(fl FieldLevel) bool { + params := parseOneOfParam2(fl.Param()) + if len(params)%2 != 0 { + panic(fmt.Sprintf("Bad param number for excluded_unless %s", fl.FieldName())) + } + for i := 0; i < len(params); i += 2 { + if !requireCheckFieldValue(fl, params[i], params[i+1], false) { + return true + } + } + return !hasValue(fl) +} + // excludedWith is the validation function // The field under validation must not be present or is empty if any of the other specified fields are present. func excludedWith(fl FieldLevel) bool { @@ -1642,7 +1716,6 @@ func requiredWithoutAll(fl FieldLevel) bool { // isGteField is the validation function for validating if the current field's value is greater than or equal to the field specified by the param's value. func isGteField(fl FieldLevel) bool { - field := fl.Field() kind := field.Kind() @@ -1669,18 +1742,18 @@ func isGteField(fl FieldLevel) bool { fieldType := field.Type() - // Not Same underlying type i.e. struct and time - if fieldType != currentField.Type() { - return false - } - - if fieldType == timeType { + if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) { - t := currentField.Interface().(time.Time) - fieldTime := field.Interface().(time.Time) + t := currentField.Convert(timeType).Interface().(time.Time) + fieldTime := field.Convert(timeType).Interface().(time.Time) return fieldTime.After(t) || fieldTime.Equal(t) } + + // Not Same underlying type i.e. struct and time + if fieldType != currentField.Type() { + return false + } } // default reflect.String @@ -1689,7 +1762,6 @@ func isGteField(fl FieldLevel) bool { // isGtField is the validation function for validating if the current field's value is greater than the field specified by the param's value. func isGtField(fl FieldLevel) bool { - field := fl.Field() kind := field.Kind() @@ -1716,18 +1788,18 @@ func isGtField(fl FieldLevel) bool { fieldType := field.Type() - // Not Same underlying type i.e. struct and time - if fieldType != currentField.Type() { - return false - } - - if fieldType == timeType { + if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) { - t := currentField.Interface().(time.Time) - fieldTime := field.Interface().(time.Time) + t := currentField.Convert(timeType).Interface().(time.Time) + fieldTime := field.Convert(timeType).Interface().(time.Time) return fieldTime.After(t) } + + // Not Same underlying type i.e. struct and time + if fieldType != currentField.Type() { + return false + } } // default reflect.String @@ -1736,7 +1808,6 @@ func isGtField(fl FieldLevel) bool { // isGte is the validation function for validating if the current field's value is greater than or equal to the param's value. func isGte(fl FieldLevel) bool { - field := fl.Field() param := fl.Param() @@ -1769,10 +1840,10 @@ func isGte(fl FieldLevel) bool { case reflect.Struct: - if field.Type() == timeType { + if field.Type().ConvertibleTo(timeType) { now := time.Now().UTC() - t := field.Interface().(time.Time) + t := field.Convert(timeType).Interface().(time.Time) return t.After(now) || t.Equal(now) } @@ -1783,7 +1854,6 @@ func isGte(fl FieldLevel) bool { // isGt is the validation function for validating if the current field's value is greater than the param's value. func isGt(fl FieldLevel) bool { - field := fl.Field() param := fl.Param() @@ -1815,9 +1885,9 @@ func isGt(fl FieldLevel) bool { return field.Float() > p case reflect.Struct: - if field.Type() == timeType { + if field.Type().ConvertibleTo(timeType) { - return field.Interface().(time.Time).After(time.Now().UTC()) + return field.Convert(timeType).Interface().(time.Time).After(time.Now().UTC()) } } @@ -1826,7 +1896,6 @@ func isGt(fl FieldLevel) bool { // hasLengthOf is the validation function for validating if the current field's value is equal to the param's value. func hasLengthOf(fl FieldLevel) bool { - field := fl.Field() param := fl.Param() @@ -1868,7 +1937,6 @@ func hasMinOf(fl FieldLevel) bool { // isLteField is the validation function for validating if the current field's value is less than or equal to the field specified by the param's value. func isLteField(fl FieldLevel) bool { - field := fl.Field() kind := field.Kind() @@ -1895,18 +1963,18 @@ func isLteField(fl FieldLevel) bool { fieldType := field.Type() - // Not Same underlying type i.e. struct and time - if fieldType != currentField.Type() { - return false - } + if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) { - if fieldType == timeType { - - t := currentField.Interface().(time.Time) - fieldTime := field.Interface().(time.Time) + t := currentField.Convert(timeType).Interface().(time.Time) + fieldTime := field.Convert(timeType).Interface().(time.Time) return fieldTime.Before(t) || fieldTime.Equal(t) } + + // Not Same underlying type i.e. struct and time + if fieldType != currentField.Type() { + return false + } } // default reflect.String @@ -1915,7 +1983,6 @@ func isLteField(fl FieldLevel) bool { // isLtField is the validation function for validating if the current field's value is less than the field specified by the param's value. func isLtField(fl FieldLevel) bool { - field := fl.Field() kind := field.Kind() @@ -1942,18 +2009,18 @@ func isLtField(fl FieldLevel) bool { fieldType := field.Type() - // Not Same underlying type i.e. struct and time - if fieldType != currentField.Type() { - return false - } - - if fieldType == timeType { + if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) { - t := currentField.Interface().(time.Time) - fieldTime := field.Interface().(time.Time) + t := currentField.Convert(timeType).Interface().(time.Time) + fieldTime := field.Convert(timeType).Interface().(time.Time) return fieldTime.Before(t) } + + // Not Same underlying type i.e. struct and time + if fieldType != currentField.Type() { + return false + } } // default reflect.String @@ -1962,7 +2029,6 @@ func isLtField(fl FieldLevel) bool { // isLte is the validation function for validating if the current field's value is less than or equal to the param's value. func isLte(fl FieldLevel) bool { - field := fl.Field() param := fl.Param() @@ -1995,10 +2061,10 @@ func isLte(fl FieldLevel) bool { case reflect.Struct: - if field.Type() == timeType { + if field.Type().ConvertibleTo(timeType) { now := time.Now().UTC() - t := field.Interface().(time.Time) + t := field.Convert(timeType).Interface().(time.Time) return t.Before(now) || t.Equal(now) } @@ -2009,7 +2075,6 @@ func isLte(fl FieldLevel) bool { // isLt is the validation function for validating if the current field's value is less than the param's value. func isLt(fl FieldLevel) bool { - field := fl.Field() param := fl.Param() @@ -2042,9 +2107,9 @@ func isLt(fl FieldLevel) bool { case reflect.Struct: - if field.Type() == timeType { + if field.Type().ConvertibleTo(timeType) { - return field.Interface().(time.Time).Before(time.Now().UTC()) + return field.Convert(timeType).Interface().(time.Time).Before(time.Now().UTC()) } } @@ -2058,7 +2123,6 @@ func hasMaxOf(fl FieldLevel) bool { // isTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address. func isTCP4AddrResolvable(fl FieldLevel) bool { - if !isIP4Addr(fl) { return false } @@ -2069,7 +2133,6 @@ func isTCP4AddrResolvable(fl FieldLevel) bool { // isTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address. func isTCP6AddrResolvable(fl FieldLevel) bool { - if !isIP6Addr(fl) { return false } @@ -2081,7 +2144,6 @@ func isTCP6AddrResolvable(fl FieldLevel) bool { // isTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address. func isTCPAddrResolvable(fl FieldLevel) bool { - if !isIP4Addr(fl) && !isIP6Addr(fl) { return false } @@ -2093,7 +2155,6 @@ func isTCPAddrResolvable(fl FieldLevel) bool { // isUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address. func isUDP4AddrResolvable(fl FieldLevel) bool { - if !isIP4Addr(fl) { return false } @@ -2105,7 +2166,6 @@ func isUDP4AddrResolvable(fl FieldLevel) bool { // isUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address. func isUDP6AddrResolvable(fl FieldLevel) bool { - if !isIP6Addr(fl) { return false } @@ -2117,7 +2177,6 @@ func isUDP6AddrResolvable(fl FieldLevel) bool { // isUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address. func isUDPAddrResolvable(fl FieldLevel) bool { - if !isIP4Addr(fl) && !isIP6Addr(fl) { return false } @@ -2129,7 +2188,6 @@ func isUDPAddrResolvable(fl FieldLevel) bool { // isIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address. func isIP4AddrResolvable(fl FieldLevel) bool { - if !isIPv4(fl) { return false } @@ -2141,7 +2199,6 @@ func isIP4AddrResolvable(fl FieldLevel) bool { // isIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address. func isIP6AddrResolvable(fl FieldLevel) bool { - if !isIPv6(fl) { return false } @@ -2153,7 +2210,6 @@ func isIP6AddrResolvable(fl FieldLevel) bool { // isIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address. func isIPAddrResolvable(fl FieldLevel) bool { - if !isIP(fl) { return false } @@ -2165,14 +2221,12 @@ func isIPAddrResolvable(fl FieldLevel) bool { // isUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address. func isUnixAddrResolvable(fl FieldLevel) bool { - _, err := net.ResolveUnixAddr("unix", fl.Field().String()) return err == nil } func isIP4Addr(fl FieldLevel) bool { - val := fl.Field().String() if idx := strings.LastIndex(val, ":"); idx != -1 { @@ -2185,7 +2239,6 @@ func isIP4Addr(fl FieldLevel) bool { } func isIP6Addr(fl FieldLevel) bool { - val := fl.Field().String() if idx := strings.LastIndex(val, ":"); idx != -1 { @@ -2351,6 +2404,12 @@ func isIso3166AlphaNumeric(fl FieldLevel) bool { var code int switch field.Kind() { + case reflect.String: + i, err := strconv.Atoi(field.String()) + if err != nil { + return false + } + code = i % 1000 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: code = int(field.Int() % 1000) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: @@ -2407,3 +2466,56 @@ func isIsoBicFormat(fl FieldLevel) bool { return bicRegex.MatchString(bicString) } + +// isSemverFormat is the validation function for validating if the current field's value is a valid semver version, defined in Semantic Versioning 2.0.0 +func isSemverFormat(fl FieldLevel) bool { + semverString := fl.Field().String() + + return semverRegex.MatchString(semverString) +} + +// isDnsRFC1035LabelFormat is the validation function +// for validating if the current field's value is +// a valid dns RFC 1035 label, defined in RFC 1035. +func isDnsRFC1035LabelFormat(fl FieldLevel) bool { + val := fl.Field().String() + return dnsRegexRFC1035Label.MatchString(val) +} + +// isCreditCard is the validation function for validating if the current field's value is a valid credit card number +func isCreditCard(fl FieldLevel) bool { + val := fl.Field().String() + var creditCard bytes.Buffer + segments := strings.Split(val, " ") + for _, segment := range segments { + if len(segment) < 3 { + return false + } + creditCard.WriteString(segment) + } + + ccDigits := strings.Split(creditCard.String(), "") + size := len(ccDigits) + if size < 12 || size > 19 { + return false + } + + sum := 0 + for i, digit := range ccDigits { + value, err := strconv.Atoi(digit) + if err != nil { + return false + } + if size%2 == 0 && i%2 == 0 || size%2 == 1 && i%2 == 1 { + v := value * 2 + if v >= 10 { + sum += 1 + (v % 10) + } else { + sum += v + } + } else { + sum += value + } + } + return (sum % 10) == 0 +} diff --git a/vendor/github.com/go-playground/validator/v10/cache.go b/vendor/github.com/go-playground/validator/v10/cache.go index 0d18d6ec4..7b84c91fe 100644 --- a/vendor/github.com/go-playground/validator/v10/cache.go +++ b/vendor/github.com/go-playground/validator/v10/cache.go @@ -114,12 +114,13 @@ func (v *Validate) extractStructCache(current reflect.Value, sName string) *cStr cs = &cStruct{name: sName, fields: make([]*cField, 0), fn: v.structLevelFuncs[typ]} numFields := current.NumField() + rules := v.rules[typ] var ctag *cTag var fld reflect.StructField var tag string var customName string - + for i := 0; i < numFields; i++ { fld = typ.Field(i) @@ -128,7 +129,11 @@ func (v *Validate) extractStructCache(current reflect.Value, sName string) *cStr continue } - tag = fld.Tag.Get(v.tagName) + if rtag, ok := rules[fld.Name]; ok { + tag = rtag + } else { + tag = fld.Tag.Get(v.tagName) + } if tag == skipValidationTag { continue diff --git a/vendor/github.com/go-playground/validator/v10/doc.go b/vendor/github.com/go-playground/validator/v10/doc.go index 8c2584792..7341c67d7 100644 --- a/vendor/github.com/go-playground/validator/v10/doc.go +++ b/vendor/github.com/go-playground/validator/v10/doc.go @@ -349,6 +349,40 @@ Example: // require the field if the Field1 and Field2 is not present: Usage: required_without_all=Field1 Field2 +Excluded If + +The field under validation must not be present or not empty only if all +the other specified fields are equal to the value following the specified +field. For strings ensures value is not "". For slices, maps, pointers, +interfaces, channels and functions ensures the value is not nil. + + Usage: excluded_if + +Examples: + + // exclude the field if the Field1 is equal to the parameter given: + Usage: excluded_if=Field1 foobar + + // exclude the field if the Field1 and Field2 is equal to the value respectively: + Usage: excluded_if=Field1 foo Field2 bar + +Excluded Unless + +The field under validation must not be present or empty unless all +the other specified fields are equal to the value following the specified +field. For strings ensures value is not "". For slices, maps, pointers, +interfaces, channels and functions ensures the value is not nil. + + Usage: excluded_unless + +Examples: + + // exclude the field unless the Field1 is equal to the parameter given: + Usage: excluded_unless=Field1 foobar + + // exclude the field unless the Field1 and Field2 is equal to the value respectively: + Usage: excluded_unless=Field1 foo Field2 bar + Is Default This validates that the value is the default value and is almost the @@ -1007,6 +1041,12 @@ This validates that a string value contains a valid version 5 UUID. Uppercase U Usage: uuid5 +Universally Unique Lexicographically Sortable Identifier ULID + +This validates that a string value contains a valid ULID value. + + Usage: ulid + ASCII This validates that a string value contains only ASCII characters. @@ -1255,6 +1295,13 @@ More information on https://www.iso.org/standard/60390.html Usage: bic +RFC 1035 label + +This validates that a string value is a valid dns RFC 1035 label, defined in RFC 1035. +More information on https://datatracker.ietf.org/doc/html/rfc1035 + + Usage: dns_rfc1035_label + TimeZone This validates that a string value is a valid time zone based on the time zone database present on the system. @@ -1263,6 +1310,18 @@ More information on https://golang.org/pkg/time/#LoadLocation Usage: timezone +Semantic Version + +This validates that a string value is a valid semver version, defined in Semantic Versioning 2.0.0. +More information on https://semver.org/ + + Usage: semver + +Credit Card + +This validates that a string value contains a valid credit card number using Luhn algoritm. + + Usage: credit_card Alias Validators and Tags diff --git a/vendor/github.com/go-playground/validator/v10/regexes.go b/vendor/github.com/go-playground/validator/v10/regexes.go index df00c4ebc..9c1c63423 100644 --- a/vendor/github.com/go-playground/validator/v10/regexes.go +++ b/vendor/github.com/go-playground/validator/v10/regexes.go @@ -10,7 +10,7 @@ const ( numericRegexString = "^[-+]?[0-9]+(?:\\.[0-9]+)?$" numberRegexString = "^[0-9]+$" hexadecimalRegexString = "^(0[xX])?[0-9a-fA-F]+$" - hexColorRegexString = "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$" + hexColorRegexString = "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$" rgbRegexString = "^rgb\\(\\s*(?:(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])|(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%)\\s*\\)$" rgbaRegexString = "^rgba\\(\\s*(?:(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])|(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%)\\s*,\\s*(?:(?:0.[1-9]*)|[01])\\s*\\)$" hslRegexString = "^hsl\\(\\s*(?:0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d|360)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*\\)$" @@ -29,6 +29,17 @@ const ( uUID4RFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" uUID5RFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-5[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" uUIDRFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + uLIDRegexString = "^[A-HJKMNP-TV-Z0-9]{26}$" + md4RegexString = "^[0-9a-f]{32}$" + md5RegexString = "^[0-9a-f]{32}$" + sha256RegexString = "^[0-9a-f]{64}$" + sha384RegexString = "^[0-9a-f]{96}$" + sha512RegexString = "^[0-9a-f]{128}$" + ripemd128RegexString = "^[0-9a-f]{32}$" + ripemd160RegexString = "^[0-9a-f]{40}$" + tiger128RegexString = "^[0-9a-f]{32}$" + tiger160RegexString = "^[0-9a-f]{40}$" + tiger192RegexString = "^[0-9a-f]{48}$" aSCIIRegexString = "^[\x00-\x7F]*$" printableASCIIRegexString = "^[\x20-\x7E]*$" multibyteRegexString = "[^\x00-\x7F]" @@ -36,12 +47,12 @@ const ( latitudeRegexString = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$" longitudeRegexString = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$" sSNRegexString = `^[0-9]{3}[ -]?(0[1-9]|[1-9][0-9])[ -]?([1-9][0-9]{3}|[0-9][1-9][0-9]{2}|[0-9]{2}[1-9][0-9]|[0-9]{3}[1-9])$` - hostnameRegexStringRFC952 = `^[a-zA-Z]([a-zA-Z0-9\-]+[\.]?)*[a-zA-Z0-9]$` // https://tools.ietf.org/html/rfc952 - hostnameRegexStringRFC1123 = `^([a-zA-Z0-9]{1}[a-zA-Z0-9_-]{0,62}){1}(\.[a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62})*?$` // accepts hostname starting with a digit https://tools.ietf.org/html/rfc1123 - fqdnRegexStringRFC1123 = `^([a-zA-Z0-9]{1}[a-zA-Z0-9_-]{0,62})(\.[a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62})*?(\.[a-zA-Z]{1}[a-zA-Z0-9]{0,62})\.?$` // same as hostnameRegexStringRFC1123 but must contain a non numerical TLD (possibly ending with '.') - btcAddressRegexString = `^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$` // bitcoin address - btcAddressUpperRegexStringBech32 = `^BC1[02-9AC-HJ-NP-Z]{7,76}$` // bitcoin bech32 address https://en.bitcoin.it/wiki/Bech32 - btcAddressLowerRegexStringBech32 = `^bc1[02-9ac-hj-np-z]{7,76}$` // bitcoin bech32 address https://en.bitcoin.it/wiki/Bech32 + hostnameRegexStringRFC952 = `^[a-zA-Z]([a-zA-Z0-9\-]+[\.]?)*[a-zA-Z0-9]$` // https://tools.ietf.org/html/rfc952 + hostnameRegexStringRFC1123 = `^([a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62}){1}(\.[a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62})*?$` // accepts hostname starting with a digit https://tools.ietf.org/html/rfc1123 + fqdnRegexStringRFC1123 = `^([a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62})(\.[a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62})*?(\.[a-zA-Z]{1}[a-zA-Z0-9]{0,62})\.?$` // same as hostnameRegexStringRFC1123 but must contain a non numerical TLD (possibly ending with '.') + btcAddressRegexString = `^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$` // bitcoin address + btcAddressUpperRegexStringBech32 = `^BC1[02-9AC-HJ-NP-Z]{7,76}$` // bitcoin bech32 address https://en.bitcoin.it/wiki/Bech32 + btcAddressLowerRegexStringBech32 = `^bc1[02-9ac-hj-np-z]{7,76}$` // bitcoin bech32 address https://en.bitcoin.it/wiki/Bech32 ethAddressRegexString = `^0x[0-9a-fA-F]{40}$` ethAddressUpperRegexString = `^0x[0-9A-F]{40}$` ethAddressLowerRegexString = `^0x[0-9a-f]{40}$` @@ -51,6 +62,8 @@ const ( jWTRegexString = "^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$" splitParamsRegexString = `'[^']*'|\S+` bicRegexString = `^[A-Za-z]{6}[A-Za-z0-9]{2}([A-Za-z0-9]{3})?$` + semverRegexString = `^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$` // numbered capture groups https://semver.org/ + dnsRegexStringRFC1035Label = "^[a-z]([-a-z0-9]*[a-z0-9]){0,62}$" ) var ( @@ -80,6 +93,17 @@ var ( uUID4RFC4122Regex = regexp.MustCompile(uUID4RFC4122RegexString) uUID5RFC4122Regex = regexp.MustCompile(uUID5RFC4122RegexString) uUIDRFC4122Regex = regexp.MustCompile(uUIDRFC4122RegexString) + uLIDRegex = regexp.MustCompile(uLIDRegexString) + md4Regex = regexp.MustCompile(md4RegexString) + md5Regex = regexp.MustCompile(md5RegexString) + sha256Regex = regexp.MustCompile(sha256RegexString) + sha384Regex = regexp.MustCompile(sha384RegexString) + sha512Regex = regexp.MustCompile(sha512RegexString) + ripemd128Regex = regexp.MustCompile(ripemd128RegexString) + ripemd160Regex = regexp.MustCompile(ripemd160RegexString) + tiger128Regex = regexp.MustCompile(tiger128RegexString) + tiger160Regex = regexp.MustCompile(tiger160RegexString) + tiger192Regex = regexp.MustCompile(tiger192RegexString) aSCIIRegex = regexp.MustCompile(aSCIIRegexString) printableASCIIRegex = regexp.MustCompile(printableASCIIRegexString) multibyteRegex = regexp.MustCompile(multibyteRegexString) @@ -102,4 +126,6 @@ var ( jWTRegex = regexp.MustCompile(jWTRegexString) splitParamsRegex = regexp.MustCompile(splitParamsRegexString) bicRegex = regexp.MustCompile(bicRegexString) + semverRegex = regexp.MustCompile(semverRegexString) + dnsRegexRFC1035Label = regexp.MustCompile(dnsRegexStringRFC1035Label) ) diff --git a/vendor/github.com/go-playground/validator/v10/util.go b/vendor/github.com/go-playground/validator/v10/util.go index 56420f430..36da85514 100644 --- a/vendor/github.com/go-playground/validator/v10/util.go +++ b/vendor/github.com/go-playground/validator/v10/util.go @@ -82,7 +82,7 @@ BEGIN: fld := namespace var ns string - if typ != timeType { + if !typ.ConvertibleTo(timeType) { idx := strings.Index(namespace, namespaceSeparator) diff --git a/vendor/github.com/go-playground/validator/v10/validator.go b/vendor/github.com/go-playground/validator/v10/validator.go index 2a4fad022..80da095a6 100644 --- a/vendor/github.com/go-playground/validator/v10/validator.go +++ b/vendor/github.com/go-playground/validator/v10/validator.go @@ -164,7 +164,7 @@ func (v *validate) traverseField(ctx context.Context, parent reflect.Value, curr typ = current.Type() - if typ != timeType { + if !typ.ConvertibleTo(timeType) { if ct != nil { @@ -355,6 +355,10 @@ OUTER: v.ct = ct if ct.fn(ctx, v) { + if ct.isBlockEnd { + ct = ct.next + continue OUTER + } // drain rest of the 'or' values, then continue or leave for { @@ -368,6 +372,11 @@ OUTER: if ct.typeof != typeOr { continue OUTER } + + if ct.isBlockEnd { + ct = ct.next + continue OUTER + } } } diff --git a/vendor/github.com/go-playground/validator/v10/validator_instance.go b/vendor/github.com/go-playground/validator/v10/validator_instance.go index 973964fc2..9493da491 100644 --- a/vendor/github.com/go-playground/validator/v10/validator_instance.go +++ b/vendor/github.com/go-playground/validator/v10/validator_instance.go @@ -33,6 +33,8 @@ const ( excludedWithoutTag = "excluded_without" excludedWithTag = "excluded_with" excludedWithAllTag = "excluded_with_all" + excludedIfTag = "excluded_if" + excludedUnlessTag = "excluded_unless" skipValidationTag = "-" diveTag = "dive" keysTag = "keys" @@ -84,6 +86,7 @@ type Validate struct { aliases map[string]string validations map[string]internalValidationFuncWrapper transTagFunc map[ut.Translator]map[string]TranslationFunc // map[<locale>]map[<tag>]TranslationFunc + rules map[reflect.Type]map[string]string tagCache *tagCache structCache *structCache } @@ -120,7 +123,7 @@ func New() *Validate { switch k { // these require that even if the value is nil that the validation should run, omitempty still overrides this behaviour case requiredIfTag, requiredUnlessTag, requiredWithTag, requiredWithAllTag, requiredWithoutTag, requiredWithoutAllTag, - excludedWithTag, excludedWithAllTag, excludedWithoutTag, excludedWithoutAllTag: + excludedIfTag, excludedUnlessTag, excludedWithTag, excludedWithAllTag, excludedWithoutTag, excludedWithoutAllTag: _ = v.registerValidation(k, wrapFunc(val), true, true) default: // no need to error check here, baked in will always be valid @@ -152,15 +155,24 @@ func (v *Validate) SetTagName(name string) { func (v Validate) ValidateMapCtx(ctx context.Context, data map[string]interface{}, rules map[string]interface{}) map[string]interface{} { errs := make(map[string]interface{}) for field, rule := range rules { - if reflect.ValueOf(rule).Kind() == reflect.Map && reflect.ValueOf(data[field]).Kind() == reflect.Map { - err := v.ValidateMapCtx(ctx, data[field].(map[string]interface{}), rule.(map[string]interface{})) - if len(err) > 0 { - errs[field] = err + if ruleObj, ok := rule.(map[string]interface{}); ok { + if dataObj, ok := data[field].(map[string]interface{}); ok { + err := v.ValidateMapCtx(ctx, dataObj, ruleObj) + if len(err) > 0 { + errs[field] = err + } + } else if dataObjs, ok := data[field].([]map[string]interface{}); ok { + for _, obj := range dataObjs { + err := v.ValidateMapCtx(ctx, obj, ruleObj) + if len(err) > 0 { + errs[field] = err + } + } + } else { + errs[field] = errors.New("The field: '" + field + "' is not a map to dive") } - } else if reflect.ValueOf(rule).Kind() == reflect.Map { - errs[field] = errors.New("The field: '" + field + "' is not a map to dive") - } else { - err := v.VarCtx(ctx, data[field], rule.(string)) + } else if ruleStr, ok := rule.(string); ok { + err := v.VarCtx(ctx, data[field], ruleStr) if err != nil { errs[field] = err } @@ -169,7 +181,7 @@ func (v Validate) ValidateMapCtx(ctx context.Context, data map[string]interface{ return errs } -// ValidateMap validates map data form a map of tags +// ValidateMap validates map data from a map of tags func (v *Validate) ValidateMap(data map[string]interface{}, rules map[string]interface{}) map[string]interface{} { return v.ValidateMapCtx(context.Background(), data, rules) } @@ -180,6 +192,7 @@ func (v *Validate) ValidateMap(data map[string]interface{}, rules map[string]int // // validate.RegisterTagNameFunc(func(fld reflect.StructField) string { // name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] +// // skip if tag key says it should be ignored // if name == "-" { // return "" // } @@ -271,6 +284,34 @@ func (v *Validate) RegisterStructValidationCtx(fn StructLevelFuncCtx, types ...i } } +// RegisterStructValidationMapRules registers validate map rules. +// Be aware that map validation rules supersede those defined on a/the struct if present. +// +// NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation +func (v *Validate) RegisterStructValidationMapRules(rules map[string]string, types ...interface{}) { + if v.rules == nil { + v.rules = make(map[reflect.Type]map[string]string) + } + + deepCopyRules := make(map[string]string) + for i, rule := range rules { + deepCopyRules[i] = rule + } + + for _, t := range types { + typ := reflect.TypeOf(t) + + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() + } + + if typ.Kind() != reflect.Struct { + continue + } + v.rules[typ] = deepCopyRules + } +} + // RegisterCustomTypeFunc registers a CustomTypeFunc against a number of types // // NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation @@ -331,7 +372,7 @@ func (v *Validate) StructCtx(ctx context.Context, s interface{}) (err error) { val = val.Elem() } - if val.Kind() != reflect.Struct || val.Type() == timeType { + if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) { return &InvalidValidationError{Type: reflect.TypeOf(s)} } @@ -376,7 +417,7 @@ func (v *Validate) StructFilteredCtx(ctx context.Context, s interface{}, fn Filt val = val.Elem() } - if val.Kind() != reflect.Struct || val.Type() == timeType { + if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) { return &InvalidValidationError{Type: reflect.TypeOf(s)} } @@ -424,7 +465,7 @@ func (v *Validate) StructPartialCtx(ctx context.Context, s interface{}, fields . val = val.Elem() } - if val.Kind() != reflect.Struct || val.Type() == timeType { + if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) { return &InvalidValidationError{Type: reflect.TypeOf(s)} } @@ -514,7 +555,7 @@ func (v *Validate) StructExceptCtx(ctx context.Context, s interface{}, fields .. val = val.Elem() } - if val.Kind() != reflect.Struct || val.Type() == timeType { + if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) { return &InvalidValidationError{Type: reflect.TypeOf(s)} } |