Skip to content

Commit

Permalink
[add] widget.apis process
Browse files Browse the repository at this point in the history
  • Loading branch information
trheyi committed Dec 3, 2022
1 parent 1c1b551 commit 0d8ff40
Show file tree
Hide file tree
Showing 6 changed files with 387 additions and 0 deletions.
1 change: 1 addition & 0 deletions widgets/action.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package widgets
231 changes: 231 additions & 0 deletions widgets/api.go
Original file line number Diff line number Diff line change
@@ -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 changes: 89 additions & 0 deletions widgets/item.go
Original file line number Diff line number Diff line change
@@ -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 changes: 32 additions & 0 deletions widgets/process.go
Original file line number Diff line number Diff line change
@@ -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 changes: 27 additions & 0 deletions widgets/process_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
}
Loading

0 comments on commit 0d8ff40

Please sign in to comment.