From 4e1bc0d5d6b3ccec43a3239db028af55e9b735ae Mon Sep 17 00:00:00 2001 From: d34dscene Date: Mon, 8 Dec 2025 11:11:49 +0100 Subject: [PATCH] fix: better router service naming, fix db regression --- agent/cmd/main.go | 88 +++-- agent/internal/client/client.go | 2 + agent/internal/client/config.go | 28 +- agent/internal/client/sync.go | 5 - agent/internal/collector/docker.go | 86 +++-- docs/package.json | 4 +- docs/pnpm-lock.yaml | 393 ++++++++++++---------- go.mod | 5 +- go.sum | 12 +- server/internal/api/handler/oidc.go | 3 +- server/internal/api/service/router_ops.go | 60 ++-- server/internal/dns/client.go | 21 +- server/internal/store/connection.go | 7 +- server/internal/tasks/tasks.go | 4 +- web/package.json | 10 +- web/pnpm-lock.yaml | 164 ++++----- 16 files changed, 514 insertions(+), 378 deletions(-) diff --git a/agent/cmd/main.go b/agent/cmd/main.go index 7166822..470e28f 100644 --- a/agent/cmd/main.go +++ b/agent/cmd/main.go @@ -1,45 +1,87 @@ -// Package main is the entrypoint for the mantrae agent. package main import ( "context" - "flag" "fmt" - "log/slog" + "log" "os" "os/signal" "syscall" "github.com/mizuchilabs/mantrae/agent/internal/client" - "github.com/mizuchilabs/mantrae/pkg/logger" + "github.com/mizuchilabs/mantrae/pkg/build" "github.com/mizuchilabs/mantrae/pkg/meta" + "github.com/urfave/cli/v3" ) func main() { - version := flag.Bool("version", false, "Show version") - flag.Parse() + cmd := &cli.Command{ + EnableShellCompletion: true, + Suggest: true, + Name: "mantrae-agent", + Version: meta.Version, + Usage: "mantrae-agent [command]", + Action: func(ctx context.Context, cmd *cli.Command) error { + cfg, err := client.Load(cmd) + if err != nil { + return fmt.Errorf("failed to load configuration: %w", err) + } - if *version { - fmt.Println(meta.Version) - return + // Start agent + client.NewAgent(cfg).Run(ctx) + return nil + }, + Commands: []*cli.Command{ + { + Name: "update", + Usage: "Check for updates or update mantrae-agent to the latest version", + Description: `Check if a newer version of mantrae-agent is available. +Use the --install flag to download and install the latest version. + +Note: Automatic installation does not work inside Docker containers.`, + Action: func(ctx context.Context, cmd *cli.Command) error { + build.Update(cmd.Bool("install")) + return nil + }, + }, + }, + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "version", + Aliases: []string{"v"}, + Usage: "Display version information and exit", + }, + &cli.BoolFlag{ + Name: "debug", + Aliases: []string{"d"}, + Usage: "Enable debug logging", + Sources: cli.EnvVars("DEBUG"), + }, + &cli.BoolFlag{ + Name: "install", + Usage: "Download and install the latest version (used with update command, does not work in Docker)", + Value: false, + }, + &cli.StringFlag{ + Name: "token", + Usage: "Mantrae API token", + Value: "", + Sources: cli.EnvVars("TOKEN"), + }, + &cli.StringFlag{ + Name: "host", + Usage: "Mantrae API host", + Value: "", + Sources: cli.EnvVars("HOST"), + }, + }, } - logger.Setup() - - cfg, err := client.Load() - if err != nil { - slog.Error("Failed to load configuration", "error", err) - os.Exit(1) - } - - slog.Info("Starting agent", - "server", cfg.ServerURL, - "profile_id", cfg.ProfileID, - "agent_id", cfg.AgentID) - // Graceful shutdown ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) defer stop() - client.NewAgent(cfg).Run(ctx) + if err := cmd.Run(ctx, os.Args); err != nil { + log.Fatal(err) + } } diff --git a/agent/internal/client/client.go b/agent/internal/client/client.go index b82618d..a9de70b 100644 --- a/agent/internal/client/client.go +++ b/agent/internal/client/client.go @@ -40,6 +40,8 @@ func NewAgent(cfg *Config) *Agent { } func (a *Agent) Run(ctx context.Context) { + slog.Info("Agent starting...", "version", meta.Version) + // Run initial health check a.healthCheck(ctx) diff --git a/agent/internal/client/config.go b/agent/internal/client/config.go index c5b6df5..0cafcca 100644 --- a/agent/internal/client/config.go +++ b/agent/internal/client/config.go @@ -2,12 +2,17 @@ package client import ( "errors" + "log/slog" "os" "strconv" "strings" "time" + "github.com/lmittmann/tint" + "github.com/mattn/go-colorable" + "github.com/mattn/go-isatty" "github.com/mizuchilabs/mantrae/pkg/util" + "github.com/urfave/cli/v3" ) type Config struct { @@ -22,9 +27,11 @@ type Config struct { HealthTimeout time.Duration } -func Load() (*Config, error) { - token := os.Getenv("TOKEN") - host := os.Getenv("HOST") +func Load(cmd *cli.Command) (*Config, error) { + Logger(cmd) // setup logger + + token := cmd.String("token") + host := cmd.String("host") if token == "" || host == "" { return nil, errors.New("TOKEN and HOST must be set") } @@ -47,6 +54,21 @@ func Load() (*Config, error) { }, nil } +func Logger(cmd *cli.Command) { + level := slog.LevelInfo + if cmd.Bool("debug") { + level = slog.LevelDebug + } + + slog.SetDefault(slog.New( + tint.NewHandler(colorable.NewColorable(os.Stderr), &tint.Options{ + Level: level, + TimeFormat: time.RFC3339, + NoColor: !isatty.IsTerminal(os.Stderr.Fd()), + }), + )) +} + func parseToken(token string) (int64, string, error) { parts := strings.Split(token, ".") if len(parts) < 2 { diff --git a/agent/internal/client/sync.go b/agent/internal/client/sync.go index ab2dd54..dc93e9d 100644 --- a/agent/internal/client/sync.go +++ b/agent/internal/client/sync.go @@ -168,11 +168,6 @@ func (s *SyncJob) upsertResources(ctx context.Context, containerID, resourceType if err != nil { return err } - if resourceType == "router" { - config.Fields["service"] = &structpb.Value{ - Kind: &structpb.Value_StringValue{StringValue: name}, - } - } if err := s.upsertResource(ctx, resourceType, protocol, name, config); err != nil { return err diff --git a/agent/internal/collector/docker.go b/agent/internal/collector/docker.go index 6ee58b2..7b789c7 100644 --- a/agent/internal/collector/docker.go +++ b/agent/internal/collector/docker.go @@ -5,6 +5,7 @@ import ( "context" "errors" "log/slog" + "os" "slices" "strings" @@ -22,6 +23,7 @@ type ContainerInfo struct { } var CleanupActions = []events.Action{ + events.ActionStop, events.ActionDestroy, events.ActionKill, events.ActionRemove, @@ -33,12 +35,30 @@ var SyncActions = []events.Action{ events.ActionUnPause, } +func dockerClient() (*client.Client, error) { + if _, err := os.Stat("/var/run/docker.sock"); err != nil { + slog.Warn("Docker socket not found", "path", "/var/run/docker.sock") + } + if _, ok := os.LookupEnv("DOCKER_HOST"); !ok { + _ = os.Setenv("DOCKER_HOST", "unix:///var/run/docker.sock") + } + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + slog.Error("Failed to create Docker client", "error", err) + return nil, err + } + return cli, nil +} + // GetContainers retrieves all local containers func GetContainers() ([]ContainerInfo, error) { - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + cli, err := dockerClient() if err != nil { return nil, errors.New("failed to create Docker client") } + defer func() { + _ = cli.Close() + }() containers, err := cli.ContainerList( context.Background(), @@ -51,8 +71,10 @@ func GetContainers() ([]ContainerInfo, error) { var result []ContainerInfo for _, c := range containers { name := strings.TrimPrefix(c.Names[0], "/") - if strings.Contains(c.Image, "traefik") && name != "whoami" { - slog.Debug("Skipping Traefik container", "name", c.Names[0]) + + // Skip Traefik reverse proxy itself + if isTraefikProxy(c.Image, c.Labels) { + slog.Debug("Skipping Traefik proxy", "name", name) continue } @@ -77,49 +99,35 @@ func GetContainers() ([]ContainerInfo, error) { } func WatchContainers(ctx context.Context, ch chan<- ContainerInfo) { - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + cli, err := dockerClient() if err != nil { slog.Error("Failed to create Docker client", "error", err) return } + defer func() { + _ = cli.Close() + }() eventFilter := filters.NewArgs() eventFilter.Add("type", "container") - eventFilter.Add("event", string(events.ActionStart)) - eventFilter.Add("event", string(events.ActionRestart)) - eventFilter.Add("event", string(events.ActionDie)) - eventFilter.Add("event", string(events.ActionDestroy)) - eventFilter.Add("event", string(events.ActionKill)) - eventFilter.Add("event", string(events.ActionPause)) - eventFilter.Add("event", string(events.ActionUnPause)) - eventFilter.Add("event", string(events.ActionStop)) - eventFilter.Add("event", string(events.ActionRemove)) + for _, action := range slices.Concat(SyncActions, CleanupActions) { + eventFilter.Add("event", string(action)) + } msgs, errs := cli.Events(ctx, events.ListOptions{Filters: eventFilter}) for { select { case event := <-msgs: + slog.Debug("Received Docker event", "action", event.Action, "id", event.Actor.ID[:12]) image := event.Actor.Attributes["image"] name := event.Actor.Attributes["name"] - // Skip traefik containers - if strings.Contains(image, "traefik") { - continue - } - - slog.Debug("Container event", - "action", event.Action, - "id", event.Actor.ID[:12], - "image", image, - "name", name, - ) containerInfo := ContainerInfo{ ID: event.Actor.ID, Name: name, Action: event.Action, } - inspect, err := cli.ContainerInspect(ctx, event.Actor.ID) if err != nil { if slices.Contains(CleanupActions, event.Action) { @@ -130,8 +138,21 @@ func WatchContainers(ctx context.Context, ch chan<- ContainerInfo) { continue } + // Skip Traefik reverse proxy itself (not whoami or other services) + if isTraefikProxy(image, containerInfo.Labels) { + slog.Debug("Skipping Traefik proxy", "name", name) + continue + } + containerInfo.Name = inspect.Name containerInfo.Labels = inspect.Config.Labels + slog.Debug( + "Sending container info", + "name", + containerInfo.Name, + "action", + containerInfo.Action, + ) ch <- containerInfo case err := <-errs: @@ -143,3 +164,18 @@ func WatchContainers(ctx context.Context, ch chan<- ContainerInfo) { } } } + +// isTraefikProxy checks if a container is the Traefik reverse proxy itself +func isTraefikProxy(image string, labels map[string]string) bool { + // Check for official Traefik image + if strings.HasPrefix(image, "traefik:") || + strings.HasPrefix(image, "docker.io/traefik:") { + return true + } + + // Check for Traefik-specific labels that only the proxy has + if _, ok := labels["traefik.http.routers.api.rule"]; ok { + return true + } + return false +} diff --git a/docs/package.json b/docs/package.json index ca56f77..2c88195 100644 --- a/docs/package.json +++ b/docs/package.json @@ -20,8 +20,8 @@ "@mdx-js/react": "^3.1.1", "clsx": "^2.1.1", "prism-react-renderer": "^2.4.1", - "react": "^19.2.0", - "react-dom": "^19.2.0" + "react": "^19.2.1", + "react-dom": "^19.2.1" }, "devDependencies": { "@docusaurus/module-type-aliases": "^3.9.2", diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml index 587c12f..4d5ddc8 100644 --- a/docs/pnpm-lock.yaml +++ b/docs/pnpm-lock.yaml @@ -13,7 +13,7 @@ importers: version: 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(typescript@5.9.3) '@docusaurus/preset-classic': specifier: ^3.9.2 - version: 3.9.2(@algolia/client-search@5.45.0)(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.1))(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(search-insights@2.17.3)(typescript@5.9.3) + version: 3.9.2(@algolia/client-search@5.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.1))(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(search-insights@2.17.3)(typescript@5.9.3) '@mdx-js/react': specifier: ^3.1.1 version: 3.1.1(@types/react@19.2.7)(react@19.2.1) @@ -24,10 +24,10 @@ importers: specifier: ^2.4.1 version: 2.4.1(react@19.2.1) react: - specifier: ^19.2.0 + specifier: ^19.2.1 version: 19.2.1 react-dom: - specifier: ^19.2.0 + specifier: ^19.2.1 version: 19.2.1(react@19.2.1) devDependencies: '@docusaurus/module-type-aliases': @@ -61,8 +61,8 @@ packages: resolution: {integrity: sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA==} engines: {node: '>=18'} - '@ai-sdk/react@2.0.106': - resolution: {integrity: sha512-TU8ONNhm64GI7O60UDCcOz9CdyCp3emQwSYrSnq+QWBNgS8vDlRQ3ZwXyPNAJQdXyBTafVS2iyS0kvV+KXaPAQ==} + '@ai-sdk/react@2.0.109': + resolution: {integrity: sha512-5qM8KuN7bv7E+g6BXkSAYLFjwIfMSTKOA1prjg1zEShJXJyLSc+Yqkd3EfGibm75b7nJAqJNShurDmR/IlQqFQ==} engines: {node: '>=18'} peerDependencies: react: ^18 || ^19 || ^19.0.0-rc @@ -71,8 +71,8 @@ packages: zod: optional: true - '@algolia/abtesting@1.11.0': - resolution: {integrity: sha512-a7oQ8dwiyoyVmzLY0FcuBqyqcNSq78qlcOtHmNBumRlHCSnXDcuoYGBGPN1F6n8JoGhviDDsIaF/oQrzTzs6Lg==} + '@algolia/abtesting@1.12.0': + resolution: {integrity: sha512-EfW0bfxjPs+C7ANkJDw2TATntfBKsFiy7APh+KO0pQ8A6HYa5I0NjFuCGCXWfzzzLXNZta3QUl3n5Kmm6aJo9Q==} engines: {node: '>= 14.0.0'} '@algolia/autocomplete-core@1.19.2': @@ -89,59 +89,59 @@ packages: '@algolia/client-search': '>= 4.9.1 < 6' algoliasearch: '>= 4.9.1 < 6' - '@algolia/client-abtesting@5.45.0': - resolution: {integrity: sha512-WTW0VZA8xHMbzuQD5b3f41ovKZ0MNTIXkWfm0F2PU+XGcLxmxX15UqODzF2sWab0vSbi3URM1xLhJx+bXbd1eQ==} + '@algolia/client-abtesting@5.46.0': + resolution: {integrity: sha512-eG5xV8rujK4ZIHXrRshvv9O13NmU/k42Rnd3w43iKH5RaQ2zWuZO6Q7XjaoJjAFVCsJWqRbXzbYyPGrbF3wGNg==} engines: {node: '>= 14.0.0'} - '@algolia/client-analytics@5.45.0': - resolution: {integrity: sha512-I3g7VtvG/QJOH3tQO7E7zWTwBfK/nIQXShFLR8RvPgWburZ626JNj332M3wHCYcaAMivN9WJG66S2JNXhm6+Xg==} + '@algolia/client-analytics@5.46.0': + resolution: {integrity: sha512-AYh2uL8IUW9eZrbbT+wZElyb7QkkeV3US2NEKY7doqMlyPWE8lErNfkVN1NvZdVcY4/SVic5GDbeDz2ft8YIiQ==} engines: {node: '>= 14.0.0'} - '@algolia/client-common@5.45.0': - resolution: {integrity: sha512-/nTqm1tLiPtbUr+8kHKyFiCOfhRfgC+JxLvOCq471gFZZOlsh6VtFRiKI60/zGmHTojFC6B0mD80PB7KeK94og==} + '@algolia/client-common@5.46.0': + resolution: {integrity: sha512-0emZTaYOeI9WzJi0TcNd2k3SxiN6DZfdWc2x2gHt855Jl9jPUOzfVTL6gTvCCrOlT4McvpDGg5nGO+9doEjjig==} engines: {node: '>= 14.0.0'} - '@algolia/client-insights@5.45.0': - resolution: {integrity: sha512-suQTx/1bRL1g/K2hRtbK3ANmbzaZCi13487sxxmqok+alBDKKw0/TI73ZiHjjFXM2NV52inwwcmW4fUR45206Q==} + '@algolia/client-insights@5.46.0': + resolution: {integrity: sha512-wrBJ8fE+M0TDG1As4DDmwPn2TXajrvmvAN72Qwpuv8e2JOKNohF7+JxBoF70ZLlvP1A1EiH8DBu+JpfhBbNphQ==} engines: {node: '>= 14.0.0'} - '@algolia/client-personalization@5.45.0': - resolution: {integrity: sha512-CId/dbjpzI3eoUhPU6rt/z4GrRsDesqFISEMOwrqWNSrf4FJhiUIzN42Ac+Gzg69uC0RnzRYy60K1y4Na5VSMw==} + '@algolia/client-personalization@5.46.0': + resolution: {integrity: sha512-LnkeX4p0ENt0DoftDJJDzQQJig/sFQmD1eQifl/iSjhUOGUIKC/7VTeXRcKtQB78naS8njUAwpzFvxy1CDDXDQ==} engines: {node: '>= 14.0.0'} - '@algolia/client-query-suggestions@5.45.0': - resolution: {integrity: sha512-tjbBKfA8fjAiFtvl9g/MpIPiD6pf3fj7rirVfh1eMIUi8ybHP4ovDzIaE216vHuRXoePQVCkMd2CokKvYq1CLw==} + '@algolia/client-query-suggestions@5.46.0': + resolution: {integrity: sha512-aF9tc4ex/smypXw+W3lBPB1jjKoaGHpZezTqofvDOI/oK1dR2sdTpFpK2Ru+7IRzYgwtRqHF3znmTlyoNs9dpA==} engines: {node: '>= 14.0.0'} - '@algolia/client-search@5.45.0': - resolution: {integrity: sha512-nxuCid+Nszs4xqwIMDw11pRJPes2c+Th1yup/+LtpjFH8QWXkr3SirNYSD3OXAeM060HgWWPLA8/Fxk+vwxQOA==} + '@algolia/client-search@5.46.0': + resolution: {integrity: sha512-22SHEEVNjZfFWkFks3P6HilkR3rS7a6GjnCIqR22Zz4HNxdfT0FG+RE7efTcFVfLUkTTMQQybvaUcwMrHXYa7Q==} engines: {node: '>= 14.0.0'} '@algolia/events@4.0.1': resolution: {integrity: sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==} - '@algolia/ingestion@1.45.0': - resolution: {integrity: sha512-t+1doBzhkQTeOOjLHMlm4slmXBhvgtEGQhOmNpMPTnIgWOyZyESWdm+XD984qM4Ej1i9FRh8VttOGrdGnAjAng==} + '@algolia/ingestion@1.46.0': + resolution: {integrity: sha512-2LT0/Z+/sFwEpZLH6V17WSZ81JX2uPjgvv5eNlxgU7rPyup4NXXfuMbtCJ+6uc4RO/LQpEJd3Li59ke3wtyAsA==} engines: {node: '>= 14.0.0'} - '@algolia/monitoring@1.45.0': - resolution: {integrity: sha512-IaX3ZX1A/0wlgWZue+1BNWlq5xtJgsRo7uUk/aSiYD7lPbJ7dFuZ+yTLFLKgbl4O0QcyHTj1/mSBj9ryF1Lizg==} + '@algolia/monitoring@1.46.0': + resolution: {integrity: sha512-uivZ9wSWZ8mz2ZU0dgDvQwvVZV8XBv6lYBXf8UtkQF3u7WeTqBPeU8ZoeTyLpf0jAXCYOvc1mAVmK0xPLuEwOQ==} engines: {node: '>= 14.0.0'} - '@algolia/recommend@5.45.0': - resolution: {integrity: sha512-1jeMLoOhkgezCCPsOqkScwYzAAc1Jr5T2hisZl0s32D94ZV7d1OHozBukgOjf8Dw+6Hgi6j52jlAdUWTtkX9Mg==} + '@algolia/recommend@5.46.0': + resolution: {integrity: sha512-O2BB8DuySuddgOAbhyH4jsGbL+KyDGpzJRtkDZkv091OMomqIA78emhhMhX9d/nIRrzS1wNLWB/ix7Hb2eV5rg==} engines: {node: '>= 14.0.0'} - '@algolia/requester-browser-xhr@5.45.0': - resolution: {integrity: sha512-46FIoUkQ9N7wq4/YkHS5/W9Yjm4Ab+q5kfbahdyMpkBPJ7IBlwuNEGnWUZIQ6JfUZuJVojRujPRHMihX4awUMg==} + '@algolia/requester-browser-xhr@5.46.0': + resolution: {integrity: sha512-eW6xyHCyYrJD0Kjk9Mz33gQ40LfWiEA51JJTVfJy3yeoRSw/NXhAL81Pljpa0qslTs6+LO/5DYPZddct6HvISQ==} engines: {node: '>= 14.0.0'} - '@algolia/requester-fetch@5.45.0': - resolution: {integrity: sha512-XFTSAtCwy4HdBhSReN2rhSyH/nZOM3q3qe5ERG2FLbYId62heIlJBGVyAPRbltRwNlotlydbvSJ+SQ0ruWC2cw==} + '@algolia/requester-fetch@5.46.0': + resolution: {integrity: sha512-Vn2+TukMGHy4PIxmdvP667tN/MhS7MPT8EEvEhS6JyFLPx3weLcxSa1F9gVvrfHWCUJhLWoMVJVB2PT8YfRGcw==} engines: {node: '>= 14.0.0'} - '@algolia/requester-node-http@5.45.0': - resolution: {integrity: sha512-8mTg6lHx5i44raCU52APsu0EqMsdm4+7Hch/e4ZsYZw0hzwkuaMFh826ngnkYf9XOl58nHoou63aZ874m8AbpQ==} + '@algolia/requester-node-http@5.46.0': + resolution: {integrity: sha512-xaqXyna5yBZ+r1SJ9my/DM6vfTqJg9FJgVydRJ0lnO+D5NhqGW/qaRG/iBGKr/d4fho34el6WakV7BqJvrl/HQ==} engines: {node: '>= 14.0.0'} '@babel/code-frame@7.27.1': @@ -922,6 +922,12 @@ packages: peerDependencies: postcss: ^8.4 + '@csstools/postcss-position-area-property@1.0.0': + resolution: {integrity: sha512-fUP6KR8qV2NuUZV3Cw8itx0Ep90aRjAZxAEzC3vrl6yjFv+pFsQbR18UuQctEKmA72K9O27CoYiKEgXxkqjg8Q==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + '@csstools/postcss-progressive-custom-properties@4.2.1': resolution: {integrity: sha512-uPiiXf7IEKtUQXsxu6uWtOlRMXd2QWWy5fhxHDnPdXKCQckPP3E34ZgDoZ62r2iT+UOgWsSbM4NvHE5m3mAEdw==} engines: {node: '>=18'} @@ -958,6 +964,12 @@ packages: peerDependencies: postcss: ^8.4 + '@csstools/postcss-system-ui-font-family@1.0.0': + resolution: {integrity: sha512-s3xdBvfWYfoPSBsikDXbuorcMG1nN1M6GdU0qBsGfcmNR0A/qhloQZpTxjA3Xsyrk1VJvwb2pOfiOT3at/DuIQ==} + engines: {node: '>=18'} + peerDependencies: + postcss: ^8.4 + '@csstools/postcss-text-decoration-shorthand@4.0.3': resolution: {integrity: sha512-KSkGgZfx0kQjRIYnpsD7X2Om9BUXX/Kii77VBifQW9Ih929hK0KNjVngHDH0bFB9GmfWcR9vJYJJRvw/NQjkrA==} engines: {node: '>=18'} @@ -1666,8 +1678,8 @@ packages: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} - ai@5.0.106: - resolution: {integrity: sha512-M5obwavxSJJ3tGlAFqI6eltYNJB0D20X6gIBCFx/KVorb/X1fxVVfiZZpZb+Gslu4340droSOjT0aKQFCarNVg==} + ai@5.0.108: + resolution: {integrity: sha512-Jex3Lb7V41NNpuqJHKgrwoU6BCLHdI1Pg4qb4GJH4jRIDRXUBySJErHjyN4oTCwbiYCeb/8II9EnqSRPq9EifA==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 @@ -1701,8 +1713,8 @@ packages: peerDependencies: algoliasearch: '>= 3.1 < 6' - algoliasearch@5.45.0: - resolution: {integrity: sha512-wrj4FGr14heLOYkBKV3Fbq5ZBGuIFeDJkTilYq/G+hH1CSlQBtYvG2X1j67flwv0fUeQJwnWxxRIunSemAZirA==} + algoliasearch@5.46.0: + resolution: {integrity: sha512-7ML6fa2K93FIfifG3GMWhDEwT5qQzPTmoHKCTvhzGEwdbQ4n0yYUWZlLYT75WllTGJCJtNUI0C1ybN4BCegqvg==} engines: {node: '>= 14.0.0'} ansi-align@3.0.1: @@ -1795,8 +1807,8 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - baseline-browser-mapping@2.8.32: - resolution: {integrity: sha512-OPz5aBThlyLFgxyhdwf/s2+8ab3OvT7AdTNvKHBwpXomIYeXqpUUuT8LrdtxZSsWJ4R4CU1un4XGh5Ez3nlTpw==} + baseline-browser-mapping@2.9.4: + resolution: {integrity: sha512-ZCQ9GEWl73BVm8bu5Fts8nt7MHdbt5vY9bP6WGnUh+r3l8M7CgfyTlwsgCbMC66BNxPr6Xoce3j66Ms5YUQTNA==} hasBin: true batch@0.6.1: @@ -1834,8 +1846,8 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.28.0: - resolution: {integrity: sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==} + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -2172,8 +2184,8 @@ packages: resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} engines: {node: '>= 6'} - cssdb@8.4.3: - resolution: {integrity: sha512-8aaDS5nVqMXmYjlmmJpqlDJosiqbl2NJkYuSFOXR6RTY14qNosMrqT4t7O+EUm+OdduQg3GNI2ZwC03No1Y58Q==} + cssdb@8.5.2: + resolution: {integrity: sha512-Pmoj9RmD8RIoIzA2EQWO4D4RMeDts0tgAH0VXdlNdxjuBGI3a9wMOIcUwaPNmD4r2qtIa06gqkIf7sECl+cBCg==} cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} @@ -2355,8 +2367,8 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.263: - resolution: {integrity: sha512-DrqJ11Knd+lo+dv+lltvfMDLU27g14LMdH2b0O3Pio4uk0x+z7OR+JrmyacTPN2M8w3BrZ7/RTwG3R9B7irPlg==} + electron-to-chromium@1.5.266: + resolution: {integrity: sha512-kgWEglXvkEfMH7rxP5OSZZwnaDWT7J9EoZCujhnpLbfi0bbNtRkgdX2E3gt0Uer11c61qCYktB3hwkAS325sJg==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -2738,8 +2750,8 @@ packages: hast-util-to-jsx-runtime@2.3.6: resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} - hast-util-to-parse5@8.0.0: - resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==} + hast-util-to-parse5@8.0.1: + resolution: {integrity: sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==} hast-util-whitespace@3.0.0: resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} @@ -3985,8 +3997,8 @@ packages: peerDependencies: postcss: ^8.4 - postcss-preset-env@10.4.0: - resolution: {integrity: sha512-2kqpOthQ6JhxqQq1FSAAZGe9COQv75Aw8WbsOvQVNJ2nSevc9Yx/IKZGuZ7XJ+iOTtVon7LfO7ELRzg8AZ+sdw==} + postcss-preset-env@10.5.0: + resolution: {integrity: sha512-xgxFQPAPxeWmsgy8cR7GM1PGAL/smA5E9qU7K//D4vucS01es3M0fDujhDJn3kY8Ip7/vVYcecbe1yY+vBo3qQ==} engines: {node: '>=18'} peerDependencies: postcss: ^8.4 @@ -4091,9 +4103,6 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} - property-information@6.5.0: - resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} - property-information@7.1.0: resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} @@ -4618,8 +4627,8 @@ packages: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} - terser-webpack-plugin@5.3.14: - resolution: {integrity: sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==} + terser-webpack-plugin@5.3.15: + resolution: {integrity: sha512-PGkOdpRFK+rb1TzVz+msVhw4YMRT9txLF4kRqvJhGhCM324xuR3REBSHALN+l+sAhKUmz0aotnjp5D+P83mLhQ==} engines: {node: '>= 10.13.0'} peerDependencies: '@swc/core': '*' @@ -4769,8 +4778,8 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - update-browserslist-db@1.1.4: - resolution: {integrity: sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==} + update-browserslist-db@1.2.2: + resolution: {integrity: sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -4996,123 +5005,123 @@ snapshots: dependencies: json-schema: 0.4.0 - '@ai-sdk/react@2.0.106(react@19.2.1)(zod@4.1.13)': + '@ai-sdk/react@2.0.109(react@19.2.1)(zod@4.1.13)': dependencies: '@ai-sdk/provider-utils': 3.0.18(zod@4.1.13) - ai: 5.0.106(zod@4.1.13) + ai: 5.0.108(zod@4.1.13) react: 19.2.1 swr: 2.3.7(react@19.2.1) throttleit: 2.1.0 optionalDependencies: zod: 4.1.13 - '@algolia/abtesting@1.11.0': + '@algolia/abtesting@1.12.0': dependencies: - '@algolia/client-common': 5.45.0 - '@algolia/requester-browser-xhr': 5.45.0 - '@algolia/requester-fetch': 5.45.0 - '@algolia/requester-node-http': 5.45.0 + '@algolia/client-common': 5.46.0 + '@algolia/requester-browser-xhr': 5.46.0 + '@algolia/requester-fetch': 5.46.0 + '@algolia/requester-node-http': 5.46.0 - '@algolia/autocomplete-core@1.19.2(@algolia/client-search@5.45.0)(algoliasearch@5.45.0)(search-insights@2.17.3)': + '@algolia/autocomplete-core@1.19.2(@algolia/client-search@5.46.0)(algoliasearch@5.46.0)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-plugin-algolia-insights': 1.19.2(@algolia/client-search@5.45.0)(algoliasearch@5.45.0)(search-insights@2.17.3) - '@algolia/autocomplete-shared': 1.19.2(@algolia/client-search@5.45.0)(algoliasearch@5.45.0) + '@algolia/autocomplete-plugin-algolia-insights': 1.19.2(@algolia/client-search@5.46.0)(algoliasearch@5.46.0)(search-insights@2.17.3) + '@algolia/autocomplete-shared': 1.19.2(@algolia/client-search@5.46.0)(algoliasearch@5.46.0) transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - search-insights - '@algolia/autocomplete-plugin-algolia-insights@1.19.2(@algolia/client-search@5.45.0)(algoliasearch@5.45.0)(search-insights@2.17.3)': + '@algolia/autocomplete-plugin-algolia-insights@1.19.2(@algolia/client-search@5.46.0)(algoliasearch@5.46.0)(search-insights@2.17.3)': dependencies: - '@algolia/autocomplete-shared': 1.19.2(@algolia/client-search@5.45.0)(algoliasearch@5.45.0) + '@algolia/autocomplete-shared': 1.19.2(@algolia/client-search@5.46.0)(algoliasearch@5.46.0) search-insights: 2.17.3 transitivePeerDependencies: - '@algolia/client-search' - algoliasearch - '@algolia/autocomplete-shared@1.19.2(@algolia/client-search@5.45.0)(algoliasearch@5.45.0)': + '@algolia/autocomplete-shared@1.19.2(@algolia/client-search@5.46.0)(algoliasearch@5.46.0)': dependencies: - '@algolia/client-search': 5.45.0 - algoliasearch: 5.45.0 + '@algolia/client-search': 5.46.0 + algoliasearch: 5.46.0 - '@algolia/client-abtesting@5.45.0': + '@algolia/client-abtesting@5.46.0': dependencies: - '@algolia/client-common': 5.45.0 - '@algolia/requester-browser-xhr': 5.45.0 - '@algolia/requester-fetch': 5.45.0 - '@algolia/requester-node-http': 5.45.0 + '@algolia/client-common': 5.46.0 + '@algolia/requester-browser-xhr': 5.46.0 + '@algolia/requester-fetch': 5.46.0 + '@algolia/requester-node-http': 5.46.0 - '@algolia/client-analytics@5.45.0': + '@algolia/client-analytics@5.46.0': dependencies: - '@algolia/client-common': 5.45.0 - '@algolia/requester-browser-xhr': 5.45.0 - '@algolia/requester-fetch': 5.45.0 - '@algolia/requester-node-http': 5.45.0 + '@algolia/client-common': 5.46.0 + '@algolia/requester-browser-xhr': 5.46.0 + '@algolia/requester-fetch': 5.46.0 + '@algolia/requester-node-http': 5.46.0 - '@algolia/client-common@5.45.0': {} + '@algolia/client-common@5.46.0': {} - '@algolia/client-insights@5.45.0': + '@algolia/client-insights@5.46.0': dependencies: - '@algolia/client-common': 5.45.0 - '@algolia/requester-browser-xhr': 5.45.0 - '@algolia/requester-fetch': 5.45.0 - '@algolia/requester-node-http': 5.45.0 + '@algolia/client-common': 5.46.0 + '@algolia/requester-browser-xhr': 5.46.0 + '@algolia/requester-fetch': 5.46.0 + '@algolia/requester-node-http': 5.46.0 - '@algolia/client-personalization@5.45.0': + '@algolia/client-personalization@5.46.0': dependencies: - '@algolia/client-common': 5.45.0 - '@algolia/requester-browser-xhr': 5.45.0 - '@algolia/requester-fetch': 5.45.0 - '@algolia/requester-node-http': 5.45.0 + '@algolia/client-common': 5.46.0 + '@algolia/requester-browser-xhr': 5.46.0 + '@algolia/requester-fetch': 5.46.0 + '@algolia/requester-node-http': 5.46.0 - '@algolia/client-query-suggestions@5.45.0': + '@algolia/client-query-suggestions@5.46.0': dependencies: - '@algolia/client-common': 5.45.0 - '@algolia/requester-browser-xhr': 5.45.0 - '@algolia/requester-fetch': 5.45.0 - '@algolia/requester-node-http': 5.45.0 + '@algolia/client-common': 5.46.0 + '@algolia/requester-browser-xhr': 5.46.0 + '@algolia/requester-fetch': 5.46.0 + '@algolia/requester-node-http': 5.46.0 - '@algolia/client-search@5.45.0': + '@algolia/client-search@5.46.0': dependencies: - '@algolia/client-common': 5.45.0 - '@algolia/requester-browser-xhr': 5.45.0 - '@algolia/requester-fetch': 5.45.0 - '@algolia/requester-node-http': 5.45.0 + '@algolia/client-common': 5.46.0 + '@algolia/requester-browser-xhr': 5.46.0 + '@algolia/requester-fetch': 5.46.0 + '@algolia/requester-node-http': 5.46.0 '@algolia/events@4.0.1': {} - '@algolia/ingestion@1.45.0': + '@algolia/ingestion@1.46.0': dependencies: - '@algolia/client-common': 5.45.0 - '@algolia/requester-browser-xhr': 5.45.0 - '@algolia/requester-fetch': 5.45.0 - '@algolia/requester-node-http': 5.45.0 + '@algolia/client-common': 5.46.0 + '@algolia/requester-browser-xhr': 5.46.0 + '@algolia/requester-fetch': 5.46.0 + '@algolia/requester-node-http': 5.46.0 - '@algolia/monitoring@1.45.0': + '@algolia/monitoring@1.46.0': dependencies: - '@algolia/client-common': 5.45.0 - '@algolia/requester-browser-xhr': 5.45.0 - '@algolia/requester-fetch': 5.45.0 - '@algolia/requester-node-http': 5.45.0 + '@algolia/client-common': 5.46.0 + '@algolia/requester-browser-xhr': 5.46.0 + '@algolia/requester-fetch': 5.46.0 + '@algolia/requester-node-http': 5.46.0 - '@algolia/recommend@5.45.0': + '@algolia/recommend@5.46.0': dependencies: - '@algolia/client-common': 5.45.0 - '@algolia/requester-browser-xhr': 5.45.0 - '@algolia/requester-fetch': 5.45.0 - '@algolia/requester-node-http': 5.45.0 + '@algolia/client-common': 5.46.0 + '@algolia/requester-browser-xhr': 5.46.0 + '@algolia/requester-fetch': 5.46.0 + '@algolia/requester-node-http': 5.46.0 - '@algolia/requester-browser-xhr@5.45.0': + '@algolia/requester-browser-xhr@5.46.0': dependencies: - '@algolia/client-common': 5.45.0 + '@algolia/client-common': 5.46.0 - '@algolia/requester-fetch@5.45.0': + '@algolia/requester-fetch@5.46.0': dependencies: - '@algolia/client-common': 5.45.0 + '@algolia/client-common': 5.46.0 - '@algolia/requester-node-http@5.45.0': + '@algolia/requester-node-http@5.46.0': dependencies: - '@algolia/client-common': 5.45.0 + '@algolia/client-common': 5.46.0 '@babel/code-frame@7.27.1': dependencies: @@ -5158,7 +5167,7 @@ snapshots: dependencies: '@babel/compat-data': 7.28.5 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.28.0 + browserslist: 4.28.1 lru-cache: 5.1.1 semver: 6.3.1 @@ -6089,6 +6098,10 @@ snapshots: '@csstools/utilities': 2.0.0(postcss@8.5.6) postcss: 8.5.6 + '@csstools/postcss-position-area-property@1.0.0(postcss@8.5.6)': + dependencies: + postcss: 8.5.6 + '@csstools/postcss-progressive-custom-properties@4.2.1(postcss@8.5.6)': dependencies: postcss: 8.5.6 @@ -6129,6 +6142,12 @@ snapshots: '@csstools/css-tokenizer': 3.0.4 postcss: 8.5.6 + '@csstools/postcss-system-ui-font-family@1.0.0(postcss@8.5.6)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + postcss: 8.5.6 + '@csstools/postcss-text-decoration-shorthand@4.0.3(postcss@8.5.6)': dependencies: '@csstools/color-helpers': 5.1.0 @@ -6168,14 +6187,14 @@ snapshots: '@docsearch/css@4.3.2': {} - '@docsearch/react@4.3.2(@algolia/client-search@5.45.0)(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(search-insights@2.17.3)': + '@docsearch/react@4.3.2(@algolia/client-search@5.46.0)(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(search-insights@2.17.3)': dependencies: - '@ai-sdk/react': 2.0.106(react@19.2.1)(zod@4.1.13) - '@algolia/autocomplete-core': 1.19.2(@algolia/client-search@5.45.0)(algoliasearch@5.45.0)(search-insights@2.17.3) + '@ai-sdk/react': 2.0.109(react@19.2.1)(zod@4.1.13) + '@algolia/autocomplete-core': 1.19.2(@algolia/client-search@5.46.0)(algoliasearch@5.46.0)(search-insights@2.17.3) '@docsearch/core': 4.3.1(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1) '@docsearch/css': 4.3.2 - ai: 5.0.106(zod@4.1.13) - algoliasearch: 5.45.0 + ai: 5.0.108(zod@4.1.13) + algoliasearch: 5.46.0 marked: 16.4.2 zod: 4.1.13 optionalDependencies: @@ -6232,8 +6251,8 @@ snapshots: null-loader: 4.0.1(webpack@5.103.0) postcss: 8.5.6 postcss-loader: 7.3.4(postcss@8.5.6)(typescript@5.9.3)(webpack@5.103.0) - postcss-preset-env: 10.4.0(postcss@8.5.6) - terser-webpack-plugin: 5.3.14(webpack@5.103.0) + postcss-preset-env: 10.5.0(postcss@8.5.6) + terser-webpack-plugin: 5.3.15(webpack@5.103.0) tslib: 2.8.1 url-loader: 4.1.1(file-loader@6.2.0(webpack@5.103.0))(webpack@5.103.0) webpack: 5.103.0 @@ -6688,7 +6707,7 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/preset-classic@3.9.2(@algolia/client-search@5.45.0)(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.1))(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(search-insights@2.17.3)(typescript@5.9.3)': + '@docusaurus/preset-classic@3.9.2(@algolia/client-search@5.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.1))(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(search-insights@2.17.3)(typescript@5.9.3)': dependencies: '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(typescript@5.9.3) '@docusaurus/plugin-content-blog': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(typescript@5.9.3))(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(typescript@5.9.3) @@ -6703,7 +6722,7 @@ snapshots: '@docusaurus/plugin-svgr': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(typescript@5.9.3) '@docusaurus/theme-classic': 3.9.2(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(typescript@5.9.3) '@docusaurus/theme-common': 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(typescript@5.9.3))(react-dom@19.2.1(react@19.2.1))(react@19.2.1) - '@docusaurus/theme-search-algolia': 3.9.2(@algolia/client-search@5.45.0)(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.1))(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(search-insights@2.17.3)(typescript@5.9.3) + '@docusaurus/theme-search-algolia': 3.9.2(@algolia/client-search@5.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.1))(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(search-insights@2.17.3)(typescript@5.9.3) '@docusaurus/types': 3.9.2(react-dom@19.2.1(react@19.2.1))(react@19.2.1) react: 19.2.1 react-dom: 19.2.1(react@19.2.1) @@ -6804,9 +6823,9 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/theme-search-algolia@3.9.2(@algolia/client-search@5.45.0)(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.1))(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(search-insights@2.17.3)(typescript@5.9.3)': + '@docusaurus/theme-search-algolia@3.9.2(@algolia/client-search@5.46.0)(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.1))(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(search-insights@2.17.3)(typescript@5.9.3)': dependencies: - '@docsearch/react': 4.3.2(@algolia/client-search@5.45.0)(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(search-insights@2.17.3) + '@docsearch/react': 4.3.2(@algolia/client-search@5.46.0)(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(search-insights@2.17.3) '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(typescript@5.9.3) '@docusaurus/logger': 3.9.2 '@docusaurus/plugin-content-docs': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.7)(react@19.2.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(typescript@5.9.3) @@ -6814,8 +6833,8 @@ snapshots: '@docusaurus/theme-translations': 3.9.2 '@docusaurus/utils': 3.9.2(react-dom@19.2.1(react@19.2.1))(react@19.2.1) '@docusaurus/utils-validation': 3.9.2(react-dom@19.2.1(react@19.2.1))(react@19.2.1) - algoliasearch: 5.45.0 - algoliasearch-helper: 3.26.1(algoliasearch@5.45.0) + algoliasearch: 5.46.0 + algoliasearch-helper: 3.26.1(algoliasearch@5.46.0) clsx: 2.1.1 eta: 2.2.0 fs-extra: 11.3.2 @@ -7495,7 +7514,7 @@ snapshots: clean-stack: 2.2.0 indent-string: 4.0.0 - ai@5.0.106(zod@4.1.13): + ai@5.0.108(zod@4.1.13): dependencies: '@ai-sdk/gateway': 2.0.18(zod@4.1.13) '@ai-sdk/provider': 2.0.0 @@ -7530,27 +7549,27 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - algoliasearch-helper@3.26.1(algoliasearch@5.45.0): + algoliasearch-helper@3.26.1(algoliasearch@5.46.0): dependencies: '@algolia/events': 4.0.1 - algoliasearch: 5.45.0 + algoliasearch: 5.46.0 - algoliasearch@5.45.0: + algoliasearch@5.46.0: dependencies: - '@algolia/abtesting': 1.11.0 - '@algolia/client-abtesting': 5.45.0 - '@algolia/client-analytics': 5.45.0 - '@algolia/client-common': 5.45.0 - '@algolia/client-insights': 5.45.0 - '@algolia/client-personalization': 5.45.0 - '@algolia/client-query-suggestions': 5.45.0 - '@algolia/client-search': 5.45.0 - '@algolia/ingestion': 1.45.0 - '@algolia/monitoring': 1.45.0 - '@algolia/recommend': 5.45.0 - '@algolia/requester-browser-xhr': 5.45.0 - '@algolia/requester-fetch': 5.45.0 - '@algolia/requester-node-http': 5.45.0 + '@algolia/abtesting': 1.12.0 + '@algolia/client-abtesting': 5.46.0 + '@algolia/client-analytics': 5.46.0 + '@algolia/client-common': 5.46.0 + '@algolia/client-insights': 5.46.0 + '@algolia/client-personalization': 5.46.0 + '@algolia/client-query-suggestions': 5.46.0 + '@algolia/client-search': 5.46.0 + '@algolia/ingestion': 1.46.0 + '@algolia/monitoring': 1.46.0 + '@algolia/recommend': 5.46.0 + '@algolia/requester-browser-xhr': 5.46.0 + '@algolia/requester-fetch': 5.46.0 + '@algolia/requester-node-http': 5.46.0 ansi-align@3.0.1: dependencies: @@ -7593,7 +7612,7 @@ snapshots: autoprefixer@10.4.22(postcss@8.5.6): dependencies: - browserslist: 4.28.0 + browserslist: 4.28.1 caniuse-lite: 1.0.30001759 fraction.js: 5.3.4 normalize-range: 0.1.2 @@ -7640,7 +7659,7 @@ snapshots: balanced-match@1.0.2: {} - baseline-browser-mapping@2.8.32: {} + baseline-browser-mapping@2.9.4: {} batch@0.6.1: {} @@ -7703,13 +7722,13 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.28.0: + browserslist@4.28.1: dependencies: - baseline-browser-mapping: 2.8.32 + baseline-browser-mapping: 2.9.4 caniuse-lite: 1.0.30001759 - electron-to-chromium: 1.5.263 + electron-to-chromium: 1.5.266 node-releases: 2.0.27 - update-browserslist-db: 1.1.4(browserslist@4.28.0) + update-browserslist-db: 1.2.2(browserslist@4.28.1) buffer-from@1.1.2: {} @@ -7763,7 +7782,7 @@ snapshots: caniuse-api@3.0.0: dependencies: - browserslist: 4.28.0 + browserslist: 4.28.1 caniuse-lite: 1.0.30001759 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 @@ -7935,7 +7954,7 @@ snapshots: core-js-compat@3.47.0: dependencies: - browserslist: 4.28.0 + browserslist: 4.28.1 core-js-pure@3.47.0: {} @@ -8035,14 +8054,14 @@ snapshots: css-what@6.2.2: {} - cssdb@8.4.3: {} + cssdb@8.5.2: {} cssesc@3.0.0: {} cssnano-preset-advanced@6.1.2(postcss@8.5.6): dependencies: autoprefixer: 10.4.22(postcss@8.5.6) - browserslist: 4.28.0 + browserslist: 4.28.1 cssnano-preset-default: 6.1.2(postcss@8.5.6) postcss: 8.5.6 postcss-discard-unused: 6.0.5(postcss@8.5.6) @@ -8052,7 +8071,7 @@ snapshots: cssnano-preset-default@6.1.2(postcss@8.5.6): dependencies: - browserslist: 4.28.0 + browserslist: 4.28.1 css-declaration-sorter: 7.3.0(postcss@8.5.6) cssnano-utils: 4.0.2(postcss@8.5.6) postcss: 8.5.6 @@ -8235,7 +8254,7 @@ snapshots: ee-first@1.1.1: {} - electron-to-chromium@1.5.263: {} + electron-to-chromium@1.5.266: {} emoji-regex@8.0.0: {} @@ -8645,7 +8664,7 @@ snapshots: '@types/unist': 3.0.3 '@ungap/structured-clone': 1.3.0 hast-util-from-parse5: 8.0.3 - hast-util-to-parse5: 8.0.0 + hast-util-to-parse5: 8.0.1 html-void-elements: 3.0.0 mdast-util-to-hast: 13.2.1 parse5: 7.3.0 @@ -8696,12 +8715,12 @@ snapshots: transitivePeerDependencies: - supports-color - hast-util-to-parse5@8.0.0: + hast-util-to-parse5@8.0.1: dependencies: '@types/hast': 3.0.4 comma-separated-tokens: 2.0.3 devlop: 1.1.0 - property-information: 6.5.0 + property-information: 7.1.0 space-separated-tokens: 2.0.2 web-namespaces: 2.0.1 zwitch: 2.0.4 @@ -9914,7 +9933,7 @@ snapshots: postcss-colormin@6.1.0(postcss@8.5.6): dependencies: - browserslist: 4.28.0 + browserslist: 4.28.1 caniuse-api: 3.0.0 colord: 2.9.3 postcss: 8.5.6 @@ -9922,7 +9941,7 @@ snapshots: postcss-convert-values@6.1.0(postcss@8.5.6): dependencies: - browserslist: 4.28.0 + browserslist: 4.28.1 postcss: 8.5.6 postcss-value-parser: 4.2.0 @@ -10046,7 +10065,7 @@ snapshots: postcss-merge-rules@6.1.1(postcss@8.5.6): dependencies: - browserslist: 4.28.0 + browserslist: 4.28.1 caniuse-api: 3.0.0 cssnano-utils: 4.0.2(postcss@8.5.6) postcss: 8.5.6 @@ -10066,7 +10085,7 @@ snapshots: postcss-minify-params@6.1.0(postcss@8.5.6): dependencies: - browserslist: 4.28.0 + browserslist: 4.28.1 cssnano-utils: 4.0.2(postcss@8.5.6) postcss: 8.5.6 postcss-value-parser: 4.2.0 @@ -10135,7 +10154,7 @@ snapshots: postcss-normalize-unicode@6.1.0(postcss@8.5.6): dependencies: - browserslist: 4.28.0 + browserslist: 4.28.1 postcss: 8.5.6 postcss-value-parser: 4.2.0 @@ -10173,7 +10192,7 @@ snapshots: postcss: 8.5.6 postcss-value-parser: 4.2.0 - postcss-preset-env@10.4.0(postcss@8.5.6): + postcss-preset-env@10.5.0(postcss@8.5.6): dependencies: '@csstools/postcss-alpha-function': 1.0.1(postcss@8.5.6) '@csstools/postcss-cascade-layers': 5.0.2(postcss@8.5.6) @@ -10202,21 +10221,23 @@ snapshots: '@csstools/postcss-nested-calc': 4.0.0(postcss@8.5.6) '@csstools/postcss-normalize-display-values': 4.0.0(postcss@8.5.6) '@csstools/postcss-oklab-function': 4.0.12(postcss@8.5.6) + '@csstools/postcss-position-area-property': 1.0.0(postcss@8.5.6) '@csstools/postcss-progressive-custom-properties': 4.2.1(postcss@8.5.6) '@csstools/postcss-random-function': 2.0.1(postcss@8.5.6) '@csstools/postcss-relative-color-syntax': 3.0.12(postcss@8.5.6) '@csstools/postcss-scope-pseudo-class': 4.0.1(postcss@8.5.6) '@csstools/postcss-sign-functions': 1.1.4(postcss@8.5.6) '@csstools/postcss-stepped-value-functions': 4.0.9(postcss@8.5.6) + '@csstools/postcss-system-ui-font-family': 1.0.0(postcss@8.5.6) '@csstools/postcss-text-decoration-shorthand': 4.0.3(postcss@8.5.6) '@csstools/postcss-trigonometric-functions': 4.0.9(postcss@8.5.6) '@csstools/postcss-unset-value': 4.0.0(postcss@8.5.6) autoprefixer: 10.4.22(postcss@8.5.6) - browserslist: 4.28.0 + browserslist: 4.28.1 css-blank-pseudo: 7.0.1(postcss@8.5.6) css-has-pseudo: 7.0.3(postcss@8.5.6) css-prefers-color-scheme: 10.0.0(postcss@8.5.6) - cssdb: 8.4.3 + cssdb: 8.5.2 postcss: 8.5.6 postcss-attribute-case-insensitive: 7.0.1(postcss@8.5.6) postcss-clamp: 4.1.0(postcss@8.5.6) @@ -10256,7 +10277,7 @@ snapshots: postcss-reduce-initial@6.1.0(postcss@8.5.6): dependencies: - browserslist: 4.28.0 + browserslist: 4.28.1 caniuse-api: 3.0.0 postcss: 8.5.6 @@ -10340,8 +10361,6 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 - property-information@6.5.0: {} - property-information@7.1.0: {} proto-list@1.2.4: {} @@ -10962,7 +10981,7 @@ snapshots: stylehacks@6.1.1(postcss@8.5.6): dependencies: - browserslist: 4.28.0 + browserslist: 4.28.1 postcss: 8.5.6 postcss-selector-parser: 6.1.2 @@ -10996,7 +11015,7 @@ snapshots: tapable@2.3.0: {} - terser-webpack-plugin@5.3.14(webpack@5.103.0): + terser-webpack-plugin@5.3.15(webpack@5.103.0): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 @@ -11121,9 +11140,9 @@ snapshots: unpipe@1.0.0: {} - update-browserslist-db@1.1.4(browserslist@4.28.0): + update-browserslist-db@1.2.2(browserslist@4.28.1): dependencies: - browserslist: 4.28.0 + browserslist: 4.28.1 escalade: 3.2.0 picocolors: 1.1.1 @@ -11292,7 +11311,7 @@ snapshots: '@webassemblyjs/wasm-parser': 1.14.1 acorn: 8.15.0 acorn-import-phases: 1.0.4(acorn@8.15.0) - browserslist: 4.28.0 + browserslist: 4.28.1 chrome-trace-event: 1.0.4 enhanced-resolve: 5.18.3 es-module-lexer: 1.7.0 @@ -11306,7 +11325,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.0 - terser-webpack-plugin: 5.3.14(webpack@5.103.0) + terser-webpack-plugin: 5.3.15(webpack@5.103.0) watchpack: 2.4.4 webpack-sources: 3.3.3 transitivePeerDependencies: diff --git a/go.mod b/go.mod index 611b4bc..bcaa3ac 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,9 @@ require ( github.com/gosimple/slug v1.15.0 github.com/hypersequent/zen v0.0.0-20250923135653-056103bb12ce github.com/joeig/go-powerdns/v3 v3.19.0 + github.com/lmittmann/tint v1.1.2 + github.com/mattn/go-colorable v0.1.14 + github.com/mattn/go-isatty v0.0.20 github.com/pressly/goose/v3 v3.26.0 github.com/rs/cors v1.11.1 github.com/stretchr/testify v1.11.1 @@ -104,8 +107,6 @@ require ( github.com/hashicorp/go-version v1.8.0 // indirect github.com/http-wasm/http-wasm-host-go v0.7.0 // indirect github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 // indirect - github.com/mattn/go-colorable v0.1.14 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect github.com/mfridman/interpolate v0.0.2 // indirect github.com/miekg/dns v1.1.68 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect diff --git a/go.sum b/go.sum index c8d6f18..872cd94 100644 --- a/go.sum +++ b/go.sum @@ -72,8 +72,6 @@ github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK3 github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= -github.com/cloudflare/cloudflare-go/v6 v6.3.0 h1:6oL/iTOv1fYe6nVT14gRQWp49EyJxVe+OPrO92c/mmE= -github.com/cloudflare/cloudflare-go/v6 v6.3.0/go.mod h1:Lj3MUqjvKctXRpdRhLQxZYRrNZHuRs0XYuH8JtQGyoI= github.com/cloudflare/cloudflare-go/v6 v6.4.0 h1:uigzhmfDfve+zFAYYWIBOAMEuDoPEJXdPS3NBrEm8/Q= github.com/cloudflare/cloudflare-go/v6 v6.4.0/go.mod h1:Lj3MUqjvKctXRpdRhLQxZYRrNZHuRs0XYuH8JtQGyoI= github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= @@ -214,6 +212,8 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lmittmann/tint v1.1.2 h1:2CQzrL6rslrsyjqLDwD11bZ5OpLBPU+g3G/r5LSfS8w= +github.com/lmittmann/tint v1.1.2/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= @@ -305,10 +305,6 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/traefik/paerser v0.2.2 h1:cpzW/ZrQrBh3mdwD/jnp6aXASiUFKOVr6ldP+keJTcQ= github.com/traefik/paerser v0.2.2/go.mod h1:7BBDd4FANoVgaTZG+yh26jI6CA2nds7D/4VTEdIsh24= -github.com/traefik/traefik/v3 v3.6.2 h1:nR6rGDV8R1kT1BB3n3sPN86d4D8F17ew6sQMVJlTJZ8= -github.com/traefik/traefik/v3 v3.6.2/go.mod h1:82/EIeYGZXjHvBfOizWI4VA1SV39fcVHRKNwDWHTD1w= -github.com/traefik/traefik/v3 v3.6.3 h1:qVuptRtWWgfOAeX1MA8uGDeFR9N+kQ8kpj8cyaLYjGc= -github.com/traefik/traefik/v3 v3.6.3/go.mod h1:zWCc8opV9GZqDsCRDB4/AKkOjdbZe+SPfgAAIZHmBos= github.com/traefik/traefik/v3 v3.6.4 h1:03xDnjdvQ51kLK6YyTJHIEPZ/4F9fSAcDS4lL69SuaE= github.com/traefik/traefik/v3 v3.6.4/go.mod h1:zWCc8opV9GZqDsCRDB4/AKkOjdbZe+SPfgAAIZHmBos= github.com/unrolled/render v1.7.0 h1:1yke01/tZiZpiXfUG+zqB+6fq3G4I+KDmnh0EhPq7So= @@ -423,12 +419,8 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/genproto/googleapis/api v0.0.0-20251124214823-79d6a2a48846 h1:ZdyUkS9po3H7G0tuh955QVyyotWvOD4W0aEapeGeUYk= -google.golang.org/genproto/googleapis/api v0.0.0-20251124214823-79d6a2a48846/go.mod h1:Fk4kyraUvqD7i5H6S43sj2W98fbZa75lpZz/eUyhfO0= google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251124214823-79d6a2a48846 h1:Wgl1rcDNThT+Zn47YyCXOXyX/COgMTIdhJ717F0l4xk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251124214823-79d6a2a48846/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= diff --git a/server/internal/api/handler/oidc.go b/server/internal/api/handler/oidc.go index ef49599..b2f3b3f 100644 --- a/server/internal/api/handler/oidc.go +++ b/server/internal/api/handler/oidc.go @@ -7,6 +7,7 @@ import ( "encoding/base64" "errors" "fmt" + "log/slog" "net/http" "net/url" "regexp" @@ -220,7 +221,7 @@ func OIDCCallback(a *config.App) http.HandlerFunc { } if err := q.UpdateUserLastLogin(r.Context(), user.ID); err != nil { - fmt.Printf("Failed to update last login for user %s: %v\n", user.Username, err) + slog.Warn("Failed to update last login for user", "user", user.Username, "error", err) } http.SetCookie(w, &http.Cookie{ diff --git a/server/internal/api/service/router_ops.go b/server/internal/api/service/router_ops.go index 4951ab6..b77ec5f 100644 --- a/server/internal/api/service/router_ops.go +++ b/server/internal/api/service/router_ops.go @@ -97,7 +97,10 @@ func (s *HTTPRouterOps) Create( if err != nil { return nil, err } - params.Config.Service = params.Name + // Use router name as fallback + if params.Config.Service == "" { + params.Config.Service = params.Name + } // Add default DNS provider @@ -119,7 +122,7 @@ func (s *HTTPRouterOps) Create( } go func() { - if err := s.app.DNS.UpdateDNS(ctx); err != nil { + if err := s.app.DNS.UpdateDNS(); err != nil { slog.Error("failed to update DNS record", "error", err) } }() @@ -150,7 +153,10 @@ func (s *HTTPRouterOps) Update( if err != nil { return nil, err } - params.Config.Service = params.Name + // Use router name as fallback + if params.Config.Service == "" { + params.Config.Service = params.Name + } // Update DNS Providers existing, err := s.app.Conn.GetQuery().GetDnsProvidersByHttpRouter(ctx, params.ID) @@ -185,7 +191,7 @@ func (s *HTTPRouterOps) Update( for id := range existingMap { if !desiredMap[id] { go func() { - if err := s.app.DNS.DeleteDNS(ctx, "http", params.ID); err != nil { + if err := s.app.DNS.DeleteDNS("http", params.ID); err != nil { slog.Error("failed to delete DNS record", "error", err) } }() @@ -235,7 +241,7 @@ func (s *HTTPRouterOps) Delete( return nil, err } go func() { - if err := s.app.DNS.DeleteDNS(ctx, "http", req.Id); err != nil { + if err := s.app.DNS.DeleteDNS("http", req.Id); err != nil { slog.Error("failed to delete DNS record", "error", err) } }() @@ -346,7 +352,10 @@ func (s *TCPRouterOps) Create( if err != nil { return nil, err } - params.Config.Service = params.Name + // Use router name as fallback + if params.Config.Service == "" { + params.Config.Service = params.Name + } result, err := s.app.Conn.GetQuery().CreateTcpRouter(ctx, params) if err != nil { @@ -379,7 +388,10 @@ func (s *TCPRouterOps) Update( if err != nil { return nil, err } - params.Config.Service = params.Name + // Use router name as fallback + if params.Config.Service == "" { + params.Config.Service = params.Name + } // Update DNS Providers existing, err := s.app.Conn.GetQuery().GetDnsProvidersByTcpRouter(ctx, params.ID) @@ -401,7 +413,7 @@ func (s *TCPRouterOps) Update( for _, id := range desiredIDs { if !existingMap[id] { go func() { - if err := s.app.DNS.UpdateDNS(ctx); err != nil { + if err := s.app.DNS.UpdateDNS(); err != nil { slog.Error("failed to update DNS record", "error", err) } }() @@ -419,7 +431,7 @@ func (s *TCPRouterOps) Update( for id := range existingMap { if !desiredMap[id] { go func() { - if err := s.app.DNS.DeleteDNS(ctx, "tcp", params.ID); err != nil { + if err := s.app.DNS.DeleteDNS("tcp", params.ID); err != nil { slog.Error("failed to delete DNS record", "error", err) } }() @@ -459,16 +471,17 @@ func (s *TCPRouterOps) Delete( return nil, err } go func() { - if err := s.app.DNS.DeleteDNS(ctx, "tcp", req.Id); err != nil { + if err := s.app.DNS.DeleteDNS("tcp", req.Id); err != nil { slog.Error("failed to delete DNS record", "error", err) } }() if router.Config.Service != "" { - service, err := s.app.Conn.GetQuery().GetTcpServiceByName(ctx, &db.GetTcpServiceByNameParams{ - ProfileID: router.ProfileID, - Name: router.Config.Service, - }) + service, err := s.app.Conn.GetQuery(). + GetTcpServiceByName(ctx, &db.GetTcpServiceByNameParams{ + ProfileID: router.ProfileID, + Name: router.Config.Service, + }) if err != nil { slog.Error("failed to get tcp service", "err", err) } @@ -561,7 +574,10 @@ func (s *UDPRouterOps) Create( if err != nil { return nil, err } - params.Config.Service = params.Name + // Use router name as fallback + if params.Config.Service == "" { + params.Config.Service = params.Name + } result, err := s.app.Conn.GetQuery().CreateUdpRouter(ctx, params) if err != nil { @@ -594,7 +610,10 @@ func (s *UDPRouterOps) Update( if err != nil { return nil, err } - params.Config.Service = params.Name + // Use router name as fallback + if params.Config.Service == "" { + params.Config.Service = params.Name + } result, err := s.app.Conn.GetQuery().UpdateUdpRouter(ctx, params) if err != nil { @@ -621,10 +640,11 @@ func (s *UDPRouterOps) Delete( return nil, err } if router.Config.Service != "" { - service, err := s.app.Conn.GetQuery().GetUdpServiceByName(ctx, &db.GetUdpServiceByNameParams{ - ProfileID: router.ProfileID, - Name: router.Config.Service, - }) + service, err := s.app.Conn.GetQuery(). + GetUdpServiceByName(ctx, &db.GetUdpServiceByNameParams{ + ProfileID: router.ProfileID, + Name: router.Config.Service, + }) if err != nil { slog.Error("failed to get udp service", "err", err) } diff --git a/server/internal/dns/client.go b/server/internal/dns/client.go index aa9e6ed..3992f27 100644 --- a/server/internal/dns/client.go +++ b/server/internal/dns/client.go @@ -6,6 +6,7 @@ import ( "fmt" "log/slog" "sync" + "time" "github.com/mizuchilabs/mantrae/pkg/util" mantraev1 "github.com/mizuchilabs/mantrae/proto/gen/mantrae/v1" @@ -44,11 +45,11 @@ func NewManager(conn *store.Connection, secret string) *DNSManager { } // UpdateDNS updates the DNS records for all locally managed domains -func (d *DNSManager) UpdateDNS(ctx context.Context) (err error) { +func (d *DNSManager) UpdateDNS() (err error) { d.mu.Lock() defer d.mu.Unlock() - domainMap, err := d.getDomainConfig(ctx) + domainMap, err := d.getDomainConfig() if err != nil { return err } @@ -70,10 +71,13 @@ func (d *DNSManager) UpdateDNS(ctx context.Context) (err error) { } // DeleteDNS deletes the DNS record for a router if it's managed by us -func (d *DNSManager) DeleteDNS(ctx context.Context, proto, routerID string) error { +func (d *DNSManager) DeleteDNS(proto, routerID string) error { d.mu.Lock() defer d.mu.Unlock() + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + switch proto { case "http": router, err := d.conn.GetQuery().GetHttpRouter(ctx, routerID) @@ -148,7 +152,10 @@ func (d *DNSManager) getProvider(id string) (DNSProvider, error) { return nil, fmt.Errorf("invalid provider id") } - provider, err := d.conn.GetQuery().GetDnsProvider(context.Background(), id) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + provider, err := d.conn.GetQuery().GetDnsProvider(ctx, id) if err != nil { return nil, err } @@ -193,7 +200,7 @@ func (d *DNSManager) getProvider(id string) (DNSProvider, error) { } // Result: map from domain → slice of provider info -func (d *DNSManager) getDomainConfig(ctx context.Context) (map[string][]DNSRouterInfo, error) { +func (d *DNSManager) getDomainConfig() (map[string][]DNSRouterInfo, error) { domainMap := make(map[string][]DNSRouterInfo) process := func( @@ -230,7 +237,7 @@ func (d *DNSManager) getDomainConfig(ctx context.Context) (map[string][]DNSRoute } // HTTP - if httpRouters, err := d.conn.GetQuery().GetHttpRouterDomains(ctx); err != nil { + if httpRouters, err := d.conn.GetQuery().GetHttpRouterDomains(context.Background()); err != nil { return nil, err } else { for _, r := range httpRouters { @@ -244,7 +251,7 @@ func (d *DNSManager) getDomainConfig(ctx context.Context) (map[string][]DNSRoute } // TCP - if tcpRouters, err := d.conn.GetQuery().GetTcpRouterDomains(ctx); err != nil { + if tcpRouters, err := d.conn.GetQuery().GetTcpRouterDomains(context.Background()); err != nil { return nil, err } else { for _, r := range tcpRouters { diff --git a/server/internal/store/connection.go b/server/internal/store/connection.go index 63ec971..f6506c1 100644 --- a/server/internal/store/connection.go +++ b/server/internal/store/connection.go @@ -70,10 +70,9 @@ func configureSQLite(db *sql.DB) error { return fmt.Errorf("executing pragmas: %w", err) } - db.SetMaxOpenConns(10) // Allow multiple concurrent connections - db.SetMaxIdleConns(5) // Keep some connections alive - db.SetConnMaxLifetime(0) // Reuse connections indefinitely - db.SetConnMaxIdleTime(5 * time.Minute) // Close idle connections after 5min + db.SetMaxOpenConns(1) // Single connection + db.SetMaxIdleConns(1) // Keep some connections alive + db.SetConnMaxLifetime(0) // Reuse connections indefinitely return nil } diff --git a/server/internal/tasks/tasks.go b/server/internal/tasks/tasks.go index 7cdcffb..6049df3 100644 --- a/server/internal/tasks/tasks.go +++ b/server/internal/tasks/tasks.go @@ -38,7 +38,7 @@ func (s *Scheduler) syncDNS() { defer ticker.Stop() manager := dns.NewManager(s.cfg.Conn, s.cfg.Secret) - if err := manager.UpdateDNS(s.ctx); err != nil { + if err := manager.UpdateDNS(); err != nil { slog.Error("Failed to update DNS", "error", err) } for { @@ -46,7 +46,7 @@ func (s *Scheduler) syncDNS() { case <-s.ctx.Done(): return case <-ticker.C: - if err := manager.UpdateDNS(s.ctx); err != nil { + if err := manager.UpdateDNS(); err != nil { slog.Error("Failed to update DNS", "error", err) } } diff --git a/web/package.json b/web/package.json index 7c779ec..56ec960 100644 --- a/web/package.json +++ b/web/package.json @@ -15,7 +15,7 @@ "@connectrpc/connect": "^2.1.1", "@connectrpc/connect-web": "^2.1.1", "@internationalized/date": "^3.10.0", - "@lucide/svelte": "^0.555.0", + "@lucide/svelte": "^0.556.0", "@sveltejs/adapter-static": "^3.0.10", "@sveltejs/kit": "^2.49.1", "@sveltejs/vite-plugin-svelte": "^6.2.1", @@ -28,12 +28,12 @@ "globals": "^16.5.0", "mode-watcher": "^1.1.0", "oxlint": "^1.31.0", - "oxlint-tsgolint": "^0.8.3", + "oxlint-tsgolint": "^0.8.4", "prettier": "^3.7.4", "prettier-plugin-svelte": "^3.4.0", "prettier-plugin-tailwindcss": "^0.7.2", "shiki": "^3.19.0", - "svelte": "^5.45.4", + "svelte": "^5.45.6", "svelte-check": "^4.3.4", "svelte-highlight": "^7.9.0", "svelte-sonner": "^1.0.7", @@ -43,8 +43,8 @@ "tailwindcss": "^4.1.17", "tw-animate-css": "^1.4.0", "typescript": "^5.9.3", - "vite": "^7.2.6", - "vite-plugin-compression2": "^2.3.1", + "vite": "^7.2.7", + "vite-plugin-compression2": "^2.4.0", "yaml": "^2.8.2", "zod": "^4.1.13" }, diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 9f70fd0..4d0440c 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -34,35 +34,35 @@ importers: specifier: ^3.10.0 version: 3.10.0 '@lucide/svelte': - specifier: ^0.555.0 - version: 0.555.0(svelte@5.45.6) + specifier: ^0.556.0 + version: 0.556.0(svelte@5.45.6) '@sveltejs/adapter-static': specifier: ^3.0.10 - version: 3.0.10(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))) + version: 3.0.10(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))) '@sveltejs/kit': specifier: ^2.49.1 - version: 2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) + version: 2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) '@sveltejs/vite-plugin-svelte': specifier: ^6.2.1 - version: 6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) + version: 6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) '@tailwindcss/typography': specifier: ^0.5.19 version: 0.5.19(tailwindcss@4.1.17) '@tailwindcss/vite': specifier: ^4.1.17 - version: 4.1.17(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) + version: 4.1.17(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) '@types/node': specifier: ^24.10.1 version: 24.10.1 bits-ui: specifier: 2.14.4 - version: 2.14.4(@internationalized/date@3.10.0)(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6) + version: 2.14.4(@internationalized/date@3.10.0)(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6) clsx: specifier: ^2.1.1 version: 2.1.1 formsnap: specifier: ^2.0.1 - version: 2.0.1(svelte@5.45.6)(sveltekit-superforms@2.28.1(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(@types/json-schema@7.0.15)(esbuild@0.25.12)(svelte@5.45.6)(typescript@5.9.3)) + version: 2.0.1(svelte@5.45.6)(sveltekit-superforms@2.28.1(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(@types/json-schema@7.0.15)(esbuild@0.25.12)(svelte@5.45.6)(typescript@5.9.3)) globals: specifier: ^16.5.0 version: 16.5.0 @@ -71,10 +71,10 @@ importers: version: 1.1.0(svelte@5.45.6) oxlint: specifier: ^1.31.0 - version: 1.31.0(oxlint-tsgolint@0.8.3) + version: 1.31.0(oxlint-tsgolint@0.8.4) oxlint-tsgolint: - specifier: ^0.8.3 - version: 0.8.3 + specifier: ^0.8.4 + version: 0.8.4 prettier: specifier: ^3.7.4 version: 3.7.4 @@ -88,7 +88,7 @@ importers: specifier: ^3.19.0 version: 3.19.0 svelte: - specifier: ^5.45.4 + specifier: ^5.45.6 version: 5.45.6 svelte-check: specifier: ^4.3.4 @@ -101,7 +101,7 @@ importers: version: 1.0.7(svelte@5.45.6) sveltekit-superforms: specifier: ^2.28.1 - version: 2.28.1(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(@types/json-schema@7.0.15)(esbuild@0.25.12)(svelte@5.45.6)(typescript@5.9.3) + version: 2.28.1(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(@types/json-schema@7.0.15)(esbuild@0.25.12)(svelte@5.45.6)(typescript@5.9.3) tailwind-merge: specifier: ^3.4.0 version: 3.4.0 @@ -118,10 +118,10 @@ importers: specifier: ^5.9.3 version: 5.9.3 vite: - specifier: ^7.2.6 - version: 7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2) + specifier: ^7.2.7 + version: 7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2) vite-plugin-compression2: - specifier: ^2.3.1 + specifier: ^2.4.0 version: 2.4.0(rollup@4.53.3) yaml: specifier: ^2.8.2 @@ -365,38 +365,38 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@lucide/svelte@0.555.0': - resolution: {integrity: sha512-aqTOMjBjf/HNwrhggRdb83T0QslZdpJTyTwr/chtXTGw7u4Hcu4zQb/5uA+csF0KKawKWVnsNI1MdHEHeEXTcQ==} + '@lucide/svelte@0.556.0': + resolution: {integrity: sha512-jsJhyyd2xrJ4WtflO5TrTtyCBacF4OLBNCzotvwh4zfbbuE6aqdblx+OB0zg6zOno06ib1GJGdDcfR/2TUcb7g==} peerDependencies: svelte: ^5 - '@oxlint-tsgolint/darwin-arm64@0.8.3': - resolution: {integrity: sha512-BhCcCtddJyQL1fvkGmQqqLfZzJg3vRHMHz0x06juPJupo/3HQOEz46iUXlfLiW1SbcwiRSzxWRGLXM3TiVxNPg==} + '@oxlint-tsgolint/darwin-arm64@0.8.4': + resolution: {integrity: sha512-aygL+K1tOIDXkGncB8q6DbwQjK6CD81sfsUNmhQUcYNNgpOAc88BWyCR3Si8/nlu4sQOdydmfjeVJqJsHaQUxQ==} cpu: [arm64] os: [darwin] - '@oxlint-tsgolint/darwin-x64@0.8.3': - resolution: {integrity: sha512-PqA/jb+zdR31fLvQnQ1TRm/pDEmYhPUn504+UxBu8EfuYWxDeRXr7E34PphJpYwE+RlqKLfthbuYVbVaGjx6yw==} + '@oxlint-tsgolint/darwin-x64@0.8.4': + resolution: {integrity: sha512-rc4iOtwir3eK+f4eh8EzYyVvtwNlkIP+7WkVfkFydNJ1wzzrAZvn2TT1C9U6vcFaaDp2aDM3jie3ZwmMghQxbA==} cpu: [x64] os: [darwin] - '@oxlint-tsgolint/linux-arm64@0.8.3': - resolution: {integrity: sha512-Dk62XzusCxnnEG82AB10LWpGq2ikdsjk9r0C9k5u8SUGfbXDID27Jbo9NCG0/ob+uG/SGdJKGAuY9rVYXO0/Mg==} + '@oxlint-tsgolint/linux-arm64@0.8.4': + resolution: {integrity: sha512-Wbdr640YAG7++2GAeHGDDijA69XwC3xQRp4hgaz6wR+JK6VWXQpeaHKW8v9axNLH9AVlnjUbEpZSh2MPkOpF3Q==} cpu: [arm64] os: [linux] - '@oxlint-tsgolint/linux-x64@0.8.3': - resolution: {integrity: sha512-yKNhHL1r2Xl59Av8UmE0ZeA89SojTyK/ByNleFhGFhLzIvEGJHFbC7jMGHMokfnrh73tR83g8KHNEz6iP8Iw/w==} + '@oxlint-tsgolint/linux-x64@0.8.4': + resolution: {integrity: sha512-nWg57xz4xA++COoEb26RnwiMOOA+wfzipOSfqz/xSCwEXQDKryXfYMl7no7a3MsneHP2f4/JbOrDHbYishm3rw==} cpu: [x64] os: [linux] - '@oxlint-tsgolint/win32-arm64@0.8.3': - resolution: {integrity: sha512-UC2oUZ2MtaJ7jWP0kHtzx4Rkw+nTykGtncv72xKphFooKJWXi4MSQuVQ7RTsbmZa4poPYkYW1vaQayQU8Q586Q==} + '@oxlint-tsgolint/win32-arm64@0.8.4': + resolution: {integrity: sha512-LwRTv/30zlms4BaJrfW+ZnihdIvOku0Rrdo0FfMwSt7HlYfZdoB1yibTkC8yLfRlnbxyR0d57AQPjRasKAgyyQ==} cpu: [arm64] os: [win32] - '@oxlint-tsgolint/win32-x64@0.8.3': - resolution: {integrity: sha512-EACSsZjLe7l8VYXIGZGuqrJMIZymE/zDsmaQRy1MXeuWqg4F89zKh7b7KTBCiOLpkapkHiVWGCPqkoVZ2Lyvnw==} + '@oxlint-tsgolint/win32-x64@0.8.4': + resolution: {integrity: sha512-jg2OezQ4Wwe+B3bOAUWH3CQdu/r5XtYwG/mwmgueL4KLmbJyO47w40hjBESHHgD8057BuHhJrf7lZpZN80bdzw==} cpu: [x64] os: [win32] @@ -891,8 +891,8 @@ packages: dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} - effect@3.19.8: - resolution: {integrity: sha512-OmLw8EfH02vdmyU2fO4uY9He/wepwKI5E/JNpE2pseaWWUbaYOK9UlxIiKP20ZEqQr+S/jSqRDGmpiqD/2DeCQ==} + effect@3.19.9: + resolution: {integrity: sha512-taMXnfG/p+j7AmMOHHQaCHvjqwu9QBO3cxuZqL2dMG/yWcEMw0ZHruHe9B49OxtfKH/vKKDDKRhZ+1GJ2p5R5w==} enhanced-resolve@5.18.3: resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} @@ -1119,8 +1119,8 @@ packages: oniguruma-to-es@4.3.4: resolution: {integrity: sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA==} - oxlint-tsgolint@0.8.3: - resolution: {integrity: sha512-R/pqgXPC4DRQyrODa5xyqiHZNiCcX+R96Bu3qsAMkeSJOKarL8wEszNVNlR+bx8gbWYjPDFuRnlYionTHNjFPA==} + oxlint-tsgolint@0.8.4: + resolution: {integrity: sha512-0eyQ83M0JpeA8a4SPk61xwxBw+N9jMolDCLmzoD9J8HcL3BGTEcOLb5Ud7nCcmM3hSYzO91RqNPHayESG+os2A==} hasBin: true oxlint@1.31.0: @@ -1471,8 +1471,8 @@ packages: vite-plugin-compression2@2.4.0: resolution: {integrity: sha512-8J4CBF1+dM1I06azba/eXJuJHinLF0Am7lUvRH8AZpu0otJoBaDEnxrIEr5iPZJSwH0AEglJGYCveh7pN52jCg==} - vite@7.2.6: - resolution: {integrity: sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==} + vite@7.2.7: + resolution: {integrity: sha512-ITcnkFeR3+fI8P1wMgItjGrR10170d8auB4EpMLPqmx6uxElH3a/hHGQabSHKdqd4FXWO1nFIp9rRn7JQ34ACQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -1703,26 +1703,26 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@lucide/svelte@0.555.0(svelte@5.45.6)': + '@lucide/svelte@0.556.0(svelte@5.45.6)': dependencies: svelte: 5.45.6 - '@oxlint-tsgolint/darwin-arm64@0.8.3': + '@oxlint-tsgolint/darwin-arm64@0.8.4': optional: true - '@oxlint-tsgolint/darwin-x64@0.8.3': + '@oxlint-tsgolint/darwin-x64@0.8.4': optional: true - '@oxlint-tsgolint/linux-arm64@0.8.3': + '@oxlint-tsgolint/linux-arm64@0.8.4': optional: true - '@oxlint-tsgolint/linux-x64@0.8.3': + '@oxlint-tsgolint/linux-x64@0.8.4': optional: true - '@oxlint-tsgolint/win32-arm64@0.8.3': + '@oxlint-tsgolint/win32-arm64@0.8.4': optional: true - '@oxlint-tsgolint/win32-x64@0.8.3': + '@oxlint-tsgolint/win32-x64@0.8.4': optional: true '@oxlint/darwin-arm64@1.31.0': @@ -1878,15 +1878,15 @@ snapshots: dependencies: acorn: 8.15.0 - '@sveltejs/adapter-static@3.0.10(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))': + '@sveltejs/adapter-static@3.0.10(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))': dependencies: - '@sveltejs/kit': 2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) + '@sveltejs/kit': 2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) - '@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))': + '@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))': dependencies: '@standard-schema/spec': 1.0.0 '@sveltejs/acorn-typescript': 1.0.8(acorn@8.15.0) - '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) '@types/cookie': 0.6.0 acorn: 8.15.0 cookie: 0.6.0 @@ -1899,26 +1899,26 @@ snapshots: set-cookie-parser: 2.7.2 sirv: 3.0.2 svelte: 5.45.6 - vite: 7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2) + vite: 7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2) - '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))': + '@sveltejs/vite-plugin-svelte-inspector@5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) + '@sveltejs/vite-plugin-svelte': 6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) debug: 4.4.3 svelte: 5.45.6 - vite: 7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2) + vite: 7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))': + '@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) debug: 4.4.3 deepmerge: 4.3.1 magic-string: 0.30.21 svelte: 5.45.6 - vite: 7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2) - vitefu: 1.1.1(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) + vite: 7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2) + vitefu: 1.1.1(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) transitivePeerDependencies: - supports-color @@ -1992,12 +1992,12 @@ snapshots: postcss-selector-parser: 6.0.10 tailwindcss: 4.1.17 - '@tailwindcss/vite@4.1.17(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))': + '@tailwindcss/vite@4.1.17(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2))': dependencies: '@tailwindcss/node': 4.1.17 '@tailwindcss/oxide': 4.1.17 tailwindcss: 4.1.17 - vite: 7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2) + vite: 7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2) '@tanstack/match-sorter-utils@8.19.4': dependencies: @@ -2078,15 +2078,15 @@ snapshots: axobject-query@4.1.0: {} - bits-ui@2.14.4(@internationalized/date@3.10.0)(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6): + bits-ui@2.14.4(@internationalized/date@3.10.0)(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6): dependencies: '@floating-ui/core': 1.7.3 '@floating-ui/dom': 1.7.4 '@internationalized/date': 3.10.0 esm-env: 1.2.2 - runed: 0.35.1(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6) + runed: 0.35.1(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6) svelte: 5.45.6 - svelte-toolbelt: 0.10.6(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6) + svelte-toolbelt: 0.10.6(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6) tabbable: 6.3.0 transitivePeerDependencies: - '@sveltejs/kit' @@ -2144,7 +2144,7 @@ snapshots: dlv@1.1.3: optional: true - effect@3.19.8: + effect@3.19.9: dependencies: '@standard-schema/spec': 1.0.0 fast-check: 3.23.2 @@ -2208,11 +2208,11 @@ snapshots: optionalDependencies: picomatch: 4.0.3 - formsnap@2.0.1(svelte@5.45.6)(sveltekit-superforms@2.28.1(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(@types/json-schema@7.0.15)(esbuild@0.25.12)(svelte@5.45.6)(typescript@5.9.3)): + formsnap@2.0.1(svelte@5.45.6)(sveltekit-superforms@2.28.1(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(@types/json-schema@7.0.15)(esbuild@0.25.12)(svelte@5.45.6)(typescript@5.9.3)): dependencies: svelte: 5.45.6 svelte-toolbelt: 0.5.0(svelte@5.45.6) - sveltekit-superforms: 2.28.1(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(@types/json-schema@7.0.15)(esbuild@0.25.12)(svelte@5.45.6)(typescript@5.9.3) + sveltekit-superforms: 2.28.1(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(@types/json-schema@7.0.15)(esbuild@0.25.12)(svelte@5.45.6)(typescript@5.9.3) fsevents@2.3.3: optional: true @@ -2384,16 +2384,16 @@ snapshots: regex: 6.0.1 regex-recursion: 6.0.2 - oxlint-tsgolint@0.8.3: + oxlint-tsgolint@0.8.4: optionalDependencies: - '@oxlint-tsgolint/darwin-arm64': 0.8.3 - '@oxlint-tsgolint/darwin-x64': 0.8.3 - '@oxlint-tsgolint/linux-arm64': 0.8.3 - '@oxlint-tsgolint/linux-x64': 0.8.3 - '@oxlint-tsgolint/win32-arm64': 0.8.3 - '@oxlint-tsgolint/win32-x64': 0.8.3 + '@oxlint-tsgolint/darwin-arm64': 0.8.4 + '@oxlint-tsgolint/darwin-x64': 0.8.4 + '@oxlint-tsgolint/linux-arm64': 0.8.4 + '@oxlint-tsgolint/linux-x64': 0.8.4 + '@oxlint-tsgolint/win32-arm64': 0.8.4 + '@oxlint-tsgolint/win32-x64': 0.8.4 - oxlint@1.31.0(oxlint-tsgolint@0.8.3): + oxlint@1.31.0(oxlint-tsgolint@0.8.4): optionalDependencies: '@oxlint/darwin-arm64': 1.31.0 '@oxlint/darwin-x64': 1.31.0 @@ -2403,7 +2403,7 @@ snapshots: '@oxlint/linux-x64-musl': 1.31.0 '@oxlint/win32-arm64': 1.31.0 '@oxlint/win32-x64': 1.31.0 - oxlint-tsgolint: 0.8.3 + oxlint-tsgolint: 0.8.4 picocolors@1.1.1: {} @@ -2498,14 +2498,14 @@ snapshots: esm-env: 1.2.2 svelte: 5.45.6 - runed@0.35.1(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6): + runed@0.35.1(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6): dependencies: dequal: 2.0.3 esm-env: 1.2.2 lz-string: 1.5.0 svelte: 5.45.6 optionalDependencies: - '@sveltejs/kit': 2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) + '@sveltejs/kit': 2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) sade@1.8.1: dependencies: @@ -2576,10 +2576,10 @@ snapshots: runed: 0.28.0(svelte@5.45.6) svelte: 5.45.6 - svelte-toolbelt@0.10.6(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6): + svelte-toolbelt@0.10.6(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6): dependencies: clsx: 2.1.1 - runed: 0.35.1(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6) + runed: 0.35.1(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6) style-to-object: 1.0.14 svelte: 5.45.6 transitivePeerDependencies: @@ -2616,9 +2616,9 @@ snapshots: magic-string: 0.30.21 zimmerframe: 1.1.4 - sveltekit-superforms@2.28.1(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(@types/json-schema@7.0.15)(esbuild@0.25.12)(svelte@5.45.6)(typescript@5.9.3): + sveltekit-superforms@2.28.1(@sveltejs/kit@2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(@types/json-schema@7.0.15)(esbuild@0.25.12)(svelte@5.45.6)(typescript@5.9.3): dependencies: - '@sveltejs/kit': 2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) + '@sveltejs/kit': 2.49.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)))(svelte@5.45.6)(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) devalue: 5.5.0 memoize-weak: 1.0.2 svelte: 5.45.6 @@ -2631,7 +2631,7 @@ snapshots: '@vinejs/vine': 3.0.1 arktype: 2.1.28 class-validator: 0.14.3 - effect: 3.19.8 + effect: 3.19.9 joi: 17.13.3 json-schema-to-ts: 3.1.1 superstruct: 2.0.2 @@ -2752,7 +2752,7 @@ snapshots: transitivePeerDependencies: - rollup - vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2): + vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) @@ -2767,9 +2767,9 @@ snapshots: lightningcss: 1.30.2 yaml: 2.8.2 - vitefu@1.1.1(vite@7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)): + vitefu@1.1.1(vite@7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)): optionalDependencies: - vite: 7.2.6(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2) + vite: 7.2.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2) yaml@2.8.2: {}