[add] widget.apis process

This commit is contained in:
Max 2022-12-03 19:12:51 +08:00
parent 1c1b551715
commit 0d8ff4073a
6 changed files with 387 additions and 0 deletions

1
widgets/action.go Normal file
View file

@ -0,0 +1 @@
package widgets

231
widgets/api.go Normal file
View file

@ -0,0 +1,231 @@
package widgets
import (
"fmt"
"os"
"strings"
"github.com/yaoapp/gou"
"github.com/yaoapp/yao/widgets/chart"
"github.com/yaoapp/yao/widgets/form"
"github.com/yaoapp/yao/widgets/list"
"github.com/yaoapp/yao/widgets/table"
)
// Apis return loaded apis
func Apis() []Item {
apis := map[string]interface{}{}
userApis(apis)
tableApis(apis)
formApis(apis)
listApis(apis)
chartApis(apis)
grouping := Grouping(apis)
items := Array(grouping, []Item{})
Sort(items, []string{"apis", "tables", "forms", "lists", "charts"})
return items
}
func userApis(apis map[string]interface{}) {
// Name string `json:"name"`
// Version string `json:"version"`
// Description string `json:"description,omitempty"`
// Group string `json:"group,omitempty"`
// Guard string `json:"guard,omitempty"`
// Paths []Path `json:"paths,omitempty"`
for group, api := range gou.APIs {
if strings.HasPrefix(group, "widgets") {
continue
}
// Label string `json:"label,omitempty"`
// Description string `json:"description,omitempty"`
// Path string `json:"path"`
// Method string `json:"method"`
// Process string `json:"process"`
// Guard string `json:"guard,omitempty"`
// In []string `json:"in,omitempty"`
// Out Out `json:"out,omitempty"`
paths := []map[string]interface{}{}
for _, path := range api.HTTP.Paths {
guard := path.Guard
if guard == "" {
guard = api.HTTP.Guard
}
fullpath := fmt.Sprintf("/apis/%s%s", api.HTTP.Group, path.Path)
paths = append(paths, map[string]interface{}{
"name": path.Label,
"description": path.Description,
"guard": guard,
"method": path.Method,
"path": path.Path,
"router": fullpath,
"fullpath": fullpath,
"in": path.In,
"out": path.Out,
"process": path.Process,
"params": map[string]interface{}{},
})
}
dsl := fmt.Sprintf("apis%s%s.http.json", string(os.PathSeparator), strings.ReplaceAll(group, ".", string(os.PathSeparator)))
apis[dsl] = map[string]interface{}{
"DSL": dsl,
"name": api.HTTP.Name,
"version": api.HTTP.Version,
"group": fmt.Sprintf("/%s", api.HTTP.Group),
"guard": api.HTTP.Guard,
"description": api.HTTP.Description,
"paths": paths,
}
}
}
func tableApis(apis map[string]interface{}) {
api, has := gou.APIs["widgets.table"]
if !has {
return
}
for id, widget := range table.Tables {
dsl := fmt.Sprintf("tables%s%s.tab.json", string(os.PathSeparator), strings.ReplaceAll(id, ".", string(os.PathSeparator)))
groupGuard := "bearer-jwt"
pathGuards := []map[string]string{
{"name": "/:id/search", "guard": widget.Action.Search.Guard},
{"name": "/:id/get", "guard": widget.Action.Get.Guard},
{"name": "/:id/find/:primary", "guard": widget.Action.Find.Guard},
{"name": "/:id/save", "guard": widget.Action.Save.Guard},
{"name": "/:id/create", "guard": widget.Action.Create.Guard},
{"name": "/:id/insert", "guard": widget.Action.Insert.Guard},
{"name": "/:id/update/:primary", "guard": widget.Action.Update.Guard},
{"name": "/:id/update/in", "guard": widget.Action.UpdateIn.Guard},
{"name": "/:id/update/where", "guard": widget.Action.UpdateWhere.Guard},
{"name": "/:id/delete/:primary", "guard": widget.Action.Delete.Guard},
{"name": "/:id/delete/in", "guard": widget.Action.DeleteIn.Guard},
{"name": "/:id/delete/where", "guard": widget.Action.DeleteWhere.Guard},
{"name": "/:id/upload/:xpath/:method", "guard": widget.Action.Upload.Guard},
{"name": "/:id/download/:field", "guard": widget.Action.Download.Guard},
}
widgetApis(apis, api, id, dsl, groupGuard, pathGuards)
}
}
func formApis(apis map[string]interface{}) {
api, has := gou.APIs["widgets.form"]
if !has {
return
}
for id, widget := range form.Forms {
dsl := fmt.Sprintf("forms%s%s.form.json", string(os.PathSeparator), strings.ReplaceAll(id, ".", string(os.PathSeparator)))
groupGuard := "bearer-jwt"
pathGuards := []map[string]string{
{"name": "/:id/find/:primary", "guard": widget.Action.Find.Guard},
{"name": "/:id/save", "guard": widget.Action.Save.Guard},
{"name": "/:id/create", "guard": widget.Action.Create.Guard},
{"name": "/:id/update/:primary", "guard": widget.Action.Update.Guard},
{"name": "/:id/delete/:primary", "guard": widget.Action.Delete.Guard},
{"name": "/:id/upload/:xpath/:method", "guard": widget.Action.Upload.Guard},
{"name": "/:id/download/:field", "guard": widget.Action.Download.Guard},
}
widgetApis(apis, api, id, dsl, groupGuard, pathGuards)
}
}
func listApis(apis map[string]interface{}) {
api, has := gou.APIs["widgets.list"]
if !has {
return
}
for id, widget := range list.Lists {
dsl := fmt.Sprintf("lists%s%s.list.json", string(os.PathSeparator), strings.ReplaceAll(id, ".", string(os.PathSeparator)))
groupGuard := "bearer-jwt"
pathGuards := []map[string]string{
{"name": "/:id/get", "guard": widget.Action.Get.Guard},
{"name": "/:id/save", "guard": widget.Action.Save.Guard},
{"name": "/:id/upload/:xpath/:method", "guard": widget.Action.Upload.Guard},
{"name": "/:id/download/:field", "guard": widget.Action.Download.Guard},
}
widgetApis(apis, api, id, dsl, groupGuard, pathGuards)
}
}
func chartApis(apis map[string]interface{}) {
api, has := gou.APIs["widgets.chart"]
if !has {
return
}
for id, widget := range chart.Charts {
dsl := fmt.Sprintf("charts%s%s.chart.json", string(os.PathSeparator), strings.ReplaceAll(id, ".", string(os.PathSeparator)))
groupGuard := "bearer-jwt"
pathGuards := []map[string]string{
{"name": "/:id/data", "guard": widget.Action.Data.Guard},
}
widgetApis(apis, api, id, dsl, groupGuard, pathGuards)
}
}
func widgetApis(apis map[string]interface{}, api *gou.API, widgetID string, dsl string, groupGuard string, pathGuards []map[string]string) {
pathMapping := map[string]gou.Path{}
for _, path := range api.HTTP.Paths {
pathMapping[path.Path] = path
}
// Label string `json:"label,omitempty"`
// Description string `json:"description,omitempty"`
// Path string `json:"path"`
// Method string `json:"method"`
// Process string `json:"process"`
// Guard string `json:"guard,omitempty"`
// In []string `json:"in,omitempty"`
// Out Out `json:"out,omitempty"`
paths := []map[string]interface{}{}
for _, pathGuard := range pathGuards {
name := pathGuard["name"]
guard := pathGuard["guard"]
path, has := pathMapping[name]
if !has {
continue
}
if guard == "" {
guard = groupGuard
}
fullpath := fmt.Sprintf("/apis/%s%s", api.HTTP.Group, path.Path)
paths = append(paths, map[string]interface{}{
"name": path.Label,
"description": path.Description,
"guard": guard,
"method": path.Method,
"path": path.Path,
"fullpath": fullpath,
"router": strings.ReplaceAll(fullpath, ":id", widgetID),
"in": path.In,
"out": path.Out,
"process": path.Process,
"params": map[string]interface{}{"id": widgetID},
})
}
apis[dsl] = map[string]interface{}{
"DSL": dsl,
"name": api.HTTP.Name,
"version": api.HTTP.Version,
"group": fmt.Sprintf("/%s", api.HTTP.Group),
"guard": groupGuard,
"description": api.HTTP.Description,
"paths": paths,
}
}

