diff --git a/attachment/load.go b/attachment/load.go new file mode 100644 index 00000000..1105256e --- /dev/null +++ b/attachment/load.go @@ -0,0 +1,152 @@ +package attachment + +import ( + "fmt" + "strings" + + "github.com/yaoapp/gou/application" + "github.com/yaoapp/kun/log" + "github.com/yaoapp/yao/config" + "github.com/yaoapp/yao/data" + "github.com/yaoapp/yao/share" +) + +// SystemUploaders system uploaders +var systemUploaders = map[string]string{ + "__yao.attachment": "yao/uploaders/attachment.local.yao", +} + +// Load load uploaders +func Load(cfg config.Config) error { + messages := []string{} + + // Load system uploaders + err := loadSystemUploaders(cfg) + if err != nil { + return err + } + + // Load filesystem uploaders + exts := []string{"*.s3.yao", "*.local.yao", "*.s3.json", "*.local.json", "*.s3.jsonc", "*.local.jsonc"} + err = application.App.Walk("uploaders", func(root, file string, isdir bool) error { + if isdir { + return nil + } + + // Skip if not uploader file + if !isUploaderFile(file) { + return nil + } + + err := loadUploaderFile(root, file, cfg) + if err != nil { + messages = append(messages, err.Error()) + } + return err + }, exts...) + + if len(messages) > 0 { + for _, message := range messages { + log.Error("Load filesystem uploaders error: %s", message) + } + return fmt.Errorf(strings.Join(messages, ";\n")) + } + + return nil +} + +// loadSystemUploaders load system uploaders +func loadSystemUploaders(cfg config.Config) error { + for id, path := range systemUploaders { + content, err := data.Read(path) + if err != nil { + return err + } + + // Parse uploader config + var option ManagerOption + err = application.Parse(path, content, &option) + if err != nil { + return err + } + + // Replace environment variables and paths + option.ReplaceEnv(cfg.DataRoot) + + // Register the uploader manager + _, err = Register(id, option.Driver, option) + if err != nil { + log.Error("register system uploader %s error: %s", id, err.Error()) + return err + } + + log.Info("loaded system uploader: %s (%s)", id, option.Label) + } + + return nil +} + +// loadUploaderFile load a single uploader file +func loadUploaderFile(root, file string, cfg config.Config) error { + // Generate uploader ID + id := share.ID(root, file) + + // Read file content + content, err := application.App.Read(file) + if err != nil { + return fmt.Errorf("failed to read uploader file %s: %v", file, err) + } + + // Parse uploader config + var option ManagerOption + err = application.Parse(file, content, &option) + if err != nil { + return fmt.Errorf("failed to parse uploader file %s: %v", file, err) + } + + // Validate driver consistency between filename and config + filenameDriver := extractDriverFromFilename(file) + if filenameDriver != "" && option.Driver != "" && filenameDriver != option.Driver { + log.Warn("Driver mismatch in uploader file %s: filename suggests '%s' but config has '%s'", + file, filenameDriver, option.Driver) + } + + // Replace environment variables and paths + option.ReplaceEnv(cfg.DataRoot) + + // Register the uploader manager + _, err = Register(id, option.Driver, option) + if err != nil { + log.Error("register uploader %s error: %s", id, err.Error()) + return fmt.Errorf("failed to register uploader %s: %v", id, err) + } + + log.Info("loaded uploader: %s (%s)", id, option.Label) + return nil +} + +// isUploaderFile checks if the file is an uploader configuration file +func isUploaderFile(filename string) bool { + // Accept files with specific driver patterns: *.s3.yao, *.local.yao, etc. + lower := strings.ToLower(filename) + return strings.HasSuffix(lower, ".s3.yao") || + strings.HasSuffix(lower, ".local.yao") || + strings.HasSuffix(lower, ".s3.json") || + strings.HasSuffix(lower, ".local.json") || + strings.HasSuffix(lower, ".s3.jsonc") || + strings.HasSuffix(lower, ".local.jsonc") +} + +// extractDriverFromFilename extracts the driver name from filename (e.g., "test.s3.yao" -> "s3") +func extractDriverFromFilename(filename string) string { + lower := strings.ToLower(filename) + + // Extract driver from patterns like "*.s3.yao", "*.local.json", etc. + if strings.Contains(lower, ".s3.") { + return "s3" + } else if strings.Contains(lower, ".local.") { + return "local" + } + + return "" +} diff --git a/attachment/load_test.go b/attachment/load_test.go new file mode 100644 index 00000000..180cd383 --- /dev/null +++ b/attachment/load_test.go @@ -0,0 +1,48 @@ +package attachment + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/yaoapp/yao/config" + "github.com/yaoapp/yao/test" +) + +func TestLoad(t *testing.T) { + test.Prepare(t, config.Conf) + defer test.Clean() + + err := Load(config.Conf) + assert.NoError(t, err) + check(t) +} + +func check(t *testing.T) { + // Check that managers are loaded + assert.NotEmpty(t, Managers, "Managers should not be empty after loading") + + // Check system uploader + _, exists := Managers["__yao.attachment"] + assert.True(t, exists, "System uploader __yao.attachment should be loaded") + + // Check test app uploaders (must exist) + // These are the uploaders in yao-dev-app/uploaders/ + _, hasData := Managers["data"] + _, hasTest := Managers["test"] + + // Both test uploaders should be loaded + assert.True(t, hasData, "Test uploader 'data' should be loaded from data.local.yao") + assert.True(t, hasTest, "Test uploader 'test' should be loaded from test.s3.yao") + + // Log all loaded managers for debugging + t.Logf("Loaded managers: %v", getManagerNames()) +} + +// getManagerNames returns a slice of manager names for testing +func getManagerNames() []string { + names := make([]string, 0, len(Managers)) + for name := range Managers { + names = append(names, name) + } + return names +} diff --git a/attachment/types.go b/attachment/types.go index 6dbd4fe3..4b8323ca 100644 --- a/attachment/types.go +++ b/attachment/types.go @@ -4,6 +4,8 @@ import ( "context" "io" "mime/multipart" + + "github.com/yaoapp/gou/types" ) // File the file @@ -25,17 +27,16 @@ type FileResponse struct { // Attachment represents a file attachment type Attachment struct { - Name string `json:"name,omitempty"` - URL string `json:"url,omitempty"` - Description string `json:"description,omitempty"` - Type string `json:"type,omitempty"` - ContentType string `json:"content_type,omitempty"` - Bytes int64 `json:"bytes,omitempty"` - CreatedAt int64 `json:"created_at,omitempty"` - FileID string `json:"file_id,omitempty"` - ChatID string `json:"chat_id,omitempty"` - AssistantID string `json:"assistant_id,omitempty"` - Gzip bool `json:"gzip,omitempty"` // Gzip the file, Optional, default is false + Name string `json:"name,omitempty"` + URL string `json:"url,omitempty"` + Description string `json:"description,omitempty"` + Type string `json:"type,omitempty"` + ContentType string `json:"content_type,omitempty"` + Bytes int64 `json:"bytes,omitempty"` + CreatedAt int64 `json:"created_at,omitempty"` + FileID string `json:"file_id,omitempty"` + Groups []string `json:"groups,omitempty"` + Gzip bool `json:"gzip,omitempty"` // Gzip the file, Optional, default is false } // Manager the manager struct @@ -61,6 +62,7 @@ type Storage interface { // ManagerOption the manager option type ManagerOption struct { + types.MetaInfo MaxSize string `json:"max_size,omitempty" yaml:"max_size,omitempty"` // Max size of the file, Optional, default is 20M ChunkSize string `json:"chunk_size,omitempty" yaml:"chunk_size,omitempty"` // Chunk size of the file, Optional, default is 2M AllowedTypes []string `json:"allowed_types,omitempty" yaml:"allowed_types,omitempty"` // Allowed types of the file, Optional, default is all diff --git a/data/bindata.go b/data/bindata.go index 0c53417e..ecefc4a0 100644 --- a/data/bindata.go +++ b/data/bindata.go @@ -101,6 +101,7 @@ // .tmp/data/yao/stores/oauth/client.badger.yao // .tmp/data/yao/stores/oauth/store.badger.yao // .tmp/data/yao/stores/store.badger.yao +// .tmp/data/yao/uploaders/attachment.local.yao package data import ( @@ -279,7 +280,7 @@ func cuiSetupIndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "cui/setup/index.html", size: 10, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "cui/setup/index.html", size: 10, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -299,7 +300,7 @@ func cuiV09IndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "cui/v0.9/index.html", size: 13, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "cui/v0.9/index.html", size: 13, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -319,7 +320,7 @@ func cuiV10IndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "cui/v1.0/index.html", size: 49, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "cui/v1.0/index.html", size: 49, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -339,7 +340,7 @@ func cuiV10Layouts__indexAsyncJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "cui/v1.0/layouts__index.async.js", size: 71, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "cui/v1.0/layouts__index.async.js", size: 71, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -359,7 +360,7 @@ func cuiV10UmiJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "cui/v1.0/umi.js", size: 71, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "cui/v1.0/umi.js", size: 71, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -379,7 +380,7 @@ func initEnv() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/.env", size: 219, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/.env", size: 219, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -399,7 +400,7 @@ func initVscodeSettingsJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/.vscode/settings.json", size: 4666, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/.vscode/settings.json", size: 4666, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -419,7 +420,7 @@ func initVscodeTypesRuntimeConsoleDTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/.vscode/types/runtime/console.d.ts", size: 221, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/.vscode/types/runtime/console.d.ts", size: 221, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -439,7 +440,7 @@ func initVscodeTypesRuntimeExceptionDTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/.vscode/types/runtime/exception.d.ts", size: 738, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/.vscode/types/runtime/exception.d.ts", size: 738, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -459,7 +460,7 @@ func initVscodeTypesRuntimeFsDTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/.vscode/types/runtime/fs.d.ts", size: 8554, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/.vscode/types/runtime/fs.d.ts", size: 8554, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -479,7 +480,7 @@ func initVscodeTypesRuntimeGlobalDTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/.vscode/types/runtime/global.d.ts", size: 1759, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/.vscode/types/runtime/global.d.ts", size: 1759, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -499,7 +500,7 @@ func initVscodeTypesRuntimeHttpDTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/.vscode/types/runtime/http.d.ts", size: 6179, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/.vscode/types/runtime/http.d.ts", size: 6179, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -519,7 +520,7 @@ func initVscodeTypesRuntimeIoDTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/.vscode/types/runtime/io.d.ts", size: 587, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/.vscode/types/runtime/io.d.ts", size: 587, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -539,7 +540,7 @@ func initVscodeTypesRuntimeLogDTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/.vscode/types/runtime/log.d.ts", size: 1692, mode: os.FileMode(493), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/.vscode/types/runtime/log.d.ts", size: 1692, mode: os.FileMode(493), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -559,7 +560,7 @@ func initVscodeTypesRuntimeNeoDTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/.vscode/types/runtime/neo.d.ts", size: 3750, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/.vscode/types/runtime/neo.d.ts", size: 3750, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -579,7 +580,7 @@ func initVscodeTypesRuntimeProcessFsDTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/.vscode/types/runtime/process/fs.d.ts", size: 11133, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/.vscode/types/runtime/process/fs.d.ts", size: 11133, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -599,7 +600,7 @@ func initVscodeTypesRuntimeProcessHttpDTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/.vscode/types/runtime/process/http.d.ts", size: 5653, mode: os.FileMode(493), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/.vscode/types/runtime/process/http.d.ts", size: 5653, mode: os.FileMode(493), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -619,7 +620,7 @@ func initVscodeTypesRuntimeProcessModelDTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/.vscode/types/runtime/process/model.d.ts", size: 6656, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/.vscode/types/runtime/process/model.d.ts", size: 6656, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -639,7 +640,7 @@ func initVscodeTypesRuntimeProcessDTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/.vscode/types/runtime/process.d.ts", size: 23165, mode: os.FileMode(493), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/.vscode/types/runtime/process.d.ts", size: 23165, mode: os.FileMode(493), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -659,7 +660,7 @@ func initVscodeTypesRuntimeQueryDTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/.vscode/types/runtime/query.d.ts", size: 6124, mode: os.FileMode(493), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/.vscode/types/runtime/query.d.ts", size: 6124, mode: os.FileMode(493), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -679,7 +680,7 @@ func initVscodeTypesRuntimeStoreDTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/.vscode/types/runtime/store.d.ts", size: 2251, mode: os.FileMode(493), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/.vscode/types/runtime/store.d.ts", size: 2251, mode: os.FileMode(493), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -699,7 +700,7 @@ func initVscodeTypesRuntimeSuiDTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/.vscode/types/runtime/sui.d.ts", size: 1713, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/.vscode/types/runtime/sui.d.ts", size: 1713, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -719,7 +720,7 @@ func initVscodeTypesRuntimeTimeDTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/.vscode/types/runtime/time.d.ts", size: 711, mode: os.FileMode(493), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/.vscode/types/runtime/time.d.ts", size: 711, mode: os.FileMode(493), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -739,7 +740,7 @@ func initVscodeTypesRuntimeDTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/.vscode/types/runtime.d.ts", size: 424, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/.vscode/types/runtime.d.ts", size: 424, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -759,7 +760,7 @@ func initVscodeTypesSuiDTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/.vscode/types/sui.d.ts", size: 8931, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/.vscode/types/sui.d.ts", size: 8931, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -779,7 +780,7 @@ func initAppYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/app.yao", size: 3115, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/app.yao", size: 3115, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -799,7 +800,7 @@ func initDataReadmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/data/README.md", size: 41, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/data/README.md", size: 41, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -819,7 +820,7 @@ func initDataTemplatesDefault__assetsReadmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/data/templates/default/__assets/README.md", size: 33, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/data/templates/default/__assets/README.md", size: 33, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -839,7 +840,7 @@ func initDataTemplatesDefault__assetsImagesIconsAppPng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/data/templates/default/__assets/images/icons/app.png", size: 34558, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/data/templates/default/__assets/images/icons/app.png", size: 34558, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -859,7 +860,7 @@ func initDataTemplatesDefault__assetsImagesLogosLogo_colorSvg() (*asset, error) return nil, err } - info := bindataFileInfo{name: "init/data/templates/default/__assets/images/logos/logo_color.svg", size: 2909, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/data/templates/default/__assets/images/logos/logo_color.svg", size: 2909, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -879,7 +880,7 @@ func initDataTemplatesDefault__assetsImagesLogosWordmarkSvg() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/data/templates/default/__assets/images/logos/wordmark.svg", size: 3615, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/data/templates/default/__assets/images/logos/wordmark.svg", size: 3615, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -899,7 +900,7 @@ func initDataTemplatesDefault__dataJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/data/templates/default/__data.json", size: 30, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/data/templates/default/__data.json", size: 30, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -919,7 +920,7 @@ func initDataTemplatesDefault__documentHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/data/templates/default/__document.html", size: 492, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/data/templates/default/__document.html", size: 492, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -939,7 +940,7 @@ func initDataTemplatesDefaultIndexIndexCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/data/templates/default/index/index.css", size: 2896, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/data/templates/default/index/index.css", size: 2896, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -959,7 +960,7 @@ func initDataTemplatesDefaultIndexIndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/data/templates/default/index/index.html", size: 2361, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/data/templates/default/index/index.html", size: 2361, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -979,7 +980,7 @@ func initDataTemplatesDefaultIndexIndexJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/data/templates/default/index/index.json", size: 31, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/data/templates/default/index/index.json", size: 31, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -999,7 +1000,7 @@ func initDbReadmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/db/README.md", size: 84, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/db/README.md", size: 84, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1019,7 +1020,7 @@ func initFlowsMenuFlowYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/flows/menu.flow.yao", size: 813, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/flows/menu.flow.yao", size: 813, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1039,7 +1040,7 @@ func initFormsAccountFormYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/forms/account.form.yao", size: 1194, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/forms/account.form.yao", size: 1194, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1059,7 +1060,7 @@ func initIconsAppIcns() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/icons/app.icns", size: 67465, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/icons/app.icns", size: 67465, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1079,7 +1080,7 @@ func initIconsAppIco() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/icons/app.ico", size: 54993, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/icons/app.ico", size: 54993, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1099,7 +1100,7 @@ func initIconsAppPng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/icons/app.png", size: 34558, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/icons/app.png", size: 34558, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1119,7 +1120,7 @@ func initLoginsAdminLoginYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/logins/admin.login.yao", size: 302, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/logins/admin.login.yao", size: 302, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1139,7 +1140,7 @@ func initLogsReadmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/logs/README.md", size: 28, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/logs/README.md", size: 28, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1159,7 +1160,7 @@ func initModelsAdminUserModYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/models/admin/user.mod.yao", size: 6416, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/models/admin/user.mod.yao", size: 6416, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1179,7 +1180,7 @@ func initModelsTestsPetModYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/models/tests/pet.mod.yao", size: 525, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/models/tests/pet.mod.yao", size: 525, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1199,7 +1200,7 @@ func initNeoNeoYml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/neo/neo.yml", size: 724, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/neo/neo.yml", size: 724, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1219,7 +1220,7 @@ func initPublicReadmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/public/README.md", size: 108, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/public/README.md", size: 108, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1239,7 +1240,7 @@ func initPublicAssetsReadmeMd() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/public/assets/README.md", size: 33, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/public/assets/README.md", size: 33, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1259,7 +1260,7 @@ func initPublicAssetsImagesIconsAppPng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/public/assets/images/icons/app.png", size: 34558, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/public/assets/images/icons/app.png", size: 34558, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1279,7 +1280,7 @@ func initPublicAssetsImagesLogosLogo_colorSvg() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/public/assets/images/logos/logo_color.svg", size: 2909, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/public/assets/images/logos/logo_color.svg", size: 2909, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1299,7 +1300,7 @@ func initPublicAssetsImagesLogosWordmarkSvg() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/public/assets/images/logos/wordmark.svg", size: 3615, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/public/assets/images/logos/wordmark.svg", size: 3615, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1319,7 +1320,7 @@ func initPublicAssetsLibsuiMinJs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/public/assets/libsui.min.js", size: 12569, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/public/assets/libsui.min.js", size: 12569, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1339,7 +1340,7 @@ func initPublicAssetsLibsuiMinJsMap() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/public/assets/libsui.min.js.map", size: 38553, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/public/assets/libsui.min.js.map", size: 38553, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1359,7 +1360,7 @@ func initPublicIndexCfg() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/public/index.cfg", size: 85, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/public/index.cfg", size: 85, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1379,7 +1380,7 @@ func initPublicIndexSui() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/public/index.sui", size: 5682, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/public/index.sui", size: 5682, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1399,7 +1400,7 @@ func initScriptsAccountTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/scripts/account.ts", size: 2521, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/scripts/account.ts", size: 2521, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1419,7 +1420,7 @@ func initScriptsAiNeoTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/scripts/ai/neo.ts", size: 375, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/scripts/ai/neo.ts", size: 375, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1439,7 +1440,7 @@ func initScriptsTestsTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/scripts/tests.ts", size: 1044, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/scripts/tests.ts", size: 1044, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1459,7 +1460,7 @@ func initScriptsUtilsTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/scripts/utils.ts", size: 1230, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/scripts/utils.ts", size: 1230, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1479,7 +1480,7 @@ func initSuisWebSuiYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/suis/web.sui.yao", size: 675, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/suis/web.sui.yao", size: 675, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1499,7 +1500,7 @@ func initTablesAccountTabYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/tables/account.tab.yao", size: 5597, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/tables/account.tab.yao", size: 5597, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1519,7 +1520,7 @@ func initTsconfigJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "init/tsconfig.json", size: 178, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "init/tsconfig.json", size: 178, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1539,7 +1540,7 @@ func libsuiAgentTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "libsui/agent.ts", size: 15267, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "libsui/agent.ts", size: 15267, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1559,7 +1560,7 @@ func libsuiIndexTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "libsui/index.ts", size: 13049, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "libsui/index.ts", size: 13049, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1579,7 +1580,7 @@ func libsuiUtilsTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "libsui/utils.ts", size: 5959, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "libsui/utils.ts", size: 5959, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1599,7 +1600,7 @@ func libsuiYaoTs() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "libsui/yao.ts", size: 4338, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "libsui/yao.ts", size: 4338, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1619,7 +1620,7 @@ func publicIndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "public/index.html", size: 11, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "public/index.html", size: 11, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1639,7 +1640,7 @@ func uiIndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "ui/index.html", size: 11, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "ui/index.html", size: 11, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1659,7 +1660,7 @@ func yaoDataIcons404Png() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/data/icons/404.png", size: 9342, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/data/icons/404.png", size: 9342, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1679,7 +1680,7 @@ func yaoDataIconsIconIcns() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/data/icons/icon.icns", size: 67465, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/data/icons/icon.icns", size: 67465, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1699,7 +1700,7 @@ func yaoDataIconsIconIco() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/data/icons/icon.ico", size: 54993, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/data/icons/icon.ico", size: 54993, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1719,7 +1720,7 @@ func yaoDataIconsIconPng() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/data/icons/icon.png", size: 34558, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/data/icons/icon.png", size: 34558, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1739,7 +1740,7 @@ func yaoDataIndexHtml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/data/index.html", size: 282, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/data/index.html", size: 282, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1759,7 +1760,7 @@ func yaoFieldsModelTransJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/fields/model.trans.json", size: 14938, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/fields/model.trans.json", size: 14938, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1779,7 +1780,7 @@ func yaoLangsEnUsJson() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/langs/en-US.json", size: 66, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/langs/en-US.json", size: 66, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1799,7 +1800,7 @@ func yaoLangsZhCnGlobalYml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/langs/zh-cn/global.yml", size: 1762, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/langs/zh-cn/global.yml", size: 1762, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1819,7 +1820,7 @@ func yaoLangsZhCnLoginsAdminLoginYml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/langs/zh-cn/logins/admin.login.yml", size: 94, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/langs/zh-cn/logins/admin.login.yml", size: 94, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1839,7 +1840,7 @@ func yaoLangsZhCnLoginsUserLoginYml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/langs/zh-cn/logins/user.login.yml", size: 90, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/langs/zh-cn/logins/user.login.yml", size: 90, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1859,7 +1860,7 @@ func yaoLangsZhHkGlobalYml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/langs/zh-hk/global.yml", size: 1762, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/langs/zh-hk/global.yml", size: 1762, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1879,7 +1880,7 @@ func yaoLangsZhHkLoginsAdminLoginYml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/langs/zh-hk/logins/admin.login.yml", size: 94, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/langs/zh-hk/logins/admin.login.yml", size: 94, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1899,7 +1900,7 @@ func yaoLangsZhHkLoginsUserLoginYml() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/langs/zh-hk/logins/user.login.yml", size: 90, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/langs/zh-hk/logins/user.login.yml", size: 90, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1919,7 +1920,7 @@ func yaoModelsAssistantModYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/models/assistant.mod.yao", size: 4114, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/models/assistant.mod.yao", size: 4114, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1939,7 +1940,7 @@ func yaoModelsAttachmentModYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/models/attachment.mod.yao", size: 3264, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/models/attachment.mod.yao", size: 3264, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1959,7 +1960,7 @@ func yaoModelsAuditModYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/models/audit.mod.yao", size: 5588, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/models/audit.mod.yao", size: 5588, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1979,7 +1980,7 @@ func yaoModelsChatModYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/models/chat.mod.yao", size: 1444, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/models/chat.mod.yao", size: 1444, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -1999,7 +2000,7 @@ func yaoModelsConfigModYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/models/config.mod.yao", size: 1649, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/models/config.mod.yao", size: 1649, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -2019,7 +2020,7 @@ func yaoModelsDslModYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/models/dsl.mod.yao", size: 3806, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/models/dsl.mod.yao", size: 3806, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -2039,7 +2040,7 @@ func yaoModelsHistoryModYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/models/history.mod.yao", size: 2902, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/models/history.mod.yao", size: 2902, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -2059,7 +2060,7 @@ func yaoModelsKbModYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/models/kb.mod.yao", size: 2881, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/models/kb.mod.yao", size: 2881, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -2079,7 +2080,7 @@ func yaoModelsUserModYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/models/user.mod.yao", size: 6775, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/models/user.mod.yao", size: 6775, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -2099,7 +2100,7 @@ func yaoReleaseAppYaz() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/release/app.yaz", size: 181682, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/release/app.yaz", size: 181682, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -2119,7 +2120,7 @@ func yaoStoresAgentCacheLruYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/stores/agent/cache.lru.yao", size: 301, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/stores/agent/cache.lru.yao", size: 301, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -2139,7 +2140,7 @@ func yaoStoresAgentMemoryBadgerYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/stores/agent/memory.badger.yao", size: 352, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/stores/agent/memory.badger.yao", size: 352, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -2159,7 +2160,7 @@ func yaoStoresCacheLruYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/stores/cache.lru.yao", size: 285, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/stores/cache.lru.yao", size: 285, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -2179,7 +2180,7 @@ func yaoStoresKbCacheLruYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/stores/kb/cache.lru.yao", size: 304, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/stores/kb/cache.lru.yao", size: 304, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -2199,7 +2200,7 @@ func yaoStoresKbStoreBadgerYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/stores/kb/store.badger.yao", size: 349, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/stores/kb/store.badger.yao", size: 349, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -2219,7 +2220,7 @@ func yaoStoresOauthCacheLruYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/stores/oauth/cache.lru.yao", size: 301, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/stores/oauth/cache.lru.yao", size: 301, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -2239,7 +2240,7 @@ func yaoStoresOauthClientBadgerYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/stores/oauth/client.badger.yao", size: 352, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/stores/oauth/client.badger.yao", size: 352, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -2259,7 +2260,7 @@ func yaoStoresOauthStoreBadgerYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/stores/oauth/store.badger.yao", size: 376, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/stores/oauth/store.badger.yao", size: 376, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -2279,7 +2280,27 @@ func yaoStoresStoreBadgerYao() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "yao/stores/store.badger.yao", size: 341, mode: os.FileMode(420), modTime: time.Unix(1753261259, 0)} + info := bindataFileInfo{name: "yao/stores/store.badger.yao", size: 341, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var _yaoUploadersAttachmentLocalYao = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x52\x31\x8f\xdb\x3c\x0c\xdd\xf3\x2b\x08\x8d\x1f\x2e\xce\x7d\xd7\xeb\xd0\x6c\x05\x3a\xb6\x63\xa7\xe2\x10\x30\x12\x9d\xa8\x95\x44\x41\x94\x13\x27\x87\xfb\xef\x85\xe4\xc4\x76\x01\x77\x39\x74\xf2\xe3\xe3\xe3\x7b\x94\xa5\xd7\x15\x80\x72\xb8\x27\xa7\xb6\xa0\x3e\xe7\x8c\xfa\xe8\x29\x64\x81\xaf\xac\xd1\xc1\xf7\xe8\x18\x0d\x25\xf8\x42\x2d\x76\x2e\xab\x87\x32\x60\x48\x74\xb2\x31\x5b\x0e\x65\xec\xd6\x03\x57\x47\x24\x73\xc2\x03\x41\x77\x1f\x6d\x39\x81\x5c\x24\x93\x07\x9c\x02\x06\xa7\x8c\x07\x51\x5b\xf8\xa1\x06\x81\x7a\x00\x55\x5d\x0a\x30\xb7\xc8\x97\x21\x33\xd9\x13\xa5\x12\x77\x13\x14\x32\x11\x1a\x0e\xee\xa2\xb6\x90\x53\x47\x95\xdb\x77\xd6\x65\x1b\xe6\x14\xd7\x55\x4b\xd0\x2b\xa8\x88\xf9\x58\x6c\x36\xbb\xdd\x05\x79\x33\x5f\x09\xde\xaa\x5c\x1f\xbb\xf0\x6b\x27\xf6\x4a\x45\xf7\xf4\x6d\xc8\xf2\xd8\x8f\xdc\xc7\xc7\x1b\x79\xb8\xda\xa8\xb6\xd0\xa2\x93\x21\x4a\xb3\x8f\x89\x44\x76\xd6\xe3\xa1\x68\xff\xff\xf4\xf4\x58\x3b\xe8\x1c\x9f\xc9\xec\xf2\x25\x52\x3d\xf3\x0a\xa0\xfc\x01\xea\xf3\xe6\xbf\xea\x06\xa0\xea\xd4\x54\x9e\xac\x21\x9e\x4a\xec\x8c\x9d\x97\x31\x3a\xab\xb1\x9c\x6d\xd3\xaf\xaf\x36\xae\xef\xe9\x64\x96\x35\x19\xd3\x72\xa3\x9e\x63\xa1\x73\x41\x5e\xa2\xff\xa2\x8e\xa6\x5d\xa2\x7f\x0a\x87\x25\xfe\x14\x4c\xc3\x91\x42\xef\x5d\xcb\xc9\x63\x96\x35\xb7\xad\xd5\x64\x58\x77\xe5\x46\x9a\x33\x27\x13\x13\x6b\x12\xb1\xe1\xe0\x5d\x73\xef\xbc\xcf\x4e\x62\x79\x30\x72\x24\xca\xde\x35\xf5\xfb\x3e\xa3\xf2\x93\x29\xe4\x2a\xf7\xee\x8f\xf2\x9f\x18\x8a\xb3\x86\xe4\xc8\xe7\xbb\x5b\xe3\xc7\x1b\x6d\x72\x3f\x6e\xdd\x68\x39\x8d\xb8\x77\x32\xc7\xfd\x58\xc4\x98\xe7\x78\x6a\x18\xd6\x73\xdc\xcf\xd2\x66\xf8\x19\x27\x1c\x3f\xcc\xf0\xf3\x88\xcf\x38\xad\x71\xa6\xbd\x1f\x8b\xf2\x7e\x56\x00\x2f\xab\xb7\xd5\xef\x00\x00\x00\xff\xff\x13\x82\xb1\x9d\x6b\x04\x00\x00") + +func yaoUploadersAttachmentLocalYaoBytes() ([]byte, error) { + return bindataRead( + _yaoUploadersAttachmentLocalYao, + "yao/uploaders/attachment.local.yao", + ) +} + +func yaoUploadersAttachmentLocalYao() (*asset, error) { + bytes, err := yaoUploadersAttachmentLocalYaoBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "yao/uploaders/attachment.local.yao", size: 1131, mode: os.FileMode(420), modTime: time.Unix(1753437622, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -2437,6 +2458,7 @@ var _bindata = map[string]func() (*asset, error){ "yao/stores/oauth/client.badger.yao": yaoStoresOauthClientBadgerYao, "yao/stores/oauth/store.badger.yao": yaoStoresOauthStoreBadgerYao, "yao/stores/store.badger.yao": yaoStoresStoreBadgerYao, + "yao/uploaders/attachment.local.yao": yaoUploadersAttachmentLocalYao, } // AssetDir returns the file names below a certain @@ -2690,6 +2712,9 @@ var _bintree = &bintree{nil, map[string]*bintree{ }}, "store.badger.yao": {yaoStoresStoreBadgerYao, map[string]*bintree{}}, }}, + "uploaders": {nil, map[string]*bintree{ + "attachment.local.yao": {yaoUploadersAttachmentLocalYao, map[string]*bintree{}}, + }}, }}, }} diff --git a/engine/load.go b/engine/load.go index 71b2deee..cbb8c403 100644 --- a/engine/load.go +++ b/engine/load.go @@ -12,6 +12,7 @@ import ( "github.com/yaoapp/kun/exception" "github.com/yaoapp/yao/aigc" "github.com/yaoapp/yao/api" + "github.com/yaoapp/yao/attachment" "github.com/yaoapp/yao/cert" "github.com/yaoapp/yao/config" "github.com/yaoapp/yao/connector" @@ -166,6 +167,13 @@ func Load(cfg config.Config, options LoadOption) (warnings []Warning, err error) warnings = append(warnings, Warning{Widget: "Store", Error: err}) } + // Load Uploaders + err = attachment.Load(cfg) + if err != nil { + // printErr(cfg.Mode, "Uploader", err) + warnings = append(warnings, Warning{Widget: "Uploader", Error: err}) + } + // Load Plugins err = plugin.Load(cfg) if err != nil { @@ -422,6 +430,12 @@ func Reload(cfg config.Config, options LoadOption) (err error) { printErr(cfg.Mode, "Store", err) } + // Load Uploaders + err = attachment.Load(cfg) + if err != nil { + printErr(cfg.Mode, "Uploader", err) + } + // Load Plugins err = plugin.Load(cfg) if err != nil { diff --git a/neo/message/message.go b/neo/message/message.go index 78a0e632..098e61c4 100644 --- a/neo/message/message.go +++ b/neo/message/message.go @@ -13,7 +13,7 @@ import ( "github.com/yaoapp/kun/exception" "github.com/yaoapp/kun/log" "github.com/yaoapp/kun/maps" - "github.com/yaoapp/yao/neo/attachment" + "github.com/yaoapp/yao/attachment" "github.com/yaoapp/yao/openai" ) diff --git a/yao/uploaders/attachment.local.yao b/yao/uploaders/attachment.local.yao new file mode 100644 index 00000000..5bd3ff0c --- /dev/null +++ b/yao/uploaders/attachment.local.yao @@ -0,0 +1,46 @@ +{ + "label": "Attachments Local Uploader Default", + "description": "Default local storage uploader for system attachments", + "tags": ["system", "local", "default"], + "driver": "local", + "readonly": true, + "builtin": true, + "options": { "path": "/__yao/attachments" }, + "chunk_size": "2M", + "max_size": "50M", + "gzip": false, + "compress_image": 1920, + "allowed_types": [ + "text/*", + "image/*", + "video/*", + "audio/*", + "application/x-zip-compressed", + "application/x-tar", + "application/x-gzip", + "application/yao", + "application/zip", + "application/pdf", + "application/json", + "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + "application/vnd.openxmlformats-officedocument.presentationml.presentation", + "application/vnd.openxmlformats-officedocument.presentationml.slideshow", + ".md", + ".txt", + ".csv", + ".xls", + ".xlsx", + ".ppt", + ".pptx", + ".doc", + ".docx", + ".mdx", + ".m4a", + ".mp3", + ".mp4", + ".wav", + ".webm", + ".yao" + ] +}