diff --git a/CHANGELOG.md b/CHANGELOG.md index b6156c1..a6c2492 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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` 默认快捷操作。 diff --git a/TEST.md b/TEST.md index a1ebfec..f4e2b10 100644 --- a/TEST.md +++ b/TEST.md @@ -18,5 +18,6 @@ | 内存占用 | 低 | 采用流式处理及即时擦除 | ## 验证结果 -- **单元测试**: `go test -v ./...` 通过。 +- **单元测试**: `go test -v ./...` 通过 (2026-06-21)。 - **并发安全性**: 经过 `sync.RWMutex` 保护,支持多协程下注册 Handler 及发送。 +- **JS 错误调用栈**: JS 桥接层改用具名导出并使用 `jsmod.MakeError` 包裹错误,确保 JS 抛出异常时携带准确的 Go 运行时堆栈。 diff --git a/go.mod b/go.mod index a3b7502..08208bd 100644 --- a/go.mod +++ b/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 diff --git a/js_export.go b/js_export.go index 306f187..0e7e0cb 100644 --- a/js_export.go +++ b/js_export.go @@ -8,34 +8,59 @@ 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 { - target := "default" - if name != nil { - target = *name - } - m := GetMailbox(target) - if m == nil { - return nil - } - return &jsMailbox{m: m} - }, + "Mailbox": jsMailboxGetter, // 辅助工具 - "FormatAddr": FormatAddr, - "ParseAddr": ParseAddr, + "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 + } + m := GetMailbox(target) + if m == nil { + return nil + } + return &jsMailbox{m: m} +} + +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 实例 type jsMailbox struct { m *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 }