89
widgets/item.go Normal file
View file

@ -0,0 +1,89 @@
package widgets
import (
"os"
"sort"
"strings"
)
// Item the item
type Item struct {
Name string `json:"name,omitempty"`
Data interface{} `json:"data,omitempty"`
Children []Item `json:"children,omitempty"`
}
// Sort items
func Sort(items []Item, orders []string) {
rank := map[string]int{}
if orders != nil {
for i, name := range orders {
rank[name] = i
}
}
sort.Slice(items, func(i, j int) bool {
rankI, hasI := rank[items[i].Name]
rankJ, hasJ := rank[items[j].Name]
if hasI && hasJ {
return rankI < rankJ
}
return strings.Compare(items[i].Name, items[j].Name) < 0
})
// Sort Children
for i := range items {
if len(items[i].Children) > 0 {
Sort(items[i].Children, nil)
}
}
}
// Grouping by name
func Grouping(items map[string]interface{}) map[string]interface{} {
grouping := map[string]interface{}{}
for name, item := range items {
paths := strings.Split(name, string(os.PathSeparator))
node := grouping
for _, path := range paths {
if strings.HasSuffix(path, ".json") {
node[path] = Item{Name: path, Data: item, Children: []Item{}}
continue
}
if _, has := node[path]; !has {
node[path] = map[string]interface{}{"name": path, "data": map[string]interface{}{}}
}
node = node[path].(map[string]interface{})
}
}
return grouping
}
// Array to Array
func Array(groupingItems map[string]interface{}, res []Item) []Item {
for key, item := range groupingItems {
switch it := item.(type) {
case map[string]interface{}: // Path
if it["name"] == nil {
break
}
res = append(res, Item{
Name: key,
Data: nil,
Children: Array(it, []Item{}),
})
break
case Item: // Data
res = append(res, it)
break
}
}
return res
}

