feat: register enhanced http capabilities to jsmod

This commit is contained in:
AI Engineer 2026-05-30 19:02:57 +08:00
parent 8db540a5c3
commit 63983dbd60
4 changed files with 109 additions and 0 deletions

View File

@ -1,5 +1,9 @@
# CHANGELOG # CHANGELOG
## v1.3.3 (2026-05-30)
- **新增**: 注册到 `jsmod`
- **优化 (JSMOD)**: 提供 `timeout(ms)` 支持动态超时控制,封装 `jsResult` 以屏蔽敏感的 `Save()` 方法,支持 `form()``multipart()` 数据标记。
## v1.0.10 (2026-05-09) ## v1.0.10 (2026-05-09)
- **CI/CD 对齐**: - **CI/CD 对齐**:
- 修复测试用例由于默认绑定泛地址导致的 `connection refused` 错误,显式绑定本地测试服务器至 `127.0.0.1`,提高 macOS 与多网卡环境下的测试稳定性。 - 修复测试用例由于默认绑定泛地址导致的 `connection refused` 错误,显式绑定本地测试服务器至 `127.0.0.1`,提高 macOS 与多网卡环境下的测试稳定性。

1
go.mod
View File

@ -6,6 +6,7 @@ require (
apigo.cc/go/cast v1.3.3 apigo.cc/go/cast v1.3.3
apigo.cc/go/encoding v1.3.1 apigo.cc/go/encoding v1.3.1
apigo.cc/go/file v1.3.2 apigo.cc/go/file v1.3.2
apigo.cc/go/jsmod v1.0.0
apigo.cc/go/log v1.3.4 apigo.cc/go/log v1.3.4
apigo.cc/go/rand v1.3.1 apigo.cc/go/rand v1.3.1
golang.org/x/net v0.54.0 golang.org/x/net v0.54.0

2
go.sum
View File

@ -8,6 +8,8 @@ apigo.cc/go/file v1.3.2 h1:pu4oiDyiqgj3/eykfnJf+/6+A9v/Z0b3ClP5XK+lwG4=
apigo.cc/go/file v1.3.2/go.mod h1:vci4h0Pz94mV6dkniQkuyBYERVYeq7/LX4jJVuCg9hs= apigo.cc/go/file v1.3.2/go.mod h1:vci4h0Pz94mV6dkniQkuyBYERVYeq7/LX4jJVuCg9hs=
apigo.cc/go/id v1.3.1 h1:pkqi6VeWyQoHuIu0Zbx/RRxIAdM61Js0j6cY1M9XVCk= apigo.cc/go/id v1.3.1 h1:pkqi6VeWyQoHuIu0Zbx/RRxIAdM61Js0j6cY1M9XVCk=
apigo.cc/go/id v1.3.1/go.mod h1:P2/vl3tyW3US+ayOFSMoPIOCulNLBngNYPhXJC/Z7J4= apigo.cc/go/id v1.3.1/go.mod h1:P2/vl3tyW3US+ayOFSMoPIOCulNLBngNYPhXJC/Z7J4=
apigo.cc/go/jsmod v1.0.0 h1:lVQMq0tCno4kbHlQ3j5wzsm+v24J+bznIoHxpton0pE=
apigo.cc/go/jsmod v1.0.0/go.mod h1:bmyeZtOAP/j5am+YRnaiM89smysK24K7ebk0koFtsSw=
apigo.cc/go/log v1.3.4 h1:UT8Neb9r4QjjbCFbTzw+ZeTxd+DmdmR5gNExeR4Cj+g= apigo.cc/go/log v1.3.4 h1:UT8Neb9r4QjjbCFbTzw+ZeTxd+DmdmR5gNExeR4Cj+g=
apigo.cc/go/log v1.3.4/go.mod h1:/Q/2r51xWSsrS4QN5U9jLiTw8n6qNC8kG9nuVHweY20= apigo.cc/go/log v1.3.4/go.mod h1:/Q/2r51xWSsrS4QN5U9jLiTw8n6qNC8kG9nuVHweY20=
apigo.cc/go/rand v1.3.1 h1:7FvsI6PtQ5XrWER0dTiLVo0p7GIxRidT/TBKhVy93j8= apigo.cc/go/rand v1.3.1 h1:7FvsI6PtQ5XrWER0dTiLVo0p7GIxRidT/TBKhVy93j8=

102
js_export.go Normal file
View File

@ -0,0 +1,102 @@
package http
import (
"time"
"apigo.cc/go/jsmod"
)
func init() {
jsmod.Register("http", map[string]any{
// Static requests with default timeout (30s)
"get": func(url string, headers ...string) *jsResult {
return wrapResult(Get(url, headers...))
},
"post": func(url string, data any, headers ...string) *jsResult {
return wrapResult(Post(url, data, headers...))
},
"put": func(url string, data any, headers ...string) *jsResult {
return wrapResult(Put(url, data, headers...))
},
"delete": func(url string, data any, headers ...string) *jsResult {
return wrapResult(Delete(url, data, headers...))
},
// Timeout control
"timeout": func(ms int) *jsClient {
return &jsClient{c: NewClient(time.Duration(ms) * time.Millisecond)}
},
// Data markers
"form": func(data map[string]string) Form {
return Form(data)
},
"multipart": func(data map[string]any) Multipart {
return Multipart(data)
},
// Global Headers
"setGlobalHeader": DefaultClient.SetGlobalHeader,
"getGlobalHeader": DefaultClient.GetGlobalHeader,
})
}
// jsClient wraps the internal Client to provide a JS-friendly interface
type jsClient struct {
c *Client
}
func (jc *jsClient) Get(url string, headers ...string) *jsResult {
return wrapResult(jc.c.Get(url, headers...))
}
func (jc *jsClient) Post(url string, data any, headers ...string) *jsResult {
return wrapResult(jc.c.Post(url, data, headers...))
}
func (jc *jsClient) Put(url string, data any, headers ...string) *jsResult {
return wrapResult(jc.c.Put(url, data, headers...))
}
func (jc *jsClient) Delete(url string, data any, headers ...string) *jsResult {
return wrapResult(jc.c.Delete(url, data, headers...))
}
// jsResult wraps *Result to hide sensitive methods like Save()
type jsResult struct {
r *Result
}
func wrapResult(r *Result) *jsResult {
return &jsResult{r: r}
}
func (jr *jsResult) String() string {
return jr.r.String()
}
func (jr *jsResult) Bytes() []byte {
return jr.r.Bytes()
}
func (jr *jsResult) Map() map[string]any {
return jr.r.Map()
}
func (jr *jsResult) Slice() []any {
return jr.r.Slice()
}
func (jr *jsResult) Status() int {
if jr.r.Response != nil {
return jr.r.Response.StatusCode
}
return 0
}
func (jr *jsResult) Error() string {
if jr.r.Error != nil {
return jr.r.Error.Error()
}
return ""
}