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.GetData("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 ""
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |