refactor(api): replace apitypes module and fix swagger generation

This commit is contained in:
yusing
2025-10-26 01:05:18 +08:00
parent 964ba1eac1
commit 6f75bb7593
41 changed files with 53 additions and 138 deletions

View File

@@ -3,8 +3,8 @@ export VERSION ?= $(shell git describe --tags --abbrev=0)
export BUILD_DATE ?= $(shell date -u +'%Y%m%d-%H%M')
export GOOS = linux
WEBUI_DIR ?= ../godoxy-frontend
DOCS_DIR ?= ../godoxy-wiki
WEBUI_DIR ?= ../godoxy-webui
DOCS_DIR ?= ${WEBUI_DIR}/wiki
LDFLAGS = -X github.com/yusing/goutils/version.version=${VERSION} -checklinkname=0
@@ -143,15 +143,17 @@ push-github:
git push origin $(shell git rev-parse --abbrev-ref HEAD)
gen-swagger:
swag init --parseDependency --parseInternal -g handler.go -d internal/api -o internal/api/v1/docs
swag init --parseDependency --parseInternal --parseFuncBody -g handler.go -d internal/api -o internal/api/v1/docs
python3 scripts/fix-swagger-json.py
# we don't need this
rm internal/api/v1/docs/docs.go
gen-swagger-markdown: gen-swagger
# brew tap go-swagger/go-swagger && brew install go-swagger
swagger generate markdown -f internal/api/v1/docs/swagger.yaml --skip-validation --output ${DOCS_DIR}/src/API.md
gen-api-types: gen-swagger
# --disable-throw-on-error
pnpx swagger-typescript-api generate --sort-types --generate-union-enums --axios --add-readonly --route-types \
bunx --bun swagger-typescript-api generate --sort-types --generate-union-enums --axios --add-readonly --route-types \
--responses -o ${WEBUI_DIR}/lib -n api.ts -p internal/api/v1/docs/swagger.json
bunx --bun prettier --config ${WEBUI_DIR}/.prettierrc --write ${WEBUI_DIR}/lib/api.ts

View File

