diff --git a/changelog/unreleased/enhancement-sharing-ng.md b/changelog/unreleased/enhancement-sharing-ng.md
index 6edd0dd0902..542c644950c 100644
--- a/changelog/unreleased/enhancement-sharing-ng.md
+++ b/changelog/unreleased/enhancement-sharing-ng.md
@@ -7,12 +7,14 @@ The following endpoints are added:
* /v1beta1/me/drive/sharedWithMe
* /v1beta1/roleManagement/permissions/roleDefinitions
* /v1beta1/roleManagement/permissions/roleDefinitions/{roleID}
+* /v1beta1/drives/{drive-id}/items/{item-id}/createLink (create a sharing link)
https://github.com/owncloud/ocis/pull/7633
https://github.com/owncloud/ocis/pull/7686
https://github.com/owncloud/ocis/pull/7684
https://github.com/owncloud/ocis/pull/7683
https://github.com/owncloud/ocis/pull/7239
+https://github.com/owncloud/ocis/pull/7687
https://github.com/owncloud/libre-graph-api/pull/112
https://github.com/owncloud/ocis/issues/7436
https://github.com/owncloud/ocis/issues/6993
diff --git a/go.mod b/go.mod
index a2b7a7eb7ab..275327fdd24 100644
--- a/go.mod
+++ b/go.mod
@@ -40,6 +40,7 @@ require (
github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus v1.2.0
github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry v1.2.0
github.com/go-ozzo/ozzo-validation/v4 v4.3.0
+ github.com/go-playground/validator/v10 v10.16.0
github.com/gofrs/uuid v4.4.0+incompatible
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/golang/protobuf v1.5.3
@@ -194,9 +195,8 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-micro/plugins/v4/events/natsjs v1.2.2-0.20230807070816-bc05fb076ce7 // indirect
github.com/go-micro/plugins/v4/store/redis v1.2.1-0.20230510195111-07cd57e1bc9d // indirect
- github.com/go-playground/locales v0.13.0 // indirect
- github.com/go-playground/universal-translator v0.17.0 // indirect
- github.com/go-playground/validator/v10 v10.4.1 // indirect
+ github.com/go-playground/locales v0.14.1 // indirect
+ github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect
github.com/go-resty/resty/v2 v2.7.0 // indirect
github.com/go-sql-driver/mysql v1.6.0 // indirect
@@ -247,7 +247,7 @@ require (
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.17.2 // indirect
github.com/klauspost/cpuid/v2 v2.1.0 // indirect
- github.com/leodido/go-urn v1.2.0 // indirect
+ github.com/leodido/go-urn v1.2.4 // indirect
github.com/libregraph/oidc-go v1.0.0 // indirect
github.com/longsleep/go-metrics v1.0.0 // indirect
github.com/longsleep/rndm v1.2.0 // indirect
diff --git a/go.sum b/go.sum
index 1a92f50b2bc..674f382bfc4 100644
--- a/go.sum
+++ b/go.sum
@@ -1213,14 +1213,13 @@ github.com/go-ozzo/ozzo-validation/v4 v4.3.0 h1:byhDUpfEwjsVQb1vBunvIjh2BHQ9ead5
github.com/go-ozzo/ozzo-validation/v4 v4.3.0/go.mod h1:2NKgrcHl3z6cJs+3Oo940FPRiTzuqKbvfrL2RxCj6Ew=
github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M=
github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M=
-github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
-github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
-github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
-github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
-github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
-github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
-github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
-github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
+github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
+github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
+github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
+github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
+github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
+github.com/go-playground/validator/v10 v10.16.0 h1:x+plE831WK4vaKHO/jpgUGsvLKIqRRkz6M78GuJAfGE=
+github.com/go-playground/validator/v10 v10.16.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8=
@@ -1597,8 +1596,8 @@ github.com/labbsr0x/bindman-dns-webhook v1.0.2/go.mod h1:p6b+VCXIR8NYKpDr8/dg1HK
github.com/labbsr0x/goh v1.0.1/go.mod h1:8K2UhVoaWXcCU7Lxoa2omWnC8gyW8px7/lmO61c027w=
github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
-github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
-github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
+github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
+github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/leonelquinteros/gotext v1.5.3-0.20230317130943-71a59c05b2c1 h1:k56sFOOJ0CYuQtGoRSeAMhP1R692+iNH+S1dC/CEz0w=
github.com/leonelquinteros/gotext v1.5.3-0.20230317130943-71a59c05b2c1/go.mod h1:AT4NpQrOmyj1L/+hLja6aR0lk81yYYL4ePnj2kp7d6M=
github.com/libregraph/idm v0.4.1-0.20230221143410-3503963047a5 h1:brLMXSjWoWhGXs8LpK+Lx+FQCtGLUa51Mq/ggHv9AV0=
diff --git a/services/graph/pkg/server/http/server.go b/services/graph/pkg/server/http/server.go
index 113ffac6002..dd772dfecf0 100644
--- a/services/graph/pkg/server/http/server.go
+++ b/services/graph/pkg/server/http/server.go
@@ -8,6 +8,10 @@ import (
"github.com/cs3org/reva/v2/pkg/events/stream"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
chimiddleware "github.com/go-chi/chi/v5/middleware"
+ "github.com/pkg/errors"
+ "go-micro.dev/v4"
+ "go-micro.dev/v4/events"
+
"github.com/owncloud/ocis/v2/ocis-pkg/account"
"github.com/owncloud/ocis/v2/ocis-pkg/cors"
"github.com/owncloud/ocis/v2/ocis-pkg/keycloak"
@@ -21,9 +25,6 @@ import (
settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
graphMiddleware "github.com/owncloud/ocis/v2/services/graph/pkg/middleware"
svc "github.com/owncloud/ocis/v2/services/graph/pkg/service/v0"
- "github.com/pkg/errors"
- "go-micro.dev/v4"
- "go-micro.dev/v4/events"
)
// Server initializes the http service and server.
diff --git a/services/graph/pkg/service/v0/driveitems.go b/services/graph/pkg/service/v0/driveitems.go
index f8028bc711a..005a116b044 100644
--- a/services/graph/pkg/service/v0/driveitems.go
+++ b/services/graph/pkg/service/v0/driveitems.go
@@ -2,6 +2,7 @@ package svc
import (
"context"
+ "encoding/json"
"errors"
"fmt"
"net/http"
@@ -10,19 +11,28 @@ import (
"reflect"
"strconv"
"strings"
+ "sync"
"time"
+ grouppb "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
+ userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
cs3rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
+ collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
+ "github.com/go-chi/render"
+ libregraph "github.com/owncloud/libre-graph-api-go"
+ "golang.org/x/crypto/sha3"
+ "golang.org/x/sync/errgroup"
+
+ "github.com/cs3org/reva/v2/pkg/conversions"
revactx "github.com/cs3org/reva/v2/pkg/ctx"
"github.com/cs3org/reva/v2/pkg/storagespace"
"github.com/cs3org/reva/v2/pkg/utils"
- "github.com/go-chi/render"
- libregraph "github.com/owncloud/libre-graph-api-go"
+
"github.com/owncloud/ocis/v2/ocis-pkg/log"
"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
- "golang.org/x/crypto/sha3"
+ "github.com/owncloud/ocis/v2/services/graph/pkg/validate"
)
// GetRootDriveChildren implements the Service interface.
@@ -234,6 +244,207 @@ func (g Graph) GetDriveItemChildren(w http.ResponseWriter, r *http.Request) {
render.JSON(w, r, &ListResponse{Value: files})
}
+// Invite invites a user to a storage drive (space).
+func (g Graph) Invite(w http.ResponseWriter, r *http.Request) {
+ gatewayClient, err := g.gatewaySelector.Next()
+ if err != nil {
+ g.logger.Debug().Err(err).Msg("selecting gatewaySelector failed")
+ errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
+ return
+ }
+
+ driveID, err := parseIDParam(r, "driveID")
+ if err != nil {
+ g.logger.Debug().Err(err).Msg("could not parse driveID")
+ errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "invalid driveID")
+ return
+ }
+
+ itemID, err := parseIDParam(r, "itemID")
+ if err != nil {
+ g.logger.Debug().Err(err).Msg("could not parse itemID")
+ errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "invalid itemID")
+ return
+ }
+
+ if driveID.GetStorageId() != itemID.GetStorageId() || driveID.GetSpaceId() != itemID.GetSpaceId() {
+ g.logger.Debug().Interface("driveID", driveID).Interface("itemID", itemID).Msg("driveID and itemID do not match")
+ errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "driveID and itemID do not match")
+ return
+ }
+
+ driveItemInvite := &libregraph.DriveItemInvite{}
+ if err := StrictJSONUnmarshal(r.Body, driveItemInvite); err != nil {
+ g.logger.Debug().Err(err).Interface("Body", r.Body).Msg("failed unmarshalling request body")
+ errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "invalid request body")
+ return
+ }
+
+ ctx := r.Context()
+
+ if err = validate.StructCtx(ctx, driveItemInvite); err != nil {
+ g.logger.Debug().Err(err).Interface("Body", r.Body).Msg("invalid request body")
+ errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
+ return
+ }
+
+ statResponse, err := gatewayClient.Stat(ctx, &storageprovider.StatRequest{Ref: &storageprovider.Reference{ResourceId: &itemID}})
+ switch {
+ case err != nil:
+ fallthrough
+ case statResponse.GetStatus().GetCode() != cs3rpc.Code_CODE_OK:
+ g.logger.Debug().Err(err).Interface("itemID", itemID).Interface("Stat", statResponse).Msg("stat failed")
+ errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
+ return
+ }
+
+ role := conversions.RoleFromName(driveItemInvite.GetRoles()[0], g.config.FilesSharing.EnableResharing)
+ roleJson, err := json.Marshal(role)
+ if err != nil {
+ g.logger.Debug().Err(err).Interface("role", role).Msg("stat marshaling failed")
+ errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
+ return
+ }
+
+ createShareErrors := sync.Map{}
+ createShareSuccesses := sync.Map{}
+
+ shareCreateGroup, ctx := errgroup.WithContext(ctx)
+
+ for _, driveRecipient := range driveItemInvite.GetRecipients() {
+ // not needed anymore with go 1.22 and higher
+ driveRecipient := driveRecipient // https://golang.org/doc/faq#closures_and_goroutines,
+
+ shareCreateGroup.Go(func() error {
+ objectId := driveRecipient.GetObjectId()
+
+ if objectId == "" {
+ return nil
+ }
+
+ createShareRequest := &collaboration.CreateShareRequest{
+ Opaque: &types.Opaque{
+ Map: map[string]*types.OpaqueEntry{
+ "role": {
+ Decoder: "json",
+ Value: roleJson,
+ },
+ },
+ },
+ ResourceInfo: statResponse.GetInfo(),
+ Grant: &collaboration.ShareGrant{
+ Permissions: &collaboration.SharePermissions{
+ Permissions: role.CS3ResourcePermissions(),
+ },
+ },
+ }
+
+ permission := &libregraph.Permission{
+ Roles: []string{role.Name},
+ }
+
+ switch driveRecipient.GetLibreGraphRecipientType() {
+ case "group":
+ group, err := g.identityCache.GetGroup(ctx, objectId)
+ if err != nil {
+ g.logger.Debug().Err(err).Interface("groupId", objectId).Msg("failed group lookup")
+ createShareErrors.Store(objectId, errorcode.GeneralException.CreateOdataError(r.Context(), http.StatusText(http.StatusInternalServerError)))
+ return nil
+ }
+ createShareRequest.GetGrant().Grantee = &storageprovider.Grantee{
+ Type: storageprovider.GranteeType_GRANTEE_TYPE_GROUP,
+ Id: &storageprovider.Grantee_GroupId{GroupId: &grouppb.GroupId{
+ OpaqueId: group.GetId(),
+ }},
+ }
+ permission.GrantedToV2 = &libregraph.SharePointIdentitySet{
+ Group: &libregraph.Identity{
+ DisplayName: group.GetDisplayName(),
+ Id: libregraph.PtrString(group.GetId()),
+ },
+ }
+ default:
+ user, err := g.identityCache.GetUser(ctx, objectId)
+ if err != nil {
+ g.logger.Debug().Err(err).Interface("userId", objectId).Msg("failed user lookup")
+ createShareErrors.Store(objectId, errorcode.GeneralException.CreateOdataError(r.Context(), http.StatusText(http.StatusInternalServerError)))
+ return nil
+ }
+ createShareRequest.GetGrant().Grantee = &storageprovider.Grantee{
+ Type: storageprovider.GranteeType_GRANTEE_TYPE_USER,
+ Id: &storageprovider.Grantee_UserId{UserId: &userpb.UserId{
+ OpaqueId: user.GetId(),
+ }},
+ }
+ permission.GrantedToV2 = &libregraph.SharePointIdentitySet{
+ User: &libregraph.Identity{
+ DisplayName: user.GetDisplayName(),
+ Id: libregraph.PtrString(user.GetId()),
+ },
+ }
+ }
+
+ if driveItemInvite.ExpirationDateTime != nil {
+ createShareRequest.GetGrant().Expiration = utils.TimeToTS(*driveItemInvite.ExpirationDateTime)
+ }
+
+ createShareResponse, err := gatewayClient.CreateShare(ctx, createShareRequest)
+ switch {
+ case err != nil:
+ fallthrough
+ case createShareResponse.GetStatus().GetCode() != cs3rpc.Code_CODE_OK:
+ g.logger.Debug().Err(err).Msg("share creation failed")
+ createShareErrors.Store(objectId, errorcode.GeneralException.CreateOdataError(r.Context(), http.StatusText(http.StatusInternalServerError)))
+ return nil
+ }
+
+ if id := createShareResponse.GetShare().GetId().GetOpaqueId(); id != "" {
+ permission.Id = libregraph.PtrString(id)
+ }
+
+ if expiration := createShareResponse.GetShare().GetExpiration(); expiration != nil {
+ permission.ExpirationDateTime = libregraph.PtrTime(utils.TSToTime(expiration))
+ }
+
+ createShareSuccesses.Store(objectId, permission)
+
+ return nil
+ })
+ }
+
+ if err := shareCreateGroup.Wait(); err != nil {
+ errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
+ return
+ }
+
+ value := make([]interface{}, 0, len(driveItemInvite.Recipients))
+
+ hasSuccesses := false
+ createShareSuccesses.Range(func(key, permission interface{}) bool {
+ value = append(value, permission)
+ hasSuccesses = true
+ return true
+ })
+
+ hasErrors := false
+ createShareErrors.Range(func(key, err interface{}) bool {
+ value = append(value, err)
+ hasErrors = true
+ return true
+ })
+
+ switch {
+ case hasErrors && hasSuccesses:
+ render.Status(r, http.StatusMultiStatus)
+ case hasSuccesses:
+ render.Status(r, http.StatusCreated)
+ default:
+ render.Status(r, http.StatusInternalServerError)
+ }
+
+ render.JSON(w, r, &ListResponse{Value: value})
+}
+
func (g Graph) getDriveItem(ctx context.Context, ref storageprovider.Reference) (*libregraph.DriveItem, error) {
gatewayClient, err := g.gatewaySelector.Next()
if err != nil {
@@ -531,14 +742,14 @@ func spaceRootStatKey(id *storageprovider.ResourceId, imagenode, readmeNode stri
if id == nil {
return ""
}
- sha3 := sha3.NewShake256()
- _, _ = sha3.Write([]byte(id.GetStorageId()))
- _, _ = sha3.Write([]byte(id.GetSpaceId()))
- _, _ = sha3.Write([]byte(id.GetOpaqueId()))
- _, _ = sha3.Write([]byte(imagenode))
- _, _ = sha3.Write([]byte(readmeNode))
+ shakeHash := sha3.NewShake256()
+ _, _ = shakeHash.Write([]byte(id.GetStorageId()))
+ _, _ = shakeHash.Write([]byte(id.GetSpaceId()))
+ _, _ = shakeHash.Write([]byte(id.GetOpaqueId()))
+ _, _ = shakeHash.Write([]byte(imagenode))
+ _, _ = shakeHash.Write([]byte(readmeNode))
h := make([]byte, 64)
- _, _ = sha3.Read(h)
+ _, _ = shakeHash.Read(h)
return fmt.Sprintf("%x", h)
}
diff --git a/services/graph/pkg/service/v0/driveitems_test.go b/services/graph/pkg/service/v0/driveitems_test.go
index c8f8ff2082f..20373c3cd26 100644
--- a/services/graph/pkg/service/v0/driveitems_test.go
+++ b/services/graph/pkg/service/v0/driveitems_test.go
@@ -7,28 +7,34 @@ import (
"io"
"net/http"
"net/http/httptest"
+ "strings"
"time"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
+ grouppb "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
+ collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
+ "github.com/go-chi/chi/v5"
+ . "github.com/onsi/ginkgo/v2"
+ . "github.com/onsi/gomega"
+ libregraph "github.com/owncloud/libre-graph-api-go"
+ "github.com/stretchr/testify/mock"
+ "github.com/tidwall/gjson"
+ "google.golang.org/grpc"
+
revactx "github.com/cs3org/reva/v2/pkg/ctx"
"github.com/cs3org/reva/v2/pkg/rgrpc/status"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/v2/pkg/utils"
cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
- "github.com/go-chi/chi/v5"
- . "github.com/onsi/ginkgo/v2"
- . "github.com/onsi/gomega"
- libregraph "github.com/owncloud/libre-graph-api-go"
+
"github.com/owncloud/ocis/v2/ocis-pkg/shared"
"github.com/owncloud/ocis/v2/services/graph/mocks"
"github.com/owncloud/ocis/v2/services/graph/pkg/config"
"github.com/owncloud/ocis/v2/services/graph/pkg/config/defaults"
identitymocks "github.com/owncloud/ocis/v2/services/graph/pkg/identity/mocks"
service "github.com/owncloud/ocis/v2/services/graph/pkg/service/v0"
- "github.com/stretchr/testify/mock"
- "google.golang.org/grpc"
)
type itemsList struct {
@@ -93,8 +99,302 @@ var _ = Describe("Driveitems", func() {
)
})
+ Describe("Invite", func() {
+ var (
+ itemID string
+ driveItemInvite *libregraph.DriveItemInvite
+ listSharesMock *mock.Call
+ listSharesResponse *collaboration.ListSharesResponse
+ statMock *mock.Call
+ statResponse *provider.StatResponse
+ getUserResponse *userpb.GetUserResponse
+ getUserMock *mock.Call
+ getGroupResponse *grouppb.GetGroupResponse
+ getGroupMock *mock.Call
+ createShareResponse *collaboration.CreateShareResponse
+ createShareMock *mock.Call
+ )
+
+ BeforeEach(func() {
+ itemID = "f0042750-23c5-441c-9f2c-ff7c53e5bd2a$cd621428-dfbe-44c1-9393-65bf0dd440a6!1177add3-b4eb-434e-a2e8-1859b31b17bf"
+ rctx := chi.NewRouteContext()
+ rctx.URLParams.Add("driveID", "f0042750-23c5-441c-9f2c-ff7c53e5bd2a$cd621428-dfbe-44c1-9393-65bf0dd440a6!cd621428-dfbe-44c1-9393-65bf0dd440a6")
+ rctx.URLParams.Add("itemID", itemID)
+
+ ctx = context.WithValue(ctx, chi.RouteCtxKey, rctx)
+ ctx = revactx.ContextSetUser(ctx, currentUser)
+
+ driveItemInvite = &libregraph.DriveItemInvite{
+ Recipients: []libregraph.DriveRecipient{
+ {ObjectId: libregraph.PtrString("1")},
+ },
+ Roles: []string{"viewer"},
+ }
+
+ statMock = gatewayClient.On("Stat", mock.Anything, mock.Anything)
+ statResponse = &provider.StatResponse{
+ Status: status.NewOK(ctx),
+ }
+ statMock.Return(statResponse, nil)
+
+ getUserMock = gatewayClient.On("GetUser", mock.Anything, mock.Anything)
+ getUserResponse = &userpb.GetUserResponse{
+ Status: status.NewOK(ctx),
+ User: &userpb.User{
+ Id: &userpb.UserId{OpaqueId: "1"},
+ DisplayName: "Cem Kaner",
+ },
+ }
+ getUserMock.Return(getUserResponse, nil)
+
+ getGroupMock = gatewayClient.On("GetGroup", mock.Anything, mock.Anything)
+ getGroupResponse = &grouppb.GetGroupResponse{
+ Status: status.NewOK(ctx),
+ Group: &grouppb.Group{
+ Id: &grouppb.GroupId{OpaqueId: "2"},
+ GroupName: "Florida Institute of Technology",
+ },
+ }
+ getGroupMock.Return(getGroupResponse, nil)
+
+ listSharesMock = gatewayClient.On("ListShares", mock.Anything, mock.Anything)
+ listSharesResponse = &collaboration.ListSharesResponse{
+ Status: status.NewOK(ctx),
+ }
+ listSharesMock.Return(listSharesResponse, nil)
+
+ createShareMock = gatewayClient.On("CreateShare", mock.Anything, mock.Anything)
+ createShareResponse = &collaboration.CreateShareResponse{
+ Status: status.NewOK(ctx),
+ }
+ createShareMock.Return(createShareResponse, nil)
+ })
+
+ toJSONReader := func(v any) *strings.Reader {
+ driveItemInviteBytes, err := json.Marshal(v)
+ Expect(err).ToNot(HaveOccurred())
+
+ return strings.NewReader(string(driveItemInviteBytes))
+ }
+
+ It("creates user and group shares as expected (happy path)", func() {
+ driveItemInvite.Recipients = []libregraph.DriveRecipient{
+ {ObjectId: libregraph.PtrString("1")},
+ {ObjectId: libregraph.PtrString("2"), LibreGraphRecipientType: libregraph.PtrString("group")},
+ }
+ driveItemInvite.ExpirationDateTime = libregraph.PtrTime(time.Now().Add(time.Hour))
+ createShareResponse.Share = &collaboration.Share{
+ Id: &collaboration.ShareId{OpaqueId: "123"},
+ Expiration: utils.TimeToTS(*driveItemInvite.ExpirationDateTime),
+ }
+
+ svc.Invite(
+ rr,
+ httptest.NewRequest(http.MethodPost, "/", toJSONReader(driveItemInvite)).
+ WithContext(ctx),
+ )
+
+ jsonData := gjson.Get(rr.Body.String(), "value")
+
+ Expect(rr.Code).To(Equal(http.StatusCreated))
+ Expect(jsonData.Get("#").Num).To(Equal(float64(2)))
+
+ Expect(jsonData.Get("0.id").Str).To(Equal("123"))
+ Expect(jsonData.Get("1.id").Str).To(Equal("123"))
+
+ Expect(jsonData.Get("0.expirationDateTime").Str).To(Equal(driveItemInvite.ExpirationDateTime.Format(time.RFC3339Nano)))
+ Expect(jsonData.Get("1.expirationDateTime").Str).To(Equal(driveItemInvite.ExpirationDateTime.Format(time.RFC3339Nano)))
+
+ Expect(jsonData.Get("0.roles.#").Num).To(Equal(float64(1)))
+ Expect(jsonData.Get("0.roles.0").String()).To(Equal("viewer"))
+ Expect(jsonData.Get("1.roles.#").Num).To(Equal(float64(1)))
+ Expect(jsonData.Get("1.roles.0").String()).To(Equal("viewer"))
+
+ Expect(jsonData.Get("#.grantedToV2.user.displayName").Array()[0].Str).To(Equal(getUserResponse.User.DisplayName))
+ Expect(jsonData.Get("#.grantedToV2.user.id").Array()[0].Str).To(Equal("1"))
+
+ Expect(jsonData.Get("#.grantedToV2.group.displayName").Array()[0].Str).To(Equal(getGroupResponse.Group.GroupName))
+ Expect(jsonData.Get("#.grantedToV2.group.id").Array()[0].Str).To(Equal("2"))
+ })
+
+ It("validates the driveID", func() {
+ rctx := chi.NewRouteContext()
+ rctx.URLParams.Add("driveID", "")
+
+ ctx = context.WithValue(context.Background(), chi.RouteCtxKey, rctx)
+
+ svc.Invite(
+ rr,
+ httptest.NewRequest(http.MethodPost, "/", toJSONReader(driveItemInvite)).
+ WithContext(ctx),
+ )
+
+ Expect(rr.Code).To(Equal(http.StatusBadRequest))
+ })
+
+ It("validates the itemID", func() {
+ rctx := chi.NewRouteContext()
+ rctx.URLParams.Add("driveID", "f0042750-23c5-441c-9f2c-ff7c53e5bd2a$cd621428-dfbe-44c1-9393-65bf0dd440a6!cd621428-dfbe-44c1-9393-65bf0dd440a6")
+ rctx.URLParams.Add("itemID", "")
+
+ ctx = context.WithValue(context.Background(), chi.RouteCtxKey, rctx)
+
+ svc.Invite(
+ rr,
+ httptest.NewRequest(http.MethodPost, "/", toJSONReader(driveItemInvite)).
+ WithContext(ctx),
+ )
+
+ Expect(rr.Code).To(Equal(http.StatusBadRequest))
+ })
+
+ It("checks if the itemID and driveID is compatible to each other", func() {
+ rctx := chi.NewRouteContext()
+ rctx.URLParams.Add("driveID", "1$2!3")
+ rctx.URLParams.Add("itemID", "4$5!6")
+
+ ctx = context.WithValue(context.Background(), chi.RouteCtxKey, rctx)
+
+ svc.Invite(
+ rr,
+ httptest.NewRequest(http.MethodPost, "/", toJSONReader(driveItemInvite)).
+ WithContext(ctx),
+ )
+
+ Expect(rr.Code).To(Equal(http.StatusBadRequest))
+ })
+
+ It("fails if the request body is empty", func() {
+ svc.Invite(
+ rr,
+ httptest.NewRequest(http.MethodPost, "/", nil).
+ WithContext(ctx),
+ )
+
+ Expect(rr.Code).To(Equal(http.StatusBadRequest))
+ })
+
+ DescribeTable("request validations",
+ func(body func() *strings.Reader, code int) {
+ svc.Invite(
+ rr,
+ httptest.NewRequest(http.MethodPost, "/", body()).
+ WithContext(ctx),
+ )
+
+ Expect(rr.Code).To(Equal(code))
+ },
+ Entry("fails on unknown fields", func() *strings.Reader {
+ return strings.NewReader(`{"unknown":"field"}`)
+ }, http.StatusBadRequest),
+ Entry("fails without recipients", func() *strings.Reader {
+ driveItemInvite.Recipients = nil
+ return toJSONReader(driveItemInvite)
+ }, http.StatusBadRequest),
+ Entry("fails without roles", func() *strings.Reader {
+ driveItemInvite.Roles = []string{}
+ return toJSONReader(driveItemInvite)
+ }, http.StatusBadRequest),
+ Entry("fails if more than one role item is present", func() *strings.Reader {
+ driveItemInvite.Roles = []string{"", ""}
+ return toJSONReader(driveItemInvite)
+ }, http.StatusBadRequest),
+ Entry("fails if the ExpirationDateTime is not in the future", func() *strings.Reader {
+ driveItemInvite.ExpirationDateTime = libregraph.PtrTime(time.Now())
+ return toJSONReader(driveItemInvite)
+ }, http.StatusBadRequest),
+ )
+
+ DescribeTable("Stat",
+ func(prep func(), code int) {
+ prep()
+ svc.Invite(
+ rr,
+ httptest.NewRequest(http.MethodPost, "/", toJSONReader(driveItemInvite)).
+ WithContext(ctx),
+ )
+
+ Expect(rr.Code).To(Equal(code))
+ statMock.Parent.AssertNumberOfCalls(GinkgoT(), "Stat", 1)
+ },
+ Entry("fails if not ok", func() {
+ statResponse.Status = status.NewNotFound(context.Background(), "")
+ }, http.StatusInternalServerError),
+ Entry("fails if errors", func() {
+ statMock.Return(nil, errors.New("error"))
+ }, http.StatusInternalServerError),
+ )
+
+ DescribeTable("GetGroup",
+ func(prep func(), code int) {
+ driveItemInvite.Recipients = []libregraph.DriveRecipient{
+ {ObjectId: libregraph.PtrString("1"), LibreGraphRecipientType: libregraph.PtrString("group")},
+ }
+
+ prep()
+
+ svc.Invite(
+ rr,
+ httptest.NewRequest(http.MethodPost, "/", toJSONReader(driveItemInvite)).
+ WithContext(ctx),
+ )
+
+ Expect(rr.Code).To(Equal(code))
+ getGroupMock.Parent.AssertNumberOfCalls(GinkgoT(), "GetGroup", 1)
+ },
+ Entry("fails if not ok", func() {
+ getGroupResponse.Status = status.NewNotFound(context.Background(), "")
+ }, http.StatusInternalServerError),
+ Entry("fails if errors", func() {
+ getGroupMock.Return(nil, errors.New("error"))
+ }, http.StatusInternalServerError),
+ )
+
+ DescribeTable("GetUser",
+ func(prep func(), code int) {
+ prep()
+
+ svc.Invite(
+ rr,
+ httptest.NewRequest(http.MethodPost, "/", toJSONReader(driveItemInvite)).
+ WithContext(ctx),
+ )
+
+ Expect(rr.Code).To(Equal(code))
+ getUserMock.Parent.AssertNumberOfCalls(GinkgoT(), "GetUser", 1)
+ },
+ Entry("fails if not ok", func() {
+ getUserResponse.Status = status.NewNotFound(context.Background(), "")
+ }, http.StatusInternalServerError),
+ Entry("fails if errors", func() {
+ getUserMock.Return(nil, errors.New("error"))
+ }, http.StatusInternalServerError),
+ )
+
+ DescribeTable("CreateShare",
+ func(prep func(), code int) {
+ prep()
+
+ svc.Invite(
+ rr,
+ httptest.NewRequest(http.MethodPost, "/", toJSONReader(driveItemInvite)).
+ WithContext(ctx),
+ )
+
+ Expect(rr.Code).To(Equal(code))
+ createShareMock.Parent.AssertNumberOfCalls(GinkgoT(), "CreateShare", 1)
+ },
+ Entry("fails if not ok", func() {
+ createShareResponse.Status = status.NewNotFound(context.Background(), "")
+ }, http.StatusInternalServerError),
+ Entry("fails if errors", func() {
+ createShareMock.Return(nil, errors.New("error"))
+ }, http.StatusInternalServerError),
+ )
+ })
+
Describe("GetRootDriveChildren", func() {
- It("handles ListStorageSpaces not found ", func() {
+ It("handles ListStorageSpaces not found", func() {
gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(&provider.ListStorageSpacesResponse{
Status: status.NewNotFound(ctx, "not found"),
}, nil)
diff --git a/services/graph/pkg/service/v0/errorcode/errorcode.go b/services/graph/pkg/service/v0/errorcode/errorcode.go
index 65b6beb5a4c..df288d6dbc9 100644
--- a/services/graph/pkg/service/v0/errorcode/errorcode.go
+++ b/services/graph/pkg/service/v0/errorcode/errorcode.go
@@ -2,6 +2,7 @@
package errorcode
import (
+ "context"
"errors"
"net/http"
"time"
@@ -91,20 +92,24 @@ func New(e ErrorCode, msg string) Error {
// Render writes an Graph ErrorCode object to the response writer
func (e ErrorCode) Render(w http.ResponseWriter, r *http.Request, status int, msg string) {
+ render.Status(r, status)
+ render.JSON(w, r, e.CreateOdataError(r.Context(), msg))
+}
+
+// CreateOdataError creates and populates a Graph ErrorCode object
+func (e ErrorCode) CreateOdataError(ctx context.Context, msg string) *libregraph.OdataError {
innererror := map[string]interface{}{
"date": time.Now().UTC().Format(time.RFC3339),
}
- innererror["request-id"] = middleware.GetReqID(r.Context())
- resp := &libregraph.OdataError{
+ innererror["request-id"] = middleware.GetReqID(ctx)
+ return &libregraph.OdataError{
Error: libregraph.OdataErrorMain{
Code: e.String(),
Message: msg,
Innererror: innererror,
},
}
- render.Status(r, status)
- render.JSON(w, r, resp)
}
// Render writes an Graph Error object to the response writer
diff --git a/services/graph/pkg/service/v0/service.go b/services/graph/pkg/service/v0/service.go
index 3012bbd7298..7f9f0d39214 100644
--- a/services/graph/pkg/service/v0/service.go
+++ b/services/graph/pkg/service/v0/service.go
@@ -10,14 +10,15 @@ import (
"strconv"
"time"
- "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
- "github.com/cs3org/reva/v2/pkg/store"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
ldapv3 "github.com/go-ldap/ldap/v3"
"github.com/jellydator/ttlcache/v3"
microstore "go-micro.dev/v4/store"
+ "github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
+ "github.com/cs3org/reva/v2/pkg/store"
+
ocisldap "github.com/owncloud/ocis/v2/ocis-pkg/ldap"
"github.com/owncloud/ocis/v2/ocis-pkg/registry"
"github.com/owncloud/ocis/v2/ocis-pkg/roles"
@@ -107,6 +108,8 @@ type Service interface {
GetDriveItem(w http.ResponseWriter, r *http.Request)
GetDriveItemChildren(w http.ResponseWriter, r *http.Request)
+ Invite(w http.ResponseWriter, r *http.Request)
+
GetTags(w http.ResponseWriter, r *http.Request)
AssignTags(w http.ResponseWriter, r *http.Request)
UnassignTags(w http.ResponseWriter, r *http.Request)
@@ -195,6 +198,7 @@ func NewService(opts ...Option) (Graph, error) {
r.Route("/v1beta1", func(r chi.Router) {
r.Get("/me/drive/sharedByMe", svc.GetSharedByMe)
r.Get("/me/drive/sharedWithMe", svc.ListSharedWithMe)
+ r.Post("/drives/{driveID}/items/{itemID}/invite", svc.Invite)
r.Route("/roleManagement/permissions/roleDefinitions", func(r chi.Router) {
r.Get("/", svc.GetRoleDefinitions)
r.Get("/{roleID}", svc.GetRoleDefinition)
diff --git a/services/graph/pkg/validate/validate.go b/services/graph/pkg/validate/validate.go
new file mode 100644
index 00000000000..534ff4c984e
--- /dev/null
+++ b/services/graph/pkg/validate/validate.go
@@ -0,0 +1,36 @@
+package validate
+
+import (
+ "context"
+ "sync/atomic"
+
+ "github.com/go-playground/validator/v10"
+ libregraph "github.com/owncloud/libre-graph-api-go"
+)
+
+var defaultValidator atomic.Value
+var structMapValidations = map[any]map[string]string{
+ &libregraph.DriveItemInvite{}: {
+ "Recipients": "min=1",
+ "Roles": "len=1", // currently it is not possible to set more than one role
+ "ExpirationDateTime": "omitnil,gt",
+ },
+}
+
+func init() {
+ v := validator.New()
+
+ for s, rules := range structMapValidations {
+ v.RegisterStructValidationMapRules(rules, s)
+ }
+
+ defaultValidator.Store(v)
+}
+
+// Default returns the default validator.
+func Default() *validator.Validate { return defaultValidator.Load().(*validator.Validate) }
+
+// StructCtx validates a struct and returns the error.
+func StructCtx(ctx context.Context, s interface{}) error {
+ return Default().StructCtx(ctx, s)
+}
diff --git a/vendor/github.com/go-playground/locales/README.md b/vendor/github.com/go-playground/locales/README.md
index ba1b0680c97..7b6be2c6478 100644
--- a/vendor/github.com/go-playground/locales/README.md
+++ b/vendor/github.com/go-playground/locales/README.md
@@ -1,17 +1,15 @@
## locales
-![Project status](https://img.shields.io/badge/version-0.13.0-green.svg)
+![Project status](https://img.shields.io/badge/version-0.14.1-green.svg)
[![Build Status](https://travis-ci.org/go-playground/locales.svg?branch=master)](https://travis-ci.org/go-playground/locales)
-[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/locales)](https://goreportcard.com/report/github.com/go-playground/locales)
[![GoDoc](https://godoc.org/github.com/go-playground/locales?status.svg)](https://godoc.org/github.com/go-playground/locales)
![License](https://img.shields.io/dub/l/vibe-d.svg)
-[![Gitter](https://badges.gitter.im/go-playground/locales.svg)](https://gitter.im/go-playground/locales?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
Locales is a set of locales generated from the [Unicode CLDR Project](http://cldr.unicode.org/) which can be used independently or within
an i18n package; these were built for use with, but not exclusive to, [Universal Translator](https://github.com/go-playground/universal-translator).
Features
--------
-- [x] Rules generated from the latest [CLDR](http://cldr.unicode.org/index/downloads) data, v31.0.1
+- [x] Rules generated from the latest [CLDR](http://cldr.unicode.org/index/downloads) data, v36.0.1
- [x] Contains Cardinal, Ordinal and Range Plural Rules
- [x] Contains Month, Weekday and Timezone translations built in
- [x] Contains Date & Time formatting functions
diff --git a/vendor/github.com/go-playground/locales/currency/currency.go b/vendor/github.com/go-playground/locales/currency/currency.go
index cdaba596b62..b5a95fb0743 100644
--- a/vendor/github.com/go-playground/locales/currency/currency.go
+++ b/vendor/github.com/go-playground/locales/currency/currency.go
@@ -176,6 +176,7 @@ const (
MNT
MOP
MRO
+ MRU
MTL
MTP
MUR
@@ -262,9 +263,11 @@ const (
UYI
UYP
UYU
+ UYW
UZS
VEB
VEF
+ VES
VND
VNN
VUV
diff --git a/vendor/github.com/go-playground/locales/en/en.go b/vendor/github.com/go-playground/locales/en/en.go
index 8fff3a56abb..baf343d4ff2 100644
--- a/vendor/github.com/go-playground/locales/en/en.go
+++ b/vendor/github.com/go-playground/locales/en/en.go
@@ -55,7 +55,7 @@ func New() locales.Translator {
perMille: "‰",
timeSeparator: ":",
inifinity: "∞",
- currencies: []string{"ADP", "AED", "AFA", "AFN", "ALK", "ALL", "AMD", "ANG", "AOA", "AOK", "AON", "AOR", "ARA", "ARL", "ARM", "ARP", "ARS", "ATS", "AUD", "AWG", "AZM", "AZN", "BAD", "BAM", "BAN", "BBD", "BDT", "BEC", "BEF", "BEL", "BGL", "BGM", "BGN", "BGO", "BHD", "BIF", "BMD", "BND", "BOB", "BOL", "BOP", "BOV", "BRB", "BRC", "BRE", "BRL", "BRN", "BRR", "BRZ", "BSD", "BTN", "BUK", "BWP", "BYB", "BYN", "BYR", "BZD", "CAD", "CDF", "CHE", "CHF", "CHW", "CLE", "CLF", "CLP", "CNH", "CNX", "CNY", "COP", "COU", "CRC", "CSD", "CSK", "CUC", "CUP", "CVE", "CYP", "CZK", "DDM", "DEM", "DJF", "DKK", "DOP", "DZD", "ECS", "ECV", "EEK", "EGP", "ERN", "ESA", "ESB", "ESP", "ETB", "EUR", "FIM", "FJD", "FKP", "FRF", "GBP", "GEK", "GEL", "GHC", "GHS", "GIP", "GMD", "GNF", "GNS", "GQE", "GRD", "GTQ", "GWE", "GWP", "GYD", "HKD", "HNL", "HRD", "HRK", "HTG", "HUF", "IDR", "IEP", "ILP", "ILR", "ILS", "INR", "IQD", "IRR", "ISJ", "ISK", "ITL", "JMD", "JOD", "¥", "KES", "KGS", "KHR", "KMF", "KPW", "KRH", "KRO", "KRW", "KWD", "KYD", "KZT", "LAK", "LBP", "LKR", "LRD", "LSL", "LTL", "LTT", "LUC", "LUF", "LUL", "LVL", "LVR", "LYD", "MAD", "MAF", "MCF", "MDC", "MDL", "MGA", "MGF", "MKD", "MKN", "MLF", "MMK", "MNT", "MOP", "MRO", "MTL", "MTP", "MUR", "MVP", "MVR", "MWK", "MXN", "MXP", "MXV", "MYR", "MZE", "MZM", "MZN", "NAD", "NGN", "NIC", "NIO", "NLG", "NOK", "NPR", "NZD", "OMR", "PAB", "PEI", "PEN", "PES", "PGK", "PHP", "PKR", "PLN", "PLZ", "PTE", "PYG", "QAR", "RHD", "ROL", "RON", "RSD", "RUB", "RUR", "RWF", "SAR", "SBD", "SCR", "SDD", "SDG", "SDP", "SEK", "SGD", "SHP", "SIT", "SKK", "SLL", "SOS", "SRD", "SRG", "SSP", "STD", "STN", "SUR", "SVC", "SYP", "SZL", "THB", "TJR", "TJS", "TMM", "TMT", "TND", "TOP", "TPE", "TRL", "TRY", "TTD", "TWD", "TZS", "UAH", "UAK", "UGS", "UGX", "$", "USN", "USS", "UYI", "UYP", "UYU", "UZS", "VEB", "VEF", "VND", "VNN", "VUV", "WST", "XAF", "XAG", "XAU", "XBA", "XBB", "XBC", "XBD", "XCD", "XDR", "XEU", "XFO", "XFU", "XOF", "XPD", "XPF", "XPT", "XRE", "XSU", "XTS", "XUA", "XXX", "YDD", "YER", "YUD", "YUM", "YUN", "YUR", "ZAL", "ZAR", "ZMK", "ZMW", "ZRN", "ZRZ", "ZWD", "ZWL", "ZWR"},
+ currencies: []string{"ADP", "AED", "AFA", "AFN", "ALK", "ALL", "AMD", "ANG", "AOA", "AOK", "AON", "AOR", "ARA", "ARL", "ARM", "ARP", "ARS", "ATS", "AUD", "AWG", "AZM", "AZN", "BAD", "BAM", "BAN", "BBD", "BDT", "BEC", "BEF", "BEL", "BGL", "BGM", "BGN", "BGO", "BHD", "BIF", "BMD", "BND", "BOB", "BOL", "BOP", "BOV", "BRB", "BRC", "BRE", "BRL", "BRN", "BRR", "BRZ", "BSD", "BTN", "BUK", "BWP", "BYB", "BYN", "BYR", "BZD", "CAD", "CDF", "CHE", "CHF", "CHW", "CLE", "CLF", "CLP", "CNH", "CNX", "CNY", "COP", "COU", "CRC", "CSD", "CSK", "CUC", "CUP", "CVE", "CYP", "CZK", "DDM", "DEM", "DJF", "DKK", "DOP", "DZD", "ECS", "ECV", "EEK", "EGP", "ERN", "ESA", "ESB", "ESP", "ETB", "EUR", "FIM", "FJD", "FKP", "FRF", "GBP", "GEK", "GEL", "GHC", "GHS", "GIP", "GMD", "GNF", "GNS", "GQE", "GRD", "GTQ", "GWE", "GWP", "GYD", "HKD", "HNL", "HRD", "HRK", "HTG", "HUF", "IDR", "IEP", "ILP", "ILR", "ILS", "INR", "IQD", "IRR", "ISJ", "ISK", "ITL", "JMD", "JOD", "¥", "KES", "KGS", "KHR", "KMF", "KPW", "KRH", "KRO", "KRW", "KWD", "KYD", "KZT", "LAK", "LBP", "LKR", "LRD", "LSL", "LTL", "LTT", "LUC", "LUF", "LUL", "LVL", "LVR", "LYD", "MAD", "MAF", "MCF", "MDC", "MDL", "MGA", "MGF", "MKD", "MKN", "MLF", "MMK", "MNT", "MOP", "MRO", "MRU", "MTL", "MTP", "MUR", "MVP", "MVR", "MWK", "MXN", "MXP", "MXV", "MYR", "MZE", "MZM", "MZN", "NAD", "NGN", "NIC", "NIO", "NLG", "NOK", "NPR", "NZD", "OMR", "PAB", "PEI", "PEN", "PES", "PGK", "PHP", "PKR", "PLN", "PLZ", "PTE", "PYG", "QAR", "RHD", "ROL", "RON", "RSD", "RUB", "RUR", "RWF", "SAR", "SBD", "SCR", "SDD", "SDG", "SDP", "SEK", "SGD", "SHP", "SIT", "SKK", "SLL", "SOS", "SRD", "SRG", "SSP", "STD", "STN", "SUR", "SVC", "SYP", "SZL", "THB", "TJR", "TJS", "TMM", "TMT", "TND", "TOP", "TPE", "TRL", "TRY", "TTD", "TWD", "TZS", "UAH", "UAK", "UGS", "UGX", "$", "USN", "USS", "UYI", "UYP", "UYU", "UYW", "UZS", "VEB", "VEF", "VES", "VND", "VNN", "VUV", "WST", "XAF", "XAG", "XAU", "XBA", "XBB", "XBC", "XBD", "XCD", "XDR", "XEU", "XFO", "XFU", "XOF", "XPD", "XPF", "XPT", "XRE", "XSU", "XTS", "XUA", "XXX", "YDD", "YER", "YUD", "YUM", "YUN", "YUR", "ZAL", "ZAR", "ZMK", "ZMW", "ZRN", "ZRZ", "ZWD", "ZWL", "ZWR"},
currencyNegativePrefix: "(",
currencyNegativeSuffix: ")",
monthsAbbreviated: []string{"", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"},
@@ -71,7 +71,7 @@ func New() locales.Translator {
erasAbbreviated: []string{"BC", "AD"},
erasNarrow: []string{"B", "A"},
erasWide: []string{"Before Christ", "Anno Domini"},
- timezones: map[string]string{"IST": "India Standard Time", "WARST": "Western Argentina Summer Time", "HNT": "Newfoundland Standard Time", "VET": "Venezuela Time", "HAST": "Hawaii-Aleutian Standard Time", "CDT": "Central Daylight Time", "HEEG": "East Greenland Summer Time", "HKT": "Hong Kong Standard Time", "SGT": "Singapore Standard Time", "EDT": "Eastern Daylight Time", "HEPM": "St. Pierre & Miquelon Daylight Time", "CST": "Central Standard Time", "HNPMX": "Mexican Pacific Standard Time", "WAT": "West Africa Standard Time", "JDT": "Japan Daylight Time", "ACST": "Australian Central Standard Time", "TMST": "Turkmenistan Summer Time", "LHDT": "Lord Howe Daylight Time", "CAT": "Central Africa Time", "UYT": "Uruguay Standard Time", "HEPMX": "Mexican Pacific Daylight Time", "WEZ": "Western European Standard Time", "BOT": "Bolivia Time", "GFT": "French Guiana Time", "HNNOMX": "Northwest Mexico Standard Time", "OEZ": "Eastern European Standard Time", "AEST": "Australian Eastern Standard Time", "MDT": "Mountain Daylight Time", "SAST": "South Africa Standard Time", "BT": "Bhutan Time", "SRT": "Suriname Time", "TMT": "Turkmenistan Standard Time", "CHADT": "Chatham Daylight Time", "PST": "Pacific Standard Time", "ADT": "Atlantic Daylight Time", "HENOMX": "Northwest Mexico Daylight Time", "EAT": "East Africa Time", "CLT": "Chile Standard Time", "∅∅∅": "Brasilia Summer Time", "WESZ": "Western European Summer Time", "HAT": "Newfoundland Daylight Time", "WIB": "Western Indonesia Time", "NZST": "New Zealand Standard Time", "HNEG": "East Greenland Standard Time", "HNPM": "St. Pierre & Miquelon Standard Time", "WITA": "Central Indonesia Time", "GMT": "Greenwich Mean Time", "UYST": "Uruguay Summer Time", "HNCU": "Cuba Standard Time", "GYT": "Guyana Time", "MYT": "Malaysia Time", "COT": "Colombia Standard Time", "AST": "Atlantic Standard Time", "ACDT": "Australian Central Daylight Time", "MEZ": "Central European Standard Time", "AKDT": "Alaska Daylight Time", "EST": "Eastern Standard Time", "HNOG": "West Greenland Standard Time", "ECT": "Ecuador Time", "ART": "Argentina Standard Time", "HEOG": "West Greenland Summer Time", "MESZ": "Central European Summer Time", "LHST": "Lord Howe Standard Time", "OESZ": "Eastern European Summer Time", "AWST": "Australian Western Standard Time", "AEDT": "Australian Eastern Daylight Time", "ACWDT": "Australian Central Western Daylight Time", "NZDT": "New Zealand Daylight Time", "JST": "Japan Standard Time", "WART": "Western Argentina Standard Time", "CHAST": "Chatham Standard Time", "HECU": "Cuba Daylight Time", "WAST": "West Africa Summer Time", "ACWST": "Australian Central Western Standard Time", "HKST": "Hong Kong Summer Time", "ARST": "Argentina Summer Time", "MST": "Mountain Standard Time", "AKST": "Alaska Standard Time", "CLST": "Chile Summer Time", "WIT": "Eastern Indonesia Time", "HADT": "Hawaii-Aleutian Daylight Time", "ChST": "Chamorro Standard Time", "PDT": "Pacific Daylight Time", "AWDT": "Australian Western Daylight Time", "COST": "Colombia Summer Time"},
+ timezones: map[string]string{"ACDT": "Australian Central Daylight Time", "ACST": "Australian Central Standard Time", "ACWDT": "Australian Central Western Daylight Time", "ACWST": "Australian Central Western Standard Time", "ADT": "Atlantic Daylight Time", "AEDT": "Australian Eastern Daylight Time", "AEST": "Australian Eastern Standard Time", "AKDT": "Alaska Daylight Time", "AKST": "Alaska Standard Time", "ARST": "Argentina Summer Time", "ART": "Argentina Standard Time", "AST": "Atlantic Standard Time", "AWDT": "Australian Western Daylight Time", "AWST": "Australian Western Standard Time", "BOT": "Bolivia Time", "BT": "Bhutan Time", "CAT": "Central Africa Time", "CDT": "Central Daylight Time", "CHADT": "Chatham Daylight Time", "CHAST": "Chatham Standard Time", "CLST": "Chile Summer Time", "CLT": "Chile Standard Time", "COST": "Colombia Summer Time", "COT": "Colombia Standard Time", "CST": "Central Standard Time", "ChST": "Chamorro Standard Time", "EAT": "East Africa Time", "ECT": "Ecuador Time", "EDT": "Eastern Daylight Time", "EST": "Eastern Standard Time", "GFT": "French Guiana Time", "GMT": "Greenwich Mean Time", "GST": "Gulf Standard Time", "GYT": "Guyana Time", "HADT": "Hawaii-Aleutian Daylight Time", "HAST": "Hawaii-Aleutian Standard Time", "HAT": "Newfoundland Daylight Time", "HECU": "Cuba Daylight Time", "HEEG": "East Greenland Summer Time", "HENOMX": "Northwest Mexico Daylight Time", "HEOG": "West Greenland Summer Time", "HEPM": "St. Pierre & Miquelon Daylight Time", "HEPMX": "Mexican Pacific Daylight Time", "HKST": "Hong Kong Summer Time", "HKT": "Hong Kong Standard Time", "HNCU": "Cuba Standard Time", "HNEG": "East Greenland Standard Time", "HNNOMX": "Northwest Mexico Standard Time", "HNOG": "West Greenland Standard Time", "HNPM": "St. Pierre & Miquelon Standard Time", "HNPMX": "Mexican Pacific Standard Time", "HNT": "Newfoundland Standard Time", "IST": "India Standard Time", "JDT": "Japan Daylight Time", "JST": "Japan Standard Time", "LHDT": "Lord Howe Daylight Time", "LHST": "Lord Howe Standard Time", "MDT": "Mountain Daylight Time", "MESZ": "Central European Summer Time", "MEZ": "Central European Standard Time", "MST": "Mountain Standard Time", "MYT": "Malaysia Time", "NZDT": "New Zealand Daylight Time", "NZST": "New Zealand Standard Time", "OESZ": "Eastern European Summer Time", "OEZ": "Eastern European Standard Time", "PDT": "Pacific Daylight Time", "PST": "Pacific Standard Time", "SAST": "South Africa Standard Time", "SGT": "Singapore Standard Time", "SRT": "Suriname Time", "TMST": "Turkmenistan Summer Time", "TMT": "Turkmenistan Standard Time", "UYST": "Uruguay Summer Time", "UYT": "Uruguay Standard Time", "VET": "Venezuela Time", "WARST": "Western Argentina Summer Time", "WART": "Western Argentina Standard Time", "WAST": "West Africa Summer Time", "WAT": "West Africa Standard Time", "WESZ": "Western European Summer Time", "WEZ": "Western European Standard Time", "WIB": "Western Indonesia Time", "WIT": "Eastern Indonesia Time", "WITA": "Central Indonesia Time", "∅∅∅": "Brasilia Summer Time"},
}
}
diff --git a/vendor/github.com/go-playground/universal-translator/Makefile b/vendor/github.com/go-playground/universal-translator/Makefile
new file mode 100644
index 00000000000..ec3455bd59c
--- /dev/null
+++ b/vendor/github.com/go-playground/universal-translator/Makefile
@@ -0,0 +1,18 @@
+GOCMD=GO111MODULE=on go
+
+linters-install:
+ @golangci-lint --version >/dev/null 2>&1 || { \
+ echo "installing linting tools..."; \
+ curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v1.41.1; \
+ }
+
+lint: linters-install
+ golangci-lint run
+
+test:
+ $(GOCMD) test -cover -race ./...
+
+bench:
+ $(GOCMD) test -bench=. -benchmem ./...
+
+.PHONY: test lint linters-install
\ No newline at end of file
diff --git a/vendor/github.com/go-playground/universal-translator/README.md b/vendor/github.com/go-playground/universal-translator/README.md
index 071f33ab25a..d9b6654741b 100644
--- a/vendor/github.com/go-playground/universal-translator/README.md
+++ b/vendor/github.com/go-playground/universal-translator/README.md
@@ -1,11 +1,9 @@
## universal-translator
-![Project status](https://img.shields.io/badge/version-0.17.0-green.svg)
-[![Build Status](https://travis-ci.org/go-playground/universal-translator.svg?branch=master)](https://travis-ci.org/go-playground/universal-translator)
+![Project status](https://img.shields.io/badge/version-0.18.1-green.svg)
[![Coverage Status](https://coveralls.io/repos/github/go-playground/universal-translator/badge.svg)](https://coveralls.io/github/go-playground/universal-translator)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/universal-translator)](https://goreportcard.com/report/github.com/go-playground/universal-translator)
[![GoDoc](https://godoc.org/github.com/go-playground/universal-translator?status.svg)](https://godoc.org/github.com/go-playground/universal-translator)
![License](https://img.shields.io/dub/l/vibe-d.svg)
-[![Gitter](https://badges.gitter.im/go-playground/universal-translator.svg)](https://gitter.im/go-playground/universal-translator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
Universal Translator is an i18n Translator for Go/Golang using CLDR data + pluralization rules
@@ -18,7 +16,7 @@ use in your applications.
Features
--------
-- [x] Rules generated from the [CLDR](http://cldr.unicode.org/index/downloads) data, v30.0.3
+- [x] Rules generated from the [CLDR](http://cldr.unicode.org/index/downloads) data, v36.0.1
- [x] Contains Cardinal, Ordinal and Range Plural Rules
- [x] Contains Month, Weekday and Timezone translations built in
- [x] Contains Date & Time formatting functions
@@ -51,7 +49,7 @@ Please see https://godoc.org/github.com/go-playground/universal-translator for u
File formatting
--------------
-All types, Plain substitution, Cardinal, Ordinal and Range translations can all be contained withing the same file(s);
+All types, Plain substitution, Cardinal, Ordinal and Range translations can all be contained within the same file(s);
they are only separated for easy viewing.
##### Examples:
diff --git a/vendor/github.com/go-playground/universal-translator/import_export.go b/vendor/github.com/go-playground/universal-translator/import_export.go
index 7bd76f26b6f..87a1b465cba 100644
--- a/vendor/github.com/go-playground/universal-translator/import_export.go
+++ b/vendor/github.com/go-playground/universal-translator/import_export.go
@@ -3,7 +3,6 @@ package ut
import (
"encoding/json"
"fmt"
- "io/ioutil"
"os"
"path/filepath"
@@ -41,7 +40,6 @@ const (
func (t *UniversalTranslator) Export(format ImportExportFormat, dirname string) error {
_, err := os.Stat(dirname)
- fmt.Println(dirname, err, os.IsNotExist(err))
if err != nil {
if !os.IsNotExist(err) {
@@ -138,7 +136,7 @@ func (t *UniversalTranslator) Export(format ImportExportFormat, dirname string)
return err
}
- err = ioutil.WriteFile(filepath.Join(dirname, fmt.Sprintf("%s%s", locale.Locale(), ext)), b, 0644)
+ err = os.WriteFile(filepath.Join(dirname, fmt.Sprintf("%s%s", locale.Locale(), ext)), b, 0644)
if err != nil {
return err
}
@@ -200,7 +198,7 @@ func (t *UniversalTranslator) Import(format ImportExportFormat, dirnameOrFilenam
// NOTE: generally used when assets have been embedded into the binary and are already in memory.
func (t *UniversalTranslator) ImportByReader(format ImportExportFormat, reader io.Reader) error {
- b, err := ioutil.ReadAll(reader)
+ b, err := io.ReadAll(reader)
if err != nil {
return err
}
@@ -257,6 +255,8 @@ func (t *UniversalTranslator) ImportByReader(format ImportExportFormat, reader i
func stringToPR(s string) locales.PluralRule {
switch s {
+ case "Zero":
+ return locales.PluralRuleZero
case "One":
return locales.PluralRuleOne
case "Two":
diff --git a/vendor/github.com/go-playground/universal-translator/translator.go b/vendor/github.com/go-playground/universal-translator/translator.go
index cfafce8a09d..24b18db92a1 100644
--- a/vendor/github.com/go-playground/universal-translator/translator.go
+++ b/vendor/github.com/go-playground/universal-translator/translator.go
@@ -159,13 +159,13 @@ func (t *translator) AddCardinal(key interface{}, text string, rule locales.Plur
}
} else {
- tarr = make([]*transText, 7, 7)
+ tarr = make([]*transText, 7)
t.cardinalTanslations[key] = tarr
}
trans := &transText{
text: text,
- indexes: make([]int, 2, 2),
+ indexes: make([]int, 2),
}
tarr[rule] = trans
@@ -211,13 +211,13 @@ func (t *translator) AddOrdinal(key interface{}, text string, rule locales.Plura
}
} else {
- tarr = make([]*transText, 7, 7)
+ tarr = make([]*transText, 7)
t.ordinalTanslations[key] = tarr
}
trans := &transText{
text: text,
- indexes: make([]int, 2, 2),
+ indexes: make([]int, 2),
}
tarr[rule] = trans
@@ -261,13 +261,13 @@ func (t *translator) AddRange(key interface{}, text string, rule locales.PluralR
}
} else {
- tarr = make([]*transText, 7, 7)
+ tarr = make([]*transText, 7)
t.rangeTanslations[key] = tarr
}
trans := &transText{
text: text,
- indexes: make([]int, 4, 4),
+ indexes: make([]int, 4),
}
tarr[rule] = trans
diff --git a/vendor/github.com/go-playground/validator/v10/.gitignore b/vendor/github.com/go-playground/validator/v10/.gitignore
index 6e43fac0d5a..6305e52900a 100644
--- a/vendor/github.com/go-playground/validator/v10/.gitignore
+++ b/vendor/github.com/go-playground/validator/v10/.gitignore
@@ -26,5 +26,7 @@ _testmain.go
*.test
*.out
*.txt
+/**/*.DS_Store
cover.html
README.html
+.idea
diff --git a/vendor/github.com/go-playground/validator/v10/.travis.yml b/vendor/github.com/go-playground/validator/v10/.travis.yml
deleted file mode 100644
index 85a7be34b11..00000000000
--- a/vendor/github.com/go-playground/validator/v10/.travis.yml
+++ /dev/null
@@ -1,29 +0,0 @@
-language: go
-go:
- - 1.15.2
- - tip
-matrix:
- allow_failures:
- - go: tip
-
-notifications:
- email:
- recipients: dean.karn@gmail.com
- on_success: change
- on_failure: always
-
-before_install:
- - go install github.com/mattn/goveralls
- - mkdir -p $GOPATH/src/gopkg.in
- - ln -s $GOPATH/src/github.com/$TRAVIS_REPO_SLUG $GOPATH/src/gopkg.in/validator.v9
-
-# Only clone the most recent commit.
-git:
- depth: 1
-
-script:
- - go test -v -race -covermode=atomic -coverprofile=coverage.coverprofile ./...
-
-after_success: |
- [ $TRAVIS_GO_VERSION = 1.15.2 ] &&
- goveralls -coverprofile=coverage.coverprofile -service travis-ci -repotoken $COVERALLS_TOKEN
diff --git a/vendor/github.com/go-playground/validator/v10/MAINTAINERS.md b/vendor/github.com/go-playground/validator/v10/MAINTAINERS.md
new file mode 100644
index 00000000000..b809c4ce128
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/MAINTAINERS.md
@@ -0,0 +1,16 @@
+## Maintainers Guide
+
+### Semantic Versioning
+Semantic versioning as defined [here](https://semver.org) must be strictly adhered to.
+
+### External Dependencies
+Any new external dependencies MUST:
+- Have a compatible LICENSE present.
+- Be actively maintained.
+- Be approved by @go-playground/admins
+
+### PR Merge Requirements
+- Up-to-date branch.
+- Passing tests and linting.
+- CODEOWNERS approval.
+- Tests that cover both the Happy and Unhappy paths.
\ No newline at end of file
diff --git a/vendor/github.com/go-playground/validator/v10/Makefile b/vendor/github.com/go-playground/validator/v10/Makefile
index 19c91ed73e9..09f171ba10d 100644
--- a/vendor/github.com/go-playground/validator/v10/Makefile
+++ b/vendor/github.com/go-playground/validator/v10/Makefile
@@ -3,16 +3,16 @@ GOCMD=GO111MODULE=on go
linters-install:
@golangci-lint --version >/dev/null 2>&1 || { \
echo "installing linting tools..."; \
- curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v1.21.0; \
+ curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v1.41.1; \
}
lint: linters-install
- $(PWD)/bin/golangci-lint run
+ golangci-lint run
test:
$(GOCMD) test -cover -race ./...
bench:
- $(GOCMD) test -bench=. -benchmem ./...
+ $(GOCMD) test -run=NONE -bench=. -benchmem ./...
.PHONY: test lint linters-install
\ No newline at end of file
diff --git a/vendor/github.com/go-playground/validator/v10/README.md b/vendor/github.com/go-playground/validator/v10/README.md
index 04fbb3c8699..dbbafc3e34d 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
-================
-[![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-![Project status](https://img.shields.io/badge/version-10.4.1-green.svg)
+=================
+[![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+![Project status](https://img.shields.io/badge/version-10.16.0-green.svg)
[![Build Status](https://travis-ci.org/go-playground/validator.svg?branch=master)](https://travis-ci.org/go-playground/validator)
[![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=master&service=github)](https://coveralls.io/github/go-playground/validator?branch=master)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator)
@@ -43,7 +43,7 @@ They return type error to avoid the issue discussed in the following, where err
* http://stackoverflow.com/a/29138676/3158232
* https://github.com/go-playground/validator/issues/134
-Validator only InvalidValidationError for bad validation input, nil or ValidationErrors as type error; so, in your code all you need to do is check if the error returned is not nil, and if it's not check if error is InvalidValidationError ( if necessary, most of the time it isn't ) type cast it to type ValidationErrors like so:
+Validator returns only InvalidValidationError for bad validation input, nil or ValidationErrors as type error; so, in your code all you need to do is check if the error returned is not nil, and if it's not check if error is InvalidValidationError ( if necessary, most of the time it isn't ) type cast it to type ValidationErrors like so:
```go
err := validate.Struct(mystruct)
@@ -53,7 +53,7 @@ validationErrors := err.(validator.ValidationErrors)
Usage and documentation
------
-Please see https://godoc.org/github.com/go-playground/validator for detailed usage docs.
+Please see https://pkg.go.dev/github.com/go-playground/validator/v10 for detailed usage docs.
##### Examples:
@@ -67,14 +67,20 @@ Please see https://godoc.org/github.com/go-playground/validator for detailed usa
Baked-in Validations
------
+### Special Notes:
+- If new to using validator it is highly recommended to initialize it using the `WithRequiredStructEnabled` option which is opt-in to new behaviour that will become the default behaviour in v11+. See documentation for more details.
+```go
+validate := validator.New(validator.WithRequiredStructEnabled())
+```
+
### Fields:
| Tag | Description |
| - | - |
| eqcsfield | Field Equals Another Field (relative)|
| eqfield | Field Equals Another Field |
-| fieldcontains | NOT DOCUMENTED IN doc.go |
-| fieldexcludes | NOT DOCUMENTED IN doc.go |
+| fieldcontains | Check the indicated characters are present in the Field |
+| fieldexcludes | Check the indicated characters are not present in the field |
| gtcsfield | Field Greater Than Another Relative Field |
| gtecsfield | Field Greater Than or Equal To Another Relative Field |
| gtefield | Field Greater Than or Equal To Another Field |
@@ -100,7 +106,7 @@ Baked-in Validations
| hostname_rfc1123 | Hostname RFC 1123 |
| ip | Internet Protocol Address IP |
| ip4_addr | Internet Protocol Address IPv4 |
-| ip6_addr |Internet Protocol Address IPv6 |
+| ip6_addr | Internet Protocol Address IPv6 |
| ip_addr | Internet Protocol Address IP |
| ipv4 | Internet Protocol Address IPv4 |
| ipv6 | Internet Protocol Address IPv6 |
@@ -114,6 +120,7 @@ Baked-in Validations
| unix_addr | Unix domain socket end point Address |
| uri | URI String |
| url | URL String |
+| http_url | HTTP URL String |
| url_encoded | URL Encoded |
| urn_rfc2141 | Urn RFC 2141 String |
@@ -126,15 +133,21 @@ Baked-in Validations
| alphanumunicode | Alphanumeric Unicode |
| alphaunicode | Alpha Unicode |
| ascii | ASCII |
+| boolean | Boolean |
| contains | Contains |
| containsany | Contains Any |
| containsrune | Contains Rune |
+| endsnotwith | Ends Not With |
| endswith | Ends With |
+| excludes | Excludes |
+| excludesall | Excludes All |
+| excludesrune | Excludes Rune |
| lowercase | Lowercase |
| multibyte | Multi-Byte Characters |
-| number | NOT DOCUMENTED IN doc.go |
+| number | Number |
| numeric | Numeric |
| printascii | Printable ASCII |
+| startsnotwith | Starts Not With |
| startswith | Starts With |
| uppercase | Uppercase |
@@ -143,8 +156,15 @@ Baked-in Validations
| - | - |
| base64 | Base64 String |
| base64url | Base64URL String |
+| base64rawurl | Base64RawURL String |
+| bic | Business Identifier Code (ISO 9362) |
+| bcp47_language_tag | Language tag (BCP 47) |
| btc_addr | Bitcoin Address |
| btc_addr_bech32 | Bitcoin Bech32 Address (segwit) |
+| credit_card | Credit Card Number |
+| mongodb | MongoDB ObjectID |
+| cron | Cron |
+| spicedb | SpiceDb ObjectID/Permission/Type |
| datetime | Datetime |
| e164 | e164 formatted phone number |
| email | E-mail String
@@ -158,12 +178,23 @@ Baked-in Validations
| isbn | International Standard Book Number |
| isbn10 | International Standard Book Number 10 |
| isbn13 | International Standard Book Number 13 |
+| issn | International Standard Serial Number |
+| iso3166_1_alpha2 | Two-letter country code (ISO 3166-1 alpha-2) |
+| iso3166_1_alpha3 | Three-letter country code (ISO 3166-1 alpha-3) |
+| iso3166_1_alpha_numeric | Numeric country code (ISO 3166-1 numeric) |
+| iso3166_2 | Country subdivision code (ISO 3166-2) |
+| iso4217 | Currency code (ISO 4217) |
| json | JSON |
+| jwt | JSON Web Token (JWT) |
| latitude | Latitude |
| longitude | Longitude |
+| luhn_checksum | Luhn Algorithm Checksum (for strings and (u)int) |
+| postcode_iso3166_alpha2 | Postcode |
+| postcode_iso3166_alpha2_field | Postcode |
| rgb | RGB String |
| rgba | RGBA String |
| ssn | Social Security Number SSN |
+| timezone | Timezone |
| uuid | Universally Unique Identifier UUID |
| uuid3 | Universally Unique Identifier UUID v3 |
| uuid3_rfc4122 | Universally Unique Identifier UUID v3 RFC4122 |
@@ -172,26 +203,40 @@ 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 |
+| cve | Common Vulnerabilities and Exposures Identifier (CVE id) |
### Comparisons:
| Tag | Description |
| - | - |
| eq | Equals |
+| eq_ignore_case | Equals ignoring case |
| gt | Greater than|
-| gte |Greater than or equal |
+| gte | Greater than or equal |
| lt | Less Than |
| lte | Less Than or Equal |
| ne | Not Equal |
+| ne_ignore_case | Not Equal ignoring case |
### Other:
| Tag | Description |
| - | - |
-| dir | Directory |
-| endswith | Ends With |
-| excludes | Excludes |
-| excludesall | Excludes All |
-| excludesrune | Excludes Rune |
-| file | File path |
+| dir | Existing Directory |
+| dirpath | Directory Path |
+| file | Existing File |
+| filepath | File Path |
+| image | Image |
| isdefault | Is Default |
| len | Length |
| max | Maximum |
@@ -204,81 +249,90 @@ 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 |
| excluded_without_all | Excluded Without All |
| unique | Unique |
+#### Aliases:
+| Tag | Description |
+| - | - |
+| iscolor | hexcolor\|rgb\|rgba\|hsl\|hsla |
+| country_code | iso3166_1_alpha2\|iso3166_1_alpha3\|iso3166_1_alpha_numeric |
+
Benchmarks
------
###### Run on MacBook Pro (15-inch, 2017) go version go1.10.2 darwin/amd64
```go
+go version go1.21.0 darwin/arm64
goos: darwin
-goarch: amd64
-pkg: github.com/go-playground/validator
-BenchmarkFieldSuccess-8 20000000 83.6 ns/op 0 B/op 0 allocs/op
-BenchmarkFieldSuccessParallel-8 50000000 26.8 ns/op 0 B/op 0 allocs/op
-BenchmarkFieldFailure-8 5000000 291 ns/op 208 B/op 4 allocs/op
-BenchmarkFieldFailureParallel-8 20000000 107 ns/op 208 B/op 4 allocs/op
-BenchmarkFieldArrayDiveSuccess-8 2000000 623 ns/op 201 B/op 11 allocs/op
-BenchmarkFieldArrayDiveSuccessParallel-8 10000000 237 ns/op 201 B/op 11 allocs/op
-BenchmarkFieldArrayDiveFailure-8 2000000 859 ns/op 412 B/op 16 allocs/op
-BenchmarkFieldArrayDiveFailureParallel-8 5000000 335 ns/op 413 B/op 16 allocs/op
-BenchmarkFieldMapDiveSuccess-8 1000000 1292 ns/op 432 B/op 18 allocs/op
-BenchmarkFieldMapDiveSuccessParallel-8 3000000 467 ns/op 432 B/op 18 allocs/op
-BenchmarkFieldMapDiveFailure-8 1000000 1082 ns/op 512 B/op 16 allocs/op
-BenchmarkFieldMapDiveFailureParallel-8 5000000 425 ns/op 512 B/op 16 allocs/op
-BenchmarkFieldMapDiveWithKeysSuccess-8 1000000 1539 ns/op 480 B/op 21 allocs/op
-BenchmarkFieldMapDiveWithKeysSuccessParallel-8 3000000 613 ns/op 480 B/op 21 allocs/op
-BenchmarkFieldMapDiveWithKeysFailure-8 1000000 1413 ns/op 721 B/op 21 allocs/op
-BenchmarkFieldMapDiveWithKeysFailureParallel-8 3000000 575 ns/op 721 B/op 21 allocs/op
-BenchmarkFieldCustomTypeSuccess-8 10000000 216 ns/op 32 B/op 2 allocs/op
-BenchmarkFieldCustomTypeSuccessParallel-8 20000000 82.2 ns/op 32 B/op 2 allocs/op
-BenchmarkFieldCustomTypeFailure-8 5000000 274 ns/op 208 B/op 4 allocs/op
-BenchmarkFieldCustomTypeFailureParallel-8 20000000 116 ns/op 208 B/op 4 allocs/op
-BenchmarkFieldOrTagSuccess-8 2000000 740 ns/op 16 B/op 1 allocs/op
-BenchmarkFieldOrTagSuccessParallel-8 3000000 474 ns/op 16 B/op 1 allocs/op
-BenchmarkFieldOrTagFailure-8 3000000 471 ns/op 224 B/op 5 allocs/op
-BenchmarkFieldOrTagFailureParallel-8 3000000 414 ns/op 224 B/op 5 allocs/op
-BenchmarkStructLevelValidationSuccess-8 10000000 213 ns/op 32 B/op 2 allocs/op
-BenchmarkStructLevelValidationSuccessParallel-8 20000000 91.8 ns/op 32 B/op 2 allocs/op
-BenchmarkStructLevelValidationFailure-8 3000000 473 ns/op 304 B/op 8 allocs/op
-BenchmarkStructLevelValidationFailureParallel-8 10000000 234 ns/op 304 B/op 8 allocs/op
-BenchmarkStructSimpleCustomTypeSuccess-8 5000000 385 ns/op 32 B/op 2 allocs/op
-BenchmarkStructSimpleCustomTypeSuccessParallel-8 10000000 161 ns/op 32 B/op 2 allocs/op
-BenchmarkStructSimpleCustomTypeFailure-8 2000000 640 ns/op 424 B/op 9 allocs/op
-BenchmarkStructSimpleCustomTypeFailureParallel-8 5000000 318 ns/op 440 B/op 10 allocs/op
-BenchmarkStructFilteredSuccess-8 2000000 597 ns/op 288 B/op 9 allocs/op
-BenchmarkStructFilteredSuccessParallel-8 10000000 266 ns/op 288 B/op 9 allocs/op
-BenchmarkStructFilteredFailure-8 3000000 454 ns/op 256 B/op 7 allocs/op
-BenchmarkStructFilteredFailureParallel-8 10000000 214 ns/op 256 B/op 7 allocs/op
-BenchmarkStructPartialSuccess-8 3000000 502 ns/op 256 B/op 6 allocs/op
-BenchmarkStructPartialSuccessParallel-8 10000000 225 ns/op 256 B/op 6 allocs/op
-BenchmarkStructPartialFailure-8 2000000 702 ns/op 480 B/op 11 allocs/op
-BenchmarkStructPartialFailureParallel-8 5000000 329 ns/op 480 B/op 11 allocs/op
-BenchmarkStructExceptSuccess-8 2000000 793 ns/op 496 B/op 12 allocs/op
-BenchmarkStructExceptSuccessParallel-8 10000000 193 ns/op 240 B/op 5 allocs/op
-BenchmarkStructExceptFailure-8 2000000 639 ns/op 464 B/op 10 allocs/op
-BenchmarkStructExceptFailureParallel-8 5000000 300 ns/op 464 B/op 10 allocs/op
-BenchmarkStructSimpleCrossFieldSuccess-8 3000000 417 ns/op 72 B/op 3 allocs/op
-BenchmarkStructSimpleCrossFieldSuccessParallel-8 10000000 163 ns/op 72 B/op 3 allocs/op
-BenchmarkStructSimpleCrossFieldFailure-8 2000000 645 ns/op 304 B/op 8 allocs/op
-BenchmarkStructSimpleCrossFieldFailureParallel-8 5000000 285 ns/op 304 B/op 8 allocs/op
-BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 3000000 588 ns/op 80 B/op 4 allocs/op
-BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 10000000 221 ns/op 80 B/op 4 allocs/op
-BenchmarkStructSimpleCrossStructCrossFieldFailure-8 2000000 868 ns/op 320 B/op 9 allocs/op
-BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 5000000 337 ns/op 320 B/op 9 allocs/op
-BenchmarkStructSimpleSuccess-8 5000000 260 ns/op 0 B/op 0 allocs/op
-BenchmarkStructSimpleSuccessParallel-8 20000000 90.6 ns/op 0 B/op 0 allocs/op
-BenchmarkStructSimpleFailure-8 2000000 619 ns/op 424 B/op 9 allocs/op
-BenchmarkStructSimpleFailureParallel-8 5000000 296 ns/op 424 B/op 9 allocs/op
-BenchmarkStructComplexSuccess-8 1000000 1454 ns/op 128 B/op 8 allocs/op
-BenchmarkStructComplexSuccessParallel-8 3000000 579 ns/op 128 B/op 8 allocs/op
-BenchmarkStructComplexFailure-8 300000 4140 ns/op 3041 B/op 53 allocs/op
-BenchmarkStructComplexFailureParallel-8 1000000 2127 ns/op 3041 B/op 53 allocs/op
-BenchmarkOneof-8 10000000 140 ns/op 0 B/op 0 allocs/op
-BenchmarkOneofParallel-8 20000000 70.1 ns/op 0 B/op 0 allocs/op
+goarch: arm64
+pkg: github.com/go-playground/validator/v10
+BenchmarkFieldSuccess-8 33142266 35.94 ns/op 0 B/op 0 allocs/op
+BenchmarkFieldSuccessParallel-8 200816191 6.568 ns/op 0 B/op 0 allocs/op
+BenchmarkFieldFailure-8 6779707 175.1 ns/op 200 B/op 4 allocs/op
+BenchmarkFieldFailureParallel-8 11044147 108.4 ns/op 200 B/op 4 allocs/op
+BenchmarkFieldArrayDiveSuccess-8 6054232 194.4 ns/op 97 B/op 5 allocs/op
+BenchmarkFieldArrayDiveSuccessParallel-8 12523388 94.07 ns/op 97 B/op 5 allocs/op
+BenchmarkFieldArrayDiveFailure-8 3587043 334.3 ns/op 300 B/op 10 allocs/op
+BenchmarkFieldArrayDiveFailureParallel-8 5816665 200.8 ns/op 300 B/op 10 allocs/op
+BenchmarkFieldMapDiveSuccess-8 2217910 540.1 ns/op 288 B/op 14 allocs/op
+BenchmarkFieldMapDiveSuccessParallel-8 4446698 258.7 ns/op 288 B/op 14 allocs/op
+BenchmarkFieldMapDiveFailure-8 2392759 504.6 ns/op 376 B/op 13 allocs/op
+BenchmarkFieldMapDiveFailureParallel-8 4244199 286.9 ns/op 376 B/op 13 allocs/op
+BenchmarkFieldMapDiveWithKeysSuccess-8 2005857 592.1 ns/op 288 B/op 14 allocs/op
+BenchmarkFieldMapDiveWithKeysSuccessParallel-8 4400850 296.9 ns/op 288 B/op 14 allocs/op
+BenchmarkFieldMapDiveWithKeysFailure-8 1850227 643.8 ns/op 553 B/op 16 allocs/op
+BenchmarkFieldMapDiveWithKeysFailureParallel-8 3293233 375.1 ns/op 553 B/op 16 allocs/op
+BenchmarkFieldCustomTypeSuccess-8 12174412 98.25 ns/op 32 B/op 2 allocs/op
+BenchmarkFieldCustomTypeSuccessParallel-8 34389907 35.49 ns/op 32 B/op 2 allocs/op
+BenchmarkFieldCustomTypeFailure-8 7582524 156.6 ns/op 184 B/op 3 allocs/op
+BenchmarkFieldCustomTypeFailureParallel-8 13019902 92.79 ns/op 184 B/op 3 allocs/op
+BenchmarkFieldOrTagSuccess-8 3427260 349.4 ns/op 16 B/op 1 allocs/op
+BenchmarkFieldOrTagSuccessParallel-8 15144128 81.25 ns/op 16 B/op 1 allocs/op
+BenchmarkFieldOrTagFailure-8 5913546 201.9 ns/op 216 B/op 5 allocs/op
+BenchmarkFieldOrTagFailureParallel-8 9810212 113.7 ns/op 216 B/op 5 allocs/op
+BenchmarkStructLevelValidationSuccess-8 13456327 87.66 ns/op 16 B/op 1 allocs/op
+BenchmarkStructLevelValidationSuccessParallel-8 41818888 27.77 ns/op 16 B/op 1 allocs/op
+BenchmarkStructLevelValidationFailure-8 4166284 272.6 ns/op 264 B/op 7 allocs/op
+BenchmarkStructLevelValidationFailureParallel-8 7594581 152.1 ns/op 264 B/op 7 allocs/op
+BenchmarkStructSimpleCustomTypeSuccess-8 6508082 182.6 ns/op 32 B/op 2 allocs/op
+BenchmarkStructSimpleCustomTypeSuccessParallel-8 23078605 54.78 ns/op 32 B/op 2 allocs/op
+BenchmarkStructSimpleCustomTypeFailure-8 3118352 381.0 ns/op 416 B/op 9 allocs/op
+BenchmarkStructSimpleCustomTypeFailureParallel-8 5300738 224.1 ns/op 432 B/op 10 allocs/op
+BenchmarkStructFilteredSuccess-8 4761807 251.1 ns/op 216 B/op 5 allocs/op
+BenchmarkStructFilteredSuccessParallel-8 8792598 128.6 ns/op 216 B/op 5 allocs/op
+BenchmarkStructFilteredFailure-8 5202573 232.1 ns/op 216 B/op 5 allocs/op
+BenchmarkStructFilteredFailureParallel-8 9591267 121.4 ns/op 216 B/op 5 allocs/op
+BenchmarkStructPartialSuccess-8 5188512 231.6 ns/op 224 B/op 4 allocs/op
+BenchmarkStructPartialSuccessParallel-8 9179776 123.1 ns/op 224 B/op 4 allocs/op
+BenchmarkStructPartialFailure-8 3071212 392.5 ns/op 440 B/op 9 allocs/op
+BenchmarkStructPartialFailureParallel-8 5344261 223.7 ns/op 440 B/op 9 allocs/op
+BenchmarkStructExceptSuccess-8 3184230 375.0 ns/op 424 B/op 8 allocs/op
+BenchmarkStructExceptSuccessParallel-8 10090130 108.9 ns/op 208 B/op 3 allocs/op
+BenchmarkStructExceptFailure-8 3347226 357.7 ns/op 424 B/op 8 allocs/op
+BenchmarkStructExceptFailureParallel-8 5654923 209.5 ns/op 424 B/op 8 allocs/op
+BenchmarkStructSimpleCrossFieldSuccess-8 5232265 229.1 ns/op 56 B/op 3 allocs/op
+BenchmarkStructSimpleCrossFieldSuccessParallel-8 17436674 64.75 ns/op 56 B/op 3 allocs/op
+BenchmarkStructSimpleCrossFieldFailure-8 3128613 383.6 ns/op 272 B/op 8 allocs/op
+BenchmarkStructSimpleCrossFieldFailureParallel-8 6994113 168.8 ns/op 272 B/op 8 allocs/op
+BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 3506487 340.9 ns/op 64 B/op 4 allocs/op
+BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 13431300 91.77 ns/op 64 B/op 4 allocs/op
+BenchmarkStructSimpleCrossStructCrossFieldFailure-8 2410566 500.9 ns/op 288 B/op 9 allocs/op
+BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 6344510 188.2 ns/op 288 B/op 9 allocs/op
+BenchmarkStructSimpleSuccess-8 8922726 133.8 ns/op 0 B/op 0 allocs/op
+BenchmarkStructSimpleSuccessParallel-8 55291153 23.63 ns/op 0 B/op 0 allocs/op
+BenchmarkStructSimpleFailure-8 3171553 378.4 ns/op 416 B/op 9 allocs/op
+BenchmarkStructSimpleFailureParallel-8 5571692 212.0 ns/op 416 B/op 9 allocs/op
+BenchmarkStructComplexSuccess-8 1683750 714.5 ns/op 224 B/op 5 allocs/op
+BenchmarkStructComplexSuccessParallel-8 4578046 257.0 ns/op 224 B/op 5 allocs/op
+BenchmarkStructComplexFailure-8 481585 2547 ns/op 3041 B/op 48 allocs/op
+BenchmarkStructComplexFailureParallel-8 965764 1577 ns/op 3040 B/op 48 allocs/op
+BenchmarkOneof-8 17380881 68.50 ns/op 0 B/op 0 allocs/op
+BenchmarkOneofParallel-8 8084733 153.5 ns/op 0 B/op 0 allocs/op
```
Complementary Software
@@ -295,5 +349,10 @@ How to Contribute
Make a pull request...
License
-------
+-------
Distributed under MIT License, please see license file within the code for more details.
+
+Maintainers
+-----------
+This project has grown large enough that more than one person is required to properly support the community.
+If you are interested in becoming a maintainer please reach out to me https://github.com/deankarn
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 6ce762d152a..95f56e00803 100644
--- a/vendor/github.com/go-playground/validator/v10/baked_in.go
+++ b/vendor/github.com/go-playground/validator/v10/baked_in.go
@@ -7,6 +7,7 @@ import (
"encoding/hex"
"encoding/json"
"fmt"
+ "io/fs"
"net"
"net/url"
"os"
@@ -14,11 +15,14 @@ import (
"strconv"
"strings"
"sync"
+ "syscall"
"time"
"unicode/utf8"
"golang.org/x/crypto/sha3"
+ "golang.org/x/text/language"
+ "github.com/gabriel-vasile/mimetype"
urn "github.com/leodido/go-urn"
)
@@ -30,7 +34,7 @@ type Func func(fl FieldLevel) bool
// validation needs. The return value should be true when validation succeeds.
type FuncCtx func(ctx context.Context, fl FieldLevel) bool
-// wrapFunc wraps noramal Func makes it compatible with FuncCtx
+// wrapFunc wraps normal Func makes it compatible with FuncCtx
func wrapFunc(fn Func) FuncCtx {
if fn == nil {
return nil // be sure not to wrap a bad function.
@@ -47,6 +51,7 @@ var (
endKeysTag: {},
structOnlyTag: {},
omitempty: {},
+ omitnil: {},
skipValidationTag: {},
utf8HexComma: {},
utf8Pipe: {},
@@ -55,7 +60,7 @@ var (
isdefault: {},
}
- // BakedInAliasValidators is a default mapping of a single validation tag that
+ // bakedInAliases is a default mapping of a single validation tag that
// defines a common or complex set of validation(s) to simplify
// adding validation to structs.
bakedInAliases = map[string]string{
@@ -63,136 +68,178 @@ var (
"country_code": "iso3166_1_alpha2|iso3166_1_alpha3|iso3166_1_alpha_numeric",
}
- // BakedInValidators is the default map of ValidationFunc
+ // bakedInValidators is the default map of ValidationFunc
// you can add, remove or even replace items to suite your needs,
// or even disregard and use your own map if so desired.
bakedInValidators = map[string]Func{
- "required": hasValue,
- "required_if": requiredIf,
- "required_unless": requiredUnless,
- "required_with": requiredWith,
- "required_with_all": requiredWithAll,
- "required_without": requiredWithout,
- "required_without_all": requiredWithoutAll,
- "excluded_with": excludedWith,
- "excluded_with_all": excludedWithAll,
- "excluded_without": excludedWithout,
- "excluded_without_all": excludedWithoutAll,
- "isdefault": isDefault,
- "len": hasLengthOf,
- "min": hasMinOf,
- "max": hasMaxOf,
- "eq": isEq,
- "ne": isNe,
- "lt": isLt,
- "lte": isLte,
- "gt": isGt,
- "gte": isGte,
- "eqfield": isEqField,
- "eqcsfield": isEqCrossStructField,
- "necsfield": isNeCrossStructField,
- "gtcsfield": isGtCrossStructField,
- "gtecsfield": isGteCrossStructField,
- "ltcsfield": isLtCrossStructField,
- "ltecsfield": isLteCrossStructField,
- "nefield": isNeField,
- "gtefield": isGteField,
- "gtfield": isGtField,
- "ltefield": isLteField,
- "ltfield": isLtField,
- "fieldcontains": fieldContains,
- "fieldexcludes": fieldExcludes,
- "alpha": isAlpha,
- "alphanum": isAlphanum,
- "alphaunicode": isAlphaUnicode,
- "alphanumunicode": isAlphanumUnicode,
- "numeric": isNumeric,
- "number": isNumber,
- "hexadecimal": isHexadecimal,
- "hexcolor": isHEXColor,
- "rgb": isRGB,
- "rgba": isRGBA,
- "hsl": isHSL,
- "hsla": isHSLA,
- "e164": isE164,
- "email": isEmail,
- "url": isURL,
- "uri": isURI,
- "urn_rfc2141": isUrnRFC2141, // RFC 2141
- "file": isFile,
- "base64": isBase64,
- "base64url": isBase64URL,
- "contains": contains,
- "containsany": containsAny,
- "containsrune": containsRune,
- "excludes": excludes,
- "excludesall": excludesAll,
- "excludesrune": excludesRune,
- "startswith": startsWith,
- "endswith": endsWith,
- "startsnotwith": startsNotWith,
- "endsnotwith": endsNotWith,
- "isbn": isISBN,
- "isbn10": isISBN10,
- "isbn13": isISBN13,
- "eth_addr": isEthereumAddress,
- "btc_addr": isBitcoinAddress,
- "btc_addr_bech32": isBitcoinBech32Address,
- "uuid": isUUID,
- "uuid3": isUUID3,
- "uuid4": isUUID4,
- "uuid5": isUUID5,
- "uuid_rfc4122": isUUIDRFC4122,
- "uuid3_rfc4122": isUUID3RFC4122,
- "uuid4_rfc4122": isUUID4RFC4122,
- "uuid5_rfc4122": isUUID5RFC4122,
- "ascii": isASCII,
- "printascii": isPrintableASCII,
- "multibyte": hasMultiByteCharacter,
- "datauri": isDataURI,
- "latitude": isLatitude,
- "longitude": isLongitude,
- "ssn": isSSN,
- "ipv4": isIPv4,
- "ipv6": isIPv6,
- "ip": isIP,
- "cidrv4": isCIDRv4,
- "cidrv6": isCIDRv6,
- "cidr": isCIDR,
- "tcp4_addr": isTCP4AddrResolvable,
- "tcp6_addr": isTCP6AddrResolvable,
- "tcp_addr": isTCPAddrResolvable,
- "udp4_addr": isUDP4AddrResolvable,
- "udp6_addr": isUDP6AddrResolvable,
- "udp_addr": isUDPAddrResolvable,
- "ip4_addr": isIP4AddrResolvable,
- "ip6_addr": isIP6AddrResolvable,
- "ip_addr": isIPAddrResolvable,
- "unix_addr": isUnixAddrResolvable,
- "mac": isMAC,
- "hostname": isHostnameRFC952, // RFC 952
- "hostname_rfc1123": isHostnameRFC1123, // RFC 1123
- "fqdn": isFQDN,
- "unique": isUnique,
- "oneof": isOneOf,
- "html": isHTML,
- "html_encoded": isHTMLEncoded,
- "url_encoded": isURLEncoded,
- "dir": isDir,
- "json": isJSON,
- "hostname_port": isHostnamePort,
- "lowercase": isLowercase,
- "uppercase": isUppercase,
- "datetime": isDatetime,
- "timezone": isTimeZone,
- "iso3166_1_alpha2": isIso3166Alpha2,
- "iso3166_1_alpha3": isIso3166Alpha3,
- "iso3166_1_alpha_numeric": isIso3166AlphaNumeric,
+ "required": hasValue,
+ "required_if": requiredIf,
+ "required_unless": requiredUnless,
+ "skip_unless": skipUnless,
+ "required_with": requiredWith,
+ "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,
+ "excluded_without_all": excludedWithoutAll,
+ "isdefault": isDefault,
+ "len": hasLengthOf,
+ "min": hasMinOf,
+ "max": hasMaxOf,
+ "eq": isEq,
+ "eq_ignore_case": isEqIgnoreCase,
+ "ne": isNe,
+ "ne_ignore_case": isNeIgnoreCase,
+ "lt": isLt,
+ "lte": isLte,
+ "gt": isGt,
+ "gte": isGte,
+ "eqfield": isEqField,
+ "eqcsfield": isEqCrossStructField,
+ "necsfield": isNeCrossStructField,
+ "gtcsfield": isGtCrossStructField,
+ "gtecsfield": isGteCrossStructField,
+ "ltcsfield": isLtCrossStructField,
+ "ltecsfield": isLteCrossStructField,
+ "nefield": isNeField,
+ "gtefield": isGteField,
+ "gtfield": isGtField,
+ "ltefield": isLteField,
+ "ltfield": isLtField,
+ "fieldcontains": fieldContains,
+ "fieldexcludes": fieldExcludes,
+ "alpha": isAlpha,
+ "alphanum": isAlphanum,
+ "alphaunicode": isAlphaUnicode,
+ "alphanumunicode": isAlphanumUnicode,
+ "boolean": isBoolean,
+ "numeric": isNumeric,
+ "number": isNumber,
+ "hexadecimal": isHexadecimal,
+ "hexcolor": isHEXColor,
+ "rgb": isRGB,
+ "rgba": isRGBA,
+ "hsl": isHSL,
+ "hsla": isHSLA,
+ "e164": isE164,
+ "email": isEmail,
+ "url": isURL,
+ "http_url": isHttpURL,
+ "uri": isURI,
+ "urn_rfc2141": isUrnRFC2141, // RFC 2141
+ "file": isFile,
+ "filepath": isFilePath,
+ "base64": isBase64,
+ "base64url": isBase64URL,
+ "base64rawurl": isBase64RawURL,
+ "contains": contains,
+ "containsany": containsAny,
+ "containsrune": containsRune,
+ "excludes": excludes,
+ "excludesall": excludesAll,
+ "excludesrune": excludesRune,
+ "startswith": startsWith,
+ "endswith": endsWith,
+ "startsnotwith": startsNotWith,
+ "endsnotwith": endsNotWith,
+ "image": isImage,
+ "isbn": isISBN,
+ "isbn10": isISBN10,
+ "isbn13": isISBN13,
+ "issn": isISSN,
+ "eth_addr": isEthereumAddress,
+ "eth_addr_checksum": isEthereumAddressChecksum,
+ "btc_addr": isBitcoinAddress,
+ "btc_addr_bech32": isBitcoinBech32Address,
+ "uuid": isUUID,
+ "uuid3": isUUID3,
+ "uuid4": isUUID4,
+ "uuid5": isUUID5,
+ "uuid_rfc4122": isUUIDRFC4122,
+ "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,
+ "datauri": isDataURI,
+ "latitude": isLatitude,
+ "longitude": isLongitude,
+ "ssn": isSSN,
+ "ipv4": isIPv4,
+ "ipv6": isIPv6,
+ "ip": isIP,
+ "cidrv4": isCIDRv4,
+ "cidrv6": isCIDRv6,
+ "cidr": isCIDR,
+ "tcp4_addr": isTCP4AddrResolvable,
+ "tcp6_addr": isTCP6AddrResolvable,
+ "tcp_addr": isTCPAddrResolvable,
+ "udp4_addr": isUDP4AddrResolvable,
+ "udp6_addr": isUDP6AddrResolvable,
+ "udp_addr": isUDPAddrResolvable,
+ "ip4_addr": isIP4AddrResolvable,
+ "ip6_addr": isIP6AddrResolvable,
+ "ip_addr": isIPAddrResolvable,
+ "unix_addr": isUnixAddrResolvable,
+ "mac": isMAC,
+ "hostname": isHostnameRFC952, // RFC 952
+ "hostname_rfc1123": isHostnameRFC1123, // RFC 1123
+ "fqdn": isFQDN,
+ "unique": isUnique,
+ "oneof": isOneOf,
+ "html": isHTML,
+ "html_encoded": isHTMLEncoded,
+ "url_encoded": isURLEncoded,
+ "dir": isDir,
+ "dirpath": isDirPath,
+ "json": isJSON,
+ "jwt": isJWT,
+ "hostname_port": isHostnamePort,
+ "lowercase": isLowercase,
+ "uppercase": isUppercase,
+ "datetime": isDatetime,
+ "timezone": isTimeZone,
+ "iso3166_1_alpha2": isIso3166Alpha2,
+ "iso3166_1_alpha3": isIso3166Alpha3,
+ "iso3166_1_alpha_numeric": isIso3166AlphaNumeric,
+ "iso3166_2": isIso31662,
+ "iso4217": isIso4217,
+ "iso4217_numeric": isIso4217Numeric,
+ "bcp47_language_tag": isBCP47LanguageTag,
+ "postcode_iso3166_alpha2": isPostcodeByIso3166Alpha2,
+ "postcode_iso3166_alpha2_field": isPostcodeByIso3166Alpha2Field,
+ "bic": isIsoBicFormat,
+ "semver": isSemverFormat,
+ "dns_rfc1035_label": isDnsRFC1035LabelFormat,
+ "credit_card": isCreditCard,
+ "cve": isCveFormat,
+ "luhn_checksum": hasLuhnChecksum,
+ "mongodb": isMongoDB,
+ "cron": isCron,
+ "spicedb": isSpiceDB,
}
)
-var oneofValsCache = map[string][]string{}
-var oneofValsCacheRWLock = sync.RWMutex{}
+var (
+ oneofValsCache = map[string][]string{}
+ oneofValsCacheRWLock = sync.RWMutex{}
+)
func parseOneOfParam2(s string) []string {
oneofValsCacheRWLock.RLock()
@@ -248,7 +295,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{}{})
@@ -280,81 +326,97 @@ func isUnique(fl FieldLevel) bool {
}
m := reflect.MakeMap(reflect.MapOf(sfTyp, v.Type()))
+ var fieldlen int
for i := 0; i < field.Len(); i++ {
- m.SetMapIndex(reflect.Indirect(reflect.Indirect(field.Index(i)).FieldByName(param)), v)
+ key := reflect.Indirect(reflect.Indirect(field.Index(i)).FieldByName(param))
+ if key.IsValid() {
+ fieldlen++
+ m.SetMapIndex(key, v)
+ }
}
- return field.Len() == m.Len()
+ return fieldlen == m.Len()
case reflect.Map:
- m := reflect.MakeMap(reflect.MapOf(field.Type().Elem(), v.Type()))
+ var m reflect.Value
+ if field.Type().Elem().Kind() == reflect.Ptr {
+ m = reflect.MakeMap(reflect.MapOf(field.Type().Elem().Elem(), v.Type()))
+ } else {
+ m = reflect.MakeMap(reflect.MapOf(field.Type().Elem(), v.Type()))
+ }
for _, k := range field.MapKeys() {
- m.SetMapIndex(field.MapIndex(k), v)
+ m.SetMapIndex(reflect.Indirect(field.MapIndex(k)), v)
}
+
return field.Len() == m.Len()
default:
+ if parent := fl.Parent(); parent.Kind() == reflect.Struct {
+ uniqueField := parent.FieldByName(param)
+ if uniqueField == reflect.ValueOf(nil) {
+ panic(fmt.Sprintf("Bad field name provided %s", param))
+ }
+
+ if uniqueField.Kind() != field.Kind() {
+ panic(fmt.Sprintf("Bad field type %T:%T", field.Interface(), uniqueField.Interface()))
+ }
+
+ return field.Interface() != uniqueField.Interface()
+ }
+
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}
}
-// IsMAC is the validation function for validating if the field's value is a valid MAC address.
+// 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
}
-// IsCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address.
+// isCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address.
func isCIDRv4(fl FieldLevel) bool {
+ ip, net, err := net.ParseCIDR(fl.Field().String())
- ip, _, err := net.ParseCIDR(fl.Field().String())
-
- return err == nil && ip.To4() != nil
+ return err == nil && ip.To4() != nil && net.IP.Equal(ip)
}
-// IsCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address.
+// 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
}
-// IsCIDR is the validation function for validating if the field's value is a valid v4 or v6 CIDR address.
+// 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
}
-// IsIPv4 is the validation function for validating if a value is a valid v4 IP address.
+// 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
}
-// IsIPv6 is the validation function for validating if the field's value is a valid v6 IP address.
+// 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
}
-// IsIP is the validation function for validating if the field's value is a valid v4 or v6 IP address.
+// 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
}
-// IsSSN is the validation function for validating if the field's value is a valid SSN.
+// 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 {
@@ -364,7 +426,7 @@ func isSSN(fl FieldLevel) bool {
return sSNRegex.MatchString(field.String())
}
-// IsLongitude is the validation function for validating if the field's value is a valid longitude coordinate.
+// isLongitude is the validation function for validating if the field's value is a valid longitude coordinate.
func isLongitude(fl FieldLevel) bool {
field := fl.Field()
@@ -387,7 +449,7 @@ func isLongitude(fl FieldLevel) bool {
return longitudeRegex.MatchString(v)
}
-// IsLatitude is the validation function for validating if the field's value is a valid latitude coordinate.
+// isLatitude is the validation function for validating if the field's value is a valid latitude coordinate.
func isLatitude(fl FieldLevel) bool {
field := fl.Field()
@@ -410,9 +472,8 @@ func isLatitude(fl FieldLevel) bool {
return latitudeRegex.MatchString(v)
}
-// IsDataURI is the validation function for validating if the field's value is a valid data URI.
+// 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 {
@@ -426,9 +487,8 @@ func isDataURI(fl FieldLevel) bool {
return base64Regex.MatchString(uri[1])
}
-// HasMultiByteCharacter is the validation function for validating if the field's value has a multi byte character.
+// 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 {
@@ -438,64 +498,118 @@ func hasMultiByteCharacter(fl FieldLevel) bool {
return multibyteRegex.MatchString(field.String())
}
-// IsPrintableASCII is the validation function for validating if the field's value is a valid printable ASCII character.
+// isPrintableASCII is the validation function for validating if the field's value is a valid printable ASCII character.
func isPrintableASCII(fl FieldLevel) bool {
return printableASCIIRegex.MatchString(fl.Field().String())
}
-// IsASCII is the validation function for validating if the field's value is a valid ASCII character.
+// isASCII is the validation function for validating if the field's value is a valid ASCII character.
func isASCII(fl FieldLevel) bool {
return aSCIIRegex.MatchString(fl.Field().String())
}
-// IsUUID5 is the validation function for validating if the field's value is a valid v5 UUID.
+// isUUID5 is the validation function for validating if the field's value is a valid v5 UUID.
func isUUID5(fl FieldLevel) bool {
- return uUID5Regex.MatchString(fl.Field().String())
+ return fieldMatchesRegexByStringerValOrString(uUID5Regex, fl)
}
-// IsUUID4 is the validation function for validating if the field's value is a valid v4 UUID.
+// isUUID4 is the validation function for validating if the field's value is a valid v4 UUID.
func isUUID4(fl FieldLevel) bool {
- return uUID4Regex.MatchString(fl.Field().String())
+ return fieldMatchesRegexByStringerValOrString(uUID4Regex, fl)
}
-// IsUUID3 is the validation function for validating if the field's value is a valid v3 UUID.
+// isUUID3 is the validation function for validating if the field's value is a valid v3 UUID.
func isUUID3(fl FieldLevel) bool {
- return uUID3Regex.MatchString(fl.Field().String())
+ return fieldMatchesRegexByStringerValOrString(uUID3Regex, fl)
}
-// IsUUID is the validation function for validating if the field's value is a valid UUID of any version.
+// isUUID is the validation function for validating if the field's value is a valid UUID of any version.
func isUUID(fl FieldLevel) bool {
- return uUIDRegex.MatchString(fl.Field().String())
+ return fieldMatchesRegexByStringerValOrString(uUIDRegex, fl)
}
-// IsUUID5RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v5 UUID.
+// isUUID5RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v5 UUID.
func isUUID5RFC4122(fl FieldLevel) bool {
- return uUID5RFC4122Regex.MatchString(fl.Field().String())
+ return fieldMatchesRegexByStringerValOrString(uUID5RFC4122Regex, fl)
}
-// IsUUID4RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v4 UUID.
+// isUUID4RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v4 UUID.
func isUUID4RFC4122(fl FieldLevel) bool {
- return uUID4RFC4122Regex.MatchString(fl.Field().String())
+ return fieldMatchesRegexByStringerValOrString(uUID4RFC4122Regex, fl)
}
-// IsUUID3RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v3 UUID.
+// isUUID3RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v3 UUID.
func isUUID3RFC4122(fl FieldLevel) bool {
- return uUID3RFC4122Regex.MatchString(fl.Field().String())
+ return fieldMatchesRegexByStringerValOrString(uUID3RFC4122Regex, fl)
}
-// IsUUIDRFC4122 is the validation function for validating if the field's value is a valid RFC4122 UUID of any version.
+// isUUIDRFC4122 is the validation function for validating if the field's value is a valid RFC4122 UUID of any version.
func isUUIDRFC4122(fl FieldLevel) bool {
- return uUIDRFC4122Regex.MatchString(fl.Field().String())
+ return fieldMatchesRegexByStringerValOrString(uUIDRFC4122Regex, fl)
+}
+
+// isULID is the validation function for validating if the field's value is a valid ULID.
+func isULID(fl FieldLevel) bool {
+ return fieldMatchesRegexByStringerValOrString(uLIDRegex, fl)
+}
+
+// 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())
}
-// IsISBN is the validation function for validating if the field's value is a valid v10 or v13 ISBN.
+// 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)
}
-// IsISBN13 is the validation function for validating if the field's value is a valid v13 ISBN.
+// 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) {
@@ -514,9 +628,8 @@ func isISBN13(fl FieldLevel) bool {
return (int32(s[12]-'0'))-((10-(checksum%10))%10) == 0
}
-// IsISBN10 is the validation function for validating if the field's value is a valid v10 ISBN.
+// 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) {
@@ -539,18 +652,46 @@ func isISBN10(fl FieldLevel) bool {
return checksum%11 == 0
}
-// IsEthereumAddress is the validation function for validating if the field's value is a valid Ethereum address.
-func isEthereumAddress(fl FieldLevel) bool {
- address := fl.Field().String()
+// isISSN is the validation function for validating if the field's value is a valid ISSN.
+func isISSN(fl FieldLevel) bool {
+ s := fl.Field().String()
- if !ethAddressRegex.MatchString(address) {
+ if !iSSNRegex.MatchString(s) {
return false
}
+ s = strings.ReplaceAll(s, "-", "")
- if ethaddressRegexUpper.MatchString(address) || ethAddressRegexLower.MatchString(address) {
- return true
+ pos := 8
+ checksum := 0
+
+ for i := 0; i < 7; i++ {
+ checksum += pos * int(s[i]-'0')
+ pos--
+ }
+
+ if s[7] == 'X' {
+ checksum += 10
+ } else {
+ checksum += int(s[7] - '0')
}
+ return checksum%11 == 0
+}
+
+// isEthereumAddress is the validation function for validating if the field's value is a valid Ethereum address.
+func isEthereumAddress(fl FieldLevel) bool {
+ address := fl.Field().String()
+
+ return ethAddressRegex.MatchString(address)
+}
+
+// isEthereumAddressChecksum is the validation function for validating if the field's value is a valid checksumed Ethereum address.
+func isEthereumAddressChecksum(fl FieldLevel) bool {
+ address := fl.Field().String()
+
+ if !ethAddressRegex.MatchString(address) {
+ return false
+ }
// Checksum validation. Reference: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md
address = address[2:] // Skip "0x" prefix.
h := sha3.NewLegacyKeccak256()
@@ -570,7 +711,7 @@ func isEthereumAddress(fl FieldLevel) bool {
return true
}
-// IsBitcoinAddress is the validation function for validating if the field's value is a valid btc address
+// isBitcoinAddress is the validation function for validating if the field's value is a valid btc address
func isBitcoinAddress(fl FieldLevel) bool {
address := fl.Field().String()
@@ -607,7 +748,7 @@ func isBitcoinAddress(fl FieldLevel) bool {
return validchecksum == computedchecksum
}
-// IsBitcoinBech32Address is the validation function for validating if the field's value is a valid bech32 btc address
+// isBitcoinBech32Address is the validation function for validating if the field's value is a valid bech32 btc address
func isBitcoinBech32Address(fl FieldLevel) bool {
address := fl.Field().String()
@@ -687,60 +828,59 @@ func isBitcoinBech32Address(fl FieldLevel) bool {
return true
}
-// ExcludesRune is the validation function for validating that the field's value does not contain the rune specified within the param.
+// excludesRune is the validation function for validating that the field's value does not contain the rune specified within the param.
func excludesRune(fl FieldLevel) bool {
return !containsRune(fl)
}
-// ExcludesAll is the validation function for validating that the field's value does not contain any of the characters specified within the param.
+// excludesAll is the validation function for validating that the field's value does not contain any of the characters specified within the param.
func excludesAll(fl FieldLevel) bool {
return !containsAny(fl)
}
-// Excludes is the validation function for validating that the field's value does not contain the text specified within the param.
+// excludes is the validation function for validating that the field's value does not contain the text specified within the param.
func excludes(fl FieldLevel) bool {
return !contains(fl)
}
-// ContainsRune is the validation function for validating that the field's value contains the rune specified within the param.
+// 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)
}
-// ContainsAny is the validation function for validating that the field's value contains any of the characters specified within the param.
+// containsAny is the validation function for validating that the field's value contains any of the characters specified within the param.
func containsAny(fl FieldLevel) bool {
return strings.ContainsAny(fl.Field().String(), fl.Param())
}
-// Contains is the validation function for validating that the field's value contains the text specified within the param.
+// contains is the validation function for validating that the field's value contains the text specified within the param.
func contains(fl FieldLevel) bool {
return strings.Contains(fl.Field().String(), fl.Param())
}
-// StartsWith is the validation function for validating that the field's value starts with the text specified within the param.
+// startsWith is the validation function for validating that the field's value starts with the text specified within the param.
func startsWith(fl FieldLevel) bool {
return strings.HasPrefix(fl.Field().String(), fl.Param())
}
-// EndsWith is the validation function for validating that the field's value ends with the text specified within the param.
+// endsWith is the validation function for validating that the field's value ends with the text specified within the param.
func endsWith(fl FieldLevel) bool {
return strings.HasSuffix(fl.Field().String(), fl.Param())
}
-// StartsNotWith is the validation function for validating that the field's value does not start with the text specified within the param.
+// startsNotWith is the validation function for validating that the field's value does not start with the text specified within the param.
func startsNotWith(fl FieldLevel) bool {
return !startsWith(fl)
}
-// EndsNotWith is the validation function for validating that the field's value does not end with the text specified within the param.
+// endsNotWith is the validation function for validating that the field's value does not end with the text specified within the param.
func endsNotWith(fl FieldLevel) bool {
return !endsWith(fl)
}
-// FieldContains is the validation function for validating if the current field's value contains the field specified by the param's value.
+// fieldContains is the validation function for validating if the current field's value contains the field specified by the param's value.
func fieldContains(fl FieldLevel) bool {
field := fl.Field()
@@ -753,7 +893,7 @@ func fieldContains(fl FieldLevel) bool {
return strings.Contains(field.String(), currentField.String())
}
-// FieldExcludes is the validation function for validating if the current field's value excludes the field specified by the param's value.
+// fieldExcludes is the validation function for validating if the current field's value excludes the field specified by the param's value.
func fieldExcludes(fl FieldLevel) bool {
field := fl.Field()
@@ -765,9 +905,8 @@ func fieldExcludes(fl FieldLevel) bool {
return !strings.Contains(field.String(), currentField.String())
}
-// 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.
+// 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()
@@ -791,16 +930,14 @@ func isNeField(fl FieldLevel) bool {
case reflect.Slice, reflect.Map, reflect.Array:
return int64(field.Len()) != int64(currentField.Len())
+ case reflect.Bool:
+ return field.Bool() != currentField.Bool()
+
case reflect.Struct:
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)
@@ -808,20 +945,29 @@ 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:
return field.String() != currentField.String()
}
-// IsNe is the validation function for validating that the field's value does not equal the provided param value.
+// isNe is the validation function for validating that the field's value does not equal the provided param value.
func isNe(fl FieldLevel) bool {
return !isEq(fl)
}
-// 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 {
+// isNeIgnoreCase is the validation function for validating that the field's string value does not equal the
+// provided param value. The comparison is case-insensitive
+func isNeIgnoreCase(fl FieldLevel) bool {
+ return !isEqIgnoreCase(fl)
+}
+// 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()
@@ -848,28 +994,27 @@ 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:
return field.String() <= topField.String()
}
-// 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.
+// 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()
@@ -896,27 +1041,26 @@ 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:
return field.String() < topField.String()
}
-// 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.
+// 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()
@@ -943,27 +1087,26 @@ 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:
return field.String() >= topField.String()
}
-// 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.
+// 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()
@@ -990,27 +1133,26 @@ 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:
return field.String() > topField.String()
}
-// 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.
+// 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()
@@ -1033,31 +1175,33 @@ func isNeCrossStructField(fl FieldLevel) bool {
case reflect.Slice, reflect.Map, reflect.Array:
return int64(topField.Len()) != int64(field.Len())
+ case reflect.Bool:
+ return topField.Bool() != field.Bool()
+
case reflect.Struct:
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:
return topField.String() != field.String()
}
-// 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.
+// 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()
@@ -1080,31 +1224,33 @@ func isEqCrossStructField(fl FieldLevel) bool {
case reflect.Slice, reflect.Map, reflect.Array:
return int64(topField.Len()) == int64(field.Len())
+ case reflect.Bool:
+ return topField.Bool() == field.Bool()
+
case reflect.Struct:
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) {
- 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:
return topField.String() == field.String()
}
-// IsEqField is the validation function for validating if the current field's value is equal to the field specified by the param's value.
+// 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()
@@ -1127,32 +1273,33 @@ func isEqField(fl FieldLevel) bool {
case reflect.Slice, reflect.Map, reflect.Array:
return int64(field.Len()) == int64(currentField.Len())
+ case reflect.Bool:
+ return field.Bool() == currentField.Bool()
+
case reflect.Struct:
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.Equal(t)
}
+ // Not Same underlying type i.e. struct and time
+ if fieldType != currentField.Type() {
+ return false
+ }
}
// default reflect.String:
return field.String() == currentField.String()
}
-// IsEq is the validation function for validating if the current field's value is equal to the param's value.
+// 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()
@@ -1176,8 +1323,13 @@ func isEq(fl FieldLevel) bool {
return field.Uint() == p
- case reflect.Float32, reflect.Float64:
- p := asFloat(param)
+ case reflect.Float32:
+ p := asFloat32(param)
+
+ return field.Float() == p
+
+ case reflect.Float64:
+ p := asFloat64(param)
return field.Float() == p
@@ -1190,23 +1342,83 @@ func isEq(fl FieldLevel) bool {
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}
-// IsBase64 is the validation function for validating if the current field's value is a valid base 64.
+// isEqIgnoreCase is the validation function for validating if the current field's string value is
+// equal to the param's value.
+// The comparison is case-insensitive.
+func isEqIgnoreCase(fl FieldLevel) bool {
+ field := fl.Field()
+ param := fl.Param()
+
+ switch field.Kind() {
+
+ case reflect.String:
+ return strings.EqualFold(field.String(), param)
+ }
+
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+}
+
+// isPostcodeByIso3166Alpha2 validates by value which is country code in iso 3166 alpha 2
+// example: `postcode_iso3166_alpha2=US`
+func isPostcodeByIso3166Alpha2(fl FieldLevel) bool {
+ field := fl.Field()
+ param := fl.Param()
+
+ reg, found := postCodeRegexDict[param]
+ if !found {
+ return false
+ }
+
+ return reg.MatchString(field.String())
+}
+
+// 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()
+ params := parseOneOfParam2(fl.Param())
+
+ if len(params) != 1 {
+ return false
+ }
+
+ currentField, kind, _, found := fl.GetStructFieldOKAdvanced2(fl.Parent(), params[0])
+ if !found {
+ return false
+ }
+
+ if kind != reflect.String {
+ panic(fmt.Sprintf("Bad field type %T", currentField.Interface()))
+ }
+
+ reg, found := postCodeRegexDict[currentField.String()]
+ if !found {
+ return false
+ }
+
+ return reg.MatchString(field.String())
+}
+
+// isBase64 is the validation function for validating if the current field's value is a valid base 64.
func isBase64(fl FieldLevel) bool {
return base64Regex.MatchString(fl.Field().String())
}
-// IsBase64URL is the validation function for validating if the current field's value is a valid base64 URL safe string.
+// isBase64URL is the validation function for validating if the current field's value is a valid base64 URL safe string.
func isBase64URL(fl FieldLevel) bool {
return base64URLRegex.MatchString(fl.Field().String())
}
-// IsURI is the validation function for validating if the current field's value is a valid URI.
-func isURI(fl FieldLevel) bool {
+// isBase64RawURL is the validation function for validating if the current field's value is a valid base64 URL safe string without '=' padding.
+func isBase64RawURL(fl FieldLevel) bool {
+ return base64RawURLRegex.MatchString(fl.Field().String())
+}
+// 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()
@@ -1229,46 +1441,75 @@ func isURI(fl FieldLevel) bool {
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}
-// IsURL is the validation function for validating if the current field's value is a valid URL.
-func isURL(fl FieldLevel) bool {
+// isFileURL is the helper function for validating if the `path` valid file URL as per RFC8089
+func isFileURL(path string) bool {
+ if !strings.HasPrefix(path, "file:/") {
+ return false
+ }
+ _, err := url.ParseRequestURI(path)
+ return err == nil
+}
+// 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
- s := field.String()
-
- // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195
- // emulate browser and strip the '#' suffix prior to validation. see issue-#237
- if i = strings.Index(s, "#"); i > -1 {
- s = s[:i]
- }
+ s := strings.ToLower(field.String())
if len(s) == 0 {
return false
}
- url, err := url.ParseRequestURI(s)
+ if isFileURL(s) {
+ return true
+ }
+ url, err := url.Parse(s)
if err != nil || url.Scheme == "" {
return false
}
+ if url.Host == "" && url.Fragment == "" && url.Opaque == "" {
+ return false
+ }
+
return true
}
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}
+// isHttpURL is the validation function for validating if the current field's value is a valid HTTP(s) URL.
+func isHttpURL(fl FieldLevel) bool {
+ if !isURL(fl) {
+ return false
+ }
+
+ field := fl.Field()
+ switch field.Kind() {
+ case reflect.String:
+
+ s := strings.ToLower(field.String())
+
+ url, err := url.Parse(s)
+ if err != nil || url.Host == "" {
+ return false
+ }
+
+ return url.Scheme == "http" || url.Scheme == "https"
+ }
+
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+}
+
// isUrnRFC2141 is the validation function for validating if the current field's value is a valid URN as per RFC 2141.
func isUrnRFC2141(fl FieldLevel) bool {
field := fl.Field()
switch field.Kind() {
-
case reflect.String:
str := field.String()
@@ -1281,7 +1522,7 @@ func isUrnRFC2141(fl FieldLevel) bool {
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}
-// IsFile is the validation function for validating if the current field's value is a valid file path.
+// isFile is the validation function for validating if the current field's value is a valid existing file path.
func isFile(fl FieldLevel) bool {
field := fl.Field()
@@ -1298,47 +1539,163 @@ func isFile(fl FieldLevel) bool {
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}
-// IsE164 is the validation function for validating if the current field's value is a valid e.164 formatted phone number.
+// isImage is the validation function for validating if the current field's value contains the path to a valid image file
+func isImage(fl FieldLevel) bool {
+ mimetypes := map[string]bool{
+ "image/bmp": true,
+ "image/cis-cod": true,
+ "image/gif": true,
+ "image/ief": true,
+ "image/jpeg": true,
+ "image/jp2": true,
+ "image/jpx": true,
+ "image/jpm": true,
+ "image/pipeg": true,
+ "image/png": true,
+ "image/svg+xml": true,
+ "image/tiff": true,
+ "image/webp": true,
+ "image/x-cmu-raster": true,
+ "image/x-cmx": true,
+ "image/x-icon": true,
+ "image/x-portable-anymap": true,
+ "image/x-portable-bitmap": true,
+ "image/x-portable-graymap": true,
+ "image/x-portable-pixmap": true,
+ "image/x-rgb": true,
+ "image/x-xbitmap": true,
+ "image/x-xpixmap": true,
+ "image/x-xwindowdump": true,
+ }
+ field := fl.Field()
+
+ switch field.Kind() {
+ case reflect.String:
+ filePath := field.String()
+ fileInfo, err := os.Stat(filePath)
+
+ if err != nil {
+ return false
+ }
+
+ if fileInfo.IsDir() {
+ return false
+ }
+
+ file, err := os.Open(filePath)
+ if err != nil {
+ return false
+ }
+ defer file.Close()
+
+ mime, err := mimetype.DetectReader(file)
+ if err != nil {
+ return false
+ }
+
+ if _, ok := mimetypes[mime.String()]; ok {
+ return true
+ }
+ }
+ return false
+}
+
+// isFilePath is the validation function for validating if the current field's value is a valid file path.
+func isFilePath(fl FieldLevel) bool {
+
+ var exists bool
+ var err error
+
+ field := fl.Field()
+
+ // Not valid if it is a directory.
+ if isDir(fl) {
+ return false
+ }
+ // If it exists, it obviously is valid.
+ // This is done first to avoid code duplication and unnecessary additional logic.
+ if exists = isFile(fl); exists {
+ return true
+ }
+
+ // It does not exist but may still be a valid filepath.
+ switch field.Kind() {
+ case reflect.String:
+ // Every OS allows for whitespace, but none
+ // let you use a file with no filename (to my knowledge).
+ // Unless you're dealing with raw inodes, but I digress.
+ if strings.TrimSpace(field.String()) == "" {
+ return false
+ }
+ // We make sure it isn't a directory.
+ if strings.HasSuffix(field.String(), string(os.PathSeparator)) {
+ return false
+ }
+ if _, err = os.Stat(field.String()); err != nil {
+ switch t := err.(type) {
+ case *fs.PathError:
+ if t.Err == syscall.EINVAL {
+ // It's definitely an invalid character in the filepath.
+ return false
+ }
+ // It could be a permission error, a does-not-exist error, etc.
+ // Out-of-scope for this validation, though.
+ return true
+ default:
+ // Something went *seriously* wrong.
+ /*
+ Per https://pkg.go.dev/os#Stat:
+ "If there is an error, it will be of type *PathError."
+ */
+ panic(err)
+ }
+ }
+ }
+
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+}
+
+// isE164 is the validation function for validating if the current field's value is a valid e.164 formatted phone number.
func isE164(fl FieldLevel) bool {
return e164Regex.MatchString(fl.Field().String())
}
-// IsEmail is the validation function for validating if the current field's value is a valid email address.
+// isEmail is the validation function for validating if the current field's value is a valid email address.
func isEmail(fl FieldLevel) bool {
return emailRegex.MatchString(fl.Field().String())
}
-// IsHSLA is the validation function for validating if the current field's value is a valid HSLA color.
+// isHSLA is the validation function for validating if the current field's value is a valid HSLA color.
func isHSLA(fl FieldLevel) bool {
return hslaRegex.MatchString(fl.Field().String())
}
-// IsHSL is the validation function for validating if the current field's value is a valid HSL color.
+// isHSL is the validation function for validating if the current field's value is a valid HSL color.
func isHSL(fl FieldLevel) bool {
return hslRegex.MatchString(fl.Field().String())
}
-// IsRGBA is the validation function for validating if the current field's value is a valid RGBA color.
+// isRGBA is the validation function for validating if the current field's value is a valid RGBA color.
func isRGBA(fl FieldLevel) bool {
return rgbaRegex.MatchString(fl.Field().String())
}
-// IsRGB is the validation function for validating if the current field's value is a valid RGB color.
+// isRGB is the validation function for validating if the current field's value is a valid RGB color.
func isRGB(fl FieldLevel) bool {
return rgbRegex.MatchString(fl.Field().String())
}
-// IsHEXColor is the validation function for validating if the current field's value is a valid HEX color.
+// isHEXColor is the validation function for validating if the current field's value is a valid HEX color.
func isHEXColor(fl FieldLevel) bool {
- return hexcolorRegex.MatchString(fl.Field().String())
+ return hexColorRegex.MatchString(fl.Field().String())
}
-// IsHexadecimal is the validation function for validating if the current field's value is a valid hexadecimal.
+// isHexadecimal is the validation function for validating if the current field's value is a valid hexadecimal.
func isHexadecimal(fl FieldLevel) bool {
return hexadecimalRegex.MatchString(fl.Field().String())
}
-// IsNumber is the validation function for validating if the current field's value is a valid number.
+// isNumber is the validation function for validating if the current field's value is a valid number.
func isNumber(fl FieldLevel) bool {
switch fl.Field().Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64:
@@ -1348,7 +1705,7 @@ func isNumber(fl FieldLevel) bool {
}
}
-// IsNumeric is the validation function for validating if the current field's value is a valid numeric value.
+// isNumeric is the validation function for validating if the current field's value is a valid numeric value.
func isNumeric(fl FieldLevel) bool {
switch fl.Field().Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64:
@@ -1358,32 +1715,43 @@ func isNumeric(fl FieldLevel) bool {
}
}
-// IsAlphanum is the validation function for validating if the current field's value is a valid alphanumeric value.
+// isAlphanum is the validation function for validating if the current field's value is a valid alphanumeric value.
func isAlphanum(fl FieldLevel) bool {
return alphaNumericRegex.MatchString(fl.Field().String())
}
-// IsAlpha is the validation function for validating if the current field's value is a valid alpha value.
+// isAlpha is the validation function for validating if the current field's value is a valid alpha value.
func isAlpha(fl FieldLevel) bool {
return alphaRegex.MatchString(fl.Field().String())
}
-// IsAlphanumUnicode is the validation function for validating if the current field's value is a valid alphanumeric unicode value.
+// isAlphanumUnicode is the validation function for validating if the current field's value is a valid alphanumeric unicode value.
func isAlphanumUnicode(fl FieldLevel) bool {
return alphaUnicodeNumericRegex.MatchString(fl.Field().String())
}
-// IsAlphaUnicode is the validation function for validating if the current field's value is a valid alpha unicode value.
+// isAlphaUnicode is the validation function for validating if the current field's value is a valid alpha unicode value.
func isAlphaUnicode(fl FieldLevel) bool {
return alphaUnicodeRegex.MatchString(fl.Field().String())
}
+// isBoolean is the validation function for validating if the current field's value is a valid boolean value or can be safely converted to a boolean value.
+func isBoolean(fl FieldLevel) bool {
+ switch fl.Field().Kind() {
+ case reflect.Bool:
+ return true
+ default:
+ _, err := strconv.ParseBool(fl.Field().String())
+ return err == nil
+ }
+}
+
// isDefault is the opposite of required aka hasValue
func isDefault(fl FieldLevel) bool {
return !hasValue(fl)
}
-// HasValue is the validation function for validating if the current field's value is not the default static value.
+// hasValue is the validation function for validating if the current field's value is not the default static value.
func hasValue(fl FieldLevel) bool {
field := fl.Field()
switch field.Kind() {
@@ -1393,11 +1761,11 @@ func hasValue(fl FieldLevel) bool {
if fl.(*validate).fldIsPointer && field.Interface() != nil {
return true
}
- return field.IsValid() && field.Interface() != reflect.Zero(field.Type()).Interface()
+ return field.IsValid() && !field.IsZero()
}
}
-// requireCheckField is a func for check field kind
+// requireCheckFieldKind is a func for check field kind
func requireCheckFieldKind(fl FieldLevel, param string, defaultNotFoundValue bool) bool {
field := fl.Field()
kind := field.Kind()
@@ -1417,12 +1785,14 @@ func requireCheckFieldKind(fl FieldLevel, param string, defaultNotFoundValue boo
if nullable && field.Interface() != nil {
return false
}
- return field.IsValid() && field.Interface() == reflect.Zero(field.Type()).Interface()
+ return field.IsValid() && field.IsZero()
}
}
// requireCheckFieldValue is a func for check field value
-func requireCheckFieldValue(fl FieldLevel, param string, value string, defaultNotFoundValue bool) bool {
+func requireCheckFieldValue(
+ fl FieldLevel, param string, value string, defaultNotFoundValue bool,
+) bool {
field, kind, _, found := fl.GetStructFieldOKAdvanced2(fl.Parent(), param)
if !found {
return defaultNotFoundValue
@@ -1436,11 +1806,17 @@ func requireCheckFieldValue(fl FieldLevel, param string, value string, defaultNo
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
return field.Uint() == asUint(value)
- case reflect.Float32, reflect.Float64:
- return field.Float() == asFloat(value)
+ case reflect.Float32:
+ return field.Float() == asFloat32(value)
+
+ case reflect.Float64:
+ return field.Float() == asFloat64(value)
case reflect.Slice, reflect.Map, reflect.Array:
return int64(field.Len()) == asInt(value)
+
+ case reflect.Bool:
+ return field.Bool() == asBool(value)
}
// default reflect.String:
@@ -1462,6 +1838,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 true
+ }
+ }
+ return !hasValue(fl)
+}
+
// 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 {
@@ -1478,7 +1870,37 @@ func requiredUnless(fl FieldLevel) bool {
return hasValue(fl)
}
-// ExcludedWith is the validation function
+// skipUnless 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 skipUnless(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ if len(params)%2 != 0 {
+ panic(fmt.Sprintf("Bad param number for skip_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)
+}
+
+// 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 !hasValue(fl)
+ }
+ }
+ return true
+}
+
+// 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 {
params := parseOneOfParam2(fl.Param())
@@ -1490,7 +1912,7 @@ func excludedWith(fl FieldLevel) bool {
return true
}
-// RequiredWith is the validation function
+// requiredWith is the validation function
// The field under validation must be present and not empty only if any of the other specified fields are present.
func requiredWith(fl FieldLevel) bool {
params := parseOneOfParam2(fl.Param())
@@ -1502,7 +1924,7 @@ func requiredWith(fl FieldLevel) bool {
return true
}
-// ExcludedWithAll is the validation function
+// excludedWithAll is the validation function
// The field under validation must not be present or is empty if all of the other specified fields are present.
func excludedWithAll(fl FieldLevel) bool {
params := parseOneOfParam2(fl.Param())
@@ -1514,7 +1936,7 @@ func excludedWithAll(fl FieldLevel) bool {
return !hasValue(fl)
}
-// RequiredWithAll is the validation function
+// requiredWithAll is the validation function
// The field under validation must be present and not empty only if all of the other specified fields are present.
func requiredWithAll(fl FieldLevel) bool {
params := parseOneOfParam2(fl.Param())
@@ -1526,7 +1948,7 @@ func requiredWithAll(fl FieldLevel) bool {
return hasValue(fl)
}
-// ExcludedWithout is the validation function
+// excludedWithout is the validation function
// The field under validation must not be present or is empty when any of the other specified fields are not present.
func excludedWithout(fl FieldLevel) bool {
if requireCheckFieldKind(fl, strings.TrimSpace(fl.Param()), true) {
@@ -1535,7 +1957,7 @@ func excludedWithout(fl FieldLevel) bool {
return true
}
-// RequiredWithout is the validation function
+// requiredWithout is the validation function
// The field under validation must be present and not empty only when any of the other specified fields are not present.
func requiredWithout(fl FieldLevel) bool {
if requireCheckFieldKind(fl, strings.TrimSpace(fl.Param()), true) {
@@ -1544,7 +1966,7 @@ func requiredWithout(fl FieldLevel) bool {
return true
}
-// RequiredWithoutAll is the validation function
+// excludedWithoutAll is the validation function
// The field under validation must not be present or is empty when all of the other specified fields are not present.
func excludedWithoutAll(fl FieldLevel) bool {
params := parseOneOfParam2(fl.Param())
@@ -1556,7 +1978,7 @@ func excludedWithoutAll(fl FieldLevel) bool {
return !hasValue(fl)
}
-// RequiredWithoutAll is the validation function
+// requiredWithoutAll is the validation function
// The field under validation must be present and not empty only when all of the other specified fields are not present.
func requiredWithoutAll(fl FieldLevel) bool {
params := parseOneOfParam2(fl.Param())
@@ -1568,9 +1990,8 @@ func requiredWithoutAll(fl FieldLevel) bool {
return hasValue(fl)
}
-// 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.
+// 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()
@@ -1597,27 +2018,26 @@ 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
return len(field.String()) >= len(currentField.String())
}
-// IsGtField is the validation function for validating if the current field's value is greater than the field specified by the param's value.
+// 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()
@@ -1644,27 +2064,26 @@ 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
return len(field.String()) > len(currentField.String())
}
-// IsGte is the validation function for validating if the current field's value is greater than or equal to the param's value.
+// 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()
@@ -1690,17 +2109,22 @@ func isGte(fl FieldLevel) bool {
return field.Uint() >= p
- case reflect.Float32, reflect.Float64:
- p := asFloat(param)
+ case reflect.Float32:
+ p := asFloat32(param)
+
+ return field.Float() >= p
+
+ case reflect.Float64:
+ p := asFloat64(param)
return field.Float() >= p
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)
}
@@ -1709,9 +2133,8 @@ func isGte(fl FieldLevel) bool {
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}
-// IsGt is the validation function for validating if the current field's value is greater than the param's value.
+// 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()
@@ -1737,24 +2160,29 @@ func isGt(fl FieldLevel) bool {
return field.Uint() > p
- case reflect.Float32, reflect.Float64:
- p := asFloat(param)
+ case reflect.Float32:
+ p := asFloat32(param)
return field.Float() > p
+
+ case reflect.Float64:
+ p := asFloat64(param)
+
+ 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())
}
}
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}
-// HasLengthOf is the validation function for validating if the current field's value is equal to the param's value.
+// 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()
@@ -1780,8 +2208,13 @@ func hasLengthOf(fl FieldLevel) bool {
return field.Uint() == p
- case reflect.Float32, reflect.Float64:
- p := asFloat(param)
+ case reflect.Float32:
+ p := asFloat32(param)
+
+ return field.Float() == p
+
+ case reflect.Float64:
+ p := asFloat64(param)
return field.Float() == p
}
@@ -1789,14 +2222,13 @@ func hasLengthOf(fl FieldLevel) bool {
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}
-// HasMinOf is the validation function for validating if the current field's value is greater than or equal to the param's value.
+// hasMinOf is the validation function for validating if the current field's value is greater than or equal to the param's value.
func hasMinOf(fl FieldLevel) bool {
return isGte(fl)
}
-// 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.
+// 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()
@@ -1823,27 +2255,26 @@ 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
return len(field.String()) <= len(currentField.String())
}
-// IsLtField is the validation function for validating if the current field's value is less than the field specified by the param's value.
+// 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()
@@ -1870,27 +2301,26 @@ 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
return len(field.String()) < len(currentField.String())
}
-// IsLte is the validation function for validating if the current field's value is less than or equal to the param's value.
+// 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()
@@ -1916,17 +2346,22 @@ func isLte(fl FieldLevel) bool {
return field.Uint() <= p
- case reflect.Float32, reflect.Float64:
- p := asFloat(param)
+ case reflect.Float32:
+ p := asFloat32(param)
+
+ return field.Float() <= p
+
+ case reflect.Float64:
+ p := asFloat64(param)
return field.Float() <= p
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)
}
@@ -1935,9 +2370,8 @@ func isLte(fl FieldLevel) bool {
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}
-// IsLt is the validation function for validating if the current field's value is less than the param's value.
+// 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()
@@ -1963,30 +2397,34 @@ func isLt(fl FieldLevel) bool {
return field.Uint() < p
- case reflect.Float32, reflect.Float64:
- p := asFloat(param)
+ case reflect.Float32:
+ p := asFloat32(param)
+
+ return field.Float() < p
+
+ case reflect.Float64:
+ p := asFloat64(param)
return field.Float() < p
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())
}
}
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}
-// HasMaxOf is the validation function for validating if the current field's value is less than or equal to the param's value.
+// hasMaxOf is the validation function for validating if the current field's value is less than or equal to the param's value.
func hasMaxOf(fl FieldLevel) bool {
return isLte(fl)
}
-// IsTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address.
+// 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
}
@@ -1995,9 +2433,8 @@ func isTCP4AddrResolvable(fl FieldLevel) bool {
return err == nil
}
-// IsTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address.
+// 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
}
@@ -2007,9 +2444,8 @@ func isTCP6AddrResolvable(fl FieldLevel) bool {
return err == nil
}
-// IsTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address.
+// 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
}
@@ -2019,9 +2455,8 @@ func isTCPAddrResolvable(fl FieldLevel) bool {
return err == nil
}
-// IsUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address.
+// 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
}
@@ -2031,9 +2466,8 @@ func isUDP4AddrResolvable(fl FieldLevel) bool {
return err == nil
}
-// IsUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address.
+// 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
}
@@ -2043,9 +2477,8 @@ func isUDP6AddrResolvable(fl FieldLevel) bool {
return err == nil
}
-// IsUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address.
+// 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
}
@@ -2055,9 +2488,8 @@ func isUDPAddrResolvable(fl FieldLevel) bool {
return err == nil
}
-// IsIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address.
+// 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
}
@@ -2067,9 +2499,8 @@ func isIP4AddrResolvable(fl FieldLevel) bool {
return err == nil
}
-// IsIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address.
+// 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
}
@@ -2079,9 +2510,8 @@ func isIP6AddrResolvable(fl FieldLevel) bool {
return err == nil
}
-// IsIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address.
+// 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
}
@@ -2091,16 +2521,14 @@ func isIPAddrResolvable(fl FieldLevel) bool {
return err == nil
}
-// IsUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address.
+// 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 {
@@ -2113,7 +2541,6 @@ func isIP4Addr(fl FieldLevel) bool {
}
func isIP6Addr(fl FieldLevel) bool {
-
val := fl.Field().String()
if idx := strings.LastIndex(val, ":"); idx != -1 {
@@ -2145,7 +2572,7 @@ func isFQDN(fl FieldLevel) bool {
return fqdnRegexRFC1123.MatchString(val)
}
-// IsDir is the validation function for validating if the current field's value is a valid directory.
+// isDir is the validation function for validating if the current field's value is a valid existing directory.
func isDir(fl FieldLevel) bool {
field := fl.Field()
@@ -2161,18 +2588,89 @@ func isDir(fl FieldLevel) bool {
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}
+// isDirPath is the validation function for validating if the current field's value is a valid directory.
+func isDirPath(fl FieldLevel) bool {
+
+ var exists bool
+ var err error
+
+ field := fl.Field()
+
+ // If it exists, it obviously is valid.
+ // This is done first to avoid code duplication and unnecessary additional logic.
+ if exists = isDir(fl); exists {
+ return true
+ }
+
+ // It does not exist but may still be a valid path.
+ switch field.Kind() {
+ case reflect.String:
+ // Every OS allows for whitespace, but none
+ // let you use a dir with no name (to my knowledge).
+ // Unless you're dealing with raw inodes, but I digress.
+ if strings.TrimSpace(field.String()) == "" {
+ return false
+ }
+ if _, err = os.Stat(field.String()); err != nil {
+ switch t := err.(type) {
+ case *fs.PathError:
+ if t.Err == syscall.EINVAL {
+ // It's definitely an invalid character in the path.
+ return false
+ }
+ // It could be a permission error, a does-not-exist error, etc.
+ // Out-of-scope for this validation, though.
+ // Lastly, we make sure it is a directory.
+ if strings.HasSuffix(field.String(), string(os.PathSeparator)) {
+ return true
+ } else {
+ return false
+ }
+ default:
+ // Something went *seriously* wrong.
+ /*
+ Per https://pkg.go.dev/os#Stat:
+ "If there is an error, it will be of type *PathError."
+ */
+ panic(err)
+ }
+ }
+ // We repeat the check here to make sure it is an explicit directory in case the above os.Stat didn't trigger an error.
+ if strings.HasSuffix(field.String(), string(os.PathSeparator)) {
+ return true
+ } else {
+ return false
+ }
+ }
+
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+}
+
// isJSON is the validation function for validating if the current field's value is a valid json string.
func isJSON(fl FieldLevel) bool {
field := fl.Field()
- if field.Kind() == reflect.String {
+ switch field.Kind() {
+ case reflect.String:
val := field.String()
return json.Valid([]byte(val))
+ case reflect.Slice:
+ fieldType := field.Type()
+
+ if fieldType.ConvertibleTo(byteSliceType) {
+ b := field.Convert(byteSliceType).Interface().([]byte)
+ return json.Valid(b)
+ }
}
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}
+// isJWT is the validation function for validating if the current field's value is a valid JWT string.
+func isJWT(fl FieldLevel) bool {
+ return jWTRegex.MatchString(fl.Field().String())
+}
+
// isHostnamePort validates a : combination for fields typically used for socket address.
func isHostnamePort(fl FieldLevel) bool {
val := fl.Field().String()
@@ -2181,7 +2679,9 @@ func isHostnamePort(fl FieldLevel) bool {
return false
}
// Port must be a iny <= 65535.
- if portNum, err := strconv.ParseInt(port, 10, 32); err != nil || portNum > 65535 || portNum < 1 {
+ if portNum, err := strconv.ParseInt(
+ port, 10, 32,
+ ); err != nil || portNum > 65535 || portNum < 1 {
return false
}
@@ -2262,18 +2762,24 @@ func isIso3166Alpha2(fl FieldLevel) bool {
return iso3166_1_alpha2[val]
}
-// isIso3166Alpha2 is the validation function for validating if the current field's value is a valid iso3166-1 alpha-3 country code.
+// isIso3166Alpha3 is the validation function for validating if the current field's value is a valid iso3166-1 alpha-3 country code.
func isIso3166Alpha3(fl FieldLevel) bool {
val := fl.Field().String()
return iso3166_1_alpha3[val]
}
-// isIso3166Alpha2 is the validation function for validating if the current field's value is a valid iso3166-1 alpha-numeric country code.
+// isIso3166AlphaNumeric is the validation function for validating if the current field's value is a valid iso3166-1 alpha-numeric country code.
func isIso3166AlphaNumeric(fl FieldLevel) bool {
field := fl.Field()
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:
@@ -2283,3 +2789,167 @@ func isIso3166AlphaNumeric(fl FieldLevel) bool {
}
return iso3166_1_alpha_numeric[code]
}
+
+// isIso31662 is the validation function for validating if the current field's value is a valid iso3166-2 code.
+func isIso31662(fl FieldLevel) bool {
+ val := fl.Field().String()
+ return iso3166_2[val]
+}
+
+// isIso4217 is the validation function for validating if the current field's value is a valid iso4217 currency code.
+func isIso4217(fl FieldLevel) bool {
+ val := fl.Field().String()
+ return iso4217[val]
+}
+
+// isIso4217Numeric is the validation function for validating if the current field's value is a valid iso4217 numeric currency code.
+func isIso4217Numeric(fl FieldLevel) bool {
+ field := fl.Field()
+
+ var code int
+ switch field.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ code = int(field.Int())
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ code = int(field.Uint())
+ default:
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+ }
+ return iso4217_numeric[code]
+}
+
+// isBCP47LanguageTag is the validation function for validating if the current field's value is a valid BCP 47 language tag, as parsed by language.Parse
+func isBCP47LanguageTag(fl FieldLevel) bool {
+ field := fl.Field()
+
+ if field.Kind() == reflect.String {
+ _, err := language.Parse(field.String())
+ return err == nil
+ }
+
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+}
+
+// isIsoBicFormat is the validation function for validating if the current field's value is a valid Business Identifier Code (SWIFT code), defined in ISO 9362
+func isIsoBicFormat(fl FieldLevel) bool {
+ bicString := fl.Field().String()
+
+ 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)
+}
+
+// isCveFormat is the validation function for validating if the current field's value is a valid cve id, defined in CVE mitre org
+func isCveFormat(fl FieldLevel) bool {
+ cveString := fl.Field().String()
+
+ return cveRegex.MatchString(cveString)
+}
+
+// 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)
+}
+
+// digitsHaveLuhnChecksum returns true if and only if the last element of the given digits slice is the Luhn checksum of the previous elements
+func digitsHaveLuhnChecksum(digits []string) bool {
+ size := len(digits)
+ sum := 0
+ for i, digit := range digits {
+ 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
+}
+
+// isMongoDB is the validation function for validating if the current field's value is valid mongoDB objectID
+func isMongoDB(fl FieldLevel) bool {
+ val := fl.Field().String()
+ return mongodbRegex.MatchString(val)
+}
+
+// isSpiceDB is the validation function for validating if the current field's value is valid for use with Authzed SpiceDB in the indicated way
+func isSpiceDB(fl FieldLevel) bool {
+ val := fl.Field().String()
+ param := fl.Param()
+
+ switch param {
+ case "permission":
+ return spicedbPermissionRegex.MatchString(val)
+ case "type":
+ return spicedbTypeRegex.MatchString(val)
+ case "id", "":
+ return spicedbIDRegex.MatchString(val)
+ }
+
+ panic("Unrecognized parameter: " + param)
+}
+
+// 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
+ }
+
+ return digitsHaveLuhnChecksum(ccDigits)
+}
+
+// hasLuhnChecksum is the validation for validating if the current field's value has a valid Luhn checksum
+func hasLuhnChecksum(fl FieldLevel) bool {
+ field := fl.Field()
+ var str string // convert to a string which will then be split into single digits; easier and more readable than shifting/extracting single digits from a number
+ switch field.Kind() {
+ case reflect.String:
+ str = field.String()
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ str = strconv.FormatInt(field.Int(), 10)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ str = strconv.FormatUint(field.Uint(), 10)
+ default:
+ panic(fmt.Sprintf("Bad field type %T", field.Interface()))
+ }
+ size := len(str)
+ if size < 2 { // there has to be at least one digit that carries a meaning + the checksum
+ return false
+ }
+ digits := strings.Split(str, "")
+ return digitsHaveLuhnChecksum(digits)
+}
+
+// isCron is the validation function for validating if the current field's value is a valid cron expression
+func isCron(fl FieldLevel) bool {
+ cronString := fl.Field().String()
+ return cronRegex.MatchString(cronString)
+}
diff --git a/vendor/github.com/go-playground/validator/v10/cache.go b/vendor/github.com/go-playground/validator/v10/cache.go
index 0d18d6ec49c..0f4fa6b5cec 100644
--- a/vendor/github.com/go-playground/validator/v10/cache.go
+++ b/vendor/github.com/go-playground/validator/v10/cache.go
@@ -20,6 +20,7 @@ const (
typeOr
typeKeys
typeEndKeys
+ typeOmitNil
)
const (
@@ -114,6 +115,7 @@ 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
@@ -128,7 +130,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
@@ -247,6 +253,10 @@ func (v *Validate) parseFieldTagsRecursive(tag string, fieldName string, alias s
current.typeof = typeOmitEmpty
continue
+ case omitnil:
+ current.typeof = typeOmitNil
+ continue
+
case structOnlyTag:
current.typeof = typeStructOnly
continue
diff --git a/vendor/github.com/go-playground/validator/v10/country_codes.go b/vendor/github.com/go-playground/validator/v10/country_codes.go
index ef81eada88f..0119f0574d9 100644
--- a/vendor/github.com/go-playground/validator/v10/country_codes.go
+++ b/vendor/github.com/go-playground/validator/v10/country_codes.go
@@ -51,7 +51,7 @@ var iso3166_1_alpha2 = map[string]bool{
"TV": true, "UG": true, "UA": true, "AE": true, "GB": true,
"US": true, "UM": true, "UY": true, "UZ": true, "VU": true,
"VE": true, "VN": true, "VG": true, "VI": true, "WF": true,
- "EH": true, "YE": true, "ZM": true, "ZW": true,
+ "EH": true, "YE": true, "ZM": true, "ZW": true, "XK": true,
}
var iso3166_1_alpha3 = map[string]bool{
@@ -105,7 +105,7 @@ var iso3166_1_alpha3 = map[string]bool{
"UGA": true, "UKR": true, "ARE": true, "GBR": true, "UMI": true,
"USA": true, "URY": true, "UZB": true, "VUT": true, "VEN": true,
"VNM": true, "VGB": true, "VIR": true, "WLF": true, "ESH": true,
- "YEM": true, "ZMB": true, "ZWE": true, "ALA": true,
+ "YEM": true, "ZMB": true, "ZWE": true, "ALA": true, "UNK": true,
}
var iso3166_1_alpha_numeric = map[int]bool{
// see: https://www.iso.org/iso-3166-country-codes.html
@@ -158,5 +158,993 @@ var iso3166_1_alpha_numeric = map[int]bool{
800: true, 804: true, 784: true, 826: true, 581: true,
840: true, 858: true, 860: true, 548: true, 862: true,
704: true, 92: true, 850: true, 876: true, 732: true,
- 887: true, 894: true, 716: true, 248: true,
+ 887: true, 894: true, 716: true, 248: true, 153: true,
+}
+
+var iso3166_2 = map[string]bool{
+ "AD-02": true, "AD-03": true, "AD-04": true, "AD-05": true, "AD-06": true,
+ "AD-07": true, "AD-08": true, "AE-AJ": true, "AE-AZ": true, "AE-DU": true,
+ "AE-FU": true, "AE-RK": true, "AE-SH": true, "AE-UQ": true, "AF-BAL": true,
+ "AF-BAM": true, "AF-BDG": true, "AF-BDS": true, "AF-BGL": true, "AF-DAY": true,
+ "AF-FRA": true, "AF-FYB": true, "AF-GHA": true, "AF-GHO": true, "AF-HEL": true,
+ "AF-HER": true, "AF-JOW": true, "AF-KAB": true, "AF-KAN": true, "AF-KAP": true,
+ "AF-KDZ": true, "AF-KHO": true, "AF-KNR": true, "AF-LAG": true, "AF-LOG": true,
+ "AF-NAN": true, "AF-NIM": true, "AF-NUR": true, "AF-PAN": true, "AF-PAR": true,
+ "AF-PIA": true, "AF-PKA": true, "AF-SAM": true, "AF-SAR": true, "AF-TAK": true,
+ "AF-URU": true, "AF-WAR": true, "AF-ZAB": true, "AG-03": true, "AG-04": true,
+ "AG-05": true, "AG-06": true, "AG-07": true, "AG-08": true, "AG-10": true,
+ "AG-11": true, "AL-01": true, "AL-02": true, "AL-03": true, "AL-04": true,
+ "AL-05": true, "AL-06": true, "AL-07": true, "AL-08": true, "AL-09": true,
+ "AL-10": true, "AL-11": true, "AL-12": true, "AL-BR": true, "AL-BU": true,
+ "AL-DI": true, "AL-DL": true, "AL-DR": true, "AL-DV": true, "AL-EL": true,
+ "AL-ER": true, "AL-FR": true, "AL-GJ": true, "AL-GR": true, "AL-HA": true,
+ "AL-KA": true, "AL-KB": true, "AL-KC": true, "AL-KO": true, "AL-KR": true,
+ "AL-KU": true, "AL-LB": true, "AL-LE": true, "AL-LU": true, "AL-MK": true,
+ "AL-MM": true, "AL-MR": true, "AL-MT": true, "AL-PG": true, "AL-PQ": true,
+ "AL-PR": true, "AL-PU": true, "AL-SH": true, "AL-SK": true, "AL-SR": true,
+ "AL-TE": true, "AL-TP": true, "AL-TR": true, "AL-VL": true, "AM-AG": true,
+ "AM-AR": true, "AM-AV": true, "AM-ER": true, "AM-GR": true, "AM-KT": true,
+ "AM-LO": true, "AM-SH": true, "AM-SU": true, "AM-TV": true, "AM-VD": true,
+ "AO-BGO": true, "AO-BGU": true, "AO-BIE": true, "AO-CAB": true, "AO-CCU": true,
+ "AO-CNN": true, "AO-CNO": true, "AO-CUS": true, "AO-HUA": true, "AO-HUI": true,
+ "AO-LNO": true, "AO-LSU": true, "AO-LUA": true, "AO-MAL": true, "AO-MOX": true,
+ "AO-NAM": true, "AO-UIG": true, "AO-ZAI": true, "AR-A": true, "AR-B": true,
+ "AR-C": true, "AR-D": true, "AR-E": true, "AR-F": true, "AR-G": true, "AR-H": true,
+ "AR-J": true, "AR-K": true, "AR-L": true, "AR-M": true, "AR-N": true,
+ "AR-P": true, "AR-Q": true, "AR-R": true, "AR-S": true, "AR-T": true,
+ "AR-U": true, "AR-V": true, "AR-W": true, "AR-X": true, "AR-Y": true,
+ "AR-Z": true, "AT-1": true, "AT-2": true, "AT-3": true, "AT-4": true,
+ "AT-5": true, "AT-6": true, "AT-7": true, "AT-8": true, "AT-9": true,
+ "AU-ACT": true, "AU-NSW": true, "AU-NT": true, "AU-QLD": true, "AU-SA": true,
+ "AU-TAS": true, "AU-VIC": true, "AU-WA": true, "AZ-ABS": true, "AZ-AGA": true,
+ "AZ-AGC": true, "AZ-AGM": true, "AZ-AGS": true, "AZ-AGU": true, "AZ-AST": true,
+ "AZ-BA": true, "AZ-BAB": true, "AZ-BAL": true, "AZ-BAR": true, "AZ-BEY": true,
+ "AZ-BIL": true, "AZ-CAB": true, "AZ-CAL": true, "AZ-CUL": true, "AZ-DAS": true,
+ "AZ-FUZ": true, "AZ-GA": true, "AZ-GAD": true, "AZ-GOR": true, "AZ-GOY": true,
+ "AZ-GYG": true, "AZ-HAC": true, "AZ-IMI": true, "AZ-ISM": true, "AZ-KAL": true,
+ "AZ-KAN": true, "AZ-KUR": true, "AZ-LA": true, "AZ-LAC": true, "AZ-LAN": true,
+ "AZ-LER": true, "AZ-MAS": true, "AZ-MI": true, "AZ-NA": true, "AZ-NEF": true,
+ "AZ-NV": true, "AZ-NX": true, "AZ-OGU": true, "AZ-ORD": true, "AZ-QAB": true,
+ "AZ-QAX": true, "AZ-QAZ": true, "AZ-QBA": true, "AZ-QBI": true, "AZ-QOB": true,
+ "AZ-QUS": true, "AZ-SA": true, "AZ-SAB": true, "AZ-SAD": true, "AZ-SAH": true,
+ "AZ-SAK": true, "AZ-SAL": true, "AZ-SAR": true, "AZ-SAT": true, "AZ-SBN": true,
+ "AZ-SIY": true, "AZ-SKR": true, "AZ-SM": true, "AZ-SMI": true, "AZ-SMX": true,
+ "AZ-SR": true, "AZ-SUS": true, "AZ-TAR": true, "AZ-TOV": true, "AZ-UCA": true,
+ "AZ-XA": true, "AZ-XAC": true, "AZ-XCI": true, "AZ-XIZ": true, "AZ-XVD": true,
+ "AZ-YAR": true, "AZ-YE": true, "AZ-YEV": true, "AZ-ZAN": true, "AZ-ZAQ": true,
+ "AZ-ZAR": true, "BA-01": true, "BA-02": true, "BA-03": true, "BA-04": true,
+ "BA-05": true, "BA-06": true, "BA-07": true, "BA-08": true, "BA-09": true,
+ "BA-10": true, "BA-BIH": true, "BA-BRC": true, "BA-SRP": true, "BB-01": true,
+ "BB-02": true, "BB-03": true, "BB-04": true, "BB-05": true, "BB-06": true,
+ "BB-07": true, "BB-08": true, "BB-09": true, "BB-10": true, "BB-11": true,
+ "BD-01": true, "BD-02": true, "BD-03": true, "BD-04": true, "BD-05": true,
+ "BD-06": true, "BD-07": true, "BD-08": true, "BD-09": true, "BD-10": true,
+ "BD-11": true, "BD-12": true, "BD-13": true, "BD-14": true, "BD-15": true,
+ "BD-16": true, "BD-17": true, "BD-18": true, "BD-19": true, "BD-20": true,
+ "BD-21": true, "BD-22": true, "BD-23": true, "BD-24": true, "BD-25": true,
+ "BD-26": true, "BD-27": true, "BD-28": true, "BD-29": true, "BD-30": true,
+ "BD-31": true, "BD-32": true, "BD-33": true, "BD-34": true, "BD-35": true,
+ "BD-36": true, "BD-37": true, "BD-38": true, "BD-39": true, "BD-40": true,
+ "BD-41": true, "BD-42": true, "BD-43": true, "BD-44": true, "BD-45": true,
+ "BD-46": true, "BD-47": true, "BD-48": true, "BD-49": true, "BD-50": true,
+ "BD-51": true, "BD-52": true, "BD-53": true, "BD-54": true, "BD-55": true,
+ "BD-56": true, "BD-57": true, "BD-58": true, "BD-59": true, "BD-60": true,
+ "BD-61": true, "BD-62": true, "BD-63": true, "BD-64": true, "BD-A": true,
+ "BD-B": true, "BD-C": true, "BD-D": true, "BD-E": true, "BD-F": true,
+ "BD-G": true, "BE-BRU": true, "BE-VAN": true, "BE-VBR": true, "BE-VLG": true,
+ "BE-VLI": true, "BE-VOV": true, "BE-VWV": true, "BE-WAL": true, "BE-WBR": true,
+ "BE-WHT": true, "BE-WLG": true, "BE-WLX": true, "BE-WNA": true, "BF-01": true,
+ "BF-02": true, "BF-03": true, "BF-04": true, "BF-05": true, "BF-06": true,
+ "BF-07": true, "BF-08": true, "BF-09": true, "BF-10": true, "BF-11": true,
+ "BF-12": true, "BF-13": true, "BF-BAL": true, "BF-BAM": true, "BF-BAN": true,
+ "BF-BAZ": true, "BF-BGR": true, "BF-BLG": true, "BF-BLK": true, "BF-COM": true,
+ "BF-GAN": true, "BF-GNA": true, "BF-GOU": true, "BF-HOU": true, "BF-IOB": true,
+ "BF-KAD": true, "BF-KEN": true, "BF-KMD": true, "BF-KMP": true, "BF-KOP": true,
+ "BF-KOS": true, "BF-KOT": true, "BF-KOW": true, "BF-LER": true, "BF-LOR": true,
+ "BF-MOU": true, "BF-NAM": true, "BF-NAO": true, "BF-NAY": true, "BF-NOU": true,
+ "BF-OUB": true, "BF-OUD": true, "BF-PAS": true, "BF-PON": true, "BF-SEN": true,
+ "BF-SIS": true, "BF-SMT": true, "BF-SNG": true, "BF-SOM": true, "BF-SOR": true,
+ "BF-TAP": true, "BF-TUI": true, "BF-YAG": true, "BF-YAT": true, "BF-ZIR": true,
+ "BF-ZON": true, "BF-ZOU": true, "BG-01": true, "BG-02": true, "BG-03": true,
+ "BG-04": true, "BG-05": true, "BG-06": true, "BG-07": true, "BG-08": true,
+ "BG-09": true, "BG-10": true, "BG-11": true, "BG-12": true, "BG-13": true,
+ "BG-14": true, "BG-15": true, "BG-16": true, "BG-17": true, "BG-18": true,
+ "BG-19": true, "BG-20": true, "BG-21": true, "BG-22": true, "BG-23": true,
+ "BG-24": true, "BG-25": true, "BG-26": true, "BG-27": true, "BG-28": true,
+ "BH-13": true, "BH-14": true, "BH-15": true, "BH-16": true, "BH-17": true,
+ "BI-BB": true, "BI-BL": true, "BI-BM": true, "BI-BR": true, "BI-CA": true,
+ "BI-CI": true, "BI-GI": true, "BI-KI": true, "BI-KR": true, "BI-KY": true,
+ "BI-MA": true, "BI-MU": true, "BI-MW": true, "BI-NG": true, "BI-RM": true, "BI-RT": true,
+ "BI-RY": true, "BJ-AK": true, "BJ-AL": true, "BJ-AQ": true, "BJ-BO": true,
+ "BJ-CO": true, "BJ-DO": true, "BJ-KO": true, "BJ-LI": true, "BJ-MO": true,
+ "BJ-OU": true, "BJ-PL": true, "BJ-ZO": true, "BN-BE": true, "BN-BM": true,
+ "BN-TE": true, "BN-TU": true, "BO-B": true, "BO-C": true, "BO-H": true,
+ "BO-L": true, "BO-N": true, "BO-O": true, "BO-P": true, "BO-S": true,
+ "BO-T": true, "BQ-BO": true, "BQ-SA": true, "BQ-SE": true, "BR-AC": true,
+ "BR-AL": true, "BR-AM": true, "BR-AP": true, "BR-BA": true, "BR-CE": true,
+ "BR-DF": true, "BR-ES": true, "BR-FN": true, "BR-GO": true, "BR-MA": true,
+ "BR-MG": true, "BR-MS": true, "BR-MT": true, "BR-PA": true, "BR-PB": true,
+ "BR-PE": true, "BR-PI": true, "BR-PR": true, "BR-RJ": true, "BR-RN": true,
+ "BR-RO": true, "BR-RR": true, "BR-RS": true, "BR-SC": true, "BR-SE": true,
+ "BR-SP": true, "BR-TO": true, "BS-AK": true, "BS-BI": true, "BS-BP": true,
+ "BS-BY": true, "BS-CE": true, "BS-CI": true, "BS-CK": true, "BS-CO": true,
+ "BS-CS": true, "BS-EG": true, "BS-EX": true, "BS-FP": true, "BS-GC": true,
+ "BS-HI": true, "BS-HT": true, "BS-IN": true, "BS-LI": true, "BS-MC": true,
+ "BS-MG": true, "BS-MI": true, "BS-NE": true, "BS-NO": true, "BS-NP": true, "BS-NS": true,
+ "BS-RC": true, "BS-RI": true, "BS-SA": true, "BS-SE": true, "BS-SO": true,
+ "BS-SS": true, "BS-SW": true, "BS-WG": true, "BT-11": true, "BT-12": true,
+ "BT-13": true, "BT-14": true, "BT-15": true, "BT-21": true, "BT-22": true,
+ "BT-23": true, "BT-24": true, "BT-31": true, "BT-32": true, "BT-33": true,
+ "BT-34": true, "BT-41": true, "BT-42": true, "BT-43": true, "BT-44": true,
+ "BT-45": true, "BT-GA": true, "BT-TY": true, "BW-CE": true, "BW-CH": true, "BW-GH": true,
+ "BW-KG": true, "BW-KL": true, "BW-KW": true, "BW-NE": true, "BW-NW": true,
+ "BW-SE": true, "BW-SO": true, "BY-BR": true, "BY-HM": true, "BY-HO": true,
+ "BY-HR": true, "BY-MA": true, "BY-MI": true, "BY-VI": true, "BZ-BZ": true,
+ "BZ-CY": true, "BZ-CZL": true, "BZ-OW": true, "BZ-SC": true, "BZ-TOL": true,
+ "CA-AB": true, "CA-BC": true, "CA-MB": true, "CA-NB": true, "CA-NL": true,
+ "CA-NS": true, "CA-NT": true, "CA-NU": true, "CA-ON": true, "CA-PE": true,
+ "CA-QC": true, "CA-SK": true, "CA-YT": true, "CD-BC": true, "CD-BN": true,
+ "CD-EQ": true, "CD-HK": true, "CD-IT": true, "CD-KA": true, "CD-KC": true, "CD-KE": true, "CD-KG": true, "CD-KN": true,
+ "CD-KW": true, "CD-KS": true, "CD-LU": true, "CD-MA": true, "CD-NK": true, "CD-OR": true, "CD-SA": true, "CD-SK": true,
+ "CD-TA": true, "CD-TO": true, "CF-AC": true, "CF-BB": true, "CF-BGF": true, "CF-BK": true, "CF-HK": true, "CF-HM": true,
+ "CF-HS": true, "CF-KB": true, "CF-KG": true, "CF-LB": true, "CF-MB": true,
+ "CF-MP": true, "CF-NM": true, "CF-OP": true, "CF-SE": true, "CF-UK": true,
+ "CF-VK": true, "CG-11": true, "CG-12": true, "CG-13": true, "CG-14": true,
+ "CG-15": true, "CG-16": true, "CG-2": true, "CG-5": true, "CG-7": true, "CG-8": true,
+ "CG-9": true, "CG-BZV": true, "CH-AG": true, "CH-AI": true, "CH-AR": true,
+ "CH-BE": true, "CH-BL": true, "CH-BS": true, "CH-FR": true, "CH-GE": true,
+ "CH-GL": true, "CH-GR": true, "CH-JU": true, "CH-LU": true, "CH-NE": true,
+ "CH-NW": true, "CH-OW": true, "CH-SG": true, "CH-SH": true, "CH-SO": true,
+ "CH-SZ": true, "CH-TG": true, "CH-TI": true, "CH-UR": true, "CH-VD": true,
+ "CH-VS": true, "CH-ZG": true, "CH-ZH": true, "CI-AB": true, "CI-BS": true,
+ "CI-CM": true, "CI-DN": true, "CI-GD": true, "CI-LC": true, "CI-LG": true,
+ "CI-MG": true, "CI-SM": true, "CI-SV": true, "CI-VB": true, "CI-WR": true,
+ "CI-YM": true, "CI-ZZ": true, "CL-AI": true, "CL-AN": true, "CL-AP": true,
+ "CL-AR": true, "CL-AT": true, "CL-BI": true, "CL-CO": true, "CL-LI": true,
+ "CL-LL": true, "CL-LR": true, "CL-MA": true, "CL-ML": true, "CL-NB": true, "CL-RM": true,
+ "CL-TA": true, "CL-VS": true, "CM-AD": true, "CM-CE": true, "CM-EN": true,
+ "CM-ES": true, "CM-LT": true, "CM-NO": true, "CM-NW": true, "CM-OU": true,
+ "CM-SU": true, "CM-SW": true, "CN-AH": true, "CN-BJ": true, "CN-CQ": true,
+ "CN-FJ": true, "CN-GS": true, "CN-GD": true, "CN-GX": true, "CN-GZ": true,
+ "CN-HI": true, "CN-HE": true, "CN-HL": true, "CN-HA": true, "CN-HB": true,
+ "CN-HN": true, "CN-JS": true, "CN-JX": true, "CN-JL": true, "CN-LN": true,
+ "CN-NM": true, "CN-NX": true, "CN-QH": true, "CN-SN": true, "CN-SD": true, "CN-SH": true,
+ "CN-SX": true, "CN-SC": true, "CN-TJ": true, "CN-XJ": true, "CN-XZ": true, "CN-YN": true,
+ "CN-ZJ": true, "CO-AMA": true, "CO-ANT": true, "CO-ARA": true, "CO-ATL": true,
+ "CO-BOL": true, "CO-BOY": true, "CO-CAL": true, "CO-CAQ": true, "CO-CAS": true,
+ "CO-CAU": true, "CO-CES": true, "CO-CHO": true, "CO-COR": true, "CO-CUN": true,
+ "CO-DC": true, "CO-GUA": true, "CO-GUV": true, "CO-HUI": true, "CO-LAG": true,
+ "CO-MAG": true, "CO-MET": true, "CO-NAR": true, "CO-NSA": true, "CO-PUT": true,
+ "CO-QUI": true, "CO-RIS": true, "CO-SAN": true, "CO-SAP": true, "CO-SUC": true,
+ "CO-TOL": true, "CO-VAC": true, "CO-VAU": true, "CO-VID": true, "CR-A": true,
+ "CR-C": true, "CR-G": true, "CR-H": true, "CR-L": true, "CR-P": true,
+ "CR-SJ": true, "CU-01": true, "CU-02": true, "CU-03": true, "CU-04": true,
+ "CU-05": true, "CU-06": true, "CU-07": true, "CU-08": true, "CU-09": true,
+ "CU-10": true, "CU-11": true, "CU-12": true, "CU-13": true, "CU-14": true, "CU-15": true,
+ "CU-16": true, "CU-99": true, "CV-B": true, "CV-BR": true, "CV-BV": true, "CV-CA": true,
+ "CV-CF": true, "CV-CR": true, "CV-MA": true, "CV-MO": true, "CV-PA": true,
+ "CV-PN": true, "CV-PR": true, "CV-RB": true, "CV-RG": true, "CV-RS": true,
+ "CV-S": true, "CV-SD": true, "CV-SF": true, "CV-SL": true, "CV-SM": true,
+ "CV-SO": true, "CV-SS": true, "CV-SV": true, "CV-TA": true, "CV-TS": true,
+ "CY-01": true, "CY-02": true, "CY-03": true, "CY-04": true, "CY-05": true,
+ "CY-06": true, "CZ-10": true, "CZ-101": true, "CZ-102": true, "CZ-103": true,
+ "CZ-104": true, "CZ-105": true, "CZ-106": true, "CZ-107": true, "CZ-108": true,
+ "CZ-109": true, "CZ-110": true, "CZ-111": true, "CZ-112": true, "CZ-113": true,
+ "CZ-114": true, "CZ-115": true, "CZ-116": true, "CZ-117": true, "CZ-118": true,
+ "CZ-119": true, "CZ-120": true, "CZ-121": true, "CZ-122": true, "CZ-20": true,
+ "CZ-201": true, "CZ-202": true, "CZ-203": true, "CZ-204": true, "CZ-205": true,
+ "CZ-206": true, "CZ-207": true, "CZ-208": true, "CZ-209": true, "CZ-20A": true,
+ "CZ-20B": true, "CZ-20C": true, "CZ-31": true, "CZ-311": true, "CZ-312": true,
+ "CZ-313": true, "CZ-314": true, "CZ-315": true, "CZ-316": true, "CZ-317": true,
+ "CZ-32": true, "CZ-321": true, "CZ-322": true, "CZ-323": true, "CZ-324": true,
+ "CZ-325": true, "CZ-326": true, "CZ-327": true, "CZ-41": true, "CZ-411": true,
+ "CZ-412": true, "CZ-413": true, "CZ-42": true, "CZ-421": true, "CZ-422": true,
+ "CZ-423": true, "CZ-424": true, "CZ-425": true, "CZ-426": true, "CZ-427": true,
+ "CZ-51": true, "CZ-511": true, "CZ-512": true, "CZ-513": true, "CZ-514": true,
+ "CZ-52": true, "CZ-521": true, "CZ-522": true, "CZ-523": true, "CZ-524": true,
+ "CZ-525": true, "CZ-53": true, "CZ-531": true, "CZ-532": true, "CZ-533": true,
+ "CZ-534": true, "CZ-63": true, "CZ-631": true, "CZ-632": true, "CZ-633": true,
+ "CZ-634": true, "CZ-635": true, "CZ-64": true, "CZ-641": true, "CZ-642": true,
+ "CZ-643": true, "CZ-644": true, "CZ-645": true, "CZ-646": true, "CZ-647": true,
+ "CZ-71": true, "CZ-711": true, "CZ-712": true, "CZ-713": true, "CZ-714": true,
+ "CZ-715": true, "CZ-72": true, "CZ-721": true, "CZ-722": true, "CZ-723": true,
+ "CZ-724": true, "CZ-80": true, "CZ-801": true, "CZ-802": true, "CZ-803": true,
+ "CZ-804": true, "CZ-805": true, "CZ-806": true, "DE-BB": true, "DE-BE": true,
+ "DE-BW": true, "DE-BY": true, "DE-HB": true, "DE-HE": true, "DE-HH": true,
+ "DE-MV": true, "DE-NI": true, "DE-NW": true, "DE-RP": true, "DE-SH": true,
+ "DE-SL": true, "DE-SN": true, "DE-ST": true, "DE-TH": true, "DJ-AR": true,
+ "DJ-AS": true, "DJ-DI": true, "DJ-DJ": true, "DJ-OB": true, "DJ-TA": true,
+ "DK-81": true, "DK-82": true, "DK-83": true, "DK-84": true, "DK-85": true,
+ "DM-01": true, "DM-02": true, "DM-03": true, "DM-04": true, "DM-05": true,
+ "DM-06": true, "DM-07": true, "DM-08": true, "DM-09": true, "DM-10": true,
+ "DO-01": true, "DO-02": true, "DO-03": true, "DO-04": true, "DO-05": true,
+ "DO-06": true, "DO-07": true, "DO-08": true, "DO-09": true, "DO-10": true,
+ "DO-11": true, "DO-12": true, "DO-13": true, "DO-14": true, "DO-15": true,
+ "DO-16": true, "DO-17": true, "DO-18": true, "DO-19": true, "DO-20": true,
+ "DO-21": true, "DO-22": true, "DO-23": true, "DO-24": true, "DO-25": true,
+ "DO-26": true, "DO-27": true, "DO-28": true, "DO-29": true, "DO-30": true, "DO-31": true,
+ "DZ-01": true, "DZ-02": true, "DZ-03": true, "DZ-04": true, "DZ-05": true,
+ "DZ-06": true, "DZ-07": true, "DZ-08": true, "DZ-09": true, "DZ-10": true,
+ "DZ-11": true, "DZ-12": true, "DZ-13": true, "DZ-14": true, "DZ-15": true,
+ "DZ-16": true, "DZ-17": true, "DZ-18": true, "DZ-19": true, "DZ-20": true,
+ "DZ-21": true, "DZ-22": true, "DZ-23": true, "DZ-24": true, "DZ-25": true,
+ "DZ-26": true, "DZ-27": true, "DZ-28": true, "DZ-29": true, "DZ-30": true,
+ "DZ-31": true, "DZ-32": true, "DZ-33": true, "DZ-34": true, "DZ-35": true,
+ "DZ-36": true, "DZ-37": true, "DZ-38": true, "DZ-39": true, "DZ-40": true,
+ "DZ-41": true, "DZ-42": true, "DZ-43": true, "DZ-44": true, "DZ-45": true,
+ "DZ-46": true, "DZ-47": true, "DZ-48": true, "DZ-49": true, "DZ-51": true,
+ "DZ-53": true, "DZ-55": true, "DZ-56": true, "DZ-57": true, "EC-A": true, "EC-B": true,
+ "EC-C": true, "EC-D": true, "EC-E": true, "EC-F": true, "EC-G": true,
+ "EC-H": true, "EC-I": true, "EC-L": true, "EC-M": true, "EC-N": true,
+ "EC-O": true, "EC-P": true, "EC-R": true, "EC-S": true, "EC-SD": true,
+ "EC-SE": true, "EC-T": true, "EC-U": true, "EC-W": true, "EC-X": true,
+ "EC-Y": true, "EC-Z": true, "EE-37": true, "EE-39": true, "EE-44": true, "EE-45": true,
+ "EE-49": true, "EE-50": true, "EE-51": true, "EE-52": true, "EE-56": true, "EE-57": true,
+ "EE-59": true, "EE-60": true, "EE-64": true, "EE-65": true, "EE-67": true, "EE-68": true,
+ "EE-70": true, "EE-71": true, "EE-74": true, "EE-78": true, "EE-79": true, "EE-81": true, "EE-82": true,
+ "EE-84": true, "EE-86": true, "EE-87": true, "EG-ALX": true, "EG-ASN": true, "EG-AST": true,
+ "EG-BA": true, "EG-BH": true, "EG-BNS": true, "EG-C": true, "EG-DK": true,
+ "EG-DT": true, "EG-FYM": true, "EG-GH": true, "EG-GZ": true, "EG-HU": true,
+ "EG-IS": true, "EG-JS": true, "EG-KB": true, "EG-KFS": true, "EG-KN": true,
+ "EG-LX": true, "EG-MN": true, "EG-MNF": true, "EG-MT": true, "EG-PTS": true, "EG-SHG": true,
+ "EG-SHR": true, "EG-SIN": true, "EG-SU": true, "EG-SUZ": true, "EG-WAD": true,
+ "ER-AN": true, "ER-DK": true, "ER-DU": true, "ER-GB": true, "ER-MA": true,
+ "ER-SK": true, "ES-A": true, "ES-AB": true, "ES-AL": true, "ES-AN": true,
+ "ES-AR": true, "ES-AS": true, "ES-AV": true, "ES-B": true, "ES-BA": true,
+ "ES-BI": true, "ES-BU": true, "ES-C": true, "ES-CA": true, "ES-CB": true,
+ "ES-CC": true, "ES-CE": true, "ES-CL": true, "ES-CM": true, "ES-CN": true,
+ "ES-CO": true, "ES-CR": true, "ES-CS": true, "ES-CT": true, "ES-CU": true,
+ "ES-EX": true, "ES-GA": true, "ES-GC": true, "ES-GI": true, "ES-GR": true,
+ "ES-GU": true, "ES-H": true, "ES-HU": true, "ES-IB": true, "ES-J": true,
+ "ES-L": true, "ES-LE": true, "ES-LO": true, "ES-LU": true, "ES-M": true,
+ "ES-MA": true, "ES-MC": true, "ES-MD": true, "ES-ML": true, "ES-MU": true,
+ "ES-NA": true, "ES-NC": true, "ES-O": true, "ES-OR": true, "ES-P": true,
+ "ES-PM": true, "ES-PO": true, "ES-PV": true, "ES-RI": true, "ES-S": true,
+ "ES-SA": true, "ES-SE": true, "ES-SG": true, "ES-SO": true, "ES-SS": true,
+ "ES-T": true, "ES-TE": true, "ES-TF": true, "ES-TO": true, "ES-V": true,
+ "ES-VA": true, "ES-VC": true, "ES-VI": true, "ES-Z": true, "ES-ZA": true,
+ "ET-AA": true, "ET-AF": true, "ET-AM": true, "ET-BE": true, "ET-DD": true,
+ "ET-GA": true, "ET-HA": true, "ET-OR": true, "ET-SN": true, "ET-SO": true,
+ "ET-TI": true, "FI-01": true, "FI-02": true, "FI-03": true, "FI-04": true,
+ "FI-05": true, "FI-06": true, "FI-07": true, "FI-08": true, "FI-09": true,
+ "FI-10": true, "FI-11": true, "FI-12": true, "FI-13": true, "FI-14": true,
+ "FI-15": true, "FI-16": true, "FI-17": true, "FI-18": true, "FI-19": true,
+ "FJ-C": true, "FJ-E": true, "FJ-N": true, "FJ-R": true, "FJ-W": true,
+ "FM-KSA": true, "FM-PNI": true, "FM-TRK": true, "FM-YAP": true, "FR-01": true,
+ "FR-02": true, "FR-03": true, "FR-04": true, "FR-05": true, "FR-06": true,
+ "FR-07": true, "FR-08": true, "FR-09": true, "FR-10": true, "FR-11": true,
+ "FR-12": true, "FR-13": true, "FR-14": true, "FR-15": true, "FR-16": true,
+ "FR-17": true, "FR-18": true, "FR-19": true, "FR-20R": true, "FR-21": true, "FR-22": true,
+ "FR-23": true, "FR-24": true, "FR-25": true, "FR-26": true, "FR-27": true,
+ "FR-28": true, "FR-29": true, "FR-2A": true, "FR-2B": true, "FR-30": true,
+ "FR-31": true, "FR-32": true, "FR-33": true, "FR-34": true, "FR-35": true,
+ "FR-36": true, "FR-37": true, "FR-38": true, "FR-39": true, "FR-40": true,
+ "FR-41": true, "FR-42": true, "FR-43": true, "FR-44": true, "FR-45": true,
+ "FR-46": true, "FR-47": true, "FR-48": true, "FR-49": true, "FR-50": true,
+ "FR-51": true, "FR-52": true, "FR-53": true, "FR-54": true, "FR-55": true,
+ "FR-56": true, "FR-57": true, "FR-58": true, "FR-59": true, "FR-60": true,
+ "FR-61": true, "FR-62": true, "FR-63": true, "FR-64": true, "FR-65": true,
+ "FR-66": true, "FR-67": true, "FR-68": true, "FR-69": true, "FR-70": true,
+ "FR-71": true, "FR-72": true, "FR-73": true, "FR-74": true, "FR-75": true,
+ "FR-76": true, "FR-77": true, "FR-78": true, "FR-79": true, "FR-80": true,
+ "FR-81": true, "FR-82": true, "FR-83": true, "FR-84": true, "FR-85": true,
+ "FR-86": true, "FR-87": true, "FR-88": true, "FR-89": true, "FR-90": true,
+ "FR-91": true, "FR-92": true, "FR-93": true, "FR-94": true, "FR-95": true,
+ "FR-ARA": true, "FR-BFC": true, "FR-BL": true, "FR-BRE": true, "FR-COR": true,
+ "FR-CP": true, "FR-CVL": true, "FR-GES": true, "FR-GF": true, "FR-GP": true,
+ "FR-GUA": true, "FR-HDF": true, "FR-IDF": true, "FR-LRE": true, "FR-MAY": true,
+ "FR-MF": true, "FR-MQ": true, "FR-NAQ": true, "FR-NC": true, "FR-NOR": true,
+ "FR-OCC": true, "FR-PAC": true, "FR-PDL": true, "FR-PF": true, "FR-PM": true,
+ "FR-RE": true, "FR-TF": true, "FR-WF": true, "FR-YT": true, "GA-1": true,
+ "GA-2": true, "GA-3": true, "GA-4": true, "GA-5": true, "GA-6": true,
+ "GA-7": true, "GA-8": true, "GA-9": true, "GB-ABC": true, "GB-ABD": true,
+ "GB-ABE": true, "GB-AGB": true, "GB-AGY": true, "GB-AND": true, "GB-ANN": true,
+ "GB-ANS": true, "GB-BAS": true, "GB-BBD": true, "GB-BDF": true, "GB-BDG": true,
+ "GB-BEN": true, "GB-BEX": true, "GB-BFS": true, "GB-BGE": true, "GB-BGW": true,
+ "GB-BIR": true, "GB-BKM": true, "GB-BMH": true, "GB-BNE": true, "GB-BNH": true,
+ "GB-BNS": true, "GB-BOL": true, "GB-BPL": true, "GB-BRC": true, "GB-BRD": true,
+ "GB-BRY": true, "GB-BST": true, "GB-BUR": true, "GB-CAM": true, "GB-CAY": true,
+ "GB-CBF": true, "GB-CCG": true, "GB-CGN": true, "GB-CHE": true, "GB-CHW": true,
+ "GB-CLD": true, "GB-CLK": true, "GB-CMA": true, "GB-CMD": true, "GB-CMN": true,
+ "GB-CON": true, "GB-COV": true, "GB-CRF": true, "GB-CRY": true, "GB-CWY": true,
+ "GB-DAL": true, "GB-DBY": true, "GB-DEN": true, "GB-DER": true, "GB-DEV": true,
+ "GB-DGY": true, "GB-DNC": true, "GB-DND": true, "GB-DOR": true, "GB-DRS": true,
+ "GB-DUD": true, "GB-DUR": true, "GB-EAL": true, "GB-EAW": true, "GB-EAY": true,
+ "GB-EDH": true, "GB-EDU": true, "GB-ELN": true, "GB-ELS": true, "GB-ENF": true,
+ "GB-ENG": true, "GB-ERW": true, "GB-ERY": true, "GB-ESS": true, "GB-ESX": true,
+ "GB-FAL": true, "GB-FIF": true, "GB-FLN": true, "GB-FMO": true, "GB-GAT": true,
+ "GB-GBN": true, "GB-GLG": true, "GB-GLS": true, "GB-GRE": true, "GB-GWN": true,
+ "GB-HAL": true, "GB-HAM": true, "GB-HAV": true, "GB-HCK": true, "GB-HEF": true,
+ "GB-HIL": true, "GB-HLD": true, "GB-HMF": true, "GB-HNS": true, "GB-HPL": true,
+ "GB-HRT": true, "GB-HRW": true, "GB-HRY": true, "GB-IOS": true, "GB-IOW": true,
+ "GB-ISL": true, "GB-IVC": true, "GB-KEC": true, "GB-KEN": true, "GB-KHL": true,
+ "GB-KIR": true, "GB-KTT": true, "GB-KWL": true, "GB-LAN": true, "GB-LBC": true,
+ "GB-LBH": true, "GB-LCE": true, "GB-LDS": true, "GB-LEC": true, "GB-LEW": true,
+ "GB-LIN": true, "GB-LIV": true, "GB-LND": true, "GB-LUT": true, "GB-MAN": true,
+ "GB-MDB": true, "GB-MDW": true, "GB-MEA": true, "GB-MIK": true, "GD-01": true,
+ "GB-MLN": true, "GB-MON": true, "GB-MRT": true, "GB-MRY": true, "GB-MTY": true,
+ "GB-MUL": true, "GB-NAY": true, "GB-NBL": true, "GB-NEL": true, "GB-NET": true,
+ "GB-NFK": true, "GB-NGM": true, "GB-NIR": true, "GB-NLK": true, "GB-NLN": true,
+ "GB-NMD": true, "GB-NSM": true, "GB-NTH": true, "GB-NTL": true, "GB-NTT": true,
+ "GB-NTY": true, "GB-NWM": true, "GB-NWP": true, "GB-NYK": true, "GB-OLD": true,
+ "GB-ORK": true, "GB-OXF": true, "GB-PEM": true, "GB-PKN": true, "GB-PLY": true,
+ "GB-POL": true, "GB-POR": true, "GB-POW": true, "GB-PTE": true, "GB-RCC": true,
+ "GB-RCH": true, "GB-RCT": true, "GB-RDB": true, "GB-RDG": true, "GB-RFW": true,
+ "GB-RIC": true, "GB-ROT": true, "GB-RUT": true, "GB-SAW": true, "GB-SAY": true,
+ "GB-SCB": true, "GB-SCT": true, "GB-SFK": true, "GB-SFT": true, "GB-SGC": true,
+ "GB-SHF": true, "GB-SHN": true, "GB-SHR": true, "GB-SKP": true, "GB-SLF": true,
+ "GB-SLG": true, "GB-SLK": true, "GB-SND": true, "GB-SOL": true, "GB-SOM": true,
+ "GB-SOS": true, "GB-SRY": true, "GB-STE": true, "GB-STG": true, "GB-STH": true,
+ "GB-STN": true, "GB-STS": true, "GB-STT": true, "GB-STY": true, "GB-SWA": true,
+ "GB-SWD": true, "GB-SWK": true, "GB-TAM": true, "GB-TFW": true, "GB-THR": true,
+ "GB-TOB": true, "GB-TOF": true, "GB-TRF": true, "GB-TWH": true, "GB-UKM": true,
+ "GB-VGL": true, "GB-WAR": true, "GB-WBK": true, "GB-WDU": true, "GB-WFT": true,
+ "GB-WGN": true, "GB-WIL": true, "GB-WKF": true, "GB-WLL": true, "GB-WLN": true,
+ "GB-WLS": true, "GB-WLV": true, "GB-WND": true, "GB-WNM": true, "GB-WOK": true,
+ "GB-WOR": true, "GB-WRL": true, "GB-WRT": true, "GB-WRX": true, "GB-WSM": true,
+ "GB-WSX": true, "GB-YOR": true, "GB-ZET": true, "GD-02": true, "GD-03": true,
+ "GD-04": true, "GD-05": true, "GD-06": true, "GD-10": true, "GE-AB": true,
+ "GE-AJ": true, "GE-GU": true, "GE-IM": true, "GE-KA": true, "GE-KK": true,
+ "GE-MM": true, "GE-RL": true, "GE-SJ": true, "GE-SK": true, "GE-SZ": true,
+ "GE-TB": true, "GH-AA": true, "GH-AH": true, "GH-AF": true, "GH-BA": true, "GH-BO": true, "GH-BE": true, "GH-CP": true,
+ "GH-EP": true, "GH-NP": true, "GH-TV": true, "GH-UE": true, "GH-UW": true,
+ "GH-WP": true, "GL-AV": true, "GL-KU": true, "GL-QA": true, "GL-QT": true, "GL-QE": true, "GL-SM": true,
+ "GM-B": true, "GM-L": true, "GM-M": true, "GM-N": true, "GM-U": true,
+ "GM-W": true, "GN-B": true, "GN-BE": true, "GN-BF": true, "GN-BK": true,
+ "GN-C": true, "GN-CO": true, "GN-D": true, "GN-DB": true, "GN-DI": true,
+ "GN-DL": true, "GN-DU": true, "GN-F": true, "GN-FA": true, "GN-FO": true,
+ "GN-FR": true, "GN-GA": true, "GN-GU": true, "GN-K": true, "GN-KA": true,
+ "GN-KB": true, "GN-KD": true, "GN-KE": true, "GN-KN": true, "GN-KO": true,
+ "GN-KS": true, "GN-L": true, "GN-LA": true, "GN-LE": true, "GN-LO": true,
+ "GN-M": true, "GN-MC": true, "GN-MD": true, "GN-ML": true, "GN-MM": true,
+ "GN-N": true, "GN-NZ": true, "GN-PI": true, "GN-SI": true, "GN-TE": true,
+ "GN-TO": true, "GN-YO": true, "GQ-AN": true, "GQ-BN": true, "GQ-BS": true,
+ "GQ-C": true, "GQ-CS": true, "GQ-I": true, "GQ-KN": true, "GQ-LI": true,
+ "GQ-WN": true, "GR-01": true, "GR-03": true, "GR-04": true, "GR-05": true,
+ "GR-06": true, "GR-07": true, "GR-11": true, "GR-12": true, "GR-13": true,
+ "GR-14": true, "GR-15": true, "GR-16": true, "GR-17": true, "GR-21": true,
+ "GR-22": true, "GR-23": true, "GR-24": true, "GR-31": true, "GR-32": true,
+ "GR-33": true, "GR-34": true, "GR-41": true, "GR-42": true, "GR-43": true,
+ "GR-44": true, "GR-51": true, "GR-52": true, "GR-53": true, "GR-54": true,
+ "GR-55": true, "GR-56": true, "GR-57": true, "GR-58": true, "GR-59": true,
+ "GR-61": true, "GR-62": true, "GR-63": true, "GR-64": true, "GR-69": true,
+ "GR-71": true, "GR-72": true, "GR-73": true, "GR-81": true, "GR-82": true,
+ "GR-83": true, "GR-84": true, "GR-85": true, "GR-91": true, "GR-92": true,
+ "GR-93": true, "GR-94": true, "GR-A": true, "GR-A1": true, "GR-B": true,
+ "GR-C": true, "GR-D": true, "GR-E": true, "GR-F": true, "GR-G": true,
+ "GR-H": true, "GR-I": true, "GR-J": true, "GR-K": true, "GR-L": true,
+ "GR-M": true, "GT-01": true, "GT-02": true, "GT-03": true, "GT-04": true,
+ "GT-05": true, "GT-06": true, "GT-07": true, "GT-08": true, "GT-09": true,
+ "GT-10": true, "GT-11": true, "GT-12": true, "GT-13": true, "GT-14": true,
+ "GT-15": true, "GT-16": true, "GT-17": true, "GT-18": true, "GT-19": true,
+ "GT-20": true, "GT-21": true, "GT-22": true, "GW-BA": true, "GW-BL": true,
+ "GW-BM": true, "GW-BS": true, "GW-CA": true, "GW-GA": true, "GW-L": true,
+ "GW-N": true, "GW-OI": true, "GW-QU": true, "GW-S": true, "GW-TO": true,
+ "GY-BA": true, "GY-CU": true, "GY-DE": true, "GY-EB": true, "GY-ES": true,
+ "GY-MA": true, "GY-PM": true, "GY-PT": true, "GY-UD": true, "GY-UT": true,
+ "HN-AT": true, "HN-CH": true, "HN-CL": true, "HN-CM": true, "HN-CP": true,
+ "HN-CR": true, "HN-EP": true, "HN-FM": true, "HN-GD": true, "HN-IB": true,
+ "HN-IN": true, "HN-LE": true, "HN-LP": true, "HN-OC": true, "HN-OL": true,
+ "HN-SB": true, "HN-VA": true, "HN-YO": true, "HR-01": true, "HR-02": true,
+ "HR-03": true, "HR-04": true, "HR-05": true, "HR-06": true, "HR-07": true,
+ "HR-08": true, "HR-09": true, "HR-10": true, "HR-11": true, "HR-12": true,
+ "HR-13": true, "HR-14": true, "HR-15": true, "HR-16": true, "HR-17": true,
+ "HR-18": true, "HR-19": true, "HR-20": true, "HR-21": true, "HT-AR": true,
+ "HT-CE": true, "HT-GA": true, "HT-ND": true, "HT-NE": true, "HT-NO": true, "HT-NI": true,
+ "HT-OU": true, "HT-SD": true, "HT-SE": true, "HU-BA": true, "HU-BC": true,
+ "HU-BE": true, "HU-BK": true, "HU-BU": true, "HU-BZ": true, "HU-CS": true,
+ "HU-DE": true, "HU-DU": true, "HU-EG": true, "HU-ER": true, "HU-FE": true,
+ "HU-GS": true, "HU-GY": true, "HU-HB": true, "HU-HE": true, "HU-HV": true,
+ "HU-JN": true, "HU-KE": true, "HU-KM": true, "HU-KV": true, "HU-MI": true,
+ "HU-NK": true, "HU-NO": true, "HU-NY": true, "HU-PE": true, "HU-PS": true,
+ "HU-SD": true, "HU-SF": true, "HU-SH": true, "HU-SK": true, "HU-SN": true,
+ "HU-SO": true, "HU-SS": true, "HU-ST": true, "HU-SZ": true, "HU-TB": true,
+ "HU-TO": true, "HU-VA": true, "HU-VE": true, "HU-VM": true, "HU-ZA": true,
+ "HU-ZE": true, "ID-AC": true, "ID-BA": true, "ID-BB": true, "ID-BE": true,
+ "ID-BT": true, "ID-GO": true, "ID-IJ": true, "ID-JA": true, "ID-JB": true,
+ "ID-JI": true, "ID-JK": true, "ID-JT": true, "ID-JW": true, "ID-KA": true,
+ "ID-KB": true, "ID-KI": true, "ID-KU": true, "ID-KR": true, "ID-KS": true,
+ "ID-KT": true, "ID-LA": true, "ID-MA": true, "ID-ML": true, "ID-MU": true,
+ "ID-NB": true, "ID-NT": true, "ID-NU": true, "ID-PA": true, "ID-PB": true,
+ "ID-PE": true, "ID-PP": true, "ID-PS": true, "ID-PT": true, "ID-RI": true,
+ "ID-SA": true, "ID-SB": true, "ID-SG": true, "ID-SL": true, "ID-SM": true,
+ "ID-SN": true, "ID-SR": true, "ID-SS": true, "ID-ST": true, "ID-SU": true,
+ "ID-YO": true, "IE-C": true, "IE-CE": true, "IE-CN": true, "IE-CO": true,
+ "IE-CW": true, "IE-D": true, "IE-DL": true, "IE-G": true, "IE-KE": true,
+ "IE-KK": true, "IE-KY": true, "IE-L": true, "IE-LD": true, "IE-LH": true,
+ "IE-LK": true, "IE-LM": true, "IE-LS": true, "IE-M": true, "IE-MH": true,
+ "IE-MN": true, "IE-MO": true, "IE-OY": true, "IE-RN": true, "IE-SO": true,
+ "IE-TA": true, "IE-U": true, "IE-WD": true, "IE-WH": true, "IE-WW": true,
+ "IE-WX": true, "IL-D": true, "IL-HA": true, "IL-JM": true, "IL-M": true,
+ "IL-TA": true, "IL-Z": true, "IN-AN": true, "IN-AP": true, "IN-AR": true,
+ "IN-AS": true, "IN-BR": true, "IN-CH": true, "IN-CT": true, "IN-DH": true,
+ "IN-DL": true, "IN-DN": true, "IN-GA": true, "IN-GJ": true, "IN-HP": true,
+ "IN-HR": true, "IN-JH": true, "IN-JK": true, "IN-KA": true, "IN-KL": true,
+ "IN-LD": true, "IN-MH": true, "IN-ML": true, "IN-MN": true, "IN-MP": true,
+ "IN-MZ": true, "IN-NL": true, "IN-TG": true, "IN-OR": true, "IN-PB": true, "IN-PY": true,
+ "IN-RJ": true, "IN-SK": true, "IN-TN": true, "IN-TR": true, "IN-UP": true,
+ "IN-UT": true, "IN-WB": true, "IQ-AN": true, "IQ-AR": true, "IQ-BA": true,
+ "IQ-BB": true, "IQ-BG": true, "IQ-DA": true, "IQ-DI": true, "IQ-DQ": true,
+ "IQ-KA": true, "IQ-KI": true, "IQ-MA": true, "IQ-MU": true, "IQ-NA": true, "IQ-NI": true,
+ "IQ-QA": true, "IQ-SD": true, "IQ-SW": true, "IQ-SU": true, "IQ-TS": true, "IQ-WA": true,
+ "IR-00": true, "IR-01": true, "IR-02": true, "IR-03": true, "IR-04": true, "IR-05": true,
+ "IR-06": true, "IR-07": true, "IR-08": true, "IR-09": true, "IR-10": true, "IR-11": true,
+ "IR-12": true, "IR-13": true, "IR-14": true, "IR-15": true, "IR-16": true,
+ "IR-17": true, "IR-18": true, "IR-19": true, "IR-20": true, "IR-21": true,
+ "IR-22": true, "IR-23": true, "IR-24": true, "IR-25": true, "IR-26": true,
+ "IR-27": true, "IR-28": true, "IR-29": true, "IR-30": true, "IR-31": true,
+ "IS-0": true, "IS-1": true, "IS-2": true, "IS-3": true, "IS-4": true,
+ "IS-5": true, "IS-6": true, "IS-7": true, "IS-8": true, "IT-21": true,
+ "IT-23": true, "IT-25": true, "IT-32": true, "IT-34": true, "IT-36": true,
+ "IT-42": true, "IT-45": true, "IT-52": true, "IT-55": true, "IT-57": true,
+ "IT-62": true, "IT-65": true, "IT-67": true, "IT-72": true, "IT-75": true,
+ "IT-77": true, "IT-78": true, "IT-82": true, "IT-88": true, "IT-AG": true,
+ "IT-AL": true, "IT-AN": true, "IT-AO": true, "IT-AP": true, "IT-AQ": true,
+ "IT-AR": true, "IT-AT": true, "IT-AV": true, "IT-BA": true, "IT-BG": true,
+ "IT-BI": true, "IT-BL": true, "IT-BN": true, "IT-BO": true, "IT-BR": true,
+ "IT-BS": true, "IT-BT": true, "IT-BZ": true, "IT-CA": true, "IT-CB": true,
+ "IT-CE": true, "IT-CH": true, "IT-CI": true, "IT-CL": true, "IT-CN": true,
+ "IT-CO": true, "IT-CR": true, "IT-CS": true, "IT-CT": true, "IT-CZ": true,
+ "IT-EN": true, "IT-FC": true, "IT-FE": true, "IT-FG": true, "IT-FI": true,
+ "IT-FM": true, "IT-FR": true, "IT-GE": true, "IT-GO": true, "IT-GR": true,
+ "IT-IM": true, "IT-IS": true, "IT-KR": true, "IT-LC": true, "IT-LE": true,
+ "IT-LI": true, "IT-LO": true, "IT-LT": true, "IT-LU": true, "IT-MB": true,
+ "IT-MC": true, "IT-ME": true, "IT-MI": true, "IT-MN": true, "IT-MO": true,
+ "IT-MS": true, "IT-MT": true, "IT-NA": true, "IT-NO": true, "IT-NU": true,
+ "IT-OG": true, "IT-OR": true, "IT-OT": true, "IT-PA": true, "IT-PC": true,
+ "IT-PD": true, "IT-PE": true, "IT-PG": true, "IT-PI": true, "IT-PN": true,
+ "IT-PO": true, "IT-PR": true, "IT-PT": true, "IT-PU": true, "IT-PV": true,
+ "IT-PZ": true, "IT-RA": true, "IT-RC": true, "IT-RE": true, "IT-RG": true,
+ "IT-RI": true, "IT-RM": true, "IT-RN": true, "IT-RO": true, "IT-SA": true,
+ "IT-SI": true, "IT-SO": true, "IT-SP": true, "IT-SR": true, "IT-SS": true,
+ "IT-SV": true, "IT-TA": true, "IT-TE": true, "IT-TN": true, "IT-TO": true,
+ "IT-TP": true, "IT-TR": true, "IT-TS": true, "IT-TV": true, "IT-UD": true,
+ "IT-VA": true, "IT-VB": true, "IT-VC": true, "IT-VE": true, "IT-VI": true,
+ "IT-VR": true, "IT-VS": true, "IT-VT": true, "IT-VV": true, "JM-01": true,
+ "JM-02": true, "JM-03": true, "JM-04": true, "JM-05": true, "JM-06": true,
+ "JM-07": true, "JM-08": true, "JM-09": true, "JM-10": true, "JM-11": true,
+ "JM-12": true, "JM-13": true, "JM-14": true, "JO-AJ": true, "JO-AM": true,
+ "JO-AQ": true, "JO-AT": true, "JO-AZ": true, "JO-BA": true, "JO-IR": true,
+ "JO-JA": true, "JO-KA": true, "JO-MA": true, "JO-MD": true, "JO-MN": true,
+ "JP-01": true, "JP-02": true, "JP-03": true, "JP-04": true, "JP-05": true,
+ "JP-06": true, "JP-07": true, "JP-08": true, "JP-09": true, "JP-10": true,
+ "JP-11": true, "JP-12": true, "JP-13": true, "JP-14": true, "JP-15": true,
+ "JP-16": true, "JP-17": true, "JP-18": true, "JP-19": true, "JP-20": true,
+ "JP-21": true, "JP-22": true, "JP-23": true, "JP-24": true, "JP-25": true,
+ "JP-26": true, "JP-27": true, "JP-28": true, "JP-29": true, "JP-30": true,
+ "JP-31": true, "JP-32": true, "JP-33": true, "JP-34": true, "JP-35": true,
+ "JP-36": true, "JP-37": true, "JP-38": true, "JP-39": true, "JP-40": true,
+ "JP-41": true, "JP-42": true, "JP-43": true, "JP-44": true, "JP-45": true,
+ "JP-46": true, "JP-47": true, "KE-01": true, "KE-02": true, "KE-03": true,
+ "KE-04": true, "KE-05": true, "KE-06": true, "KE-07": true, "KE-08": true,
+ "KE-09": true, "KE-10": true, "KE-11": true, "KE-12": true, "KE-13": true,
+ "KE-14": true, "KE-15": true, "KE-16": true, "KE-17": true, "KE-18": true,
+ "KE-19": true, "KE-20": true, "KE-21": true, "KE-22": true, "KE-23": true,
+ "KE-24": true, "KE-25": true, "KE-26": true, "KE-27": true, "KE-28": true,
+ "KE-29": true, "KE-30": true, "KE-31": true, "KE-32": true, "KE-33": true,
+ "KE-34": true, "KE-35": true, "KE-36": true, "KE-37": true, "KE-38": true,
+ "KE-39": true, "KE-40": true, "KE-41": true, "KE-42": true, "KE-43": true,
+ "KE-44": true, "KE-45": true, "KE-46": true, "KE-47": true, "KG-B": true,
+ "KG-C": true, "KG-GB": true, "KG-GO": true, "KG-J": true, "KG-N": true, "KG-O": true,
+ "KG-T": true, "KG-Y": true, "KH-1": true, "KH-10": true, "KH-11": true,
+ "KH-12": true, "KH-13": true, "KH-14": true, "KH-15": true, "KH-16": true,
+ "KH-17": true, "KH-18": true, "KH-19": true, "KH-2": true, "KH-20": true,
+ "KH-21": true, "KH-22": true, "KH-23": true, "KH-24": true, "KH-3": true,
+ "KH-4": true, "KH-5": true, "KH-6": true, "KH-7": true, "KH-8": true,
+ "KH-9": true, "KI-G": true, "KI-L": true, "KI-P": true, "KM-A": true,
+ "KM-G": true, "KM-M": true, "KN-01": true, "KN-02": true, "KN-03": true,
+ "KN-04": true, "KN-05": true, "KN-06": true, "KN-07": true, "KN-08": true,
+ "KN-09": true, "KN-10": true, "KN-11": true, "KN-12": true, "KN-13": true,
+ "KN-15": true, "KN-K": true, "KN-N": true, "KP-01": true, "KP-02": true,
+ "KP-03": true, "KP-04": true, "KP-05": true, "KP-06": true, "KP-07": true,
+ "KP-08": true, "KP-09": true, "KP-10": true, "KP-13": true, "KR-11": true,
+ "KR-26": true, "KR-27": true, "KR-28": true, "KR-29": true, "KR-30": true,
+ "KR-31": true, "KR-41": true, "KR-42": true, "KR-43": true, "KR-44": true,
+ "KR-45": true, "KR-46": true, "KR-47": true, "KR-48": true, "KR-49": true,
+ "KW-AH": true, "KW-FA": true, "KW-HA": true, "KW-JA": true, "KW-KU": true,
+ "KW-MU": true, "KZ-10": true, "KZ-75": true, "KZ-19": true, "KZ-11": true,
+ "KZ-15": true, "KZ-71": true, "KZ-23": true, "KZ-27": true, "KZ-47": true,
+ "KZ-55": true, "KZ-35": true, "KZ-39": true, "KZ-43": true, "KZ-63": true,
+ "KZ-79": true, "KZ-59": true, "KZ-61": true, "KZ-62": true, "KZ-31": true,
+ "KZ-33": true, "LA-AT": true, "LA-BK": true, "LA-BL": true,
+ "LA-CH": true, "LA-HO": true, "LA-KH": true, "LA-LM": true, "LA-LP": true,
+ "LA-OU": true, "LA-PH": true, "LA-SL": true, "LA-SV": true, "LA-VI": true,
+ "LA-VT": true, "LA-XA": true, "LA-XE": true, "LA-XI": true, "LA-XS": true,
+ "LB-AK": true, "LB-AS": true, "LB-BA": true, "LB-BH": true, "LB-BI": true,
+ "LB-JA": true, "LB-JL": true, "LB-NA": true, "LC-01": true, "LC-02": true,
+ "LC-03": true, "LC-05": true, "LC-06": true, "LC-07": true, "LC-08": true,
+ "LC-10": true, "LC-11": true, "LI-01": true, "LI-02": true,
+ "LI-03": true, "LI-04": true, "LI-05": true, "LI-06": true, "LI-07": true,
+ "LI-08": true, "LI-09": true, "LI-10": true, "LI-11": true, "LK-1": true,
+ "LK-11": true, "LK-12": true, "LK-13": true, "LK-2": true, "LK-21": true,
+ "LK-22": true, "LK-23": true, "LK-3": true, "LK-31": true, "LK-32": true,
+ "LK-33": true, "LK-4": true, "LK-41": true, "LK-42": true, "LK-43": true,
+ "LK-44": true, "LK-45": true, "LK-5": true, "LK-51": true, "LK-52": true,
+ "LK-53": true, "LK-6": true, "LK-61": true, "LK-62": true, "LK-7": true,
+ "LK-71": true, "LK-72": true, "LK-8": true, "LK-81": true, "LK-82": true,
+ "LK-9": true, "LK-91": true, "LK-92": true, "LR-BG": true, "LR-BM": true,
+ "LR-CM": true, "LR-GB": true, "LR-GG": true, "LR-GK": true, "LR-LO": true,
+ "LR-MG": true, "LR-MO": true, "LR-MY": true, "LR-NI": true, "LR-RI": true,
+ "LR-SI": true, "LS-A": true, "LS-B": true, "LS-C": true, "LS-D": true,
+ "LS-E": true, "LS-F": true, "LS-G": true, "LS-H": true, "LS-J": true,
+ "LS-K": true, "LT-AL": true, "LT-KL": true, "LT-KU": true, "LT-MR": true,
+ "LT-PN": true, "LT-SA": true, "LT-TA": true, "LT-TE": true, "LT-UT": true,
+ "LT-VL": true, "LU-CA": true, "LU-CL": true, "LU-DI": true, "LU-EC": true,
+ "LU-ES": true, "LU-GR": true, "LU-LU": true, "LU-ME": true, "LU-RD": true,
+ "LU-RM": true, "LU-VD": true, "LU-WI": true, "LU-D": true, "LU-G": true, "LU-L": true,
+ "LV-001": true, "LV-111": true, "LV-112": true, "LV-113": true,
+ "LV-002": true, "LV-003": true, "LV-004": true, "LV-005": true, "LV-006": true,
+ "LV-007": true, "LV-008": true, "LV-009": true, "LV-010": true, "LV-011": true,
+ "LV-012": true, "LV-013": true, "LV-014": true, "LV-015": true, "LV-016": true,
+ "LV-017": true, "LV-018": true, "LV-019": true, "LV-020": true, "LV-021": true,
+ "LV-022": true, "LV-023": true, "LV-024": true, "LV-025": true, "LV-026": true,
+ "LV-027": true, "LV-028": true, "LV-029": true, "LV-030": true, "LV-031": true,
+ "LV-032": true, "LV-033": true, "LV-034": true, "LV-035": true, "LV-036": true,
+ "LV-037": true, "LV-038": true, "LV-039": true, "LV-040": true, "LV-041": true,
+ "LV-042": true, "LV-043": true, "LV-044": true, "LV-045": true, "LV-046": true,
+ "LV-047": true, "LV-048": true, "LV-049": true, "LV-050": true, "LV-051": true,
+ "LV-052": true, "LV-053": true, "LV-054": true, "LV-055": true, "LV-056": true,
+ "LV-057": true, "LV-058": true, "LV-059": true, "LV-060": true, "LV-061": true,
+ "LV-062": true, "LV-063": true, "LV-064": true, "LV-065": true, "LV-066": true,
+ "LV-067": true, "LV-068": true, "LV-069": true, "LV-070": true, "LV-071": true,
+ "LV-072": true, "LV-073": true, "LV-074": true, "LV-075": true, "LV-076": true,
+ "LV-077": true, "LV-078": true, "LV-079": true, "LV-080": true, "LV-081": true,
+ "LV-082": true, "LV-083": true, "LV-084": true, "LV-085": true, "LV-086": true,
+ "LV-087": true, "LV-088": true, "LV-089": true, "LV-090": true, "LV-091": true,
+ "LV-092": true, "LV-093": true, "LV-094": true, "LV-095": true, "LV-096": true,
+ "LV-097": true, "LV-098": true, "LV-099": true, "LV-100": true, "LV-101": true,
+ "LV-102": true, "LV-103": true, "LV-104": true, "LV-105": true, "LV-106": true,
+ "LV-107": true, "LV-108": true, "LV-109": true, "LV-110": true, "LV-DGV": true,
+ "LV-JEL": true, "LV-JKB": true, "LV-JUR": true, "LV-LPX": true, "LV-REZ": true,
+ "LV-RIX": true, "LV-VEN": true, "LV-VMR": true, "LY-BA": true, "LY-BU": true,
+ "LY-DR": true, "LY-GT": true, "LY-JA": true, "LY-JB": true, "LY-JG": true,
+ "LY-JI": true, "LY-JU": true, "LY-KF": true, "LY-MB": true, "LY-MI": true,
+ "LY-MJ": true, "LY-MQ": true, "LY-NL": true, "LY-NQ": true, "LY-SB": true,
+ "LY-SR": true, "LY-TB": true, "LY-WA": true, "LY-WD": true, "LY-WS": true,
+ "LY-ZA": true, "MA-01": true, "MA-02": true, "MA-03": true, "MA-04": true,
+ "MA-05": true, "MA-06": true, "MA-07": true, "MA-08": true, "MA-09": true,
+ "MA-10": true, "MA-11": true, "MA-12": true, "MA-13": true, "MA-14": true,
+ "MA-15": true, "MA-16": true, "MA-AGD": true, "MA-AOU": true, "MA-ASZ": true,
+ "MA-AZI": true, "MA-BEM": true, "MA-BER": true, "MA-BES": true, "MA-BOD": true,
+ "MA-BOM": true, "MA-CAS": true, "MA-CHE": true, "MA-CHI": true, "MA-CHT": true,
+ "MA-ERR": true, "MA-ESI": true, "MA-ESM": true, "MA-FAH": true, "MA-FES": true,
+ "MA-FIG": true, "MA-GUE": true, "MA-HAJ": true, "MA-HAO": true, "MA-HOC": true,
+ "MA-IFR": true, "MA-INE": true, "MA-JDI": true, "MA-JRA": true, "MA-KEN": true,
+ "MA-KES": true, "MA-KHE": true, "MA-KHN": true, "MA-KHO": true, "MA-LAA": true,
+ "MA-LAR": true, "MA-MED": true, "MA-MEK": true, "MA-MMD": true, "MA-MMN": true,
+ "MA-MOH": true, "MA-MOU": true, "MA-NAD": true, "MA-NOU": true, "MA-OUA": true,
+ "MA-OUD": true, "MA-OUJ": true, "MA-RAB": true, "MA-SAF": true, "MA-SAL": true,
+ "MA-SEF": true, "MA-SET": true, "MA-SIK": true, "MA-SKH": true, "MA-SYB": true,
+ "MA-TAI": true, "MA-TAO": true, "MA-TAR": true, "MA-TAT": true, "MA-TAZ": true,
+ "MA-TET": true, "MA-TIZ": true, "MA-TNG": true, "MA-TNT": true, "MA-ZAG": true,
+ "MC-CL": true, "MC-CO": true, "MC-FO": true, "MC-GA": true, "MC-JE": true,
+ "MC-LA": true, "MC-MA": true, "MC-MC": true, "MC-MG": true, "MC-MO": true,
+ "MC-MU": true, "MC-PH": true, "MC-SD": true, "MC-SO": true, "MC-SP": true,
+ "MC-SR": true, "MC-VR": true, "MD-AN": true, "MD-BA": true, "MD-BD": true,
+ "MD-BR": true, "MD-BS": true, "MD-CA": true, "MD-CL": true, "MD-CM": true,
+ "MD-CR": true, "MD-CS": true, "MD-CT": true, "MD-CU": true, "MD-DO": true,
+ "MD-DR": true, "MD-DU": true, "MD-ED": true, "MD-FA": true, "MD-FL": true,
+ "MD-GA": true, "MD-GL": true, "MD-HI": true, "MD-IA": true, "MD-LE": true,
+ "MD-NI": true, "MD-OC": true, "MD-OR": true, "MD-RE": true, "MD-RI": true,
+ "MD-SD": true, "MD-SI": true, "MD-SN": true, "MD-SO": true, "MD-ST": true,
+ "MD-SV": true, "MD-TA": true, "MD-TE": true, "MD-UN": true, "ME-01": true,
+ "ME-02": true, "ME-03": true, "ME-04": true, "ME-05": true, "ME-06": true,
+ "ME-07": true, "ME-08": true, "ME-09": true, "ME-10": true, "ME-11": true,
+ "ME-12": true, "ME-13": true, "ME-14": true, "ME-15": true, "ME-16": true,
+ "ME-17": true, "ME-18": true, "ME-19": true, "ME-20": true, "ME-21": true, "ME-24": true,
+ "MG-A": true, "MG-D": true, "MG-F": true, "MG-M": true, "MG-T": true,
+ "MG-U": true, "MH-ALK": true, "MH-ALL": true, "MH-ARN": true, "MH-AUR": true,
+ "MH-EBO": true, "MH-ENI": true, "MH-JAB": true, "MH-JAL": true, "MH-KIL": true,
+ "MH-KWA": true, "MH-L": true, "MH-LAE": true, "MH-LIB": true, "MH-LIK": true,
+ "MH-MAJ": true, "MH-MAL": true, "MH-MEJ": true, "MH-MIL": true, "MH-NMK": true,
+ "MH-NMU": true, "MH-RON": true, "MH-T": true, "MH-UJA": true, "MH-UTI": true,
+ "MH-WTJ": true, "MH-WTN": true, "MK-101": true, "MK-102": true, "MK-103": true,
+ "MK-104": true, "MK-105": true,
+ "MK-106": true, "MK-107": true, "MK-108": true, "MK-109": true, "MK-201": true,
+ "MK-202": true, "MK-205": true, "MK-206": true, "MK-207": true, "MK-208": true,
+ "MK-209": true, "MK-210": true, "MK-211": true, "MK-301": true, "MK-303": true,
+ "MK-307": true, "MK-308": true, "MK-310": true, "MK-311": true, "MK-312": true,
+ "MK-401": true, "MK-402": true, "MK-403": true, "MK-404": true, "MK-405": true,
+ "MK-406": true, "MK-408": true, "MK-409": true, "MK-410": true, "MK-501": true,
+ "MK-502": true, "MK-503": true, "MK-505": true, "MK-506": true, "MK-507": true,
+ "MK-508": true, "MK-509": true, "MK-601": true, "MK-602": true, "MK-604": true,
+ "MK-605": true, "MK-606": true, "MK-607": true, "MK-608": true, "MK-609": true,
+ "MK-701": true, "MK-702": true, "MK-703": true, "MK-704": true, "MK-705": true,
+ "MK-803": true, "MK-804": true, "MK-806": true, "MK-807": true, "MK-809": true,
+ "MK-810": true, "MK-811": true, "MK-812": true, "MK-813": true, "MK-814": true,
+ "MK-816": true, "ML-1": true, "ML-2": true, "ML-3": true, "ML-4": true,
+ "ML-5": true, "ML-6": true, "ML-7": true, "ML-8": true, "ML-BKO": true,
+ "MM-01": true, "MM-02": true, "MM-03": true, "MM-04": true, "MM-05": true,
+ "MM-06": true, "MM-07": true, "MM-11": true, "MM-12": true, "MM-13": true,
+ "MM-14": true, "MM-15": true, "MM-16": true, "MM-17": true, "MM-18": true, "MN-035": true,
+ "MN-037": true, "MN-039": true, "MN-041": true, "MN-043": true, "MN-046": true,
+ "MN-047": true, "MN-049": true, "MN-051": true, "MN-053": true, "MN-055": true,
+ "MN-057": true, "MN-059": true, "MN-061": true, "MN-063": true, "MN-064": true,
+ "MN-065": true, "MN-067": true, "MN-069": true, "MN-071": true, "MN-073": true,
+ "MN-1": true, "MR-01": true, "MR-02": true, "MR-03": true, "MR-04": true,
+ "MR-05": true, "MR-06": true, "MR-07": true, "MR-08": true, "MR-09": true,
+ "MR-10": true, "MR-11": true, "MR-12": true, "MR-13": true, "MR-NKC": true, "MT-01": true,
+ "MT-02": true, "MT-03": true, "MT-04": true, "MT-05": true, "MT-06": true,
+ "MT-07": true, "MT-08": true, "MT-09": true, "MT-10": true, "MT-11": true,
+ "MT-12": true, "MT-13": true, "MT-14": true, "MT-15": true, "MT-16": true,
+ "MT-17": true, "MT-18": true, "MT-19": true, "MT-20": true, "MT-21": true,
+ "MT-22": true, "MT-23": true, "MT-24": true, "MT-25": true, "MT-26": true,
+ "MT-27": true, "MT-28": true, "MT-29": true, "MT-30": true, "MT-31": true,
+ "MT-32": true, "MT-33": true, "MT-34": true, "MT-35": true, "MT-36": true,
+ "MT-37": true, "MT-38": true, "MT-39": true, "MT-40": true, "MT-41": true,
+ "MT-42": true, "MT-43": true, "MT-44": true, "MT-45": true, "MT-46": true,
+ "MT-47": true, "MT-48": true, "MT-49": true, "MT-50": true, "MT-51": true,
+ "MT-52": true, "MT-53": true, "MT-54": true, "MT-55": true, "MT-56": true,
+ "MT-57": true, "MT-58": true, "MT-59": true, "MT-60": true, "MT-61": true,
+ "MT-62": true, "MT-63": true, "MT-64": true, "MT-65": true, "MT-66": true,
+ "MT-67": true, "MT-68": true, "MU-AG": true, "MU-BL": true, "MU-BR": true,
+ "MU-CC": true, "MU-CU": true, "MU-FL": true, "MU-GP": true, "MU-MO": true,
+ "MU-PA": true, "MU-PL": true, "MU-PU": true, "MU-PW": true, "MU-QB": true,
+ "MU-RO": true, "MU-RP": true, "MU-RR": true, "MU-SA": true, "MU-VP": true, "MV-00": true,
+ "MV-01": true, "MV-02": true, "MV-03": true, "MV-04": true, "MV-05": true,
+ "MV-07": true, "MV-08": true, "MV-12": true, "MV-13": true, "MV-14": true,
+ "MV-17": true, "MV-20": true, "MV-23": true, "MV-24": true, "MV-25": true,
+ "MV-26": true, "MV-27": true, "MV-28": true, "MV-29": true, "MV-CE": true,
+ "MV-MLE": true, "MV-NC": true, "MV-NO": true, "MV-SC": true, "MV-SU": true,
+ "MV-UN": true, "MV-US": true, "MW-BA": true, "MW-BL": true, "MW-C": true,
+ "MW-CK": true, "MW-CR": true, "MW-CT": true, "MW-DE": true, "MW-DO": true,
+ "MW-KR": true, "MW-KS": true, "MW-LI": true, "MW-LK": true, "MW-MC": true,
+ "MW-MG": true, "MW-MH": true, "MW-MU": true, "MW-MW": true, "MW-MZ": true,
+ "MW-N": true, "MW-NB": true, "MW-NE": true, "MW-NI": true, "MW-NK": true,
+ "MW-NS": true, "MW-NU": true, "MW-PH": true, "MW-RU": true, "MW-S": true,
+ "MW-SA": true, "MW-TH": true, "MW-ZO": true, "MX-AGU": true, "MX-BCN": true,
+ "MX-BCS": true, "MX-CAM": true, "MX-CHH": true, "MX-CHP": true, "MX-COA": true,
+ "MX-COL": true, "MX-CMX": true, "MX-DIF": true, "MX-DUR": true, "MX-GRO": true, "MX-GUA": true,
+ "MX-HID": true, "MX-JAL": true, "MX-MEX": true, "MX-MIC": true, "MX-MOR": true,
+ "MX-NAY": true, "MX-NLE": true, "MX-OAX": true, "MX-PUE": true, "MX-QUE": true,
+ "MX-ROO": true, "MX-SIN": true, "MX-SLP": true, "MX-SON": true, "MX-TAB": true,
+ "MX-TAM": true, "MX-TLA": true, "MX-VER": true, "MX-YUC": true, "MX-ZAC": true,
+ "MY-01": true, "MY-02": true, "MY-03": true, "MY-04": true, "MY-05": true,
+ "MY-06": true, "MY-07": true, "MY-08": true, "MY-09": true, "MY-10": true,
+ "MY-11": true, "MY-12": true, "MY-13": true, "MY-14": true, "MY-15": true,
+ "MY-16": true, "MZ-A": true, "MZ-B": true, "MZ-G": true, "MZ-I": true,
+ "MZ-L": true, "MZ-MPM": true, "MZ-N": true, "MZ-P": true, "MZ-Q": true,
+ "MZ-S": true, "MZ-T": true, "NA-CA": true, "NA-ER": true, "NA-HA": true,
+ "NA-KA": true, "NA-KE": true, "NA-KH": true, "NA-KU": true, "NA-KW": true, "NA-OD": true, "NA-OH": true,
+ "NA-OK": true, "NA-ON": true, "NA-OS": true, "NA-OT": true, "NA-OW": true,
+ "NE-1": true, "NE-2": true, "NE-3": true, "NE-4": true, "NE-5": true,
+ "NE-6": true, "NE-7": true, "NE-8": true, "NG-AB": true, "NG-AD": true,
+ "NG-AK": true, "NG-AN": true, "NG-BA": true, "NG-BE": true, "NG-BO": true,
+ "NG-BY": true, "NG-CR": true, "NG-DE": true, "NG-EB": true, "NG-ED": true,
+ "NG-EK": true, "NG-EN": true, "NG-FC": true, "NG-GO": true, "NG-IM": true,
+ "NG-JI": true, "NG-KD": true, "NG-KE": true, "NG-KN": true, "NG-KO": true,
+ "NG-KT": true, "NG-KW": true, "NG-LA": true, "NG-NA": true, "NG-NI": true,
+ "NG-OG": true, "NG-ON": true, "NG-OS": true, "NG-OY": true, "NG-PL": true,
+ "NG-RI": true, "NG-SO": true, "NG-TA": true, "NG-YO": true, "NG-ZA": true,
+ "NI-AN": true, "NI-AS": true, "NI-BO": true, "NI-CA": true, "NI-CI": true,
+ "NI-CO": true, "NI-ES": true, "NI-GR": true, "NI-JI": true, "NI-LE": true,
+ "NI-MD": true, "NI-MN": true, "NI-MS": true, "NI-MT": true, "NI-NS": true,
+ "NI-RI": true, "NI-SJ": true, "NL-AW": true, "NL-BQ1": true, "NL-BQ2": true,
+ "NL-BQ3": true, "NL-CW": true, "NL-DR": true, "NL-FL": true, "NL-FR": true,
+ "NL-GE": true, "NL-GR": true, "NL-LI": true, "NL-NB": true, "NL-NH": true,
+ "NL-OV": true, "NL-SX": true, "NL-UT": true, "NL-ZE": true, "NL-ZH": true,
+ "NO-03": true, "NO-11": true, "NO-15": true, "NO-16": true, "NO-17": true,
+ "NO-18": true, "NO-21": true, "NO-30": true, "NO-34": true, "NO-38": true,
+ "NO-42": true, "NO-46": true, "NO-50": true, "NO-54": true,
+ "NO-22": true, "NP-1": true, "NP-2": true, "NP-3": true, "NP-4": true,
+ "NP-5": true, "NP-BA": true, "NP-BH": true, "NP-DH": true, "NP-GA": true,
+ "NP-JA": true, "NP-KA": true, "NP-KO": true, "NP-LU": true, "NP-MA": true,
+ "NP-ME": true, "NP-NA": true, "NP-RA": true, "NP-SA": true, "NP-SE": true,
+ "NR-01": true, "NR-02": true, "NR-03": true, "NR-04": true, "NR-05": true,
+ "NR-06": true, "NR-07": true, "NR-08": true, "NR-09": true, "NR-10": true,
+ "NR-11": true, "NR-12": true, "NR-13": true, "NR-14": true, "NZ-AUK": true,
+ "NZ-BOP": true, "NZ-CAN": true, "NZ-CIT": true, "NZ-GIS": true, "NZ-HKB": true,
+ "NZ-MBH": true, "NZ-MWT": true, "NZ-N": true, "NZ-NSN": true, "NZ-NTL": true,
+ "NZ-OTA": true, "NZ-S": true, "NZ-STL": true, "NZ-TAS": true, "NZ-TKI": true,
+ "NZ-WGN": true, "NZ-WKO": true, "NZ-WTC": true, "OM-BA": true, "OM-BS": true, "OM-BU": true, "OM-BJ": true,
+ "OM-DA": true, "OM-MA": true, "OM-MU": true, "OM-SH": true, "OM-SJ": true, "OM-SS": true, "OM-WU": true,
+ "OM-ZA": true, "OM-ZU": true, "PA-1": true, "PA-2": true, "PA-3": true,
+ "PA-4": true, "PA-5": true, "PA-6": true, "PA-7": true, "PA-8": true,
+ "PA-9": true, "PA-EM": true, "PA-KY": true, "PA-NB": true, "PE-AMA": true,
+ "PE-ANC": true, "PE-APU": true, "PE-ARE": true, "PE-AYA": true, "PE-CAJ": true,
+ "PE-CAL": true, "PE-CUS": true, "PE-HUC": true, "PE-HUV": true, "PE-ICA": true,
+ "PE-JUN": true, "PE-LAL": true, "PE-LAM": true, "PE-LIM": true, "PE-LMA": true,
+ "PE-LOR": true, "PE-MDD": true, "PE-MOQ": true, "PE-PAS": true, "PE-PIU": true,
+ "PE-PUN": true, "PE-SAM": true, "PE-TAC": true, "PE-TUM": true, "PE-UCA": true,
+ "PG-CPK": true, "PG-CPM": true, "PG-EBR": true, "PG-EHG": true, "PG-EPW": true,
+ "PG-ESW": true, "PG-GPK": true, "PG-MBA": true, "PG-MPL": true, "PG-MPM": true,
+ "PG-MRL": true, "PG-NCD": true, "PG-NIK": true, "PG-NPP": true, "PG-NSB": true,
+ "PG-SAN": true, "PG-SHM": true, "PG-WBK": true, "PG-WHM": true, "PG-WPD": true,
+ "PH-00": true, "PH-01": true, "PH-02": true, "PH-03": true, "PH-05": true,
+ "PH-06": true, "PH-07": true, "PH-08": true, "PH-09": true, "PH-10": true,
+ "PH-11": true, "PH-12": true, "PH-13": true, "PH-14": true, "PH-15": true,
+ "PH-40": true, "PH-41": true, "PH-ABR": true, "PH-AGN": true, "PH-AGS": true,
+ "PH-AKL": true, "PH-ALB": true, "PH-ANT": true, "PH-APA": true, "PH-AUR": true,
+ "PH-BAN": true, "PH-BAS": true, "PH-BEN": true, "PH-BIL": true, "PH-BOH": true,
+ "PH-BTG": true, "PH-BTN": true, "PH-BUK": true, "PH-BUL": true, "PH-CAG": true,
+ "PH-CAM": true, "PH-CAN": true, "PH-CAP": true, "PH-CAS": true, "PH-CAT": true,
+ "PH-CAV": true, "PH-CEB": true, "PH-COM": true, "PH-DAO": true, "PH-DAS": true,
+ "PH-DAV": true, "PH-DIN": true, "PH-EAS": true, "PH-GUI": true, "PH-IFU": true,
+ "PH-ILI": true, "PH-ILN": true, "PH-ILS": true, "PH-ISA": true, "PH-KAL": true,
+ "PH-LAG": true, "PH-LAN": true, "PH-LAS": true, "PH-LEY": true, "PH-LUN": true,
+ "PH-MAD": true, "PH-MAG": true, "PH-MAS": true, "PH-MDC": true, "PH-MDR": true,
+ "PH-MOU": true, "PH-MSC": true, "PH-MSR": true, "PH-NCO": true, "PH-NEC": true,
+ "PH-NER": true, "PH-NSA": true, "PH-NUE": true, "PH-NUV": true, "PH-PAM": true,
+ "PH-PAN": true, "PH-PLW": true, "PH-QUE": true, "PH-QUI": true, "PH-RIZ": true,
+ "PH-ROM": true, "PH-SAR": true, "PH-SCO": true, "PH-SIG": true, "PH-SLE": true,
+ "PH-SLU": true, "PH-SOR": true, "PH-SUK": true, "PH-SUN": true, "PH-SUR": true,
+ "PH-TAR": true, "PH-TAW": true, "PH-WSA": true, "PH-ZAN": true, "PH-ZAS": true,
+ "PH-ZMB": true, "PH-ZSI": true, "PK-BA": true, "PK-GB": true, "PK-IS": true,
+ "PK-JK": true, "PK-KP": true, "PK-PB": true, "PK-SD": true, "PK-TA": true,
+ "PL-02": true, "PL-04": true, "PL-06": true, "PL-08": true, "PL-10": true,
+ "PL-12": true, "PL-14": true, "PL-16": true, "PL-18": true, "PL-20": true,
+ "PL-22": true, "PL-24": true, "PL-26": true, "PL-28": true, "PL-30": true, "PL-32": true,
+ "PS-BTH": true, "PS-DEB": true, "PS-GZA": true, "PS-HBN": true,
+ "PS-JEM": true, "PS-JEN": true, "PS-JRH": true, "PS-KYS": true, "PS-NBS": true,
+ "PS-NGZ": true, "PS-QQA": true, "PS-RBH": true, "PS-RFH": true, "PS-SLT": true,
+ "PS-TBS": true, "PS-TKM": true, "PT-01": true, "PT-02": true, "PT-03": true,
+ "PT-04": true, "PT-05": true, "PT-06": true, "PT-07": true, "PT-08": true,
+ "PT-09": true, "PT-10": true, "PT-11": true, "PT-12": true, "PT-13": true,
+ "PT-14": true, "PT-15": true, "PT-16": true, "PT-17": true, "PT-18": true,
+ "PT-20": true, "PT-30": true, "PW-002": true, "PW-004": true, "PW-010": true,
+ "PW-050": true, "PW-100": true, "PW-150": true, "PW-212": true, "PW-214": true,
+ "PW-218": true, "PW-222": true, "PW-224": true, "PW-226": true, "PW-227": true,
+ "PW-228": true, "PW-350": true, "PW-370": true, "PY-1": true, "PY-10": true,
+ "PY-11": true, "PY-12": true, "PY-13": true, "PY-14": true, "PY-15": true,
+ "PY-16": true, "PY-19": true, "PY-2": true, "PY-3": true, "PY-4": true,
+ "PY-5": true, "PY-6": true, "PY-7": true, "PY-8": true, "PY-9": true,
+ "PY-ASU": true, "QA-DA": true, "QA-KH": true, "QA-MS": true, "QA-RA": true,
+ "QA-US": true, "QA-WA": true, "QA-ZA": true, "RO-AB": true, "RO-AG": true,
+ "RO-AR": true, "RO-B": true, "RO-BC": true, "RO-BH": true, "RO-BN": true,
+ "RO-BR": true, "RO-BT": true, "RO-BV": true, "RO-BZ": true, "RO-CJ": true,
+ "RO-CL": true, "RO-CS": true, "RO-CT": true, "RO-CV": true, "RO-DB": true,
+ "RO-DJ": true, "RO-GJ": true, "RO-GL": true, "RO-GR": true, "RO-HD": true,
+ "RO-HR": true, "RO-IF": true, "RO-IL": true, "RO-IS": true, "RO-MH": true,
+ "RO-MM": true, "RO-MS": true, "RO-NT": true, "RO-OT": true, "RO-PH": true,
+ "RO-SB": true, "RO-SJ": true, "RO-SM": true, "RO-SV": true, "RO-TL": true,
+ "RO-TM": true, "RO-TR": true, "RO-VL": true, "RO-VN": true, "RO-VS": true,
+ "RS-00": true, "RS-01": true, "RS-02": true, "RS-03": true, "RS-04": true,
+ "RS-05": true, "RS-06": true, "RS-07": true, "RS-08": true, "RS-09": true,
+ "RS-10": true, "RS-11": true, "RS-12": true, "RS-13": true, "RS-14": true,
+ "RS-15": true, "RS-16": true, "RS-17": true, "RS-18": true, "RS-19": true,
+ "RS-20": true, "RS-21": true, "RS-22": true, "RS-23": true, "RS-24": true,
+ "RS-25": true, "RS-26": true, "RS-27": true, "RS-28": true, "RS-29": true,
+ "RS-KM": true, "RS-VO": true, "RU-AD": true, "RU-AL": true, "RU-ALT": true,
+ "RU-AMU": true, "RU-ARK": true, "RU-AST": true, "RU-BA": true, "RU-BEL": true,
+ "RU-BRY": true, "RU-BU": true, "RU-CE": true, "RU-CHE": true, "RU-CHU": true,
+ "RU-CU": true, "RU-DA": true, "RU-IN": true, "RU-IRK": true, "RU-IVA": true,
+ "RU-KAM": true, "RU-KB": true, "RU-KC": true, "RU-KDA": true, "RU-KEM": true,
+ "RU-KGD": true, "RU-KGN": true, "RU-KHA": true, "RU-KHM": true, "RU-KIR": true,
+ "RU-KK": true, "RU-KL": true, "RU-KLU": true, "RU-KO": true, "RU-KOS": true,
+ "RU-KR": true, "RU-KRS": true, "RU-KYA": true, "RU-LEN": true, "RU-LIP": true,
+ "RU-MAG": true, "RU-ME": true, "RU-MO": true, "RU-MOS": true, "RU-MOW": true,
+ "RU-MUR": true, "RU-NEN": true, "RU-NGR": true, "RU-NIZ": true, "RU-NVS": true,
+ "RU-OMS": true, "RU-ORE": true, "RU-ORL": true, "RU-PER": true, "RU-PNZ": true,
+ "RU-PRI": true, "RU-PSK": true, "RU-ROS": true, "RU-RYA": true, "RU-SA": true,
+ "RU-SAK": true, "RU-SAM": true, "RU-SAR": true, "RU-SE": true, "RU-SMO": true,
+ "RU-SPE": true, "RU-STA": true, "RU-SVE": true, "RU-TA": true, "RU-TAM": true,
+ "RU-TOM": true, "RU-TUL": true, "RU-TVE": true, "RU-TY": true, "RU-TYU": true,
+ "RU-UD": true, "RU-ULY": true, "RU-VGG": true, "RU-VLA": true, "RU-VLG": true,
+ "RU-VOR": true, "RU-YAN": true, "RU-YAR": true, "RU-YEV": true, "RU-ZAB": true,
+ "RW-01": true, "RW-02": true, "RW-03": true, "RW-04": true, "RW-05": true,
+ "SA-01": true, "SA-02": true, "SA-03": true, "SA-04": true, "SA-05": true,
+ "SA-06": true, "SA-07": true, "SA-08": true, "SA-09": true, "SA-10": true,
+ "SA-11": true, "SA-12": true, "SA-14": true, "SB-CE": true, "SB-CH": true,
+ "SB-CT": true, "SB-GU": true, "SB-IS": true, "SB-MK": true, "SB-ML": true,
+ "SB-RB": true, "SB-TE": true, "SB-WE": true, "SC-01": true, "SC-02": true,
+ "SC-03": true, "SC-04": true, "SC-05": true, "SC-06": true, "SC-07": true,
+ "SC-08": true, "SC-09": true, "SC-10": true, "SC-11": true, "SC-12": true,
+ "SC-13": true, "SC-14": true, "SC-15": true, "SC-16": true, "SC-17": true,
+ "SC-18": true, "SC-19": true, "SC-20": true, "SC-21": true, "SC-22": true,
+ "SC-23": true, "SC-24": true, "SC-25": true, "SD-DC": true, "SD-DE": true,
+ "SD-DN": true, "SD-DS": true, "SD-DW": true, "SD-GD": true, "SD-GK": true, "SD-GZ": true,
+ "SD-KA": true, "SD-KH": true, "SD-KN": true, "SD-KS": true, "SD-NB": true,
+ "SD-NO": true, "SD-NR": true, "SD-NW": true, "SD-RS": true, "SD-SI": true,
+ "SE-AB": true, "SE-AC": true, "SE-BD": true, "SE-C": true, "SE-D": true,
+ "SE-E": true, "SE-F": true, "SE-G": true, "SE-H": true, "SE-I": true,
+ "SE-K": true, "SE-M": true, "SE-N": true, "SE-O": true, "SE-S": true,
+ "SE-T": true, "SE-U": true, "SE-W": true, "SE-X": true, "SE-Y": true,
+ "SE-Z": true, "SG-01": true, "SG-02": true, "SG-03": true, "SG-04": true,
+ "SG-05": true, "SH-AC": true, "SH-HL": true, "SH-TA": true, "SI-001": true,
+ "SI-002": true, "SI-003": true, "SI-004": true, "SI-005": true, "SI-006": true,
+ "SI-007": true, "SI-008": true, "SI-009": true, "SI-010": true, "SI-011": true,
+ "SI-012": true, "SI-013": true, "SI-014": true, "SI-015": true, "SI-016": true,
+ "SI-017": true, "SI-018": true, "SI-019": true, "SI-020": true, "SI-021": true,
+ "SI-022": true, "SI-023": true, "SI-024": true, "SI-025": true, "SI-026": true,
+ "SI-027": true, "SI-028": true, "SI-029": true, "SI-030": true, "SI-031": true,
+ "SI-032": true, "SI-033": true, "SI-034": true, "SI-035": true, "SI-036": true,
+ "SI-037": true, "SI-038": true, "SI-039": true, "SI-040": true, "SI-041": true,
+ "SI-042": true, "SI-043": true, "SI-044": true, "SI-045": true, "SI-046": true,
+ "SI-047": true, "SI-048": true, "SI-049": true, "SI-050": true, "SI-051": true,
+ "SI-052": true, "SI-053": true, "SI-054": true, "SI-055": true, "SI-056": true,
+ "SI-057": true, "SI-058": true, "SI-059": true, "SI-060": true, "SI-061": true,
+ "SI-062": true, "SI-063": true, "SI-064": true, "SI-065": true, "SI-066": true,
+ "SI-067": true, "SI-068": true, "SI-069": true, "SI-070": true, "SI-071": true,
+ "SI-072": true, "SI-073": true, "SI-074": true, "SI-075": true, "SI-076": true,
+ "SI-077": true, "SI-078": true, "SI-079": true, "SI-080": true, "SI-081": true,
+ "SI-082": true, "SI-083": true, "SI-084": true, "SI-085": true, "SI-086": true,
+ "SI-087": true, "SI-088": true, "SI-089": true, "SI-090": true, "SI-091": true,
+ "SI-092": true, "SI-093": true, "SI-094": true, "SI-095": true, "SI-096": true,
+ "SI-097": true, "SI-098": true, "SI-099": true, "SI-100": true, "SI-101": true,
+ "SI-102": true, "SI-103": true, "SI-104": true, "SI-105": true, "SI-106": true,
+ "SI-107": true, "SI-108": true, "SI-109": true, "SI-110": true, "SI-111": true,
+ "SI-112": true, "SI-113": true, "SI-114": true, "SI-115": true, "SI-116": true,
+ "SI-117": true, "SI-118": true, "SI-119": true, "SI-120": true, "SI-121": true,
+ "SI-122": true, "SI-123": true, "SI-124": true, "SI-125": true, "SI-126": true,
+ "SI-127": true, "SI-128": true, "SI-129": true, "SI-130": true, "SI-131": true,
+ "SI-132": true, "SI-133": true, "SI-134": true, "SI-135": true, "SI-136": true,
+ "SI-137": true, "SI-138": true, "SI-139": true, "SI-140": true, "SI-141": true,
+ "SI-142": true, "SI-143": true, "SI-144": true, "SI-146": true, "SI-147": true,
+ "SI-148": true, "SI-149": true, "SI-150": true, "SI-151": true, "SI-152": true,
+ "SI-153": true, "SI-154": true, "SI-155": true, "SI-156": true, "SI-157": true,
+ "SI-158": true, "SI-159": true, "SI-160": true, "SI-161": true, "SI-162": true,
+ "SI-163": true, "SI-164": true, "SI-165": true, "SI-166": true, "SI-167": true,
+ "SI-168": true, "SI-169": true, "SI-170": true, "SI-171": true, "SI-172": true,
+ "SI-173": true, "SI-174": true, "SI-175": true, "SI-176": true, "SI-177": true,
+ "SI-178": true, "SI-179": true, "SI-180": true, "SI-181": true, "SI-182": true,
+ "SI-183": true, "SI-184": true, "SI-185": true, "SI-186": true, "SI-187": true,
+ "SI-188": true, "SI-189": true, "SI-190": true, "SI-191": true, "SI-192": true,
+ "SI-193": true, "SI-194": true, "SI-195": true, "SI-196": true, "SI-197": true,
+ "SI-198": true, "SI-199": true, "SI-200": true, "SI-201": true, "SI-202": true,
+ "SI-203": true, "SI-204": true, "SI-205": true, "SI-206": true, "SI-207": true,
+ "SI-208": true, "SI-209": true, "SI-210": true, "SI-211": true, "SI-212": true, "SI-213": true, "SK-BC": true,
+ "SK-BL": true, "SK-KI": true, "SK-NI": true, "SK-PV": true, "SK-TA": true,
+ "SK-TC": true, "SK-ZI": true, "SL-E": true, "SL-N": true, "SL-S": true,
+ "SL-W": true, "SM-01": true, "SM-02": true, "SM-03": true, "SM-04": true,
+ "SM-05": true, "SM-06": true, "SM-07": true, "SM-08": true, "SM-09": true,
+ "SN-DB": true, "SN-DK": true, "SN-FK": true, "SN-KA": true, "SN-KD": true,
+ "SN-KE": true, "SN-KL": true, "SN-LG": true, "SN-MT": true, "SN-SE": true,
+ "SN-SL": true, "SN-TC": true, "SN-TH": true, "SN-ZG": true, "SO-AW": true,
+ "SO-BK": true, "SO-BN": true, "SO-BR": true, "SO-BY": true, "SO-GA": true,
+ "SO-GE": true, "SO-HI": true, "SO-JD": true, "SO-JH": true, "SO-MU": true,
+ "SO-NU": true, "SO-SA": true, "SO-SD": true, "SO-SH": true, "SO-SO": true,
+ "SO-TO": true, "SO-WO": true, "SR-BR": true, "SR-CM": true, "SR-CR": true,
+ "SR-MA": true, "SR-NI": true, "SR-PM": true, "SR-PR": true, "SR-SA": true,
+ "SR-SI": true, "SR-WA": true, "SS-BN": true, "SS-BW": true, "SS-EC": true,
+ "SS-EE8": true, "SS-EE": true, "SS-EW": true, "SS-JG": true, "SS-LK": true, "SS-NU": true,
+ "SS-UY": true, "SS-WR": true, "ST-01": true, "ST-P": true, "ST-S": true, "SV-AH": true,
+ "SV-CA": true, "SV-CH": true, "SV-CU": true, "SV-LI": true, "SV-MO": true,
+ "SV-PA": true, "SV-SA": true, "SV-SM": true, "SV-SO": true, "SV-SS": true,
+ "SV-SV": true, "SV-UN": true, "SV-US": true, "SY-DI": true, "SY-DR": true,
+ "SY-DY": true, "SY-HA": true, "SY-HI": true, "SY-HL": true, "SY-HM": true,
+ "SY-ID": true, "SY-LA": true, "SY-QU": true, "SY-RA": true, "SY-RD": true,
+ "SY-SU": true, "SY-TA": true, "SZ-HH": true, "SZ-LU": true, "SZ-MA": true,
+ "SZ-SH": true, "TD-BA": true, "TD-BG": true, "TD-BO": true, "TD-CB": true,
+ "TD-EN": true, "TD-GR": true, "TD-HL": true, "TD-KA": true, "TD-LC": true,
+ "TD-LO": true, "TD-LR": true, "TD-MA": true, "TD-MC": true, "TD-ME": true,
+ "TD-MO": true, "TD-ND": true, "TD-OD": true, "TD-SA": true, "TD-SI": true,
+ "TD-TA": true, "TD-TI": true, "TD-WF": true, "TG-C": true, "TG-K": true,
+ "TG-M": true, "TG-P": true, "TG-S": true, "TH-10": true, "TH-11": true,
+ "TH-12": true, "TH-13": true, "TH-14": true, "TH-15": true, "TH-16": true,
+ "TH-17": true, "TH-18": true, "TH-19": true, "TH-20": true, "TH-21": true,
+ "TH-22": true, "TH-23": true, "TH-24": true, "TH-25": true, "TH-26": true,
+ "TH-27": true, "TH-30": true, "TH-31": true, "TH-32": true, "TH-33": true,
+ "TH-34": true, "TH-35": true, "TH-36": true, "TH-37": true, "TH-38": true, "TH-39": true,
+ "TH-40": true, "TH-41": true, "TH-42": true, "TH-43": true, "TH-44": true,
+ "TH-45": true, "TH-46": true, "TH-47": true, "TH-48": true, "TH-49": true,
+ "TH-50": true, "TH-51": true, "TH-52": true, "TH-53": true, "TH-54": true,
+ "TH-55": true, "TH-56": true, "TH-57": true, "TH-58": true, "TH-60": true,
+ "TH-61": true, "TH-62": true, "TH-63": true, "TH-64": true, "TH-65": true,
+ "TH-66": true, "TH-67": true, "TH-70": true, "TH-71": true, "TH-72": true,
+ "TH-73": true, "TH-74": true, "TH-75": true, "TH-76": true, "TH-77": true,
+ "TH-80": true, "TH-81": true, "TH-82": true, "TH-83": true, "TH-84": true,
+ "TH-85": true, "TH-86": true, "TH-90": true, "TH-91": true, "TH-92": true,
+ "TH-93": true, "TH-94": true, "TH-95": true, "TH-96": true, "TH-S": true,
+ "TJ-GB": true, "TJ-KT": true, "TJ-SU": true, "TJ-DU": true, "TJ-RA": true, "TL-AL": true, "TL-AN": true,
+ "TL-BA": true, "TL-BO": true, "TL-CO": true, "TL-DI": true, "TL-ER": true,
+ "TL-LA": true, "TL-LI": true, "TL-MF": true, "TL-MT": true, "TL-OE": true,
+ "TL-VI": true, "TM-A": true, "TM-B": true, "TM-D": true, "TM-L": true,
+ "TM-M": true, "TM-S": true, "TN-11": true, "TN-12": true, "TN-13": true,
+ "TN-14": true, "TN-21": true, "TN-22": true, "TN-23": true, "TN-31": true,
+ "TN-32": true, "TN-33": true, "TN-34": true, "TN-41": true, "TN-42": true,
+ "TN-43": true, "TN-51": true, "TN-52": true, "TN-53": true, "TN-61": true,
+ "TN-71": true, "TN-72": true, "TN-73": true, "TN-81": true, "TN-82": true,
+ "TN-83": true, "TO-01": true, "TO-02": true, "TO-03": true, "TO-04": true,
+ "TO-05": true, "TR-01": true, "TR-02": true, "TR-03": true, "TR-04": true,
+ "TR-05": true, "TR-06": true, "TR-07": true, "TR-08": true, "TR-09": true,
+ "TR-10": true, "TR-11": true, "TR-12": true, "TR-13": true, "TR-14": true,
+ "TR-15": true, "TR-16": true, "TR-17": true, "TR-18": true, "TR-19": true,
+ "TR-20": true, "TR-21": true, "TR-22": true, "TR-23": true, "TR-24": true,
+ "TR-25": true, "TR-26": true, "TR-27": true, "TR-28": true, "TR-29": true,
+ "TR-30": true, "TR-31": true, "TR-32": true, "TR-33": true, "TR-34": true,
+ "TR-35": true, "TR-36": true, "TR-37": true, "TR-38": true, "TR-39": true,
+ "TR-40": true, "TR-41": true, "TR-42": true, "TR-43": true, "TR-44": true,
+ "TR-45": true, "TR-46": true, "TR-47": true, "TR-48": true, "TR-49": true,
+ "TR-50": true, "TR-51": true, "TR-52": true, "TR-53": true, "TR-54": true,
+ "TR-55": true, "TR-56": true, "TR-57": true, "TR-58": true, "TR-59": true,
+ "TR-60": true, "TR-61": true, "TR-62": true, "TR-63": true, "TR-64": true,
+ "TR-65": true, "TR-66": true, "TR-67": true, "TR-68": true, "TR-69": true,
+ "TR-70": true, "TR-71": true, "TR-72": true, "TR-73": true, "TR-74": true,
+ "TR-75": true, "TR-76": true, "TR-77": true, "TR-78": true, "TR-79": true,
+ "TR-80": true, "TR-81": true, "TT-ARI": true, "TT-CHA": true, "TT-CTT": true,
+ "TT-DMN": true, "TT-ETO": true, "TT-MRC": true, "TT-TOB": true, "TT-PED": true, "TT-POS": true, "TT-PRT": true,
+ "TT-PTF": true, "TT-RCM": true, "TT-SFO": true, "TT-SGE": true, "TT-SIP": true,
+ "TT-SJL": true, "TT-TUP": true, "TT-WTO": true, "TV-FUN": true, "TV-NIT": true,
+ "TV-NKF": true, "TV-NKL": true, "TV-NMA": true, "TV-NMG": true, "TV-NUI": true,
+ "TV-VAI": true, "TW-CHA": true, "TW-CYI": true, "TW-CYQ": true, "TW-KIN": true, "TW-HSQ": true,
+ "TW-HSZ": true, "TW-HUA": true, "TW-LIE": true, "TW-ILA": true, "TW-KEE": true, "TW-KHH": true,
+ "TW-KHQ": true, "TW-MIA": true, "TW-NAN": true, "TW-NWT": true, "TW-PEN": true, "TW-PIF": true,
+ "TW-TAO": true, "TW-TNN": true, "TW-TNQ": true, "TW-TPE": true, "TW-TPQ": true,
+ "TW-TTT": true, "TW-TXG": true, "TW-TXQ": true, "TW-YUN": true, "TZ-01": true,
+ "TZ-02": true, "TZ-03": true, "TZ-04": true, "TZ-05": true, "TZ-06": true,
+ "TZ-07": true, "TZ-08": true, "TZ-09": true, "TZ-10": true, "TZ-11": true,
+ "TZ-12": true, "TZ-13": true, "TZ-14": true, "TZ-15": true, "TZ-16": true,
+ "TZ-17": true, "TZ-18": true, "TZ-19": true, "TZ-20": true, "TZ-21": true,
+ "TZ-22": true, "TZ-23": true, "TZ-24": true, "TZ-25": true, "TZ-26": true, "TZ-27": true, "TZ-28": true, "TZ-29": true, "TZ-30": true, "TZ-31": true,
+ "UA-05": true, "UA-07": true, "UA-09": true, "UA-12": true, "UA-14": true,
+ "UA-18": true, "UA-21": true, "UA-23": true, "UA-26": true, "UA-30": true,
+ "UA-32": true, "UA-35": true, "UA-40": true, "UA-43": true, "UA-46": true,
+ "UA-48": true, "UA-51": true, "UA-53": true, "UA-56": true, "UA-59": true,
+ "UA-61": true, "UA-63": true, "UA-65": true, "UA-68": true, "UA-71": true,
+ "UA-74": true, "UA-77": true, "UG-101": true, "UG-102": true, "UG-103": true,
+ "UG-104": true, "UG-105": true, "UG-106": true, "UG-107": true, "UG-108": true,
+ "UG-109": true, "UG-110": true, "UG-111": true, "UG-112": true, "UG-113": true,
+ "UG-114": true, "UG-115": true, "UG-116": true, "UG-201": true, "UG-202": true,
+ "UG-203": true, "UG-204": true, "UG-205": true, "UG-206": true, "UG-207": true,
+ "UG-208": true, "UG-209": true, "UG-210": true, "UG-211": true, "UG-212": true,
+ "UG-213": true, "UG-214": true, "UG-215": true, "UG-216": true, "UG-217": true,
+ "UG-218": true, "UG-219": true, "UG-220": true, "UG-221": true, "UG-222": true,
+ "UG-223": true, "UG-224": true, "UG-301": true, "UG-302": true, "UG-303": true,
+ "UG-304": true, "UG-305": true, "UG-306": true, "UG-307": true, "UG-308": true,
+ "UG-309": true, "UG-310": true, "UG-311": true, "UG-312": true, "UG-313": true,
+ "UG-314": true, "UG-315": true, "UG-316": true, "UG-317": true, "UG-318": true,
+ "UG-319": true, "UG-320": true, "UG-321": true, "UG-401": true, "UG-402": true,
+ "UG-403": true, "UG-404": true, "UG-405": true, "UG-406": true, "UG-407": true,
+ "UG-408": true, "UG-409": true, "UG-410": true, "UG-411": true, "UG-412": true,
+ "UG-413": true, "UG-414": true, "UG-415": true, "UG-416": true, "UG-417": true,
+ "UG-418": true, "UG-419": true, "UG-C": true, "UG-E": true, "UG-N": true,
+ "UG-W": true, "UG-322": true, "UG-323": true, "UG-420": true, "UG-117": true,
+ "UG-118": true, "UG-225": true, "UG-120": true, "UG-226": true,
+ "UG-121": true, "UG-122": true, "UG-227": true, "UG-421": true,
+ "UG-325": true, "UG-228": true, "UG-123": true, "UG-422": true,
+ "UG-326": true, "UG-229": true, "UG-124": true, "UG-423": true,
+ "UG-230": true, "UG-327": true, "UG-424": true, "UG-328": true,
+ "UG-425": true, "UG-426": true, "UG-330": true,
+ "UM-67": true, "UM-71": true, "UM-76": true, "UM-79": true,
+ "UM-81": true, "UM-84": true, "UM-86": true, "UM-89": true, "UM-95": true,
+ "US-AK": true, "US-AL": true, "US-AR": true, "US-AS": true, "US-AZ": true,
+ "US-CA": true, "US-CO": true, "US-CT": true, "US-DC": true, "US-DE": true,
+ "US-FL": true, "US-GA": true, "US-GU": true, "US-HI": true, "US-IA": true,
+ "US-ID": true, "US-IL": true, "US-IN": true, "US-KS": true, "US-KY": true,
+ "US-LA": true, "US-MA": true, "US-MD": true, "US-ME": true, "US-MI": true,
+ "US-MN": true, "US-MO": true, "US-MP": true, "US-MS": true, "US-MT": true,
+ "US-NC": true, "US-ND": true, "US-NE": true, "US-NH": true, "US-NJ": true,
+ "US-NM": true, "US-NV": true, "US-NY": true, "US-OH": true, "US-OK": true,
+ "US-OR": true, "US-PA": true, "US-PR": true, "US-RI": true, "US-SC": true,
+ "US-SD": true, "US-TN": true, "US-TX": true, "US-UM": true, "US-UT": true,
+ "US-VA": true, "US-VI": true, "US-VT": true, "US-WA": true, "US-WI": true,
+ "US-WV": true, "US-WY": true, "UY-AR": true, "UY-CA": true, "UY-CL": true,
+ "UY-CO": true, "UY-DU": true, "UY-FD": true, "UY-FS": true, "UY-LA": true,
+ "UY-MA": true, "UY-MO": true, "UY-PA": true, "UY-RN": true, "UY-RO": true,
+ "UY-RV": true, "UY-SA": true, "UY-SJ": true, "UY-SO": true, "UY-TA": true,
+ "UY-TT": true, "UZ-AN": true, "UZ-BU": true, "UZ-FA": true, "UZ-JI": true,
+ "UZ-NG": true, "UZ-NW": true, "UZ-QA": true, "UZ-QR": true, "UZ-SA": true,
+ "UZ-SI": true, "UZ-SU": true, "UZ-TK": true, "UZ-TO": true, "UZ-XO": true,
+ "VC-01": true, "VC-02": true, "VC-03": true, "VC-04": true, "VC-05": true,
+ "VC-06": true, "VE-A": true, "VE-B": true, "VE-C": true, "VE-D": true,
+ "VE-E": true, "VE-F": true, "VE-G": true, "VE-H": true, "VE-I": true,
+ "VE-J": true, "VE-K": true, "VE-L": true, "VE-M": true, "VE-N": true,
+ "VE-O": true, "VE-P": true, "VE-R": true, "VE-S": true, "VE-T": true,
+ "VE-U": true, "VE-V": true, "VE-W": true, "VE-X": true, "VE-Y": true,
+ "VE-Z": true, "VN-01": true, "VN-02": true, "VN-03": true, "VN-04": true,
+ "VN-05": true, "VN-06": true, "VN-07": true, "VN-09": true, "VN-13": true,
+ "VN-14": true, "VN-15": true, "VN-18": true, "VN-20": true, "VN-21": true,
+ "VN-22": true, "VN-23": true, "VN-24": true, "VN-25": true, "VN-26": true,
+ "VN-27": true, "VN-28": true, "VN-29": true, "VN-30": true, "VN-31": true,
+ "VN-32": true, "VN-33": true, "VN-34": true, "VN-35": true, "VN-36": true,
+ "VN-37": true, "VN-39": true, "VN-40": true, "VN-41": true, "VN-43": true,
+ "VN-44": true, "VN-45": true, "VN-46": true, "VN-47": true, "VN-49": true,
+ "VN-50": true, "VN-51": true, "VN-52": true, "VN-53": true, "VN-54": true,
+ "VN-55": true, "VN-56": true, "VN-57": true, "VN-58": true, "VN-59": true,
+ "VN-61": true, "VN-63": true, "VN-66": true, "VN-67": true, "VN-68": true,
+ "VN-69": true, "VN-70": true, "VN-71": true, "VN-72": true, "VN-73": true,
+ "VN-CT": true, "VN-DN": true, "VN-HN": true, "VN-HP": true, "VN-SG": true,
+ "VU-MAP": true, "VU-PAM": true, "VU-SAM": true, "VU-SEE": true, "VU-TAE": true,
+ "VU-TOB": true, "WF-SG": true, "WF-UV": true, "WS-AA": true, "WS-AL": true, "WS-AT": true, "WS-FA": true,
+ "WS-GE": true, "WS-GI": true, "WS-PA": true, "WS-SA": true, "WS-TU": true,
+ "WS-VF": true, "WS-VS": true, "YE-AB": true, "YE-AD": true, "YE-AM": true,
+ "YE-BA": true, "YE-DA": true, "YE-DH": true, "YE-HD": true, "YE-HJ": true, "YE-HU": true,
+ "YE-IB": true, "YE-JA": true, "YE-LA": true, "YE-MA": true, "YE-MR": true,
+ "YE-MU": true, "YE-MW": true, "YE-RA": true, "YE-SA": true, "YE-SD": true, "YE-SH": true,
+ "YE-SN": true, "YE-TA": true, "ZA-EC": true, "ZA-FS": true, "ZA-GP": true,
+ "ZA-LP": true, "ZA-MP": true, "ZA-NC": true, "ZA-NW": true, "ZA-WC": true,
+ "ZA-ZN": true, "ZA-KZN": true, "ZM-01": true, "ZM-02": true, "ZM-03": true, "ZM-04": true,
+ "ZM-05": true, "ZM-06": true, "ZM-07": true, "ZM-08": true, "ZM-09": true, "ZM-10": true,
+ "ZW-BU": true, "ZW-HA": true, "ZW-MA": true, "ZW-MC": true, "ZW-ME": true,
+ "ZW-MI": true, "ZW-MN": true, "ZW-MS": true, "ZW-MV": true, "ZW-MW": true,
}
diff --git a/vendor/github.com/go-playground/validator/v10/currency_codes.go b/vendor/github.com/go-playground/validator/v10/currency_codes.go
new file mode 100644
index 00000000000..a5cd9b18a0a
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/currency_codes.go
@@ -0,0 +1,79 @@
+package validator
+
+var iso4217 = map[string]bool{
+ "AFN": true, "EUR": true, "ALL": true, "DZD": true, "USD": true,
+ "AOA": true, "XCD": true, "ARS": true, "AMD": true, "AWG": true,
+ "AUD": true, "AZN": true, "BSD": true, "BHD": true, "BDT": true,
+ "BBD": true, "BYN": true, "BZD": true, "XOF": true, "BMD": true,
+ "INR": true, "BTN": true, "BOB": true, "BOV": true, "BAM": true,
+ "BWP": true, "NOK": true, "BRL": true, "BND": true, "BGN": true,
+ "BIF": true, "CVE": true, "KHR": true, "XAF": true, "CAD": true,
+ "KYD": true, "CLP": true, "CLF": true, "CNY": true, "COP": true,
+ "COU": true, "KMF": true, "CDF": true, "NZD": true, "CRC": true,
+ "HRK": true, "CUP": true, "CUC": true, "ANG": true, "CZK": true,
+ "DKK": true, "DJF": true, "DOP": true, "EGP": true, "SVC": true,
+ "ERN": true, "SZL": true, "ETB": true, "FKP": true, "FJD": true,
+ "XPF": true, "GMD": true, "GEL": true, "GHS": true, "GIP": true,
+ "GTQ": true, "GBP": true, "GNF": true, "GYD": true, "HTG": true,
+ "HNL": true, "HKD": true, "HUF": true, "ISK": true, "IDR": true,
+ "XDR": true, "IRR": true, "IQD": true, "ILS": true, "JMD": true,
+ "JPY": true, "JOD": true, "KZT": true, "KES": true, "KPW": true,
+ "KRW": true, "KWD": true, "KGS": true, "LAK": true, "LBP": true,
+ "LSL": true, "ZAR": true, "LRD": true, "LYD": true, "CHF": true,
+ "MOP": true, "MKD": true, "MGA": true, "MWK": true, "MYR": true,
+ "MVR": true, "MRU": true, "MUR": true, "XUA": true, "MXN": true,
+ "MXV": true, "MDL": true, "MNT": true, "MAD": true, "MZN": true,
+ "MMK": true, "NAD": true, "NPR": true, "NIO": true, "NGN": true,
+ "OMR": true, "PKR": true, "PAB": true, "PGK": true, "PYG": true,
+ "PEN": true, "PHP": true, "PLN": true, "QAR": true, "RON": true,
+ "RUB": true, "RWF": true, "SHP": true, "WST": true, "STN": true,
+ "SAR": true, "RSD": true, "SCR": true, "SLL": true, "SGD": true,
+ "XSU": true, "SBD": true, "SOS": true, "SSP": true, "LKR": true,
+ "SDG": true, "SRD": true, "SEK": true, "CHE": true, "CHW": true,
+ "SYP": true, "TWD": true, "TJS": true, "TZS": true, "THB": true,
+ "TOP": true, "TTD": true, "TND": true, "TRY": true, "TMT": true,
+ "UGX": true, "UAH": true, "AED": true, "USN": true, "UYU": true,
+ "UYI": true, "UYW": true, "UZS": true, "VUV": true, "VES": true,
+ "VND": true, "YER": true, "ZMW": true, "ZWL": true, "XBA": true,
+ "XBB": true, "XBC": true, "XBD": true, "XTS": true, "XXX": true,
+ "XAU": true, "XPD": true, "XPT": true, "XAG": true,
+}
+
+var iso4217_numeric = map[int]bool{
+ 8: true, 12: true, 32: true, 36: true, 44: true,
+ 48: true, 50: true, 51: true, 52: true, 60: true,
+ 64: true, 68: true, 72: true, 84: true, 90: true,
+ 96: true, 104: true, 108: true, 116: true, 124: true,
+ 132: true, 136: true, 144: true, 152: true, 156: true,
+ 170: true, 174: true, 188: true, 191: true, 192: true,
+ 203: true, 208: true, 214: true, 222: true, 230: true,
+ 232: true, 238: true, 242: true, 262: true, 270: true,
+ 292: true, 320: true, 324: true, 328: true, 332: true,
+ 340: true, 344: true, 348: true, 352: true, 356: true,
+ 360: true, 364: true, 368: true, 376: true, 388: true,
+ 392: true, 398: true, 400: true, 404: true, 408: true,
+ 410: true, 414: true, 417: true, 418: true, 422: true,
+ 426: true, 430: true, 434: true, 446: true, 454: true,
+ 458: true, 462: true, 480: true, 484: true, 496: true,
+ 498: true, 504: true, 512: true, 516: true, 524: true,
+ 532: true, 533: true, 548: true, 554: true, 558: true,
+ 566: true, 578: true, 586: true, 590: true, 598: true,
+ 600: true, 604: true, 608: true, 634: true, 643: true,
+ 646: true, 654: true, 682: true, 690: true, 694: true,
+ 702: true, 704: true, 706: true, 710: true, 728: true,
+ 748: true, 752: true, 756: true, 760: true, 764: true,
+ 776: true, 780: true, 784: true, 788: true, 800: true,
+ 807: true, 818: true, 826: true, 834: true, 840: true,
+ 858: true, 860: true, 882: true, 886: true, 901: true,
+ 927: true, 928: true, 929: true, 930: true, 931: true,
+ 932: true, 933: true, 934: true, 936: true, 938: true,
+ 940: true, 941: true, 943: true, 944: true, 946: true,
+ 947: true, 948: true, 949: true, 950: true, 951: true,
+ 952: true, 953: true, 955: true, 956: true, 957: true,
+ 958: true, 959: true, 960: true, 961: true, 962: true,
+ 963: true, 964: true, 965: true, 967: true, 968: true,
+ 969: true, 970: true, 971: true, 972: true, 973: true,
+ 975: true, 976: true, 977: true, 978: true, 979: true,
+ 980: true, 981: true, 984: true, 985: true, 986: true,
+ 990: true, 994: true, 997: true, 999: true,
+}
diff --git a/vendor/github.com/go-playground/validator/v10/doc.go b/vendor/github.com/go-playground/validator/v10/doc.go
index a816c20a418..b4740918813 100644
--- a/vendor/github.com/go-playground/validator/v10/doc.go
+++ b/vendor/github.com/go-playground/validator/v10/doc.go
@@ -7,7 +7,15 @@ and has the ability to dive into arrays and maps of any type.
see more examples https://github.com/go-playground/validator/tree/master/_examples
-Validation Functions Return Type error
+# Singleton
+
+Validator is designed to be thread-safe and used as a singleton instance.
+It caches information about your struct and validations,
+in essence only parsing your validation tags once per struct type.
+Using multiple instances neglects the benefit of caching.
+The not thread-safe functions are explicitly marked as such in the documentation.
+
+# Validation Functions Return Type error
Doing things this way is actually the way the standard library does, see the
file.Open method here:
@@ -26,7 +34,7 @@ if the error returned is not nil, and if it's not check if error is
InvalidValidationError ( if necessary, most of the time it isn't ) type cast
it to type ValidationErrors like so err.(validator.ValidationErrors).
-Custom Validation Functions
+# Custom Validation Functions
Custom Validation functions can be added. Example:
@@ -44,21 +52,21 @@ Custom Validation functions can be added. Example:
// NOTES: using the same tag name as an existing function
// will overwrite the existing one
-Cross-Field Validation
+# Cross-Field Validation
Cross-Field Validation can be done via the following tags:
- - eqfield
- - nefield
- - gtfield
- - gtefield
- - ltfield
- - ltefield
- - eqcsfield
- - necsfield
- - gtcsfield
- - gtecsfield
- - ltcsfield
- - ltecsfield
+ - eqfield
+ - nefield
+ - gtfield
+ - gtefield
+ - ltfield
+ - ltefield
+ - eqcsfield
+ - necsfield
+ - gtcsfield
+ - gtecsfield
+ - ltcsfield
+ - ltecsfield
If, however, some custom cross-field validation is required, it can be done
using a custom validation.
@@ -98,7 +106,7 @@ used "eqcsfield" it could be multiple levels down. Example:
// whatever you pass, struct, field...
// when calling validate.Field(field, tag) val will be nil
-Multiple Validators
+# Multiple Validators
Multiple validators on a field will process in the order defined. Example:
@@ -116,7 +124,7 @@ Bad Validator definitions are not handled by the library. Example:
// this definition of min max will never succeed
-Using Validator Tags
+# Using Validator Tags
Baked In Cross-Field validation only compares fields on the same struct.
If Cross-Field + Cross-Struct validation is needed you should implement your
@@ -138,24 +146,22 @@ use the UTF-8 hex representation 0x7C, which is replaced in the code as a pipe,
so the above will become excludesall=0x7C
type Test struct {
- Field `validate:"excludesall=|"` // BAD! Do not include a a pipe!
+ Field `validate:"excludesall=|"` // BAD! Do not include a pipe!
Field `validate:"excludesall=0x7C"` // GOOD! Use the UTF-8 hex representation.
}
-
-Baked In Validators and Tags
+# Baked In Validators and Tags
Here is a list of the current built in validators:
-
-Skip Field
+# Skip Field
Tells the validation to skip this struct field; this is particularly
handy in ignoring embedded structs from being validated. (Usage: -)
- Usage: -
+ Usage: -
-Or Operator
+# Or Operator
This is the 'or' operator allowing multiple validators to be used and
accepted. (Usage: rgb|rgba) <-- this would allow either rgb or rgba
@@ -164,7 +170,7 @@ colors to be accepted. This can also be combined with 'and' for example
Usage: |
-StructOnly
+# StructOnly
When a field that is a nested struct is encountered, and contains this flag
any validation on the nested struct will be run, but none of the nested
@@ -174,13 +180,13 @@ NOTE: only "required" and "omitempty" can be used on a struct itself.
Usage: structonly
-NoStructLevel
+# NoStructLevel
Same as structonly tag except that any struct level validations will not run.
Usage: nostructlevel
-Omit Empty
+# Omit Empty
Allows conditional validation, for example if a field is not set with
a value (Determined by the "required" validator) then other validation
@@ -188,7 +194,14 @@ such as min or max won't run, but if a value is set validation will run.
Usage: omitempty
-Dive
+# Omit Nil
+
+Allows to skip the validation if the value is nil (same as omitempty, but
+only for the nil-values).
+
+ Usage: omitnil
+
+# Dive
This tells the validator to dive into a slice, array or map and validate that
level of the slice, array or map with the validation tags that follow.
@@ -224,33 +237,33 @@ require another 'keys' and 'endkeys' tag. These tags are only valid for maps.
Example #1
- map[string]string with validation tag "gt=0,dive,keys,eg=1|eq=2,endkeys,required"
+ map[string]string with validation tag "gt=0,dive,keys,eq=1|eq=2,endkeys,required"
// gt=0 will be applied to the map itself
- // eg=1|eq=2 will be applied to the map keys
+ // eq=1|eq=2 will be applied to the map keys
// required will be applied to map values
Example #2
map[[2]string]string with validation tag "gt=0,dive,keys,dive,eq=1|eq=2,endkeys,required"
// gt=0 will be applied to the map itself
- // eg=1|eq=2 will be applied to each array element in the the map keys
+ // eq=1|eq=2 will be applied to each array element in the map keys
// required will be applied to map values
-Required
+# Required
This validates that the value is not the data types default zero value.
For numbers ensures value is not zero. For strings ensures value is
not "". For slices, maps, pointers, interfaces, channels and functions
-ensures the value is not nil.
+ensures the value is not nil. For structs ensures value is not the zero value when using WithRequiredStructEnabled.
Usage: required
-Required If
+# Required If
The field under validation must be present and 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.
+interfaces, channels and functions ensures the value is not nil. For structs ensures value is not the zero value.
Usage: required_if
@@ -262,12 +275,12 @@ Examples:
// require the field if the Field1 and Field2 is equal to the value respectively:
Usage: required_if=Field1 foo Field2 bar
-Required Unless
+# Required Unless
The field under validation must be present and not 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.
+interfaces, channels and functions ensures the value is not nil. For structs ensures value is not the zero value.
Usage: required_unless
@@ -279,12 +292,12 @@ Examples:
// require the field unless the Field1 and Field2 is equal to the value respectively:
Usage: required_unless=Field1 foo Field2 bar
-Required With
+# Required With
The field under validation must be present and not empty only if any
of the other specified fields are present. For strings ensures value is
not "". For slices, maps, pointers, interfaces, channels and functions
-ensures the value is not nil.
+ensures the value is not nil. For structs ensures value is not the zero value.
Usage: required_with
@@ -296,12 +309,12 @@ Examples:
// require the field if the Field1 or Field2 is present:
Usage: required_with=Field1 Field2
-Required With All
+# Required With All
The field under validation must be present and not empty only if all
of the other specified fields are present. For strings ensures value is
not "". For slices, maps, pointers, interfaces, channels and functions
-ensures the value is not nil.
+ensures the value is not nil. For structs ensures value is not the zero value.
Usage: required_with_all
@@ -310,12 +323,12 @@ Example:
// require the field if the Field1 and Field2 is present:
Usage: required_with_all=Field1 Field2
-Required Without
+# Required Without
The field under validation must be present and not empty only when any
of the other specified fields are not present. For strings ensures value is
not "". For slices, maps, pointers, interfaces, channels and functions
-ensures the value is not nil.
+ensures the value is not nil. For structs ensures value is not the zero value.
Usage: required_without
@@ -327,12 +340,12 @@ Examples:
// require the field if the Field1 or Field2 is not present:
Usage: required_without=Field1 Field2
-Required Without All
+# Required Without All
The field under validation must be present and not empty only when all
of the other specified fields are not present. For strings ensures value is
not "". For slices, maps, pointers, interfaces, channels and functions
-ensures the value is not nil.
+ensures the value is not nil. For structs ensures value is not the zero value.
Usage: required_without_all
@@ -341,14 +354,48 @@ Example:
// require the field if the Field1 and Field2 is not present:
Usage: required_without_all=Field1 Field2
-Is Default
+# 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. For structs ensures value is not the zero value.
+
+ 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. For structs ensures value is not the zero value.
+
+ 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
opposite of required.
Usage: isdefault
-Length
+# Length
For numbers, length will ensure that the value is
equal to the parameter given. For strings, it checks that
@@ -366,7 +413,7 @@ in the parameter.
Usage: len=1h30m
-Maximum
+# Maximum
For numbers, max will ensure that the value is
less than or equal to the parameter given. For strings, it checks
@@ -384,7 +431,7 @@ duration given in the parameter.
Usage: max=1h30m
-Minimum
+# Minimum
For numbers, min will ensure that the value is
greater or equal to the parameter given. For strings, it checks that
@@ -402,7 +449,7 @@ the duration given in the parameter.
Usage: min=1h30m
-Equals
+# Equals
For strings & numbers, eq will ensure that the value is
equal to the parameter given. For slices, arrays, and maps,
@@ -419,7 +466,7 @@ in the parameter.
Usage: eq=1h30m
-Not Equal
+# Not Equal
For strings & numbers, ne will ensure that the value is not
equal to the parameter given. For slices, arrays, and maps,
@@ -436,7 +483,7 @@ given in the parameter.
Usage: ne=1h30m
-One Of
+# One Of
For strings, ints, and uints, oneof will ensure that the value
is one of the values in the parameter. The parameter should be
@@ -444,11 +491,11 @@ a list of values separated by whitespace. Values may be
strings or numbers. To match strings with spaces in them, include
the target string between single quotes.
- Usage: oneof=red green
- oneof='red green' 'blue yellow'
- oneof=5 7 9
+ Usage: oneof=red green
+ oneof='red green' 'blue yellow'
+ oneof=5 7 9
-Greater Than
+# Greater Than
For numbers, this will ensure that the value is greater than the
parameter given. For strings, it checks that the string length
@@ -472,7 +519,7 @@ given in the parameter.
Usage: gt=1h30m
-Greater Than or Equal
+# Greater Than or Equal
Same as 'min' above. Kept both to make terminology with 'len' easier.
@@ -493,7 +540,7 @@ the duration given in the parameter.
Usage: gte=1h30m
-Less Than
+# Less Than
For numbers, this will ensure that the value is less than the parameter given.
For strings, it checks that the string length is less than that number of
@@ -516,7 +563,7 @@ in the parameter.
Usage: lt=1h30m
-Less Than or Equal
+# Less Than or Equal
Same as 'max' above. Kept both to make terminology with 'len' easier.
@@ -537,7 +584,7 @@ duration given in the parameter.
Usage: lte=1h30m
-Field Equals Another Field
+# Field Equals Another Field
This will validate the field value against another fields value either within
a struct or passed in field.
@@ -559,7 +606,7 @@ to the top level struct.
Usage: eqcsfield=InnerStructField.Field)
-Field Does Not Equal Another Field
+# Field Does Not Equal Another Field
This will validate the field value against another fields value either within
a struct or passed in field.
@@ -581,7 +628,7 @@ relative to the top level struct.
Usage: necsfield=InnerStructField.Field
-Field Greater Than Another Field
+# Field Greater Than Another Field
Only valid for Numbers, time.Duration and time.Time types, this will validate
the field value against another fields value either within a struct or passed in
@@ -597,14 +644,14 @@ Example #2:
// Validating by field:
validate.VarWithValue(start, end, "gtfield")
-Field Greater Than Another Relative Field
+# Field Greater Than Another Relative Field
This does the same as gtfield except that it validates the field provided
relative to the top level struct.
Usage: gtcsfield=InnerStructField.Field
-Field Greater Than or Equal To Another Field
+# Field Greater Than or Equal To Another Field
Only valid for Numbers, time.Duration and time.Time types, this will validate
the field value against another fields value either within a struct or passed in
@@ -620,14 +667,14 @@ Example #2:
// Validating by field:
validate.VarWithValue(start, end, "gtefield")
-Field Greater Than or Equal To Another Relative Field
+# Field Greater Than or Equal To Another Relative Field
This does the same as gtefield except that it validates the field provided relative
to the top level struct.
Usage: gtecsfield=InnerStructField.Field
-Less Than Another Field
+# Less Than Another Field
Only valid for Numbers, time.Duration and time.Time types, this will validate
the field value against another fields value either within a struct or passed in
@@ -643,14 +690,14 @@ Example #2:
// Validating by field:
validate.VarWithValue(start, end, "ltfield")
-Less Than Another Relative Field
+# Less Than Another Relative Field
This does the same as ltfield except that it validates the field provided relative
to the top level struct.
Usage: ltcsfield=InnerStructField.Field
-Less Than or Equal To Another Field
+# Less Than or Equal To Another Field
Only valid for Numbers, time.Duration and time.Time types, this will validate
the field value against another fields value either within a struct or passed in
@@ -666,14 +713,14 @@ Example #2:
// Validating by field:
validate.VarWithValue(start, end, "ltefield")
-Less Than or Equal To Another Relative Field
+# Less Than or Equal To Another Relative Field
This does the same as ltefield except that it validates the field provided relative
to the top level struct.
Usage: ltecsfield=InnerStructField.Field
-Field Contains Another Field
+# Field Contains Another Field
This does the same as contains except for struct fields. It should only be used
with string types. See the behavior of reflect.Value.String() for behavior on
@@ -681,7 +728,7 @@ other types.
Usage: containsfield=InnerStructField.Field
-Field Excludes Another Field
+# Field Excludes Another Field
This does the same as excludes except for struct fields. It should only be used
with string types. See the behavior of reflect.Value.String() for behavior on
@@ -689,7 +736,7 @@ other types.
Usage: excludesfield=InnerStructField.Field
-Unique
+# Unique
For arrays & slices, unique will ensure that there are no duplicates.
For maps, unique will ensure that there are no duplicate values.
@@ -702,38 +749,44 @@ in a field of the struct specified via a parameter.
// For slices of struct:
Usage: unique=field
-Alpha Only
+# Alpha Only
This validates that a string value contains ASCII alpha characters only
Usage: alpha
-Alphanumeric
+# Alphanumeric
This validates that a string value contains ASCII alphanumeric characters only
Usage: alphanum
-Alpha Unicode
+# Alpha Unicode
This validates that a string value contains unicode alpha characters only
Usage: alphaunicode
-Alphanumeric Unicode
+# Alphanumeric Unicode
This validates that a string value contains unicode alphanumeric characters only
Usage: alphanumunicode
-Number
+# Boolean
+
+This validates that a string value can successfully be parsed into a boolean with strconv.ParseBool
+
+ Usage: boolean
+
+# Number
This validates that a string value contains number values only.
For integers or float it returns true.
Usage: number
-Numeric
+# Numeric
This validates that a string value contains a basic numeric value.
basic excludes exponents etc...
@@ -741,63 +794,63 @@ for integers or float it returns true.
Usage: numeric
-Hexadecimal String
+# Hexadecimal String
This validates that a string value contains a valid hexadecimal.
Usage: hexadecimal
-Hexcolor String
+# Hexcolor String
This validates that a string value contains a valid hex color including
hashtag (#)
- Usage: hexcolor
+ Usage: hexcolor
-Lowercase String
+# Lowercase String
This validates that a string value contains only lowercase characters. An empty string is not a valid lowercase string.
Usage: lowercase
-Uppercase String
+# Uppercase String
This validates that a string value contains only uppercase characters. An empty string is not a valid uppercase string.
Usage: uppercase
-RGB String
+# RGB String
This validates that a string value contains a valid rgb color
Usage: rgb
-RGBA String
+# RGBA String
This validates that a string value contains a valid rgba color
Usage: rgba
-HSL String
+# HSL String
This validates that a string value contains a valid hsl color
Usage: hsl
-HSLA String
+# HSLA String
This validates that a string value contains a valid hsla color
Usage: hsla
-E.164 Phone Number String
+# E.164 Phone Number String
This validates that a string value contains a valid E.164 Phone number
https://en.wikipedia.org/wiki/E.164 (ex. +1123456789)
Usage: e164
-E-mail String
+# E-mail String
This validates that a string value contains a valid email
This may not conform to all possibilities of any rfc standard, but neither
@@ -805,13 +858,19 @@ does any email provider accept all possibilities.
Usage: email
-JSON String
+# JSON String
This validates that a string value is valid JSON
Usage: json
-File path
+# JWT String
+
+This validates that a string value is a valid JWT
+
+ Usage: jwt
+
+# File
This validates that a string value contains a valid file path and that
the file exists on the machine.
@@ -819,7 +878,23 @@ This is done using os.Stat, which is a platform independent function.
Usage: file
-URL String
+# Image path
+
+This validates that a string value contains a valid file path and that
+the file exists on the machine and is an image.
+This is done using os.Stat and github.com/gabriel-vasile/mimetype
+
+ Usage: image
+
+# File Path
+
+This validates that a string value contains a valid file path but does not
+validate the existence of that file.
+This is done using os.Stat, which is a platform independent function.
+
+ Usage: filepath
+
+# URL String
This validates that a string value contains a valid url
This will accept any url the golang request uri accepts but must contain
@@ -827,21 +902,21 @@ a schema for example http:// or rtmp://
Usage: url
-URI String
+# URI String
This validates that a string value contains a valid uri
This will accept any uri the golang request uri accepts
Usage: uri
-Urn RFC 2141 String
+# Urn RFC 2141 String
This validataes that a string value contains a valid URN
according to the RFC 2141 spec.
Usage: urn_rfc2141
-Base64 String
+# Base64 String
This validates that a string value contains a valid base64 value.
Although an empty string is valid base64 this will report an empty string
@@ -850,17 +925,27 @@ this with the omitempty tag.
Usage: base64
-Base64URL String
+# Base64URL String
This validates that a string value contains a valid base64 URL safe value
-according the the RFC4648 spec.
+according the RFC4648 spec.
Although an empty string is a valid base64 URL safe value, this will report
an empty string as an error, if you wish to accept an empty string as valid
you can use this with the omitempty tag.
Usage: base64url
-Bitcoin Address
+# Base64RawURL String
+
+This validates that a string value contains a valid base64 URL safe value,
+but without = padding, according the RFC4648 spec, section 3.2.
+Although an empty string is a valid base64 URL safe value, this will report
+an empty string as an error, if you wish to accept an empty string as valid
+you can use this with the omitempty tag.
+
+ Usage: base64url
+
+# Bitcoin Address
This validates that a string value contains a valid bitcoin address.
The format of the string is checked to ensure it matches one of the three formats
@@ -876,260 +961,266 @@ Special thanks to Pieter Wuille for providng reference implementations.
Usage: btc_addr_bech32
-Ethereum Address
+# Ethereum Address
This validates that a string value contains a valid ethereum address.
The format of the string is checked to ensure it matches the standard Ethereum address format.
Usage: eth_addr
-Contains
+# Contains
This validates that a string value contains the substring value.
Usage: contains=@
-Contains Any
+# Contains Any
This validates that a string value contains any Unicode code points
in the substring value.
Usage: containsany=!@#?
-Contains Rune
+# Contains Rune
This validates that a string value contains the supplied rune value.
Usage: containsrune=@
-Excludes
+# Excludes
This validates that a string value does not contain the substring value.
Usage: excludes=@
-Excludes All
+# Excludes All
This validates that a string value does not contain any Unicode code
points in the substring value.
Usage: excludesall=!@#?
-Excludes Rune
+# Excludes Rune
This validates that a string value does not contain the supplied rune value.
Usage: excludesrune=@
-Starts With
+# Starts With
This validates that a string value starts with the supplied string value
Usage: startswith=hello
-Ends With
+# Ends With
This validates that a string value ends with the supplied string value
Usage: endswith=goodbye
-Does Not Start With
+# Does Not Start With
This validates that a string value does not start with the supplied string value
Usage: startsnotwith=hello
-Does Not End With
+# Does Not End With
This validates that a string value does not end with the supplied string value
Usage: endsnotwith=goodbye
-International Standard Book Number
+# International Standard Book Number
This validates that a string value contains a valid isbn10 or isbn13 value.
Usage: isbn
-International Standard Book Number 10
+# International Standard Book Number 10
This validates that a string value contains a valid isbn10 value.
Usage: isbn10
-International Standard Book Number 13
+# International Standard Book Number 13
This validates that a string value contains a valid isbn13 value.
Usage: isbn13
-Universally Unique Identifier UUID
+# Universally Unique Identifier UUID
This validates that a string value contains a valid UUID. Uppercase UUID values will not pass - use `uuid_rfc4122` instead.
Usage: uuid
-Universally Unique Identifier UUID v3
+# Universally Unique Identifier UUID v3
This validates that a string value contains a valid version 3 UUID. Uppercase UUID values will not pass - use `uuid3_rfc4122` instead.
Usage: uuid3
-Universally Unique Identifier UUID v4
+# Universally Unique Identifier UUID v4
This validates that a string value contains a valid version 4 UUID. Uppercase UUID values will not pass - use `uuid4_rfc4122` instead.
Usage: uuid4
-Universally Unique Identifier UUID v5
+# Universally Unique Identifier UUID v5
This validates that a string value contains a valid version 5 UUID. Uppercase UUID values will not pass - use `uuid5_rfc4122` instead.
Usage: uuid5
-ASCII
+# 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.
NOTE: if the string is blank, this validates as true.
Usage: ascii
-Printable ASCII
+# Printable ASCII
This validates that a string value contains only printable ASCII characters.
NOTE: if the string is blank, this validates as true.
Usage: printascii
-Multi-Byte Characters
+# Multi-Byte Characters
This validates that a string value contains one or more multibyte characters.
NOTE: if the string is blank, this validates as true.
Usage: multibyte
-Data URL
+# Data URL
This validates that a string value contains a valid DataURI.
NOTE: this will also validate that the data portion is valid base64
Usage: datauri
-Latitude
+# Latitude
This validates that a string value contains a valid latitude.
Usage: latitude
-Longitude
+# Longitude
This validates that a string value contains a valid longitude.
Usage: longitude
-Social Security Number SSN
+# Social Security Number SSN
This validates that a string value contains a valid U.S. Social Security Number.
Usage: ssn
-Internet Protocol Address IP
+# Internet Protocol Address IP
This validates that a string value contains a valid IP Address.
Usage: ip
-Internet Protocol Address IPv4
+# Internet Protocol Address IPv4
This validates that a string value contains a valid v4 IP Address.
Usage: ipv4
-Internet Protocol Address IPv6
+# Internet Protocol Address IPv6
This validates that a string value contains a valid v6 IP Address.
Usage: ipv6
-Classless Inter-Domain Routing CIDR
+# Classless Inter-Domain Routing CIDR
This validates that a string value contains a valid CIDR Address.
Usage: cidr
-Classless Inter-Domain Routing CIDRv4
+# Classless Inter-Domain Routing CIDRv4
This validates that a string value contains a valid v4 CIDR Address.
Usage: cidrv4
-Classless Inter-Domain Routing CIDRv6
+# Classless Inter-Domain Routing CIDRv6
This validates that a string value contains a valid v6 CIDR Address.
Usage: cidrv6
-Transmission Control Protocol Address TCP
+# Transmission Control Protocol Address TCP
This validates that a string value contains a valid resolvable TCP Address.
Usage: tcp_addr
-Transmission Control Protocol Address TCPv4
+# Transmission Control Protocol Address TCPv4
This validates that a string value contains a valid resolvable v4 TCP Address.
Usage: tcp4_addr
-Transmission Control Protocol Address TCPv6
+# Transmission Control Protocol Address TCPv6
This validates that a string value contains a valid resolvable v6 TCP Address.
Usage: tcp6_addr
-User Datagram Protocol Address UDP
+# User Datagram Protocol Address UDP
This validates that a string value contains a valid resolvable UDP Address.
Usage: udp_addr
-User Datagram Protocol Address UDPv4
+# User Datagram Protocol Address UDPv4
This validates that a string value contains a valid resolvable v4 UDP Address.
Usage: udp4_addr
-User Datagram Protocol Address UDPv6
+# User Datagram Protocol Address UDPv6
This validates that a string value contains a valid resolvable v6 UDP Address.
Usage: udp6_addr
-Internet Protocol Address IP
+# Internet Protocol Address IP
This validates that a string value contains a valid resolvable IP Address.
Usage: ip_addr
-Internet Protocol Address IPv4
+# Internet Protocol Address IPv4
This validates that a string value contains a valid resolvable v4 IP Address.
Usage: ip4_addr
-Internet Protocol Address IPv6
+# Internet Protocol Address IPv6
This validates that a string value contains a valid resolvable v6 IP Address.
Usage: ip6_addr
-Unix domain socket end point Address
+# Unix domain socket end point Address
This validates that a string value contains a valid Unix Address.
Usage: unix_addr
-Media Access Control Address MAC
+# Media Access Control Address MAC
This validates that a string value contains a valid MAC Address.
@@ -1139,13 +1230,13 @@ Note: See Go's ParseMAC for accepted formats and types:
http://golang.org/src/net/mac.go?s=866:918#L29
-Hostname RFC 952
+# Hostname RFC 952
This validates that a string value is a valid Hostname according to RFC 952 https://tools.ietf.org/html/rfc952
Usage: hostname
-Hostname RFC 1123
+# Hostname RFC 1123
This validates that a string value is a valid Hostname according to RFC 1123 https://tools.ietf.org/html/rfc1123
@@ -1157,28 +1248,28 @@ This validates that a string value contains a valid FQDN.
Usage: fqdn
-HTML Tags
+# HTML Tags
This validates that a string value appears to be an HTML element tag
including those described at https://developer.mozilla.org/en-US/docs/Web/HTML/Element
Usage: html
-HTML Encoded
+# HTML Encoded
This validates that a string value is a proper character reference in decimal
or hexadecimal format
Usage: html_encoded
-URL Encoded
+# URL Encoded
This validates that a string value is percent-encoded (URL encoded) according
to https://tools.ietf.org/html/rfc3986#section-2.1
Usage: url_encoded
-Directory
+# Directory
This validates that a string value contains a valid directory and that
it exists on the machine.
@@ -1186,52 +1277,127 @@ This is done using os.Stat, which is a platform independent function.
Usage: dir
-HostPort
+# Directory Path
+
+This validates that a string value contains a valid directory but does
+not validate the existence of that directory.
+This is done using os.Stat, which is a platform independent function.
+It is safest to suffix the string with os.PathSeparator if the directory
+may not exist at the time of validation.
+
+ Usage: dirpath
+
+# HostPort
This validates that a string value contains a valid DNS hostname and port that
can be used to valiate fields typically passed to sockets and connections.
Usage: hostname_port
-Datetime
+# Datetime
This validates that a string value is a valid datetime based on the supplied datetime format.
Supplied format must match the official Go time format layout as documented in https://golang.org/pkg/time/
Usage: datetime=2006-01-02
-Iso3166-1 alpha-2
+# Iso3166-1 alpha-2
This validates that a string value is a valid country code based on iso3166-1 alpha-2 standard.
see: https://www.iso.org/iso-3166-country-codes.html
Usage: iso3166_1_alpha2
-Iso3166-1 alpha-3
+# Iso3166-1 alpha-3
This validates that a string value is a valid country code based on iso3166-1 alpha-3 standard.
see: https://www.iso.org/iso-3166-country-codes.html
Usage: iso3166_1_alpha3
-Iso3166-1 alpha-numeric
+# Iso3166-1 alpha-numeric
This validates that a string value is a valid country code based on iso3166-1 alpha-numeric standard.
see: https://www.iso.org/iso-3166-country-codes.html
Usage: iso3166_1_alpha3
-TimeZone
+# BCP 47 Language Tag
+
+This validates that a string value is a valid BCP 47 language tag, as parsed by language.Parse.
+More information on https://pkg.go.dev/golang.org/x/text/language
+
+ Usage: bcp47_language_tag
+
+BIC (SWIFT code)
+
+This validates that a string value is a valid Business Identifier Code (SWIFT code), defined in ISO 9362.
+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.
Although empty value and Local value are allowed by time.LoadLocation golang function, they are not allowed by this validator.
More information on https://golang.org/pkg/time/#LoadLocation
Usage: timezone
-
-Alias Validators and Tags
+# 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
+
+# CVE Identifier
+
+This validates that a string value is a valid cve id, defined in cve mitre.
+More information on https://cve.mitre.org/
+
+ Usage: cve
+
+# Credit Card
+
+This validates that a string value contains a valid credit card number using Luhn algorithm.
+
+ Usage: credit_card
+
+# Luhn Checksum
+
+ Usage: luhn_checksum
+
+This validates that a string or (u)int value contains a valid checksum using the Luhn algorithm.
+
+# MongoDb ObjectID
+
+This validates that a string is a valid 24 character hexadecimal string.
+
+ Usage: mongodb
+
+# Cron
+
+This validates that a string value contains a valid cron expression.
+
+ Usage: cron
+
+# SpiceDb ObjectID/Permission/Object Type
+
+This validates that a string is valid for use with SpiceDb for the indicated purpose. If no purpose is given, a purpose of 'id' is assumed.
+
+ Usage: spicedb=id|permission|type
+
+# Alias Validators and Tags
+
+Alias Validators and Tags
NOTE: When returning an error, the tag returned in "FieldError" will be
the alias tag unless the dive tag is part of the alias. Everything after the
dive tag is not reported as the alias tag. Also, the "ActualTag" in the before
@@ -1261,7 +1427,7 @@ Validator notes:
And the best reason, you can submit a pull request and we can keep on
adding to the validation library of this package!
-Non standard validators
+# Non standard validators
A collection of validation rules that are frequently needed but are more
complex than the ones found in the baked in validators.
@@ -1290,7 +1456,7 @@ Here is a list of the current non standard validators:
Usage: notblank
-Panics
+# Panics
This package panics when bad input is provided, this is by design, bad code like
that should not make it to production.
diff --git a/vendor/github.com/go-playground/validator/v10/errors.go b/vendor/github.com/go-playground/validator/v10/errors.go
index 63293cf9edc..5856d57c8c9 100644
--- a/vendor/github.com/go-playground/validator/v10/errors.go
+++ b/vendor/github.com/go-playground/validator/v10/errors.go
@@ -44,12 +44,9 @@ func (ve ValidationErrors) Error() string {
buff := bytes.NewBufferString("")
- var fe *fieldError
-
for i := 0; i < len(ve); i++ {
- fe = ve[i].(*fieldError)
- buff.WriteString(fe.Error())
+ buff.WriteString(ve[i].Error())
buff.WriteString("\n")
}
@@ -82,7 +79,7 @@ func (ve ValidationErrors) Translate(ut ut.Translator) ValidationErrorsTranslati
// FieldError contains all functions to get error details
type FieldError interface {
- // returns the validation tag that failed. if the
+ // Tag returns the validation tag that failed. if the
// validation was an alias, this will return the
// alias name and not the underlying tag that failed.
//
@@ -90,7 +87,7 @@ type FieldError interface {
// will return "iscolor"
Tag() string
- // returns the validation tag that failed, even if an
+ // ActualTag returns the validation tag that failed, even if an
// alias the actual tag within the alias will be returned.
// If an 'or' validation fails the entire or will be returned.
//
@@ -98,7 +95,7 @@ type FieldError interface {
// will return "hexcolor|rgb|rgba|hsl|hsla"
ActualTag() string
- // returns the namespace for the field error, with the tag
+ // Namespace returns the namespace for the field error, with the tag
// name taking precedence over the field's actual name.
//
// eg. JSON name "User.fname"
@@ -109,7 +106,7 @@ type FieldError interface {
// using validate.Field(...) as there is no way to extract it's name
Namespace() string
- // returns the namespace for the field error, with the field's
+ // StructNamespace returns the namespace for the field error, with the field's
// actual name.
//
// eq. "User.FirstName" see Namespace for comparison
@@ -118,24 +115,24 @@ type FieldError interface {
// using validate.Field(...) as there is no way to extract its name
StructNamespace() string
- // returns the fields name with the tag name taking precedence over the
+ // Field returns the fields name with the tag name taking precedence over the
// field's actual name.
//
// eq. JSON name "fname"
// see StructField for comparison
Field() string
- // returns the field's actual name from the struct, when able to determine.
+ // StructField returns the field's actual name from the struct, when able to determine.
//
// eq. "FirstName"
// see Field for comparison
StructField() string
- // returns the actual field's value in case needed for creating the error
+ // Value returns the actual field's value in case needed for creating the error
// message
Value() interface{}
- // returns the param value, in string form for comparison; this will also
+ // Param returns the param value, in string form for comparison; this will also
// help with generating an error message
Param() string
@@ -146,10 +143,10 @@ type FieldError interface {
// Type returns the Field's reflect Type
//
- // // eg. time.Time's type is time.Time
+ // eg. time.Time's type is time.Time
Type() reflect.Type
- // returns the FieldError's translated error
+ // Translate returns the FieldError's translated error
// from the provided 'ut.Translator' and registered 'TranslationFunc'
//
// NOTE: if no registered translator can be found it returns the same as
@@ -221,7 +218,7 @@ func (fe *fieldError) Field() string {
// return fld
}
-// returns the field's actual name from the struct, when able to determine.
+// StructField returns the field's actual name from the struct, when able to determine.
func (fe *fieldError) StructField() string {
// return fe.structField
return fe.structNs[len(fe.structNs)-int(fe.structfieldLen):]
diff --git a/vendor/github.com/go-playground/validator/v10/field_level.go b/vendor/github.com/go-playground/validator/v10/field_level.go
index f0e2a9a855e..ef35826ee6f 100644
--- a/vendor/github.com/go-playground/validator/v10/field_level.go
+++ b/vendor/github.com/go-playground/validator/v10/field_level.go
@@ -5,24 +5,25 @@ import "reflect"
// FieldLevel contains all the information and helper functions
// to validate a field
type FieldLevel interface {
- // returns the top level struct, if any
+
+ // Top returns the top level struct, if any
Top() reflect.Value
- // returns the current fields parent struct, if any or
+ // Parent returns the current fields parent struct, if any or
// the comparison value if called 'VarWithValue'
Parent() reflect.Value
- // returns current field for validation
+ // Field returns current field for validation
Field() reflect.Value
- // returns the field's name with the tag
+ // FieldName returns the field's name with the tag
// name taking precedence over the fields actual name.
FieldName() string
- // returns the struct field's name
+ // StructFieldName returns the struct field's name
StructFieldName() string
- // returns param for validation against current field
+ // Param returns param for validation against current field
Param() string
// GetTag returns the current validations tag name
@@ -33,7 +34,7 @@ type FieldLevel interface {
// underlying value and it's kind.
ExtractType(field reflect.Value) (value reflect.Value, kind reflect.Kind, nullable bool)
- // traverses the parent struct to retrieve a specific field denoted by the provided namespace
+ // GetStructFieldOK traverses the parent struct to retrieve a specific field denoted by the provided namespace
// in the param and returns the field, field kind and whether is was successful in retrieving
// the field at all.
//
@@ -49,7 +50,7 @@ type FieldLevel interface {
// Deprecated: Use GetStructFieldOKAdvanced2() instead which also return if the value is nullable.
GetStructFieldOKAdvanced(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool)
- // traverses the parent struct to retrieve a specific field denoted by the provided namespace
+ // GetStructFieldOK2 traverses the parent struct to retrieve a specific field denoted by the provided namespace
// in the param and returns the field, field kind, if it's a nullable type and whether is was successful in retrieving
// the field at all.
//
@@ -57,7 +58,7 @@ type FieldLevel interface {
// could not be retrieved because it didn't exist.
GetStructFieldOK2() (reflect.Value, reflect.Kind, bool, bool)
- // GetStructFieldOKAdvanced is the same as GetStructFieldOK except that it accepts the parent struct to start looking for
+ // GetStructFieldOKAdvanced2 is the same as GetStructFieldOK except that it accepts the parent struct to start looking for
// the field and namespace allowing more extensibility for validators.
GetStructFieldOKAdvanced2(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool, bool)
}
@@ -107,12 +108,12 @@ func (v *validate) GetStructFieldOKAdvanced(val reflect.Value, namespace string)
return current, kind, found
}
-// GetStructFieldOK returns Param returns param for validation against current field
+// GetStructFieldOK2 returns Param returns param for validation against current field
func (v *validate) GetStructFieldOK2() (reflect.Value, reflect.Kind, bool, bool) {
return v.getStructFieldOKInternal(v.slflParent, v.ct.param)
}
-// GetStructFieldOKAdvanced is the same as GetStructFieldOK except that it accepts the parent struct to start looking for
+// GetStructFieldOKAdvanced2 is the same as GetStructFieldOK except that it accepts the parent struct to start looking for
// the field and namespace allowing more extensibility for validators.
func (v *validate) GetStructFieldOKAdvanced2(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool, bool) {
return v.getStructFieldOKInternal(val, namespace)
diff --git a/vendor/github.com/go-playground/validator/v10/options.go b/vendor/github.com/go-playground/validator/v10/options.go
new file mode 100644
index 00000000000..1dea56fd783
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/options.go
@@ -0,0 +1,16 @@
+package validator
+
+// Option represents a configurations option to be applied to validator during initialization.
+type Option func(*Validate)
+
+// WithRequiredStructEnabled enables required tag on non-pointer structs to be applied instead of ignored.
+//
+// This was made opt-in behaviour in order to maintain backward compatibility with the behaviour previous
+// to being able to apply struct level validations on struct fields directly.
+//
+// It is recommended you enabled this as it will be the default behaviour in v11+
+func WithRequiredStructEnabled() Option {
+ return func(v *Validate) {
+ v.requiredStructEnabled = true
+ }
+}
diff --git a/vendor/github.com/go-playground/validator/v10/postcode_regexes.go b/vendor/github.com/go-playground/validator/v10/postcode_regexes.go
new file mode 100644
index 00000000000..e7e7b687f4b
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/postcode_regexes.go
@@ -0,0 +1,173 @@
+package validator
+
+import "regexp"
+
+var postCodePatternDict = map[string]string{
+ "GB": `^GIR[ ]?0AA|((AB|AL|B|BA|BB|BD|BH|BL|BN|BR|BS|BT|CA|CB|CF|CH|CM|CO|CR|CT|CV|CW|DA|DD|DE|DG|DH|DL|DN|DT|DY|E|EC|EH|EN|EX|FK|FY|G|GL|GY|GU|HA|HD|HG|HP|HR|HS|HU|HX|IG|IM|IP|IV|JE|KA|KT|KW|KY|L|LA|LD|LE|LL|LN|LS|LU|M|ME|MK|ML|N|NE|NG|NN|NP|NR|NW|OL|OX|PA|PE|PH|PL|PO|PR|RG|RH|RM|S|SA|SE|SG|SK|SL|SM|SN|SO|SP|SR|SS|ST|SW|SY|TA|TD|TF|TN|TQ|TR|TS|TW|UB|W|WA|WC|WD|WF|WN|WR|WS|WV|YO|ZE)(\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}))|BFPO[ ]?\d{1,4}$`,
+ "JE": `^JE\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}$`,
+ "GG": `^GY\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}$`,
+ "IM": `^IM\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}$`,
+ "US": `^\d{5}([ \-]\d{4})?$`,
+ "CA": `^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ ]?\d[ABCEGHJ-NPRSTV-Z]\d$`,
+ "DE": `^\d{5}$`,
+ "JP": `^\d{3}-\d{4}$`,
+ "FR": `^\d{2}[ ]?\d{3}$`,
+ "AU": `^\d{4}$`,
+ "IT": `^\d{5}$`,
+ "CH": `^\d{4}$`,
+ "AT": `^\d{4}$`,
+ "ES": `^\d{5}$`,
+ "NL": `^\d{4}[ ]?[A-Z]{2}$`,
+ "BE": `^\d{4}$`,
+ "DK": `^\d{4}$`,
+ "SE": `^\d{3}[ ]?\d{2}$`,
+ "NO": `^\d{4}$`,
+ "BR": `^\d{5}[\-]?\d{3}$`,
+ "PT": `^\d{4}([\-]\d{3})?$`,
+ "FI": `^\d{5}$`,
+ "AX": `^22\d{3}$`,
+ "KR": `^\d{3}[\-]\d{3}$`,
+ "CN": `^\d{6}$`,
+ "TW": `^\d{3}(\d{2})?$`,
+ "SG": `^\d{6}$`,
+ "DZ": `^\d{5}$`,
+ "AD": `^AD\d{3}$`,
+ "AR": `^([A-HJ-NP-Z])?\d{4}([A-Z]{3})?$`,
+ "AM": `^(37)?\d{4}$`,
+ "AZ": `^\d{4}$`,
+ "BH": `^((1[0-2]|[2-9])\d{2})?$`,
+ "BD": `^\d{4}$`,
+ "BB": `^(BB\d{5})?$`,
+ "BY": `^\d{6}$`,
+ "BM": `^[A-Z]{2}[ ]?[A-Z0-9]{2}$`,
+ "BA": `^\d{5}$`,
+ "IO": `^BBND 1ZZ$`,
+ "BN": `^[A-Z]{2}[ ]?\d{4}$`,
+ "BG": `^\d{4}$`,
+ "KH": `^\d{5}$`,
+ "CV": `^\d{4}$`,
+ "CL": `^\d{7}$`,
+ "CR": `^\d{4,5}|\d{3}-\d{4}$`,
+ "HR": `^\d{5}$`,
+ "CY": `^\d{4}$`,
+ "CZ": `^\d{3}[ ]?\d{2}$`,
+ "DO": `^\d{5}$`,
+ "EC": `^([A-Z]\d{4}[A-Z]|(?:[A-Z]{2})?\d{6})?$`,
+ "EG": `^\d{5}$`,
+ "EE": `^\d{5}$`,
+ "FO": `^\d{3}$`,
+ "GE": `^\d{4}$`,
+ "GR": `^\d{3}[ ]?\d{2}$`,
+ "GL": `^39\d{2}$`,
+ "GT": `^\d{5}$`,
+ "HT": `^\d{4}$`,
+ "HN": `^(?:\d{5})?$`,
+ "HU": `^\d{4}$`,
+ "IS": `^\d{3}$`,
+ "IN": `^\d{6}$`,
+ "ID": `^\d{5}$`,
+ "IL": `^\d{5}$`,
+ "JO": `^\d{5}$`,
+ "KZ": `^\d{6}$`,
+ "KE": `^\d{5}$`,
+ "KW": `^\d{5}$`,
+ "LA": `^\d{5}$`,
+ "LV": `^\d{4}$`,
+ "LB": `^(\d{4}([ ]?\d{4})?)?$`,
+ "LI": `^(948[5-9])|(949[0-7])$`,
+ "LT": `^\d{5}$`,
+ "LU": `^\d{4}$`,
+ "MK": `^\d{4}$`,
+ "MY": `^\d{5}$`,
+ "MV": `^\d{5}$`,
+ "MT": `^[A-Z]{3}[ ]?\d{2,4}$`,
+ "MU": `^(\d{3}[A-Z]{2}\d{3})?$`,
+ "MX": `^\d{5}$`,
+ "MD": `^\d{4}$`,
+ "MC": `^980\d{2}$`,
+ "MA": `^\d{5}$`,
+ "NP": `^\d{5}$`,
+ "NZ": `^\d{4}$`,
+ "NI": `^((\d{4}-)?\d{3}-\d{3}(-\d{1})?)?$`,
+ "NG": `^(\d{6})?$`,
+ "OM": `^(PC )?\d{3}$`,
+ "PK": `^\d{5}$`,
+ "PY": `^\d{4}$`,
+ "PH": `^\d{4}$`,
+ "PL": `^\d{2}-\d{3}$`,
+ "PR": `^00[679]\d{2}([ \-]\d{4})?$`,
+ "RO": `^\d{6}$`,
+ "RU": `^\d{6}$`,
+ "SM": `^4789\d$`,
+ "SA": `^\d{5}$`,
+ "SN": `^\d{5}$`,
+ "SK": `^\d{3}[ ]?\d{2}$`,
+ "SI": `^\d{4}$`,
+ "ZA": `^\d{4}$`,
+ "LK": `^\d{5}$`,
+ "TJ": `^\d{6}$`,
+ "TH": `^\d{5}$`,
+ "TN": `^\d{4}$`,
+ "TR": `^\d{5}$`,
+ "TM": `^\d{6}$`,
+ "UA": `^\d{5}$`,
+ "UY": `^\d{5}$`,
+ "UZ": `^\d{6}$`,
+ "VA": `^00120$`,
+ "VE": `^\d{4}$`,
+ "ZM": `^\d{5}$`,
+ "AS": `^96799$`,
+ "CC": `^6799$`,
+ "CK": `^\d{4}$`,
+ "RS": `^\d{6}$`,
+ "ME": `^8\d{4}$`,
+ "CS": `^\d{5}$`,
+ "YU": `^\d{5}$`,
+ "CX": `^6798$`,
+ "ET": `^\d{4}$`,
+ "FK": `^FIQQ 1ZZ$`,
+ "NF": `^2899$`,
+ "FM": `^(9694[1-4])([ \-]\d{4})?$`,
+ "GF": `^9[78]3\d{2}$`,
+ "GN": `^\d{3}$`,
+ "GP": `^9[78][01]\d{2}$`,
+ "GS": `^SIQQ 1ZZ$`,
+ "GU": `^969[123]\d([ \-]\d{4})?$`,
+ "GW": `^\d{4}$`,
+ "HM": `^\d{4}$`,
+ "IQ": `^\d{5}$`,
+ "KG": `^\d{6}$`,
+ "LR": `^\d{4}$`,
+ "LS": `^\d{3}$`,
+ "MG": `^\d{3}$`,
+ "MH": `^969[67]\d([ \-]\d{4})?$`,
+ "MN": `^\d{6}$`,
+ "MP": `^9695[012]([ \-]\d{4})?$`,
+ "MQ": `^9[78]2\d{2}$`,
+ "NC": `^988\d{2}$`,
+ "NE": `^\d{4}$`,
+ "VI": `^008(([0-4]\d)|(5[01]))([ \-]\d{4})?$`,
+ "VN": `^[0-9]{1,6}$`,
+ "PF": `^987\d{2}$`,
+ "PG": `^\d{3}$`,
+ "PM": `^9[78]5\d{2}$`,
+ "PN": `^PCRN 1ZZ$`,
+ "PW": `^96940$`,
+ "RE": `^9[78]4\d{2}$`,
+ "SH": `^(ASCN|STHL) 1ZZ$`,
+ "SJ": `^\d{4}$`,
+ "SO": `^\d{5}$`,
+ "SZ": `^[HLMS]\d{3}$`,
+ "TC": `^TKCA 1ZZ$`,
+ "WF": `^986\d{2}$`,
+ "XK": `^\d{5}$`,
+ "YT": `^976\d{2}$`,
+}
+
+var postCodeRegexDict = map[string]*regexp.Regexp{}
+
+func init() {
+ for countryCode, pattern := range postCodePatternDict {
+ postCodeRegexDict[countryCode] = regexp.MustCompile(pattern)
+ }
+}
diff --git a/vendor/github.com/go-playground/validator/v10/regexes.go b/vendor/github.com/go-playground/validator/v10/regexes.go
index b741f4e1767..af98d8daa62 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*\\)$"
@@ -19,8 +19,10 @@ const (
e164RegexString = "^\\+[1-9]?[0-9]{7,14}$"
base64RegexString = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$"
base64URLRegexString = "^(?:[A-Za-z0-9-_]{4})*(?:[A-Za-z0-9-_]{2}==|[A-Za-z0-9-_]{3}=|[A-Za-z0-9-_]{4})$"
+ base64RawURLRegexString = "^(?:[A-Za-z0-9-_]{4})*(?:[A-Za-z0-9-_]{2,4})$"
iSBN10RegexString = "^(?:[0-9]{9}X|[0-9]{10})$"
iSBN13RegexString = "^(?:(?:97(?:8|9))[0-9]{10})$"
+ iSSNRegexString = "^(?:[0-9]{4}-[0-9]{3}[0-9X])$"
uUID3RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$"
uUID4RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
uUID5RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
@@ -29,6 +31,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,19 +49,29 @@ 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}$`
- uRLEncodedRegexString = `(%[A-Fa-f0-9]{2})`
+ uRLEncodedRegexString = `^(?:[^%]|%[0-9A-Fa-f]{2})*$`
hTMLEncodedRegexString = `[x]?([0-9a-fA-F]{2})|(>)|(<)|(")|(&)+[;]?`
hTMLRegexString = `<[/]?([a-zA-Z]+).*?>`
+ 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}$"
+ cveRegexString = `^CVE-(1999|2\d{3})-(0[^0]\d{2}|0\d[^0]\d{1}|0\d{2}[^0]|[1-9]{1}\d{3,})$` // CVE Format Id https://cve.mitre.org/cve/identifiers/syntaxchange.html
+ mongodbRegexString = "^[a-f\\d]{24}$"
+ cronRegexString = `(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|µs|ms|s|m|h))+)|((((\d+,)+\d+|(\d+(\/|-)\d+)|\d+|\*) ?){5,7})`
+ spicedbIDRegexString = `^(([a-zA-Z0-9/_|\-=+]{1,})|\*)$`
+ spicedbPermissionRegexString = "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
+ spicedbTypeRegexString = "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)?[a-z][a-z0-9_]{1,62}[a-z0-9]$"
)
var (
@@ -59,7 +82,7 @@ var (
numericRegex = regexp.MustCompile(numericRegexString)
numberRegex = regexp.MustCompile(numberRegexString)
hexadecimalRegex = regexp.MustCompile(hexadecimalRegexString)
- hexcolorRegex = regexp.MustCompile(hexcolorRegexString)
+ hexColorRegex = regexp.MustCompile(hexColorRegexString)
rgbRegex = regexp.MustCompile(rgbRegexString)
rgbaRegex = regexp.MustCompile(rgbaRegexString)
hslRegex = regexp.MustCompile(hslRegexString)
@@ -68,8 +91,10 @@ var (
emailRegex = regexp.MustCompile(emailRegexString)
base64Regex = regexp.MustCompile(base64RegexString)
base64URLRegex = regexp.MustCompile(base64URLRegexString)
+ base64RawURLRegex = regexp.MustCompile(base64RawURLRegexString)
iSBN10Regex = regexp.MustCompile(iSBN10RegexString)
iSBN13Regex = regexp.MustCompile(iSBN13RegexString)
+ iSSNRegex = regexp.MustCompile(iSSNRegexString)
uUID3Regex = regexp.MustCompile(uUID3RegexString)
uUID4Regex = regexp.MustCompile(uUID4RegexString)
uUID5Regex = regexp.MustCompile(uUID5RegexString)
@@ -78,6 +103,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)
@@ -92,10 +128,18 @@ var (
btcUpperAddressRegexBech32 = regexp.MustCompile(btcAddressUpperRegexStringBech32)
btcLowerAddressRegexBech32 = regexp.MustCompile(btcAddressLowerRegexStringBech32)
ethAddressRegex = regexp.MustCompile(ethAddressRegexString)
- ethaddressRegexUpper = regexp.MustCompile(ethAddressUpperRegexString)
- ethAddressRegexLower = regexp.MustCompile(ethAddressLowerRegexString)
uRLEncodedRegex = regexp.MustCompile(uRLEncodedRegexString)
hTMLEncodedRegex = regexp.MustCompile(hTMLEncodedRegexString)
hTMLRegex = regexp.MustCompile(hTMLRegexString)
+ jWTRegex = regexp.MustCompile(jWTRegexString)
splitParamsRegex = regexp.MustCompile(splitParamsRegexString)
+ bicRegex = regexp.MustCompile(bicRegexString)
+ semverRegex = regexp.MustCompile(semverRegexString)
+ dnsRegexRFC1035Label = regexp.MustCompile(dnsRegexStringRFC1035Label)
+ cveRegex = regexp.MustCompile(cveRegexString)
+ mongodbRegex = regexp.MustCompile(mongodbRegexString)
+ cronRegex = regexp.MustCompile(cronRegexString)
+ spicedbIDRegex = regexp.MustCompile(spicedbIDRegexString)
+ spicedbPermissionRegex = regexp.MustCompile(spicedbPermissionRegexString)
+ spicedbTypeRegex = regexp.MustCompile(spicedbTypeRegexString)
)
diff --git a/vendor/github.com/go-playground/validator/v10/struct_level.go b/vendor/github.com/go-playground/validator/v10/struct_level.go
index 57691ee380c..271328f7107 100644
--- a/vendor/github.com/go-playground/validator/v10/struct_level.go
+++ b/vendor/github.com/go-playground/validator/v10/struct_level.go
@@ -23,18 +23,18 @@ func wrapStructLevelFunc(fn StructLevelFunc) StructLevelFuncCtx {
// to validate a struct
type StructLevel interface {
- // returns the main validation object, in case one wants to call validations internally.
+ // Validator returns the main validation object, in case one wants to call validations internally.
// this is so you don't have to use anonymous functions to get access to the validate
// instance.
Validator() *Validate
- // returns the top level struct, if any
+ // Top returns the top level struct, if any
Top() reflect.Value
- // returns the current fields parent struct, if any
+ // Parent returns the current fields parent struct, if any
Parent() reflect.Value
- // returns the current struct.
+ // Current returns the current struct.
Current() reflect.Value
// ExtractType gets the actual underlying type of field value.
@@ -42,7 +42,7 @@ type StructLevel interface {
// underlying value and its kind.
ExtractType(field reflect.Value) (value reflect.Value, kind reflect.Kind, nullable bool)
- // reports an error just by passing the field and tag information
+ // ReportError reports an error just by passing the field and tag information
//
// NOTES:
//
@@ -54,7 +54,7 @@ type StructLevel interface {
// and process on the flip side it's up to you.
ReportError(field interface{}, fieldName, structFieldName string, tag, param string)
- // reports an error just by passing ValidationErrors
+ // ReportValidationErrors reports an error just by passing ValidationErrors
//
// NOTES:
//
@@ -62,7 +62,7 @@ type StructLevel interface {
// existing namespace that validator is on.
// e.g. pass 'User.FirstName' or 'Users[0].FirstName' depending
// on the nesting. most of the time they will be blank, unless you validate
- // at a level lower the the current field depth
+ // at a level lower the current field depth
ReportValidationErrors(relativeNamespace, relativeActualNamespace string, errs ValidationErrors)
}
@@ -74,7 +74,7 @@ var _ StructLevel = new(validate)
// if not is a nested struct.
//
// this is only called when within Struct and Field Level validation and
-// should not be relied upon for an acurate value otherwise.
+// should not be relied upon for an accurate value otherwise.
func (v *validate) Top() reflect.Value {
return v.top
}
@@ -85,7 +85,7 @@ func (v *validate) Top() reflect.Value {
// if not is a nested struct.
//
// this is only called when within Struct and Field Level validation and
-// should not be relied upon for an acurate value otherwise.
+// should not be relied upon for an accurate value otherwise.
func (v *validate) Parent() reflect.Value {
return v.slflParent
}
diff --git a/vendor/github.com/go-playground/validator/v10/translations/en/en.go b/vendor/github.com/go-playground/validator/v10/translations/en/en.go
index 1fdea951e0b..4c34dedbf5e 100644
--- a/vendor/github.com/go-playground/validator/v10/translations/en/en.go
+++ b/vendor/github.com/go-playground/validator/v10/translations/en/en.go
@@ -10,13 +10,13 @@ import (
"github.com/go-playground/locales"
ut "github.com/go-playground/universal-translator"
+
"github.com/go-playground/validator/v10"
)
// RegisterDefaultTranslations registers a set of default translations
// for all built in tag's in validator; you may add your own as desired.
func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (err error) {
-
translations := []struct {
tag string
translation string
@@ -29,10 +29,14 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} is a required field",
override: false,
},
+ {
+ tag: "required_if",
+ translation: "{0} is a required field",
+ override: false,
+ },
{
tag: "len",
customRegisFunc: func(ut ut.Translator) (err error) {
-
if err = ut.Add("len-string", "{0} must be {1} in length", false); err != nil {
return
}
@@ -61,10 +65,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
}
return
-
},
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
var err error
var t string
@@ -123,7 +125,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{
tag: "min",
customRegisFunc: func(ut ut.Translator) (err error) {
-
if err = ut.Add("min-string", "{0} must be at least {1} in length", false); err != nil {
return
}
@@ -152,10 +153,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
}
return
-
},
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
var err error
var t string
@@ -214,7 +213,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{
tag: "max",
customRegisFunc: func(ut ut.Translator) (err error) {
-
if err = ut.Add("max-string", "{0} must be a maximum of {1} in length", false); err != nil {
return
}
@@ -243,10 +241,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
}
return
-
},
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
var err error
var t string
@@ -307,7 +303,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} is not equal to {1}",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
fmt.Printf("warning: error translating FieldError: %#v", fe)
@@ -322,7 +317,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} should not be equal to {1}",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
fmt.Printf("warning: error translating FieldError: %#v", fe)
@@ -335,7 +329,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{
tag: "lt",
customRegisFunc: func(ut ut.Translator) (err error) {
-
if err = ut.Add("lt-string", "{0} must be less than {1} in length", false); err != nil {
return
}
@@ -369,10 +362,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
}
return
-
},
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
var err error
var t string
var f64 float64
@@ -380,7 +371,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var kind reflect.Kind
fn := func() (err error) {
-
if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:]))
}
@@ -456,7 +446,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{
tag: "lte",
customRegisFunc: func(ut ut.Translator) (err error) {
-
if err = ut.Add("lte-string", "{0} must be at maximum {1} in length", false); err != nil {
return
}
@@ -492,7 +481,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return
},
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
var err error
var t string
var f64 float64
@@ -500,7 +488,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var kind reflect.Kind
fn := func() (err error) {
-
if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:]))
}
@@ -576,7 +563,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{
tag: "gt",
customRegisFunc: func(ut ut.Translator) (err error) {
-
if err = ut.Add("gt-string", "{0} must be greater than {1} in length", false); err != nil {
return
}
@@ -612,7 +598,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return
},
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
var err error
var t string
var f64 float64
@@ -620,7 +605,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var kind reflect.Kind
fn := func() (err error) {
-
if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:]))
}
@@ -696,7 +680,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{
tag: "gte",
customRegisFunc: func(ut ut.Translator) (err error) {
-
if err = ut.Add("gte-string", "{0} must be at least {1} in length", false); err != nil {
return
}
@@ -732,7 +715,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return
},
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
var err error
var t string
var f64 float64
@@ -740,7 +722,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var kind reflect.Kind
fn := func() (err error) {
-
if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:]))
}
@@ -818,7 +799,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be equal to {1}",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
@@ -833,7 +813,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be equal to {1}",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
@@ -848,7 +827,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} cannot be equal to {1}",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
@@ -863,7 +841,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be greater than {1}",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
@@ -878,7 +855,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be greater than or equal to {1}",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
@@ -893,7 +869,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be less than {1}",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
@@ -908,7 +883,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be less than or equal to {1}",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
@@ -923,7 +897,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} cannot be equal to {1}",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
@@ -938,7 +911,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be greater than {1}",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
@@ -953,7 +925,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be greater than or equal to {1}",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
@@ -968,7 +939,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be less than {1}",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
@@ -983,7 +953,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be less than or equal to {1}",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
@@ -1073,7 +1042,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must contain the text '{1}'",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
@@ -1088,7 +1056,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must contain at least one of the following characters '{1}'",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
@@ -1103,7 +1070,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} cannot contain the text '{1}'",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
@@ -1118,7 +1084,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} cannot contain any of the following characters '{1}'",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
@@ -1133,7 +1098,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} cannot contain the following '{1}'",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
-
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
@@ -1158,6 +1122,11 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be a valid ISBN-13 number",
override: false,
},
+ {
+ tag: "issn",
+ translation: "{0} must be a valid ISSN number",
+ override: false,
+ },
{
tag: "uuid",
translation: "{0} must be a valid UUID",
@@ -1178,6 +1147,11 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be a valid version 5 UUID",
override: false,
},
+ {
+ tag: "ulid",
+ translation: "{0} must be a valid ULID",
+ override: false,
+ },
{
tag: "ascii",
translation: "{0} must contain only ascii characters",
@@ -1298,6 +1272,11 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must contain a valid MAC address",
override: false,
},
+ {
+ tag: "fqdn",
+ translation: "{0} must be a valid FQDN",
+ override: false,
+ },
{
tag: "unique",
translation: "{0} must contain unique values",
@@ -1308,6 +1287,11 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be a valid color",
override: false,
},
+ {
+ tag: "cron",
+ translation: "{0} must be a valid cron expression",
+ override: false,
+ },
{
tag: "oneof",
translation: "{0} must be one of [{1}]",
@@ -1325,8 +1309,13 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
tag: "json",
translation: "{0} must be a valid json string",
override: false,
- },
- {
+ },
+ {
+ tag: "jwt",
+ translation: "{0} must be a valid jwt string",
+ override: false,
+ },
+ {
tag: "lowercase",
translation: "{0} must be a lowercase string",
override: false,
@@ -1341,7 +1330,20 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} does not match the {1} format",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
+ t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
+ if err != nil {
+ log.Printf("warning: error translating FieldError: %#v", fe)
+ return fe.(error).Error()
+ }
+ return t
+ },
+ },
+ {
+ tag: "postcode_iso3166_alpha2",
+ translation: "{0} does not match postcode format of {1} country",
+ override: false,
+ customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
@@ -1351,22 +1353,45 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return t
},
},
+ {
+ tag: "postcode_iso3166_alpha2_field",
+ translation: "{0} does not match postcode format of country in {1} field",
+ override: false,
+ customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
+ t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
+ if err != nil {
+ log.Printf("warning: error translating FieldError: %#v", fe)
+ return fe.(error).Error()
+ }
+
+ return t
+ },
+ },
+ {
+ tag: "boolean",
+ translation: "{0} must be a valid boolean value",
+ override: false,
+ },
+ {
+ tag: "image",
+ translation: "{0} must be a valid image",
+ override: false,
+ },
+ {
+ tag: "cve",
+ translation: "{0} must be a valid cve identifier",
+ override: false,
+ },
}
for _, t := range translations {
if t.customTransFunc != nil && t.customRegisFunc != nil {
-
err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, t.customTransFunc)
-
} else if t.customTransFunc != nil && t.customRegisFunc == nil {
-
err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), t.customTransFunc)
-
} else if t.customTransFunc == nil && t.customRegisFunc != nil {
-
err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, translateFunc)
-
} else {
err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), translateFunc)
}
@@ -1380,21 +1405,16 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
}
func registrationFunc(tag string, translation string, override bool) validator.RegisterTranslationsFunc {
-
return func(ut ut.Translator) (err error) {
-
if err = ut.Add(tag, translation, override); err != nil {
return
}
return
-
}
-
}
func translateFunc(ut ut.Translator, fe validator.FieldError) string {
-
t, err := ut.T(fe.Tag(), fe.Field())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
diff --git a/vendor/github.com/go-playground/validator/v10/util.go b/vendor/github.com/go-playground/validator/v10/util.go
index 56420f4301f..16851593da5 100644
--- a/vendor/github.com/go-playground/validator/v10/util.go
+++ b/vendor/github.com/go-playground/validator/v10/util.go
@@ -1,7 +1,9 @@
package validator
import (
+ "fmt"
"reflect"
+ "regexp"
"strconv"
"strings"
"time"
@@ -82,7 +84,7 @@ BEGIN:
fld := namespace
var ns string
- if typ != timeType {
+ if !typ.ConvertibleTo(timeType) {
idx := strings.Index(namespace, namespaceSeparator)
@@ -234,7 +236,7 @@ func asInt(param string) int64 {
func asIntFromTimeDuration(param string) int64 {
d, err := time.ParseDuration(param)
if err != nil {
- // attempt parsing as an an integer assuming nanosecond precision
+ // attempt parsing as an integer assuming nanosecond precision
return asInt(param)
}
return int64(d)
@@ -261,13 +263,19 @@ func asUint(param string) uint64 {
return i
}
-// asFloat returns the parameter as a float64
+// asFloat64 returns the parameter as a float64
// or panics if it can't convert
-func asFloat(param string) float64 {
-
+func asFloat64(param string) float64 {
i, err := strconv.ParseFloat(param, 64)
panicIf(err)
+ return i
+}
+// asFloat64 returns the parameter as a float64
+// or panics if it can't convert
+func asFloat32(param string) float64 {
+ i, err := strconv.ParseFloat(param, 32)
+ panicIf(err)
return i
}
@@ -286,3 +294,18 @@ func panicIf(err error) {
panic(err.Error())
}
}
+
+// Checks if field value matches regex. If fl.Field can be cast to Stringer, it uses the Stringer interfaces
+// String() return value. Otherwise, it uses fl.Field's String() value.
+func fieldMatchesRegexByStringerValOrString(regex *regexp.Regexp, fl FieldLevel) bool {
+ switch fl.Field().Kind() {
+ case reflect.String:
+ return regex.MatchString(fl.Field().String())
+ default:
+ if stringer, ok := fl.Field().Interface().(fmt.Stringer); ok {
+ return regex.MatchString(stringer.String())
+ } else {
+ return regex.MatchString(fl.Field().String())
+ }
+ }
+}
diff --git a/vendor/github.com/go-playground/validator/v10/validator.go b/vendor/github.com/go-playground/validator/v10/validator.go
index f097f394296..a072d39ce6a 100644
--- a/vendor/github.com/go-playground/validator/v10/validator.go
+++ b/vendor/github.com/go-playground/validator/v10/validator.go
@@ -74,7 +74,7 @@ func (v *validate) validateStruct(ctx context.Context, parent reflect.Value, cur
}
}
- v.traverseField(ctx, parent, current.Field(f.idx), ns, structNs, f, f.cTags)
+ v.traverseField(ctx, current, current.Field(f.idx), ns, structNs, f, f.cTags)
}
}
@@ -99,6 +99,8 @@ func (v *validate) traverseField(ctx context.Context, parent reflect.Value, curr
current, kind, v.fldIsPointer = v.extractTypeInternal(current, false)
+ var isNestedStruct bool
+
switch kind {
case reflect.Ptr, reflect.Interface, reflect.Invalid:
@@ -110,6 +112,10 @@ func (v *validate) traverseField(ctx context.Context, parent reflect.Value, curr
return
}
+ if ct.typeof == typeOmitNil && (kind != reflect.Invalid && current.IsNil()) {
+ return
+ }
+
if ct.hasTag {
if kind == reflect.Invalid {
v.str1 = string(append(ns, cf.altName...))
@@ -160,86 +166,61 @@ func (v *validate) traverseField(ctx context.Context, parent reflect.Value, curr
}
}
- case reflect.Struct:
-
- typ = current.Type()
-
- if typ != timeType {
-
- if ct != nil {
-
- if ct.typeof == typeStructOnly {
- goto CONTINUE
- } else if ct.typeof == typeIsDefault {
- // set Field Level fields
- v.slflParent = parent
- v.flField = current
- v.cf = cf
- v.ct = ct
-
- if !ct.fn(ctx, v) {
- v.str1 = string(append(ns, cf.altName...))
-
- if v.v.hasTagNameFunc {
- v.str2 = string(append(structNs, cf.name...))
- } else {
- v.str2 = v.str1
- }
-
- v.errs = append(v.errs,
- &fieldError{
- v: v.v,
- tag: ct.aliasTag,
- actualTag: ct.tag,
- ns: v.str1,
- structNs: v.str2,
- fieldLen: uint8(len(cf.altName)),
- structfieldLen: uint8(len(cf.name)),
- value: current.Interface(),
- param: ct.param,
- kind: kind,
- typ: typ,
- },
- )
- return
- }
- }
-
- ct = ct.next
- }
-
- if ct != nil && ct.typeof == typeNoStructLevel {
- return
- }
-
- CONTINUE:
- // if len == 0 then validating using 'Var' or 'VarWithValue'
- // Var - doesn't make much sense to do it that way, should call 'Struct', but no harm...
- // VarWithField - this allows for validating against each field within the struct against a specific value
- // pretty handy in certain situations
- if len(cf.name) > 0 {
- ns = append(append(ns, cf.altName...), '.')
- structNs = append(append(structNs, cf.name...), '.')
- }
-
- v.validateStruct(ctx, current, current, typ, ns, structNs, ct)
+ if kind == reflect.Invalid {
return
}
- }
- if !ct.hasTag {
- return
+ case reflect.Struct:
+ isNestedStruct = !current.Type().ConvertibleTo(timeType)
+ // For backward compatibility before struct level validation tags were supported
+ // as there were a number of projects relying on `required` not failing on non-pointer
+ // structs. Since it's basically nonsensical to use `required` with a non-pointer struct
+ // are explicitly skipping the required validation for it. This WILL be removed in the
+ // next major version.
+ if isNestedStruct && !v.v.requiredStructEnabled && ct != nil && ct.tag == requiredTag {
+ ct = ct.next
+ }
}
typ = current.Type()
OUTER:
for {
- if ct == nil {
+ if ct == nil || !ct.hasTag || (isNestedStruct && len(cf.name) == 0) {
+ // isNestedStruct check here
+ if isNestedStruct {
+ // if len == 0 then validating using 'Var' or 'VarWithValue'
+ // Var - doesn't make much sense to do it that way, should call 'Struct', but no harm...
+ // VarWithField - this allows for validating against each field within the struct against a specific value
+ // pretty handy in certain situations
+ if len(cf.name) > 0 {
+ ns = append(append(ns, cf.altName...), '.')
+ structNs = append(append(structNs, cf.name...), '.')
+ }
+
+ v.validateStruct(ctx, parent, current, typ, ns, structNs, ct)
+ }
return
}
switch ct.typeof {
+ case typeNoStructLevel:
+ return
+
+ case typeStructOnly:
+ if isNestedStruct {
+ // if len == 0 then validating using 'Var' or 'VarWithValue'
+ // Var - doesn't make much sense to do it that way, should call 'Struct', but no harm...
+ // VarWithField - this allows for validating against each field within the struct against a specific value
+ // pretty handy in certain situations
+ if len(cf.name) > 0 {
+ ns = append(append(ns, cf.altName...), '.')
+ structNs = append(append(structNs, cf.name...), '.')
+ }
+
+ v.validateStruct(ctx, parent, current, typ, ns, structNs, ct)
+ }
+ return
case typeOmitEmpty:
@@ -256,6 +237,26 @@ OUTER:
ct = ct.next
continue
+ case typeOmitNil:
+ v.slflParent = parent
+ v.flField = current
+ v.cf = cf
+ v.ct = ct
+
+ switch field := v.Field(); field.Kind() {
+ case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
+ if field.IsNil() {
+ return
+ }
+ default:
+ if v.fldIsPointer && field.Interface() == nil {
+ return
+ }
+ }
+
+ ct = ct.next
+ continue
+
case typeEndKeys:
return
@@ -355,6 +356,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 {
@@ -362,12 +367,17 @@ OUTER:
ct = ct.next
if ct == nil {
- return
+ continue OUTER
}
if ct.typeof != typeOr {
continue OUTER
}
+
+ if ct.isBlockEnd {
+ ct = ct.next
+ continue OUTER
+ }
}
}
@@ -443,7 +453,6 @@ OUTER:
v.ct = ct
if !ct.fn(ctx, v) {
-
v.str1 = string(append(ns, cf.altName...))
if v.v.hasTagNameFunc {
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 fe6a48775f8..d5a7be1ded3 100644
--- a/vendor/github.com/go-playground/validator/v10/validator_instance.go
+++ b/vendor/github.com/go-playground/validator/v10/validator_instance.go
@@ -22,6 +22,7 @@ const (
structOnlyTag = "structonly"
noStructLevelTag = "nostructlevel"
omitempty = "omitempty"
+ omitnil = "omitnil"
isdefault = "isdefault"
requiredWithoutAllTag = "required_without_all"
requiredWithoutTag = "required_without"
@@ -29,6 +30,13 @@ const (
requiredWithAllTag = "required_with_all"
requiredIfTag = "required_if"
requiredUnlessTag = "required_unless"
+ skipUnlessTag = "skip_unless"
+ excludedWithoutAllTag = "excluded_without_all"
+ excludedWithoutTag = "excluded_without"
+ excludedWithTag = "excluded_with"
+ excludedWithAllTag = "excluded_with_all"
+ excludedIfTag = "excluded_if"
+ excludedUnlessTag = "excluded_unless"
skipValidationTag = "-"
diveTag = "dive"
keysTag = "keys"
@@ -46,12 +54,14 @@ var (
timeDurationType = reflect.TypeOf(time.Duration(0))
timeType = reflect.TypeOf(time.Time{})
+ byteSliceType = reflect.TypeOf([]byte{})
+
defaultCField = &cField{namesEqual: true}
)
// FilterFunc is the type used to filter fields using
// StructFiltered(...) function.
-// returning true results in the field being filtered/skiped from
+// returning true results in the field being filtered/skipped from
// validation
type FilterFunc func(ns []byte) bool
@@ -70,22 +80,28 @@ type internalValidationFuncWrapper struct {
// Validate contains the validator settings and cache
type Validate struct {
- tagName string
- pool *sync.Pool
- hasCustomFuncs bool
- hasTagNameFunc bool
- tagNameFunc TagNameFunc
- structLevelFuncs map[reflect.Type]StructLevelFuncCtx
- customFuncs map[reflect.Type]CustomTypeFunc
- aliases map[string]string
- validations map[string]internalValidationFuncWrapper
- transTagFunc map[ut.Translator]map[string]TranslationFunc // map[]map[]TranslationFunc
- tagCache *tagCache
- structCache *structCache
+ tagName string
+ pool *sync.Pool
+ tagNameFunc TagNameFunc
+ structLevelFuncs map[reflect.Type]StructLevelFuncCtx
+ customFuncs map[reflect.Type]CustomTypeFunc
+ aliases map[string]string
+ validations map[string]internalValidationFuncWrapper
+ transTagFunc map[ut.Translator]map[string]TranslationFunc // map[]map[]TranslationFunc
+ rules map[reflect.Type]map[string]string
+ tagCache *tagCache
+ structCache *structCache
+ hasCustomFuncs bool
+ hasTagNameFunc bool
+ requiredStructEnabled bool
}
// New returns a new instance of 'validate' with sane defaults.
-func New() *Validate {
+// Validate is designed to be thread-safe and used as a singleton instance.
+// It caches information about your struct and validations,
+// in essence only parsing your validation tags once per struct type.
+// Using multiple instances neglects the benefit of caching.
+func New(options ...Option) *Validate {
tc := new(tagCache)
tc.m.Store(make(map[string]*cTag))
@@ -111,7 +127,9 @@ 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:
+ case requiredIfTag, requiredUnlessTag, requiredWithTag, requiredWithAllTag, requiredWithoutTag, requiredWithoutAllTag,
+ excludedIfTag, excludedUnlessTag, excludedWithTag, excludedWithAllTag, excludedWithoutTag, excludedWithoutAllTag,
+ skipUnlessTag:
_ = v.registerValidation(k, wrapFunc(val), true, true)
default:
// no need to error check here, baked in will always be valid
@@ -130,6 +148,9 @@ func New() *Validate {
},
}
+ for _, o := range options {
+ o(v)
+ }
return v
}
@@ -138,17 +159,54 @@ func (v *Validate) SetTagName(name string) {
v.tagName = name
}
+// ValidateMapCtx validates a map using a map of validation rules and allows passing of contextual
+// validation information via context.Context.
+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 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 ruleStr, ok := rule.(string); ok {
+ err := v.VarCtx(ctx, data[field], ruleStr)
+ if err != nil {
+ errs[field] = err
+ }
+ }
+ }
+ return errs
+}
+
+// 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)
+}
+
// RegisterTagNameFunc registers a function to get alternate names for StructFields.
//
// eg. to use the names which have been specified for JSON representations of structs, rather than normal Go field names:
//
-// validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
-// name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
-// if name == "-" {
-// return ""
-// }
-// return name
-// })
+// 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 ""
+// }
+// return name
+// })
func (v *Validate) RegisterTagNameFunc(fn TagNameFunc) {
v.tagNameFunc = fn
v.hasTagNameFunc = true
@@ -175,11 +233,11 @@ func (v *Validate) RegisterValidationCtx(tag string, fn FuncCtx, callValidationE
func (v *Validate) registerValidation(tag string, fn FuncCtx, bakedIn bool, nilCheckable bool) error {
if len(tag) == 0 {
- return errors.New("Function Key cannot be empty")
+ return errors.New("function Key cannot be empty")
}
if fn == nil {
- return errors.New("Function cannot be empty")
+ return errors.New("function cannot be empty")
}
_, ok := restrictedTags[tag]
@@ -235,6 +293,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
@@ -295,7 +381,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)}
}
@@ -340,7 +426,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)}
}
@@ -374,7 +460,7 @@ func (v *Validate) StructPartial(s interface{}, fields ...string) error {
}
// StructPartialCtx validates the fields passed in only, ignoring all others and allows passing of contextual
-// validation validation information via context.Context
+// validation information via context.Context
// Fields may be provided in a namespaced fashion relative to the struct provided
// eg. NestedStruct.Field or NestedArrayField[0].Struct.Name
//
@@ -388,7 +474,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)}
}
@@ -409,7 +495,10 @@ func (v *Validate) StructPartialCtx(ctx context.Context, s interface{}, fields .
if len(flds) > 0 {
vd.misc = append(vd.misc[0:0], name...)
- vd.misc = append(vd.misc, '.')
+ // Don't append empty name for unnamed structs
+ if len(vd.misc) != 0 {
+ vd.misc = append(vd.misc, '.')
+ }
for _, s := range flds {
@@ -461,7 +550,7 @@ func (v *Validate) StructExcept(s interface{}, fields ...string) error {
}
// StructExceptCtx validates all fields except the ones passed in and allows passing of contextual
-// validation validation information via context.Context
+// validation information via context.Context
// Fields may be provided in a namespaced fashion relative to the struct provided
// i.e. NestedStruct.Field or NestedArrayField[0].Struct.Name
//
@@ -475,7 +564,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)}
}
@@ -533,7 +622,7 @@ func (v *Validate) Var(field interface{}, tag string) error {
}
// VarCtx validates a single variable using tag style validation and allows passing of contextual
-// validation validation information via context.Context.
+// validation information via context.Context.
// eg.
// var i int
// validate.Var(i, "gt=1,lt=10")
@@ -552,6 +641,7 @@ func (v *Validate) VarCtx(ctx context.Context, field interface{}, tag string) (e
}
ctag := v.fetchCacheTag(tag)
+
val := reflect.ValueOf(field)
vd := v.pool.Get().(*validate)
vd.top = val
diff --git a/vendor/github.com/leodido/go-urn/.gitignore b/vendor/github.com/leodido/go-urn/.gitignore
index 5bcf4bade0b..89d4bc55dce 100644
--- a/vendor/github.com/leodido/go-urn/.gitignore
+++ b/vendor/github.com/leodido/go-urn/.gitignore
@@ -8,4 +8,5 @@
*.out
*.txt
-vendor/
\ No newline at end of file
+vendor/
+/removecomments
\ No newline at end of file
diff --git a/vendor/github.com/leodido/go-urn/.travis.yml b/vendor/github.com/leodido/go-urn/.travis.yml
deleted file mode 100644
index e56cf7cc066..00000000000
--- a/vendor/github.com/leodido/go-urn/.travis.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-language: go
-
-go:
- - 1.9.x
- - 1.10.x
- - 1.11.x
- - 1.12.x
- - 1.13.x
- - tip
-
-before_install:
- - go get -t -v ./...
-
-script:
- - go test -race -coverprofile=coverage.txt -covermode=atomic
-
-after_success:
- - bash <(curl -s https://codecov.io/bash)
\ No newline at end of file
diff --git a/vendor/github.com/leodido/go-urn/README.md b/vendor/github.com/leodido/go-urn/README.md
index cc902ec0e37..731eecbb5ff 100644
--- a/vendor/github.com/leodido/go-urn/README.md
+++ b/vendor/github.com/leodido/go-urn/README.md
@@ -1,4 +1,4 @@
-[![Build](https://img.shields.io/travis/leodido/go-urn/master.svg?style=for-the-badge)](https://travis-ci.org/leodido/go-urn) [![Coverage](https://img.shields.io/codecov/c/github/leodido/go-urn.svg?style=for-the-badge)](https://codecov.io/gh/leodido/go-urn) [![Documentation](https://img.shields.io/badge/godoc-reference-blue.svg?style=for-the-badge)](https://godoc.org/github.com/leodido/go-urn)
+[![Build](https://img.shields.io/circleci/build/github/leodido/go-urn?style=for-the-badge)](https://app.circleci.com/pipelines/github/leodido/go-urn) [![Coverage](https://img.shields.io/codecov/c/github/leodido/go-urn.svg?style=for-the-badge)](https://codecov.io/gh/leodido/go-urn) [![Documentation](https://img.shields.io/badge/godoc-reference-blue.svg?style=for-the-badge)](https://godoc.org/github.com/leodido/go-urn)
**A parser for URNs**.
@@ -52,4 +52,30 @@ no/19/urn:UrN:NSS__________________________________/-4 20000000 399 ns
---
+## Example
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/leodido/go-urn"
+)
+
+func main() {
+ var uid = "URN:foo:a123,456"
+
+ u, ok := urn.Parse([]byte(uid))
+ if !ok {
+ panic("error parsing urn")
+ }
+
+ fmt.Println(u.ID)
+ fmt.Println(u.SS)
+
+ // Output:
+ // foo
+ // a123,456
+}
+```
+
[![Analytics](https://ga-beacon.appspot.com/UA-49657176-1/go-urn?flat)](https://github.com/igrigorik/ga-beacon)
\ No newline at end of file
diff --git a/vendor/github.com/leodido/go-urn/machine.go b/vendor/github.com/leodido/go-urn/machine.go
index fe5a0cc8611..f8d57b412d6 100644
--- a/vendor/github.com/leodido/go-urn/machine.go
+++ b/vendor/github.com/leodido/go-urn/machine.go
@@ -61,11 +61,9 @@ func (m *machine) Parse(input []byte) (*URN, error) {
m.err = nil
m.tolower = []int{}
output := &URN{}
-
{
m.cs = start
}
-
{
if (m.p) == (m.pe) {
goto _testEof
@@ -1674,7 +1672,6 @@ func (m *machine) Parse(input []byte) (*URN, error) {
{
goto st46
}
-
}
}
diff --git a/vendor/github.com/leodido/go-urn/makefile b/vendor/github.com/leodido/go-urn/makefile
index 47026d50999..df87cdc6d27 100644
--- a/vendor/github.com/leodido/go-urn/makefile
+++ b/vendor/github.com/leodido/go-urn/makefile
@@ -1,18 +1,37 @@
SHELL := /bin/bash
+RAGEL := ragel
+GOFMT := go fmt
+export GO_TEST=env GOTRACEBACK=all go test $(GO_ARGS)
+
+.PHONY: build
build: machine.go
+.PHONY: clean
+clean:
+ @rm -rf docs
+ @rm -f machine.go
+
+.PHONY: images
images: docs/urn.png
+.PHONY: removecomments
+removecomments:
+ @cd ./tools/removecomments; go build -o ../../removecomments .
+
machine.go: machine.go.rl
- ragel -Z -G2 -e -o $@ $<
- @sed -i '/^\/\/line/d' $@
- @$(MAKE) -s file=$@ snake2camel
- @gofmt -w -s $@
+
+machine.go: removecomments
+
+machine.go:
+ $(RAGEL) -Z -G2 -e -o $@ $<
+ @./removecomments $@
+ $(MAKE) -s file=$@ snake2camel
+ $(GOFMT) $@
docs/urn.dot: machine.go.rl
@mkdir -p docs
- ragel -Z -e -Vp $< -o $@
+ $(RAGEL) -Z -e -Vp $< -o $@
docs/urn.png: docs/urn.dot
dot $< -Tpng -o $@
@@ -22,13 +41,8 @@ bench: *_test.go machine.go
go test -bench=. -benchmem -benchtime=5s ./...
.PHONY: tests
-tests: *_test.go machine.go
- go test -race -timeout 10s -coverprofile=coverage.out -covermode=atomic -v ./...
-
-.PHONY: clean
-clean:
- @rm -rf docs
- @rm -f machine.go
+tests: *_test.go
+ $(GO_TEST) ./...
.PHONY: snake2camel
snake2camel:
@@ -36,4 +50,4 @@ snake2camel:
while ( match($$0, /(.*)([a-z]+[0-9]*)_([a-zA-Z0-9])(.*)/, cap) ) \
$$0 = cap[1] cap[2] toupper(cap[3]) cap[4]; \
print \
- }' $(file)
\ No newline at end of file
+ }' $(file)
diff --git a/vendor/github.com/leodido/go-urn/urn.go b/vendor/github.com/leodido/go-urn/urn.go
index b903b7b3cd5..d51a6c915be 100644
--- a/vendor/github.com/leodido/go-urn/urn.go
+++ b/vendor/github.com/leodido/go-urn/urn.go
@@ -1,9 +1,13 @@
package urn
import (
+ "encoding/json"
+ "fmt"
"strings"
)
+const errInvalidURN = "invalid URN: %s"
+
// URN represents an Uniform Resource Name.
//
// The general form represented is:
@@ -61,3 +65,22 @@ func Parse(u []byte) (*URN, bool) {
return urn, true
}
+
+// MarshalJSON marshals the URN to JSON string form (e.g. `"urn:oid:1.2.3.4"`).
+func (u URN) MarshalJSON() ([]byte, error) {
+ return json.Marshal(u.String())
+}
+
+// MarshalJSON unmarshals a URN from JSON string form (e.g. `"urn:oid:1.2.3.4"`).
+func (u *URN) UnmarshalJSON(bytes []byte) error {
+ var str string
+ if err := json.Unmarshal(bytes, &str); err != nil {
+ return err
+ }
+ if value, ok := Parse([]byte(str)); !ok {
+ return fmt.Errorf(errInvalidURN, str)
+ } else {
+ *u = *value
+ }
+ return nil
+}
\ No newline at end of file
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 139e221f408..960d838386f 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -951,16 +951,16 @@ github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry
## explicit; go 1.13
github.com/go-ozzo/ozzo-validation/v4
github.com/go-ozzo/ozzo-validation/v4/is
-# github.com/go-playground/locales v0.13.0
-## explicit; go 1.13
+# github.com/go-playground/locales v0.14.1
+## explicit; go 1.17
github.com/go-playground/locales
github.com/go-playground/locales/currency
github.com/go-playground/locales/en
-# github.com/go-playground/universal-translator v0.17.0
-## explicit; go 1.13
+# github.com/go-playground/universal-translator v0.18.1
+## explicit; go 1.18
github.com/go-playground/universal-translator
-# github.com/go-playground/validator/v10 v10.4.1
-## explicit; go 1.13
+# github.com/go-playground/validator/v10 v10.16.0
+## explicit; go 1.18
github.com/go-playground/validator/v10
github.com/go-playground/validator/v10/translations/en
# github.com/go-redis/redis/v8 v8.11.5
@@ -1224,8 +1224,8 @@ github.com/klauspost/compress/s2
# github.com/klauspost/cpuid/v2 v2.1.0
## explicit; go 1.15
github.com/klauspost/cpuid/v2
-# github.com/leodido/go-urn v1.2.0
-## explicit; go 1.13
+# github.com/leodido/go-urn v1.2.4
+## explicit; go 1.16
github.com/leodido/go-urn
# github.com/leonelquinteros/gotext v1.5.3-0.20230317130943-71a59c05b2c1
## explicit; go 1.13