feat: bootstrap foundation application
This commit is contained in:
93
apps/server/internal/httpserver/server.go
Normal file
93
apps/server/internal/httpserver/server.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package httpserver
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"html/template"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
|
||||
"github.com/tim/md-hub-secure/apps/server/internal/config"
|
||||
"github.com/tim/md-hub-secure/apps/server/internal/docs"
|
||||
"github.com/tim/md-hub-secure/apps/server/internal/store"
|
||||
)
|
||||
|
||||
//go:embed templates/*.gohtml static/*
|
||||
var assets embed.FS
|
||||
|
||||
type Dependencies struct {
|
||||
Config config.Config
|
||||
Logger *slog.Logger
|
||||
Documents *docs.Service
|
||||
Repository *docs.Repository
|
||||
ContentStore *store.ContentStore
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
config config.Config
|
||||
logger *slog.Logger
|
||||
documents *docs.Service
|
||||
repository *docs.Repository
|
||||
contentStore *store.ContentStore
|
||||
templates *template.Template
|
||||
webEnabled bool
|
||||
}
|
||||
|
||||
func New(deps Dependencies) (http.Handler, error) {
|
||||
templates, err := template.New("").Funcs(template.FuncMap{
|
||||
"trimMd": func(path string) string {
|
||||
return strings.TrimSuffix(path, ".md")
|
||||
},
|
||||
}).ParseFS(assets, "templates/*.gohtml")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
server := &Server{
|
||||
config: deps.Config,
|
||||
logger: deps.Logger,
|
||||
documents: deps.Documents,
|
||||
repository: deps.Repository,
|
||||
contentStore: deps.ContentStore,
|
||||
templates: templates,
|
||||
}
|
||||
|
||||
if _, err := os.Stat(deps.Config.Web.DistDir); err == nil {
|
||||
server.webEnabled = true
|
||||
}
|
||||
|
||||
router := chi.NewRouter()
|
||||
router.Use(middleware.RequestID)
|
||||
router.Use(middleware.RealIP)
|
||||
router.Use(middleware.Recoverer)
|
||||
router.Use(middleware.Timeout(30 * time.Second))
|
||||
router.Use(server.requestLogger)
|
||||
router.Use(server.securityHeaders)
|
||||
|
||||
router.Get("/", server.handleIndex)
|
||||
router.Get("/health", server.handleHealth)
|
||||
router.Get("/docs", server.handleDocsIndexRedirect)
|
||||
router.Get("/docs/*", server.handleDocument)
|
||||
router.Post("/api/uploads", server.handleUpload)
|
||||
router.Get("/attachments/{hash}", server.handleAttachment)
|
||||
router.Handle("/static/*", http.StripPrefix("/static/", http.FileServer(mustSub("static"))))
|
||||
|
||||
if server.webEnabled {
|
||||
router.Handle("/app/*", http.StripPrefix("/app/", http.FileServer(http.Dir(deps.Config.Web.DistDir))))
|
||||
}
|
||||
|
||||
return router, nil
|
||||
}
|
||||
|
||||
func mustSub(path string) http.FileSystem {
|
||||
sub, err := fsSub(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return http.FS(sub)
|
||||
}
|
||||
Reference in New Issue
Block a user