集成内置http服务器
This commit is contained in:
parent
0500a5752b
commit
9fd888d5ff
2
.gitignore
vendored
2
.gitignore
vendored
@ -77,3 +77,5 @@ fabric.properties
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
config.toml
|
||||
.pid
|
||||
|
106
app/wails/app.go
106
app/wails/app.go
@ -3,25 +3,121 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/wailsapp/wails/v2/pkg/runtime"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"skapp/global"
|
||||
"skapp/pkg/config/toml"
|
||||
"skapp/pkg/logger"
|
||||
"skapp/pkg/pid"
|
||||
server "skapp/pkg/server"
|
||||
"time"
|
||||
)
|
||||
|
||||
var pidFile = "./.pid"
|
||||
|
||||
// App struct
|
||||
type App struct {
|
||||
ctx context.Context
|
||||
srv *http.Server
|
||||
Handler http.Handler
|
||||
pidLock *pid.PidLock
|
||||
}
|
||||
|
||||
// NewApp creates a new App application struct
|
||||
func NewApp() *App {
|
||||
return &App{}
|
||||
app := &App{}
|
||||
app.load()
|
||||
return app
|
||||
}
|
||||
|
||||
func (a *App) ReloadApp() {
|
||||
runtime.WindowReloadApp(a.ctx)
|
||||
}
|
||||
|
||||
func (a *App) ForceClose() {
|
||||
a.shutdown(a.ctx)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
func (a *App) load() {
|
||||
a.pidLock = pid.NewPidLock(pidFile)
|
||||
|
||||
conf, err := toml.LoadConfig()
|
||||
if err != nil {
|
||||
logger.Log.Fatalf("%s", err)
|
||||
}
|
||||
|
||||
global.Config = conf
|
||||
|
||||
if conf.HasDebug() && conf.Debug.Enable {
|
||||
logger.SetLevel(zapcore.DebugLevel)
|
||||
} else {
|
||||
logger.SetLevel(zapcore.ErrorLevel)
|
||||
}
|
||||
|
||||
engine := server.Server(conf)
|
||||
|
||||
a.srv = &http.Server{
|
||||
Addr: fmt.Sprintf("%s:%d", conf.Server.Host, conf.Server.Port),
|
||||
Handler: engine,
|
||||
}
|
||||
|
||||
a.Handler = engine.Handler()
|
||||
}
|
||||
|
||||
// startup is called when the app starts. The context is saved
|
||||
// so we can call the runtime methods
|
||||
func (a *App) startup(ctx context.Context) {
|
||||
a.ctx = ctx
|
||||
if !global.Config.HasDebug() || !global.Config.Debug.Enable {
|
||||
err := a.pidLock.Lock()
|
||||
if err != nil {
|
||||
os.Exit(-1)
|
||||
}
|
||||
}
|
||||
|
||||
// Greet returns a greeting for the given name
|
||||
func (a *App) Greet(name string) string {
|
||||
return fmt.Sprintf("Hello %s, It's show time!", name)
|
||||
a.ctx = ctx
|
||||
|
||||
go func() {
|
||||
logger.Log.Infof("启动本地后台服务: %s", a.srv.Addr)
|
||||
// 服务连接
|
||||
if err := a.srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
switch err.(type) {
|
||||
case *net.OpError:
|
||||
_, _ = runtime.MessageDialog(ctx, runtime.MessageDialogOptions{
|
||||
Title: "错误",
|
||||
Type: runtime.ErrorDialog,
|
||||
Message: fmt.Sprintf("服务启动失败: 请检查 %s 是否被其他进程占用", a.srv.Addr),
|
||||
})
|
||||
default:
|
||||
_, _ = runtime.MessageDialog(ctx, runtime.MessageDialogOptions{
|
||||
Title: "错误",
|
||||
Type: runtime.ErrorDialog,
|
||||
Message: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
logger.Log.Fatalf("listen: %s\n", err)
|
||||
os.Exit(-1)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (a *App) beforeClose(ctx context.Context) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (a *App) shutdown(ctx context.Context) {
|
||||
ctx2, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if !global.Config.HasDebug() || !global.Config.Debug.Enable {
|
||||
a.pidLock.UnLock()
|
||||
}
|
||||
|
||||
if err := a.srv.Shutdown(ctx2); err != nil {
|
||||
logger.Log.Fatalf("Server Shutdown:", err)
|
||||
}
|
||||
}
|
||||
|
7
app/wails/cmd/server/main.go
Normal file
7
app/wails/cmd/server/main.go
Normal file
@ -0,0 +1,7 @@
|
||||
package main
|
||||
|
||||
import "skapp/pkg/server"
|
||||
|
||||
func main() {
|
||||
server.Main()
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="mx-1">
|
||||
<div class="mx-2">
|
||||
<el-config-provider v-bind="globalConfig">
|
||||
<router-view v-slot="{ Component, route }">
|
||||
<transition name="fade" mode="out-in">
|
||||
|
@ -1,5 +1,4 @@
|
||||
<script setup>
|
||||
import {Greet} from 'frontend/wailsjs/go/main/App';
|
||||
import {reactive} from "vue";
|
||||
import {useWebNotification} from '@vueuse/core'
|
||||
import {GetAllEnv} from "frontend/wailsjs/go/env/Env";
|
||||
@ -11,41 +10,11 @@ const controller = reactive({
|
||||
input: ""
|
||||
})
|
||||
|
||||
function greet() {
|
||||
let resultElement = document.getElementById("result");
|
||||
|
||||
// Get name
|
||||
let name = controller.input
|
||||
|
||||
// Check if the input is empty
|
||||
if (name === "") return;
|
||||
|
||||
// Call App.Greet(name)
|
||||
try {
|
||||
Greet(name)
|
||||
.then((result) => {
|
||||
// Update result with data back from App.Greet()
|
||||
resultElement.innerText = result;
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
|
||||
function sendNotify() {
|
||||
Greet(controller.input)
|
||||
.then((result) => {
|
||||
/**
|
||||
*
|
||||
* @type {UseWebNotificationOptions}
|
||||
*/
|
||||
const options = {
|
||||
title: '通知测试',
|
||||
dir: 'auto',
|
||||
body: result,
|
||||
body: "通知测试",
|
||||
lang: 'zh-CN',
|
||||
renotify: true,
|
||||
tag: 'notify',
|
||||
@ -56,10 +25,6 @@ function sendNotify() {
|
||||
notification.close()
|
||||
}, 5 * 1000)
|
||||
notification.show()
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
|
||||
function getAllEnv(){
|
||||
|
@ -1,9 +1,29 @@
|
||||
<script setup lang="ts">
|
||||
<script setup>
|
||||
import {reactive, ref} from "vue";
|
||||
|
||||
const data = reactive({
|
||||
videoSrc: "http://127.0.0.1:32323/s/file/?path=E:/Repository/skcks.cn/sk-box/build/bin/video.mp4",
|
||||
})
|
||||
|
||||
const videoInst = ref();
|
||||
|
||||
function loadVideo() {
|
||||
if(!videoInst.value){
|
||||
return
|
||||
}
|
||||
|
||||
videoInst.value.src = data.videoSrc
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>测试页面</div>
|
||||
|
||||
<video ref="videoInst" preload="metadata" controls class="full-width"></video>
|
||||
<div id="input" class="input-box">
|
||||
<input id="name" v-model="data.videoSrc" autocomplete="off" class="input w-full" type="text"/>
|
||||
<button class="btn" @click="loadVideo">加载</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
@ -7,7 +7,7 @@ const route = useRoute();
|
||||
const router = useRouter();
|
||||
const globalTabsState = useGlobalTabs()
|
||||
globalTabsState.tab = route.path
|
||||
if(globalTabsState.tabs.find(item => item.name === route.path) == null){
|
||||
if(globalTabsState.tabs.find(item => item.name === route.path) == null && route.path !== "/"){
|
||||
globalTabsState.tabs = [...new Set(globalTabsState.tabs).add({
|
||||
name: route.path,
|
||||
title: route.meta.title,
|
||||
|
@ -1,10 +1,15 @@
|
||||
import {defineConfig} from "vite";
|
||||
import vuePlugin from "@vitejs/plugin-vue";
|
||||
import path from "path"
|
||||
|
||||
import wailsPlugin from "./wails-plugin";
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
vuePlugin()
|
||||
vuePlugin(),
|
||||
wailsPlugin({
|
||||
excludeUrls: [
|
||||
"/s/.*"
|
||||
]
|
||||
})
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
|
36
app/wails/frontend/wails-plugin.ts
Normal file
36
app/wails/frontend/wails-plugin.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import {Plugin} from "vite";
|
||||
|
||||
export interface WailsPluginOptions {
|
||||
excludeUrls?: string[]
|
||||
}
|
||||
|
||||
const wailsPlugin:(options?:WailsPluginOptions)=>Plugin = (options)=>({
|
||||
name: "wailsPlugin",
|
||||
configureServer(server) {
|
||||
server.middlewares.use((req, res, next) => {
|
||||
if(!options){
|
||||
next()
|
||||
return
|
||||
}
|
||||
|
||||
if(!options.excludeUrls){
|
||||
next()
|
||||
return
|
||||
}
|
||||
|
||||
let excludeUrls = options.excludeUrls || []
|
||||
for (let i = 0; i < excludeUrls.length; i++) {
|
||||
let excludeUrl = excludeUrls[i]
|
||||
let reg = new RegExp(excludeUrl)
|
||||
if(reg.test(req.originalUrl)){
|
||||
res.writeHead(404)
|
||||
res.end()
|
||||
return
|
||||
}
|
||||
}
|
||||
next()
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
export default wailsPlugin;
|
4
app/wails/frontend/wailsjs/go/main/App.d.ts
vendored
4
app/wails/frontend/wailsjs/go/main/App.d.ts
vendored
@ -1,4 +1,6 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
export function Greet(arg1:string):Promise<string>;
|
||||
export function ForceClose():Promise<void>;
|
||||
|
||||
export function ReloadApp():Promise<void>;
|
||||
|
@ -2,6 +2,10 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
export function Greet(arg1) {
|
||||
return window['go']['main']['App']['Greet'](arg1);
|
||||
export function ForceClose() {
|
||||
return window['go']['main']['App']['ForceClose']();
|
||||
}
|
||||
|
||||
export function ReloadApp() {
|
||||
return window['go']['main']['App']['ReloadApp']();
|
||||
}
|
||||
|
5
app/wails/global/global.go
Normal file
5
app/wails/global/global.go
Normal file
@ -0,0 +1,5 @@
|
||||
package global
|
||||
|
||||
import "skapp/pkg/config"
|
||||
|
||||
var Config *config.Config
|
@ -1,32 +1,59 @@
|
||||
module changeme
|
||||
module skapp
|
||||
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/gen2brain/beeep v0.0.0-20230602101333-f384c29b62dd
|
||||
github.com/gin-contrib/gzip v0.0.6
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/go-playground/locales v0.14.1
|
||||
github.com/go-playground/universal-translator v0.18.1
|
||||
github.com/go-playground/validator/v10 v10.14.1
|
||||
github.com/mutecomm/go-sqlcipher/v4 v4.4.2
|
||||
github.com/pelletier/go-toml/v2 v2.0.8
|
||||
github.com/shirou/gopsutil v2.21.11+incompatible
|
||||
github.com/sony/sonyflake v1.1.0
|
||||
github.com/swaggo/files v1.0.1
|
||||
github.com/swaggo/gin-swagger v1.6.0
|
||||
github.com/swaggo/swag v1.16.1
|
||||
github.com/wailsapp/wails/v2 v2.5.1
|
||||
go.uber.org/atomic v1.7.0
|
||||
go.uber.org/zap v1.24.0
|
||||
xorm.io/xorm v1.3.2
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/bep/debounce v1.2.1 // indirect
|
||||
github.com/bytedance/sonic v1.9.1 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
||||
github.com/go-openapi/spec v0.20.4 // indirect
|
||||
github.com/go-openapi/swag v0.19.15 // indirect
|
||||
github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4 // indirect
|
||||
github.com/goccy/go-json v0.8.1 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/labstack/echo/v4 v4.9.0 // indirect
|
||||
github.com/labstack/gommon v0.3.1 // indirect
|
||||
github.com/leaanthony/go-ansi-parser v1.0.1 // indirect
|
||||
github.com/leaanthony/gosod v1.0.3 // indirect
|
||||
github.com/leaanthony/slicer v1.5.0 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/mailru/easyjson v0.7.6 // indirect
|
||||
github.com/mattn/go-colorable v0.1.11 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
|
||||
@ -38,15 +65,23 @@ require (
|
||||
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
||||
github.com/tklauser/numcpus v0.6.0 // indirect
|
||||
github.com/tkrajina/go-reflector v0.5.5 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.1 // indirect
|
||||
github.com/wailsapp/mimetype v1.4.1 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||
golang.org/x/crypto v0.1.0 // indirect
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/crypto v0.9.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/net v0.10.0 // indirect
|
||||
golang.org/x/sys v0.10.0 // indirect
|
||||
golang.org/x/text v0.11.0 // indirect
|
||||
golang.org/x/tools v0.7.0 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978 // indirect
|
||||
)
|
||||
|
||||
|
157
app/wails/go.sum
157
app/wails/go.sum
@ -5,7 +5,13 @@ gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0p
|
||||
gitee.com/travelliu/dm v1.8.11192/go.mod h1:DHTzyhCrM843x9VdKVbZ+GKXGRbKM2sJ4LxihRxShkE=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||
@ -23,16 +29,23 @@ github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6l
|
||||
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
||||
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY=
|
||||
github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
|
||||
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
@ -45,6 +58,7 @@ github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -63,9 +77,18 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv
|
||||
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
|
||||
github.com/gen2brain/beeep v0.0.0-20230602101333-f384c29b62dd h1:eVPIv7aXHQYJ5lbhXHoJyfPhivIn+BvH2xPoG62lT2w=
|
||||
github.com/gen2brain/beeep v0.0.0-20230602101333-f384c29b62dd/go.mod h1:0W7dI87PvXJ1Sjs0QPvWXKcQmNERY77e8l7GFhZB/s4=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
||||
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
|
||||
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
|
||||
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
||||
@ -74,14 +97,37 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
|
||||
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
|
||||
github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=
|
||||
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
|
||||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
||||
github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k=
|
||||
github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4 h1:qZNfIGkIANxGv/OqtnntR4DfOY2+BgwR60cAcu/i3SE=
|
||||
github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4/go.mod h1:kW3HQ4UdaAyrUCSSDR4xUzBKW6O2iA4uHhk7AtyYp10=
|
||||
github.com/goccy/go-json v0.8.1 h1:4/Wjm0JIJaTDm8K1KcGrLHJoa8EsJ13YWeX+6Kfq6uI=
|
||||
github.com/goccy/go-json v0.8.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
@ -98,6 +144,7 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
@ -108,6 +155,8 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
@ -197,6 +246,8 @@ github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4P
|
||||
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
@ -208,13 +259,21 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNU
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
|
||||
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/labstack/echo/v4 v4.9.0 h1:wPOF1CE6gvt/kmbMR4dGzWvHMPT+sAEUJOwOTtvITVY=
|
||||
github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
||||
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
|
||||
@ -227,6 +286,9 @@ github.com/leaanthony/gosod v1.0.3 h1:Fnt+/B6NjQOVuCWOKYRREZnjGyvg+mEhd1nkkA04aT
|
||||
github.com/leaanthony/gosod v1.0.3/go.mod h1:BJ2J+oHsQIyIQpnLPjnqFGTMnOZXDbvWtRCSG7jGxs4=
|
||||
github.com/leaanthony/slicer v1.5.0 h1:aHYTN8xbCCLxJmkNKiLB6tgcMARl4eWmH9/F+S/0HtY=
|
||||
github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
@ -235,6 +297,10 @@ github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
|
||||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
|
||||
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
@ -250,8 +316,9 @@ github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA=
|
||||
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
@ -281,6 +348,7 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE
|
||||
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d h1:VhgPp6v9qf9Agr/56bj7Y/xa04UccTW04VP0Qed4vnQ=
|
||||
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U=
|
||||
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||
@ -303,11 +371,15 @@ github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh
|
||||
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
||||
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
|
||||
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
|
||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 h1:acNfDZXmm28D2Yg/c3ALnZStzNaZMSagpbr96vY6Zjc=
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@ -337,6 +409,9 @@ github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6O
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
@ -360,6 +435,8 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
||||
github.com/sony/sonyflake v1.1.0 h1:wnrEcL3aOkWmPlhScLEGAXKkLAIslnBteNUq4Bw6MM4=
|
||||
github.com/sony/sonyflake v1.1.0/go.mod h1:LORtCywH/cq10ZbyfhKrHYgAUGH7mOBa76enV9txy/Y=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
@ -368,12 +445,26 @@ github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5J
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
|
||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
|
||||
github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
|
||||
github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M=
|
||||
github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo=
|
||||
github.com/swaggo/swag v1.16.1 h1:fTNRhKstPKxcnoKsytm4sahr8FaYzUcT7i1/3nd/fBg=
|
||||
github.com/swaggo/swag v1.16.1/go.mod h1:9/LMvHycG3NFHfR6LwvikHv5iFvmPADQ359cKikGxto=
|
||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af h1:6yITBqGTE2lEeTPG04SN9W+iWHCRyHqlVYILiSXziwk=
|
||||
@ -386,6 +477,12 @@ github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ
|
||||
github.com/tkrajina/go-reflector v0.5.5 h1:gwoQFNye30Kk7NrExj8zm3zFtrGPqOkzFMLuQZg1DtQ=
|
||||
github.com/tkrajina/go-reflector v0.5.5/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
@ -398,6 +495,7 @@ github.com/wailsapp/wails/v2 v2.5.1 h1:mfG+2kWqQXYOwdgI43HEILjOZDXbk5woPYI3jP2b+
|
||||
github.com/wailsapp/wails/v2 v2.5.1/go.mod h1:jbOZbcr/zm79PxXxAjP8UoVlDd9wLW3uDs+isIthDfs=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
||||
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
@ -411,13 +509,23 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
|
||||
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@ -433,8 +541,10 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
|
||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM=
|
||||
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
|
||||
@ -446,7 +556,8 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -465,9 +576,12 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
||||
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -477,6 +591,7 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -503,25 +618,35 @@ golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
|
||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
|
||||
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@ -543,12 +668,15 @@ golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
|
||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
@ -568,9 +696,16 @@ google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
@ -583,11 +718,14 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
@ -701,6 +839,7 @@ modernc.org/tcl v1.8.13/go.mod h1:V+q/Ef0IJaNUSECieLU4o+8IScapxnMyFV6i/7uQlAY=
|
||||
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
|
||||
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/z v1.2.19/go.mod h1:+ZpP0pc4zz97eukOzW3xagV/lS82IpPN9NGG5pNF9vY=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
||||
xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978 h1:bvLlAPW1ZMTWA32LuZMBEGHAUOcATZjzHcotf3SWweM=
|
||||
|
@ -1,10 +1,11 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"changeme/lib/env"
|
||||
"changeme/lib/system"
|
||||
"changeme/lib/utils"
|
||||
"embed"
|
||||
"skapp/pkg/env"
|
||||
"skapp/pkg/sdk/system"
|
||||
systemUtils "skapp/pkg/system"
|
||||
"skapp/pkg/utils"
|
||||
|
||||
"github.com/wailsapp/wails/v2"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
@ -15,6 +16,9 @@ import (
|
||||
var assets embed.FS
|
||||
|
||||
func main() {
|
||||
defer func() {
|
||||
system.DestroyFileManager()
|
||||
}()
|
||||
// Create an instance of the app structure
|
||||
app := NewApp()
|
||||
|
||||
@ -28,11 +32,13 @@ func main() {
|
||||
},
|
||||
BackgroundColour: &options.RGBA{R: 255, G: 255, B: 255, A: 1},
|
||||
OnStartup: app.startup,
|
||||
OnBeforeClose: app.beforeClose,
|
||||
OnShutdown: app.shutdown,
|
||||
Bind: []interface{}{
|
||||
app,
|
||||
&env.Env{},
|
||||
&utils.Utils{},
|
||||
&system.InfoUtils{},
|
||||
&systemUtils.InfoUtils{},
|
||||
},
|
||||
Debug: options.Debug{
|
||||
OpenInspectorOnStartup: true,
|
||||
|
28
app/wails/pkg/config/config.go
Normal file
28
app/wails/pkg/config/config.go
Normal file
@ -0,0 +1,28 @@
|
||||
package config
|
||||
|
||||
type Config struct {
|
||||
Server *ServerConfig `toml:"server" json:"server" comment:"服务配置"`
|
||||
Debug *DebuggerConfig `toml:"debug" json:"debug" comment:"调试模式"`
|
||||
}
|
||||
|
||||
type ServerConfig struct {
|
||||
Host string `toml:"host" json:"host" comment:"监听ip"`
|
||||
Port int `toml:"port" json:"port" comment:"监听端口"`
|
||||
}
|
||||
|
||||
type DebuggerConfig struct {
|
||||
Enable bool `toml:"enable" json:"enable" comment:"启用"`
|
||||
}
|
||||
|
||||
func (c *Config) HasDebug() bool {
|
||||
return c.Debug != nil
|
||||
}
|
||||
|
||||
func DefaultConfig() *Config {
|
||||
return &Config{
|
||||
Server: &ServerConfig{
|
||||
Host: "localhost",
|
||||
Port: 32323,
|
||||
},
|
||||
}
|
||||
}
|
50
app/wails/pkg/config/toml/config.go
Normal file
50
app/wails/pkg/config/toml/config.go
Normal file
@ -0,0 +1,50 @@
|
||||
package toml
|
||||
|
||||
import (
|
||||
"github.com/pelletier/go-toml/v2"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"skapp/pkg/logger"
|
||||
|
||||
"skapp/pkg/config"
|
||||
)
|
||||
|
||||
func LoadConfig() (*config.Config, error) {
|
||||
p, _ := filepath.Abs("./config.toml")
|
||||
logger.Log.Infof("配置文件路径 %s", p)
|
||||
|
||||
flag := os.O_RDWR
|
||||
_, err := os.Stat(p)
|
||||
exist := !os.IsNotExist(err)
|
||||
|
||||
if !exist {
|
||||
f, err := os.OpenFile(p, flag|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
_ = f.Close()
|
||||
}()
|
||||
encoder := toml.NewEncoder(f)
|
||||
encoder.SetIndentTables(true)
|
||||
_ = encoder.Encode(config.DefaultConfig())
|
||||
_ = f.Sync()
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(p, flag, 0644)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
_ = f.Close()
|
||||
}()
|
||||
|
||||
c := &config.Config{}
|
||||
decoder := toml.NewDecoder(f)
|
||||
err = decoder.Decode(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
10
app/wails/pkg/config/toml/toml_test.go
Normal file
10
app/wails/pkg/config/toml/toml_test.go
Normal file
@ -0,0 +1,10 @@
|
||||
package toml
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestLoadConfig(t *testing.T) {
|
||||
_, err := LoadConfig()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package lib
|
||||
package pkg
|
||||
|
||||
import (
|
||||
"bytes"
|
63
app/wails/pkg/logger/adapter.go
Normal file
63
app/wails/pkg/logger/adapter.go
Normal file
@ -0,0 +1,63 @@
|
||||
package logger
|
||||
|
||||
import "go.uber.org/zap"
|
||||
|
||||
type WailsZapLoggerAdaptor struct {
|
||||
logger *zap.SugaredLogger
|
||||
}
|
||||
|
||||
func (w *WailsZapLoggerAdaptor) Print(message string) {
|
||||
w.logger.Info(message)
|
||||
}
|
||||
|
||||
func (w *WailsZapLoggerAdaptor) Trace(message string) {
|
||||
w.logger.Error(message)
|
||||
}
|
||||
|
||||
func (w *WailsZapLoggerAdaptor) Debug(message string) {
|
||||
w.logger.Debug(message)
|
||||
}
|
||||
|
||||
func (w *WailsZapLoggerAdaptor) Debugf(template string, args ...interface{}) {
|
||||
w.logger.Debugf(template, args...)
|
||||
}
|
||||
|
||||
func (w *WailsZapLoggerAdaptor) Info(message string) {
|
||||
w.logger.Info(message)
|
||||
}
|
||||
|
||||
func (w *WailsZapLoggerAdaptor) Infof(template string, args ...interface{}) {
|
||||
w.logger.Infof(template, args...)
|
||||
}
|
||||
|
||||
func (w *WailsZapLoggerAdaptor) Warning(message string) {
|
||||
w.logger.Warn(message)
|
||||
}
|
||||
|
||||
func (w *WailsZapLoggerAdaptor) Warn(message string) {
|
||||
w.Warning(message)
|
||||
}
|
||||
|
||||
func (w *WailsZapLoggerAdaptor) Warnf(message string, args ...interface{}) {
|
||||
w.logger.Warnf(message, args...)
|
||||
}
|
||||
|
||||
func (w *WailsZapLoggerAdaptor) Error(message string) {
|
||||
w.logger.Error(message)
|
||||
}
|
||||
|
||||
func (w *WailsZapLoggerAdaptor) Errorln(err error) {
|
||||
w.logger.Error(err)
|
||||
}
|
||||
|
||||
func (w *WailsZapLoggerAdaptor) Errorf(template string, args ...interface{}) {
|
||||
w.logger.Errorf(template, args...)
|
||||
}
|
||||
|
||||
func (w *WailsZapLoggerAdaptor) Fatal(message string) {
|
||||
w.logger.Fatal(message)
|
||||
}
|
||||
|
||||
func (w *WailsZapLoggerAdaptor) Fatalf(message string, args ...interface{}) {
|
||||
w.logger.Fatalf(message, args...)
|
||||
}
|
56
app/wails/pkg/logger/logger.go
Normal file
56
app/wails/pkg/logger/logger.go
Normal file
@ -0,0 +1,56 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"go.uber.org/atomic"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"os"
|
||||
)
|
||||
|
||||
var Log *WailsZapLoggerAdaptor
|
||||
|
||||
var sugar *zap.SugaredLogger
|
||||
var logger *zap.Logger
|
||||
var level = &atomic.String{}
|
||||
|
||||
func init() {
|
||||
SetLevel(zapcore.DebugLevel)
|
||||
encoder := zapcore.NewConsoleEncoder(DefaultEncoderConfig())
|
||||
multiWriteSyncer := zapcore.NewMultiWriteSyncer(DefaultConsoleSyncer())
|
||||
|
||||
core := zapcore.NewCore(encoder, multiWriteSyncer, DefaultLevelEnabler())
|
||||
logger = zap.New(core, zap.AddCaller())
|
||||
defer func() {
|
||||
_ = logger.Sync()
|
||||
}()
|
||||
sugar = logger.Sugar()
|
||||
|
||||
Log = &WailsZapLoggerAdaptor{logger: sugar}
|
||||
}
|
||||
|
||||
func DefaultTimeEncoder() (timeEncoder zapcore.TimeEncoder) {
|
||||
timeEncoder = zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05.000")
|
||||
return
|
||||
}
|
||||
|
||||
func SetLevel(l zapcore.Level) {
|
||||
level.Store(l.String())
|
||||
}
|
||||
|
||||
func DefaultLevelEnabler() zap.LevelEnablerFunc {
|
||||
return func(z zapcore.Level) bool {
|
||||
l, _ := zapcore.ParseLevel(level.Load())
|
||||
return z >= l
|
||||
}
|
||||
}
|
||||
|
||||
func DefaultEncoderConfig() (encoderConfig zapcore.EncoderConfig) {
|
||||
encoderConfig = zap.NewProductionEncoderConfig()
|
||||
encoderConfig.EncodeTime = DefaultTimeEncoder()
|
||||
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
|
||||
return
|
||||
}
|
||||
|
||||
func DefaultConsoleSyncer() zapcore.WriteSyncer {
|
||||
return zapcore.AddSync(os.Stdout)
|
||||
}
|
17
app/wails/pkg/logger/logger_test.go
Normal file
17
app/wails/pkg/logger/logger_test.go
Normal file
@ -0,0 +1,17 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"go.uber.org/zap/zapcore"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestLogger(t *testing.T) {
|
||||
Log.Debugf("%s", time.Now().Format("2006-01-02 15:04:05.000"))
|
||||
Log.Infof("%s", time.Now().Format("2006-01-02 15:04:05.000"))
|
||||
|
||||
SetLevel(zapcore.InfoLevel)
|
||||
|
||||
Log.Debugf("%s", time.Now().Format("2006-01-02 15:04:05.000"))
|
||||
Log.Infof("%s", time.Now().Format("2006-01-02 15:04:05.000"))
|
||||
}
|
24
app/wails/pkg/pid/pid.go
Normal file
24
app/wails/pkg/pid/pid.go
Normal file
@ -0,0 +1,24 @@
|
||||
package pid
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
var (
|
||||
LockFail = errors.New("进程锁创建失败")
|
||||
)
|
||||
|
||||
type PidLock struct {
|
||||
file string
|
||||
lock *os.File
|
||||
}
|
||||
|
||||
func NewPidLock(path string) *PidLock {
|
||||
absPath, _ := filepath.Abs(path)
|
||||
|
||||
return &PidLock{
|
||||
file: absPath,
|
||||
}
|
||||
}
|
21
app/wails/pkg/pid/pid_test.go
Normal file
21
app/wails/pkg/pid/pid_test.go
Normal file
@ -0,0 +1,21 @@
|
||||
package pid
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestPidLock_Lock(t *testing.T) {
|
||||
name := "./.pid"
|
||||
|
||||
lock := NewPidLock(name)
|
||||
err := lock.Lock()
|
||||
defer func(lock *PidLock) {
|
||||
lock.UnLock()
|
||||
}(lock)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(t)
|
||||
}
|
||||
time.Sleep(10 * time.Second)
|
||||
}
|
36
app/wails/pkg/pid/pid_unix.go
Normal file
36
app/wails/pkg/pid/pid_unix.go
Normal file
@ -0,0 +1,36 @@
|
||||
//go:build !windows
|
||||
|
||||
package pid
|
||||
|
||||
import (
|
||||
"os"
|
||||
"skapp/pkg/logger"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func (p *PidLock) Lock() error {
|
||||
_, err := os.Stat(p.file)
|
||||
if err == nil {
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
pidFileHandle, err := os.OpenFile(pidFile, os.O_RDONLY|os.O_CREATE, os.ModePerm)
|
||||
if err != nil {
|
||||
logger.Log.Fatalf("启动失败 进程锁文件 .pid 创建失败")
|
||||
return LockFail
|
||||
}
|
||||
|
||||
err = syscall.Flock(int(pidFileHandle.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
|
||||
if err != nil {
|
||||
logger.Log.Fatalf("启动失败 进程锁文件 .pid 被占用")
|
||||
return LockFail
|
||||
}
|
||||
p.lock = pidFileHandle
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PidLock) UnLock() {
|
||||
_ = syscall.Flock(int(p.lock.Fd()), syscall.LOCK_UN)
|
||||
_ = p.lock.Close()
|
||||
_ = os.Remove(p.file)
|
||||
}
|
119
app/wails/pkg/pid/pid_windows.go
Normal file
119
app/wails/pkg/pid/pid_windows.go
Normal file
@ -0,0 +1,119 @@
|
||||
//go:build windows
|
||||
|
||||
package pid
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"skapp/pkg/logger"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var pidFile = "./.pid"
|
||||
|
||||
var (
|
||||
kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||
procLockFileEx = kernel32.NewProc("LockFileEx")
|
||||
procUnlockFileEx = kernel32.NewProc("UnlockFileEx")
|
||||
)
|
||||
|
||||
const (
|
||||
fileFlagNormal = 0x00000080
|
||||
lockfileExclusiveLock = 0x00000002
|
||||
lockfileFailImmediately = 0x00000001
|
||||
)
|
||||
|
||||
func (p *PidLock) Lock() error {
|
||||
_, err := os.Stat(p.file)
|
||||
if err == nil {
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(pidFile, os.O_RDONLY|os.O_CREATE, os.ModePerm)
|
||||
if err != nil {
|
||||
logger.Log.Fatalf("启动失败 进程锁文件 .pid 创建失败")
|
||||
return LockFail
|
||||
}
|
||||
|
||||
p.lock = f
|
||||
_ = f.Sync()
|
||||
|
||||
err = TryLockEX(f)
|
||||
|
||||
if err != nil {
|
||||
logger.Log.Fatal(err.Error())
|
||||
return LockFail
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// LockSH places a shared lock on the file. If the file is already locked, waits until the file is released.
|
||||
func LockSH(fp *os.File) error {
|
||||
r1, errNo := wlock(fp, 0x0)
|
||||
return isWError(r1, errNo)
|
||||
}
|
||||
|
||||
// LockEX places an exclusive lock on the file. If the file is already locked, waits until the file is released.
|
||||
func LockEX(fp *os.File) error {
|
||||
r1, errNo := wlock(fp, lockfileExclusiveLock)
|
||||
return isWError(r1, errNo)
|
||||
}
|
||||
|
||||
// TryLockSH places a shared lock on the file. If the file is already locked, returns an error immediately.
|
||||
func TryLockSH(fp *os.File) error {
|
||||
r1, errNo := wlock(fp, lockfileFailImmediately)
|
||||
return isWError(r1, errNo)
|
||||
}
|
||||
|
||||
// TryLockEX places an exclusive lock on the file. If the file is already locked, returns an error immediately.
|
||||
func TryLockEX(fp *os.File) error {
|
||||
r1, errNo := wlock(fp, lockfileExclusiveLock|lockfileFailImmediately)
|
||||
return isWError(r1, errNo)
|
||||
}
|
||||
|
||||
// Unlock the file.
|
||||
func Unlock(fp *os.File) error {
|
||||
r1, _, errNo := syscall.SyscallN(
|
||||
procUnlockFileEx.Addr(),
|
||||
fp.Fd(),
|
||||
uintptr(0),
|
||||
uintptr(1),
|
||||
uintptr(0),
|
||||
uintptr(unsafe.Pointer(&syscall.Overlapped{})),
|
||||
0,
|
||||
)
|
||||
return isWError(r1, errNo)
|
||||
}
|
||||
|
||||
func wlock(fp *os.File, flags uintptr) (uintptr, syscall.Errno) {
|
||||
r1, _, errNo := syscall.SyscallN(
|
||||
procLockFileEx.Addr(),
|
||||
fp.Fd(),
|
||||
flags,
|
||||
uintptr(0),
|
||||
uintptr(1),
|
||||
uintptr(0),
|
||||
uintptr(unsafe.Pointer(&syscall.Overlapped{})),
|
||||
)
|
||||
return r1, errNo
|
||||
}
|
||||
|
||||
func isWError(r1 uintptr, errNo syscall.Errno) error {
|
||||
if r1 != 1 {
|
||||
if errNo != 0 {
|
||||
return errors.New(errNo.Error())
|
||||
} else {
|
||||
return syscall.EINVAL
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PidLock) UnLock() {
|
||||
_ = Unlock(p.lock)
|
||||
_ = p.lock.Close()
|
||||
_ = os.Remove(p.file)
|
||||
}
|
168
app/wails/pkg/sdk/system/file/manager.go
Normal file
168
app/wails/pkg/sdk/system/file/manager.go
Normal file
@ -0,0 +1,168 @@
|
||||
package file
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"skapp/pkg/logger"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Manager struct {
|
||||
FileManager *sync.Map
|
||||
lock *sync.RWMutex
|
||||
}
|
||||
|
||||
func NewManager() *Manager {
|
||||
return &Manager{
|
||||
FileManager: &sync.Map{},
|
||||
lock: &sync.RWMutex{},
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Manager) Len() (count int64) {
|
||||
defer func() {
|
||||
m.lock.RUnlock()
|
||||
}()
|
||||
m.lock.RLock()
|
||||
|
||||
m.Each(func(file *os.File) bool {
|
||||
count++
|
||||
return true
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (m *Manager) Each(cb func(*os.File) bool) {
|
||||
defer func() {
|
||||
m.lock.RUnlock()
|
||||
}()
|
||||
m.lock.RLock()
|
||||
|
||||
m.FileManager.Range(func(key, value any) bool {
|
||||
flagManager := value.(*sync.Map)
|
||||
flagManager.Range(func(key, value any) bool {
|
||||
fileModeManager := value.(*sync.Map)
|
||||
fileModeManager.Range(func(key, value any) bool {
|
||||
f := (value).(*os.File)
|
||||
return cb(f)
|
||||
})
|
||||
return true
|
||||
})
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func (m *Manager) Remove(path string, flag int, perm fs.FileMode) {
|
||||
if m.Get(path, flag, perm) == nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer func() {
|
||||
m.lock.Unlock()
|
||||
}()
|
||||
m.lock.Lock()
|
||||
|
||||
absPath, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
logger.Log.Infof("Remove %+v %+v %+v\n", absPath, flag, perm)
|
||||
var value interface{}
|
||||
value, _ = m.FileManager.Load(absPath)
|
||||
flagManager := value.(*sync.Map)
|
||||
|
||||
value, _ = flagManager.Load(flag)
|
||||
fileModeManager := value.(*sync.Map)
|
||||
|
||||
value, _ = fileModeManager.LoadAndDelete(perm.String())
|
||||
f := value.(*os.File)
|
||||
_ = f.Close()
|
||||
}
|
||||
|
||||
func (m *Manager) Get(path string, flag int, perm fs.FileMode) *os.File {
|
||||
defer func() {
|
||||
m.lock.RUnlock()
|
||||
}()
|
||||
m.lock.RLock()
|
||||
|
||||
absPath, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
logger.Log.Infof("Get %+v %+v %+v\n", absPath, flag, perm)
|
||||
value, ok := m.FileManager.Load(absPath)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch flagManager := value.(type) {
|
||||
case *sync.Map:
|
||||
value, ok := flagManager.Load(flag)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch fileModeManager := value.(type) {
|
||||
case *sync.Map:
|
||||
f, ok := fileModeManager.Load(perm.String())
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
return f.(*os.File)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Manager) Close() {
|
||||
m.Each(func(f *os.File) bool {
|
||||
_ = f.Close()
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func (m *Manager) Set(file *os.File, path string, flag int, perm fs.FileMode) {
|
||||
defer func() {
|
||||
m.lock.Unlock()
|
||||
}()
|
||||
m.lock.Lock()
|
||||
|
||||
absPath, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
logger.Log.Infof("Set %+v %+v %+v\n", absPath, flag, perm)
|
||||
value, ok := m.FileManager.Load(path)
|
||||
if !ok {
|
||||
flagManager := sync.Map{}
|
||||
fileModeManager := sync.Map{}
|
||||
fileModeManager.Store(perm.String(), file)
|
||||
flagManager.Store(flag, &fileModeManager)
|
||||
m.FileManager.Store(absPath, &flagManager)
|
||||
return
|
||||
}
|
||||
|
||||
switch flagManager := value.(type) {
|
||||
case *sync.Map:
|
||||
value, ok := flagManager.Load(flag)
|
||||
if !ok {
|
||||
fileModeManager := sync.Map{}
|
||||
fileModeManager.Store(perm.String(), file)
|
||||
flagManager.Store(flag, &fileModeManager)
|
||||
}
|
||||
|
||||
switch fileModeManager := value.(type) {
|
||||
case *sync.Map:
|
||||
_, ok := fileModeManager.Load(perm.String())
|
||||
if !ok {
|
||||
fileModeManager.Store(perm.String(), file)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
app/wails/pkg/sdk/system/io.go
Normal file
11
app/wails/pkg/sdk/system/io.go
Normal file
@ -0,0 +1,11 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"skapp/pkg/sdk/system/file"
|
||||
)
|
||||
|
||||
var FileManager = file.NewManager()
|
||||
|
||||
func DestroyFileManager() {
|
||||
FileManager.Close()
|
||||
}
|
75
app/wails/pkg/sdk/system/io_test.go
Normal file
75
app/wails/pkg/sdk/system/io_test.go
Normal file
@ -0,0 +1,75 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var wg = sync.WaitGroup{}
|
||||
|
||||
func TestAppendFileManager(t *testing.T) {
|
||||
defer func() {
|
||||
DestroyFileManager()
|
||||
}()
|
||||
|
||||
path := "./io.go"
|
||||
absPath, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = os.Stat(absPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(absPath, os.O_RDONLY, 0644)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
FileManager.Set(f, absPath, os.O_RDONLY, 0644)
|
||||
|
||||
t.Logf("文件数量: %d", FileManager.Len())
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
wg.Add(1)
|
||||
go func(i int, t *testing.T) {
|
||||
f := FileManager.Get(absPath, os.O_RDONLY, 0644)
|
||||
if f != nil {
|
||||
t.Log(f.Stat())
|
||||
}
|
||||
|
||||
if i == 5 {
|
||||
FileManager.Remove(absPath, os.O_RDONLY, 0644)
|
||||
}
|
||||
wg.Done()
|
||||
}(i, t)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestManager(t *testing.T) {
|
||||
path := "./io.go"
|
||||
absPath, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err = os.Stat(absPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(absPath, os.O_RDONLY, 0644)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
FileManager.Set(f, absPath, os.O_RDONLY, 0644)
|
||||
|
||||
f = FileManager.Get(absPath, 0, 0644)
|
||||
t.Log(f.Name())
|
||||
}
|
68
app/wails/pkg/sdk/system/system.go
Normal file
68
app/wails/pkg/sdk/system/system.go
Normal file
@ -0,0 +1,68 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type System struct{}
|
||||
|
||||
func (s *System) GetFileInfo(path string) (os.FileInfo, error) {
|
||||
f, err := os.OpenFile(path, os.O_RDONLY, 0644)
|
||||
defer func(f *os.File) {
|
||||
_ = f.Close()
|
||||
}(f)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return f.Stat()
|
||||
}
|
||||
|
||||
func (s *System) OpenFile(path string, flag int, perm fs.FileMode) (*os.File, error) {
|
||||
absPath, err := filepath.Abs(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = os.Stat(absPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(absPath, flag, perm)
|
||||
FileManager.Set(f, absPath, flag, perm)
|
||||
return f, err
|
||||
}
|
||||
|
||||
func (s *System) ReadFile(path string, chunkId int64, chunkSize int64) ([]byte, error) {
|
||||
f := FileManager.Get(path, os.O_RDONLY, fs.FileMode(0644))
|
||||
if f == nil {
|
||||
return nil, os.ErrClosed
|
||||
}
|
||||
|
||||
info, err := f.Stat()
|
||||
size := info.Size()
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
offset := chunkId * chunkSize
|
||||
if offset+chunkSize > size {
|
||||
chunkSize = size - offset
|
||||
}
|
||||
|
||||
data := make([]byte, chunkSize)
|
||||
_, err = f.ReadAt(data, offset)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (s *System) CloseFile(path string, flag int, perm fs.FileMode) {
|
||||
FileManager.Remove(path, flag, perm)
|
||||
}
|
22
app/wails/pkg/server/controller/config.go
Normal file
22
app/wails/pkg/server/controller/config.go
Normal file
@ -0,0 +1,22 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"skapp/global"
|
||||
"skapp/pkg/utils/response"
|
||||
)
|
||||
|
||||
// PostConfig
|
||||
// List 获取配置
|
||||
//
|
||||
// @Summary 获取应用列表
|
||||
// @Description 获取应用列表
|
||||
// @Tags Config
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} response.Response{data=config.Config}
|
||||
// @Failure default {object} errorx.CodeErrorResponse
|
||||
// @Router /config/ [post]
|
||||
func PostConfig(ctx *gin.Context) {
|
||||
ctx.JSON(200, response.NewResponse(global.Config))
|
||||
}
|
88
app/wails/pkg/server/controller/file.go
Normal file
88
app/wails/pkg/server/controller/file.go
Normal file
@ -0,0 +1,88 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"skapp/pkg/logger"
|
||||
"skapp/pkg/utils/errorx"
|
||||
"skapp/pkg/utils/response"
|
||||
)
|
||||
|
||||
type GetPathDto struct {
|
||||
// 路径
|
||||
Path string `form:"path" binding:"required" example:"C:\\Windows\\System32\\cmd.exe"`
|
||||
}
|
||||
|
||||
type GetFileDto struct {
|
||||
// 路径
|
||||
Path string `form:"path" binding:"required" example:"C:\\Windows\\System32\\cmd.exe"`
|
||||
// 偏移量
|
||||
Offset int64 `form:"offset"`
|
||||
// 区块大小
|
||||
ChunkSize int64 `form:"chunkSize"`
|
||||
}
|
||||
|
||||
// GetPath
|
||||
// @Summary 获取文件路径
|
||||
// @Description 获取文件路径
|
||||
// @Tags File
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param vo query controller.GetPathDto true "获取文件路径"
|
||||
// @Success 200 {object} response.Response{data=string}
|
||||
// @Failure default {object} errorx.CodeErrorResponse
|
||||
// @Router /file/path [get]
|
||||
func GetPath(ctx *gin.Context) {
|
||||
dto := &GetPathDto{}
|
||||
err := ctx.ShouldBindQuery(dto)
|
||||
if err = errorx.ParseError(err); err != nil {
|
||||
logger.Log.Errorln(err)
|
||||
ctx.JSON(200, err)
|
||||
}
|
||||
logger.Log.Infof("%+v", dto)
|
||||
|
||||
absPath, _ := filepath.Abs(dto.Path)
|
||||
ctx.JSON(200, response.NewResponse(absPath))
|
||||
}
|
||||
|
||||
// GetFile
|
||||
// @Summary 获取文件
|
||||
// @Description 获取文件
|
||||
// @Tags File
|
||||
// @Accept json
|
||||
// @Produce octet-stream
|
||||
// @Param vo query controller.GetFileDto true "获取文件"
|
||||
// @Router /file/ [get]
|
||||
func GetFile(ctx *gin.Context) {
|
||||
dto := &GetFileDto{}
|
||||
err := ctx.BindQuery(dto)
|
||||
if err != nil {
|
||||
ctx.Status(http.StatusInternalServerError)
|
||||
logger.Log.Errorln(err)
|
||||
return
|
||||
}
|
||||
|
||||
offset := dto.Offset
|
||||
chunkSize := dto.ChunkSize
|
||||
|
||||
p, _ := filepath.Abs(dto.Path)
|
||||
info, err := os.Stat(p)
|
||||
if err != nil || info.IsDir() {
|
||||
ctx.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
if offset == 0 && chunkSize == 0 {
|
||||
ctx.File(p)
|
||||
return
|
||||
} else {
|
||||
w := ctx.Writer
|
||||
ctx.Request.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", offset, offset+chunkSize))
|
||||
logger.Log.Debugf("%s", ctx.Request.Header.Get("Range"))
|
||||
http.ServeFile(w, ctx.Request, p)
|
||||
return
|
||||
}
|
||||
}
|
43
app/wails/pkg/server/controller/wol.go
Normal file
43
app/wails/pkg/server/controller/wol.go
Normal file
@ -0,0 +1,43 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"skapp/pkg/server/services/wol"
|
||||
"skapp/pkg/utils/errorx"
|
||||
"skapp/pkg/utils/response"
|
||||
)
|
||||
|
||||
type WakeupDTO struct {
|
||||
// mac 地址
|
||||
Mac string `json:"mac" example:"FF-FF-FF-FF-FF-FF-FF"`
|
||||
// 端口
|
||||
Port int `json:"port" example:"9"`
|
||||
}
|
||||
|
||||
// PostWolWakeUP
|
||||
// @Summary wol 唤醒
|
||||
// @Description wol 唤醒
|
||||
// @Tags Wol
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param vo body WakeupDTO true "局域网唤醒"
|
||||
// @Success 200 {object} response.Response{data=string}
|
||||
// @Failure default {object} errorx.CodeErrorResponse
|
||||
// @Router /wol/wakeup [post]
|
||||
func PostWolWakeUP(ctx *gin.Context) {
|
||||
dto := &WakeupDTO{
|
||||
Mac: "FF:FF:FF:FF:FF:FF",
|
||||
Port: 9,
|
||||
}
|
||||
|
||||
_ = ctx.BindJSON(dto)
|
||||
|
||||
err := wol.Services.WakeUp(dto.Mac, dto.Port)
|
||||
if err = errorx.ParseError(err); err != nil {
|
||||
ctx.JSON(200, err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSON(200, response.NewResponse(fmt.Sprintf("%s 唤醒包发送成功", dto.Mac)))
|
||||
}
|
407
app/wails/pkg/server/docs/docs.go
Normal file
407
app/wails/pkg/server/docs/docs.go
Normal file
@ -0,0 +1,407 @@
|
||||
// Code generated by swaggo/swag. DO NOT EDIT
|
||||
package docs
|
||||
|
||||
import "github.com/swaggo/swag"
|
||||
|
||||
const docTemplate = `{
|
||||
"schemes": {{ marshal .Schemes }},
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"description": "{{escape .Description}}",
|
||||
"title": "{{.Title}}",
|
||||
"termsOfService": "http://swagger.io/terms/",
|
||||
"contact": {
|
||||
"name": "Shikong",
|
||||
"email": "919411476@qq.com"
|
||||
},
|
||||
"license": {
|
||||
"name": "Apache 2.0",
|
||||
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
|
||||
},
|
||||
"version": "{{.Version}}"
|
||||
},
|
||||
"host": "{{.Host}}",
|
||||
"basePath": "{{.BasePath}}",
|
||||
"paths": {
|
||||
"/config/": {
|
||||
"post": {
|
||||
"description": "获取应用列表",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Config"
|
||||
],
|
||||
"summary": "获取应用列表",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/response.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/config.Config"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errorx.CodeErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/error": {
|
||||
"get": {
|
||||
"description": "错误信息示例",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Error"
|
||||
],
|
||||
"summary": "错误处理",
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errorx.CodeErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"description": "错误信息示例",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Error"
|
||||
],
|
||||
"summary": "错误处理",
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errorx.CodeErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"description": "错误信息示例",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Error"
|
||||
],
|
||||
"summary": "错误处理",
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errorx.CodeErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"description": "错误信息示例",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Error"
|
||||
],
|
||||
"summary": "错误处理",
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errorx.CodeErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"patch": {
|
||||
"description": "错误信息示例",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Error"
|
||||
],
|
||||
"summary": "错误处理",
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errorx.CodeErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/file/": {
|
||||
"get": {
|
||||
"description": "获取文件",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/octet-stream"
|
||||
],
|
||||
"tags": [
|
||||
"File"
|
||||
],
|
||||
"summary": "获取文件",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "区块大小",
|
||||
"name": "chunkSize",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "偏移量",
|
||||
"name": "offset",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"example": "C:\\Windows\\System32\\cmd.exe",
|
||||
"description": "路径",
|
||||
"name": "path",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/file/path": {
|
||||
"get": {
|
||||
"description": "获取文件路径",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"File"
|
||||
],
|
||||
"summary": "获取文件路径",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"example": "C:\\Windows\\System32\\cmd.exe",
|
||||
"description": "路径",
|
||||
"name": "path",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/response.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errorx.CodeErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/wol/wakeup": {
|
||||
"post": {
|
||||
"description": "wol 唤醒",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Wol"
|
||||
],
|
||||
"summary": "wol 唤醒",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "局域网唤醒",
|
||||
"name": "vo",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controller.WakeupDTO"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/response.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errorx.CodeErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"config.Config": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"debug": {
|
||||
"$ref": "#/definitions/config.DebuggerConfig"
|
||||
},
|
||||
"server": {
|
||||
"$ref": "#/definitions/config.ServerConfig"
|
||||
}
|
||||
}
|
||||
},
|
||||
"config.DebuggerConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"config.ServerConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"host": {
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"controller.WakeupDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"mac": {
|
||||
"description": "mac 地址",
|
||||
"type": "string",
|
||||
"example": "FF-FF-FF-FF-FF-FF-FF"
|
||||
},
|
||||
"port": {
|
||||
"description": "端口",
|
||||
"type": "integer",
|
||||
"example": 9
|
||||
}
|
||||
}
|
||||
},
|
||||
"errorx.CodeErrorResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "integer",
|
||||
"example": 200
|
||||
},
|
||||
"data": {},
|
||||
"msg": {
|
||||
"type": "string",
|
||||
"example": "OK"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response.Response": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "integer",
|
||||
"example": 200
|
||||
},
|
||||
"data": {},
|
||||
"msg": {
|
||||
"type": "string",
|
||||
"example": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
||||
var SwaggerInfo = &swag.Spec{
|
||||
Version: "1.0",
|
||||
Host: "",
|
||||
BasePath: "/s",
|
||||
Schemes: []string{},
|
||||
Title: "Wails AssetServer API",
|
||||
Description: "Wails AssetServer API 文档",
|
||||
InfoInstanceName: "swagger",
|
||||
SwaggerTemplate: docTemplate,
|
||||
}
|
||||
|
||||
func init() {
|
||||
swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
|
||||
}
|
384
app/wails/pkg/server/docs/swagger.json
Normal file
384
app/wails/pkg/server/docs/swagger.json
Normal file
@ -0,0 +1,384 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"description": "Wails AssetServer API 文档",
|
||||
"title": "Wails AssetServer API",
|
||||
"termsOfService": "http://swagger.io/terms/",
|
||||
"contact": {
|
||||
"name": "Shikong",
|
||||
"email": "919411476@qq.com"
|
||||
},
|
||||
"license": {
|
||||
"name": "Apache 2.0",
|
||||
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
|
||||
},
|
||||
"version": "1.0"
|
||||
},
|
||||
"basePath": "/s",
|
||||
"paths": {
|
||||
"/config/": {
|
||||
"post": {
|
||||
"description": "获取应用列表",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Config"
|
||||
],
|
||||
"summary": "获取应用列表",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/response.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/config.Config"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errorx.CodeErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/error": {
|
||||
"get": {
|
||||
"description": "错误信息示例",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Error"
|
||||
],
|
||||
"summary": "错误处理",
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errorx.CodeErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"description": "错误信息示例",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Error"
|
||||
],
|
||||
"summary": "错误处理",
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errorx.CodeErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"description": "错误信息示例",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Error"
|
||||
],
|
||||
"summary": "错误处理",
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errorx.CodeErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"description": "错误信息示例",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Error"
|
||||
],
|
||||
"summary": "错误处理",
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errorx.CodeErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"patch": {
|
||||
"description": "错误信息示例",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Error"
|
||||
],
|
||||
"summary": "错误处理",
|
||||
"responses": {
|
||||
"default": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errorx.CodeErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/file/": {
|
||||
"get": {
|
||||
"description": "获取文件",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/octet-stream"
|
||||
],
|
||||
"tags": [
|
||||
"File"
|
||||
],
|
||||
"summary": "获取文件",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "区块大小",
|
||||
"name": "chunkSize",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"description": "偏移量",
|
||||
"name": "offset",
|
||||
"in": "query"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"example": "C:\\Windows\\System32\\cmd.exe",
|
||||
"description": "路径",
|
||||
"name": "path",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {}
|
||||
}
|
||||
},
|
||||
"/file/path": {
|
||||
"get": {
|
||||
"description": "获取文件路径",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"File"
|
||||
],
|
||||
"summary": "获取文件路径",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"example": "C:\\Windows\\System32\\cmd.exe",
|
||||
"description": "路径",
|
||||
"name": "path",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/response.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errorx.CodeErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/wol/wakeup": {
|
||||
"post": {
|
||||
"description": "wol 唤醒",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Wol"
|
||||
],
|
||||
"summary": "wol 唤醒",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "局域网唤醒",
|
||||
"name": "vo",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controller.WakeupDTO"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/response.Response"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/errorx.CodeErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"config.Config": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"debug": {
|
||||
"$ref": "#/definitions/config.DebuggerConfig"
|
||||
},
|
||||
"server": {
|
||||
"$ref": "#/definitions/config.ServerConfig"
|
||||
}
|
||||
}
|
||||
},
|
||||
"config.DebuggerConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"enable": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"config.ServerConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"host": {
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"controller.WakeupDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"mac": {
|
||||
"description": "mac 地址",
|
||||
"type": "string",
|
||||
"example": "FF-FF-FF-FF-FF-FF-FF"
|
||||
},
|
||||
"port": {
|
||||
"description": "端口",
|
||||
"type": "integer",
|
||||
"example": 9
|
||||
}
|
||||
}
|
||||
},
|
||||
"errorx.CodeErrorResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "integer",
|
||||
"example": 200
|
||||
},
|
||||
"data": {},
|
||||
"msg": {
|
||||
"type": "string",
|
||||
"example": "OK"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response.Response": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "integer",
|
||||
"example": 200
|
||||
},
|
||||
"data": {},
|
||||
"msg": {
|
||||
"type": "string",
|
||||
"example": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
248
app/wails/pkg/server/docs/swagger.yaml
Normal file
248
app/wails/pkg/server/docs/swagger.yaml
Normal file
@ -0,0 +1,248 @@
|
||||
basePath: /s
|
||||
definitions:
|
||||
config.Config:
|
||||
properties:
|
||||
debug:
|
||||
$ref: '#/definitions/config.DebuggerConfig'
|
||||
server:
|
||||
$ref: '#/definitions/config.ServerConfig'
|
||||
type: object
|
||||
config.DebuggerConfig:
|
||||
properties:
|
||||
enable:
|
||||
type: boolean
|
||||
type: object
|
||||
config.ServerConfig:
|
||||
properties:
|
||||
host:
|
||||
type: string
|
||||
port:
|
||||
type: integer
|
||||
type: object
|
||||
controller.WakeupDTO:
|
||||
properties:
|
||||
mac:
|
||||
description: mac 地址
|
||||
example: FF-FF-FF-FF-FF-FF-FF
|
||||
type: string
|
||||
port:
|
||||
description: 端口
|
||||
example: 9
|
||||
type: integer
|
||||
type: object
|
||||
errorx.CodeErrorResponse:
|
||||
properties:
|
||||
code:
|
||||
example: 200
|
||||
type: integer
|
||||
data: {}
|
||||
msg:
|
||||
example: OK
|
||||
type: string
|
||||
type: object
|
||||
response.Response:
|
||||
properties:
|
||||
code:
|
||||
example: 200
|
||||
type: integer
|
||||
data: {}
|
||||
msg:
|
||||
example: OK
|
||||
type: string
|
||||
type: object
|
||||
info:
|
||||
contact:
|
||||
email: 919411476@qq.com
|
||||
name: Shikong
|
||||
description: Wails AssetServer API 文档
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
termsOfService: http://swagger.io/terms/
|
||||
title: Wails AssetServer API
|
||||
version: "1.0"
|
||||
paths:
|
||||
/config/:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 获取应用列表
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/response.Response'
|
||||
- properties:
|
||||
data:
|
||||
$ref: '#/definitions/config.Config'
|
||||
type: object
|
||||
default:
|
||||
description: ""
|
||||
schema:
|
||||
$ref: '#/definitions/errorx.CodeErrorResponse'
|
||||
summary: 获取应用列表
|
||||
tags:
|
||||
- Config
|
||||
/error:
|
||||
delete:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 错误信息示例
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
default:
|
||||
description: ""
|
||||
schema:
|
||||
$ref: '#/definitions/errorx.CodeErrorResponse'
|
||||
summary: 错误处理
|
||||
tags:
|
||||
- Error
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 错误信息示例
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
default:
|
||||
description: ""
|
||||
schema:
|
||||
$ref: '#/definitions/errorx.CodeErrorResponse'
|
||||
summary: 错误处理
|
||||
tags:
|
||||
- Error
|
||||
patch:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 错误信息示例
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
default:
|
||||
description: ""
|
||||
schema:
|
||||
$ref: '#/definitions/errorx.CodeErrorResponse'
|
||||
summary: 错误处理
|
||||
tags:
|
||||
- Error
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 错误信息示例
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
default:
|
||||
description: ""
|
||||
schema:
|
||||
$ref: '#/definitions/errorx.CodeErrorResponse'
|
||||
summary: 错误处理
|
||||
tags:
|
||||
- Error
|
||||
put:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 错误信息示例
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
default:
|
||||
description: ""
|
||||
schema:
|
||||
$ref: '#/definitions/errorx.CodeErrorResponse'
|
||||
summary: 错误处理
|
||||
tags:
|
||||
- Error
|
||||
/file/:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 获取文件
|
||||
parameters:
|
||||
- description: 区块大小
|
||||
in: query
|
||||
name: chunkSize
|
||||
type: integer
|
||||
- description: 偏移量
|
||||
in: query
|
||||
name: offset
|
||||
type: integer
|
||||
- description: 路径
|
||||
example: C:\Windows\System32\cmd.exe
|
||||
in: query
|
||||
name: path
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/octet-stream
|
||||
responses: {}
|
||||
summary: 获取文件
|
||||
tags:
|
||||
- File
|
||||
/file/path:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 获取文件路径
|
||||
parameters:
|
||||
- description: 路径
|
||||
example: C:\Windows\System32\cmd.exe
|
||||
in: query
|
||||
name: path
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/response.Response'
|
||||
- properties:
|
||||
data:
|
||||
type: string
|
||||
type: object
|
||||
default:
|
||||
description: ""
|
||||
schema:
|
||||
$ref: '#/definitions/errorx.CodeErrorResponse'
|
||||
summary: 获取文件路径
|
||||
tags:
|
||||
- File
|
||||
/wol/wakeup:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: wol 唤醒
|
||||
parameters:
|
||||
- description: 局域网唤醒
|
||||
in: body
|
||||
name: vo
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/controller.WakeupDTO'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/response.Response'
|
||||
- properties:
|
||||
data:
|
||||
type: string
|
||||
type: object
|
||||
default:
|
||||
description: ""
|
||||
schema:
|
||||
$ref: '#/definitions/errorx.CodeErrorResponse'
|
||||
summary: wol 唤醒
|
||||
tags:
|
||||
- Wol
|
||||
swagger: "2.0"
|
3
app/wails/pkg/server/generate.go
Normal file
3
app/wails/pkg/server/generate.go
Normal file
@ -0,0 +1,3 @@
|
||||
package server
|
||||
|
||||
//go:generate swag init -d ./ -g ./main.go -pd
|
10
app/wails/pkg/server/init.go
Normal file
10
app/wails/pkg/server/init.go
Normal file
@ -0,0 +1,10 @@
|
||||
package server
|
||||
|
||||
//go:generate go version
|
||||
//go:generate go env -w GO111MODULE=on
|
||||
//go:generate go env -w GOPROXY=https://goproxy.cn,direct
|
||||
//go:generate go install github.com/swaggo/swag/cmd/swag@latest
|
||||
//go:generate go get -u xorm.io/reverse
|
||||
//go:generate go install xorm.io/reverse
|
||||
//go:generate go mod tidy
|
||||
//go:generate swag init ./
|
70
app/wails/pkg/server/main.go
Normal file
70
app/wails/pkg/server/main.go
Normal file
@ -0,0 +1,70 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"go.uber.org/zap/zapcore"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
|
||||
_ "skapp/pkg/server/docs"
|
||||
|
||||
"skapp/global"
|
||||
"skapp/pkg/config/toml"
|
||||
"skapp/pkg/logger"
|
||||
"time"
|
||||
)
|
||||
|
||||
// @title Wails AssetServer API
|
||||
// @version 1.0
|
||||
// @description Wails AssetServer API 文档
|
||||
// @termsOfService http://swagger.io/terms/
|
||||
// @contact.name Shikong
|
||||
// @contact.email 919411476@qq.com
|
||||
// @license.name Apache 2.0
|
||||
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
// @BasePath /s
|
||||
|
||||
func Main() {
|
||||
conf, err := toml.LoadConfig()
|
||||
if err != nil {
|
||||
logger.Log.Fatalf("%s", err)
|
||||
}
|
||||
|
||||
global.Config = conf
|
||||
|
||||
if conf.HasDebug() && conf.Debug.Enable {
|
||||
logger.SetLevel(zapcore.DebugLevel)
|
||||
} else {
|
||||
logger.SetLevel(zapcore.ErrorLevel)
|
||||
}
|
||||
|
||||
engine := Server(conf)
|
||||
|
||||
srv := &http.Server{
|
||||
Addr: fmt.Sprintf("%s:%d", conf.Server.Host, conf.Server.Port),
|
||||
Handler: engine,
|
||||
}
|
||||
|
||||
go func() {
|
||||
logger.Log.Infof("服务启动 %s", fmt.Sprintf("%s:%d", conf.Server.Host, conf.Server.Port))
|
||||
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
logger.Log.Fatalf("listen: %s\n", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// 等待中断信号以优雅地关闭服务器(设置 5 秒的超时时间)
|
||||
quit := make(chan os.Signal, 1)
|
||||
signal.Notify(quit, os.Interrupt)
|
||||
<-quit
|
||||
logger.Log.Info("开始关闭服务")
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
if err := srv.Shutdown(ctx); err != nil {
|
||||
log.Fatal("服务关闭异常:", err)
|
||||
}
|
||||
logger.Log.Info("服务关闭完成")
|
||||
}
|
14
app/wails/pkg/server/middleware/cors.go
Normal file
14
app/wails/pkg/server/middleware/cors.go
Normal file
@ -0,0 +1,14 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func CorsMiddleWare() gin.HandlerFunc {
|
||||
return func(ctx *gin.Context) {
|
||||
ctx.Header("Access-Control-Allow-Origin", "*")
|
||||
ctx.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
|
||||
ctx.Header("Access-Control-Allow-Headers", "Action, Module, X-PINGOTHER, Content-Type, Content-Disposition")
|
||||
ctx.Next()
|
||||
}
|
||||
}
|
39
app/wails/pkg/server/middleware/error.go
Normal file
39
app/wails/pkg/server/middleware/error.go
Normal file
@ -0,0 +1,39 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"runtime/debug"
|
||||
"skapp/pkg/logger"
|
||||
"skapp/pkg/utils/errorx"
|
||||
)
|
||||
|
||||
// ErrorHandler
|
||||
// gin 全局异常处理
|
||||
func ErrorHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err := parseError(r)
|
||||
//打印错误堆栈信息
|
||||
logger.Log.Error(err)
|
||||
debug.PrintStack()
|
||||
//封装通用JSON返回
|
||||
c.JSON(http.StatusOK, errorx.NewDefaultError(err))
|
||||
//终止后续接口调用,不加的话recover到异常后,还会继续执行接口里后续代码
|
||||
c.Abort()
|
||||
}
|
||||
}()
|
||||
//加载完 defer recover,继续后续的插件及代码执行
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func parseError(r interface{}) string {
|
||||
switch v := r.(type) {
|
||||
case error:
|
||||
return v.Error()
|
||||
default:
|
||||
return r.(string)
|
||||
}
|
||||
}
|
26
app/wails/pkg/server/router/error.go
Normal file
26
app/wails/pkg/server/router/error.go
Normal file
@ -0,0 +1,26 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"skapp/pkg/utils/errorx"
|
||||
)
|
||||
|
||||
// ErrorHandler
|
||||
//
|
||||
// @Summary 错误处理
|
||||
// @Description 错误信息示例
|
||||
// @Tags Error
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Failure default {object} errorx.CodeErrorResponse
|
||||
// @Router /error [get]
|
||||
// @Router /error [post]
|
||||
// @Router /error [put]
|
||||
// @Router /error [delete]
|
||||
// @Router /error [patch]
|
||||
func setupErrorRouter(r *gin.RouterGroup) {
|
||||
r.Any("/error", func(ctx *gin.Context) {
|
||||
ctx.JSON(200, errorx.NewDefaultError("错误信息示例"))
|
||||
})
|
||||
}
|
36
app/wails/pkg/server/router/router.go
Normal file
36
app/wails/pkg/server/router/router.go
Normal file
@ -0,0 +1,36 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"skapp/pkg/server/controller"
|
||||
|
||||
"skapp/pkg/config"
|
||||
_ "skapp/pkg/server/docs"
|
||||
)
|
||||
|
||||
func SetupRouter(conf *config.Config, g *gin.RouterGroup) {
|
||||
setupConfigRouter(g)
|
||||
setupFileRouter(g)
|
||||
setupWolRouter(g)
|
||||
setupErrorRouter(g)
|
||||
|
||||
if conf.HasDebug() && conf.Debug.Enable {
|
||||
setupSwaggerRouter(g)
|
||||
}
|
||||
}
|
||||
|
||||
func setupConfigRouter(g *gin.RouterGroup) {
|
||||
conf := g.Group("/config")
|
||||
conf.POST("/", controller.PostConfig)
|
||||
}
|
||||
|
||||
func setupFileRouter(g *gin.RouterGroup) {
|
||||
file := g.Group("/file")
|
||||
file.GET("/", controller.GetFile)
|
||||
file.GET("/path", controller.GetPath)
|
||||
}
|
||||
|
||||
func setupWolRouter(g *gin.RouterGroup) {
|
||||
file := g.Group("/wol")
|
||||
file.POST("/wakeup", controller.PostWolWakeUP)
|
||||
}
|
11
app/wails/pkg/server/router/swagger.go
Normal file
11
app/wails/pkg/server/router/swagger.go
Normal file
@ -0,0 +1,11 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
swaggerFiles "github.com/swaggo/files"
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
)
|
||||
|
||||
func setupSwaggerRouter(r *gin.RouterGroup) {
|
||||
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||
}
|
28
app/wails/pkg/server/server.go
Normal file
28
app/wails/pkg/server/server.go
Normal file
@ -0,0 +1,28 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"github.com/gin-contrib/gzip"
|
||||
"github.com/gin-gonic/gin"
|
||||
"skapp/pkg/config"
|
||||
"skapp/pkg/server/middleware"
|
||||
"skapp/pkg/server/router"
|
||||
)
|
||||
|
||||
func Server(config *config.Config) (engine *gin.Engine) {
|
||||
if config.HasDebug() && config.Debug.Enable {
|
||||
gin.SetMode(gin.DebugMode)
|
||||
engine = gin.Default()
|
||||
} else {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
engine = gin.New()
|
||||
}
|
||||
|
||||
engine.Use(gzip.Gzip(gzip.DefaultCompression))
|
||||
engine.Use(middleware.CorsMiddleWare())
|
||||
engine.Use(middleware.ErrorHandler())
|
||||
|
||||
g := engine.RouterGroup.Group("/s")
|
||||
router.SetupRouter(config, g)
|
||||
|
||||
return engine
|
||||
}
|
87
app/wails/pkg/server/services/wol/wol.go
Normal file
87
app/wails/pkg/server/services/wol/wol.go
Normal file
@ -0,0 +1,87 @@
|
||||
package wol
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
MacFormatError = errors.New("mac 地址格式错误")
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
}
|
||||
|
||||
var Services *Service
|
||||
|
||||
func init() {
|
||||
Services = &Service{}
|
||||
}
|
||||
|
||||
func (s *Service) validateMac(mac string) bool {
|
||||
exp, _ := regexp.Compile("([0-9a-fA-F]{2}(-|:)?){5}([a-fA-F0-9]{2})")
|
||||
|
||||
macLen := len(mac)
|
||||
|
||||
return exp.MatchString(mac) && (macLen == 12 || macLen == 17)
|
||||
}
|
||||
|
||||
func (s *Service) WakeUp(mac string, port int) error {
|
||||
mac = strings.Replace(strings.Replace(mac, ":", "", -1), "-", "", -1)
|
||||
if !s.validateMac(mac) {
|
||||
return MacFormatError
|
||||
}
|
||||
|
||||
return s.wake(mac, port)
|
||||
}
|
||||
|
||||
func (s *Service) wake(mac string, port int) error {
|
||||
udpAddr, _ := net.ResolveUDPAddr("udp", fmt.Sprintf("255.255.255.255:%d", port))
|
||||
interfaces, err := net.Interfaces()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
macHex, _ := hex.DecodeString(mac)
|
||||
// 广播MAC地址 FF:FF:FF:FF:FF:FF
|
||||
var broadcast = []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
|
||||
var buffer bytes.Buffer
|
||||
buffer.Write(broadcast)
|
||||
for i := 0; i < 16; i++ {
|
||||
buffer.Write(macHex)
|
||||
}
|
||||
wolPackage := buffer.Bytes()
|
||||
|
||||
for _, i := range interfaces {
|
||||
if i.Flags&net.FlagUp == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
addrs, err := i.Addrs()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
if ip, ok := addr.(*net.IPNet); ok {
|
||||
if ipv4 := ip.IP.To4(); ipv4 != nil {
|
||||
conn, err := net.DialUDP("udp", &net.UDPAddr{IP: ipv4}, udpAddr)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, _ = conn.Write(wolPackage)
|
||||
_ = conn.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
92
app/wails/pkg/server/services/wol/wol_test.go
Normal file
92
app/wails/pkg/server/services/wol/wol_test.go
Normal file
@ -0,0 +1,92 @@
|
||||
package wol
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"net"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRegExp(t *testing.T) {
|
||||
validateMac := func() func(mac string) bool {
|
||||
exp, _ := regexp.Compile("([0-9a-fA-F]{2}(-|:)?){5}([a-fA-F0-9]{2})")
|
||||
return func(mac string) bool {
|
||||
macLen := len(mac)
|
||||
return exp.MatchString(mac) && (macLen == 12 || macLen == 17)
|
||||
}
|
||||
}()
|
||||
|
||||
t.Logf("255.255.255.255 %t", validateMac("255.255.255.255"))
|
||||
t.Logf("FF:FF:FF:FF:FF:FF %t", validateMac("FF:FF:FF:FF:FF:FF"))
|
||||
t.Logf("00-E0-4C-84-50-EB %t", validateMac("00-E0-4C-84-50-EB"))
|
||||
t.Logf("00E04C8450EB %t", validateMac("00E04C8450EB"))
|
||||
t.Logf("00E04C8450EBA %t", validateMac("00E04C8450EBA"))
|
||||
}
|
||||
|
||||
func TestWol(t *testing.T) {
|
||||
udpAddr, err := net.ResolveUDPAddr("udp", "255.255.255.255:9")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Logf("%v", udpAddr)
|
||||
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
mac := "00-E0-4C-84-50-EB"
|
||||
mac = strings.Replace(strings.Replace(mac, ":", "", -1), "-", "", -1)
|
||||
macHex, _ := hex.DecodeString(mac)
|
||||
// 广播MAC地址 FF:FF:FF:FF:FF:FF
|
||||
var broadcast = []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
|
||||
var buffer bytes.Buffer
|
||||
buffer.Write(broadcast)
|
||||
for i := 0; i < 16; i++ {
|
||||
buffer.Write(macHex)
|
||||
}
|
||||
wolPackage := buffer.Bytes()
|
||||
|
||||
for _, i := range interfaces {
|
||||
if i.Flags&net.FlagUp == 0 {
|
||||
t.Logf("%s 未启用", i.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
t.Logf("%s 已启用", i.Name)
|
||||
addrs, err := i.Addrs()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
if ip, ok := addr.(*net.IPNet); ok {
|
||||
if ipv4 := ip.IP.To4(); ipv4 != nil {
|
||||
t.Logf("\t ipv4: %s", ipv4.String())
|
||||
|
||||
conn, err := net.DialUDP("udp", &net.UDPAddr{IP: ipv4}, udpAddr)
|
||||
defer func() {
|
||||
_ = conn.Close()
|
||||
}()
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("wol 幻数据包发送失败 %s", err)
|
||||
}
|
||||
_, _ = conn.Write(wolPackage)
|
||||
t.Logf("wol 幻数据包发送成功, %s %s %s", i.Name, ipv4.String(), mac)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWOLService(t *testing.T) {
|
||||
var service *Service
|
||||
err := service.WakeUp("00-E0-4C-84-50-EB", 9)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log("wol 唤醒成功")
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
package sqlite
|
||||
|
||||
import (
|
||||
"changeme/lib/utils"
|
||||
"fmt"
|
||||
"log"
|
||||
"path/filepath"
|
||||
"skapp/pkg/utils"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
@ -1,9 +1,9 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"changeme/backend/utils"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"skapp/backend/utils"
|
||||
"testing"
|
||||
)
|
||||
|
59
app/wails/pkg/utils/errorx/errorx.go
Normal file
59
app/wails/pkg/utils/errorx/errorx.go
Normal file
@ -0,0 +1,59 @@
|
||||
package errorx
|
||||
|
||||
import (
|
||||
"skapp/pkg/utils/response"
|
||||
)
|
||||
|
||||
type CodeError struct {
|
||||
*response.Response
|
||||
}
|
||||
|
||||
type CodeErrorResponse struct {
|
||||
*response.Response
|
||||
}
|
||||
|
||||
func NewCustomError(code int, data interface{}, msg string) error {
|
||||
return &CodeError{
|
||||
Response: response.NewCustomResponse(code, data, msg),
|
||||
}
|
||||
}
|
||||
|
||||
func NewErrorWithCode(code int, msg string) error {
|
||||
return &CodeError{
|
||||
Response: response.NewCustomResponse(code, nil, msg),
|
||||
}
|
||||
}
|
||||
|
||||
func ParseError(err error) error {
|
||||
if err != nil {
|
||||
return NewErrorWithCode(response.ERROR, err.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ParseErrorWithCode(code int, err error) error {
|
||||
if err != nil {
|
||||
return NewErrorWithCode(code, err.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewDefaultError(msg string) error {
|
||||
return NewErrorWithCode(response.ERROR, msg)
|
||||
}
|
||||
|
||||
func (e *CodeError) Error() string {
|
||||
return e.Msg
|
||||
}
|
||||
|
||||
func (e *CodeError) Resp() *CodeErrorResponse {
|
||||
return &CodeErrorResponse{
|
||||
Response: &response.Response{
|
||||
Code: e.Code,
|
||||
Data: e.Data,
|
||||
Msg: e.Msg,
|
||||
},
|
||||
}
|
||||
}
|
20
app/wails/pkg/utils/idutils/sonyflake.go
Normal file
20
app/wails/pkg/utils/idutils/sonyflake.go
Normal file
@ -0,0 +1,20 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"github.com/sony/sonyflake"
|
||||
"time"
|
||||
)
|
||||
|
||||
const DefaultSonyFlakeStartTime = "2022-01-01"
|
||||
|
||||
var SonyFlake *sonyflake.Sonyflake
|
||||
|
||||
func init() {
|
||||
SonyFlake = initSonyFlake()
|
||||
}
|
||||
|
||||
func initSonyFlake() *sonyflake.Sonyflake {
|
||||
var s sonyflake.Settings
|
||||
s.StartTime, _ = time.Parse("2006-01-02", DefaultSonyFlakeStartTime)
|
||||
return sonyflake.NewSonyflake(s)
|
||||
}
|
27
app/wails/pkg/utils/resources/relativefs.go
Normal file
27
app/wails/pkg/utils/resources/relativefs.go
Normal file
@ -0,0 +1,27 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"io/fs"
|
||||
"path"
|
||||
)
|
||||
|
||||
type RelativeFS struct {
|
||||
Fs embed.FS
|
||||
Root string
|
||||
}
|
||||
|
||||
func (r *RelativeFS) Open(name string) (fs.File, error) {
|
||||
p := path.Join(r.Root, name)
|
||||
return r.Fs.Open(p)
|
||||
}
|
||||
|
||||
func (r *RelativeFS) ReadDir(name string) ([]fs.DirEntry, error) {
|
||||
p := path.Join(r.Root, name)
|
||||
return r.Fs.ReadDir(p)
|
||||
}
|
||||
|
||||
func (r *RelativeFS) ReadFile(name string) ([]byte, error) {
|
||||
p := path.Join(r.Root, name)
|
||||
return r.Fs.ReadFile(p)
|
||||
}
|
40
app/wails/pkg/utils/response/response.go
Normal file
40
app/wails/pkg/utils/response/response.go
Normal file
@ -0,0 +1,40 @@
|
||||
package response
|
||||
|
||||
type Response struct {
|
||||
Code Code `json:"code" example:"200"`
|
||||
Data interface{} `json:"data"`
|
||||
Msg string `json:"msg" example:"OK"`
|
||||
}
|
||||
|
||||
type Code = int
|
||||
|
||||
const (
|
||||
SUCCESS = 200
|
||||
UNAUTHORIZED = 401
|
||||
FORBIDDEN = 403
|
||||
ERROR = 500
|
||||
)
|
||||
|
||||
func NewCustomResponse(code int, data interface{}, msg string) *Response {
|
||||
return &Response{
|
||||
Code: code,
|
||||
Data: data,
|
||||
Msg: msg,
|
||||
}
|
||||
}
|
||||
|
||||
func NewResponseWithCode(code int, data interface{}) *Response {
|
||||
return &Response{
|
||||
Code: SUCCESS,
|
||||
Data: data,
|
||||
Msg: "OK",
|
||||
}
|
||||
}
|
||||
|
||||
func NewResponse(data interface{}) *Response {
|
||||
return &Response{
|
||||
Code: SUCCESS,
|
||||
Data: data,
|
||||
Msg: "OK",
|
||||
}
|
||||
}
|
31
app/wails/pkg/utils/time/time.go
Normal file
31
app/wails/pkg/utils/time/time.go
Normal file
@ -0,0 +1,31 @@
|
||||
package time
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Time time.Time
|
||||
|
||||
const (
|
||||
timeFormat = "2006-01-02 15:04:05"
|
||||
)
|
||||
|
||||
// MarshalJSON on Json Time format Time field with %Y-%m-%d %H:%M:%S
|
||||
func (t *Time) MarshalJSON() ([]byte, error) {
|
||||
// 重写time转换成json之后的格式
|
||||
var tmp = fmt.Sprintf("\"%s\"", time.Time(*t).Format(timeFormat))
|
||||
return []byte(tmp), nil
|
||||
}
|
||||
|
||||
func (t *Time) UnmarshalJSON(data []byte) error {
|
||||
// Ignore null, like in the main JSON package.
|
||||
if string(data) == "null" {
|
||||
return nil
|
||||
}
|
||||
// Fractional seconds are handled implicitly by Parse.
|
||||
var err error
|
||||
rawT, err := time.Parse(`"`+timeFormat+`"`, string(data))
|
||||
*t = Time(rawT)
|
||||
return err
|
||||
}
|
44
app/wails/pkg/utils/validator/validator.go
Normal file
44
app/wails/pkg/utils/validator/validator.go
Normal file
@ -0,0 +1,44 @@
|
||||
package validator
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/go-playground/locales/zh"
|
||||
ut "github.com/go-playground/universal-translator"
|
||||
"github.com/go-playground/validator/v10"
|
||||
zhTranslations "github.com/go-playground/validator/v10/translations/zh"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
var zhLocales = zh.New()
|
||||
var validate = validator.New()
|
||||
var uni = ut.New(zhLocales)
|
||||
var trans, _ = uni.GetTranslator("zh")
|
||||
|
||||
// 验证器注册翻译器
|
||||
var _ = zhTranslations.RegisterDefaultTranslations(validate, trans)
|
||||
|
||||
func init() {
|
||||
//注册一个函数,获取struct tag里自定义的label作为字段名
|
||||
validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
|
||||
if label := fld.Tag.Get("label"); len(label) > 0 {
|
||||
return label
|
||||
}
|
||||
|
||||
if jsonField := fld.Tag.Get("json"); len(jsonField) > 0 {
|
||||
return jsonField
|
||||
}
|
||||
|
||||
return fld.Name
|
||||
})
|
||||
}
|
||||
|
||||
func ValidateStruct(data interface{}) (err error) {
|
||||
err = validate.Struct(data)
|
||||
if err != nil {
|
||||
for _, e := range err.(validator.ValidationErrors) {
|
||||
err = errors.New(e.Translate(trans))
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
Loading…
Reference in New Issue
Block a user