chore: refresh dependencies, fix Linux tool tasks, modernize Go idioms

Frontend deps: @hookform/resolvers 5.4.0 -> 5.4.3 and react-hook-form
7.82.0 -> 7.83.0. The @typeschema/valibot override is what makes this
installable at all. Resolvers 5.4.3 re-declares 25 optional peers for its
validator matrix, and npm resolves them into the ideal tree even though none
are used here; two of them contradict, since resolvers wants valibot ^1 while
@typeschema/main -> @typeschema/valibot pins valibot ^0.39. Both target the
same node_modules/valibot, so a plain npm update dies with ERESOLVE. The
override settles that one edge and nothing extra lands in node_modules.

Backend deps: telego 1.10.0 -> 1.11.1 (Telegram Bot API v10.2, additive
only), klauspost/compress 1.19.1, plus the indirect bumps that came with them.

VS Code tasks: the golangci-lint and modernize tasks assumed Windows PATH
semantics, where PATH is a persistent user variable that every process
inherits, so ~/go/bin was always visible. On Linux that directory is exported
from ~/.bashrc, which the non-interactive `bash -c` behind a task never
sources, and both tasks failed with exit 127. Adds linux/osx option blocks
that prepend the Go bin directories and leaves the Windows path untouched,
plus tasks to install the two tools; those are split because go install
rejects packages from different modules in one invocation.

Go sources: modernize -fix output, covering range-over-int, slices.Backward,
maps.Copy, strings.CutPrefix and strings.SplitSeq. Behaviour is unchanged.
This commit is contained in:
Sanaei
2026-07-25 16:08:09 +02:00
parent edb487a005
commit f4e79e70ea
11 changed files with 724 additions and 536 deletions
+1 -1
View File
@@ -197,7 +197,7 @@ func TestBusSubscriberRunsSerially(t *testing.T) {
wg.Done()
})
for i := 0; i < n; i++ {
for range n {
b.Publish(Event{Type: EventXrayCrash})
}
+1 -1
View File
@@ -418,7 +418,7 @@ func (s *SubClashService) buildWireguardProxy(subReq *SubService, inbound *model
}
if dns, _ := inboundSettings["dns"].(string); dns != "" {
servers := make([]string, 0)
for _, server := range strings.Split(dns, ",") {
for server := range strings.SplitSeq(dns, ",") {
if server = strings.TrimSpace(server); server != "" {
servers = append(servers, server)
}
+2 -2
View File
@@ -101,8 +101,8 @@ func linkDisplayName(rawLink string) string {
if rawLink == "" {
return ""
}
if strings.HasPrefix(rawLink, "vmess://") {
b64 := strings.TrimPrefix(rawLink, "vmess://")
if after, ok := strings.CutPrefix(rawLink, "vmess://"); ok {
b64 := after
raw, err := base64.StdEncoding.DecodeString(padBase64Sub(b64))
if err != nil {
raw, err = base64.RawURLEncoding.DecodeString(strings.TrimRight(b64, "="))
+2 -3
View File
@@ -8,6 +8,7 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"maps"
"math"
"net/url"
"regexp"
@@ -627,9 +628,7 @@ func applyTransport(stream map[string]any, p url.Values) {
if extra := p.Get("extra"); extra != "" {
var parsed map[string]any
if err := json.Unmarshal([]byte(extra), &parsed); err == nil {
for k, v := range parsed {
xh[k] = v
}
maps.Copy(xh, parsed)
}
}
for _, k := range []string{"xPaddingBytes", "scMaxEachPostBytes", "scMinPostsIntervalMs", "uplinkChunkSize"} {
@@ -9,7 +9,7 @@ import (
func TestLoginLimiterBoundsMemoryUnderUsernameFlood(t *testing.T) {
limiter := newLoginLimiter(5, 5*time.Minute, 15*time.Minute)
for i := 0; i < loginLimitMaxRecords+100; i++ {
for i := range loginLimitMaxRecords + 100 {
limiter.registerFailure("1.2.3.4", "user-"+strconv.Itoa(i))
}
@@ -28,7 +28,7 @@ func TestLoginLimiterEvictionSparesActiveBlocks(t *testing.T) {
limiter.now = func() time.Time { return now }
limiter.mu.Lock()
for i := 0; i < loginLimitMaxRecords-1; i++ {
for i := range loginLimitMaxRecords - 1 {
limiter.attempts["victim-"+strconv.Itoa(i)] = &loginLimitRecord{blockedUntil: now.Add(10 * time.Minute)}
}
limiter.attempts["filler"] = &loginLimitRecord{failures: []time.Time{now}}
+3 -2
View File
@@ -4,6 +4,7 @@ import (
"encoding/gob"
"os"
"path/filepath"
"slices"
"sync"
"time"
@@ -170,8 +171,8 @@ func (h *metricHistory) aggregate(metric string, bucketSeconds int, maxPoints in
h.mu.Unlock()
startIdx := len(raw)
for i := len(raw) - 1; i >= 0; i-- {
if raw[i].T < cutoff {
for i, r := range slices.Backward(raw) {
if r.T < cutoff {
break
}
startIdx = i