[add] widget.apis process
This commit is contained in:
parent
1c1b551715
commit
0d8ff4073a
6 changed files with 387 additions and 0 deletions
1
widgets/action.go
Normal file
1
widgets/action.go
Normal file
|
|
@ -0,0 +1 @@
|
|||
package widgets
|
||||
231
widgets/api.go
Normal file
231
widgets/api.go
Normal 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
89
widgets/item.go
Normal 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
32
widgets/process.go
Normal 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
27
widgets/process_test.go
Normal 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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue