Compare commits

..

10 Commits
v0.0.2 ... main

Author SHA1 Message Date
2cbe41587e 升级异常机制 2025-12-12 21:51:15 +08:00
480250c04c update for gojs 2025-12-01 00:34:23 +08:00
20d283a270 update gojs 2025-11-30 23:03:03 +08:00
Star
3a991746ad update for ssgo/dao 2025-07-15 17:18:36 +08:00
195cbc6b59 update packages 2025-06-25 22:56:06 +08:00
Star
12fcb95b9d add querya 2025-01-14 14:28:26 +08:00
7eee72b053 fix nil bug for query11
add query1s query1a
2024-12-15 19:22:13 +08:00
183beb1286 add table _deleted for make db 2024-12-13 19:34:51 +08:00
Star
cc8c502ec0 support makeER 2024-11-22 16:36:11 +08:00
9cd64d91d0 add SetSSKey
add makeInKeys
2024-10-27 00:36:18 +08:00
5 changed files with 268 additions and 86 deletions

182
db.go
View File

@ -2,9 +2,12 @@ package db
import ( import (
_ "embed" _ "embed"
"strings"
"apigo.cc/gojs" "apigo.cc/gojs"
"apigo.cc/gojs/goja" "apigo.cc/gojs/goja"
_ "github.com/go-sql-driver/mysql"
_ "github.com/jackc/pgx/v5/stdlib"
"github.com/ssgo/dao/dao" "github.com/ssgo/dao/dao"
"github.com/ssgo/db" "github.com/ssgo/db"
"github.com/ssgo/log" "github.com/ssgo/log"
@ -16,19 +19,32 @@ var dbTS string
//go:embed README.md //go:embed README.md
var dbMD string var dbMD string
var defaultDB = "default"
// var defaultDB = "default"
// var defaultDBLock = sync.RWMutex{}
func init() { func init() {
obj := map[string]any{ obj := map[string]any{
"get": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value { "get": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(1) args := gojs.MakeArgs(&argsIn, vm).Check(1)
conn := db.GetDB(args.Str(0), args.Logger)
// 检查sqlite文件访问是否超出沙盒 userPath
dsn := fixDsn(vm, args.Str(0))
conn := db.GetDB(dsn, args.Logger)
return vm.ToValue(makeDBObject(conn, nil)) return vm.ToValue(makeDBObject(conn, nil))
}, },
"setDefault": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value { "setDefault": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(1) args := gojs.MakeArgs(&argsIn, vm).Check(1)
defaultDB = args.Str(0)
conn := db.GetDB(defaultDB, args.Logger) // 检查sqlite文件访问是否超出沙盒 userPath
dsn := fixDsn(vm, args.Str(0))
// defaultDBLock.Lock()
// defaultDB = dsn
// defaultDBLock.Unlock()
conn := db.GetDB(dsn, args.Logger)
args.This.ToObject(vm).Set("conn", conn) args.This.ToObject(vm).Set("conn", conn)
return nil return nil
}, },
@ -36,7 +52,7 @@ func init() {
gojs.Register("apigo.cc/gojs/db", gojs.Module{ gojs.Register("apigo.cc/gojs/db", gojs.Module{
ObjectMaker: func(vm *goja.Runtime) gojs.Map { ObjectMaker: func(vm *goja.Runtime) gojs.Map {
conn := db.GetDB(defaultDB, gojs.GetLogger(vm)) conn := db.GetDB("default", gojs.GetLogger(vm))
dbObj := makeDBObject(conn, nil) dbObj := makeDBObject(conn, nil)
for k, v := range obj { for k, v := range obj {
dbObj[k] = v dbObj[k] = v
@ -46,9 +62,26 @@ func init() {
Desc: "db api by github.com/ssgo/db", Desc: "db api by github.com/ssgo/db",
TsCode: dbTS, TsCode: dbTS,
Example: dbMD, Example: dbMD,
SetSSKey: func(key, iv []byte) {
db.SetEncryptKeys(key, iv)
},
}) })
} }
func fixDsn(vm *goja.Runtime, dsn string) string {
// 检查sqlite文件访问是否超出沙盒 userPath
rootPath := u.String(vm.GetData("userPath"))
if rootPath != "" && strings.HasPrefix(dsn, "sqlite") && strings.Contains(dsn, "://") {
filename := strings.SplitN(dsn, "://", 2)[1]
filename = strings.SplitN(dsn, "?", 2)[0]
fixedFilename := gojs.FixPath(vm, filename)
if fixedFilename != filename {
dsn = strings.Replace(dsn, filename, fixedFilename, 1)
}
}
return dsn
}
func makeDBObject(conn *db.DB, tx *db.Tx) map[string]any { func makeDBObject(conn *db.DB, tx *db.Tx) map[string]any {
obj := map[string]any{ obj := map[string]any{
"conn": conn, "conn": conn,
@ -64,7 +97,27 @@ func makeDBObject(conn *db.DB, tx *db.Tx) map[string]any {
if r.Error == nil { if r.Error == nil {
return vm.ToValue(makeQueryResult(r, r.MapResults())) return vm.ToValue(makeQueryResult(r, r.MapResults()))
} else { } else {
panic(vm.NewGoError(r.Error)) // panic(vm.NewGoError(r.Error))
vm.SetData("_lastError", r.Error)
gojs.GetLogger(vm).Error(r.Error.Error())
return nil
}
},
"querya": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args, conn, tx, _ := initDBArgs(argsIn, vm, 1)
var r *db.QueryResult
if tx != nil {
r = tx.Query(args.Str(0), args.Array(1)...)
} else {
r = conn.Query(args.Str(0), args.Array(1)...)
}
if r.Error == nil {
return vm.ToValue(makeQueryResult(r, r.SliceResults()))
} else {
// panic(vm.NewGoError(r.Error))
vm.SetData("_lastError", r.Error)
gojs.GetLogger(vm).Error(r.Error.Error())
return nil
} }
}, },
"query1": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value { "query1": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
@ -78,7 +131,35 @@ func makeDBObject(conn *db.DB, tx *db.Tx) map[string]any {
if r.Error == nil { if r.Error == nil {
return vm.ToValue(makeQueryResult(r, r.MapOnR1())) return vm.ToValue(makeQueryResult(r, r.MapOnR1()))
} else { } else {
panic(vm.NewGoError(r.Error)) // panic(vm.NewGoError(r.Error))
vm.SetData("_lastError", r.Error)
gojs.GetLogger(vm).Error(r.Error.Error())
return nil
}
},
"query1a": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args, conn, tx, _ := initDBArgs(argsIn, vm, 1)
var r *db.QueryResult
if tx != nil {
r = tx.Query(args.Str(0), args.Array(1)...)
} else {
r = conn.Query(args.Str(0), args.Array(1)...)
}
if r.Error == nil {
a := r.SliceResults()
if len(a) > 0 && len(a[0]) > 0 {
list := make([]any, len(a))
for i := 0; i < len(a); i++ {
list[i] = a[i][0]
}
return vm.ToValue(makeQueryResult(r, list))
}
return vm.ToValue(makeQueryResult(r, nil))
} else {
// panic(vm.NewGoError(r.Error))
vm.SetData("_lastError", r.Error)
gojs.GetLogger(vm).Error(r.Error.Error())
return nil
} }
}, },
"query11": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value { "query11": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
@ -94,9 +175,12 @@ func makeDBObject(conn *db.DB, tx *db.Tx) map[string]any {
if len(a) > 0 && len(a[0]) > 0 { if len(a) > 0 && len(a[0]) > 0 {
return vm.ToValue(makeQueryResult(r, a[0][0])) return vm.ToValue(makeQueryResult(r, a[0][0]))
} }
return vm.ToValue(nil) return vm.ToValue(makeQueryResult(r, nil))
} else { } else {
panic(vm.NewGoError(r.Error)) // panic(vm.NewGoError(r.Error))
vm.SetData("_lastError", r.Error)
gojs.GetLogger(vm).Error(r.Error.Error())
return nil
} }
}, },
"exec": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value { "exec": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
@ -110,7 +194,10 @@ func makeDBObject(conn *db.DB, tx *db.Tx) map[string]any {
if r.Error == nil { if r.Error == nil {
return vm.ToValue(makeExecResult(r)) return vm.ToValue(makeExecResult(r))
} else { } else {
panic(vm.NewGoError(r.Error)) // panic(vm.NewGoError(r.Error))
vm.SetData("_lastError", r.Error)
gojs.GetLogger(vm).Error(r.Error.Error())
return vm.ToValue(false)
} }
}, },
"insert": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value { "insert": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
@ -124,7 +211,10 @@ func makeDBObject(conn *db.DB, tx *db.Tx) map[string]any {
if r.Error == nil { if r.Error == nil {
return vm.ToValue(makeExecResult(r)) return vm.ToValue(makeExecResult(r))
} else { } else {
panic(vm.NewGoError(r.Error)) // panic(vm.NewGoError(r.Error))
vm.SetData("_lastError", r.Error)
gojs.GetLogger(vm).Error(r.Error.Error())
return vm.ToValue(false)
} }
}, },
"replace": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value { "replace": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
@ -138,7 +228,10 @@ func makeDBObject(conn *db.DB, tx *db.Tx) map[string]any {
if r.Error == nil { if r.Error == nil {
return vm.ToValue(makeExecResult(r)) return vm.ToValue(makeExecResult(r))
} else { } else {
panic(vm.NewGoError(r.Error)) // panic(vm.NewGoError(r.Error))
vm.SetData("_lastError", r.Error)
gojs.GetLogger(vm).Error(r.Error.Error())
return vm.ToValue(false)
} }
}, },
"update": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value { "update": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
@ -152,7 +245,10 @@ func makeDBObject(conn *db.DB, tx *db.Tx) map[string]any {
if r.Error == nil { if r.Error == nil {
return vm.ToValue(makeExecResult(r)) return vm.ToValue(makeExecResult(r))
} else { } else {
panic(vm.NewGoError(r.Error)) // panic(vm.NewGoError(r.Error))
vm.SetData("_lastError", r.Error)
gojs.GetLogger(vm).Error(r.Error.Error())
return vm.ToValue(false)
} }
}, },
"delete": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value { "delete": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
@ -166,32 +262,69 @@ func makeDBObject(conn *db.DB, tx *db.Tx) map[string]any {
if r.Error == nil { if r.Error == nil {
return vm.ToValue(makeExecResult(r)) return vm.ToValue(makeExecResult(r))
} else { } else {
panic(vm.NewGoError(r.Error)) // panic(vm.NewGoError(r.Error))
vm.SetData("_lastError", r.Error)
gojs.GetLogger(vm).Error(r.Error.Error())
return vm.ToValue(false)
} }
}, },
"makeInKeys": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args := gojs.MakeArgs(&argsIn, vm).Check(1)
return vm.ToValue(db.InKeys(args.Int(0)))
},
} }
if tx == nil { if tx == nil {
obj["make"] = func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value { obj["make"] = func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args, conn, _, logger := initDBArgs(argsIn, vm, 1) args, conn, _, logger := initDBArgs(argsIn, vm, 1)
arg0 := args.Str(0) erDesc := args.Str(0)
tryFile := gojs.FindPath(vm, arg0) tryFile := gojs.FixPath(vm, erDesc)
if u.FileExists(tryFile) { if u.FileExists(tryFile) {
arg0 = u.ReadFileN(tryFile) erDesc = u.ReadFileN(tryFile)
} }
if err := dao.MakeDBFromDesc(conn, args.Str(0), logger); err == nil { if err := dao.MakeDBFromDesc(conn, erDesc+`
_deleted
table v30 PK
id v30 PK
time dt ct
owner v30 I
data t
`, logger); err == nil {
return nil return nil
} else { } else {
panic(vm.NewGoError(err)) // panic(vm.NewGoError(err))
vm.SetData("_lastError", err)
gojs.GetLogger(vm).Error(err.Error())
return vm.ToValue(false)
} }
} }
obj["makeER"] = func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args, _, _, logger := initDBArgs(argsIn, vm, 1)
outputFile := args.Str(0)
erDesc := args.Str(1)
dbType := args.Str(2)
if dbType == "" {
dbType = "mysql"
}
tryFile := gojs.FixPath(vm, erDesc)
if u.FileExists(tryFile) {
erDesc = u.ReadFileN(tryFile)
}
dao.MakeERFile(dbType, erDesc, "", outputFile, logger)
return vm.ToValue(true)
}
obj["destroy"] = func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value { obj["destroy"] = func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
_, conn, _, _ := initDBArgs(argsIn, vm, 0) _, conn, _, _ := initDBArgs(argsIn, vm, 0)
if err := conn.Destroy(); err == nil { if err := conn.Destroy(); err == nil {
return nil return vm.ToValue(true)
} else { } else {
panic(vm.NewGoError(err)) // panic(vm.NewGoError(err))
vm.SetData("_lastError", err)
gojs.GetLogger(vm).Error(err.Error())
return vm.ToValue(false)
} }
} }
@ -205,9 +338,12 @@ func makeDBObject(conn *db.DB, tx *db.Tx) map[string]any {
obj["end"] = func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value { obj["end"] = func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
args, _, tx, _ := initDBArgs(argsIn, vm, 1) args, _, tx, _ := initDBArgs(argsIn, vm, 1)
if err := tx.Finish(args.Bool(0)); err != nil { if err := tx.Finish(args.Bool(0)); err != nil {
panic(vm.NewGoError(err)) // panic(vm.NewGoError(err))
vm.SetData("_lastError", err)
gojs.GetLogger(vm).Error(err.Error())
return vm.ToValue(false)
} }
return nil return vm.ToValue(true)
} }
} }
return obj return obj

95
db.ts
View File

@ -4,8 +4,10 @@ export default {
get, get,
setDefault, setDefault,
make, make,
makeER,
query, query,
query1, query1,
query1a,
query11, query11,
exec, exec,
insert, insert,
@ -14,69 +16,90 @@ export default {
delete: delete_, delete: delete_,
destroy, destroy,
begin, begin,
makeInKeys,
} }
function get(dbName: string): DB {return null as any} function get(dbName: string): DB { return null as any }
function setDefault(dbName: string): void {} function setDefault(dbName: string): void { }
function make(descFileOrContent: string): Array<Object>{return null as any} function make(descFileOrContent: string): Object[] { return null as any }
function query(sql: string, ...args:any): QueryResult{return null as any} function makeER(outputFile: string, descFileOrContent: string, dbType: string = 'mysql'): void { }
function query1(sql: string, ...args:any): QueryResult1{return null as any} function query(sql: string, ...args: any): QueryResult { return null as any }
function query11(sql: string, ...args:any): QueryResult11{return null as any} function querya(sql: string, ...args: any): QueryResultA { return null as any }
function exec(sql: string, ...args:any): ExecResult{return null as any} function query1(sql: string, ...args: any): QueryResult1 { return null as any }
function insert(table: string, data:Object): ExecResult{return null as any} function query1a(sql: string, ...args: any): QueryResult1A { return null as any }
function replace(table: string, data:Object): ExecResult{return null as any} function query11(sql: string, ...args: any): QueryResult11 { return null as any }
function update(table: string, data:Object, where: string, ...args:any): ExecResult{return null as any} function exec(sql: string, ...args: any): ExecResult { return null as any }
function delete_(table: string, where: string, ...args:any): ExecResult{return null as any} function insert(table: string, data: Object): ExecResult { return null as any }
function destroy(): void{} function replace(table: string, data: Object): ExecResult { return null as any }
function begin(): Tx{return null as any} function update(table: string, data: Object, where: string, ...args: any): ExecResult { return null as any }
function delete_(table: string, where: string, ...args: any): ExecResult { return null as any }
function destroy(): void { }
function begin(): Tx { return null as any }
function makeInKeys(numKeys: number): string { return '' }
interface DB { interface DB {
make(descFileOrContent: string): Array<Object> make(descFileOrContent: string): Object[]
query(sql: string, ...args:any): QueryResult query(sql: string, ...args: any): QueryResult
query1(sql: string, ...args:any): QueryResult1 query1(sql: string, ...args: any): QueryResult1
query11(sql: string, ...args:any): QueryResult11 query1a(sql: string, ...args: any): QueryResult1A
exec(sql: string, ...args:any): ExecResult query11(sql: string, ...args: any): QueryResult11
insert(table: string, data:Object): ExecResult exec(sql: string, ...args: any): ExecResult
replace(table: string, data:Object): ExecResult insert(table: string, data: Object): ExecResult
update(table: string, data:Object, where: string, ...args:any): ExecResult replace(table: string, data: Object): ExecResult
delete(table: string, where: string, ...args:any): ExecResult update(table: string, data: Object, where: string, ...args: any): ExecResult
delete(table: string, where: string, ...args: any): ExecResult
destroy(): void destroy(): void
begin(): Tx begin(): Tx
makeInKeys(numKeys: number): string
} }
interface Tx { interface Tx {
query(sql: string, ...args:any): QueryResult query(sql: string, ...args: any): QueryResult
query1(sql: string, ...args:any): QueryResult1 query1(sql: string, ...args: any): QueryResult1
query11(sql: string, ...args:any): QueryResult11 query1a(sql: string, ...args: any): QueryResult1A
exec(sql: string, ...args:any): ExecResult query11(sql: string, ...args: any): QueryResult11
insert(table: string, data:Object): ExecResult exec(sql: string, ...args: any): ExecResult
replace(table: string, data:Object): ExecResult insert(table: string, data: Object): ExecResult
update(table: string, data:Object, where: string, ...args:any): ExecResult replace(table: string, data: Object): ExecResult
delete(table: string, where: string, ...args:any): ExecResult update(table: string, data: Object, where: string, ...args: any): ExecResult
end(ok:boolean): void delete(table: string, where: string, ...args: any): ExecResult
end(ok: boolean): void
makeInKeys(numKeys: number): string
} }
interface QueryResult { interface QueryResult {
sql: string sql: string
args: Array<any> args: any[]
result: Array<Object> result: Object[]
}
interface QueryResultA {
sql: string
args: any[]
result: any[][]
} }
interface QueryResult1 { interface QueryResult1 {
sql: string sql: string
args: Array<any> args: any[]
result: Object result: Object
} }
interface QueryResult1A {
sql: string
args: any[]
result: any[]
}
interface QueryResult11 { interface QueryResult11 {
sql: string sql: string
args: Array<any> args: any[]
result: any result: any
} }
interface ExecResult { interface ExecResult {
sql: string sql: string
args: Array<any> args: any[]
id: number id: number
changes: number changes: number
} }

View File

@ -6,13 +6,14 @@ import (
"testing" "testing"
"apigo.cc/gojs" "apigo.cc/gojs"
_ "apigo.cc/gojs/console"
_ "apigo.cc/gojs/db" _ "apigo.cc/gojs/db"
"github.com/ssgo/u" "github.com/ssgo/u"
_ "modernc.org/sqlite" _ "modernc.org/sqlite"
) )
func Test(t *testing.T) { func Test(t *testing.T) {
// gojs.ExportForDev() gojs.ExportForDev()
defer os.Remove("test.db") defer os.Remove("test.db")
r, err := gojs.RunFile("db_test.js", "Tom") r, err := gojs.RunFile("db_test.js", "Tom")
if err != nil { if err != nil {

View File

@ -1,13 +1,30 @@
import db from 'apigo.cc/gojs/db' import db from 'apigo.cc/gojs/db'
import co from 'apigo.cc/gojs/console'
function main(testUserName){ function main(testUserName) {
db.setDefault('sqlite://test.db') db.setDefault('sqlite://test.db')
db.make(` db.make(`
User User // {api} {select:isValid=1}
id i AI id i AI
name t name v100 // [i]
password v100 // [p] {-}
age i // [n]
sex v10 // [s:Female,Male]
memo t // [t]
isValid b // [c]
version ubi //
`) `)
db.insert('User', {name: testUserName}) db.insert('User', { name: testUserName })
let user = db.query1('SELECT * FROM User').result let user = db.query1('SELECT * FROM User').result
let r = db.query1('SELECT * FROM User WHERE name = ?', testUserName)
co.info(r)
// db.delete('User', "name=?", testUserName)
db.insert('_deleted', { table: 'User', id: r.result.id })
r = db.query('SELECT * FROM _deleted')
co.info(r)
return user return user
} }

49
go.mod
View File

@ -1,40 +1,45 @@
module apigo.cc/gojs/db module apigo.cc/gojs/db
go 1.18 go 1.24.0
require ( require (
apigo.cc/gojs v0.0.4 apigo.cc/gojs v0.0.32
github.com/ssgo/dao v0.1.5 apigo.cc/gojs/console v0.0.4
github.com/ssgo/db v1.7.11 github.com/go-sql-driver/mysql v1.9.3
github.com/ssgo/log v1.7.7 github.com/jackc/pgx/v5 v5.7.6
github.com/ssgo/u v1.7.9 github.com/ssgo/dao v0.1.13
modernc.org/sqlite v1.33.1 github.com/ssgo/db v1.7.13
github.com/ssgo/log v1.7.10
github.com/ssgo/u v1.7.23
modernc.org/sqlite v1.40.1
) )
require ( require (
filippo.io/edwards25519 v1.1.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect
github.com/dlclark/regexp2 v1.11.4 // indirect github.com/dlclark/regexp2 v1.11.5 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/go-sourcemap/sourcemap v2.1.4+incompatible // indirect github.com/go-sourcemap/sourcemap v2.1.4+incompatible // indirect
github.com/go-sql-driver/mysql v1.8.1 // indirect github.com/google/pprof v0.0.0-20250903194437-c28834ac2320 // indirect
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd // indirect
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/ssgo/config v1.7.8 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/ssgo/config v1.7.10 // indirect
github.com/ssgo/standard v1.7.7 // indirect github.com/ssgo/standard v1.7.7 // indirect
github.com/ssgo/tool v0.4.27 // indirect github.com/ssgo/tool v0.4.29 // indirect
golang.org/x/sys v0.26.0 // indirect golang.org/x/crypto v0.37.0 // indirect
golang.org/x/text v0.19.0 // indirect golang.org/x/exp v0.0.0-20250711185948-6ae5c78190dc // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.39.0 // indirect
golang.org/x/text v0.32.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect modernc.org/libc v1.66.10 // indirect
modernc.org/libc v1.55.3 // indirect modernc.org/mathutil v1.7.1 // indirect
modernc.org/mathutil v1.6.0 // indirect modernc.org/memory v1.11.0 // indirect
modernc.org/memory v1.8.0 // indirect
modernc.org/strutil v1.2.0 // indirect
modernc.org/token v1.1.0 // indirect
) )