diff --git a/app/http/controllers/validation_controller.go b/app/http/controllers/validation_controller.go index dae98ab..919d0a2 100644 --- a/app/http/controllers/validation_controller.go +++ b/app/http/controllers/validation_controller.go @@ -35,9 +35,12 @@ air ********************************/ type User struct { - Context string `json:"context" form:"context"` - Name string `json:"name" form:"name"` - Date *carbon.DateTime `json:"date" form:"date"` + Context string `json:"context" form:"context"` + Name string `json:"name" form:"name"` + Date *carbon.DateTime `json:"date" form:"date"` + Age int `json:"age" form:"age"` + Items []requests.ValidationItem `json:"items" form:"items"` + Meta map[string]any `json:"meta" form:"meta"` } type ValidationController struct { @@ -52,10 +55,13 @@ func NewValidationController() *ValidationController { func (r *ValidationController) Json(ctx http.Context) http.Response { ctx.WithValue("ctx", "context") - validator, err := ctx.Request().Validate(map[string]string{ - "context": "required", - "name": "required", - "date": "required|date", + validator, err := ctx.Request().Validate(map[string]any{ + "context": "required", + "name": "required", + "date": "required|date", + "items.*.name": "sometimes|required|string", + "meta": "sometimes|map", + "meta.name": "sometimes|required|string", }, validation.PrepareForValidation(func(ctx context.Context, data contractsvalidation.Data) error { if c, exist := data.Get("context"); exist { // Test getting value from context: ValidationController.Request @@ -84,11 +90,16 @@ func (r *ValidationController) Json(ctx http.Context) http.Response { }) } - return ctx.Response().Success().Json(http.Json{ + response := http.Json{ "context": user.Context, "name": user.Name, "date": user.Date.ToDateTimeString(), - }) + "age": user.Age, + "items": user.Items, + "meta": user.Meta, + } + + return ctx.Response().Success().Json(response) } func (r *ValidationController) Request(ctx http.Context) http.Response { @@ -108,14 +119,19 @@ func (r *ValidationController) Request(ctx http.Context) http.Response { }) } - return ctx.Response().Success().Json(http.Json{ + response := http.Json{ "context": validationCreate.Context, "name": validationCreate.Name, "tags": validationCreate.Tags, "scores": validationCreate.Scores, + "items": validationCreate.Items, + "meta": validationCreate.Meta, "date": validationCreate.Date.ToDateTimeString(), "code": validationCreate.Code, - }) + "age": validationCreate.Age, + } + + return ctx.Response().Success().Json(response) } func (r *ValidationController) Form(ctx http.Context) http.Response { @@ -123,7 +139,8 @@ func (r *ValidationController) Form(ctx http.Context) http.Response { validator, err := facades.Validation().Make(ctx, map[string]any{ "context": ctx.Request().Input("context"), "name": ctx.Request().Input("name"), - }, map[string]string{ + "age": ctx.Request().Input("age"), + }, map[string]any{ "context": "required", "name": "required", }, validation.PrepareForValidation(func(ctx context.Context, data contractsvalidation.Data) error { @@ -157,6 +174,7 @@ func (r *ValidationController) Form(ctx http.Context) http.Response { return ctx.Response().Success().Json(http.Json{ "context": user.Context, "name": user.Name, + "age": user.Age, }) } @@ -176,7 +194,7 @@ func (r *ValidationController) Upload(ctx http.Context) http.Response { })) } - validator, err := ctx.Request().Validate(map[string]string{ + validator, err := ctx.Request().Validate(map[string]any{ "f": rule, }, options...) if err != nil { diff --git a/app/http/controllers/validation_controller_test.go b/app/http/controllers/validation_controller_test.go index 8b97d8e..7eaa83c 100644 --- a/app/http/controllers/validation_controller_test.go +++ b/app/http/controllers/validation_controller_test.go @@ -9,6 +9,8 @@ import ( "github.com/goravel/gin" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/suite" + + "goravel/app/http/requests" ) type ValidationControllerTestSuite struct { @@ -35,10 +37,13 @@ func (s *ValidationControllerTestSuite) TestJson() { mockValidator := mockFactory.ValidationValidator() mockContext.EXPECT().WithValue("ctx", "context").Once() mockContext.EXPECT().Request().Return(mockRequest).Once() - mockRequest.EXPECT().Validate(map[string]string{ - "context": "required", - "name": "required", - "date": "required|date", + mockRequest.EXPECT().Validate(map[string]any{ + "context": "required", + "name": "required", + "date": "required|date", + "items.*.name": "sometimes|required|string", + "meta": "sometimes|map", + "meta.name": "sometimes|required|string", }, mock.AnythingOfType("validation.Option")).Return(mockValidator, nil).Once() mockValidator.EXPECT().Fails().Return(false).Once() var user User @@ -46,6 +51,9 @@ func (s *ValidationControllerTestSuite) TestJson() { user.(*User).Context = "ctx_context" user.(*User).Name = "Goravel" user.(*User).Date = carbon.NewDateTime(carbon.Parse("2024-07-08 22:34:31")) + user.(*User).Age = 1 + user.(*User).Items = []requests.ValidationItem{{Name: "item1"}} + user.(*User).Meta = map[string]any{"source": "api"} }).Return(nil).Once() mockContext.EXPECT().Response().Return(mockResponse).Once() mockResponseStatus := mockFactory.ResponseStatus() @@ -56,6 +64,9 @@ func (s *ValidationControllerTestSuite) TestJson() { "context": "ctx_context", "name": "Goravel", "date": "2024-07-08 22:34:31", + "age": 1, + "items": []requests.ValidationItem{{Name: "item1"}}, + "meta": map[string]any{"source": "api"}, }).Return(resp).Once() s.Equal(resp, NewValidationController().Json(mockContext)) diff --git a/app/http/requests/user_create.go b/app/http/requests/user_create.go index 4e2a606..77a1685 100644 --- a/app/http/requests/user_create.go +++ b/app/http/requests/user_create.go @@ -18,8 +18,8 @@ func (r *UserCreate) Authorize(ctx http.Context) error { return nil } -func (r *UserCreate) Rules(ctx http.Context) map[string]string { - return map[string]string{ +func (r *UserCreate) Rules(ctx http.Context) map[string]any { + return map[string]any{ "name": "required", } } diff --git a/app/http/requests/validation_create.go b/app/http/requests/validation_create.go index 7f146f1..0588051 100644 --- a/app/http/requests/validation_create.go +++ b/app/http/requests/validation_create.go @@ -8,26 +8,36 @@ import ( ) type ValidationCreate struct { - Context string `form:"context" json:"context"` - Name string `form:"name" json:"name"` - Tags []string `form:"tags" json:"tags"` - Scores []int `form:"scores" json:"scores"` - Date carbon.Carbon `form:"date" json:"date"` - Code int `form:"code" json:"code"` + Context string `form:"context" json:"context"` + Name string `form:"name" json:"name"` + Tags []string `form:"tags" json:"tags"` + Scores []int `form:"scores" json:"scores"` + Items []ValidationItem `form:"items" json:"items"` + Meta map[string]any `form:"meta" json:"meta"` + Date carbon.Carbon `form:"date" json:"date"` + Code int `form:"code" json:"code"` + Age int `form:"age" json:"age"` +} + +type ValidationItem struct { + Name string `form:"name" json:"name"` } func (r *ValidationCreate) Authorize(ctx http.Context) error { return nil } -func (r *ValidationCreate) Rules(ctx http.Context) map[string]string { - return map[string]string{ - "name": "required", - "context": "required", - "tags.*": "required|string", - "scores.*": "required|int", - "date": "required|date", - "code": `required|regex:^\d{4,6}$`, +func (r *ValidationCreate) Rules(ctx http.Context) map[string]any { + return map[string]any{ + "name": "required", + "context": "required", + "tags.*": "required|string", + "scores.*": "required|int", + "items.*.name": "sometimes|required|string", + "meta": "sometimes|map", + "meta.name": "sometimes|required|string", + "date": "required|date", + "code": `required|regex:^\d{4,6}$`, } } @@ -55,8 +65,8 @@ func (r *ValidationCreate) PrepareForValidation(ctx http.Context, data validatio return nil } -func (r *ValidationCreate) Filters(ctx http.Context) map[string]string { - return map[string]string{ +func (r *ValidationCreate) Filters(ctx http.Context) map[string]any { + return map[string]any{ "name": "trim", } } diff --git a/app/rules/exists.go b/app/rules/exists.go index 2effb4a..d7f3476 100644 --- a/app/rules/exists.go +++ b/app/rules/exists.go @@ -9,12 +9,12 @@ import ( ) /** - * exists 验证一个值在某个表中的字段中存在,相较于Laravel,支持同时判断多个字段 - * exists verify a value exists in a table field, compared to Laravel, support judging multiple fields at the same time - * 用法:exists:表名称,字段名称,字段名称,字段名称 - * Usage: exists:table_name,field_name,field_name,field_name - * 例子:exists:users,phone,email - * Example: exists:users,phone,email + * custom_exists 验证一个值在某个表中的字段中存在,相较于Laravel,支持同时判断多个字段 + * custom_exists verify a value exists in a table field, compared to Laravel, support judging multiple fields at the same time + * custom_exists:表名称,字段名称,字段名称,字段名称 + * Usage: custom_exists:table_name,field_name,field_name,field_name + * custom_exists:users,phone,email + * Example: custom_exists:users,phone,email */ type Exists struct { @@ -22,7 +22,7 @@ type Exists struct { // Signature The name of the rule. func (receiver *Exists) Signature() string { - return "exists" + return "custom_exists" } // Passes Determine if the validation rule passes. diff --git a/app/rules/not_exists.go b/app/rules/not_exists.go deleted file mode 100644 index 59d0d36..0000000 --- a/app/rules/not_exists.go +++ /dev/null @@ -1,57 +0,0 @@ -package rules - -import ( - "context" - - "github.com/goravel/framework/contracts/validation" - - "goravel/app/facades" -) - -/** - * not_exists 验证一个值在某个表中的字段中不存在,相较于Laravel,支持同时判断多个字段 - * not_exists verify a value does not exist in a table field, compared to Laravel, support judging multiple fields at the same time - * 用法:not_exists:表名称,字段名称,字段名称,字段名称 - * Usage: not_exists:table_name,field_name,field_name,field_name - * 例子:not_exists:users,phone,email - * Example: not_exists:users,phone,email - */ - -type NotExists struct { -} - -// Signature The name of the rule. -func (receiver *NotExists) Signature() string { - return "not_exists" -} - -// Passes Determine if the validation rule passes. -func (receiver *NotExists) Passes(ctx context.Context, _ validation.Data, val any, options ...any) bool { - - tableName := options[0].(string) - fieldName := options[1].(string) - requestValue := val.(string) - - if len(requestValue) == 0 { - return false - } - - var count int64 - query := facades.Orm().Query().Table(tableName).Where(fieldName, requestValue) - if len(options) > 2 { - for i := 2; i < len(options); i++ { - query = query.OrWhere(options[i].(string), requestValue) - } - } - count, err := query.Count() - if err != nil { - return false - } - - return count == 0 -} - -// Message Get the validation error message. -func (receiver *NotExists) Message(ctx context.Context) string { - return "record already exists" -} diff --git a/bootstrap/rules.go b/bootstrap/rules.go index 3ef8f91..0f223ec 100644 --- a/bootstrap/rules.go +++ b/bootstrap/rules.go @@ -9,6 +9,5 @@ import ( func Rules() []validation.Rule { return []validation.Rule{ &rules.Exists{}, - &rules.NotExists{}, } } diff --git a/go.mod b/go.mod index cc30b8d..ed94133 100644 --- a/go.mod +++ b/go.mod @@ -4,14 +4,14 @@ go 1.25.0 require ( github.com/99designs/gqlgen v0.17.57 - github.com/gin-gonic/gin v1.11.0 + github.com/gin-gonic/gin v1.12.0 github.com/gofiber/fiber/v2 v2.52.11 github.com/gofiber/template/html/v2 v2.1.3 github.com/goravel/cos v1.17.0 github.com/goravel/example-proto v0.0.1 - github.com/goravel/fiber v1.17.0 - github.com/goravel/framework v1.17.2-0.20260215045043-365219d1eb4e - github.com/goravel/gin v1.17.0 + github.com/goravel/fiber v1.17.1-0.20260319150449-0a18b9c6e22b + github.com/goravel/framework v1.17.2-0.20260322042944-d61a6cc1601e + github.com/goravel/gin v1.17.1-0.20260319150458-6d1543fdf889 github.com/goravel/minio v1.17.0 github.com/goravel/mysql v1.17.0 github.com/goravel/oss v1.17.0 @@ -29,9 +29,9 @@ require ( github.com/swaggo/swag v1.16.2 github.com/uber/jaeger-client-go v2.30.0+incompatible github.com/vektah/gqlparser/v2 v2.5.19 - go.opentelemetry.io/otel v1.40.0 - go.opentelemetry.io/otel/metric v1.40.0 - google.golang.org/grpc v1.78.0 + go.opentelemetry.io/otel v1.42.0 + go.opentelemetry.io/otel/metric v1.42.0 + google.golang.org/grpc v1.79.2 ) require ( @@ -60,23 +60,26 @@ require ( github.com/aws/aws-sdk-go-v2/service/s3 v1.96.0 // indirect github.com/aws/smithy-go v1.24.0 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect - github.com/bytedance/sonic v1.14.0 // indirect - github.com/bytedance/sonic/loader v0.3.0 // indirect + github.com/bytedance/gopkg v0.1.3 // indirect + github.com/bytedance/sonic v1.15.0 // indirect + github.com/bytedance/sonic/loader v0.5.0 // indirect github.com/catppuccin/go v0.3.0 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/charmbracelet/bubbles v0.21.1-0.20250623103423-23b8fd6302d7 // indirect + github.com/charmbracelet/bubbles v1.0.0 // indirect github.com/charmbracelet/bubbletea v1.3.10 // indirect - github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect + github.com/charmbracelet/colorprofile v0.4.1 // indirect github.com/charmbracelet/huh v0.8.0 // indirect - github.com/charmbracelet/huh/spinner v0.0.0-20260209112015-5c5971ef3aeb // indirect + github.com/charmbracelet/huh/spinner v0.0.0-20260223110133-9dc45e34a40b // indirect github.com/charmbracelet/lipgloss v1.1.0 // indirect - github.com/charmbracelet/x/ansi v0.10.1 // indirect - github.com/charmbracelet/x/cellbuf v0.0.13 // indirect + github.com/charmbracelet/x/ansi v0.11.6 // indirect + github.com/charmbracelet/x/cellbuf v0.0.15 // indirect github.com/charmbracelet/x/exp/strings v0.0.0-20241222104055-e1130b311607 // indirect - github.com/charmbracelet/x/term v0.2.1 // indirect + github.com/charmbracelet/x/term v0.2.2 // indirect github.com/clbanning/mxj v1.8.4 // indirect - github.com/clipperhouse/uax29/v2 v2.2.0 // indirect + github.com/clipperhouse/displaywidth v0.9.0 // indirect + github.com/clipperhouse/stringish v0.1.1 // indirect + github.com/clipperhouse/uax29/v2 v2.7.0 // indirect github.com/cloudwego/base64x v0.1.6 // indirect github.com/containerd/console v1.0.5 // indirect github.com/dave/dst v0.27.3 // indirect @@ -98,14 +101,19 @@ require ( github.com/go-openapi/swag v0.22.7 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.27.0 // indirect + github.com/go-playground/validator/v10 v10.30.1 // indirect github.com/go-sql-driver/mysql v1.9.1 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/goccy/go-json v0.10.5 // indirect - github.com/goccy/go-yaml v1.18.0 // indirect + github.com/goccy/go-yaml v1.19.2 // indirect + github.com/gofiber/fiber/v3 v3.1.0 // indirect + github.com/gofiber/schema v1.7.0 // indirect github.com/gofiber/template v1.8.3 // indirect + github.com/gofiber/template/html/v3 v3.0.2 // indirect + github.com/gofiber/template/v2 v2.1.0 // indirect github.com/gofiber/utils v1.1.0 // indirect - github.com/goforj/godump v1.9.0 // indirect + github.com/gofiber/utils/v2 v2.0.2 // indirect + github.com/goforj/godump v1.9.1 // indirect github.com/golang-jwt/jwt/v5 v5.3.1 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect @@ -113,10 +121,7 @@ require ( github.com/google/go-querystring v1.1.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gookit/color v1.6.0 // indirect - github.com/gookit/filter v1.2.3 // indirect - github.com/gookit/goutil v0.7.1 // indirect - github.com/gookit/validate v1.5.6 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect @@ -127,19 +132,19 @@ require ( github.com/jmoiron/sqlx v1.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.18.2 // indirect + github.com/klauspost/compress v1.18.4 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/klauspost/crc32 v1.3.0 // indirect github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/lithammer/fuzzysearch v1.1.8 // indirect - github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/lucasb-eyer/go-colorful v1.3.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect - github.com/mattn/go-runewidth v0.0.19 // indirect + github.com/mattn/go-runewidth v0.0.21 // indirect github.com/microsoft/go-mssqldb v1.9.1 // indirect github.com/minio/crc64nvme v1.1.1 // indirect github.com/minio/md5-simd v1.1.2 // indirect @@ -157,9 +162,9 @@ require ( github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/philhofer/fwd v1.2.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/pterm/pterm v0.12.82 // indirect - github.com/quic-go/qpack v0.5.1 // indirect - github.com/quic-go/quic-go v0.54.0 // indirect + github.com/pterm/pterm v0.12.83 // indirect + github.com/quic-go/qpack v0.6.0 // indirect + github.com/quic-go/quic-go v0.59.0 // indirect github.com/redis/go-redis/v9 v9.17.3 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect @@ -167,7 +172,7 @@ require ( github.com/rs/cors v1.11.1 // indirect github.com/rs/xid v1.6.0 // indirect github.com/sagikazarmark/locafero v0.11.0 // indirect - github.com/samber/lo v1.52.0 // indirect + github.com/samber/lo v1.53.0 // indirect github.com/samber/slog-common v0.20.0 // indirect github.com/samber/slog-multi v1.7.1 // indirect github.com/sosodev/duration v1.3.1 // indirect @@ -180,52 +185,52 @@ require ( github.com/swaggo/files/v2 v2.0.0 // indirect github.com/tencentyun/cos-go-sdk-v5 v0.7.72 // indirect github.com/tetratelabs/wazero v1.9.0 // indirect - github.com/tinylib/msgp v1.6.1 // indirect + github.com/tinylib/msgp v1.6.3 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/uber/jaeger-lib v2.4.1+incompatible // indirect - github.com/ugorji/go/codec v1.3.0 // indirect + github.com/ugorji/go/codec v1.3.1 // indirect github.com/unrolled/secure v1.17.0 // indirect - github.com/urfave/cli/v3 v3.6.2 // indirect + github.com/urfave/cli/v3 v3.7.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.69.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 // indirect + go.mongodb.org/mongo-driver/v2 v2.5.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 // indirect - go.opentelemetry.io/contrib/propagators/b3 v1.39.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.15.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.15.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.15.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.39.0 // indirect - go.opentelemetry.io/otel/log v0.15.0 // indirect - go.opentelemetry.io/otel/sdk v1.40.0 // indirect - go.opentelemetry.io/otel/sdk/log v0.15.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.67.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect + go.opentelemetry.io/contrib/propagators/b3 v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 // indirect + go.opentelemetry.io/otel/log v0.18.0 // indirect + go.opentelemetry.io/otel/sdk v1.42.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.18.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.42.0 // indirect + go.opentelemetry.io/otel/trace v1.42.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/mock v0.5.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/arch v0.20.0 // indirect - golang.org/x/crypto v0.48.0 // indirect - golang.org/x/exp v0.0.0-20260112195511-716be5621a96 // indirect - golang.org/x/mod v0.33.0 // indirect - golang.org/x/net v0.50.0 // indirect - golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.41.0 // indirect - golang.org/x/term v0.40.0 // indirect - golang.org/x/text v0.34.0 // indirect + golang.org/x/arch v0.22.0 // indirect + golang.org/x/crypto v0.49.0 // indirect + golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 // indirect + golang.org/x/mod v0.34.0 // indirect + golang.org/x/net v0.52.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/sys v0.42.0 // indirect + golang.org/x/term v0.41.0 // indirect + golang.org/x/text v0.35.0 // indirect golang.org/x/time v0.12.0 // indirect - golang.org/x/tools v0.42.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect + golang.org/x/tools v0.43.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gorm.io/driver/mysql v1.6.0 // indirect @@ -235,4 +240,4 @@ require ( gorm.io/plugin/dbresolver v1.6.2 // indirect ) -replace github.com/goravel/framework v1.17.2 => github.com/goravel/framework v1.17.2-0.20260215045043-365219d1eb4e +replace github.com/goravel/framework => github.com/goravel/framework v1.17.2-0.20260322042944-d61a6cc1601e diff --git a/go.sum b/go.sum index 14f85bb..09c8869 100644 --- a/go.sum +++ b/go.sum @@ -101,38 +101,40 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymanbagabas/go-udiff v0.3.1 h1:LV+qyBQ2pqe0u42ZsUEtPiCaUoqgA9gYRDs3vj1nolY= github.com/aymanbagabas/go-udiff v0.3.1/go.mod h1:G0fsKmG+P6ylD0r6N/KgQD/nWzgfnl8ZBcNLgcbrw8E= -github.com/brianvoe/gofakeit/v7 v7.14.0 h1:R8tmT/rTDJmD2ngpqBL9rAKydiL7Qr2u3CXPqRt59pk= -github.com/brianvoe/gofakeit/v7 v7.14.0/go.mod h1:QXuPeBw164PJCzCUZVmgpgHJ3Llj49jSLVkKPMtxtxA= +github.com/brianvoe/gofakeit/v7 v7.14.1 h1:a7fe3fonbj0cW3wgl5VwIKfZtiH9C3cLnwcIXWT7sow= +github.com/brianvoe/gofakeit/v7 v7.14.1/go.mod h1:QXuPeBw164PJCzCUZVmgpgHJ3Llj49jSLVkKPMtxtxA= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= -github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ= -github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA= -github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= -github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M= +github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM= +github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE= +github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k= +github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE= +github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo= github.com/catppuccin/go v0.3.0 h1:d+0/YicIq+hSTo5oPuRi5kOpqkVA5tAsU6dNhvRu+aY= github.com/catppuccin/go v0.3.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/charmbracelet/bubbles v0.21.1-0.20250623103423-23b8fd6302d7 h1:JFgG/xnwFfbezlUnFMJy0nusZvytYysV4SCS2cYbvws= -github.com/charmbracelet/bubbles v0.21.1-0.20250623103423-23b8fd6302d7/go.mod h1:ISC1gtLcVilLOf23wvTfoQuYbW2q0JevFxPfUzZ9Ybw= +github.com/charmbracelet/bubbles v1.0.0 h1:12J8/ak/uCZEMQ6KU7pcfwceyjLlWsDLAxB5fXonfvc= +github.com/charmbracelet/bubbles v1.0.0/go.mod h1:9d/Zd5GdnauMI5ivUIVisuEm3ave1XwXtD1ckyV6r3E= github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= -github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs= -github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk= +github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk= +github.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk= github.com/charmbracelet/huh v0.8.0 h1:Xz/Pm2h64cXQZn/Jvele4J3r7DDiqFCNIVteYukxDvY= github.com/charmbracelet/huh v0.8.0/go.mod h1:5YVc+SlZ1IhQALxRPpkGwwEKftN/+OlJlnJYlDRFqN4= -github.com/charmbracelet/huh/spinner v0.0.0-20260209112015-5c5971ef3aeb h1:loPLebLFAjTolD/IwvNJLEMX+Nq2elBMwtzpueW014Y= -github.com/charmbracelet/huh/spinner v0.0.0-20260209112015-5c5971ef3aeb/go.mod h1:OMqKat/mm9a/qOnpuNOPyYO9bPzRNnmzLnRZT5KYltg= +github.com/charmbracelet/huh/spinner v0.0.0-20260223110133-9dc45e34a40b h1:deQbW7eR/gYwkXonGX6a1now6H6f8v4kfv0OIKECu0I= +github.com/charmbracelet/huh/spinner v0.0.0-20260223110133-9dc45e34a40b/go.mod h1:Y68nuKJuC/Q2lmiq18EkHWkVWi2VGLrwaOfOyPKLkkE= github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= -github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ= -github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE= -github.com/charmbracelet/x/cellbuf v0.0.13 h1:/KBBKHuVRbq1lYx5BzEHBAFBP8VcQzJejZ/IA3iR28k= -github.com/charmbracelet/x/cellbuf v0.0.13/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= +github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8= +github.com/charmbracelet/x/ansi v0.11.6/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ= +github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMxoFPAIztPI= +github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q= github.com/charmbracelet/x/conpty v0.1.0 h1:4zc8KaIcbiL4mghEON8D72agYtSeIgq8FSThSPQIb+U= github.com/charmbracelet/x/conpty v0.1.0/go.mod h1:rMFsDJoDwVmiYM10aD4bH2XiRgwI7NYJtQgl5yskjEQ= github.com/charmbracelet/x/errors v0.0.0-20240508181413-e8d8b6e2de86 h1:JSt3B+U9iqk37QUU2Rvb6DSBYRLtWqFqfxf8l5hOZUA= @@ -141,16 +143,20 @@ github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payR github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U= github.com/charmbracelet/x/exp/strings v0.0.0-20241222104055-e1130b311607 h1:D5Di9oyZpU7yeL2wkc5E4VaCXyg+8QYYN4kxMsLufDs= github.com/charmbracelet/x/exp/strings v0.0.0-20241222104055-e1130b311607/go.mod h1:pBhA0ybfXv6hDjQUZ7hk1lVxBiUbupdw5R31yPUViVQ= -github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= -github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= +github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= +github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8JawjaNZY= github.com/charmbracelet/x/termios v0.1.1/go.mod h1:rB7fnv1TgOPOyyKRJ9o+AsTU/vK5WHJ2ivHeut/Pcwo= github.com/charmbracelet/x/xpty v0.1.2 h1:Pqmu4TEJ8KeA9uSkISKMU3f+C1F6OGBn8ABuGlqCbtI= github.com/charmbracelet/x/xpty v0.1.2/go.mod h1:XK2Z0id5rtLWcpeNiMYBccNNBrP2IJnzHI0Lq13Xzq4= github.com/clbanning/mxj v1.8.4 h1:HuhwZtbyvyOw+3Z1AowPkU87JkJUSv751ELWaiTpj8I= github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng= -github.com/clipperhouse/uax29/v2 v2.2.0 h1:ChwIKnQN3kcZteTXMgb1wztSgaU+ZemkgWdohwgs8tY= -github.com/clipperhouse/uax29/v2 v2.2.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= +github.com/clipperhouse/displaywidth v0.9.0 h1:Qb4KOhYwRiN3viMv1v/3cTBlz3AcAZX3+y9OLhMtAtA= +github.com/clipperhouse/displaywidth v0.9.0/go.mod h1:aCAAqTlh4GIVkhQnJpbL0T/WfcrJXHcj8C0yjYcjOZA= +github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= +github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= +github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk= +github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM= github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= @@ -186,12 +192,14 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM= github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= -github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= -github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls= +github.com/gin-gonic/gin v1.12.0 h1:b3YAbrZtnf8N//yjKeU2+MQsh2mY5htkZidOM7O0wG8= +github.com/gin-gonic/gin v1.12.0/go.mod h1:VxccKfsSllpKshkBWgVgRniFFAzFb9csfngsqANjnLc= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= @@ -214,8 +222,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o 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.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= -github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= +github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w= +github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-sql-driver/mysql v1.9.1 h1:FrjNGn/BsJQjVRuSa8CBrM5BWA9BWoXXat3KrtSb/iI= github.com/go-sql-driver/mysql v1.9.1/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= @@ -223,18 +231,28 @@ github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPE github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= -github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= -github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM= +github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/gofiber/fiber/v2 v2.52.11 h1:5f4yzKLcBcF8ha1GQTWB+mpblWz3Vz6nSAbTL31HkWs= github.com/gofiber/fiber/v2 v2.52.11/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw= +github.com/gofiber/fiber/v3 v3.1.0 h1:1p4I820pIa+FGxfwWuQZ5rAyX0WlGZbGT6Hnuxt6hKY= +github.com/gofiber/fiber/v3 v3.1.0/go.mod h1:n2nYQovvL9z3Too/FGOfgtERjW3GQcAUqgfoezGBZdU= +github.com/gofiber/schema v1.7.0 h1:yNM+FNRZjyYEli9Ey0AXRBrAY9jTnb+kmGs3lJGPvKg= +github.com/gofiber/schema v1.7.0/go.mod h1:A/X5Ffyru4p9eBdp99qu+nzviHzQiZ7odLT+TwxWhbk= github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc= github.com/gofiber/template v1.8.3/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8= github.com/gofiber/template/html/v2 v2.1.3 h1:n1LYBtmr9C0V/k/3qBblXyMxV5B0o/gpb6dFLp8ea+o= github.com/gofiber/template/html/v2 v2.1.3/go.mod h1:U5Fxgc5KpyujU9OqKzy6Kn6Qup6Tm7zdsISR+VpnHRE= +github.com/gofiber/template/html/v3 v3.0.2 h1:/Fh8UcEsB4uhf1QWNbYaAOwXxSORebJ2zXkb5tgG/TI= +github.com/gofiber/template/html/v3 v3.0.2/go.mod h1:9phaCZLPZq2nFNTZj9zrmR8FSA8ydtBQFL9SEsr4jqI= +github.com/gofiber/template/v2 v2.1.0 h1:vrLY6uEW2HdioJm6J5FGUpYZuapVQhHciNz21XQjR/4= +github.com/gofiber/template/v2 v2.1.0/go.mod h1:ohgpR/Ng90nJbK+IyNzrgR/XpnBNt862/oTF5G7SAmE= github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM= github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0= -github.com/goforj/godump v1.9.0 h1:Y/APfWKQKnJetXgVJxDqD7vEpTGSgAwbKJGmj0UAteI= -github.com/goforj/godump v1.9.0/go.mod h1:/Vy+p50JtOkwsFN5dA1HQ7LS5gtPk3f61DaP4UR2o4s= +github.com/gofiber/utils/v2 v2.0.2 h1:ShRRssz0F3AhTlAQcuEj54OEDtWF7+HJDwEi/aa6QLI= +github.com/gofiber/utils/v2 v2.0.2/go.mod h1:+9Ub4NqQ+IaJoTliq5LfdmOJAA/Hzwf4pXOxOa3RrJ0= +github.com/goforj/godump v1.9.1 h1:9OGpb978Ytz3B59d5Yi2PzRYYLid6UkmhYDIDNiF15Y= +github.com/goforj/godump v1.9.1/go.mod h1:JsuL6AEZfKIU+iR5ewL6iQ2fIuhvLtPmJDH47M9Ptrc= github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= @@ -267,22 +285,16 @@ github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQ github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= github.com/gookit/color v1.6.0 h1:JjJXBTk1ETNyqyilJhkTXJYYigHG24TM9Xa2M1xAhRA= github.com/gookit/color v1.6.0/go.mod h1:9ACFc7/1IpHGBW8RwuDm/0YEnhg3dwwXpoMsmtyHfjs= -github.com/gookit/filter v1.2.3 h1:Zo7cBOtsVzAoa/jtf+Ury6zlsbJXqInFdUpbbnB2vMM= -github.com/gookit/filter v1.2.3/go.mod h1:nFLJcOV8dRgS1iiX23gUQgmHUhpuS40qCvAGgIvA1pM= -github.com/gookit/goutil v0.7.1 h1:AaFJPN9mrdeYBv8HOybri26EHGCC34WJVT7jUStGJsI= -github.com/gookit/goutil v0.7.1/go.mod h1:vJS9HXctYTCLtCsZot5L5xF+O1oR17cDYO9R0HxBmnU= -github.com/gookit/validate v1.5.6 h1:D6vbSZzreuKYpeeXm5FDDEJy3K5E4lcWsQE4saSMZbU= -github.com/gookit/validate v1.5.6/go.mod h1:WYEHndRNepIIkM+6CtgEX9MQ9ToIQRhXxmz5oLHF/fc= github.com/goravel/cos v1.17.0 h1:ovrSR8ZQbUWEN+BGhxwJrxrb64B+ryBLKwDPuX+WgCA= github.com/goravel/cos v1.17.0/go.mod h1:f3GOwA8QdEGOuwCN6OIo71FFdP/IgtVTg/vedjcgIfg= github.com/goravel/example-proto v0.0.1 h1:ZxETeKREQWjuJ49bX/Hqj1NLR5Vyj489Ks6dRxYeQsk= github.com/goravel/example-proto v0.0.1/go.mod h1:I8IPsHr4Ndf7KxmdsRpBR2LQ0Geo48+pjv9IIWf3mZg= -github.com/goravel/fiber v1.17.0 h1:XMkuz29hJzaN5mW7dK70oc6FfMDUQeYPbrLyBQoiIA8= -github.com/goravel/fiber v1.17.0/go.mod h1:hu2eLwQ6u8ZDFsVWHeV1q0bh7g7PRQg0VZxceVr29Uc= -github.com/goravel/framework v1.17.2-0.20260215045043-365219d1eb4e h1:pUys/0n2jtlSvFVxTxeg/aWwIkY53sixMps6AWrdpD0= -github.com/goravel/framework v1.17.2-0.20260215045043-365219d1eb4e/go.mod h1:bcEQ1Cvo2G9bM6aWWLYa6IiQvpamDe/7sP8FitIXEM8= -github.com/goravel/gin v1.17.0 h1:8H66v9GaYJR9UQ7C0VOef25/r8t/BAH9ZxlvxbHprlc= -github.com/goravel/gin v1.17.0/go.mod h1:n0W6V/H+E0mqO+Gh+UMjeBANZe//lpWJ6X7kF3kwxR8= +github.com/goravel/fiber v1.17.1-0.20260319150449-0a18b9c6e22b h1:peMAbfUTyQJCtA4wABmOowETE8N5v6i0GEy3vqVWeCg= +github.com/goravel/fiber v1.17.1-0.20260319150449-0a18b9c6e22b/go.mod h1:vVfU2LnxhCXOE1QH9U0/bFPBfIvbqCD3xyDkSm4wmVM= +github.com/goravel/framework v1.17.2-0.20260322042944-d61a6cc1601e h1:WXtXYc9lWIbpkbnGiPH4GtWopNh5KZaPEk/wipWPvDI= +github.com/goravel/framework v1.17.2-0.20260322042944-d61a6cc1601e/go.mod h1:2/eF2HWF3MFE1AIVnY5e+zebNCsawnMJRT14NzSiq/I= +github.com/goravel/gin v1.17.1-0.20260319150458-6d1543fdf889 h1:P1wUP46zVOoD3wXFrydvoBs3q8SfJO7Gk7TU6emKNZE= +github.com/goravel/gin v1.17.1-0.20260319150458-6d1543fdf889/go.mod h1:GsI8Ep1tfePcLHSx0vVtj+k3PLwpn/rUs4tKDFaH7b0= github.com/goravel/minio v1.17.0 h1:WGiPP/KZl/fuDpT9THRM83wjhLCqe1oIAyNVJvVjhS4= github.com/goravel/minio v1.17.0/go.mod h1:lSltN7uu5r84IIkn+5txGiRVqu3cxSs08AtuVOi9kVM= github.com/goravel/mysql v1.17.0 h1:iYIz0SHwntJSBlIBn7JXFZweMejgsiIepPHJaQuZPCo= @@ -303,8 +315,8 @@ github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+ github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 h1:X+2YciYSxvMQK0UZ7sg45ZVabVZBeBuvMkmuI2V3Fak= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7/go.mod h1:lW34nIZuQ8UDPdkon5fmfp2l3+ZkQ2me/+oecHYLOII= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= @@ -334,8 +346,8 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk= -github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= @@ -364,8 +376,8 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4= github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4= -github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= -github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= +github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= @@ -375,8 +387,8 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw= -github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= +github.com/mattn/go-runewidth v0.0.21 h1:jJKAZiQH+2mIinzCJIaIG9Be1+0NR+5sz/lYEEjdM8w= +github.com/mattn/go-runewidth v0.0.21/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/microsoft/go-mssqldb v1.8.2/go.mod h1:vp38dT33FGfVotRiTmDo3bFyaHq+p3LektQrjTULowo= @@ -436,12 +448,12 @@ github.com/pterm/pterm v0.12.31/go.mod h1:32ZAWZVXD7ZfG0s8qqHXePte42kdz8ECtRyEej github.com/pterm/pterm v0.12.33/go.mod h1:x+h2uL+n7CP/rel9+bImHD5lF3nM9vJj80k9ybiiTTE= github.com/pterm/pterm v0.12.36/go.mod h1:NjiL09hFhT/vWjQHSj1athJpx6H8cjpHXNAK5bUw8T8= github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkGTYf8s= -github.com/pterm/pterm v0.12.82 h1:+D9wYhCaeaK0FIQoZtqbNQuNpe2lB2tajKKsTd5paVQ= -github.com/pterm/pterm v0.12.82/go.mod h1:TyuyrPjnxfwP+ccJdBTeWHtd/e0ybQHkOS/TakajZCw= -github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= -github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= -github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg= -github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY= +github.com/pterm/pterm v0.12.83 h1:ie+YmGmA727VuhxBlyGr74Ks+7McV6kT99IB8EU80aA= +github.com/pterm/pterm v0.12.83/go.mod h1:xlgc6bFWyJIMtmLJvGim+L7jhSReilOlOnodeIYe4Tk= +github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8= +github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII= +github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw= +github.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU= github.com/redis/go-redis/v9 v9.17.3 h1:fN29NdNrE17KttK5Ndf20buqfDZwGNgoUr9qjl1DQx4= github.com/redis/go-redis/v9 v9.17.3/go.mod h1:u410H11HMLoB+TP67dz8rL9s6QW2j76l0//kSOd3370= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -462,8 +474,8 @@ github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc= github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik= -github.com/samber/lo v1.52.0 h1:Rvi+3BFHES3A8meP33VPAxiBZX/Aws5RxrschYGjomw= -github.com/samber/lo v1.52.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0= +github.com/samber/lo v1.53.0 h1:t975lj2py4kJPQ6haz1QMgtId2gtmfktACxIXArw3HM= +github.com/samber/lo v1.53.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0= github.com/samber/slog-common v0.20.0 h1:WaLnm/aCvBJSk5nR5aXZTFBaV0B47A+AEaEOiZDeUnc= github.com/samber/slog-common v0.20.0/go.mod h1:+Ozat1jgnnE59UAlmNX1IF3IByHsODnnwf9jUcBZ+m8= github.com/samber/slog-multi v1.7.1 h1:aCLXHRxgU+2v0PVlEOh7phynzM7CRo89ZgFtOwaqVEE= @@ -471,6 +483,8 @@ github.com/samber/slog-multi v1.7.1/go.mod h1:A4KQC99deqfkCDJcL/cO3kX6McX7FffQAx github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/shamaton/msgpack/v3 v3.1.0 h1:jsk0vEAqVvvS9+fTZ5/EcQ9tz860c9pWxJ4Iwecz8gU= +github.com/shamaton/msgpack/v3 v3.1.0/go.mod h1:DcQG8jrdrQCIxr3HlMYkiXdMhK+KfN2CitkyzsQV4uc= github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= @@ -498,6 +512,7 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= @@ -515,26 +530,28 @@ github.com/tencentyun/cos-go-sdk-v5 v0.7.72/go.mod h1:STbTNaNKq03u+gscPEGOahKzLc github.com/tencentyun/qcloud-cos-sts-sdk v0.0.0-20250515025012-e0eec8a5d123/go.mod h1:b18KQa4IxHbxeseW1GcZox53d7J0z39VNONTxvvlkXw= github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I= github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM= -github.com/tinylib/msgp v1.6.1 h1:ESRv8eL3u+DNHUoSAAQRE50Hm162zqAnBoGv9PzScPY= -github.com/tinylib/msgp v1.6.1/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA= +github.com/tinylib/msgp v1.6.3 h1:bCSxiTz386UTgyT1i0MSCvdbWjVW+8sG3PjkGsZQt4s= +github.com/tinylib/msgp v1.6.3/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= -github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= +github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY= +github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= github.com/unrolled/secure v1.17.0 h1:Io7ifFgo99Bnh0J7+Q+qcMzWM6kaDPCA5FroFZEdbWU= github.com/unrolled/secure v1.17.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40= -github.com/urfave/cli/v3 v3.6.2 h1:lQuqiPrZ1cIz8hz+HcrG0TNZFxU70dPZ3Yl+pSrH9A8= -github.com/urfave/cli/v3 v3.6.2/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso= +github.com/urfave/cli/v3 v3.7.0 h1:AGSnbUyjtLiM+WJUb4dzXKldl/gL+F8OwmRDtVr6g2U= +github.com/urfave/cli/v3 v3.7.0/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.69.0 h1:fNLLESD2SooWeh2cidsuFtOcrEi4uB4m1mPrkJMZyVI= github.com/valyala/fasthttp v1.69.0/go.mod h1:4wA4PfAraPlAsJ5jMSqCE2ug5tqUPwKXxVj8oNECGcw= github.com/vektah/gqlparser/v2 v2.5.19 h1:bhCPCX1D4WWzCDvkPl4+TP1N8/kLrWnp43egplt7iSg= github.com/vektah/gqlparser/v2 v2.5.19/go.mod h1:y7kvl5bBlDeuWIvLtA9849ncyvx6/lj06RsMrEjVy3U= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= @@ -543,64 +560,66 @@ github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342/go.mod h1:Ohn+xnUBi github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.mongodb.org/mongo-driver/v2 v2.5.0 h1:yXUhImUjjAInNcpTcAlPHiT7bIXhshCTL3jVBkF3xaE= +go.mongodb.org/mongo-driver/v2 v2.5.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0 h1:RN3ifU8y4prNWeEnQp2kRRHz8UwonAEYZl8tUzHEXAk= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.64.0/go.mod h1:habDz3tEWiFANTo6oUE99EmaFUrCNYAAg3wiVmusm70= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 h1:ssfIgGNANqpVFCndZvcuyKbl0g+UAVcbBcqGkG28H0Y= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0/go.mod h1:GQ/474YrbE4Jx8gZ4q5I4hrhUzM6UPzyrqJYV2AqPoQ= -go.opentelemetry.io/contrib/propagators/b3 v1.39.0 h1:PI7pt9pkSnimWcp5sQhUA9OzLbc3Ba4sL+VEUTNsxrk= -go.opentelemetry.io/contrib/propagators/b3 v1.39.0/go.mod h1:5gV/EzPnfYIwjzj+6y8tbGW2PKWhcsz5e/7twptRVQY= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.15.0 h1:W+m0g+/6v3pa5PgVf2xoFMi5YtNR06WtS7ve5pcvLtM= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.15.0/go.mod h1:JM31r0GGZ/GU94mX8hN4D8v6e40aFlUECSQ48HaLgHM= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.15.0 h1:EKpiGphOYq3CYnIe2eX9ftUkyU+Y8Dtte8OaWyHJ4+I= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.15.0/go.mod h1:nWFP7C+T8TygkTjJ7mAyEaFaE7wNfms3nV/vexZ6qt0= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0 h1:cEf8jF6WbuGQWUVcqgyWtTR0kOOAWY1DYZ+UhvdmQPw= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.39.0/go.mod h1:k1lzV5n5U3HkGvTCJHraTAGJ7MqsgL1wrGwTj1Isfiw= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0 h1:nKP4Z2ejtHn3yShBb+2KawiXgpn8In5cT7aO2wXuOTE= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0/go.mod h1:NwjeBbNigsO4Aj9WgM0C+cKIrxsZUaRmZUO7A8I7u8o= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 h1:QKdN8ly8zEMrByybbQgv8cWBcdAarwmIPZ6FThrWXJs= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0/go.mod h1:bTdK1nhqF76qiPoCCdyFIV+N/sRHYXYCTQc+3VCi3MI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0 h1:in9O8ESIOlwJAEGTkkf34DesGRAc/Pn8qJ7k3r/42LM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.39.0/go.mod h1:Rp0EXBm5tfnv0WL+ARyO/PHBEaEAT8UUHQ6AGJcSq6c= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.15.0 h1:0BSddrtQqLEylcErkeFrJBmwFzcqfQq9+/uxfTZq+HE= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.15.0/go.mod h1:87sjYuAPzaRCtdd09GU5gM1U9wQLrrcYrm77mh5EBoc= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0 h1:5gn2urDL/FBnK8OkCfD1j3/ER79rUuTYmCvlXBKeYL8= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.39.0/go.mod h1:0fBG6ZJxhqByfFZDwSwpZGzJU671HkwpWaNe2t4VUPI= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.39.0 h1:8UPA4IbVZxpsD76ihGOQiFml99GPAEZLohDXvqHdi6U= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.39.0/go.mod h1:MZ1T/+51uIVKlRzGw1Fo46KEWThjlCBZKl2LzY5nv4g= -go.opentelemetry.io/otel/log v0.15.0 h1:0VqVnc3MgyYd7QqNVIldC3dsLFKgazR6P3P3+ypkyDY= -go.opentelemetry.io/otel/log v0.15.0/go.mod h1:9c/G1zbyZfgu1HmQD7Qj84QMmwTp2QCQsZH1aeoWDE4= -go.opentelemetry.io/otel/log/logtest v0.15.0 h1:porNFuxAjodl6LhePevOc3n7bo3Wi3JhGXNWe7KP8iU= -go.opentelemetry.io/otel/log/logtest v0.15.0/go.mod h1:c8epqBXGHgS1LiNgmD+LuNYK9lSS3mqvtMdxLsfJgLg= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= -go.opentelemetry.io/otel/sdk/log v0.15.0 h1:WgMEHOUt5gjJE93yqfqJOkRflApNif84kxoHWS9VVHE= -go.opentelemetry.io/otel/sdk/log v0.15.0/go.mod h1:qDC/FlKQCXfH5hokGsNg9aUBGMJQsrUyeOiW5u+dKBQ= -go.opentelemetry.io/otel/sdk/log/logtest v0.14.0 h1:Ijbtz+JKXl8T2MngiwqBlPaHqc4YCaP/i13Qrow6gAM= -go.opentelemetry.io/otel/sdk/log/logtest v0.14.0/go.mod h1:dCU8aEL6q+L9cYTqcVOk8rM9Tp8WdnHOPLiBgp0SGOA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.67.0 h1:yI1/OhfEPy7J9eoa6Sj051C7n5dvpj0QX8g4sRchg04= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.67.0/go.mod h1:NoUCKYWK+3ecatC4HjkRktREheMeEtrXoQxrqYFeHSc= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg= +go.opentelemetry.io/contrib/propagators/b3 v1.42.0 h1:B2Pew5ufEtgkjLF+tSkXjgYZXQr9m7aCm1wLKB0URbU= +go.opentelemetry.io/contrib/propagators/b3 v1.42.0/go.mod h1:iPgUcSEF5DORW6+yNbdw/YevUy+QqJ508ncjhrRSCjc= +go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= +go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 h1:deI9UQMoGFgrg5iLPgzueqFPHevDl+28YKfSpPTI6rY= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0/go.mod h1:PFx9NgpNUKXdf7J4Q3agRxMs3Y07QhTCVipKmLsMKnU= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0 h1:icqq3Z34UrEFk2u+HMhTtRsvo7Ues+eiJVjaJt62njs= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0/go.mod h1:W2m8P+d5Wn5kipj4/xmbt9uMqezEKfBjzVJadfABSBE= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 h1:MdKucPl/HbzckWWEisiNqMPhRrAOQX8r4jTuGr636gk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0/go.mod h1:RolT8tWtfHcjajEH5wFIZ4Dgh5jpPdFXYV9pTAk/qjc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0 h1:H7O6RlGOMTizyl3R08Kn5pdM06bnH8oscSj7o11tmLA= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0/go.mod h1:mBFWu/WOVDkWWsR7Tx7h6EpQB8wsv7P0Yrh0Pb7othc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 h1:THuZiwpQZuHPul65w4WcwEnkX2QIuMT+UFoOrygtoJw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0/go.mod h1:J2pvYM5NGHofZ2/Ru6zw/TNWnEQp5crgyDeSrYpXkAw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 h1:zWWrB1U6nqhS/k6zYB74CjRpuiitRtLLi68VcgmOEto= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0/go.mod h1:2qXPNBX1OVRC0IwOnfo1ljoid+RD0QK3443EaqVlsOU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 h1:uLXP+3mghfMf7XmV4PkGfFhFKuNWoCvvx5wP/wOXo0o= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0/go.mod h1:v0Tj04armyT59mnURNUJf7RCKcKzq+lgJs6QSjHjaTc= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0 h1:KJVjPD3rcPb98rIs3HznyJlrfx9ge5oJvxxlGR+P/7s= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0/go.mod h1:K3kRa2ckmHWQaTWQdPRHc7qGXASuVuoEQXzrvlA98Ws= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0 h1:lSZHgNHfbmQTPfuTmWVkEu8J8qXaQwuV30pjCcAUvP8= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.42.0/go.mod h1:so9ounLcuoRDu033MW/E0AD4hhUjVqswrMF5FoZlBcw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 h1:s/1iRkCKDfhlh1JF26knRneorus8aOwVIDhvYx9WoDw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0/go.mod h1:UI3wi0FXg1Pofb8ZBiBLhtMzgoTm1TYkMvn71fAqDzs= +go.opentelemetry.io/otel/log v0.18.0 h1:XgeQIIBjZZrliksMEbcwMZefoOSMI1hdjiLEiiB0bAg= +go.opentelemetry.io/otel/log v0.18.0/go.mod h1:KEV1kad0NofR3ycsiDH4Yjcoj0+8206I6Ox2QYFSNgI= +go.opentelemetry.io/otel/log/logtest v0.18.0 h1:2QeyoKJdIgK2LJhG1yn78o/zmpXx1EditeyRDREqVS8= +go.opentelemetry.io/otel/log/logtest v0.18.0/go.mod h1:v1vh3PYR9zIa5MK6HwkH2lMrLBg/Y9Of6Qc+krlesX0= +go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= +go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= +go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= +go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= +go.opentelemetry.io/otel/sdk/log v0.18.0 h1:n8OyZr7t7otkeTnPTbDNom6rW16TBYGtvyy2Gk6buQw= +go.opentelemetry.io/otel/sdk/log v0.18.0/go.mod h1:C0+wxkTwKpOCZLrlJ3pewPiiQwpzycPI/u6W0Z9fuYk= +go.opentelemetry.io/otel/sdk/log/logtest v0.18.0 h1:l3mYuPsuBx6UKE47BVcPrZoZ0q/KER57vbj2qkgDLXA= +go.opentelemetry.io/otel/sdk/log/logtest v0.18.0/go.mod h1:7cHtiVJpZebB3wybTa4NG+FUo5NPe3PROz1FqB0+qdw= +go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= +go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= +go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= +go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= -go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= +go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= +go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c= -golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= +golang.org/x/arch v0.22.0 h1:c/Zle32i5ttqRXjdLyyHZESLD/bB90DCU1g9l/0YBDI= +golang.org/x/arch v0.22.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -614,15 +633,15 @@ golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOM golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= +golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20260112195511-716be5621a96 h1:Z/6YuSHTLOHfNFdb8zVZomZr7cqNgTJvA8+Qz75D8gU= -golang.org/x/exp v0.0.0-20260112195511-716be5621a96/go.mod h1:nzimsREAkjBCIEFtHiYkrJyT+2uy9YZJB7H1k68CXZU= +golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 h1:jiDhWWeC7jfWqR9c/uplMOqJ0sbNlNWv0UkzE0vX1MA= +golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90/go.mod h1:xE1HEv6b+1SCZ5/uscMRjUBKtIxworgEcEi+/n9NQDQ= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -634,8 +653,8 @@ golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= -golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= +golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -654,8 +673,8 @@ golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= -golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= +golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= +golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -663,8 +682,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -691,8 +710,8 @@ golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= -golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -710,8 +729,8 @@ golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= -golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= -golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= +golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= +golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -725,8 +744,8 @@ golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= +golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -738,8 +757,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= -golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= +golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s= +golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -749,12 +768,12 @@ gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 h1:merA0rdPeUV3YIIfHHcH4qBkiQAc1nfCKSI7lB4cV2M= -google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409/go.mod h1:fl8J1IvUjCilwZzQowmw2b7HQB2eAuYBabMXzWurF+I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 h1:H86B94AW+VfJWDqFeEbBPhEtHzJwJfTbgE2lZa54ZAQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= -google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= -google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= +google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0= +google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU= +google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/tests/feature/http_test.go b/tests/feature/http_test.go index 240426a..b375937 100644 --- a/tests/feature/http_test.go +++ b/tests/feature/http_test.go @@ -285,78 +285,6 @@ func (s *HttpTestSuite) TestUsers() { s.Equal("{\"users\":[]}", context) } -func (s *HttpTestSuite) TestValidationForm() { - payload := strings.NewReader(`{ - "context": "ctx", - "name": "Goravel" - }`) - - resp, err := s.Http(s.T()).Post("/validation/form", payload) - - s.NoError(err) - resp.AssertSuccessful() - context, err := resp.Content() - s.Require().NoError(err) - s.Equal("{\"context\":\"ctx_context\",\"name\":\"Goravel\"}", context) -} - -func (s *HttpTestSuite) TestValidationJson() { - payload := strings.NewReader(`{ - "context": "ctx", - "name": "Goravel", - "date": "2024-07-08 18:33:32" - }`) - - resp, err := s.Http(s.T()).Post("/validation/json", payload) - - s.NoError(err) - resp.AssertSuccessful() - context, err := resp.Content() - s.Require().NoError(err) - s.Equal("{\"context\":\"ctx_context\",\"date\":\"2024-07-08 18:33:32\",\"name\":\"Goravel\"}", context) -} - -func (s *HttpTestSuite) TestValidationRequest() { - s.Run("success", func() { - payload := strings.NewReader(`{ - "name": " Goravel ", - "context": "ctx", - "date": "2024-07-08 18:33:32", - "tags": ["tag1", "tag2"], - "scores": [1, 2], - "code": 123456 - }`) - - resp, err := s.Http(s.T()).Post("/validation/request", payload) - - s.NoError(err) - resp.AssertSuccessful() - - context, err := resp.Content() - s.Require().NoError(err) - s.Equal("{\"code\":123456,\"context\":\"ctx_context\",\"date\":\"2024-07-08 18:33:32\",\"name\":\"Goravel\",\"scores\":[1,2],\"tags\":[\"tag1\",\"tag2\"]}", context) - }) - - s.Run("failed", func() { - payload := strings.NewReader(`{ - "context": "ctx", - "date": "1", - "tags": "tag1", - "scores": 1, - "code": 1234567 - }`) - - resp, err := s.Http(s.T()).Post("/validation/request", payload) - - s.NoError(err) - resp.AssertBadRequest() - - content, err := resp.Content() - s.Require().NoError(err) - s.Equal("{\"message\":{\"code\":{\"regex\":\"code value does not pass the regex check\"},\"date\":{\"date\":\"date value should be a date string\"},\"name\":{\"required\":\"name is required to not be empty\"}}}", content) - }) -} - func (s *HttpTestSuite) TestView() { resp, err := s.Http(s.T()).Get("/view") s.NoError(err) diff --git a/tests/feature/validation_test.go b/tests/feature/validation_test.go index 31116be..e35c8e4 100644 --- a/tests/feature/validation_test.go +++ b/tests/feature/validation_test.go @@ -32,17 +32,15 @@ func (s *ValidationTestSuite) SetupTest() { s.RefreshDatabase() } -type ruleCase struct { - name string - rule string - errRule string - passData map[string]any - failData map[string]any - message string -} - func (s *ValidationTestSuite) TestRules() { - cases := []ruleCase{ + cases := []struct { + name string + rule string + errRule string + passData map[string]any + failData map[string]any + message string + }{ {name: "required", rule: "required", errRule: "required", passData: map[string]any{"f": "ok"}, failData: map[string]any{"f": ""}, message: "required failed"}, {name: "required_if", rule: "required_if:cond,yes", errRule: "required_if", passData: map[string]any{"cond": "yes", "f": "ok"}, failData: map[string]any{"cond": "yes", "f": ""}, message: "required_if failed"}, {name: "required_unless", rule: "required_unless:cond,no", errRule: "required_unless", passData: map[string]any{"cond": "yes", "f": "ok"}, failData: map[string]any{"cond": "yes", "f": ""}, message: "required_unless failed"}, @@ -102,14 +100,14 @@ func (s *ValidationTestSuite) TestRules() { for _, tc := range cases { s.Run(tc.name, func() { - validator, err := facades.Validation().Make(context.Background(), tc.passData, map[string]string{ + validator, err := facades.Validation().Make(context.Background(), tc.passData, map[string]any{ "f": tc.rule, }) s.Require().NoError(err) s.Require().NotNil(validator) s.False(validator.Fails(), tc.name+" pass case") - validator, err = facades.Validation().Make(context.Background(), tc.failData, map[string]string{ + validator, err = facades.Validation().Make(context.Background(), tc.failData, map[string]any{ "f": tc.rule, }, validation.Messages(map[string]string{ "f." + tc.errRule: tc.message, @@ -194,18 +192,18 @@ func (s *ValidationTestSuite) TestImageRule() { s.Contains(content, "image failed") } -type filterCase struct { - name string - filter string - passData map[string]any - passRule string - failData map[string]any - failRule string - message string - passAssert func(*testing.T, any) -} - func (s *ValidationTestSuite) TestFilters() { + type filterCase struct { + name string + filter string + passData map[string]any + passRule string + failData map[string]any + failRule string + message string + passAssert func(*testing.T, any) + } + stringEqCase := func(alias, in, out, failIn string) filterCase { return filterCase{ name: alias, @@ -223,35 +221,35 @@ func (s *ValidationTestSuite) TestFilters() { } tests := []filterCase{ - {name: "int", filter: "int", passData: map[string]any{"f": "12"}, passRule: "required", failData: map[string]any{"f": ""}, failRule: "required", message: "int failed", passAssert: func(t *testing.T, actual any) { require.IsType(t, int(0), actual); require.Equal(t, 12, actual) }}, - {name: "toInt", filter: "toInt", passData: map[string]any{"f": "12"}, passRule: "required", failData: map[string]any{"f": ""}, failRule: "required", message: "toInt failed", passAssert: func(t *testing.T, actual any) { require.IsType(t, int(0), actual); require.Equal(t, 12, actual) }}, - {name: "uint", filter: "uint", passData: map[string]any{"f": "12"}, passRule: "required", failData: map[string]any{"f": ""}, failRule: "required", message: "uint failed", passAssert: func(t *testing.T, actual any) { require.IsType(t, uint(0), actual); require.Equal(t, uint(12), actual) }}, - {name: "toUint", filter: "toUint", passData: map[string]any{"f": "12"}, passRule: "required", failData: map[string]any{"f": ""}, failRule: "required", message: "toUint failed", passAssert: func(t *testing.T, actual any) { require.IsType(t, uint(0), actual); require.Equal(t, uint(12), actual) }}, - {name: "int64", filter: "int64", passData: map[string]any{"f": "12"}, passRule: "required", failData: map[string]any{"f": ""}, failRule: "required", message: "int64 failed", passAssert: func(t *testing.T, actual any) { + {name: "int", filter: "int", passData: map[string]any{"f": "12"}, passRule: "required", failData: map[string]any{"f": "13"}, failRule: "eq:12", message: "int failed", passAssert: func(t *testing.T, actual any) { require.IsType(t, int(0), actual); require.Equal(t, 12, actual) }}, + {name: "toInt", filter: "toInt", passData: map[string]any{"f": "12"}, passRule: "required", failData: map[string]any{"f": "13"}, failRule: "eq:12", message: "toInt failed", passAssert: func(t *testing.T, actual any) { require.IsType(t, int(0), actual); require.Equal(t, 12, actual) }}, + {name: "uint", filter: "uint", passData: map[string]any{"f": "12"}, passRule: "required", failData: map[string]any{"f": "13"}, failRule: "eq:12", message: "uint failed", passAssert: func(t *testing.T, actual any) { require.IsType(t, uint(0), actual); require.Equal(t, uint(12), actual) }}, + {name: "toUint", filter: "toUint", passData: map[string]any{"f": "12"}, passRule: "required", failData: map[string]any{"f": "13"}, failRule: "eq:12", message: "toUint failed", passAssert: func(t *testing.T, actual any) { require.IsType(t, uint(0), actual); require.Equal(t, uint(12), actual) }}, + {name: "int64", filter: "int64", passData: map[string]any{"f": "12"}, passRule: "required", failData: map[string]any{"f": "13"}, failRule: "eq:12", message: "int64 failed", passAssert: func(t *testing.T, actual any) { require.IsType(t, int64(0), actual) require.Equal(t, int64(12), actual) }}, - {name: "toInt64", filter: "toInt64", passData: map[string]any{"f": "12"}, passRule: "required", failData: map[string]any{"f": ""}, failRule: "required", message: "toInt64 failed", passAssert: func(t *testing.T, actual any) { + {name: "toInt64", filter: "toInt64", passData: map[string]any{"f": "12"}, passRule: "required", failData: map[string]any{"f": "13"}, failRule: "eq:12", message: "toInt64 failed", passAssert: func(t *testing.T, actual any) { require.IsType(t, int64(0), actual) require.Equal(t, int64(12), actual) }}, - {name: "float", filter: "float", passData: map[string]any{"f": "1.5"}, passRule: "required", failData: map[string]any{"f": ""}, failRule: "required", message: "float failed", passAssert: func(t *testing.T, actual any) { + {name: "float", filter: "float", passData: map[string]any{"f": "1.5"}, passRule: "required", failData: map[string]any{"f": "2.5"}, failRule: "eq:1.5", message: "float failed", passAssert: func(t *testing.T, actual any) { require.IsType(t, float64(0), actual) require.InDelta(t, 1.5, actual, 0.00001) }}, {name: "toFloat", filter: "toFloat", passData: map[string]any{"f": "1.5"}, passRule: "eq:1.5", failData: map[string]any{"f": "2.5"}, failRule: "eq:1.5", message: "toFloat failed", passAssert: func(t *testing.T, actual any) { - require.IsType(t, "", actual) - require.Equal(t, "1.5", actual) + require.IsType(t, float64(0), actual) + require.InDelta(t, 1.5, actual, 0.00001) }}, - {name: "bool", filter: "bool", passData: map[string]any{"f": "true"}, passRule: "required", failData: map[string]any{"f": ""}, failRule: "required", message: "bool failed", passAssert: func(t *testing.T, actual any) { require.IsType(t, false, actual); require.Equal(t, true, actual) }}, - {name: "toBool", filter: "toBool", passData: map[string]any{"f": "true"}, passRule: "required", failData: map[string]any{"f": ""}, failRule: "required", message: "toBool failed", passAssert: func(t *testing.T, actual any) { require.IsType(t, false, actual); require.Equal(t, true, actual) }}, + {name: "bool", filter: "bool", passData: map[string]any{"f": "true"}, passRule: "required", failData: map[string]any{"f": ""}, failRule: "accepted", message: "bool failed", passAssert: func(t *testing.T, actual any) { require.IsType(t, false, actual); require.Equal(t, true, actual) }}, + {name: "toBool", filter: "toBool", passData: map[string]any{"f": "true"}, passRule: "required", failData: map[string]any{"f": ""}, failRule: "accepted", message: "toBool failed", passAssert: func(t *testing.T, actual any) { require.IsType(t, false, actual); require.Equal(t, true, actual) }}, stringEqCase("trim", " Goravel ", "Goravel", " Laravel "), stringEqCase("trimSpace", " Goravel ", "Goravel", " Laravel "), stringEqCase("ltrim", " Goravel", "Goravel", " Laravel"), stringEqCase("trimLeft", " Goravel", "Goravel", " Laravel"), stringEqCase("rtrim", "Goravel ", "Goravel", "Laravel "), stringEqCase("trimRight", "Goravel ", "Goravel", "Laravel "), - {name: "integer", filter: "integer", passData: map[string]any{"f": "12"}, passRule: "eq:12", failData: map[string]any{"f": "13"}, failRule: "eq:12", message: "integer failed", passAssert: func(t *testing.T, actual any) { require.IsType(t, "", actual); require.Equal(t, "12", actual) }}, + {name: "integer", filter: "integer", passData: map[string]any{"f": "12"}, passRule: "eq:12", failData: map[string]any{"f": "13"}, failRule: "eq:12", message: "integer failed", passAssert: func(t *testing.T, actual any) { require.IsType(t, int(0), actual); require.Equal(t, 12, actual) }}, stringEqCase("lower", "GoRavel", "goravel", "LarAvel"), stringEqCase("lowercase", "GoRavel", "goravel", "LarAvel"), stringEqCase("upper", "GoRavel", "GORAVEL", "Laravel"), @@ -296,11 +294,11 @@ func (s *ValidationTestSuite) TestFilters() { require.IsType(t, []int{}, actual) require.Equal(t, []int{1, 2, 3}, actual) }}, - {name: "str2time", filter: "str2time", passData: map[string]any{"f": "2024-01-02 03:04:05"}, passRule: "required", failData: map[string]any{"f": ""}, failRule: "required", message: "str2time failed", passAssert: func(t *testing.T, actual any) { + {name: "str2time", filter: "str2time", passData: map[string]any{"f": "2024-01-02 03:04:05"}, passRule: "required", failData: map[string]any{"f": ""}, failRule: "after:2020-01-01", message: "str2time failed", passAssert: func(t *testing.T, actual any) { require.IsType(t, time.Time{}, actual) require.False(t, actual.(time.Time).IsZero()) }}, - {name: "strToTime", filter: "strToTime", passData: map[string]any{"f": "2024-01-02 03:04:05"}, passRule: "required", failData: map[string]any{"f": ""}, failRule: "required", message: "strToTime failed", passAssert: func(t *testing.T, actual any) { + {name: "strToTime", filter: "strToTime", passData: map[string]any{"f": "2024-01-02 03:04:05"}, passRule: "required", failData: map[string]any{"f": ""}, failRule: "after:2020-01-01", message: "strToTime failed", passAssert: func(t *testing.T, actual any) { require.IsType(t, time.Time{}, actual) require.False(t, actual.(time.Time).IsZero()) }}, @@ -316,9 +314,9 @@ func (s *ValidationTestSuite) TestFilters() { for _, tt := range tests { s.Run(tt.name, func() { - validator, err := facades.Validation().Make(context.Background(), tt.passData, map[string]string{ + validator, err := facades.Validation().Make(context.Background(), tt.passData, map[string]any{ "f": tt.passRule, - }, validation.Filters(map[string]string{ + }, validation.Filters(map[string]any{ "f": tt.filter, })) s.Require().NoError(err) @@ -334,9 +332,9 @@ func (s *ValidationTestSuite) TestFilters() { tt.passAssert(s.T(), data.F) } - validator, err = facades.Validation().Make(context.Background(), tt.failData, map[string]string{ + validator, err = facades.Validation().Make(context.Background(), tt.failData, map[string]any{ "f": tt.failRule, - }, validation.Filters(map[string]string{ + }, validation.Filters(map[string]any{ "f": tt.filter, }), validation.Messages(map[string]string{ "f." + ruleKey(tt.failRule): tt.message, @@ -358,51 +356,26 @@ func (s *ValidationTestSuite) TestCustomRule() { validator, err := facades.Validation().Make(context.Background(), map[string]any{ "f": "Goravel", - }, map[string]string{ - "f": "exists:users,name", + }, map[string]any{ + "f": "custom_exists:users,name", }, validation.Messages(map[string]string{ - "f.exists": "exists failed", + "f.custom_exists": "custom_exists failed", })) s.Require().NoError(err) s.False(validator.Fails()) validator, err = facades.Validation().Make(context.Background(), map[string]any{ "f": "Unknown", - }, map[string]string{ - "f": "exists:users,name", - }, validation.Messages(map[string]string{ - "f.exists": "exists failed", - })) - s.Require().NoError(err) - s.True(validator.Fails()) - s.Equal(map[string]map[string]string{ - "f": { - "exists": "exists failed", - }, - }, validator.Errors().All()) - - validator, err = facades.Validation().Make(context.Background(), map[string]any{ - "f": "Unknown", - }, map[string]string{ - "f": "not_exists:users,name", + }, map[string]any{ + "f": "custom_exists:users,name", }, validation.Messages(map[string]string{ - "f.not_exists": "not_exists failed", - })) - s.Require().NoError(err) - s.False(validator.Fails()) - - validator, err = facades.Validation().Make(context.Background(), map[string]any{ - "f": "Goravel", - }, map[string]string{ - "f": "not_exists:users,name", - }, validation.Messages(map[string]string{ - "f.not_exists": "not_exists failed", + "f.custom_exists": "custom_exists failed", })) s.Require().NoError(err) s.True(validator.Fails()) s.Equal(map[string]map[string]string{ "f": { - "not_exists": "not_exists failed", + "custom_exists": "custom_exists failed", }, }, validator.Errors().All()) } @@ -410,9 +383,9 @@ func (s *ValidationTestSuite) TestCustomRule() { func (s *ValidationTestSuite) TestCustomFilter() { validator, err := facades.Validation().Make(context.Background(), map[string]any{ "f": "goravel", - }, map[string]string{ + }, map[string]any{ "f": "eq:goravel_suffix", - }, validation.Filters(map[string]string{ + }, validation.Filters(map[string]any{ "f": "append_suffix:_suffix", }), validation.Messages(map[string]string{ "f.eq": "append_suffix failed", @@ -422,9 +395,9 @@ func (s *ValidationTestSuite) TestCustomFilter() { validator, err = facades.Validation().Make(context.Background(), map[string]any{ "f": "goravel", - }, map[string]string{ + }, map[string]any{ "f": "eq:goravel_fail", - }, validation.Filters(map[string]string{ + }, validation.Filters(map[string]any{ "f": "append_suffix:_suffix", }), validation.Messages(map[string]string{ "f.eq": "append_suffix failed", @@ -438,42 +411,201 @@ func (s *ValidationTestSuite) TestCustomFilter() { }, validator.Errors().All()) } -func (s *ValidationTestSuite) TestTypes() { - s.Run("Validate", func() { - resp, err := s.Http(s.T()).Post("/validation/json", strings.NewReader(`{"context":"ctx","name":"Goravel","date":"2024-07-08 18:33:32"}`)) +func (s *ValidationTestSuite) TestValidateJson() { + s.Run("success", func() { + resp, err := s.Http(s.T()).Post("/validation/json", strings.NewReader(`{"context":"ctx","name":"Goravel","date":"2024-07-08 18:33:32","age":1,"items":[{"name":"item1"},{"name":"item2"}],"meta":{"name":"api","source":"api","trace":"abc"}}`)) s.Require().NoError(err) resp.AssertSuccessful() - resp, err = s.Http(s.T()).Post("/validation/json", strings.NewReader(`{"context":"ctx","name":""}`)) + result, err := resp.Json() + s.Require().NoError(err) + s.Equal(map[string]any{ + "context": "ctx_context", + "name": "Goravel", + "date": "2024-07-08 18:33:32", + "age": float64(1), + "items": []any{map[string]any{"name": "item1"}, map[string]any{"name": "item2"}}, + "meta": map[string]any{"name": "api", "source": "api", "trace": "abc"}, + }, result) + }) + + s.Run("fail", func() { + resp, err := s.Http(s.T()).Post("/validation/json", strings.NewReader(`{"context":"ctx","name":"Goravel","date":"2024-07-08 18:33:32","age":1,"items":[{"name":"item1"},{"name":""}],"meta":{"name":"","source":"api","trace":"abc"}}`)) s.Require().NoError(err) resp.AssertBadRequest() - content, err := resp.Content() + + result, err := resp.Json() s.Require().NoError(err) - s.Equal("{\"message\":{\"date\":{\"required\":\"date is required to not be empty\"},\"name\":{\"required\":\"name is required to not be empty\"}}}", content) + s.Equal(map[string]any{ + "items.1.name": map[string]any{ + "required": "The items.1.name field is required.", + }, + "meta.name": map[string]any{ + "required": "The meta.name field is required.", + }, + }, result["message"]) }) +} - s.Run("ValidateRequest", func() { - resp, err := s.Http(s.T()).Post("/validation/request", strings.NewReader(`{"name":" Goravel ","context":"ctx","date":"2024-07-08 18:33:32","tags":["tag1","tag2"],"scores":[1,2],"code":123456}`)) +func (s *ValidationTestSuite) TestValidateForm() { + s.Run("success", func() { + payload, err := http.NewBody().SetField("context", "ctx").SetField("name", "Goravel").SetField("age", 1).Build() + s.Require().NoError(err) + resp, err := s.Http(s.T()).WithHeader("Content-Type", payload.ContentType()).Post("/validation/form", payload.Reader()) s.Require().NoError(err) resp.AssertSuccessful() - resp, err = s.Http(s.T()).Post("/validation/request", strings.NewReader(`{"context":"ctx","date":"1","tags":"tag1","scores":1,"code":1234567}`)) + content, err := resp.Content() + s.Require().NoError(err) + s.Equal("{\"age\":1,\"context\":\"ctx_context\",\"name\":\"Goravel\"}", content) + }) + + s.Run("fail", func() { + payload, err := http.NewBody().SetField("context", "ctx").SetField("name", "").SetField("age", 1).Build() + s.Require().NoError(err) + resp, err := s.Http(s.T()).WithHeader("Content-Type", payload.ContentType()).Post("/validation/form", payload.Reader()) s.Require().NoError(err) resp.AssertBadRequest() + content, err := resp.Content() s.Require().NoError(err) - s.Equal("{\"message\":{\"code\":{\"regex\":\"code value does not pass the regex check\"},\"date\":{\"date\":\"date value should be a date string\"},\"name\":{\"required\":\"name is required to not be empty\"}}}", content) + s.Equal("{\"message\":{\"name\":{\"required\":\"The name field is required.\"}}}", content) }) +} - s.Run("ValidationMake", func() { - validator, err := facades.Validation().Make(context.Background(), map[string]any{"f": " goravel "}, map[string]string{"f": "eq:goravel"}, validation.Filters(map[string]string{"f": "trim"}), validation.Messages(map[string]string{"f.eq": "make failed"})) +func (s *ValidationTestSuite) TestValidateRequest() { + s.Run("success", func() { + resp, err := s.Http(s.T()).Post("/validation/request", strings.NewReader(`{"name":" Goravel ","context":"ctx","date":"2024-07-08 18:33:32","tags":["tag1","tag2"],"scores":[1,2],"items":[{"name":"item1"},{"name":"item2"}],"meta":{"name":"api","source":"api","trace":"abc"},"code":123456,"age":1}`)) + s.Require().NoError(err) + resp.AssertSuccessful() + + result, err := resp.Json() + s.Require().NoError(err) + s.Equal(map[string]any{ + "context": "ctx_context", + "name": "Goravel", + "date": "2024-07-08 18:33:32", + "tags": []any{"tag1", "tag2"}, + "scores": []any{float64(1), float64(2)}, + "items": []any{map[string]any{"name": "item1"}, map[string]any{"name": "item2"}}, + "meta": map[string]any{"name": "api", "source": "api", "trace": "abc"}, + "code": float64(123456), + "age": float64(1), + }, result) + }) + + s.Run("fail", func() { + resp, err := s.Http(s.T()).Post("/validation/request", strings.NewReader(`{"name":" Goravel ","context":"ctx","date":"2024-07-08 18:33:32","tags":["tag1","tag2"],"scores":[1,2],"items":[{"name":"item1"},{"name":""}],"meta":{"name":"","source":"api","trace":"abc"},"code":123456,"age":1}`)) + s.Require().NoError(err) + resp.AssertBadRequest() + + result, err := resp.Json() + s.Require().NoError(err) + s.Equal(map[string]any{ + "items.1.name": map[string]any{ + "required": "The items.1.name field is required.", + }, + "meta.name": map[string]any{ + "required": "The meta.name field is required.", + }, + }, result["message"]) + }) +} + +func (s *ValidationTestSuite) TestValidateMake() { + s.Run("success", func() { + validator, err := facades.Validation().Make(context.Background(), map[string]any{ + "context": "ctx", + "name": " Goravel ", + "date": "2024-07-08 18:33:32", + "tags": []any{"tag1", "tag2"}, + "scores": []any{1, 2}, + "items": []any{ + map[string]any{"name": "item1"}, + map[string]any{"name": "item2"}, + }, + "meta": map[string]any{ + "name": "api", + "source": "api", + "trace": "abc", + }, + "code": 123456, + "age": 1, + }, map[string]any{ + "name": "required", + "context": "required", + "tags.*": "required|string", + "scores.*": "required|int", + "items.*.name": "sometimes|required|string", + "meta": "sometimes|map", + "meta.name": "sometimes|required|string", + "date": "required|date", + "code": `required|regex:^\d{4,6}$`, + }, validation.Filters(map[string]any{ + "name": "trim", + })) s.Require().NoError(err) s.False(validator.Fails()) + s.Equal(map[string]any{ + "context": "ctx", + "name": "Goravel", + "date": "2024-07-08 18:33:32", + "tags": []any{"tag1", "tag2"}, + "scores": []any{1, 2}, + "items": []any{ + map[string]any{"name": "item1"}, + map[string]any{"name": "item2"}, + }, + "meta": map[string]any{ + "name": "api", + "source": "api", + "trace": "abc", + }, + "code": 123456, + }, validator.Validated()) + }) - validator, err = facades.Validation().Make(context.Background(), map[string]any{"f": " laravel "}, map[string]string{"f": "eq:goravel"}, validation.Filters(map[string]string{"f": "trim"}), validation.Messages(map[string]string{"f.eq": "make failed"})) + s.Run("fail", func() { + validator, err := facades.Validation().Make(context.Background(), map[string]any{ + "context": "ctx", + "name": " Goravel ", + "date": "2024-07-08 18:33:32", + "tags": []any{"tag1", "tag2"}, + "scores": []any{1, 2}, + "items": []any{ + map[string]any{"name": "item1"}, + map[string]any{"name": ""}, + }, + "meta": map[string]any{ + "name": "", + "source": "api", + "trace": "abc", + }, + "code": 123456, + "age": 1, + }, map[string]any{ + "name": "required", + "context": "required", + "tags.*": "required|string", + "scores.*": "required|int", + "items.*.name": "sometimes|required|string", + "meta": "sometimes|map", + "meta.name": "sometimes|required|string", + "date": "required|date", + "code": `required|regex:^\d{4,6}$`, + }, validation.Filters(map[string]any{ + "name": "trim", + })) s.Require().NoError(err) s.True(validator.Fails()) - s.Equal(map[string]map[string]string{"f": {"eq": "make failed"}}, validator.Errors().All()) + s.Equal(map[string]map[string]string{ + "items.1.name": { + "required": "The items.1.name field is required.", + }, + "meta.name": { + "required": "The meta.name field is required.", + }, + }, validator.Errors().All()) }) }