Compare commits
No commits in common. "3d5f3ba9097dfde8bd1021a5684d5a63bd73f94e" and "7b8421bf43e4dceeb4b93534b46661013333111b" have entirely different histories.
3d5f3ba909
...
7b8421bf43
@ -1,9 +1,5 @@
|
|||||||
# CHANGELOG
|
# 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)
|
## v1.0.4 (2026-05-31)
|
||||||
- **新增**: 注册到 `jsmod`。支持低代码环境下的邮件发送与接收。
|
- **新增**: 注册到 `jsmod`。支持低代码环境下的邮件发送与接收。
|
||||||
- 提供 `send`, `recv` 默认快捷操作。
|
- 提供 `send`, `recv` 默认快捷操作。
|
||||||
|
|||||||
3
TEST.md
3
TEST.md
@ -18,6 +18,5 @@
|
|||||||
| 内存占用 | 低 | 采用流式处理及即时擦除 |
|
| 内存占用 | 低 | 采用流式处理及即时擦除 |
|
||||||
|
|
||||||
## 验证结果
|
## 验证结果
|
||||||
- **单元测试**: `go test -v ./...` 通过 (2026-06-21)。
|
- **单元测试**: `go test -v ./...` 通过。
|
||||||
- **并发安全性**: 经过 `sync.RWMutex` 保护,支持多协程下注册 Handler 及发送。
|
- **并发安全性**: 经过 `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
|
go 1.26.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
apigo.cc/go/cast v1.5.3
|
apigo.cc/go/cast v1.5.0
|
||||||
apigo.cc/go/file v1.5.5
|
apigo.cc/go/file v1.5.0
|
||||||
apigo.cc/go/jsmod v1.5.3
|
apigo.cc/go/jsmod v1.5.0
|
||||||
apigo.cc/go/log v1.5.8
|
apigo.cc/go/log v1.5.0
|
||||||
apigo.cc/go/safe v1.5.2
|
apigo.cc/go/safe v1.5.0
|
||||||
github.com/emersion/go-imap/v2 v2.0.0-beta.8
|
github.com/emersion/go-imap/v2 v2.0.0-beta.8
|
||||||
github.com/jaytaylor/html2text v0.0.0-20260303211410-1a4bdc82ecec
|
github.com/jaytaylor/html2text v0.0.0-20260303211410-1a4bdc82ecec
|
||||||
github.com/jhillyerd/enmime v1.3.0
|
github.com/jhillyerd/enmime v1.3.0
|
||||||
@ -15,11 +15,11 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
apigo.cc/go/config v1.5.3 // indirect
|
apigo.cc/go/config v1.5.0 // indirect
|
||||||
apigo.cc/go/encoding v1.5.4 // indirect
|
apigo.cc/go/encoding v1.5.0 // indirect
|
||||||
apigo.cc/go/id v1.5.4 // indirect
|
apigo.cc/go/id v1.5.0 // indirect
|
||||||
apigo.cc/go/rand v1.5.3 // indirect
|
apigo.cc/go/rand v1.5.0 // indirect
|
||||||
apigo.cc/go/shell v1.5.3 // indirect
|
apigo.cc/go/shell v1.5.0 // indirect
|
||||||
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a // indirect
|
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/clipperhouse/displaywidth v0.10.0 // indirect
|
github.com/clipperhouse/displaywidth v0.10.0 // indirect
|
||||||
|
|||||||
83
js_export.go
83
js_export.go
@ -8,59 +8,34 @@ import (
|
|||||||
func init() {
|
func init() {
|
||||||
jsmod.Register("mail", map[string]any{
|
jsmod.Register("mail", map[string]any{
|
||||||
// 默认邮箱操作 (对齐 PascalCase)
|
// 默认邮箱操作 (对齐 PascalCase)
|
||||||
"Send": jsSend,
|
"Send": func(to any, subject, content string, option *SendOption) error {
|
||||||
"Recv": jsRecv,
|
var toList []string
|
||||||
|
cast.Convert(&toList, to)
|
||||||
|
return Send(toList, subject, content, option)
|
||||||
|
},
|
||||||
|
"Recv": func(opt *RecvOption) (*RecvResult, error) {
|
||||||
|
return Recv(opt)
|
||||||
|
},
|
||||||
|
|
||||||
// 多实例获取 (对齐 PascalCase,支持可选参数)
|
// 多实例获取 (对齐 PascalCase,支持可选参数)
|
||||||
"Mailbox": jsMailboxGetter,
|
"Mailbox": func(name *string) *jsMailbox {
|
||||||
|
target := "default"
|
||||||
|
if name != nil {
|
||||||
|
target = *name
|
||||||
|
}
|
||||||
|
m := GetMailbox(target)
|
||||||
|
if m == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &jsMailbox{m: m}
|
||||||
|
},
|
||||||
|
|
||||||
// 辅助工具
|
// 辅助工具
|
||||||
"FormatAddr": jsFormatAddr,
|
"FormatAddr": FormatAddr,
|
||||||
"ParseAddr": jsParseAddr,
|
"ParseAddr": ParseAddr,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
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 实例
|
// jsMailbox 包装 Mailbox 实例
|
||||||
type jsMailbox struct {
|
type jsMailbox struct {
|
||||||
m *Mailbox
|
m *Mailbox
|
||||||
@ -69,23 +44,13 @@ type jsMailbox struct {
|
|||||||
func (j *jsMailbox) Send(to any, subject, content string, option *SendOption) error {
|
func (j *jsMailbox) Send(to any, subject, content string, option *SendOption) error {
|
||||||
var toList []string
|
var toList []string
|
||||||
cast.Convert(&toList, to)
|
cast.Convert(&toList, to)
|
||||||
if err := j.m.Send(toList, subject, content, option); err != nil {
|
return j.m.Send(toList, subject, content, option)
|
||||||
return jsmod.MakeError(err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *jsMailbox) Recv(opt *RecvOption) (*RecvResult, error) {
|
func (j *jsMailbox) Recv(opt *RecvOption) (*RecvResult, error) {
|
||||||
res, err := j.m.Recv(opt)
|
return j.m.Recv(opt)
|
||||||
if err != nil {
|
|
||||||
return nil, jsmod.MakeError(err)
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *jsMailbox) Health() error {
|
func (j *jsMailbox) Health() error {
|
||||||
if err := j.m.Health(); err != nil {
|
return j.m.Health()
|
||||||
return jsmod.MakeError(err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user