mirror of
https://wget.la/https://github.com/leookun/cursor-byok
synced 2026-08-17 03:27:02 +08:00
- Integrated a tooltip with a button to open the contributor's GitHub profile in the CursorAccountCard component. - Updated the layout of the account card for better visual organization. - Removed routing mode options from the configuration view and adjusted related translations in multiple languages. - Cleaned up unused routing mode logic in the app state management.
171 lines
3.8 KiB
Go
171 lines
3.8 KiB
Go
package server
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
)
|
|
|
|
type HandlerFunc func(*Context) error
|
|
type Middleware func(HandlerFunc) HandlerFunc
|
|
|
|
type Route struct {
|
|
Method string
|
|
Pattern string
|
|
Name string
|
|
Protocol ProtocolClass
|
|
Middleware []Middleware
|
|
Local HandlerFunc
|
|
}
|
|
|
|
type App struct {
|
|
router chi.Router
|
|
globalMiddlewares []Middleware
|
|
routes []Route
|
|
mounts []mountSpec
|
|
}
|
|
|
|
type mountSpec struct {
|
|
pattern string
|
|
handler http.Handler
|
|
}
|
|
|
|
type Option func(*App)
|
|
type RouteOption func(*Route)
|
|
|
|
func New(options ...Option) http.Handler {
|
|
app := &App{router: chi.NewRouter()}
|
|
for _, option := range options {
|
|
if option != nil {
|
|
option(app)
|
|
}
|
|
}
|
|
for _, route := range app.routes {
|
|
app.registerRoute(route)
|
|
}
|
|
for _, mount := range app.mounts {
|
|
app.router.Mount(mount.pattern, mount.handler)
|
|
}
|
|
return app.router
|
|
}
|
|
|
|
func Use(middlewares ...Middleware) Option {
|
|
return func(app *App) {
|
|
app.globalMiddlewares = append(app.globalMiddlewares, middlewares...)
|
|
}
|
|
}
|
|
|
|
func Mount(pattern string, handler http.Handler) Option {
|
|
return func(app *App) {
|
|
if handler == nil {
|
|
return
|
|
}
|
|
app.mounts = append(app.mounts, mountSpec{pattern: pattern, handler: handler})
|
|
}
|
|
}
|
|
|
|
func GET(pattern string, options ...RouteOption) Option {
|
|
return routeOption(http.MethodGet, pattern, options...)
|
|
}
|
|
func POST(pattern string, options ...RouteOption) Option {
|
|
return routeOption(http.MethodPost, pattern, options...)
|
|
}
|
|
func Any(pattern string, options ...RouteOption) Option { return routeOption("", pattern, options...) }
|
|
|
|
func routeOption(method string, pattern string, options ...RouteOption) Option {
|
|
return func(app *App) {
|
|
route := Route{
|
|
Method: method,
|
|
Pattern: pattern,
|
|
Protocol: ProtocolHTTP,
|
|
Local: func(ctx *Context) error {
|
|
return fmt.Errorf("route %s has no local action", pattern)
|
|
},
|
|
}
|
|
for _, option := range options {
|
|
if option != nil {
|
|
option(&route)
|
|
}
|
|
}
|
|
app.routes = append(app.routes, route)
|
|
}
|
|
}
|
|
|
|
func Name(name string) RouteOption {
|
|
return func(route *Route) {
|
|
route.Name = name
|
|
}
|
|
}
|
|
|
|
func HTTP() RouteOption {
|
|
return func(route *Route) {
|
|
route.Protocol = ProtocolHTTP
|
|
}
|
|
}
|
|
|
|
func ConnectUnary() RouteOption {
|
|
return func(route *Route) {
|
|
route.Protocol = ProtocolConnectUnary
|
|
}
|
|
}
|
|
|
|
func ConnectStream() RouteOption {
|
|
return func(route *Route) {
|
|
route.Protocol = ProtocolConnectStream
|
|
}
|
|
}
|
|
|
|
func With(middlewares ...Middleware) RouteOption {
|
|
return func(route *Route) {
|
|
route.Middleware = append(route.Middleware, middlewares...)
|
|
}
|
|
}
|
|
|
|
func Local(action HandlerFunc) RouteOption {
|
|
return func(route *Route) {
|
|
route.Local = action
|
|
}
|
|
}
|
|
|
|
func (app *App) registerRoute(route Route) {
|
|
handler := app.buildRouteHandler(route)
|
|
if route.Method == "" {
|
|
app.router.HandleFunc(route.Pattern, handler)
|
|
return
|
|
}
|
|
app.router.MethodFunc(route.Method, route.Pattern, handler)
|
|
}
|
|
|
|
func (app *App) buildRouteHandler(route Route) http.HandlerFunc {
|
|
chain := append([]Middleware{}, app.globalMiddlewares...)
|
|
chain = append(chain, route.Middleware...)
|
|
final := Chain(chain...)(func(ctx *Context) error {
|
|
if route.Local != nil {
|
|
return route.Local(ctx)
|
|
}
|
|
return fmt.Errorf("route %s has no executable action", route.Name)
|
|
})
|
|
return func(writer http.ResponseWriter, request *http.Request) {
|
|
trackedWriter := newTrackedResponseWriter(writer)
|
|
ctx := newContext(trackedWriter, request, route)
|
|
if err := final(ctx); err != nil {
|
|
writeServerError(trackedWriter, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func Chain(middlewares ...Middleware) Middleware {
|
|
return func(final HandlerFunc) HandlerFunc {
|
|
wrapped := final
|
|
for index := len(middlewares) - 1; index >= 0; index-- {
|
|
current := middlewares[index]
|
|
if current == nil {
|
|
continue
|
|
}
|
|
wrapped = current(wrapped)
|
|
}
|
|
return wrapped
|
|
}
|
|
}
|