Merge pull request #1456 from trheyi/main
Enhance script resolution logic and update asset metadata
This commit is contained in:
commit
aebebf49c5
7 changed files with 495 additions and 380 deletions
|
|
@ -29,42 +29,68 @@ func NewScriptRunner(opts *Options) *ScriptRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResolveScript resolves the script path from scripts.xxx.yyy or scripts.xxx.yyy.zzz format
|
// ResolveScript resolves the script path from scripts.xxx.yyy or scripts.xxx.yyy.zzz format
|
||||||
|
//
|
||||||
|
// Resolution strategy:
|
||||||
|
// 1. Find the assistant directory by detecting package.yao from longest to shortest path
|
||||||
|
// 2. Remaining parts after the assistant boundary map to src/ subdirectories + module name
|
||||||
|
//
|
||||||
|
// Examples:
|
||||||
|
// - scripts.expense.setup -> assistants/expense/src/setup_test.ts
|
||||||
|
// - scripts.yao.keeper.seed -> assistants/yao/keeper/src/seed_test.ts
|
||||||
|
// - scripts.yao.keeper.tests.seed -> assistants/yao/keeper/src/tests/seed_test.ts
|
||||||
func ResolveScript(input string) (*ScriptInfo, error) {
|
func ResolveScript(input string) (*ScriptInfo, error) {
|
||||||
// Remove "scripts." prefix
|
// Remove "scripts." prefix
|
||||||
path := strings.TrimPrefix(input, "scripts.")
|
path := strings.TrimPrefix(input, "scripts.")
|
||||||
|
|
||||||
// Split into parts:
|
// Split into parts:
|
||||||
// "expense.setup" -> ["expense", "setup"]
|
// "expense.setup" -> ["expense", "setup"]
|
||||||
// "expense.submission.validation" -> ["expense", "submission", "validation"]
|
// "yao.keeper.tests.seed" -> ["yao", "keeper", "tests", "seed"]
|
||||||
parts := strings.Split(path, ".")
|
parts := strings.Split(path, ".")
|
||||||
if len(parts) < 2 {
|
if len(parts) < 2 {
|
||||||
return nil, fmt.Errorf("invalid script path: %s (expected format: scripts.assistant.module or scripts.assistant.sub_agent.module)", input)
|
return nil, fmt.Errorf("invalid script path: %s (expected format: scripts.assistant.module or scripts.assistant.sub.module)", input)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build paths based on number of parts
|
// Strategy: detect assistant boundary by looking for package.yao
|
||||||
var basePaths []string
|
// Try from the longest possible assistant path down to the shortest
|
||||||
var assistantDir, moduleName string
|
var assistantDir, modulePath string
|
||||||
|
assistantFound := false
|
||||||
|
|
||||||
if len(parts) == 2 {
|
for i := len(parts) - 1; i >= 1; i-- {
|
||||||
// Format: scripts.expense.setup
|
candidateDir := strings.Join(parts[:i], "/")
|
||||||
// assistantDir: expense
|
for _, prefix := range []string{"assistants/", ""} {
|
||||||
// moduleName: setup
|
packagePath := filepath.Join(prefix+candidateDir, "package.yao")
|
||||||
assistantDir = parts[0]
|
exists, err := application.App.Exists(packagePath)
|
||||||
moduleName = parts[1]
|
if err == nil && exists {
|
||||||
basePaths = []string{
|
assistantDir = candidateDir
|
||||||
filepath.Join("assistants", assistantDir, "src"),
|
// Remaining parts form the module path (may include subdirectories)
|
||||||
filepath.Join(assistantDir, "src"),
|
// e.g., parts[i:] = ["tests", "seed"] -> "tests/seed"
|
||||||
|
modulePath = strings.Join(parts[i:], "/")
|
||||||
|
assistantFound = true
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
if assistantFound {
|
||||||
// Format: scripts.expense.submission.validation (sub-agent)
|
break
|
||||||
// assistantDir: expense/submission (or expense.submission)
|
}
|
||||||
// moduleName: validation
|
}
|
||||||
|
|
||||||
|
// Fallback: original behavior — last part is module, rest is assistant dir
|
||||||
|
if !assistantFound {
|
||||||
assistantDir = strings.Join(parts[:len(parts)-1], "/")
|
assistantDir = strings.Join(parts[:len(parts)-1], "/")
|
||||||
moduleName = parts[len(parts)-1]
|
modulePath = parts[len(parts)-1]
|
||||||
basePaths = []string{
|
}
|
||||||
filepath.Join("assistants", assistantDir, "src"),
|
|
||||||
filepath.Join(assistantDir, "src"),
|
// modulePath may contain subdirectories: "tests/seed" -> dir="tests", module="seed"
|
||||||
}
|
moduleName := filepath.Base(modulePath)
|
||||||
|
moduleSubDir := filepath.Dir(modulePath)
|
||||||
|
if moduleSubDir == "." {
|
||||||
|
moduleSubDir = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build candidate base paths
|
||||||
|
basePaths := []string{
|
||||||
|
filepath.Join("assistants", assistantDir, "src", moduleSubDir),
|
||||||
|
filepath.Join(assistantDir, "src", moduleSubDir),
|
||||||
}
|
}
|
||||||
|
|
||||||
var scriptPath, testPath string
|
var scriptPath, testPath string
|
||||||
|
|
|
||||||
769
data/bindata.go
769
data/bindata.go
File diff suppressed because one or more lines are too long
|
|
@ -685,7 +685,7 @@ func (page *Page) BuildStyles(ctx *BuildContext, option *BuildOption, component
|
||||||
|
|
||||||
if option.ComponentName != "" {
|
if option.ComponentName != "" {
|
||||||
code = cssRe.ReplaceAllStringFunc(code, func(css string) string {
|
code = cssRe.ReplaceAllStringFunc(code, func(css string) string {
|
||||||
return fmt.Sprintf("[s\\:cn=%s] %s", option.ComponentName, css)
|
return fmt.Sprintf("[s\\:cn=\"%s\"] %s", option.ComponentName, css)
|
||||||
})
|
})
|
||||||
res, err := page.CompileCSS([]byte(code), option.StyleMinify)
|
res, err := page.CompileCSS([]byte(code), option.StyleMinify)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -75,11 +75,29 @@ func (parser *TemplateParser) Locale() *Locale {
|
||||||
return locale
|
return locale
|
||||||
}
|
}
|
||||||
|
|
||||||
path := filepath.Join("public", parser.option.Root, ".locales", name, strings.TrimPrefix(route, root)+".yml")
|
// Try exact locale first, then fallback to language prefix (e.g. zh-cn -> zh), then en-us
|
||||||
if exists, err := application.App.Exists(path); !exists {
|
routeSuffix := strings.TrimPrefix(route, root) + ".yml"
|
||||||
if err != nil {
|
candidates := []string{name}
|
||||||
|
if parts := strings.SplitN(name, "-", 2); len(parts) == 2 {
|
||||||
|
candidates = append(candidates, parts[0])
|
||||||
|
}
|
||||||
|
if name != "en-us" {
|
||||||
|
candidates = append(candidates, "en-us")
|
||||||
|
}
|
||||||
|
|
||||||
|
var path string
|
||||||
|
found := false
|
||||||
|
for _, candidate := range candidates {
|
||||||
|
path = filepath.Join("public", parser.option.Root, ".locales", candidate, routeSuffix)
|
||||||
|
if exists, err := application.App.Exists(path); exists {
|
||||||
|
found = true
|
||||||
|
name = candidate
|
||||||
|
break
|
||||||
|
} else if err != nil {
|
||||||
log.Error("[parser] %s Locale %s", route, err.Error())
|
log.Error("[parser] %s Locale %s", route, err.Error())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ func (r *Request) NewData() Data {
|
||||||
// GetLocale get the locale
|
// GetLocale get the locale
|
||||||
func GetLocale(cookies map[string]string) interface{} {
|
func GetLocale(cookies map[string]string) interface{} {
|
||||||
if lang, has := cookies["locale"]; has {
|
if lang, has := cookies["locale"]; has {
|
||||||
return lang
|
return strings.ToLower(lang)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,8 @@ func ComponentName(name string, hash ...bool) string {
|
||||||
name = strings.ReplaceAll(name, "/", "_")
|
name = strings.ReplaceAll(name, "/", "_")
|
||||||
name = strings.ReplaceAll(name, "[", "_")
|
name = strings.ReplaceAll(name, "[", "_")
|
||||||
name = strings.ReplaceAll(name, "]", "_")
|
name = strings.ReplaceAll(name, "]", "_")
|
||||||
|
name = strings.ReplaceAll(name, ".", "_")
|
||||||
|
name = strings.ReplaceAll(name, "-", "_")
|
||||||
cn := fmt.Sprintf("comp_%s", name)
|
cn := fmt.Sprintf("comp_%s", name)
|
||||||
// Keep the component name | hash will be supported later
|
// Keep the component name | hash will be supported later
|
||||||
// if len(hash) > 0 && hash[0] {
|
// if len(hash) > 0 && hash[0] {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ function $$(selector) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function __sui_component_root(elm: Element, name: string) {
|
function __sui_component_root(elm: Element, name: string) {
|
||||||
return elm.closest(`[s\\:cn=${name}]`);
|
return elm.closest(`[s\\:cn="${name}"]`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function __sui_state(component) {
|
function __sui_state(component) {
|
||||||
|
|
@ -210,7 +210,7 @@ function __sui_event_init(elm: Element) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const component = eventElm.closest(`[s\\:cn=${cn}]`);
|
const component = eventElm.closest(`[s\\:cn="${cn}"]`);
|
||||||
if (typeof window[cn] !== "function") {
|
if (typeof window[cn] !== "function") {
|
||||||
console.error(`[SUI] Component ${cn} not found`, eventElm);
|
console.error(`[SUI] Component ${cn} not found`, eventElm);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue