Serve compiled front from the same application

also add embedded build for production
This commit is contained in:
2026-02-11 01:12:53 +01:00
parent 8fc5ff84c2
commit e127088195
28 changed files with 200 additions and 130 deletions

View File

@@ -1,9 +1,14 @@
package setup
import (
"github.com/gin-contrib/cors"
"bufio"
"io"
"io/fs"
"net/http"
"github.com/gin-gonic/gin"
"git.artlef.fr/PersonalLibraryManager/front"
"git.artlef.fr/PersonalLibraryManager/internal/appcontext"
"git.artlef.fr/PersonalLibraryManager/internal/config"
"git.artlef.fr/PersonalLibraryManager/internal/db"
@@ -20,69 +25,90 @@ func Setup(config *config.Config) *gin.Engine {
panic(err)
}
r := gin.Default()
r.Use(cors.New(configureCors())) // All origins allowed by default
r.Use(middleware.Auth())
r.Static("/bookcover", config.ImageFolderPath)
bundle := i18nresource.InitializeI18n()
r.GET("/mybooks/read", func(c *gin.Context) {
ws := r.Group("/ws")
ws.Use(middleware.Auth())
ws.GET("/mybooks/read", func(c *gin.Context) {
routes.GetMyBooksReadHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.GET("/mybooks/reading", func(c *gin.Context) {
ws.GET("/mybooks/reading", func(c *gin.Context) {
routes.GetMyBooksReadingHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.GET("/mybooks/wantread", func(c *gin.Context) {
ws.GET("/mybooks/wantread", func(c *gin.Context) {
routes.GetMyBooksWantReadHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.GET("/search/:searchterm", func(c *gin.Context) {
ws.GET("/search/:searchterm", func(c *gin.Context) {
routes.GetSearchBooksHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.GET("/inventaire/books/:workId", func(c *gin.Context) {
ws.GET("/inventaire/books/:workId", func(c *gin.Context) {
routes.GetInventaireBooks(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.GET("/book/:id", func(c *gin.Context) {
ws.GET("/book/:id", func(c *gin.Context) {
routes.GetBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.PUT("/book/:id/read", func(c *gin.Context) {
ws.PUT("/book/:id/read", func(c *gin.Context) {
routes.PutReadUserBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.PUT("/book/:id/wantread", func(c *gin.Context) {
ws.PUT("/book/:id/wantread", func(c *gin.Context) {
routes.PutWantReadUserBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.PUT("/book/:id/startread", func(c *gin.Context) {
ws.PUT("/book/:id/startread", func(c *gin.Context) {
routes.PutStartReadUserBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.PUT("/book/:id/rate", func(c *gin.Context) {
ws.PUT("/book/:id/rate", func(c *gin.Context) {
routes.PutRateUserBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.POST("/book", func(c *gin.Context) {
ws.POST("/book", func(c *gin.Context) {
routes.PostBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.POST("/importbook", func(c *gin.Context) {
ws.POST("/importbook", func(c *gin.Context) {
routes.PostImportBookHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.GET("/author/:id", func(c *gin.Context) {
ws.GET("/author/:id", func(c *gin.Context) {
routes.GetAuthorHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.GET("/author/:id/books", func(c *gin.Context) {
ws.GET("/author/:id/books", func(c *gin.Context) {
routes.GetAuthorBooksHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.POST("/auth/signup", func(c *gin.Context) {
ws.POST("/auth/signup", func(c *gin.Context) {
routes.PostSignupHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.POST("/auth/login", func(c *gin.Context) {
ws.POST("/auth/login", func(c *gin.Context) {
routes.PostLoginHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.POST("/upload/cover", func(c *gin.Context) {
ws.POST("/upload/cover", func(c *gin.Context) {
routes.PostUploadBookCoverHandler(appcontext.AppContext{C: c, Db: db, I18n: bundle, Config: config})
})
r.Static("/static/bookcover", config.ImageFolderPath)
folders := []string{"assets", "css", "image"}
for _, folder := range folders {
subFs, err := fs.Sub(front.Frontend, folder)
if err != nil {
panic(err)
}
r.StaticFS("/"+folder, http.FS(subFs))
}
r.StaticFileFS("/favicon.ico", "favicon.ico", http.FS(front.Frontend))
r.GET("/", func(c *gin.Context) {
indexHtml, err := front.Frontend.Open("index.html")
if err != nil {
panic(err)
}
defer indexHtml.Close()
c.Header("Content-Type", "text/html")
fileReader := bufio.NewReader(indexHtml)
_, err = io.Copy(c.Writer, fileReader)
})
r.NoRoute(func(c *gin.Context) {
c.Redirect(http.StatusFound, "/")
})
return r
}
func configureCors() cors.Config {
config := cors.DefaultConfig()
config.AllowOrigins = []string{"http://localhost:5173"}
config.AllowPrivateNetwork = true
config.AllowCredentials = true
config.AllowHeaders = []string{"Authorization", "Content-Type"}
return config
}