v0.0.469
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 3m26s
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 3m26s
This commit is contained in:
parent
fc5803493c
commit
2504ef00a0
@ -1,13 +1,8 @@
|
||||
package ginext
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/exerr"
|
||||
json "gogs.mikescher.com/BlackForestBytes/goext/gojson"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
"os"
|
||||
)
|
||||
|
||||
type cookieval struct {
|
||||
@ -41,464 +36,6 @@ type InspectableHTTPResponse interface {
|
||||
Headers() []string
|
||||
}
|
||||
|
||||
type jsonHTTPResponse struct {
|
||||
statusCode int
|
||||
data any
|
||||
headers []headerval
|
||||
cookies []cookieval
|
||||
}
|
||||
|
||||
func (j jsonHTTPResponse) jsonRenderer(g *gin.Context) json.GoJsonRender {
|
||||
var f *string
|
||||
if jsonfilter := g.GetString("goext.jsonfilter"); jsonfilter != "" {
|
||||
f = &jsonfilter
|
||||
}
|
||||
return json.GoJsonRender{Data: j.data, NilSafeSlices: true, NilSafeMaps: true, Filter: f}
|
||||
}
|
||||
|
||||
func (j jsonHTTPResponse) Write(g *gin.Context) {
|
||||
for _, v := range j.headers {
|
||||
g.Header(v.Key, v.Val)
|
||||
}
|
||||
for _, v := range j.cookies {
|
||||
g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly)
|
||||
}
|
||||
g.Render(j.statusCode, j.jsonRenderer(g))
|
||||
}
|
||||
|
||||
func (j jsonHTTPResponse) WithHeader(k string, v string) HTTPResponse {
|
||||
j.headers = append(j.headers, headerval{k, v})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j jsonHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse {
|
||||
j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j jsonHTTPResponse) IsSuccess() bool {
|
||||
return j.statusCode >= 200 && j.statusCode <= 399
|
||||
}
|
||||
|
||||
func (j jsonHTTPResponse) Statuscode() int {
|
||||
return j.statusCode
|
||||
}
|
||||
|
||||
func (j jsonHTTPResponse) BodyString(g *gin.Context) *string {
|
||||
if str, err := j.jsonRenderer(g).RenderString(); err == nil {
|
||||
return &str
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (j jsonHTTPResponse) ContentType() string {
|
||||
return "application/json"
|
||||
}
|
||||
|
||||
func (j jsonHTTPResponse) Headers() []string {
|
||||
return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val })
|
||||
}
|
||||
|
||||
type emptyHTTPResponse struct {
|
||||
statusCode int
|
||||
headers []headerval
|
||||
cookies []cookieval
|
||||
}
|
||||
|
||||
func (j emptyHTTPResponse) Write(g *gin.Context) {
|
||||
for _, v := range j.headers {
|
||||
g.Header(v.Key, v.Val)
|
||||
}
|
||||
for _, v := range j.cookies {
|
||||
g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly)
|
||||
}
|
||||
g.Status(j.statusCode)
|
||||
}
|
||||
|
||||
func (j emptyHTTPResponse) WithHeader(k string, v string) HTTPResponse {
|
||||
j.headers = append(j.headers, headerval{k, v})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j emptyHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse {
|
||||
j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j emptyHTTPResponse) IsSuccess() bool {
|
||||
return j.statusCode >= 200 && j.statusCode <= 399
|
||||
}
|
||||
|
||||
func (j emptyHTTPResponse) Statuscode() int {
|
||||
return j.statusCode
|
||||
}
|
||||
|
||||
func (j emptyHTTPResponse) BodyString(*gin.Context) *string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (j emptyHTTPResponse) ContentType() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (j emptyHTTPResponse) Headers() []string {
|
||||
return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val })
|
||||
}
|
||||
|
||||
type textHTTPResponse struct {
|
||||
statusCode int
|
||||
data string
|
||||
headers []headerval
|
||||
cookies []cookieval
|
||||
}
|
||||
|
||||
func (j textHTTPResponse) Write(g *gin.Context) {
|
||||
for _, v := range j.headers {
|
||||
g.Header(v.Key, v.Val)
|
||||
}
|
||||
for _, v := range j.cookies {
|
||||
g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly)
|
||||
}
|
||||
g.String(j.statusCode, "%s", j.data)
|
||||
}
|
||||
|
||||
func (j textHTTPResponse) WithHeader(k string, v string) HTTPResponse {
|
||||
j.headers = append(j.headers, headerval{k, v})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j textHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse {
|
||||
j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j textHTTPResponse) IsSuccess() bool {
|
||||
return j.statusCode >= 200 && j.statusCode <= 399
|
||||
}
|
||||
|
||||
func (j textHTTPResponse) Statuscode() int {
|
||||
return j.statusCode
|
||||
}
|
||||
|
||||
func (j textHTTPResponse) BodyString(*gin.Context) *string {
|
||||
return langext.Ptr(j.data)
|
||||
}
|
||||
|
||||
func (j textHTTPResponse) ContentType() string {
|
||||
return "text/plain"
|
||||
}
|
||||
|
||||
func (j textHTTPResponse) Headers() []string {
|
||||
return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val })
|
||||
}
|
||||
|
||||
type dataHTTPResponse struct {
|
||||
statusCode int
|
||||
data []byte
|
||||
contentType string
|
||||
headers []headerval
|
||||
cookies []cookieval
|
||||
}
|
||||
|
||||
func (j dataHTTPResponse) Write(g *gin.Context) {
|
||||
for _, v := range j.headers {
|
||||
g.Header(v.Key, v.Val)
|
||||
}
|
||||
for _, v := range j.cookies {
|
||||
g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly)
|
||||
}
|
||||
g.Data(j.statusCode, j.contentType, j.data)
|
||||
}
|
||||
|
||||
func (j dataHTTPResponse) WithHeader(k string, v string) HTTPResponse {
|
||||
j.headers = append(j.headers, headerval{k, v})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j dataHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse {
|
||||
j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j dataHTTPResponse) IsSuccess() bool {
|
||||
return j.statusCode >= 200 && j.statusCode <= 399
|
||||
}
|
||||
|
||||
func (j dataHTTPResponse) Statuscode() int {
|
||||
return j.statusCode
|
||||
}
|
||||
|
||||
func (j dataHTTPResponse) BodyString(*gin.Context) *string {
|
||||
return langext.Ptr(string(j.data))
|
||||
}
|
||||
|
||||
func (j dataHTTPResponse) ContentType() string {
|
||||
return j.contentType
|
||||
}
|
||||
|
||||
func (j dataHTTPResponse) Headers() []string {
|
||||
return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val })
|
||||
}
|
||||
|
||||
type fileHTTPResponse struct {
|
||||
mimetype string
|
||||
filepath string
|
||||
filename *string
|
||||
headers []headerval
|
||||
cookies []cookieval
|
||||
}
|
||||
|
||||
func (j fileHTTPResponse) Write(g *gin.Context) {
|
||||
g.Header("Content-Type", j.mimetype) // if we don't set it here gin does weird file-sniffing later...
|
||||
if j.filename != nil {
|
||||
g.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", *j.filename))
|
||||
|
||||
}
|
||||
for _, v := range j.headers {
|
||||
g.Header(v.Key, v.Val)
|
||||
}
|
||||
for _, v := range j.cookies {
|
||||
g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly)
|
||||
}
|
||||
g.File(j.filepath)
|
||||
}
|
||||
|
||||
func (j fileHTTPResponse) WithHeader(k string, v string) HTTPResponse {
|
||||
j.headers = append(j.headers, headerval{k, v})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j fileHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse {
|
||||
j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j fileHTTPResponse) IsSuccess() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (j fileHTTPResponse) Statuscode() int {
|
||||
return 200
|
||||
}
|
||||
|
||||
func (j fileHTTPResponse) BodyString(*gin.Context) *string {
|
||||
data, err := os.ReadFile(j.filepath)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return langext.Ptr(string(data))
|
||||
}
|
||||
|
||||
func (j fileHTTPResponse) ContentType() string {
|
||||
return j.mimetype
|
||||
}
|
||||
|
||||
func (j fileHTTPResponse) Headers() []string {
|
||||
return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val })
|
||||
}
|
||||
|
||||
type downloadDataHTTPResponse struct {
|
||||
statusCode int
|
||||
mimetype string
|
||||
data []byte
|
||||
filename *string
|
||||
headers []headerval
|
||||
cookies []cookieval
|
||||
}
|
||||
|
||||
func (j downloadDataHTTPResponse) Write(g *gin.Context) {
|
||||
g.Header("Content-Type", j.mimetype) // if we don't set it here gin does weird file-sniffing later...
|
||||
if j.filename != nil {
|
||||
g.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", *j.filename))
|
||||
}
|
||||
for _, v := range j.headers {
|
||||
g.Header(v.Key, v.Val)
|
||||
}
|
||||
for _, v := range j.cookies {
|
||||
g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly)
|
||||
}
|
||||
g.Data(j.statusCode, j.mimetype, j.data)
|
||||
}
|
||||
|
||||
func (j downloadDataHTTPResponse) WithHeader(k string, v string) HTTPResponse {
|
||||
j.headers = append(j.headers, headerval{k, v})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j downloadDataHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse {
|
||||
j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j downloadDataHTTPResponse) IsSuccess() bool {
|
||||
return j.statusCode >= 200 && j.statusCode <= 399
|
||||
}
|
||||
|
||||
func (j downloadDataHTTPResponse) Statuscode() int {
|
||||
return j.statusCode
|
||||
}
|
||||
|
||||
func (j downloadDataHTTPResponse) BodyString(*gin.Context) *string {
|
||||
return langext.Ptr(string(j.data))
|
||||
}
|
||||
|
||||
func (j downloadDataHTTPResponse) ContentType() string {
|
||||
return j.mimetype
|
||||
}
|
||||
|
||||
func (j downloadDataHTTPResponse) Headers() []string {
|
||||
return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val })
|
||||
}
|
||||
|
||||
type redirectHTTPResponse struct {
|
||||
statusCode int
|
||||
url string
|
||||
headers []headerval
|
||||
cookies []cookieval
|
||||
}
|
||||
|
||||
func (j redirectHTTPResponse) Write(g *gin.Context) {
|
||||
for _, v := range j.headers {
|
||||
g.Header(v.Key, v.Val)
|
||||
}
|
||||
for _, v := range j.cookies {
|
||||
g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly)
|
||||
}
|
||||
g.Redirect(j.statusCode, j.url)
|
||||
}
|
||||
|
||||
func (j redirectHTTPResponse) WithHeader(k string, v string) HTTPResponse {
|
||||
j.headers = append(j.headers, headerval{k, v})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j redirectHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse {
|
||||
j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j redirectHTTPResponse) IsSuccess() bool {
|
||||
return j.statusCode >= 200 && j.statusCode <= 399
|
||||
}
|
||||
|
||||
func (j redirectHTTPResponse) Statuscode() int {
|
||||
return j.statusCode
|
||||
}
|
||||
|
||||
func (j redirectHTTPResponse) BodyString(*gin.Context) *string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (j redirectHTTPResponse) ContentType() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (j redirectHTTPResponse) Headers() []string {
|
||||
return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val })
|
||||
}
|
||||
|
||||
type jsonAPIErrResponse struct {
|
||||
err *exerr.ExErr
|
||||
headers []headerval
|
||||
cookies []cookieval
|
||||
}
|
||||
|
||||
func (j jsonAPIErrResponse) Write(g *gin.Context) {
|
||||
for _, v := range j.headers {
|
||||
g.Header(v.Key, v.Val)
|
||||
}
|
||||
for _, v := range j.cookies {
|
||||
g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly)
|
||||
}
|
||||
|
||||
exerr.Get(j.err).Output(context.Background(), g)
|
||||
|
||||
j.err.CallListener(exerr.MethodOutput)
|
||||
}
|
||||
|
||||
func (j jsonAPIErrResponse) WithHeader(k string, v string) HTTPResponse {
|
||||
j.headers = append(j.headers, headerval{k, v})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j jsonAPIErrResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse {
|
||||
j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j jsonAPIErrResponse) IsSuccess() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (j jsonAPIErrResponse) Statuscode() int {
|
||||
return langext.Coalesce(j.err.RecursiveStatuscode(), 0)
|
||||
}
|
||||
|
||||
func (j jsonAPIErrResponse) BodyString(*gin.Context) *string {
|
||||
if str, err := j.err.ToDefaultAPIJson(); err == nil {
|
||||
return &str
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (j jsonAPIErrResponse) ContentType() string {
|
||||
return "application/json"
|
||||
}
|
||||
|
||||
func (j jsonAPIErrResponse) Headers() []string {
|
||||
return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val })
|
||||
}
|
||||
|
||||
func (j jsonAPIErrResponse) Unwrap() error {
|
||||
return j.err
|
||||
}
|
||||
|
||||
func Status(sc int) HTTPResponse {
|
||||
return &emptyHTTPResponse{statusCode: sc}
|
||||
}
|
||||
|
||||
func JSON(sc int, data any) HTTPResponse {
|
||||
return &jsonHTTPResponse{statusCode: sc, data: data}
|
||||
}
|
||||
|
||||
func Data(sc int, contentType string, data []byte) HTTPResponse {
|
||||
return &dataHTTPResponse{statusCode: sc, contentType: contentType, data: data}
|
||||
}
|
||||
|
||||
func Text(sc int, data string) HTTPResponse {
|
||||
return &textHTTPResponse{statusCode: sc, data: data}
|
||||
}
|
||||
|
||||
func File(mimetype string, filepath string) HTTPResponse {
|
||||
return &fileHTTPResponse{mimetype: mimetype, filepath: filepath}
|
||||
}
|
||||
|
||||
func Download(mimetype string, filepath string, filename string) HTTPResponse {
|
||||
return &fileHTTPResponse{mimetype: mimetype, filepath: filepath, filename: &filename}
|
||||
}
|
||||
|
||||
func DownloadData(status int, mimetype string, filename string, data []byte) HTTPResponse {
|
||||
return &downloadDataHTTPResponse{statusCode: status, mimetype: mimetype, data: data, filename: &filename}
|
||||
}
|
||||
|
||||
func Redirect(sc int, newURL string) HTTPResponse {
|
||||
return &redirectHTTPResponse{statusCode: sc, url: newURL}
|
||||
}
|
||||
|
||||
func Error(e error) HTTPResponse {
|
||||
return &jsonAPIErrResponse{
|
||||
err: exerr.FromError(e),
|
||||
}
|
||||
}
|
||||
|
||||
func ErrWrap(e error, errorType exerr.ErrorType, msg string) HTTPResponse {
|
||||
return &jsonAPIErrResponse{
|
||||
err: exerr.FromError(exerr.Wrap(e, msg).WithType(errorType).Build()),
|
||||
}
|
||||
}
|
||||
|
||||
func NotImplemented() HTTPResponse {
|
||||
return Error(exerr.New(exerr.TypeNotImplemented, "").Build())
|
||||
}
|
||||
|
58
ginext/responseData.go
Normal file
58
ginext/responseData.go
Normal file
@ -0,0 +1,58 @@
|
||||
package ginext
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
)
|
||||
|
||||
type dataHTTPResponse struct {
|
||||
statusCode int
|
||||
data []byte
|
||||
contentType string
|
||||
headers []headerval
|
||||
cookies []cookieval
|
||||
}
|
||||
|
||||
func (j dataHTTPResponse) Write(g *gin.Context) {
|
||||
for _, v := range j.headers {
|
||||
g.Header(v.Key, v.Val)
|
||||
}
|
||||
for _, v := range j.cookies {
|
||||
g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly)
|
||||
}
|
||||
g.Data(j.statusCode, j.contentType, j.data)
|
||||
}
|
||||
|
||||
func (j dataHTTPResponse) WithHeader(k string, v string) HTTPResponse {
|
||||
j.headers = append(j.headers, headerval{k, v})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j dataHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse {
|
||||
j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j dataHTTPResponse) IsSuccess() bool {
|
||||
return j.statusCode >= 200 && j.statusCode <= 399
|
||||
}
|
||||
|
||||
func (j dataHTTPResponse) Statuscode() int {
|
||||
return j.statusCode
|
||||
}
|
||||
|
||||
func (j dataHTTPResponse) BodyString(*gin.Context) *string {
|
||||
return langext.Ptr(string(j.data))
|
||||
}
|
||||
|
||||
func (j dataHTTPResponse) ContentType() string {
|
||||
return j.contentType
|
||||
}
|
||||
|
||||
func (j dataHTTPResponse) Headers() []string {
|
||||
return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val })
|
||||
}
|
||||
|
||||
func Data(sc int, contentType string, data []byte) HTTPResponse {
|
||||
return &dataHTTPResponse{statusCode: sc, contentType: contentType, data: data}
|
||||
}
|
64
ginext/responseDownload.go
Normal file
64
ginext/responseDownload.go
Normal file
@ -0,0 +1,64 @@
|
||||
package ginext
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
)
|
||||
|
||||
type downloadDataHTTPResponse struct {
|
||||
statusCode int
|
||||
mimetype string
|
||||
data []byte
|
||||
filename *string
|
||||
headers []headerval
|
||||
cookies []cookieval
|
||||
}
|
||||
|
||||
func (j downloadDataHTTPResponse) Write(g *gin.Context) {
|
||||
g.Header("Content-Type", j.mimetype) // if we don't set it here gin does weird file-sniffing later...
|
||||
if j.filename != nil {
|
||||
g.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", *j.filename))
|
||||
}
|
||||
for _, v := range j.headers {
|
||||
g.Header(v.Key, v.Val)
|
||||
}
|
||||
for _, v := range j.cookies {
|
||||
g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly)
|
||||
}
|
||||
g.Data(j.statusCode, j.mimetype, j.data)
|
||||
}
|
||||
|
||||
func (j downloadDataHTTPResponse) WithHeader(k string, v string) HTTPResponse {
|
||||
j.headers = append(j.headers, headerval{k, v})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j downloadDataHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse {
|
||||
j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j downloadDataHTTPResponse) IsSuccess() bool {
|
||||
return j.statusCode >= 200 && j.statusCode <= 399
|
||||
}
|
||||
|
||||
func (j downloadDataHTTPResponse) Statuscode() int {
|
||||
return j.statusCode
|
||||
}
|
||||
|
||||
func (j downloadDataHTTPResponse) BodyString(*gin.Context) *string {
|
||||
return langext.Ptr(string(j.data))
|
||||
}
|
||||
|
||||
func (j downloadDataHTTPResponse) ContentType() string {
|
||||
return j.mimetype
|
||||
}
|
||||
|
||||
func (j downloadDataHTTPResponse) Headers() []string {
|
||||
return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val })
|
||||
}
|
||||
|
||||
func DownloadData(status int, mimetype string, filename string, data []byte) HTTPResponse {
|
||||
return &downloadDataHTTPResponse{statusCode: status, mimetype: mimetype, data: data, filename: &filename}
|
||||
}
|
56
ginext/responseEmpty.go
Normal file
56
ginext/responseEmpty.go
Normal file
@ -0,0 +1,56 @@
|
||||
package ginext
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
)
|
||||
|
||||
type emptyHTTPResponse struct {
|
||||
statusCode int
|
||||
headers []headerval
|
||||
cookies []cookieval
|
||||
}
|
||||
|
||||
func (j emptyHTTPResponse) Write(g *gin.Context) {
|
||||
for _, v := range j.headers {
|
||||
g.Header(v.Key, v.Val)
|
||||
}
|
||||
for _, v := range j.cookies {
|
||||
g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly)
|
||||
}
|
||||
g.Status(j.statusCode)
|
||||
}
|
||||
|
||||
func (j emptyHTTPResponse) WithHeader(k string, v string) HTTPResponse {
|
||||
j.headers = append(j.headers, headerval{k, v})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j emptyHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse {
|
||||
j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j emptyHTTPResponse) IsSuccess() bool {
|
||||
return j.statusCode >= 200 && j.statusCode <= 399
|
||||
}
|
||||
|
||||
func (j emptyHTTPResponse) Statuscode() int {
|
||||
return j.statusCode
|
||||
}
|
||||
|
||||
func (j emptyHTTPResponse) BodyString(*gin.Context) *string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (j emptyHTTPResponse) ContentType() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (j emptyHTTPResponse) Headers() []string {
|
||||
return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val })
|
||||
}
|
||||
|
||||
func Status(sc int) HTTPResponse {
|
||||
return &emptyHTTPResponse{statusCode: sc}
|
||||
}
|
73
ginext/responseFile.go
Normal file
73
ginext/responseFile.go
Normal file
@ -0,0 +1,73 @@
|
||||
package ginext
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
"os"
|
||||
)
|
||||
|
||||
type fileHTTPResponse struct {
|
||||
mimetype string
|
||||
filepath string
|
||||
filename *string
|
||||
headers []headerval
|
||||
cookies []cookieval
|
||||
}
|
||||
|
||||
func (j fileHTTPResponse) Write(g *gin.Context) {
|
||||
g.Header("Content-Type", j.mimetype) // if we don't set it here gin does weird file-sniffing later...
|
||||
if j.filename != nil {
|
||||
g.Header("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", *j.filename))
|
||||
|
||||
}
|
||||
for _, v := range j.headers {
|
||||
g.Header(v.Key, v.Val)
|
||||
}
|
||||
for _, v := range j.cookies {
|
||||
g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly)
|
||||
}
|
||||
g.File(j.filepath)
|
||||
}
|
||||
|
||||
func (j fileHTTPResponse) WithHeader(k string, v string) HTTPResponse {
|
||||
j.headers = append(j.headers, headerval{k, v})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j fileHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse {
|
||||
j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j fileHTTPResponse) IsSuccess() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (j fileHTTPResponse) Statuscode() int {
|
||||
return 200
|
||||
}
|
||||
|
||||
func (j fileHTTPResponse) BodyString(*gin.Context) *string {
|
||||
data, err := os.ReadFile(j.filepath)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return langext.Ptr(string(data))
|
||||
}
|
||||
|
||||
func (j fileHTTPResponse) ContentType() string {
|
||||
return j.mimetype
|
||||
}
|
||||
|
||||
func (j fileHTTPResponse) Headers() []string {
|
||||
return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val })
|
||||
}
|
||||
|
||||
func File(mimetype string, filepath string) HTTPResponse {
|
||||
return &fileHTTPResponse{mimetype: mimetype, filepath: filepath}
|
||||
}
|
||||
|
||||
func Download(mimetype string, filepath string, filename string) HTTPResponse {
|
||||
return &fileHTTPResponse{mimetype: mimetype, filepath: filepath, filename: &filename}
|
||||
}
|
70
ginext/responseJson.go
Normal file
70
ginext/responseJson.go
Normal file
@ -0,0 +1,70 @@
|
||||
package ginext
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
json "gogs.mikescher.com/BlackForestBytes/goext/gojson"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
)
|
||||
|
||||
type jsonHTTPResponse struct {
|
||||
statusCode int
|
||||
data any
|
||||
headers []headerval
|
||||
cookies []cookieval
|
||||
}
|
||||
|
||||
func (j jsonHTTPResponse) jsonRenderer(g *gin.Context) json.GoJsonRender {
|
||||
var f *string
|
||||
if jsonfilter := g.GetString("goext.jsonfilter"); jsonfilter != "" {
|
||||
f = &jsonfilter
|
||||
}
|
||||
return json.GoJsonRender{Data: j.data, NilSafeSlices: true, NilSafeMaps: true, Filter: f}
|
||||
}
|
||||
|
||||
func (j jsonHTTPResponse) Write(g *gin.Context) {
|
||||
for _, v := range j.headers {
|
||||
g.Header(v.Key, v.Val)
|
||||
}
|
||||
for _, v := range j.cookies {
|
||||
g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly)
|
||||
}
|
||||
g.Render(j.statusCode, j.jsonRenderer(g))
|
||||
}
|
||||
|
||||
func (j jsonHTTPResponse) WithHeader(k string, v string) HTTPResponse {
|
||||
j.headers = append(j.headers, headerval{k, v})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j jsonHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse {
|
||||
j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j jsonHTTPResponse) IsSuccess() bool {
|
||||
return j.statusCode >= 200 && j.statusCode <= 399
|
||||
}
|
||||
|
||||
func (j jsonHTTPResponse) Statuscode() int {
|
||||
return j.statusCode
|
||||
}
|
||||
|
||||
func (j jsonHTTPResponse) BodyString(g *gin.Context) *string {
|
||||
if str, err := j.jsonRenderer(g).RenderString(); err == nil {
|
||||
return &str
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (j jsonHTTPResponse) ContentType() string {
|
||||
return "application/json"
|
||||
}
|
||||
|
||||
func (j jsonHTTPResponse) Headers() []string {
|
||||
return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val })
|
||||
}
|
||||
|
||||
func JSON(sc int, data any) HTTPResponse {
|
||||
return &jsonHTTPResponse{statusCode: sc, data: data}
|
||||
}
|
77
ginext/responseJsonAPI.go
Normal file
77
ginext/responseJsonAPI.go
Normal file
@ -0,0 +1,77 @@
|
||||
package ginext
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/exerr"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
)
|
||||
|
||||
type jsonAPIErrResponse struct {
|
||||
err *exerr.ExErr
|
||||
headers []headerval
|
||||
cookies []cookieval
|
||||
}
|
||||
|
||||
func (j jsonAPIErrResponse) Write(g *gin.Context) {
|
||||
for _, v := range j.headers {
|
||||
g.Header(v.Key, v.Val)
|
||||
}
|
||||
for _, v := range j.cookies {
|
||||
g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly)
|
||||
}
|
||||
|
||||
exerr.Get(j.err).Output(context.Background(), g)
|
||||
|
||||
j.err.CallListener(exerr.MethodOutput)
|
||||
}
|
||||
|
||||
func (j jsonAPIErrResponse) WithHeader(k string, v string) HTTPResponse {
|
||||
j.headers = append(j.headers, headerval{k, v})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j jsonAPIErrResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse {
|
||||
j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j jsonAPIErrResponse) IsSuccess() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (j jsonAPIErrResponse) Statuscode() int {
|
||||
return langext.Coalesce(j.err.RecursiveStatuscode(), 0)
|
||||
}
|
||||
|
||||
func (j jsonAPIErrResponse) BodyString(*gin.Context) *string {
|
||||
if str, err := j.err.ToDefaultAPIJson(); err == nil {
|
||||
return &str
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (j jsonAPIErrResponse) ContentType() string {
|
||||
return "application/json"
|
||||
}
|
||||
|
||||
func (j jsonAPIErrResponse) Headers() []string {
|
||||
return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val })
|
||||
}
|
||||
|
||||
func (j jsonAPIErrResponse) Unwrap() error {
|
||||
return j.err
|
||||
}
|
||||
|
||||
func Error(e error) HTTPResponse {
|
||||
return &jsonAPIErrResponse{
|
||||
err: exerr.FromError(e),
|
||||
}
|
||||
}
|
||||
|
||||
func ErrWrap(e error, errorType exerr.ErrorType, msg string) HTTPResponse {
|
||||
return &jsonAPIErrResponse{
|
||||
err: exerr.FromError(exerr.Wrap(e, msg).WithType(errorType).Build()),
|
||||
}
|
||||
}
|
57
ginext/responseRedirect.go
Normal file
57
ginext/responseRedirect.go
Normal file
@ -0,0 +1,57 @@
|
||||
package ginext
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
)
|
||||
|
||||
type redirectHTTPResponse struct {
|
||||
statusCode int
|
||||
url string
|
||||
headers []headerval
|
||||
cookies []cookieval
|
||||
}
|
||||
|
||||
func (j redirectHTTPResponse) Write(g *gin.Context) {
|
||||
for _, v := range j.headers {
|
||||
g.Header(v.Key, v.Val)
|
||||
}
|
||||
for _, v := range j.cookies {
|
||||
g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly)
|
||||
}
|
||||
g.Redirect(j.statusCode, j.url)
|
||||
}
|
||||
|
||||
func (j redirectHTTPResponse) WithHeader(k string, v string) HTTPResponse {
|
||||
j.headers = append(j.headers, headerval{k, v})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j redirectHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse {
|
||||
j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j redirectHTTPResponse) IsSuccess() bool {
|
||||
return j.statusCode >= 200 && j.statusCode <= 399
|
||||
}
|
||||
|
||||
func (j redirectHTTPResponse) Statuscode() int {
|
||||
return j.statusCode
|
||||
}
|
||||
|
||||
func (j redirectHTTPResponse) BodyString(*gin.Context) *string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (j redirectHTTPResponse) ContentType() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (j redirectHTTPResponse) Headers() []string {
|
||||
return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val })
|
||||
}
|
||||
|
||||
func Redirect(sc int, newURL string) HTTPResponse {
|
||||
return &redirectHTTPResponse{statusCode: sc, url: newURL}
|
||||
}
|
72
ginext/responseSeekable.go
Normal file
72
ginext/responseSeekable.go
Normal file
@ -0,0 +1,72 @@
|
||||
package ginext
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/exerr"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type seekableResponse struct {
|
||||
data io.ReadSeeker
|
||||
contentType string
|
||||
filename string
|
||||
headers []headerval
|
||||
cookies []cookieval
|
||||
}
|
||||
|
||||
func (j seekableResponse) Write(g *gin.Context) {
|
||||
g.Header("Content-Type", j.contentType) // if we don't set it here http.ServeContent does weird sniffing later...
|
||||
|
||||
for _, v := range j.headers {
|
||||
g.Header(v.Key, v.Val)
|
||||
}
|
||||
for _, v := range j.cookies {
|
||||
g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly)
|
||||
}
|
||||
|
||||
http.ServeContent(g.Writer, g.Request, j.filename, time.Unix(0, 0), j.data)
|
||||
|
||||
if clsr, ok := j.data.(io.ReadSeekCloser); ok {
|
||||
err := clsr.Close()
|
||||
if err != nil {
|
||||
exerr.Wrap(err, "failed to close io.ReadSeerkClose in ginext.Seekable").Str("filename", j.filename).Print()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (j seekableResponse) WithHeader(k string, v string) HTTPResponse {
|
||||
j.headers = append(j.headers, headerval{k, v})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j seekableResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse {
|
||||
j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j seekableResponse) IsSuccess() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (j seekableResponse) Statuscode() int {
|
||||
return 200
|
||||
}
|
||||
|
||||
func (j seekableResponse) BodyString(*gin.Context) *string {
|
||||
return langext.Ptr("(seekable)")
|
||||
}
|
||||
|
||||
func (j seekableResponse) ContentType() string {
|
||||
return j.contentType
|
||||
}
|
||||
|
||||
func (j seekableResponse) Headers() []string {
|
||||
return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val })
|
||||
}
|
||||
|
||||
func Seekable(filename string, contentType string, data io.ReadSeeker) HTTPResponse {
|
||||
return &seekableResponse{filename: filename, contentType: contentType, data: data}
|
||||
}
|
57
ginext/responseText.go
Normal file
57
ginext/responseText.go
Normal file
@ -0,0 +1,57 @@
|
||||
package ginext
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
)
|
||||
|
||||
type textHTTPResponse struct {
|
||||
statusCode int
|
||||
data string
|
||||
headers []headerval
|
||||
cookies []cookieval
|
||||
}
|
||||
|
||||
func (j textHTTPResponse) Write(g *gin.Context) {
|
||||
for _, v := range j.headers {
|
||||
g.Header(v.Key, v.Val)
|
||||
}
|
||||
for _, v := range j.cookies {
|
||||
g.SetCookie(v.name, v.value, v.maxAge, v.path, v.domain, v.secure, v.httpOnly)
|
||||
}
|
||||
g.String(j.statusCode, "%s", j.data)
|
||||
}
|
||||
|
||||
func (j textHTTPResponse) WithHeader(k string, v string) HTTPResponse {
|
||||
j.headers = append(j.headers, headerval{k, v})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j textHTTPResponse) WithCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool) HTTPResponse {
|
||||
j.cookies = append(j.cookies, cookieval{name, value, maxAge, path, domain, secure, httpOnly})
|
||||
return j
|
||||
}
|
||||
|
||||
func (j textHTTPResponse) IsSuccess() bool {
|
||||
return j.statusCode >= 200 && j.statusCode <= 399
|
||||
}
|
||||
|
||||
func (j textHTTPResponse) Statuscode() int {
|
||||
return j.statusCode
|
||||
}
|
||||
|
||||
func (j textHTTPResponse) BodyString(*gin.Context) *string {
|
||||
return langext.Ptr(j.data)
|
||||
}
|
||||
|
||||
func (j textHTTPResponse) ContentType() string {
|
||||
return "text/plain"
|
||||
}
|
||||
|
||||
func (j textHTTPResponse) Headers() []string {
|
||||
return langext.ArrMap(j.headers, func(v headerval) string { return v.Key + "=" + v.Val })
|
||||
}
|
||||
|
||||
func Text(sc int, data string) HTTPResponse {
|
||||
return &textHTTPResponse{statusCode: sc, data: data}
|
||||
}
|
16
go.mod
16
go.mod
@ -9,9 +9,9 @@ require (
|
||||
github.com/rs/xid v1.5.0
|
||||
github.com/rs/zerolog v1.33.0
|
||||
go.mongodb.org/mongo-driver v1.15.0
|
||||
golang.org/x/crypto v0.23.0
|
||||
golang.org/x/sys v0.20.0
|
||||
golang.org/x/term v0.20.0
|
||||
golang.org/x/crypto v0.24.0
|
||||
golang.org/x/sys v0.21.0
|
||||
golang.org/x/term v0.21.0
|
||||
)
|
||||
|
||||
require (
|
||||
@ -38,7 +38,7 @@ require (
|
||||
github.com/google/uuid v1.5.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.17.8 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
@ -54,10 +54,10 @@ require (
|
||||
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20240424034433-3c2c7870ae76 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/image v0.16.0 // indirect
|
||||
golang.org/x/net v0.25.0 // indirect
|
||||
golang.org/x/text v0.15.0 // indirect
|
||||
google.golang.org/protobuf v1.34.1 // indirect
|
||||
golang.org/x/image v0.17.0 // indirect
|
||||
golang.org/x/net v0.26.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
modernc.org/libc v1.37.6 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
|
16
go.sum
16
go.sum
@ -125,6 +125,8 @@ github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/4
|
||||
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
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=
|
||||
@ -235,11 +237,15 @@ golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.16.0 h1:9kloLAKhUufZhA12l5fwnx2NZW39/we1UhBesW433jw=
|
||||
golang.org/x/image v0.16.0/go.mod h1:ugSZItdV4nOxyqp56HmXwH0Ry0nBCpjnZdpDaIHdoPs=
|
||||
golang.org/x/image v0.17.0 h1:nTRVVdajgB8zCMZVsViyzhnMKPwYeroEERRC64JuLco=
|
||||
golang.org/x/image v0.17.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
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=
|
||||
@ -258,6 +264,8 @@ golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
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.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
@ -285,6 +293,8 @@ golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
|
||||
@ -297,6 +307,8 @@ golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
|
||||
golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
|
||||
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
|
||||
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
|
||||
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.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
@ -307,6 +319,8 @@ golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
@ -322,6 +336,8 @@ google.golang.org/protobuf v1.34.0 h1:Qo/qEd2RZPCf2nKuorzksSknv0d3ERwp1vFG38gSmH
|
||||
google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
@ -1,5 +1,5 @@
|
||||
package goext
|
||||
|
||||
const GoextVersion = "0.0.466"
|
||||
const GoextVersion = "0.0.469"
|
||||
|
||||
const GoextVersionTimestamp = "2024-06-03T13:48:30+0200"
|
||||
const GoextVersionTimestamp = "2024-06-11T12:10:49+0200"
|
||||
|
Loading…
Reference in New Issue
Block a user