package app import ( "fmt" "forge.cadoles.com/arcad/edge/pkg/app" "forge.cadoles.com/arcad/edge/pkg/module/util" "github.com/dop251/goja" "github.com/pkg/errors" ) type Module struct { repository Repository } type gojaManifest struct { ID string `goja:"id" json:"id"` Version string `goja:"version" json:"version"` Title string `goja:"title" json:"title"` Description string `goja:"description" json:"description"` Tags []string `goja:"tags" json:"tags"` } func toGojaManifest(manifest *app.Manifest) *gojaManifest { return &gojaManifest{ ID: string(manifest.ID), Version: manifest.Version, Title: manifest.Title, Description: manifest.Description, Tags: manifest.Tags, } } func toGojaManifests(manifests []*app.Manifest) []*gojaManifest { gojaManifests := make([]*gojaManifest, len(manifests)) for i, m := range manifests { gojaManifests[i] = toGojaManifest(m) } return gojaManifests } func (m *Module) Name() string { return "app" } func (m *Module) Export(export *goja.Object) { if err := export.Set("list", m.list); err != nil { panic(errors.Wrap(err, "could not set 'list' function")) } if err := export.Set("get", m.get); err != nil { panic(errors.Wrap(err, "could not set 'get' function")) } if err := export.Set("getUrl", m.getURL); err != nil { panic(errors.Wrap(err, "could not set 'list' function")) } } func (m *Module) list(call goja.FunctionCall, rt *goja.Runtime) goja.Value { ctx := util.AssertContext(call.Argument(0), rt) manifests, err := m.repository.List(ctx) if err != nil { panic(rt.ToValue(errors.WithStack(err))) } return rt.ToValue(toGojaManifests(manifests)) } func (m *Module) get(call goja.FunctionCall, rt *goja.Runtime) goja.Value { ctx := util.AssertContext(call.Argument(0), rt) appID := assertAppID(call.Argument(1), rt) manifest, err := m.repository.Get(ctx, appID) if err != nil { panic(rt.ToValue(errors.WithStack(err))) } return rt.ToValue(toGojaManifest(manifest)) } func (m *Module) getURL(call goja.FunctionCall, rt *goja.Runtime) goja.Value { ctx := util.AssertContext(call.Argument(0), rt) appID := assertAppID(call.Argument(1), rt) url, err := m.repository.GetURL(ctx, appID) if err != nil { panic(rt.ToValue(errors.WithStack(err))) } return rt.ToValue(url) } func ModuleFactory(repository Repository) app.ServerModuleFactory { return func(server *app.Server) app.ServerModule { return &Module{ repository: repository, } } } func assertAppID(value goja.Value, rt *goja.Runtime) app.ID { appID, ok := value.Export().(app.ID) if !ok { rawAppID, ok := value.Export().(string) if !ok { panic(rt.NewTypeError(fmt.Sprintf("app id must be an appid or a string, got '%T'", value.Export()))) } appID = app.ID(rawAppID) } return appID }