feat(mail): 具名化 JS 导出并动态包裹错误(by AI)
This commit is contained in:
parent
3173092d4f
commit
3d5f3ba909
@ -1,5 +1,9 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v1.5.3 (2026-06-21)
|
||||
- **JS 对齐**: 重构 JS 导出为具名函数,并引入 `jsmod.MakeError` 动态包装错误以获取调用栈。
|
||||
- **依赖更新**: 升级依赖 `jsmod` 至 `v1.5.3`,`cast` 至 `v1.5.3`,`rand` 至 `v1.5.3`,`encoding` 至 `v1.5.4`,`shell` 至 `v1.5.3`,`safe` 至 `v1.5.2`,`id` 至 `v1.5.4`,`file` 至 `v1.5.5`,`config` 至 `v1.5.3`,`log` 至 `v1.5.8`。
|
||||
|
||||
## v1.0.4 (2026-05-31)
|
||||
- **新增**: 注册到 `jsmod`。支持低代码环境下的邮件发送与接收。
|
||||
- 提供 `send`, `recv` 默认快捷操作。
|
||||
|
||||
3
TEST.md
3
TEST.md
@ -18,5 +18,6 @@
|
||||
| 内存占用 | 低 | 采用流式处理及即时擦除 |
|
||||
|
||||
## 验证结果
|
||||
- **单元测试**: `go test -v ./...` 通过。
|
||||
- **单元测试**: `go test -v ./...` 通过 (2026-06-21)。
|
||||
- **并发安全性**: 经过 `sync.RWMutex` 保护,支持多协程下注册 Handler 及发送。
|
||||
- **JS 错误调用栈**: JS 桥接层改用具名导出并使用 `jsmod.MakeError` 包裹错误,确保 JS 抛出异常时携带准确的 Go 运行时堆栈。
|
||||
|
||||
20
go.mod
20
go.mod
@ -3,11 +3,11 @@ module apigo.cc/go/mail
|
||||
go 1.26.1
|
||||
|
||||
require (
|
||||
apigo.cc/go/cast v1.5.2
|
||||
apigo.cc/go/file v1.5.4
|
||||
apigo.cc/go/jsmod v1.5.2
|
||||
apigo.cc/go/log v1.5.6
|
||||
apigo.cc/go/safe v1.5.1
|
||||
apigo.cc/go/cast v1.5.3
|
||||
apigo.cc/go/file v1.5.5
|
||||
apigo.cc/go/jsmod v1.5.3
|
||||
apigo.cc/go/log v1.5.8
|
||||
apigo.cc/go/safe v1.5.2
|
||||
github.com/emersion/go-imap/v2 v2.0.0-beta.8
|
||||
github.com/jaytaylor/html2text v0.0.0-20260303211410-1a4bdc82ecec
|
||||
github.com/jhillyerd/enmime v1.3.0
|
||||
@ -15,11 +15,11 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
apigo.cc/go/config v1.5.2 // indirect
|
||||
apigo.cc/go/encoding v1.5.3 // indirect
|
||||
apigo.cc/go/id v1.5.3 // indirect
|
||||
apigo.cc/go/rand v1.5.2 // indirect
|
||||
apigo.cc/go/shell v1.5.2 // indirect
|
||||
apigo.cc/go/config v1.5.3 // indirect
|
||||
apigo.cc/go/encoding v1.5.4 // indirect
|
||||
apigo.cc/go/id v1.5.4 // indirect
|
||||
apigo.cc/go/rand v1.5.3 // indirect
|
||||
apigo.cc/go/shell v1.5.3 // indirect
|
||||
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/clipperhouse/displaywidth v0.10.0 // indirect
|
||||
|
||||
69
js_export.go
69
js_export.go
@ -8,17 +8,36 @@ import (
|
||||
func init() {
|
||||
jsmod.Register("mail", map[string]any{
|
||||
// 默认邮箱操作 (对齐 PascalCase)
|
||||
"Send": func(to any, subject, content string, option *SendOption) error {
|
||||
var toList []string
|
||||
cast.Convert(&toList, to)
|
||||
return Send(toList, subject, content, option)
|
||||
},
|
||||
"Recv": func(opt *RecvOption) (*RecvResult, error) {
|
||||
return Recv(opt)
|
||||
},
|
||||
"Send": jsSend,
|
||||
"Recv": jsRecv,
|
||||
|
||||
// 多实例获取 (对齐 PascalCase,支持可选参数)
|
||||
"Mailbox": func(name *string) *jsMailbox {
|
||||
"Mailbox": jsMailboxGetter,
|
||||
|
||||
// 辅助工具
|
||||
"FormatAddr": jsFormatAddr,
|
||||
"ParseAddr": jsParseAddr,
|
||||
})
|
||||
}
|
||||
|
||||
func jsSend(to any, subject, content string, option *SendOption) error {
|
||||
var toList []string
|
||||
cast.Convert(&toList, to)
|
||||
if err := Send(toList, subject, content, option); err != nil {
|
||||
return jsmod.MakeError(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func jsRecv(opt *RecvOption) (*RecvResult, error) {
|
||||
res, err := Recv(opt)
|
||||
if err != nil {
|
||||
return nil, jsmod.MakeError(err)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func jsMailboxGetter(name *string) *jsMailbox {
|
||||
target := "default"
|
||||
if name != nil {
|
||||
target = *name
|
||||
@ -28,12 +47,18 @@ func init() {
|
||||
return nil
|
||||
}
|
||||
return &jsMailbox{m: m}
|
||||
},
|
||||
}
|
||||
|
||||
// 辅助工具
|
||||
"FormatAddr": FormatAddr,
|
||||
"ParseAddr": ParseAddr,
|
||||
})
|
||||
func jsFormatAddr(name, address string) string {
|
||||
return FormatAddr(name, address)
|
||||
}
|
||||
|
||||
func jsParseAddr(addr string) (string, string, error) {
|
||||
name, address, err := ParseAddr(addr)
|
||||
if err != nil {
|
||||
return "", "", jsmod.MakeError(err)
|
||||
}
|
||||
return name, address, nil
|
||||
}
|
||||
|
||||
// jsMailbox 包装 Mailbox 实例
|
||||
@ -44,13 +69,23 @@ type jsMailbox struct {
|
||||
func (j *jsMailbox) Send(to any, subject, content string, option *SendOption) error {
|
||||
var toList []string
|
||||
cast.Convert(&toList, to)
|
||||
return j.m.Send(toList, subject, content, option)
|
||||
if err := j.m.Send(toList, subject, content, option); err != nil {
|
||||
return jsmod.MakeError(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (j *jsMailbox) Recv(opt *RecvOption) (*RecvResult, error) {
|
||||
return j.m.Recv(opt)
|
||||
res, err := j.m.Recv(opt)
|
||||
if err != nil {
|
||||
return nil, jsmod.MakeError(err)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (j *jsMailbox) Health() error {
|
||||
return j.m.Health()
|
||||
if err := j.m.Health(); err != nil {
|
||||
return jsmod.MakeError(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user