Merge pull request #730 from trheyi/main

[feat] SUI $backend function call supports custom Guard
This commit is contained in:
Max 2024-08-05 08:39:32 +08:00 committed by GitHub
commit f6fd4423ca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 448 additions and 333 deletions

File diff suppressed because one or more lines are too long

View file

@ -30,231 +30,236 @@ var dsl = []byte(`
"in": [":context", "$param.route", ":payload"], "in": [":context", "$param.route", ":payload"],
"out": { "status": 200, "type": "application/json" } "out": { "status": 200, "type": "application/json" }
}, },
{ //
"path": "/:id/setting", //
"method": "GET", // Remove the following code
"process": "sui.Setting", // Developer can create the API by using the process of sui.* directly
"in": ["$param.id"], //
"out": { "status": 200, "type": "application/json" } // {
}, // "path": "/:id/setting",
// "method": "GET",
// "process": "sui.Setting",
// "in": ["$param.id"],
// "out": { "status": 200, "type": "application/json" }
// },
{ // {
"path": "/:id/template", // "path": "/:id/template",
"method": "GET", // "method": "GET",
"process": "sui.Template.Get", // "process": "sui.Template.Get",
"in": ["$param.id"], // "in": ["$param.id"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
},{ // },{
"path": "/:id/template/:template_id", // "path": "/:id/template/:template_id",
"method": "GET", // "method": "GET",
"process": "sui.Template.Find", // "process": "sui.Template.Find",
"in": ["$param.id", "$param.template_id"], // "in": ["$param.id", "$param.template_id"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
}, // },
{ // {
"path": "/:id/locale/:template_id", // "path": "/:id/locale/:template_id",
"method": "GET", // "method": "GET",
"process": "sui.Locale.Get", // "process": "sui.Locale.Get",
"in": ["$param.id", "$param.template_id"], // "in": ["$param.id", "$param.template_id"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
},{ // },{
"path": "/:id/theme/:template_id", // "path": "/:id/theme/:template_id",
"method": "GET", // "method": "GET",
"process": "sui.Theme.Get", // "process": "sui.Theme.Get",
"in": ["$param.id", "$param.template_id"], // "in": ["$param.id", "$param.template_id"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
}, // },
{ // {
"path": "/:id/block/:template_id", // "path": "/:id/block/:template_id",
"method": "GET", // "method": "GET",
"process": "sui.Block.Get", // "process": "sui.Block.Get",
"in": ["$param.id", "$param.template_id"], // "in": ["$param.id", "$param.template_id"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
},{ // },{
"path": "/:id/block/export/:template_id", // "path": "/:id/block/export/:template_id",
"method": "GET", // "method": "GET",
"process": "sui.Block.Export", // "process": "sui.Block.Export",
"in": ["$param.id", "$param.template_id"], // "in": ["$param.id", "$param.template_id"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
},{ // },{
"path": "/:id/block/:template_id/:block_id", // "path": "/:id/block/:template_id/:block_id",
"guard": "query-jwt", // "guard": "query-jwt",
"method": "GET", // "method": "GET",
"process": "sui.Block.Find", // "process": "sui.Block.Find",
"in": ["$param.id", "$param.template_id", "$param.block_id"], // "in": ["$param.id", "$param.template_id", "$param.block_id"],
"out": { "status": 200, "type": "text/javascript" } // "out": { "status": 200, "type": "text/javascript" }
},{ // },{
"path": "/:id/block/:template_id/:block_id/media", // "path": "/:id/block/:template_id/:block_id/media",
"guard": "query-jwt", // "guard": "query-jwt",
"method": "GET", // "method": "GET",
"process": "sui.Block.Media", // "process": "sui.Block.Media",
"in": ["$param.id", "$param.template_id", "$param.block_id"], // "in": ["$param.id", "$param.template_id", "$param.block_id"],
"out": { // "out": {
"status": 200, // "status": 200,
"body": "?:content", // "body": "?:content",
"headers": { "Content-Type": "?:type"} // "headers": { "Content-Type": "?:type"}
} // }
}, // },
{ // {
"path": "/:id/component/:template_id", // "path": "/:id/component/:template_id",
"method": "GET", // "method": "GET",
"process": "sui.Component.Get", // "process": "sui.Component.Get",
"in": ["$param.id", "$param.template_id"], // "in": ["$param.id", "$param.template_id"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
},{ // },{
"path": "/:id/component/:template_id/:component_id", // "path": "/:id/component/:template_id/:component_id",
"guard": "query-jwt", // "guard": "query-jwt",
"method": "GET", // "method": "GET",
"process": "sui.Component.Find", // "process": "sui.Component.Find",
"in": ["$param.id", "$param.template_id", "$param.component_id"], // "in": ["$param.id", "$param.template_id", "$param.component_id"],
"out": { "status": 200, "type": "text/javascript" } // "out": { "status": 200, "type": "text/javascript" }
}, // },
{ // {
"path": "/:id/page/:template_id/*route", // "path": "/:id/page/:template_id/*route",
"method": "GET", // "method": "GET",
"process": "sui.Page.Get", // "process": "sui.Page.Get",
"in": ["$param.id", "$param.template_id", "$param.route"], // "in": ["$param.id", "$param.template_id", "$param.route"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
},{ // },{
"path": "/:id/page/tree/:template_id/*route", // "path": "/:id/page/tree/:template_id/*route",
"method": "GET", // "method": "GET",
"process": "sui.Page.Tree", // "process": "sui.Page.Tree",
"in": ["$param.id", "$param.template_id", "$param.route"], // "in": ["$param.id", "$param.template_id", "$param.route"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
},{ // },{
"path": "/:id/page/save/:template_id/*route", // "path": "/:id/page/save/:template_id/*route",
"method": "POST", // "method": "POST",
"process": "sui.Page.Save", // "process": "sui.Page.Save",
"in": ["$param.id", "$param.template_id", "$param.route", ":context"], // "in": ["$param.id", "$param.template_id", "$param.route", ":context"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
},{ // },{
"path": "/:id/page/temp/:template_id/*route", // "path": "/:id/page/temp/:template_id/*route",
"method": "POST", // "method": "POST",
"process": "sui.Page.SaveTemp", // "process": "sui.Page.SaveTemp",
"in": ["$param.id", "$param.template_id", "$param.route", ":context"], // "in": ["$param.id", "$param.template_id", "$param.route", ":context"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
},{ // },{
"path": "/:id/page/create/:template_id/*route", // "path": "/:id/page/create/:template_id/*route",
"method": "POST", // "method": "POST",
"process": "sui.Page.Create", // "process": "sui.Page.Create",
"in": ["$param.id", "$param.template_id", "$param.route", ":context", ":payload"], // "in": ["$param.id", "$param.template_id", "$param.route", ":context", ":payload"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
},{ // },{
"path": "/:id/page/duplicate/:template_id/*route", // "path": "/:id/page/duplicate/:template_id/*route",
"method": "POST", // "method": "POST",
"process": "sui.Page.Duplicate", // "process": "sui.Page.Duplicate",
"in": ["$param.id", "$param.template_id", "$param.route", ":payload"], // "in": ["$param.id", "$param.template_id", "$param.route", ":payload"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
},{ // },{
"path": "/:id/page/rename/:template_id/*route", // "path": "/:id/page/rename/:template_id/*route",
"method": "POST", // "method": "POST",
"process": "sui.Page.Rename", // "process": "sui.Page.Rename",
"in": ["$param.id", "$param.template_id", "$param.route", ":payload"], // "in": ["$param.id", "$param.template_id", "$param.route", ":payload"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
},{ // },{
"path": "/:id/page/exist/:template_id/*route", // "path": "/:id/page/exist/:template_id/*route",
"method": "GET", // "method": "GET",
"process": "sui.Page.Exist", // "process": "sui.Page.Exist",
"in": ["$param.id", "$param.template_id", "$param.route"], // "in": ["$param.id", "$param.template_id", "$param.route"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
},{ // },{
"path": "/:id/page/remove/:template_id/*route", // "path": "/:id/page/remove/:template_id/*route",
"method": "POST", // "method": "POST",
"process": "sui.Page.Remove", // "process": "sui.Page.Remove",
"in": ["$param.id", "$param.template_id", "$param.route"], // "in": ["$param.id", "$param.template_id", "$param.route"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
}, // },
{ // {
"path": "/:id/editor/render/:template_id/*route", // "path": "/:id/editor/render/:template_id/*route",
"method": "GET", // "method": "GET",
"process": "sui.Editor.Render", // "process": "sui.Editor.Render",
"in": ["$param.id", "$param.template_id", "$param.route", ":query"], // "in": ["$param.id", "$param.template_id", "$param.route", ":query"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
},{ // },{
"path": "/:id/editor/render/:template_id/*route", // "path": "/:id/editor/render/:template_id/*route",
"method": "POST", // "method": "POST",
"process": "sui.Editor.RenderAfterSaveTemp", // "process": "sui.Editor.RenderAfterSaveTemp",
"in": ["$param.id", "$param.template_id", "$param.route", ":context", ":query"], // "in": ["$param.id", "$param.template_id", "$param.route", ":context", ":query"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
},{ // },{
"path": "/:id/editor/:kind/source/:template_id/*route", // "path": "/:id/editor/:kind/source/:template_id/*route",
"method": "GET", // "method": "GET",
"process": "sui.Editor.Source", // "process": "sui.Editor.Source",
"in": ["$param.id", "$param.template_id", "$param.route", "$param.kind", ":query"], // "in": ["$param.id", "$param.template_id", "$param.route", "$param.kind", ":query"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
},{ // },{
"path": "/:id/editor/:kind/source/:template_id/*route", // "path": "/:id/editor/:kind/source/:template_id/*route",
"method": "POST", // "method": "POST",
"process": "sui.Editor.SourceAfterSaveTemp", // "process": "sui.Editor.SourceAfterSaveTemp",
"in": ["$param.id", "$param.template_id", "$param.route", ":context", "$param.kind", ":query"], // "in": ["$param.id", "$param.template_id", "$param.route", ":context", "$param.kind", ":query"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
}, // },
{ // {
"path": "/:id/asset/:template_id/@assets/*path", // "path": "/:id/asset/:template_id/@assets/*path",
"method": "GET", // "method": "GET",
"guard": "-", // "guard": "-",
"process": "sui.Template.Asset", // "process": "sui.Template.Asset",
"in": ["$param.id", "$param.template_id", "$param.path", "$query.w", "$query.h"], // "in": ["$param.id", "$param.template_id", "$param.path", "$query.w", "$query.h"],
"out": { // "out": {
"status": 200, // "status": 200,
"body": "?:content", // "body": "?:content",
"headers": { "Content-Type": "?:type"} // "headers": { "Content-Type": "?:type"}
} // }
},{ // },{
"path": "/:id/asset/:template_id/upload", // "path": "/:id/asset/:template_id/upload",
"method": "POST", // "method": "POST",
"process": "sui.Template.AssetUpload", // "process": "sui.Template.AssetUpload",
"in": ["$param.id", "$param.template_id", ":context"], // "in": ["$param.id", "$param.template_id", ":context"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
},{ // },{
"path": "/:id/asset/:template_id/@pages/*path", // "path": "/:id/asset/:template_id/@pages/*path",
"guard": "query-jwt", // "guard": "query-jwt",
"method": "GET", // "method": "GET",
"process": "sui.Page.Asset", // "process": "sui.Page.Asset",
"in": ["$param.id", "$param.template_id", "$param.path", "$query.w", "$query.h"], // "in": ["$param.id", "$param.template_id", "$param.path", "$query.w", "$query.h"],
"out": { // "out": {
"status": 200, // "status": 200,
"body": "?:content", // "body": "?:content",
"headers": { "Content-Type": "?:type"} // "headers": { "Content-Type": "?:type"}
} // }
}, // },
{ // {
"path": "/:id/media/:driver/search", // "path": "/:id/media/:driver/search",
"method": "GET", // "method": "GET",
"process": "sui.Media.Search", // "process": "sui.Media.Search",
"in": ["$param.id", "$param.driver", ":query"], // "in": ["$param.id", "$param.driver", ":query"],
"out": { "status": 200, "type": "application/json" } // "out": { "status": 200, "type": "application/json" }
}, // },
{ // {
"path": "/:id/preview/:template_id/*route", // "path": "/:id/preview/:template_id/*route",
"guard": "query-jwt", // "guard": "query-jwt",
"method": "GET", // "method": "GET",
"process": "sui.Preview.Render", // "process": "sui.Preview.Render",
"in": ["$param.id", "$param.template_id", "$param.route", "$header.Referer"], // "in": ["$param.id", "$param.template_id", "$param.route", "$header.Referer"],
"out": {"status": 200, "type": "text/html; charset=utf-8"} // "out": {"status": 200, "type": "text/html; charset=utf-8"}
}, // },
{ // {
"path": "/:id/build/:template_id", // "path": "/:id/build/:template_id",
"method": "POST", // "method": "POST",
"process": "sui.Build.All", // "process": "sui.Build.All",
"in": ["$param.id", "$param.template_id", ":payload"], // "in": ["$param.id", "$param.template_id", ":payload"],
"out": {"status": 200} // "out": {"status": 200}
},{ // },{
"path": "/:id/build/:template_id/*route", // "path": "/:id/build/:template_id/*route",
"method": "POST", // "method": "POST",
"process": "sui.Build.Page", // "process": "sui.Build.Page",
"in": ["$param.id", "$param.template_id", "$param.route", ":payload"], // "in": ["$param.id", "$param.template_id", "$param.route", ":payload"],
"out": {"status": 200} // "out": {"status": 200}
} // }
], ],
} }
`) `)

View file

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"fmt" "fmt"
"io" "io"
"strconv"
"strings" "strings"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -157,7 +158,7 @@ func (r *Request) scriptGuardExec(c *gin.Context, name string, args []interface{
script, err := v8.Select(id) script, err := v8.Select(id)
if err != nil { if err != nil {
c.JSON(403, gin.H{"code": 403, "message": fmt.Sprintf("Guard: %s %s", name, err.Error())}) c.JSON(403, gin.H{"code": 403, "message": err.Error()})
c.Abort() c.Abort()
return err return err
} }
@ -394,7 +395,29 @@ func (r *Request) scriptGuardExec(c *gin.Context, name string, args []interface{
_, err = ctx.Call(method, args...) _, err = ctx.Call(method, args...)
if err != nil { if err != nil {
c.JSON(403, gin.H{"code": 403, "message": fmt.Sprintf("Guard: %s %s", name, err.Error())})
message := err.Error()
if strings.HasPrefix(message, "Exception|") {
parts := strings.Split(message, ": ")
fmt.Println(parts)
if len(parts) > 1 {
codestr := strings.TrimPrefix(parts[0], "Exception|")
message := parts[1]
code := 403
if codestr != "" {
if v, err := strconv.Atoi(codestr); err == nil {
code = v
}
}
c.JSON(code, gin.H{"code": code, "message": message})
c.Abort()
return err
}
}
c.JSON(403, gin.H{"code": 403, "message": message})
c.Abort() c.Abort()
return err return err
} }

View file

@ -2,14 +2,24 @@ package api
import ( import (
"path/filepath" "path/filepath"
"strings"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
jsoniter "github.com/json-iterator/go"
"github.com/yaoapp/gou/application"
"github.com/yaoapp/gou/process" "github.com/yaoapp/gou/process"
"github.com/yaoapp/kun/exception" "github.com/yaoapp/kun/exception"
"github.com/yaoapp/kun/log" "github.com/yaoapp/kun/log"
"github.com/yaoapp/yao/sui/core" "github.com/yaoapp/yao/sui/core"
) )
var configs = map[string]*core.PageConfig{}
var chConfig = make(chan *core.PageConfig, 1)
func init() {
go configWriter()
}
// Run the backend script, with Api prefix method // Run the backend script, with Api prefix method
func Run(process *process.Process) interface{} { func Run(process *process.Process) interface{} {
process.ValidateArgNums(3) process.ValidateArgNums(3)
@ -38,17 +48,6 @@ func Run(process *process.Process) interface{} {
return nil return nil
} }
if payload["page"] == nil {
exception.New("The page is required", 400).Throw()
return nil
}
page, ok := payload["page"].(string)
if !ok {
exception.New("The page must be a string", 400).Throw()
return nil
}
args := []interface{}{} args := []interface{}{}
if payload["args"] != nil { if payload["args"] != nil {
args, ok = payload["args"].([]interface{}) args, ok = payload["args"].([]interface{})
@ -58,41 +57,39 @@ func Run(process *process.Process) interface{} {
} }
} }
ctx.Request.URL.Path = page
r, _, err := NewRequestContext(ctx) r, _, err := NewRequestContext(ctx)
if err != nil { if err != nil {
exception.Err(err, 500).Throw() exception.Err(err, 500).Throw()
return nil return nil
} }
var c *core.Cache = nil
if !r.Request.DisableCache() {
c = core.GetCache(r.File)
}
if c == nil {
c, _, err = r.MakeCache()
if err != nil {
log.Error("[SUI] Can't make cache, %s %s error: %s", route, method, err.Error())
exception.New("Can't make cache, the route and method is correct, get more information from the log.", 500).Throw()
return nil
}
}
// Guard the page
code, err := r.Guard(c)
if err != nil {
exception.Err(err, code).Throw()
return nil
}
if c == nil {
exception.New("Cache not found", 500).Throw()
return nil
}
// Load the script // Load the script
file := filepath.Join("/public", route) file := filepath.Join("/public", route)
// Get the page config
cfg, err := getPageConfig(file, r.Request.DisableCache())
if err != nil {
log.Error("Can't load the page config (%s), %s", route, err.Error())
exception.New("Can't load the page config (%s), get more information from the log.", 500, route).Throw()
return nil
}
// Config and guard
prefix := "Api"
if cfg != nil {
_, err := r.apiGuard(method, cfg.API)
if err != nil {
log.Error("Guard error: %s", err.Error())
r.context.Done()
return nil
}
// Custom prefix
if cfg.API != nil && cfg.API.Prefix != "" {
prefix = cfg.API.Prefix
}
}
script, err := core.LoadScript(file, r.Request.DisableCache()) script, err := core.LoadScript(file, r.Request.DisableCache())
if err != nil { if err != nil {
exception.New("Can't load the script (%s), get more information from the log.", 500, route).Throw() exception.New("Can't load the script (%s), get more information from the log.", 500, route).Throw()
@ -106,18 +103,17 @@ func Run(process *process.Process) interface{} {
scriptCtx, err := script.NewContext(process.Sid, nil) scriptCtx, err := script.NewContext(process.Sid, nil)
if err != nil { if err != nil {
exception.Err(err, 500).Throw()
return nil return nil
} }
defer scriptCtx.Close() defer scriptCtx.Close()
global := scriptCtx.Global() global := scriptCtx.Global()
if !global.Has("Api" + method) { if !global.Has(prefix + method) {
exception.New("Method %s not found", 500, method).Throw() exception.New("Method %s not found", 500, method).Throw()
return nil return nil
} }
res, err := scriptCtx.Call("Api"+method, args...) res, err := scriptCtx.Call(prefix+method, args...)
if err != nil { if err != nil {
exception.Err(err, 500).Throw() exception.Err(err, 500).Throw()
return nil return nil
@ -125,3 +121,78 @@ func Run(process *process.Process) interface{} {
return res return res
} }
// getPageConfig get the page config
func getPageConfig(file string, disableCache ...bool) (*core.PageConfig, error) {
// LOAD FROM CACHE
base := strings.TrimSuffix(strings.TrimSuffix(file, ".sui"), ".jit")
if disableCache == nil || !disableCache[0] {
if cfg, has := configs[base]; has {
return cfg, nil
}
}
file = base + ".cfg"
if exist, _ := application.App.Exists(file); !exist {
return nil, nil
}
source, err := application.App.Read(file)
if err != nil {
return nil, err
}
cfg := core.PageConfig{}
err = jsoniter.Unmarshal(source, &cfg)
if err != nil {
return nil, err
}
// Save to cache
go func() { chConfig <- &cfg }()
return &cfg, nil
}
func (r *Request) apiGuard(method string, api *core.PageAPI) (int, error) {
if api == nil {
return 200, nil
}
guard := api.DefaultGuard
if api.Guards != nil {
if g, has := api.Guards[method]; has {
guard = g
}
}
if guard == "" || guard == "-" {
return 200, nil
}
// Build in guard
if guard, has := Guards[guard]; has {
err := guard(r)
if err != nil {
return 403, err
}
return 200, nil
}
// Developer custom guard
err := r.processGuard(guard)
if err != nil {
return 403, err
}
return 200, nil
}
func configWriter() {
for {
select {
case config := <-chConfig:
configs[config.Root] = config
}
}
}

View file

@ -61,15 +61,16 @@ func (page *Page) GetConfig() *PageConfig {
// ExportConfig export the config // ExportConfig export the config
func (page *Page) ExportConfig() string { func (page *Page) ExportConfig() string {
if page.Config == nil { if page.Config == nil {
return fmt.Sprintf(`{"cache_store": "%s"}`, page.CacheStore) return fmt.Sprintf(`{"cacheStore": "%s"}`, page.CacheStore)
} }
config, err := jsoniter.MarshalToString(map[string]interface{}{ config, err := jsoniter.MarshalToString(map[string]interface{}{
"title": page.Config.Title, "title": page.Config.Title,
"guard": page.Config.Guard, "guard": page.Config.Guard,
"cache_store": page.CacheStore, "cacheStore": page.CacheStore,
"cache": page.Config.Cache, "cache": page.Config.Cache,
"data_cache": page.Config.DataCache, "dataCache": page.Config.DataCache,
"api": page.Config.API,
"root": page.Root, "root": page.Root,
}) })

View file

@ -378,9 +378,10 @@ type PageSetting struct {
CacheStore string `json:"cache_store,omitempty"` CacheStore string `json:"cache_store,omitempty"`
Cache int `json:"cache,omitempty"` Cache int `json:"cache,omitempty"`
Root string `json:"root,omitempty"` Root string `json:"root,omitempty"`
DataCache int `json:"data_cache,omitempty"` DataCache int `json:"dataCache,omitempty"`
Description string `json:"description,omitempty"` Description string `json:"description,omitempty"`
SEO *PageSEO `json:"seo,omitempty"` SEO *PageSEO `json:"seo,omitempty"`
API *PageAPI `json:"api,omitempty"`
} }
// PageConfigRendered is the struct for the page config rendered // PageConfigRendered is the struct for the page config rendered
@ -389,6 +390,13 @@ type PageConfigRendered struct {
Link string `json:"link,omitempty"` Link string `json:"link,omitempty"`
} }
// PageAPI is the struct for the page api
type PageAPI struct {
Prefix string `json:"prefix,omitempty"`
DefaultGuard string `json:"defaultGuard,omitempty"`
Guards map[string]string `json:"guards,omitempty"`
}
// PageSEO is the struct for the page seo // PageSEO is the struct for the page seo
type PageSEO struct { type PageSEO struct {
Title string `json:"title,omitempty"` Title string `json:"title,omitempty"`

View file

@ -221,16 +221,18 @@ function __sui_store(elm) {
async function __sui_backend_call( async function __sui_backend_call(
route: string, route: string,
page: string, headers: [string, string][] | Record<string, string> | Headers,
method: string, method: string,
...args: any ...args: any
): Promise<any> { ): Promise<any> {
const url = `/api/__yao/sui/v1/run${route}`; const url = `/api/__yao/sui/v1/run${route}`;
const headers = { headers = {
"Content-Type": "application/json", "Content-Type": "application/json",
Referer: window.location.href,
Cookie: document.cookie, Cookie: document.cookie,
...headers,
}; };
const payload = { method, args, page }; const payload = { method, args };
try { try {
const body = JSON.stringify(payload); const body = JSON.stringify(payload);
const response = await fetch(url, { method: "POST", headers, body: body }); const response = await fetch(url, { method: "POST", headers, body: body });

View file

@ -176,25 +176,30 @@ class __Render {
} }
} }
function $Backend(route?: string) { function $Backend(
const page = window.location.pathname; route?: string,
headers?: [string, string][] | Record<string, string> | Headers
) {
const root = document.body.getAttribute("s:public") || "/"; const root = document.body.getAttribute("s:public") || "/";
route = route || page; route = route || window.location.pathname;
const re = new RegExp("^" + root); const re = new RegExp("^" + root);
route = root + route.replace(re, ""); route = root + route.replace(re, "");
return new __Backend(route, page); return new __Backend(route, headers);
} }
class __Backend { class __Backend {
route = ""; route = "";
page = ""; headers: [string, string][] | Record<string, string> | Headers = {};
constructor(route: string, page: string) { constructor(
route: string,
headers: [string, string][] | Record<string, string> | Headers = {}
) {
this.route = route; this.route = route;
this.page = page; this.headers = headers;
} }
async Call(method: string, ...args: any): Promise<any> { async Call(method: string, ...args: any): Promise<any> {
// @ts-ignore // @ts-ignore
return await __sui_backend_call(this.route, this.page, method, ...args); return await __sui_backend_call(this.route, this.headers, method, ...args);
} }
} }