From 1645918690600f93fbd070b9f5129ff583421046 Mon Sep 17 00:00:00 2001 From: AI Engineer Date: Wed, 10 Jun 2026 11:18:04 +0800 Subject: [PATCH] feat: align JS exports to PascalCase and optimize optional params (by AI) --- CHANGELOG.md | 5 +++++ go.mod | 4 ++-- go.sum | 6 ++---- js_export.go | 51 +++++++++++++++++++++++++++++++++------------------ 4 files changed, 42 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f87c42..48d9664 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGELOG - apigo.cc/go/vision +## v1.5.1 (2026-06-08) +- **JS 对齐 & 智能文档**: + - 将所有注册到 `jsmod` 的方法名统一为 PascalCase。 + - **可选参数优化**: 将 `New` 的 `bg`、`Save` 的 `quality` 等改用指针类型包装。配合最新的 `go/js` 引擎,生成的 `.d.ts` 定义将正确标识为可选参数 `?`,大幅提升 AI 开发效率。 + ## v1.0.9 (2026-05-17) - **新特性**: 内置全能命令行工具 `vision` (`cmd/vision`)。 - **功能增强**: `vision.Load` 增加多级环境探测(sips, heif-convert, magick, ffmpeg),完美支持 HEIC 及其网格重构解码。 diff --git a/go.mod b/go.mod index 75f4f44..bc4ad40 100644 --- a/go.mod +++ b/go.mod @@ -21,8 +21,8 @@ require ( apigo.cc/go/safe v1.5.0 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/kr/text v0.2.0 // indirect - golang.org/x/crypto v0.51.0 // indirect - golang.org/x/sys v0.44.0 // indirect + golang.org/x/crypto v0.52.0 // indirect + golang.org/x/sys v0.45.0 // indirect golang.org/x/text v0.37.0 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 23e7503..47698d6 100644 --- a/go.sum +++ b/go.sum @@ -31,13 +31,11 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= -golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI= -golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= +golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.40.0 h1:Tw4GyDXMo+daZN1znreBRC3VayR1aLFUyUEOLUdW1a8= golang.org/x/image v0.40.0/go.mod h1:uIc348UZMSvS5Z65CVZ7iDPaNobNFEPeJ4kbqTOszmA= -golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= -golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= diff --git a/js_export.go b/js_export.go index 82bc7ef..174f556 100644 --- a/js_export.go +++ b/js_export.go @@ -10,7 +10,7 @@ import ( func init() { jsmod.Register("vision", map[string]any{ // 基础操作 - "load": func(ctx context.Context, path string) (*jsCanvas, error) { + "Load": func(ctx context.Context, path string) (*jsCanvas, error) { p, err := file.VerifyPathForSafeMode(ctx, path) if err != nil { return nil, err @@ -21,38 +21,44 @@ func init() { } return &jsCanvas{ctx: ctx, c: c}, nil }, - "new": func(ctx context.Context, w, h int, bg ...string) *jsCanvas { - return &jsCanvas{ctx: ctx, c: New(w, h, bg...)} + "New": func(ctx context.Context, w, h int, bg *string) *jsCanvas { + if bg != nil { + return &jsCanvas{ctx: ctx, c: New(w, h, *bg)} + } + return &jsCanvas{ctx: ctx, c: New(w, h)} }, - "save": func(ctx context.Context, j *jsCanvas, path string, quality ...int) error { + "Save": func(ctx context.Context, j *jsCanvas, path string, quality *int) error { p, err := file.VerifyPathForSafeMode(ctx, path) if err != nil { return err } - return Save(j.c, p, quality...) + if quality != nil { + return Save(j.c, p, *quality) + } + return Save(j.c, p) }, // 生成类 - "generateQRCode": func(ctx context.Context, content string, size int) (*jsCanvas, error) { + "GenerateQRCode": func(ctx context.Context, content string, size int) (*jsCanvas, error) { c, err := GenerateQRCode(content, size) if err != nil { return nil, err } return &jsCanvas{ctx: ctx, c: c}, nil }, - "generateBarcode": func(ctx context.Context, content string, w, h int) (*jsCanvas, error) { + "GenerateBarcode": func(ctx context.Context, content string, w, h int) (*jsCanvas, error) { c, err := GenerateBarcode(content, w, h) if err != nil { return nil, err } return &jsCanvas{ctx: ctx, c: c}, nil }, - "generateCaptcha": func(ctx context.Context, opt *CaptchaOption) *jsCanvas { + "GenerateCaptcha": func(ctx context.Context, opt *CaptchaOption) *jsCanvas { return &jsCanvas{ctx: ctx, c: GenerateCaptcha(opt)} }, // 预览类 (直接写文件) - "generateImagePreview": func(ctx context.Context, src, out string, w, h int) error { + "GenerateImagePreview": func(ctx context.Context, src, out string, w, h int) error { pSrc, err := file.VerifyPathForSafeMode(ctx, src) if err != nil { return err @@ -63,7 +69,7 @@ func init() { } return GenerateImagePreview(pSrc, pOut, w, h) }, - "generateVideoPreview": func(ctx context.Context, src, out string, w, h int, interval ...int) error { + "GenerateVideoPreview": func(ctx context.Context, src, out string, w, h int, interval *int) error { pSrc, err := file.VerifyPathForSafeMode(ctx, src) if err != nil { return err @@ -72,11 +78,14 @@ func init() { if err != nil { return err } - return GenerateVideoPreview(pSrc, pOut, w, h, interval...) + if interval != nil { + return GenerateVideoPreview(pSrc, pOut, w, h, *interval) + } + return GenerateVideoPreview(pSrc, pOut, w, h) }, // 转换类 - "convert": func(ctx context.Context, src, dst string, quality ...int) error { + "Convert": func(ctx context.Context, src, dst string, quality *int) error { pSrc, err := file.VerifyPathForSafeMode(ctx, src) if err != nil { return err @@ -85,9 +94,12 @@ func init() { if err != nil { return err } - return Convert(pSrc, pDst, quality...) + if quality != nil { + return Convert(pSrc, pDst, *quality) + } + return Convert(pSrc, pDst) }, - "optimize": func(ctx context.Context, path string, maxWidth int, quality int) error { + "Optimize": func(ctx context.Context, path string, maxWidth int, quality int) error { p, err := file.VerifyPathForSafeMode(ctx, path) if err != nil { return err @@ -96,8 +108,8 @@ func init() { }, // 辅助工具 - "loadFonts": LoadFonts, - "recognize": func(ctx context.Context, path string) (string, error) { + "LoadFonts": LoadFonts, + "Recognize": func(ctx context.Context, path string) (string, error) { p, err := file.VerifyPathForSafeMode(ctx, path) if err != nil { return "", err @@ -116,12 +128,15 @@ type jsCanvas struct { func (j *jsCanvas) Width() int { return j.c.Width() } func (j *jsCanvas) Height() int { return j.c.Height() } -func (j *jsCanvas) Save(path string, quality ...int) error { +func (j *jsCanvas) Save(path string, quality *int) error { p, err := file.VerifyPathForSafeMode(j.ctx, path) if err != nil { return err } - return Save(j.c, p, quality...) + if quality != nil { + return Save(j.c, p, *quality) + } + return Save(j.c, p) } // 效果与绘图 (返回自身以支持链式)