package kconfig import ( _ "embed" "html/template" "io/ioutil" "net/http" "strings" "github.com/rs/zerolog/log" "kumoly.io/lib/guard/engine" "kumoly.io/tools/kconfig/public" ) //go:embed assets/default.jcs var defaultSchema []byte //go:embed public/index.html var index string var servePublic = http.FileServer(http.FS(public.FS)) var tmpl *engine.Engine var l = log.With().Str("mod", "kconfig").Logger() func init() { tmpl = engine.Must(engine.New("").Parse(index)) } type Kconfig struct { // AppName displays appname in title and the download file will be {{.AppName}}.json AppName string // Schema json for schema, more information see [json-editor](https://github.com/json-editor/json-editor) Schema []byte // Mux the underlying Mux Mux *http.ServeMux // Apply function callback for intergrating submit Apply func([]byte) error // Load function callback for intergrating load Load func() []byte } func New() *Kconfig { k := &Kconfig{ AppName: "kconfig", Schema: defaultSchema, Apply: func(b []byte) error { l.Debug().Msgf("%s", b) return nil }, Load: func() []byte { return []byte(`{ "name": "test", "age": 21, "gender": "male", "location": { "city": "", "state": "", "citystate": ", " }, "pets": [], "cars": [] }`) }, } mux := http.NewServeMux() mux.HandleFunc("/", k.App) mux.HandleFunc("/api/schema", func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { http.NotFound(w, r) return } w.Write([]byte(k.Schema)) }) mux.HandleFunc("/api/load", func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { http.NotFound(w, r) return } w.Write([]byte(k.Load())) }) mux.HandleFunc("/api/apply", func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.NotFound(w, r) return } data, err := ioutil.ReadAll(r.Body) r.Body.Close() if err != nil { panic(err) } err = k.Apply(data) if err != nil { panic(err) } w.Write([]byte("ok")) }) k.Mux = mux return k } func (k *Kconfig) ServeHTTP(w http.ResponseWriter, r *http.Request) { k.Mux.ServeHTTP(w, r) } func (k *Kconfig) App(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/" { tmpl.Execute(w, struct { AppName string ACE_JS template.HTML }{ k.AppName, template.HTML(``), }) return } file, err := public.FS.Open(strings.TrimPrefix(r.URL.String(), "/")) if err != nil { http.NotFound(w, r) return } stat, err := file.Stat() if err != nil || stat.IsDir() { http.NotFound(w, r) return } servePublic.ServeHTTP(w, r) }