package api import ( "strings" "github.com/CloudyKit/jet/v6" "github.com/gofiber/fiber/v2" ) // JetTemplateRequest represents the request body for the checkjet endpoint type JetTemplateRequest struct { Template string `json:"template"` } // JetTemplateResponse represents the response for the checkjet endpoint type JetTemplateResponse struct { Valid bool `json:"valid"` Message string `json:"message,omitempty"` Error string `json:"error,omitempty"` } // JetHandler handles Jet template-related API endpoints type JetHandler struct { // No dependencies needed for this handler } // NewJetHandler creates a new Jet template handler func NewJetHandler() *JetHandler { return &JetHandler{} } // RegisterRoutes registers Jet template routes to the fiber app func (h *JetHandler) RegisterRoutes(app *fiber.App) { // Create a group for Jet API endpoints jetGroup := app.Group("/api/jet") // Register the checkjet endpoint jetGroup.Post("/validate", h.validateTemplate) } // @Summary Validate a Jet template // @Description Validates a Jet template and returns detailed error information if invalid // @Tags jet // @Accept json // @Produce json // @Param template body JetTemplateRequest true "Jet template to validate" // @Success 200 {object} JetTemplateResponse // @Failure 400 {object} map[string]interface{} // @Router /api/jet/validate [post] func (h *JetHandler) validateTemplate(c *fiber.Ctx) error { var req JetTemplateRequest if err := c.BodyParser(&req); err != nil { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, "error": "Invalid request: " + err.Error(), }) } if req.Template == "" { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "success": false, "error": "Template cannot be empty", }) } // Create a temporary in-memory loader for the template loader := jet.NewInMemLoader() // Add the template to the loader loader.Set("test.jet", req.Template) // Create a new Jet set with the loader and enable development mode for better error reporting set := jet.NewSet(loader, jet.InDevelopmentMode()) // Get the template to parse it _, err := set.GetTemplate("test.jet") // Check if the template is valid if err != nil { // Extract meaningful error information errMsg := err.Error() // Ignore errors related to extended or included files not found // These aren't syntax errors but dependency errors we want to ignore if strings.Contains(errMsg, "no template") || strings.Contains(errMsg, "unable to locate template") || strings.Contains(errMsg, "template not found") || strings.Contains(errMsg, "extends|import") || strings.Contains(errMsg, "could not be found") || strings.Contains(errMsg, "template /") { // Still valid since it's only a dependency error, not a syntax error return c.JSON(fiber.Map{ "success": true, "valid": true, "message": "Template syntax is valid (ignoring extends/include errors)", }) } return c.JSON(fiber.Map{ "success": false, "valid": false, "error": errMsg, }) } // If no error, the template is valid return c.JSON(fiber.Map{ "success": true, "valid": true, "message": "Template is valid", }) }