32
widgets/process.go Normal file
View file

@ -0,0 +1,32 @@
package widgets
import (
"github.com/yaoapp/gou"
)
// WidgetHandlers Processes
var WidgetHandlers = map[string]gou.ProcessHandler{
"apis": processApis,
}
func init() {
gou.RegisterProcessGroup("widget", WidgetHandlers)
}
// Get the loaded APIs
func processApis(process *gou.Process) interface{} {
return Apis()
}
// Get the actions of each widget
func processActions() {
}
// Get the loaded Models
func processModels() {}
// Get the loaded flows
func processFlows() {}
// Get the loaded Models
func processScripts() {}

27
widgets/process_test.go Normal file
View file

@ -0,0 +1,27 @@
package widgets
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/yaoapp/gou"
"github.com/yaoapp/yao/config"
)
func TestProcessApis(t *testing.T) {
testData(t)
args := []interface{}{}
res, err := gou.NewProcess("widget.apis", args...).Exec()
if err != nil {
t.Fatal(err)
}
assert.Greater(t, len(res.([]Item)), 0)
}
func testData(t *testing.T) {
prepare(t)
err := Load(config.Conf)
if err != nil {
t.Fatal(err)
}
}

View file

@ -4,6 +4,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/yaoapp/yao/api"
"github.com/yaoapp/yao/config"
"github.com/yaoapp/yao/i18n"
"github.com/yaoapp/yao/model"
@ -42,4 +43,10 @@ func prepare(t *testing.T, language ...string) {
t.Fatal(err)
}
// load apis
err = api.Load(config.Conf)
if err != nil {
t.Fatal(err)
}
}