commit 812c9605f55a22df468af688079198dbfeb5803d Author: mm Date: Sat Sep 7 16:42:56 2024 +0500 init diff --git a/.github/workflows/CI-CD.yml b/.github/workflows/CI-CD.yml new file mode 100644 index 0000000..64c7649 --- /dev/null +++ b/.github/workflows/CI-CD.yml @@ -0,0 +1,44 @@ +name: CI/CD +on: + push: + branches: + - main +jobs: + build: + name: Build + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Set up Docker Build + uses: docker/setup-buildx-action@v1 + + - name: Build and push the Docker image + uses: docker/build-push-action@v3 + with: + push: true + tags: | + dockerhub-st.ru/donat-widget:latest + dockerhub-st.ru/donat-widget:${{ github.sha }} + +# deploy: +# runs-on: ubuntu-latest +# steps: +# - name: Checkout code +# uses: actions/checkout@v2 +# +# - name: Install kubectl +# uses: azure/setup-kubectl@v1 +# with: +# version: 'v1.21.0' +# +# - name: Configure kube-config +# run: | +# mkdir -p $HOME/.kube +# echo "${{ secrets.KUBE_CONFIG }}" | base64 --decode > $HOME/.kube/config +# export KUBECONFIG=$HOME/.kube/config +# +# - name: Update deployment +# run: | +# kubectl restart rollout deployment donat-user-deployment \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6685d48 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea + +config/config.yaml \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c0ff6f5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,8 @@ +FROM golang:1.23-alpine + +WORKDIR /root +COPY . . +RUN go install github.com/swaggo/swag/cmd/swag@latest +RUN go mod tidy && swag init -g cmd/main.go -o cmd/docs + +CMD go run cmd/main.go \ No newline at end of file diff --git a/cmd/docs/docs.go b/cmd/docs/docs.go new file mode 100644 index 0000000..93cdb0e --- /dev/null +++ b/cmd/docs/docs.go @@ -0,0 +1,99 @@ +// Package docs Code generated by swaggo/swag. DO NOT EDIT +package docs + +import "github.com/swaggo/swag" + +const docTemplate = `{ + "schemes": {{ marshal .Schemes }}, + "swagger": "2.0", + "info": { + "description": "{{escape .Description}}", + "title": "{{.Title}}", + "contact": {}, + "version": "{{.Version}}" + }, + "host": "{{.Host}}", + "basePath": "{{.BasePath}}", + "paths": { + "/api/user/register": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Auth" + ], + "parameters": [ + { + "description": "Register user", + "name": "input", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/register.requestModel" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/register.responseModel" + } + } + } + } + } + }, + "definitions": { + "register.requestModel": { + "type": "object", + "required": [ + "password" + ], + "properties": { + "email": { + "type": "string" + }, + "login": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "register.responseModel": { + "type": "object", + "properties": { + "token": { + "type": "string" + }, + "userId": { + "type": "string" + } + } + } + } +}` + +// SwaggerInfo holds exported Swagger Info so clients can modify it +var SwaggerInfo = &swag.Spec{ + Version: "1.0", + Host: "localhost", + BasePath: "/v2", + Schemes: []string{}, + Title: "Template", + Description: "Описание.", + InfoInstanceName: "swagger", + SwaggerTemplate: docTemplate, + LeftDelim: "{{", + RightDelim: "}}", +} + +func init() { + swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo) +} diff --git a/cmd/docs/swagger.json b/cmd/docs/swagger.json new file mode 100644 index 0000000..ee70599 --- /dev/null +++ b/cmd/docs/swagger.json @@ -0,0 +1,75 @@ +{ + "swagger": "2.0", + "info": { + "description": "Описание.", + "title": "Template", + "contact": {}, + "version": "1.0" + }, + "host": "localhost", + "basePath": "/v2", + "paths": { + "/api/user/register": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Auth" + ], + "parameters": [ + { + "description": "Register user", + "name": "input", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/register.requestModel" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/register.responseModel" + } + } + } + } + } + }, + "definitions": { + "register.requestModel": { + "type": "object", + "required": [ + "password" + ], + "properties": { + "email": { + "type": "string" + }, + "login": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "register.responseModel": { + "type": "object", + "properties": { + "token": { + "type": "string" + }, + "userId": { + "type": "string" + } + } + } + } +} \ No newline at end of file diff --git a/cmd/docs/swagger.yaml b/cmd/docs/swagger.yaml new file mode 100644 index 0000000..19a139b --- /dev/null +++ b/cmd/docs/swagger.yaml @@ -0,0 +1,48 @@ +basePath: /v2 +definitions: + register.requestModel: + properties: + email: + type: string + login: + type: string + password: + type: string + required: + - password + type: object + register.responseModel: + properties: + token: + type: string + userId: + type: string + type: object +host: localhost +info: + contact: {} + description: Описание. + title: Template + version: "1.0" +paths: + /api/user/register: + post: + consumes: + - application/json + parameters: + - description: Register user + in: body + name: input + required: true + schema: + $ref: '#/definitions/register.requestModel' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/register.responseModel' + tags: + - Auth +swagger: "2.0" diff --git a/cmd/handlers/create/controller.go b/cmd/handlers/create/controller.go new file mode 100644 index 0000000..b1d165b --- /dev/null +++ b/cmd/handlers/create/controller.go @@ -0,0 +1,46 @@ +package create + +import ( + "context" + "github.com/labstack/echo/v4" + "log/slog" + "net/http" +) + +// Register @Description Register user +// +// @Tags Auth +// @Accept json +// @Produce json +// @Param input body requestModel true "Register user" +// @Success 200 {object} responseModel +// @Router /api/user/register [post] +func Register(request echo.Context) error { + var registerData requestModel + + // Получение данных + if err := request.Bind(®isterData); err != nil { + slog.Error(err.Error()) + return echo.NewHTTPError(400, err.Error()) + } + + // Валидаций + err := request.Validate(®isterData) + if err != nil { + slog.Error(err.Error()) + return request.JSON(422, err) + } + + // reg + err = RegUserService( + context.Background(), + registerData, + ) + if err != nil { + slog.Error(err.Error()) + return request.JSON(500, err) + } + + slog.Info("User Register success") + return request.JSON(http.StatusOK, "ok") +} diff --git a/cmd/handlers/create/repository.go b/cmd/handlers/create/repository.go new file mode 100644 index 0000000..c26bc45 --- /dev/null +++ b/cmd/handlers/create/repository.go @@ -0,0 +1,34 @@ +package create + +import ( + "context" + "fmt" + "github.com/jackc/pgx/v5" + pg "template/db/pg" +) + +type User struct { + Id int `json:"id"` + Login string `json:"login"` +} + +func RegUserRepository( + ctx context.Context, + login, email *string, + password string, +) error { + query := ` + INSERT INTO users (login, password) + VALUES (@login, @password); + ` + args := pgx.NamedArgs{ + "login": login, + "password": password, + } + result, err := pg.Pool.Db.Exec(ctx, query, args) + if err != nil { + return err + } + fmt.Println(result) + return nil +} diff --git a/cmd/handlers/create/schema.go b/cmd/handlers/create/schema.go new file mode 100644 index 0000000..f5c1813 --- /dev/null +++ b/cmd/handlers/create/schema.go @@ -0,0 +1,12 @@ +package create + +type requestModel struct { + Password string `json:"password" validate:"required"` + Login *string `json:"login"` + Email *string `json:"email"` +} + +type responseModel struct { + Token string `json:"token"` + UserId string `json:"userId"` +} diff --git a/cmd/handlers/create/service.go b/cmd/handlers/create/service.go new file mode 100644 index 0000000..64b0e8b --- /dev/null +++ b/cmd/handlers/create/service.go @@ -0,0 +1,21 @@ +package create + +import ( + "context" +) + +func RegUserService( + ctx context.Context, + registerData requestModel, +) error { + err := RegUserRepository( + ctx, + registerData.Login, + registerData.Email, + registerData.Password, + ) + if err != nil { + return err + } + return nil +} diff --git a/cmd/handlers/router.go b/cmd/handlers/router.go new file mode 100644 index 0000000..567fd0c --- /dev/null +++ b/cmd/handlers/router.go @@ -0,0 +1,10 @@ +package handlers + +import ( + "github.com/labstack/echo/v4" + "template/cmd/handlers/view" +) + +func IncludeRouters(app *echo.Echo) { + app.POST("/api/widget/view", view.BannerView) +} diff --git a/cmd/handlers/view/controller.go b/cmd/handlers/view/controller.go new file mode 100644 index 0000000..a552bef --- /dev/null +++ b/cmd/handlers/view/controller.go @@ -0,0 +1,63 @@ +package view + +import ( + "context" + "github.com/labstack/echo/v4" + "log/slog" + "net/http" +) + +// BannerView +// +// @Description View Widget +// @Tags Auth +// @Accept json +// @Produce json +// @Param input body requestModel true "Register user" +// @Success 200 {object} responseModel +// @Router /api/widget/view [post] +func BannerView(request echo.Context) error { + var registerData requestModel + + // Получение данных + if err := request.Bind(®isterData); err != nil { + slog.Error(err.Error()) + return echo.NewHTTPError(400, err.Error()) + } + + // Валидаций + err := request.Validate(®isterData) + if err != nil { + slog.Error(err.Error()) + return request.JSON(422, err) + } + + // reg + err = RegUserService( + context.Background(), + registerData, + ) + if err != nil { + slog.Error(err.Error()) + return request.JSON(500, err) + } + banner := ` + + + +
+ + + +` + slog.Info("User Register success") + return request.HTML(http.StatusOK, banner) +} diff --git a/cmd/handlers/view/repository.go b/cmd/handlers/view/repository.go new file mode 100644 index 0000000..38d4923 --- /dev/null +++ b/cmd/handlers/view/repository.go @@ -0,0 +1,34 @@ +package view + +import ( + "context" + "fmt" + "github.com/jackc/pgx/v5" + pg "template/db/pg" +) + +type User struct { + Id int `json:"id"` + Login string `json:"login"` +} + +func RegUserRepository( + ctx context.Context, + login, email *string, + password string, +) error { + query := ` + INSERT INTO users (login, password) + VALUES (@login, @password); + ` + args := pgx.NamedArgs{ + "login": login, + "password": password, + } + result, err := pg.Pool.Db.Exec(ctx, query, args) + if err != nil { + return err + } + fmt.Println(result) + return nil +} diff --git a/cmd/handlers/view/schema.go b/cmd/handlers/view/schema.go new file mode 100644 index 0000000..b71286b --- /dev/null +++ b/cmd/handlers/view/schema.go @@ -0,0 +1,12 @@ +package view + +type requestModel struct { + Password string `json:"password" validate:"required"` + Login *string `json:"login"` + Email *string `json:"email"` +} + +type responseModel struct { + Token string `json:"token"` + UserId string `json:"userId"` +} diff --git a/cmd/handlers/view/service.go b/cmd/handlers/view/service.go new file mode 100644 index 0000000..c0b112f --- /dev/null +++ b/cmd/handlers/view/service.go @@ -0,0 +1,21 @@ +package view + +import ( + "context" +) + +func RegUserService( + ctx context.Context, + registerData requestModel, +) error { + err := RegUserRepository( + ctx, + registerData.Login, + registerData.Email, + registerData.Password, + ) + if err != nil { + return err + } + return nil +} diff --git a/cmd/main.go b/cmd/main.go new file mode 100644 index 0000000..e04e8e0 --- /dev/null +++ b/cmd/main.go @@ -0,0 +1,37 @@ +package main + +import ( + "github.com/labstack/echo/v4" + "log/slog" + "os" + "template/cmd/handlers" +) + +import ( + _ "template/cmd/docs" + "template/lib/validator" +) + +// @title Template +// @version 1.0 +// @description Описание. + +// @host localhost +// @BasePath /v2 + +func init() { + logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) + slog.SetDefault(logger) +} + +func main() { + app := initApp() + app.Logger.Fatal(app.Start(":8000")) +} + +func initApp() *echo.Echo { + app := echo.New() + app.Validator = validator.NewValidator() + handlers.IncludeRouters(app) + return app +} diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..31da26f --- /dev/null +++ b/config/config.go @@ -0,0 +1,37 @@ +package config + +import ( + "gopkg.in/yaml.v2" + "os" +) + +type Cfg struct { + Database DatabaseConfig `yaml:"db"` +} + +type DatabaseConfig struct { + Username string `yaml:"username"` + Password string `yaml:"password"` + Host string `yaml:"host"` + Port string `yaml:"port"` + DBName string `yaml:"dbname"` +} + +var Config Cfg + +func InitConfig() error { + data, err := os.ReadFile("config/config.yaml") + if err != nil { + panic(err) + return err + } + + err = yaml.Unmarshal(data, &Config) + if err != nil { + panic(err) + return err + } + return nil +} + +var err = InitConfig() diff --git a/db/pg/connection.go b/db/pg/connection.go new file mode 100644 index 0000000..c7685fe --- /dev/null +++ b/db/pg/connection.go @@ -0,0 +1,61 @@ +package pg + +import ( + "context" + "fmt" + "github.com/jackc/pgx/v5/pgxpool" + "sync" + "template/config" +) + +type Postgres struct { + Db *pgxpool.Pool +} + +var ( + pgInstance *Postgres + pgOnce sync.Once +) + +func NewPgPool( + ctx context.Context, + username, password, host, port, dbname string, +) (*Postgres, error) { + connString := "postgres://" + username + ":" + password + "@" + host + ":" + port + "/" + dbname + "?pool_max_conns=100" + pgOnce.Do(func() { + db, err := pgxpool.New(ctx, connString) + if err != nil { + panic(err) + } + pgInstance = &Postgres{db} + }) + + return pgInstance, nil +} + +func (pg *Postgres) Ping(ctx context.Context) error { + err := pg.Db.Ping(ctx) + return err +} + +func (pg *Postgres) Close() { + pg.Db.Close() +} + +func (pg *Postgres) CreateTable(ctx context.Context) error { + result, err := pg.Db.Exec(ctx, createTableQuery) + if err != nil { + return err + } + fmt.Println(result) + return nil +} + +var Pool, _ = NewPgPool( + context.Background(), + config.Config.Database.Username, + config.Config.Database.Password, + config.Config.Database.Host, + config.Config.Database.Port, + config.Config.Database.DBName, +) diff --git a/db/pg/models.go b/db/pg/models.go new file mode 100644 index 0000000..97fab9c --- /dev/null +++ b/db/pg/models.go @@ -0,0 +1,12 @@ +package pg + +var createTableQuery = ` + CREATE TABLE users ( + id INTEGER PRIMARY KEY, + login VARCHAR(255) UNIQUE, + password VARCHAR(255) NOT NULL, + email VARCHAR(255) UNIQUE, + key_2fa VARCHAR(255) DEFAULT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP + )` diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..c59954a --- /dev/null +++ b/go.mod @@ -0,0 +1,46 @@ +module template + +go 1.23.0 + +require ( + github.com/go-playground/validator/v10 v10.22.0 + github.com/jackc/pgx/v5 v5.6.0 + github.com/jcobhams/echovalidate/v2 v2.0.3 + github.com/labstack/echo/v4 v4.12.0 + github.com/swaggo/echo-swagger v1.4.1 + github.com/swaggo/swag v1.16.3 + gopkg.in/yaml.v2 v2.4.0 +) + +require ( + github.com/KyleBanks/depth v1.2.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/ghodss/yaml v1.0.0 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/spec v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/puddle/v2 v2.2.1 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/labstack/gommon v0.4.2 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/swaggo/files/v2 v2.0.0 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasttemplate v1.2.2 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/tools v0.24.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..8f0fa28 --- /dev/null +++ b/go.sum @@ -0,0 +1,50 @@ +github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jcobhams/echovalidate/v2 v2.0.3/go.mod h1:I9VVW+j88qwoJC0ugb9B2Olvc2w+RN66oDyrVaT+Gns= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM= +github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/swaggo/echo-swagger v1.4.1/go.mod h1:C8bSi+9yH2FLZsnhqMZLIZddpUxZdBYuNHbtaS1Hljc= +github.com/swaggo/files/v2 v2.0.0/go.mod h1:24kk2Y9NYEJ5lHuCra6iVwkMjIekMCaFq/0JQj66kyM= +github.com/swaggo/swag v1.16.3/go.mod h1:DImHIuOFXKpMFAQjcC7FG4m3Dg4+QuUgUzJmKjI/gRk= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/lib/validator/validator.go b/lib/validator/validator.go new file mode 100644 index 0000000..02b0719 --- /dev/null +++ b/lib/validator/validator.go @@ -0,0 +1,25 @@ +package validator + +import ( + "errors" + "strings" + + validator "github.com/go-playground/validator/v10" +) + +type Validator struct { + validator *validator.Validate +} + +func NewValidator() *Validator { + return &Validator{validator: validator.New()} +} + +func (val *Validator) Validate(i interface{}) error { + err := val.validator.Struct(i) + if err == nil { + return nil + } + err = errors.New(strings.Replace(err.Error(), "\n", ", ", -1)) + return err +}