file/file.go

273 lines
7.3 KiB
Go
Raw Normal View History

2024-10-11 12:02:48 +08:00
package file
import (
_ "embed"
"encoding/base64"
"encoding/json"
2024-10-11 12:02:48 +08:00
"os"
"path/filepath"
"regexp"
"strings"
2024-10-11 12:02:48 +08:00
"apigo.cc/gojs"
"apigo.cc/gojs/goja"
"github.com/ssgo/u"
"gopkg.in/yaml.v3"
2024-10-11 12:02:48 +08:00
)
//go:embed file.ts
var fileTS string
//go:embed README.md
var fileMD string
var envConfigs map[string]map[string]any
var encryptdMatcher = regexp.MustCompile(`"([\w-=]+)"`)
var confAes = u.NewAes([]byte("?GQ$0K0GgLdO=f+~L68PLm$uhKr4'=tV"), []byte("VFs7@sK61cj^f?HZ"))
var keysIsSet = false
func SetSSKey(key, iv []byte) {
if !keysIsSet {
confAes = u.NewAes(key, iv)
keysIsSet = true
}
}
2024-10-11 12:02:48 +08:00
func init() {
obj := map[string]any{
2024-10-26 22:12:41 +08:00
"exists": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(1)
return vm.ToValue(u.FileExists(args.Path(0)))
},
2024-12-13 19:29:31 +08:00
"mkdir": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(1)
if err := os.MkdirAll(args.Path(0), 0755); err != nil {
panic(vm.NewGoError(err))
}
return nil
},
2024-10-11 12:02:48 +08:00
"read": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(1)
if r, err := u.ReadFile(args.Path(0)); err == nil {
return vm.ToValue(r)
} else {
panic(vm.NewGoError(err))
}
},
"readBytes": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(1)
if r, err := u.ReadFileBytes(args.Path(0)); err == nil {
return vm.ToValue(r)
} else {
panic(vm.NewGoError(err))
}
},
"write": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(2)
if err := u.WriteFileBytes(args.Path(0), args.Bytes(1)); err == nil {
return nil
} else {
panic(vm.NewGoError(err))
}
},
"dir": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(1)
if r, err := u.ReadDir(args.Path(0)); err == nil {
list := make([]map[string]any, len(r))
for i, info := range r {
list[i] = makeFileInfo(&info)
}
return vm.ToValue(list)
} else {
panic(vm.NewGoError(err))
}
},
"stat": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(1)
return vm.ToValue(makeFileInfo(u.GetFileInfo(args.Path(0))))
},
"find": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(1)
return vm.ToValue(args.Path(0))
},
"remove": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(1)
if err := os.RemoveAll(args.Path(0)); err == nil {
return nil
} else {
panic(vm.NewGoError(err))
}
},
"rename": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(2)
if err := os.Rename(args.Path(0), args.Path(1)); err == nil {
return nil
} else {
panic(vm.NewGoError(err))
}
},
"copy": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(2)
if err := u.CopyFile(args.Path(0), args.Path(1)); err == nil {
return nil
} else {
panic(vm.NewGoError(err))
}
},
"cache": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(1)
compress := args.Bool(1)
if compress {
u.LoadFileToMemoryWithCompress(args.Path(0))
} else {
u.LoadFileToMemory(args.Path(0))
}
return nil
},
"searchFile": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(1)
filename := args.Str(0)
searchPath := args.Str(1)
findFile := ""
if searchPath != "" {
findFile = searchFile(searchPath, filename)
} else {
findFile = searchFileFromCurrent(vm, filename)
}
return vm.ToValue(findFile)
},
"loadConfig": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if envConfigs == nil {
envConfigs = map[string]map[string]any{}
envFile := searchFileFromCurrent(vm, "env.yml")
if envFile == "" {
envFile = searchFileFromCurrent(vm, "env.json")
}
if envFile != "" {
u.LoadX(envFile, &envConfigs)
}
}
args := gojs.MakeArgs(&argsIn, vm).Check(1)
confName := args.Str(0)
conf := map[string]any{}
confFile := searchFileFromCurrent(vm, confName+".yml")
if confFile == "" {
confFile = searchFileFromCurrent(vm, confName+".json")
}
if confFile != "" {
u.LoadX(confFile, &conf)
}
if envConf, ok := envConfigs[confName]; ok {
u.Convert(envConf, &conf)
}
decTimes := 0
confStr := encryptdMatcher.ReplaceAllStringFunc(u.Json(conf), func(str string) string {
if buf, err := base64.URLEncoding.DecodeString(str[1 : len(str)-1]); err == nil {
if buf1, err1 := confAes.DecryptBytes(buf); err1 == nil && len(buf1) > 0 {
decTimes++
return "\"" + string(buf1) + "\""
}
}
return str
})
if decTimes > 0 {
u.UnJson(confStr, &conf)
}
return vm.ToValue(conf)
},
"save": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(2)
filename := args.Str(0)
var data []byte
var err error
if strings.HasSuffix(filename, ".yml") || strings.HasSuffix(filename, ".yaml") {
data, err = yaml.Marshal(args.Any(1))
} else {
data, err = json.Marshal(args.Any(1))
}
if err == nil {
if err = u.WriteFileBytes(gojs.FindPath(vm, filename), data); err != nil {
panic(vm.NewGoError(err))
}
return nil
} else {
panic(vm.NewGoError(err))
}
},
"load": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(1)
filename := args.Str(0)
if data, err := u.ReadFileBytes(gojs.FindPath(vm, filename)); err == nil {
var r any
if strings.HasSuffix(filename, ".yml") || strings.HasSuffix(filename, ".yaml") {
err = yaml.Unmarshal(data, &r)
} else {
err = json.Unmarshal(data, &r)
}
if err == nil {
return vm.ToValue(r)
} else {
panic(vm.NewGoError(err))
}
} else {
panic(vm.NewGoError(err))
}
},
2024-10-11 12:02:48 +08:00
}
gojs.Register("apigo.cc/gojs/file", gojs.Module{
Object: obj,
Desc: "file api by https://github.com/ssgo/u",
TsCode: fileTS,
Example: fileMD,
SetSSKey: SetSSKey,
2024-10-11 12:02:48 +08:00
})
}
func makeFileInfo(info *u.FileInfo) map[string]any {
return map[string]any{
"name": info.Name,
"size": info.Size,
"fullName": info.FullName,
"isDir": info.IsDir,
"modTime": info.ModTime.UnixMilli(),
}
}
func searchFile(searchPath, name string) string {
searched := map[string]bool{}
return _searchFile(searchPath, name, &searched)
}
func searchFileFromCurrent(vm *goja.Runtime, name string) string {
searched := map[string]bool{}
startPath := u.String(vm.GoData["startPath"])
filename := _searchFile(startPath, name, &searched)
if filename == "" {
currentPath, _ := os.Getwd()
filename = _searchFile(currentPath, name, &searched)
}
return filename
}
func _searchFile(checkPath, name string, searched *map[string]bool) string {
for {
if !(*searched)[checkPath] {
(*searched)[checkPath] = true
filename := filepath.Join(checkPath, name)
if u.FileExists(filename) {
return filename
}
}
oldPath := checkPath
checkPath = filepath.Dir(oldPath)
if oldPath == checkPath {
return ""
}
}
}