package app import ( "context" "database/sql" "net/http" "forge.cadoles.com/arcad/edge/pkg/app" "forge.cadoles.com/arcad/edge/pkg/bus" "forge.cadoles.com/arcad/edge/pkg/bus/memory" edgeHTTP "forge.cadoles.com/arcad/edge/pkg/http" "forge.cadoles.com/arcad/edge/pkg/module" "forge.cadoles.com/arcad/edge/pkg/module/cast" "forge.cadoles.com/arcad/edge/pkg/module/net" "forge.cadoles.com/arcad/edge/pkg/storage" "forge.cadoles.com/arcad/edge/pkg/storage/sqlite" "forge.cadoles.com/arcad/edge/pkg/bundle" "github.com/go-chi/chi/middleware" "github.com/go-chi/chi/v5" "github.com/pkg/errors" ) type Server struct { bundle bundle.Bundle db *sql.DB server *http.Server } func (s *Server) Start(ctx context.Context, addr string) error { if s.server != nil { if err := s.Stop(); err != nil { return errors.WithStack(err) } } router := chi.NewRouter() router.Use(middleware.Logger) bus := memory.NewBus() ds := sqlite.NewDocumentStoreWithDB(s.db) bs := sqlite.NewBlobStoreWithDB(s.db) handler := edgeHTTP.NewHandler( edgeHTTP.WithBus(bus), edgeHTTP.WithServerModules(s.getAppModules(bus, ds, bs)...), ) if err := handler.Load(s.bundle); err != nil { return errors.Wrap(err, "could not load app bundle") } router.Handle("/*", handler) server := &http.Server{ Addr: addr, Handler: router, } go func() { defer func() { if err := s.Stop(); err != nil { panic(errors.WithStack(err)) } }() if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { panic(errors.WithStack(err)) } }() s.server = server return nil } func (s *Server) Stop() error { if s.server == nil { return nil } defer func() { s.server = nil }() if err := s.server.Close(); err != nil { panic(errors.WithStack(err)) } return nil } func (s *Server) getAppModules(bus bus.Bus, ds storage.DocumentStore, bs storage.BlobStore) []app.ServerModuleFactory { return []app.ServerModuleFactory{ module.ContextModuleFactory(), module.ConsoleModuleFactory(), cast.CastModuleFactory(), module.LifecycleModuleFactory(), net.ModuleFactory(bus), module.RPCModuleFactory(bus), module.StoreModuleFactory(ds), module.BlobModuleFactory(bus, bs), // module.Extends( // auth.ModuleFactory( // auth.WithJWT(dummyKeyFunc), // ), // func(o *goja.Object) { // if err := o.Set("CLAIM_ROLE", "role"); err != nil { // panic(errors.New("could not set 'CLAIM_ROLE' property")) // } // if err := o.Set("CLAIM_PREFERRED_USERNAME", "preferred_username"); err != nil { // panic(errors.New("could not set 'CLAIM_PREFERRED_USERNAME' property")) // } // }, // ), } } func NewServer(bundle bundle.Bundle, db *sql.DB) *Server { return &Server{ bundle: bundle, db: db, } }