@@ -23,7 +23,7 @@ import (
type AgentConfig struct {
Addr string `json:"addr"`
Name string `json:"name"`
Version version.Version `json:"version"`
Version version.Version `json:"version" swaggertype:"string"`
Runtime ContainerRuntime `json:"runtime"`
httpClient *http.Client

View File

@@ -8,7 +8,6 @@ import (
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
"github.com/rs/zerolog/log"
apitypes "github.com/yusing/godoxy/internal/api/types"
apiV1 "github.com/yusing/godoxy/internal/api/v1"
agentApi "github.com/yusing/godoxy/internal/api/v1/agent"
authApi "github.com/yusing/godoxy/internal/api/v1/auth"
@@ -20,6 +19,7 @@ import (
routeApi "github.com/yusing/godoxy/internal/api/v1/route"
"github.com/yusing/godoxy/internal/auth"
"github.com/yusing/godoxy/internal/common"
apitypes "github.com/yusing/goutils/apitypes"
gperr "github.com/yusing/goutils/errs"
)

View File

@@ -1,55 +0,0 @@
package apitypes
import (
"errors"
gperr "github.com/yusing/goutils/errs"
)
type ErrorResponse struct {
Message string `json:"message"`
Error string `json:"error,omitempty" extensions:"x-nullable"`
} // @name ErrorResponse
type serverError struct {
Message string
Err error
}
// Error returns a generic error response
func Error(message string, err ...error) ErrorResponse {
if len(err) > 0 {
var gpErr gperr.Error
if errors.As(err[0], &gpErr) {
return ErrorResponse{
Message: message,
Error: string(gpErr.Plain()),
}
}
return ErrorResponse{
Message: message,
Error: err[0].Error(),
}
}
return ErrorResponse{
Message: message,
}
}
func InternalServerError(err error, message string) error {
return serverError{
Message: message,
Err: err,
}
}
func (e serverError) Error() string {
if e.Err != nil {
return e.Message + ": " + e.Err.Error()
}
return e.Message
}
func (e serverError) Unwrap() error {
return e.Err
}

View File

@@ -1,29 +0,0 @@
package apitypes
type QueryOptions struct {
Limit int `binding:"required,min=1,max=20" form:"limit"`
Offset int `binding:"omitempty,min=0" form:"offset"`
OrderBy QueryOrder `binding:"omitempty,oneof=created_at updated_at" form:"order_by"`
Order QueryOrderDirection `binding:"omitempty,oneof=asc desc" form:"order"`
}
type QueryOrder string
const (
QueryOrderCreatedAt QueryOrder = "created_at"
QueryOrderUpdatedAt QueryOrder = "updated_at"
)
type QueryOrderDirection string
const (
QueryOrderDirectionAsc QueryOrderDirection = "asc"
QueryOrderDirectionDesc QueryOrderDirection = "desc"
)
type QueryResponse struct {
Total int64 `json:"total"`
Limit int `json:"limit"`
Offset int `json:"offset"`
HasMore bool `json:"has_more"`
}

View File

@@ -1,18 +0,0 @@
package apitypes
type SuccessResponse struct {
Message string `json:"message"`
Details map[string]any `json:"details,omitempty" extensions:"x-nullable"`
} // @name SuccessResponse
func Success(message string, extra ...map[string]any) SuccessResponse {
if len(extra) > 0 {
return SuccessResponse{
Message: message,
Details: extra[0],
}
}
return SuccessResponse{
Message: message,
}
}

View File

@@ -8,6 +8,8 @@ import (
"github.com/yusing/godoxy/agent/pkg/agent"
"github.com/yusing/goutils/http/httpheaders"
"github.com/yusing/goutils/http/websocket"
_ "github.com/yusing/goutils/apitypes"
)
// @x-id "list"
@@ -19,7 +21,6 @@ import (
// @Produce json
// @Success 200 {array} Agent
// @Failure 403 {object} apitypes.ErrorResponse
// @Failure 500 {object} apitypes.ErrorResponse
// @Router /agent/list [get]
func List(c *gin.Context) {
if httpheaders.IsWebsocket(c.Request.Header) {

View File

@@ -4,8 +4,8 @@ import (
"net/http"
"github.com/gin-gonic/gin"
apitypes "github.com/yusing/godoxy/internal/api/types"
"github.com/yusing/godoxy/internal/autocert"
apitypes "github.com/yusing/goutils/apitypes"
)
type CertInfo struct {

View File

@@ -6,9 +6,9 @@ import (
"github.com/gin-gonic/gin"
"github.com/rs/zerolog/log"
apitypes "github.com/yusing/godoxy/internal/api/types"
"github.com/yusing/godoxy/internal/autocert"
"github.com/yusing/godoxy/internal/logging/memlogger"
apitypes "github.com/yusing/goutils/apitypes"
gperr "github.com/yusing/goutils/errs"
"github.com/yusing/goutils/http/websocket"
)

View File

@@ -4,8 +4,8 @@ import (
"net/http"
"github.com/gin-gonic/gin"
apitypes "github.com/yusing/godoxy/internal/api/types"
"github.com/yusing/godoxy/internal/docker"
apitypes "github.com/yusing/goutils/apitypes"
)
// @x-id "container"

View File

@@ -7,6 +7,8 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/gin-gonic/gin"
gperr "github.com/yusing/goutils/errs"
_ "github.com/yusing/goutils/apitypes"
)
type ContainerState = container.ContainerState // @name ContainerState

View File

@@ -8,6 +8,8 @@ import (
"github.com/gin-gonic/gin"
gperr "github.com/yusing/goutils/errs"
strutils "github.com/yusing/goutils/strings"
_ "github.com/yusing/goutils/apitypes"
)
type containerStats struct {

View File

@@ -10,8 +10,8 @@ import (
"github.com/docker/docker/pkg/stdcopy"
"github.com/gin-gonic/gin"
"github.com/rs/zerolog/log"
apitypes "github.com/yusing/godoxy/internal/api/types"
"github.com/yusing/godoxy/internal/docker"
apitypes "github.com/yusing/goutils/apitypes"
"github.com/yusing/goutils/http/websocket"
"github.com/yusing/goutils/task"
)

View File

@@ -4,8 +4,8 @@ import (
"net/http"
"github.com/gin-gonic/gin"
apitypes "github.com/yusing/godoxy/internal/api/types"
"github.com/yusing/godoxy/internal/docker"
apitypes "github.com/yusing/goutils/apitypes"
)
// @x-id "restart"

View File

@@ -5,8 +5,8 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/gin-gonic/gin"
apitypes "github.com/yusing/godoxy/internal/api/types"
"github.com/yusing/godoxy/internal/docker"
apitypes "github.com/yusing/goutils/apitypes"
)
type StartRequest struct {

View File

@@ -5,8 +5,8 @@ import (
"github.com/docker/docker/api/types/container"
"github.com/gin-gonic/gin"
apitypes "github.com/yusing/godoxy/internal/api/types"
"github.com/yusing/godoxy/internal/docker"
apitypes "github.com/yusing/goutils/apitypes"
)
type StopRequest struct {

View File

@@ -6,8 +6,8 @@ import (
"time"
"github.com/gin-gonic/gin"
apitypes "github.com/yusing/godoxy/internal/api/types"
"github.com/yusing/godoxy/internal/docker"
apitypes "github.com/yusing/goutils/apitypes"
gperr "github.com/yusing/goutils/errs"
"github.com/yusing/goutils/http/httpheaders"
"github.com/yusing/goutils/http/websocket"

View File

@@ -5,9 +5,9 @@ import (
"net/http"
"github.com/gin-gonic/gin"
apitypes "github.com/yusing/godoxy/internal/api/types"
"github.com/yusing/godoxy/internal/homepage"
"github.com/yusing/godoxy/internal/route/routes"
apitypes "github.com/yusing/goutils/apitypes"
_ "unsafe"
)

View File

@@ -7,8 +7,8 @@ import (
"strings"
"github.com/gin-gonic/gin"
apitypes "github.com/yusing/godoxy/internal/api/types"
"github.com/yusing/godoxy/internal/common"
apitypes "github.com/yusing/goutils/apitypes"
)
type FileType string // @name FileType

View File

@@ -5,9 +5,9 @@ import (
"strings"
"github.com/gin-gonic/gin"
apitypes "github.com/yusing/godoxy/internal/api/types"
"github.com/yusing/godoxy/internal/common"
"github.com/yusing/godoxy/internal/utils"
apitypes "github.com/yusing/goutils/apitypes"
)
type ListFilesResponse struct {

View File

@@ -5,7 +5,7 @@ import (
"os"
"github.com/gin-gonic/gin"
apitypes "github.com/yusing/godoxy/internal/api/types"
apitypes "github.com/yusing/goutils/apitypes"
)
type SetFileContentRequest GetFileContentRequest

View File

@@ -4,10 +4,10 @@ import (
"net/http"
"github.com/gin-gonic/gin"
apitypes "github.com/yusing/godoxy/internal/api/types"
config "github.com/yusing/godoxy/internal/config/types"
"github.com/yusing/godoxy/internal/net/gphttp/middleware"
"github.com/yusing/godoxy/internal/route/provider"
apitypes "github.com/yusing/goutils/apitypes"
gperr "github.com/yusing/goutils/errs"
)

View File

@@ -8,6 +8,8 @@ import (
"github.com/yusing/godoxy/internal/route/routes"
"github.com/yusing/goutils/http/httpheaders"
"github.com/yusing/goutils/http/websocket"
_ "github.com/yusing/goutils/apitypes"
)
type HealthMap = map[string]routes.HealthInfo // @name HealthMap

View File

@@ -6,6 +6,8 @@ import (
"github.com/gin-gonic/gin"
"github.com/yusing/godoxy/internal/homepage"
"github.com/yusing/godoxy/internal/route/routes"
_ "github.com/yusing/goutils/apitypes"
)
// @x-id "categories"

View File

@@ -4,8 +4,8 @@ import (
"net/http"
"github.com/gin-gonic/gin"
apitypes "github.com/yusing/godoxy/internal/api/types"
"github.com/yusing/godoxy/internal/homepage"
apitypes "github.com/yusing/goutils/apitypes"
)
type HomepageOverrideItemClickParams struct {

View File

@@ -10,9 +10,9 @@ import (
"github.com/gin-gonic/gin"
"github.com/lithammer/fuzzysearch/fuzzy"
apitypes "github.com/yusing/godoxy/internal/api/types"
"github.com/yusing/godoxy/internal/homepage"
"github.com/yusing/godoxy/internal/route/routes"
apitypes "github.com/yusing/goutils/apitypes"
"github.com/yusing/goutils/http/httpheaders"
"github.com/yusing/goutils/http/websocket"
)

View File

@@ -4,8 +4,8 @@ import (
"net/http"
"github.com/gin-gonic/gin"
apitypes "github.com/yusing/godoxy/internal/api/types"
"github.com/yusing/godoxy/internal/homepage"
apitypes "github.com/yusing/goutils/apitypes"
)
type (

View File

@@ -4,8 +4,8 @@ import (
"net/http"
"github.com/gin-gonic/gin"
apitypes "github.com/yusing/godoxy/internal/api/types"
"github.com/yusing/godoxy/internal/homepage"
apitypes "github.com/yusing/goutils/apitypes"
)
type ListIconsRequest struct {

View File

@@ -12,9 +12,9 @@ import (
"github.com/gin-gonic/gin"
"github.com/rs/zerolog/log"
"github.com/yusing/godoxy/agent/pkg/agent"
apitypes "github.com/yusing/godoxy/internal/api/types"
"github.com/yusing/godoxy/internal/metrics/period"
"github.com/yusing/godoxy/internal/metrics/systeminfo"
apitypes "github.com/yusing/goutils/apitypes"
gperr "github.com/yusing/goutils/errs"
httputils "github.com/yusing/goutils/http"
"github.com/yusing/goutils/http/httpheaders"

View File

@@ -7,9 +7,9 @@ import (
"github.com/gin-gonic/gin"
agentPkg "github.com/yusing/godoxy/agent/pkg/agent"
apitypes "github.com/yusing/godoxy/internal/api/types"
"github.com/yusing/godoxy/internal/metrics/period"
"github.com/yusing/godoxy/internal/metrics/systeminfo"
apitypes "github.com/yusing/goutils/apitypes"
"github.com/yusing/goutils/http/httpheaders"
"github.com/yusing/goutils/synk"
)

View File

@@ -4,6 +4,8 @@ import (
"github.com/gin-gonic/gin"
"github.com/yusing/godoxy/internal/metrics/period"
"github.com/yusing/godoxy/internal/metrics/uptime"
_ "github.com/yusing/goutils/apitypes"
)
type UptimeRequest struct {

View File

@@ -4,8 +4,8 @@ import (
"net/http"
"github.com/gin-gonic/gin"
apitypes "github.com/yusing/godoxy/internal/api/types"
"github.com/yusing/godoxy/internal/config"
apitypes "github.com/yusing/goutils/apitypes"
)
// @x-id "reload"

View File

@@ -6,6 +6,8 @@ import (
"github.com/gin-gonic/gin"
"github.com/yusing/godoxy/internal/route"
"github.com/yusing/godoxy/internal/route/routes"
_ "github.com/yusing/goutils/apitypes"
)
type RoutesByProvider map[string][]route.Route

View File

@@ -8,6 +8,8 @@ import (
statequery "github.com/yusing/godoxy/internal/config/query"
"github.com/yusing/goutils/http/httpheaders"
"github.com/yusing/goutils/http/websocket"
_ "github.com/yusing/goutils/apitypes"
)
// @x-id "providers"
@@ -17,7 +19,7 @@ import (
// @Tags route,websocket
// @Accept json
// @Produce json
// @Success 200 {array} config.RouteProviderListResponse
// @Success 200 {array} statequery.RouteProviderListResponse
// @Failure 403 {object} apitypes.ErrorResponse
// @Failure 500 {object} apitypes.ErrorResponse
// @Router /route/providers [get]

View File

@@ -4,9 +4,9 @@ import (
"net/http"
"github.com/gin-gonic/gin"
apitypes "github.com/yusing/godoxy/internal/api/types"
statequery "github.com/yusing/godoxy/internal/config/query"
"github.com/yusing/godoxy/internal/route/routes"
apitypes "github.com/yusing/goutils/apitypes"
)
type ListRouteRequest struct {

View File

@@ -15,8 +15,8 @@ import (
"github.com/PuerkitoBio/goquery"
"github.com/gin-gonic/gin"
"github.com/vincent-petithory/dataurl"
apitypes "github.com/yusing/godoxy/internal/api/types"
gphttp "github.com/yusing/godoxy/internal/net/gphttp"
apitypes "github.com/yusing/goutils/apitypes"
"github.com/yusing/goutils/cache"
httputils "github.com/yusing/goutils/http"
strutils "github.com/yusing/goutils/strings"

View File

@@ -9,7 +9,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/puzpuzpuz/xsync/v4"
apitypes "github.com/yusing/godoxy/internal/api/types"
apitypes "github.com/yusing/goutils/apitypes"
"github.com/yusing/goutils/http/websocket"
)

View File

@@ -6,8 +6,8 @@ import (
"net/url"
"github.com/gin-gonic/gin"
apitypes "github.com/yusing/godoxy/internal/api/types"
metricsutils "github.com/yusing/godoxy/internal/metrics/utils"
apitypes "github.com/yusing/goutils/apitypes"
"github.com/yusing/goutils/http/httpheaders"
"github.com/yusing/goutils/http/websocket"
)

View File

@@ -41,7 +41,7 @@ type (
_ utils.NoCopy
Alias string `json:"alias"`
Scheme route.Scheme `json:"scheme,omitempty" swaggertype:"string"`
Scheme route.Scheme `json:"scheme,omitempty" swaggertype:"string" enums:"http,https,tcp,udp,fileserver"`
Host string `json:"host,omitempty"`
Port route.Port `json:"port"`
Root string `json:"root,omitempty"`
@@ -73,7 +73,7 @@ type (
ProxyURL *nettypes.URL `json:"purl,omitempty" swaggertype:"string"`
Excluded bool `json:"excluded,omitempty" extensions:"x-nullable"`
ExcludedReason ExcludedReason `json:"excluded_reason,omitempty" extensions:"x-nullable"`
ExcludedReason ExcludedReason `json:"excluded_reason,omitempty" swaggertype:"string" extensions:"x-nullable"`
HealthMon types.HealthMonitor `json:"health,omitempty" swaggerignore:"true"`
// for swagger

View File

@@ -10,7 +10,7 @@ import (
type Port struct {
Listening int `json:"listening"`
Proxy int `json:"proxy"`
}
} // @name Port
var (
ErrInvalidPortSyntax = gperr.New("invalid port syntax, expect [listening_port:]target_port")