273 lines
7.3 KiB
Go
273 lines
7.3 KiB
Go
package file
|
|
|
|
import (
|
|
_ "embed"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"apigo.cc/gojs"
|
|
"apigo.cc/gojs/goja"
|
|
"github.com/ssgo/u"
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
//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
|
|
}
|
|
}
|
|
|
|
func init() {
|
|
obj := map[string]any{
|
|
"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)))
|
|
},
|
|
"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
|
|
},
|
|
"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))
|
|
}
|
|
},
|
|
}
|
|
|
|
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,
|
|
})
|
|
}
|
|
|
|
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 ""
|
|
}
|
|
}
|
|
}
|