fix
This commit is contained in:
parent
f296bc2dcd
commit
8de00b91da
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.env
|
99
api/handlers/products/product.go
Normal file
99
api/handlers/products/product.go
Normal file
@ -0,0 +1,99 @@
|
||||
package handler_products
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"online-order/domain"
|
||||
"online-order/entity"
|
||||
"online-order/utils"
|
||||
)
|
||||
|
||||
type controller struct {
|
||||
service domain.ProductService
|
||||
}
|
||||
|
||||
func NewProductController(svc domain.ProductService) *controller {
|
||||
return &controller{
|
||||
service: svc,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *controller) listProduct(ctx *gin.Context) {
|
||||
products, err := c.service.List()
|
||||
if err != nil {
|
||||
utils.ResponseJSON(ctx, http.StatusOK, http.StatusBadRequest, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
utils.ResponseJSON(ctx, http.StatusOK, http.StatusOK, "successful", products)
|
||||
}
|
||||
|
||||
func (c *controller) getProduct(ctx *gin.Context) {
|
||||
id := ctx.Param("id")
|
||||
id_convert, err := strconv.Atoi(id)
|
||||
if err != nil {
|
||||
utils.ResponseJSON(ctx, http.StatusOK, http.StatusNotFound, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
product, err := c.service.GetByID(id_convert)
|
||||
if err != nil || product == nil {
|
||||
utils.ResponseJSON(ctx, http.StatusOK, http.StatusBadRequest, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
utils.ResponseJSON(ctx, http.StatusOK, http.StatusFound, "successful", product)
|
||||
}
|
||||
|
||||
func (c *controller) update(ctx *gin.Context) {
|
||||
var data *entity.ProductCreateUpdate
|
||||
var id = ctx.Param("id")
|
||||
|
||||
id_convert, err := strconv.Atoi(id)
|
||||
if err != nil {
|
||||
utils.ResponseJSON(ctx, http.StatusOK, http.StatusNotFound, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
|
||||
if err := ctx.ShouldBindJSON(&data); err != nil {
|
||||
utils.ResponseJSON(ctx, http.StatusOK, http.StatusBadRequest, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
|
||||
product, err := c.service.GetByID(id_convert)
|
||||
if err != nil || product == nil {
|
||||
utils.ResponseJSON(ctx, http.StatusOK, http.StatusBadRequest, entity.ErrNotFound.Error(), nil)
|
||||
return
|
||||
}
|
||||
|
||||
data = entity.ValidateUpdate(data, product)
|
||||
|
||||
err = c.service.Update(data)
|
||||
if err != nil {
|
||||
utils.ResponseJSON(ctx, http.StatusOK, http.StatusBadRequest, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
response := entity.ProductDisplayFormatter(data)
|
||||
utils.ResponseJSON(ctx, http.StatusOK, http.StatusAccepted, "successful", response)
|
||||
}
|
||||
|
||||
func (c *controller) deleteProduct(ctx *gin.Context) {
|
||||
var id = ctx.Param("id")
|
||||
id_convert, err := strconv.Atoi(id)
|
||||
if err != nil {
|
||||
utils.ResponseJSON(ctx, http.StatusOK, http.StatusNotFound, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
|
||||
product, err := c.service.GetByID(id_convert)
|
||||
if err != nil || product == nil {
|
||||
utils.ResponseJSON(ctx, http.StatusOK, http.StatusBadRequest, entity.ErrNotFound.Error(), nil)
|
||||
return
|
||||
}
|
||||
|
||||
err = c.service.Delete(id_convert)
|
||||
if err != nil {
|
||||
utils.ResponseJSON(ctx, http.StatusOK, http.StatusBadRequest, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
utils.ResponseJSON(ctx, http.StatusOK, http.StatusAccepted, "successfully deleted", nil)
|
||||
}
|
22
api/handlers/products/router.go
Normal file
22
api/handlers/products/router.go
Normal file
@ -0,0 +1,22 @@
|
||||
package handler_products
|
||||
|
||||
import (
|
||||
"online-order/entity"
|
||||
"online-order/repository/product"
|
||||
"online-order/usecase/product"
|
||||
)
|
||||
|
||||
func NewProductRouters(server *entity.Routers) {
|
||||
productRepo := repository_product.NewProductClient(server.Database)
|
||||
|
||||
productService := service_product.NewProductService(productRepo)
|
||||
|
||||
productController := NewProductController(productService)
|
||||
|
||||
// product management
|
||||
api_product := server.OpenApp.Group("products")
|
||||
api_product.GET("/", productController.listProduct)
|
||||
api_product.GET(":id", productController.getProduct)
|
||||
api_product.PUT(":id", productController.update)
|
||||
api_product.DELETE(":id", productController.deleteProduct)
|
||||
}
|
@ -2,11 +2,12 @@ package middlewares
|
||||
|
||||
import (
|
||||
"online-order/entity"
|
||||
"online-order/repository/product"
|
||||
)
|
||||
|
||||
func NewMiddlewareRouters(server *entity.Routers) *controller {
|
||||
userRepo := repository_product.NewUserClient(server.Database)
|
||||
authService := service_authentication.NewAuthService(userRepo)
|
||||
productRepo := repository_product.NewProductClient(server.Database)
|
||||
authService := service_authentication.NewAuthService(productRepo)
|
||||
|
||||
return NewMiddlewareControllers(authService)
|
||||
}
|
||||
|
31
domain/product.go
Normal file
31
domain/product.go
Normal file
@ -0,0 +1,31 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"online-order/entity"
|
||||
)
|
||||
|
||||
type ProductRepository interface {
|
||||
List() ([]*entity.ProductDisplay, error)
|
||||
Create(p *entity.ProductCreateUpdate) error
|
||||
GetByID(id int) (*entity.ProductDisplay, error)
|
||||
SearchProduct(identifier string) (*entity.ProductDisplay, error)
|
||||
Update(p *entity.ProductCreateUpdate) error
|
||||
Delete(id int) error
|
||||
}
|
||||
|
||||
type ProductService interface {
|
||||
List() ([]*entity.ProductDisplay, error)
|
||||
Create(u *entity.ProductCreateUpdate) error
|
||||
GetByID(id int) (*entity.ProductDisplay, error)
|
||||
SearchProduct(identifier string) (*entity.ProductDisplay, error)
|
||||
Update(u *entity.ProductCreateUpdate) error
|
||||
Delete(id int) error
|
||||
}
|
||||
|
||||
type UserController interface {
|
||||
listProduct(ctx *gin.Context)
|
||||
getProduct(ctx *gin.Context)
|
||||
updateProduct(ctx *gin.Context)
|
||||
deleteProduct(ctx *gin.Context)
|
||||
}
|
7
domain/server.go
Normal file
7
domain/server.go
Normal file
@ -0,0 +1,7 @@
|
||||
package domain
|
||||
|
||||
import "github.com/gin-gonic/gin"
|
||||
|
||||
type ServerMiddleware interface {
|
||||
JwAuthtMiddleware() gin.HandlerFunc
|
||||
}
|
@ -16,7 +16,7 @@ type Product struct {
|
||||
func (Product) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
field.String("name").Default("unknown"),
|
||||
field.String("description").Optional().Nillable(),
|
||||
field.String("description").Nillable(),
|
||||
field.Float("price").Default(0).Positive(),
|
||||
field.Float("original_price").Default(0).Positive(),
|
||||
field.Int("quantity").Default(0).Positive(),
|
||||
|
63
entity/product.go
Normal file
63
entity/product.go
Normal file
@ -0,0 +1,63 @@
|
||||
package entity
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// use to display a product
|
||||
type ProductDisplay struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description *string `json:"description"`
|
||||
Price float64 `json:"price"`
|
||||
OriginalPrice float64 `json:"original_price"`
|
||||
Quantity int `json:"quantity"`
|
||||
Status bool `json:"status"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// use to create or update a product
|
||||
type ProductCreateUpdate struct {
|
||||
ProductDisplay
|
||||
}
|
||||
|
||||
// Func that will check non empty field on ProductDisplay and update product
|
||||
func ValidateUpdate(product *ProductCreateUpdate, p *ProductDisplay) *ProductCreateUpdate {
|
||||
if product.Price > p.OriginalPrice {
|
||||
product.Price = p.Price
|
||||
product.OriginalPrice = p.OriginalPrice
|
||||
}
|
||||
|
||||
if product.Quantity < 0 {
|
||||
product.Quantity = 0
|
||||
}
|
||||
|
||||
product.ID = p.ID
|
||||
product.Name = p.Name
|
||||
product.Description = p.Description
|
||||
product.Price = p.Price
|
||||
product.OriginalPrice = p.OriginalPrice
|
||||
product.Quantity = p.Quantity
|
||||
product.Status = p.Status
|
||||
product.CreatedAt = p.CreatedAt
|
||||
product.UpdatedAt = p.UpdatedAt
|
||||
|
||||
return product
|
||||
}
|
||||
|
||||
func ProductDisplayFormatter(product *ProductCreateUpdate) (p *ProductDisplay) {
|
||||
p = &ProductDisplay{
|
||||
ID: product.ID,
|
||||
Name: product.Name,
|
||||
Description: product.Description,
|
||||
Price: product.Price,
|
||||
OriginalPrice: product.OriginalPrice,
|
||||
Quantity: product.Quantity,
|
||||
Status: product.Status,
|
||||
CreatedAt: product.CreatedAt,
|
||||
UpdatedAt: product.UpdatedAt,
|
||||
}
|
||||
|
||||
return
|
||||
}
|
29
entity/product_test.go
Normal file
29
entity/product_test.go
Normal file
@ -0,0 +1,29 @@
|
||||
package entity
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_ValidateUpdate_With_Same_Name(t *testing.T) {
|
||||
p := &ProductDisplay{
|
||||
ID: 2312,
|
||||
Name: "Pizza Name",
|
||||
Description: "new Pizza",
|
||||
Price: 15000,
|
||||
}
|
||||
|
||||
product_to_update := &ProductCreateUpdate{
|
||||
ProductDisplay: ProductDisplay{
|
||||
ID: 2312,
|
||||
Name: "new Pizza Name",
|
||||
Description: "new Pizza",
|
||||
Price: 15000,
|
||||
},
|
||||
}
|
||||
|
||||
result := ValidateUpdate(product_to_update, p)
|
||||
assert.NotEqual(t, result.Name, "Pizza Name")
|
||||
assert.Equal(t, result.Name, p.Name)
|
||||
}
|
29
go.mod
29
go.mod
@ -3,45 +3,62 @@ module online-order
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
entgo.io/ent v0.12.4 // indirect
|
||||
entgo.io/ent v0.12.4
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/go-sql-driver/mysql v1.7.1
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0
|
||||
github.com/rs/zerolog v1.31.0
|
||||
github.com/spf13/viper v1.17.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
golang.org/x/crypto v0.13.0
|
||||
)
|
||||
|
||||
require (
|
||||
ariga.io/atlas v0.14.1-0.20230918065911-83ad451a4935 // indirect
|
||||
github.com/agext/levenshtein v1.2.1 // indirect
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||
github.com/bytedance/sonic v1.9.1 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/gin-gonic/gin v1.9.1 // indirect
|
||||
github.com/go-openapi/inflect v0.19.0 // 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.14.0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.7.1 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.13.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
||||
github.com/rs/zerolog v1.31.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/sagikazarmark/locafero v0.3.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.10.0 // indirect
|
||||
github.com/spf13/cast v1.5.1 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.17.0 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
github.com/zclconf/go-cty v1.8.0 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/crypto v0.13.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
||||
golang.org/x/mod v0.12.0 // indirect
|
||||
golang.org/x/net v0.15.0 // indirect
|
||||
golang.org/x/sys v0.12.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
|
55
go.sum
55
go.sum
@ -42,6 +42,7 @@ entgo.io/ent v0.12.4 h1:LddPnAyxls/O7DTXZvUGDj0NZIdGSu317+aoNLJWbD8=
|
||||
entgo.io/ent v0.12.4/go.mod h1:Y3JVAjtlIk8xVZYSn3t3mf8xlZIn5SAOXZQxD6kKI+Q=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||
github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8=
|
||||
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
|
||||
@ -63,12 +64,15 @@ github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnht
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
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 h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
||||
@ -82,6 +86,7 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4=
|
||||
github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
@ -90,9 +95,12 @@ github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg
|
||||
github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
||||
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
@ -131,9 +139,8 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
@ -163,8 +170,6 @@ github.com/hashicorp/hcl/v2 v2.13.0 h1:0Apadu1w6M11dyGFxWnmhhcMjkbAiKCv7G1r/2QgC
|
||||
github.com/hashicorp/hcl/v2 v2.13.0/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
@ -175,8 +180,11 @@ github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZX
|
||||
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
@ -186,8 +194,7 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
|
||||
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
@ -197,17 +204,16 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
|
||||
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
|
||||
github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
@ -215,14 +221,13 @@ github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9c
|
||||
github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U=
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
||||
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||
github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY=
|
||||
github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
|
||||
github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
|
||||
github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
|
||||
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI=
|
||||
@ -238,7 +243,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
@ -246,6 +251,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
|
||||
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
@ -272,8 +279,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@ -311,8 +316,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
|
||||
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -345,8 +350,6 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@ -407,10 +410,6 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
@ -420,12 +419,9 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@ -478,8 +474,6 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.8.1-0.20230428195545-5283a0178901 h1:0wxTF6pSjIIhNt7mo9GvjDfzyCOiWhmICgtO/Ah948s=
|
||||
golang.org/x/tools v0.8.1-0.20230428195545-5283a0178901/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@ -573,12 +567,11 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
|
10
main.go
10
main.go
@ -1,14 +1,14 @@
|
||||
package online_order
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
handler_products "online-order/api/handlers/products"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
logger "github.com/rs/zerolog/log"
|
||||
|
||||
"online-order/api/middlewares"
|
||||
"online-order/configs"
|
||||
"online-order/ent/migrate"
|
||||
"online-order/entity"
|
||||
@ -51,10 +51,10 @@ func main() {
|
||||
RestrictedApp: api_restricted,
|
||||
}
|
||||
|
||||
middlewareController := middlewares.NewMiddlewareRouters(router)
|
||||
api_restricted.Use(middlewareController.JwAuthtMiddleware())
|
||||
//middlewareController := middlewares.NewMiddlewareRouters(router)
|
||||
//api_restricted.Use(middlewareController.JwAuthtMiddleware())
|
||||
|
||||
handler_users.NewUserRouters(router)
|
||||
handler_products.NewProductRouters(router)
|
||||
|
||||
logger.Info().Msg("Server ready to go ...")
|
||||
app.Run(conf.ServerPort)
|
||||
|
142
repository/product/product.go
Normal file
142
repository/product/product.go
Normal file
@ -0,0 +1,142 @@
|
||||
package repository_product
|
||||
|
||||
import (
|
||||
"context"
|
||||
"online-order/ent"
|
||||
"online-order/ent/product"
|
||||
"online-order/entity"
|
||||
)
|
||||
|
||||
type ProductClient struct {
|
||||
client *ent.Client
|
||||
}
|
||||
|
||||
func NewProductClient(client *ent.Client) *ProductClient {
|
||||
return &ProductClient{
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
// List all products
|
||||
func (c *ProductClient) List() ([]*entity.ProductDisplay, error) {
|
||||
var u []*entity.ProductDisplay
|
||||
ctx := context.Background()
|
||||
|
||||
err := c.client.Product.
|
||||
Query().
|
||||
Select(product.FieldID, product.FieldName, product.FieldDescription, product.FieldOriginalPrice, product.FieldPrice, product.FieldQuantity, product.FieldStatus, product.FieldCreatedAt, product.FieldUpdatedAt).
|
||||
Scan(ctx, &u)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return u, nil
|
||||
}
|
||||
|
||||
// Create a product
|
||||
func (c *ProductClient) Create(p *entity.ProductCreateUpdate) error {
|
||||
ctx := context.Background()
|
||||
|
||||
resp, err := c.client.Product.
|
||||
Create().
|
||||
SetName(p.Name).
|
||||
SetNillableDescription(p.Description).
|
||||
SetPrice(p.Price).
|
||||
SetOriginalPrice(p.OriginalPrice).
|
||||
SetQuantity(p.Quantity).
|
||||
SetStatus(p.Status).
|
||||
Save(ctx)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p.ID = resp.ID
|
||||
p.CreatedAt = resp.CreatedAt
|
||||
p.UpdatedAt = resp.UpdatedAt
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ProductClient) GetByID(id int) (*entity.ProductDisplay, error) {
|
||||
var p entity.ProductDisplay
|
||||
ctx := context.Background()
|
||||
|
||||
resp := c.client.Product.
|
||||
Query().
|
||||
Where(product.ID(id)).
|
||||
AllX(ctx)
|
||||
|
||||
if len(resp) > 0 {
|
||||
p.ID = resp[0].ID
|
||||
p.Name = resp[0].Name
|
||||
p.Description = resp[0].Description
|
||||
p.Status = resp[0].Status
|
||||
p.Quantity = resp[0].Quantity
|
||||
p.Price = resp[0].Price
|
||||
p.OriginalPrice = resp[0].OriginalPrice
|
||||
p.CreatedAt = resp[0].CreatedAt
|
||||
p.UpdatedAt = resp[0].UpdatedAt
|
||||
} else {
|
||||
return nil, entity.ErrNotFound
|
||||
}
|
||||
|
||||
return &p, nil
|
||||
}
|
||||
|
||||
// Update product information, except password
|
||||
func (c *ProductClient) Update(p *entity.ProductCreateUpdate) error {
|
||||
ctx := context.Background()
|
||||
|
||||
_, err := c.client.Product.UpdateOneID(p.ID).
|
||||
SetName(p.Name).
|
||||
SetDescription(p.Name).
|
||||
SetPrice(p.Price).
|
||||
SetOriginalPrice(p.OriginalPrice).
|
||||
SetQuantity(p.Quantity).
|
||||
SetStatus(p.Status).
|
||||
Save(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Update user information, except password
|
||||
func (c *ProductClient) Delete(id int) error {
|
||||
ctx := context.Background()
|
||||
|
||||
err := c.client.Product.DeleteOneID(id).
|
||||
Exec(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// Search a user information by email or username
|
||||
func (c *ProductClient) SearchProduct(identifier string) (*entity.ProductDisplay, error) {
|
||||
var p entity.ProductDisplay
|
||||
ctx := context.Background()
|
||||
|
||||
resp := c.client.Product.
|
||||
Query().
|
||||
Where(
|
||||
product.NameContains(identifier),
|
||||
).
|
||||
AllX(ctx)
|
||||
|
||||
if len(resp) > 0 {
|
||||
p.ID = resp[0].ID
|
||||
p.Name = resp[0].Name
|
||||
p.Description = resp[0].Description
|
||||
p.Status = resp[0].Status
|
||||
p.Quantity = resp[0].Quantity
|
||||
p.Price = resp[0].Price
|
||||
p.OriginalPrice = resp[0].OriginalPrice
|
||||
p.CreatedAt = resp[0].CreatedAt
|
||||
p.UpdatedAt = resp[0].UpdatedAt
|
||||
|
||||
} else {
|
||||
return nil, entity.ErrNotFound
|
||||
}
|
||||
|
||||
return &p, nil
|
||||
}
|
45
usecase/product/service.go
Normal file
45
usecase/product/service.go
Normal file
@ -0,0 +1,45 @@
|
||||
package service_product
|
||||
|
||||
import (
|
||||
"online-order/domain"
|
||||
"online-order/entity"
|
||||
)
|
||||
|
||||
type productservice struct {
|
||||
repo domain.ProductRepository
|
||||
}
|
||||
|
||||
func NewProductService(r domain.ProductRepository) *productservice {
|
||||
return &productservice{
|
||||
repo: r,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *productservice) List() ([]*entity.ProductDisplay, error) {
|
||||
return s.repo.List()
|
||||
}
|
||||
|
||||
func (s *productservice) Create(u *entity.ProductCreateUpdate) error {
|
||||
return s.repo.Create(u)
|
||||
}
|
||||
|
||||
// Retrieve a product
|
||||
func (s *productservice) GetByID(id int) (*entity.ProductDisplay, error) {
|
||||
u, err := s.repo.GetByID(id)
|
||||
if err != nil {
|
||||
return &entity.ProductDisplay{}, entity.ErrNotFound
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func (s *productservice) Update(u *entity.ProductCreateUpdate) error {
|
||||
return s.repo.Update(u)
|
||||
}
|
||||
|
||||
func (s *productservice) SearchProduct(identifier string) (*entity.ProductDisplay, error) {
|
||||
return s.repo.SearchProduct(identifier)
|
||||
}
|
||||
|
||||
func (s *productservice) Delete(id int) error {
|
||||
return s.repo.Delete(id)
|
||||
}
|
@ -4,8 +4,8 @@ import (
|
||||
"errors"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/louistwiice/go/basicwithent/entity"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"online-order/entity"
|
||||
)
|
||||
|
||||
type Response struct {
|
||||
@ -39,7 +39,7 @@ func HashString(password string) (string, error) {
|
||||
func CheckHashedString(plain_word, hashed_word string) error {
|
||||
err := bcrypt.CompareHashAndPassword([]byte(hashed_word), []byte(plain_word))
|
||||
|
||||
if err == bcrypt.ErrMismatchedHashAndPassword {
|
||||
if err == bcrypt.ErrMismatchedHashAndPassword {
|
||||
return errors.New("incorrect password associated with identifier")
|
||||
}
|
||||
return err
|
||||
|
@ -7,15 +7,15 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/louistwiice/go/basicwithent/configs"
|
||||
"online-order/configs"
|
||||
)
|
||||
|
||||
// GenerateToken generates token when user connects himself
|
||||
func GenerateToken(user_id string) (map[string]string, error) {
|
||||
accessclaims := make(jwt.MapClaims) // access token claim
|
||||
refreshclaims := make(jwt.MapClaims) //refresh token claim
|
||||
refreshclaims := make(jwt.MapClaims) //refresh token claim
|
||||
now_time := time.Now().UTC()
|
||||
conf := configs.LoadConfigEnv()//LoadConfigEnv() //Load .env settings
|
||||
conf := configs.LoadConfigEnv() //LoadConfigEnv() //Load .env settings
|
||||
|
||||
// Generate access token
|
||||
accessclaims["authorized"] = true
|
||||
@ -50,7 +50,7 @@ func GenerateToken(user_id string) (map[string]string, error) {
|
||||
// ExtractToken retrieves the token send by the user in every request
|
||||
func ExtractToken(ctx *gin.Context) string {
|
||||
conf := configs.LoadConfigEnv()
|
||||
|
||||
|
||||
bearerToken := ctx.Request.Header.Get("Authorization")
|
||||
// If the token doesn not start with a good prefix: like Bearer, Token, ..., we return empty string
|
||||
if !strings.HasPrefix(bearerToken, conf.TokenPrefix) {
|
||||
@ -68,7 +68,7 @@ func IsTokenValid(ctx *gin.Context) (string, error) {
|
||||
tokenString := ExtractToken(ctx)
|
||||
conf := configs.LoadConfigEnv()
|
||||
|
||||
token , err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
||||
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
@ -89,7 +89,7 @@ func ExtractClaimsFromAccess(ctx *gin.Context) (jwt.MapClaims, error) {
|
||||
tokenString := ExtractToken(ctx)
|
||||
conf := configs.LoadConfigEnv()
|
||||
|
||||
token , err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
||||
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
@ -115,7 +115,7 @@ func ExtractClaimsFromAccess(ctx *gin.Context) (jwt.MapClaims, error) {
|
||||
func ExtractClaimsFromRefresh(refresh_string string) (jwt.MapClaims, error) {
|
||||
conf := configs.LoadConfigEnv()
|
||||
|
||||
token , err := jwt.Parse(refresh_string, func(token *jwt.Token) (interface{}, error) {
|
||||
token, err := jwt.Parse(refresh_string, func(token *jwt.Token) (interface{}, error) {
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
@ -141,7 +141,7 @@ func ExtractClaimsFromRefresh(refresh_string string) (jwt.MapClaims, error) {
|
||||
func RefreshToken(ctx *gin.Context, refresh_string string) (map[string]string, error) {
|
||||
conf := configs.LoadConfigEnv()
|
||||
|
||||
rtoken , err := jwt.Parse(refresh_string, func(token *jwt.Token) (interface{}, error) {
|
||||
rtoken, err := jwt.Parse(refresh_string, func(token *jwt.Token) (interface{}, error) {
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
@ -155,4 +155,4 @@ func RefreshToken(ctx *gin.Context, refresh_string string) (map[string]string, e
|
||||
return GenerateToken(refreshClaim["sub"].(string))
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user