diff --git a/go.mod b/go.mod index 40f89eb..f005eb5 100644 --- a/go.mod +++ b/go.mod @@ -4,12 +4,13 @@ go 1.24.0 require ( connectrpc.com/connect v1.18.1 + connectrpc.com/cors v0.1.0 connectrpc.com/grpchealth v1.4.0 connectrpc.com/grpcreflect v1.3.0 - github.com/aws/aws-sdk-go-v2 v1.36.4 - github.com/aws/aws-sdk-go-v2/config v1.29.16 - github.com/aws/aws-sdk-go-v2/credentials v1.17.69 - github.com/aws/aws-sdk-go-v2/service/s3 v1.80.2 + github.com/aws/aws-sdk-go-v2 v1.36.5 + github.com/aws/aws-sdk-go-v2/config v1.29.17 + github.com/aws/aws-sdk-go-v2/credentials v1.17.70 + github.com/aws/aws-sdk-go-v2/service/s3 v1.80.3 github.com/caarlos0/env/v11 v11.3.1 github.com/cloudflare/cloudflare-go v0.115.0 github.com/coreos/go-oidc/v3 v3.14.1 @@ -19,6 +20,7 @@ require ( github.com/google/uuid v1.6.0 github.com/joeig/go-powerdns/v3 v3.16.0 github.com/pressly/goose/v3 v3.24.3 + github.com/rs/cors v1.11.1 github.com/traefik/paerser v0.2.2 github.com/traefik/traefik/v3 v3.4.1 golang.org/x/crypto v0.39.0 @@ -27,25 +29,23 @@ require ( golang.org/x/oauth2 v0.30.0 google.golang.org/protobuf v1.36.6 modernc.org/sqlite v1.38.0 - sigs.k8s.io/yaml v1.4.0 ) require ( - connectrpc.com/cors v0.1.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.31 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.35 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.35 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.35 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.16 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.16 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.25.4 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.2 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.33.21 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.36 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.17 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.25.5 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.34.0 // indirect github.com/aws/smithy-go v1.22.4 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cenkalti/backoff/v5 v5.0.2 // indirect @@ -66,7 +66,7 @@ require ( github.com/google/go-github/v28 v28.1.1 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/gorilla/mux v1.8.1 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.0 // indirect github.com/hashicorp/go-version v1.7.0 // indirect github.com/http-wasm/http-wasm-host-go v0.7.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect @@ -80,7 +80,6 @@ require ( github.com/patrickmn/go-cache v2.1.0+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect - github.com/rs/cors v1.11.1 // indirect github.com/rs/zerolog v1.34.0 // indirect github.com/sethvargo/go-retry v0.3.0 // indirect github.com/unrolled/render v1.7.0 // indirect @@ -109,7 +108,7 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/grpc v1.73.0 // indirect gotest.tools/v3 v3.5.2 // indirect - modernc.org/libc v1.65.10 // indirect + modernc.org/libc v1.66.0 // indirect modernc.org/mathutil v1.7.1 // indirect modernc.org/memory v1.11.0 // indirect ) diff --git a/go.sum b/go.sum index d92ef13..33297aa 100644 --- a/go.sum +++ b/go.sum @@ -12,40 +12,40 @@ github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/aws/aws-sdk-go-v2 v1.36.4 h1:GySzjhVvx0ERP6eyfAbAuAXLtAda5TEy19E5q5W8I9E= -github.com/aws/aws-sdk-go-v2 v1.36.4/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10 h1:zAybnyUQXIZ5mok5Jqwlf58/TFE7uvd3IAsa1aF9cXs= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.10/go.mod h1:qqvMj6gHLR/EXWZw4ZbqlPbQUyenf4h82UQUlKc+l14= -github.com/aws/aws-sdk-go-v2/config v1.29.16 h1:XkruGnXX1nEZ+Nyo9v84TzsX+nj86icbFAeust6uo8A= -github.com/aws/aws-sdk-go-v2/config v1.29.16/go.mod h1:uCW7PNjGwZ5cOGZ5jr8vCWrYkGIhPoTNV23Q/tpHKzg= -github.com/aws/aws-sdk-go-v2/credentials v1.17.69 h1:8B8ZQboRc3uaIKjshve/XlvJ570R7BKNy3gftSbS178= -github.com/aws/aws-sdk-go-v2/credentials v1.17.69/go.mod h1:gPME6I8grR1jCqBFEGthULiolzf/Sexq/Wy42ibKK9c= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.31 h1:oQWSGexYasNpYp4epLGZxxjsDo8BMBh6iNWkTXQvkwk= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.31/go.mod h1:nc332eGUU+djP3vrMI6blS0woaCfHTe3KiSQUVTMRq0= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.35 h1:o1v1VFfPcDVlK3ll1L5xHsaQAFdNtZ5GXnNR7SwueC4= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.35/go.mod h1:rZUQNYMNG+8uZxz9FOerQJ+FceCiodXvixpeRtdESrU= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.35 h1:R5b82ubO2NntENm3SAm0ADME+H630HomNJdgv+yZ3xw= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.35/go.mod h1:FuA+nmgMRfkzVKYDNEqQadvEMxtxl9+RLT9ribCwEMs= +github.com/aws/aws-sdk-go-v2 v1.36.5 h1:0OF9RiEMEdDdZEMqF9MRjevyxAQcf6gY+E7vwBILFj0= +github.com/aws/aws-sdk-go-v2 v1.36.5/go.mod h1:EYrzvCCN9CMUTa5+6lf6MM4tq3Zjp8UhSGR/cBsjai0= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11 h1:12SpdwU8Djs+YGklkinSSlcrPyj3H4VifVsKf78KbwA= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.11/go.mod h1:dd+Lkp6YmMryke+qxW/VnKyhMBDTYP41Q2Bb+6gNZgY= +github.com/aws/aws-sdk-go-v2/config v1.29.17 h1:jSuiQ5jEe4SAMH6lLRMY9OVC+TqJLP5655pBGjmnjr0= +github.com/aws/aws-sdk-go-v2/config v1.29.17/go.mod h1:9P4wwACpbeXs9Pm9w1QTh6BwWwJjwYvJ1iCt5QbCXh8= +github.com/aws/aws-sdk-go-v2/credentials v1.17.70 h1:ONnH5CM16RTXRkS8Z1qg7/s2eDOhHhaXVd72mmyv4/0= +github.com/aws/aws-sdk-go-v2/credentials v1.17.70/go.mod h1:M+lWhhmomVGgtuPOhO85u4pEa3SmssPTdcYpP/5J/xc= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32 h1:KAXP9JSHO1vKGCr5f4O6WmlVKLFFXgWYAGoJosorxzU= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.32/go.mod h1:h4Sg6FQdexC1yYG9RDnOvLbW1a/P986++/Y/a+GyEM8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36 h1:SsytQyTMHMDPspp+spo7XwXTP44aJZZAC7fBV2C5+5s= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.36/go.mod h1:Q1lnJArKRXkenyog6+Y+zr7WDpk4e6XlR6gs20bbeNo= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36 h1:i2vNHQiXUvKhs3quBR6aqlgJaiaexz/aNvdCktW/kAM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.36/go.mod h1:UdyGa7Q91id/sdyHPwth+043HhmP6yP9MBHgbZM0xo8= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.35 h1:th/m+Q18CkajTw1iqx2cKkLCij/uz8NMwJFPK91p2ug= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.35/go.mod h1:dkJuf0a1Bc8HAA0Zm2MoTGm/WDC18Td9vSbrQ1+VqE8= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.3 h1:VHPZakq2L7w+RLzV54LmQavbvheFaR2u1NomJRSEfcU= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.3/go.mod h1:DX1e/lkbsAt0MkY3NgLYuH4jQvRfw8MYxTe9feR7aXM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.16 h1:/ldKrPPXTC421bTNWrUIpq3CxwHwRI/kpc+jPUTJocM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.16/go.mod h1:5vkf/Ws0/wgIMJDQbjI4p2op86hNW6Hie5QtebrDgT8= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.16 h1:2HuI7vWKhFWsBhIr2Zq8KfFZT6xqaId2XXnXZjkbEuc= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.16/go.mod h1:BrwWnsfbFtFeRjdx0iM1ymvlqDX1Oz68JsQaibX/wG8= -github.com/aws/aws-sdk-go-v2/service/s3 v1.80.2 h1:T6Wu+8E2LeTUqzqQ/Bh1EoFNj1u4jUyveMgmTlu9fDU= -github.com/aws/aws-sdk-go-v2/service/s3 v1.80.2/go.mod h1:chSY8zfqmS0OnhZoO/hpPx/BHfAIL80m77HwhRLYScY= -github.com/aws/aws-sdk-go-v2/service/sso v1.25.4 h1:EU58LP8ozQDVroOEyAfcq0cGc5R/FTZjVoYJ6tvby3w= -github.com/aws/aws-sdk-go-v2/service/sso v1.25.4/go.mod h1:CrtOgCcysxMvrCoHnvNAD7PHWclmoFG78Q2xLK0KKcs= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.2 h1:XB4z0hbQtpmBnb1FQYvKaCM7UsS6Y/u8jVBwIUGeCTk= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.2/go.mod h1:hwRpqkRxnQ58J9blRDrB4IanlXCpcKmsC83EhG77upg= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.21 h1:nyLjs8sYJShFYj6aiyjCBI3EcLn1udWrQTjEF+SOXB0= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.21/go.mod h1:EhdxtZ+g84MSGrSrHzZiUm9PYiZkrADNja15wtRJSJo= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.36 h1:GMYy2EOWfzdP3wfVAGXBNKY5vK4K8vMET4sYOYltmqs= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.36/go.mod h1:gDhdAV6wL3PmPqBhiPbnlS447GoWs8HTTOYef9/9Inw= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 h1:CXV68E2dNqhuynZJPB80bhPQwAKqBWVer887figW6Jc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4/go.mod h1:/xFi9KtvBXP97ppCz1TAEvU1Uf66qvid89rbem3wCzQ= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.4 h1:nAP2GYbfh8dd2zGZqFRSMlq+/F6cMPBUuCsGAMkN074= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.7.4/go.mod h1:LT10DsiGjLWh4GbjInf9LQejkYEhBgBCjLG5+lvk4EE= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17 h1:t0E6FzREdtCsiLIoLCWsYliNsRBgyGD/MCK571qk4MI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.17/go.mod h1:ygpklyoaypuyDvOM5ujWGrYWpAK3h7ugnmKCU/76Ys4= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.17 h1:qcLWgdhq45sDM9na4cvXax9dyLitn8EYBRl8Ak4XtG4= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.17/go.mod h1:M+jkjBFZ2J6DJrjMv2+vkBbuht6kxJYtJiwoVgX4p4U= +github.com/aws/aws-sdk-go-v2/service/s3 v1.80.3 h1:jBOwbbIQlfZG079E0YEnfipULNr7wnXbG2gwJyG9hrc= +github.com/aws/aws-sdk-go-v2/service/s3 v1.80.3/go.mod h1:kUklwasNoCn5YpyAqC/97r6dzTA1SRKJfKq16SXeoDU= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.5 h1:AIRJ3lfb2w/1/8wOOSqYb9fUKGwQbtysJ2H1MofRUPg= +github.com/aws/aws-sdk-go-v2/service/sso v1.25.5/go.mod h1:b7SiVprpU+iGazDUqvRSLf5XmCdn+JtT1on7uNL6Ipc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3 h1:BpOxT3yhLwSJ77qIY3DoHAQjZsc4HEGfMCE4NGy3uFg= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.3/go.mod h1:vq/GQR1gOFLquZMSrxUK/cpvKCNVYibNyJ1m7JrU88E= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.0 h1:NFOJ/NXEGV4Rq//71Hs1jC/NvPs1ezajK+yQmkwnPV0= +github.com/aws/aws-sdk-go-v2/service/sts v1.34.0/go.mod h1:7ph2tGpfQvwzgistp2+zga9f+bCjlQJPkPUmMgDSD7w= github.com/aws/smithy-go v1.22.4 h1:uqXzVZNuNexwc/xrh6Tb56u89WDlJY6HS+KC0S4QSjw= github.com/aws/smithy-go v1.22.4/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= github.com/caarlos0/env/v11 v11.3.1 h1:cArPWC15hWmEt+gWk7YBi7lEXTXCvpaSdCiZE2X5mCA= @@ -103,7 +103,6 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-github/v28 v28.1.1 h1:kORf5ekX5qwXO2mGzXXOjMe/g6ap8ahVe0sBEulhSxo= @@ -117,8 +116,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.0 h1:+epNPbD5EqgpEMm5wrl4Hqts3jZt8+kYaqUisuuIGTk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.0/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/http-wasm/http-wasm-host-go v0.7.0 h1:+1KrRyOO6tWiDB24QrtSYyDmzFLBBs3jioKaUT0mq1c= @@ -131,10 +130,6 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -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/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= @@ -172,8 +167,6 @@ github.com/pressly/goose/v3 v3.24.3 h1:DSWWNwwggVUsYZ0X2VitiAa9sKuqtBfe+Jr9zFGwW github.com/pressly/goose/v3 v3.24.3/go.mod h1:v9zYL4xdViLHCUUJh/mhjnm6JrK7Eul8AS93IxiZM4E= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= -github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= @@ -291,9 +284,6 @@ google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= @@ -306,8 +296,10 @@ modernc.org/fileutil v1.3.3 h1:3qaU+7f7xxTUmvU1pJTZiDLAIoJVdUSSauJNHg9yXoA= modernc.org/fileutil v1.3.3/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc= modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= -modernc.org/libc v1.65.10 h1:ZwEk8+jhW7qBjHIT+wd0d9VjitRyQef9BnzlzGwMODc= -modernc.org/libc v1.65.10/go.mod h1:StFvYpx7i/mXtBAfVOjaU0PWZOvIRoZSgXhrwXzr8Po= +modernc.org/goabi0 v0.0.3 h1:y81b9r3asCh6Xtse6Nz85aYGB0cG3M3U6222yap1KWI= +modernc.org/goabi0 v0.0.3/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI= +modernc.org/libc v1.66.0 h1:eoFuDb1ozurUY5WSWlgvxHp0FuL+AncMwNjFqGYMJPQ= +modernc.org/libc v1.66.0/go.mod h1:AiZxInURfEJx516LqEaFcrC+X38rt9G7+8ojIXQKHbo= modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= @@ -322,5 +314,3 @@ modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/internal/api/middlewares/auth.go b/internal/api/middlewares/auth.go index 5685189..60e3bf7 100644 --- a/internal/api/middlewares/auth.go +++ b/internal/api/middlewares/auth.go @@ -22,7 +22,7 @@ const ( AuthAgentIDKey ctxKey = "agent_id" ) -// BasicAuth middleware for simple authentication +// BasicAuth middleware for http endpoints func (h *MiddlewareHandler) BasicAuth(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { username, password, ok := r.BasicAuth() @@ -51,6 +51,7 @@ func (h *MiddlewareHandler) BasicAuth(next http.Handler) http.Handler { }) } +// Authentication middleware for gRPC endpoints func Authentication(app *config.App) connect.UnaryInterceptorFunc { return connect.UnaryInterceptorFunc(func(next connect.UnaryFunc) connect.UnaryFunc { return func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) { @@ -106,12 +107,12 @@ func Authentication(app *config.App) connect.UnaryInterceptorFunc { // Add claims to context ctx = context.WithValue(ctx, AuthUserIDKey, claims.ID) - return next(ctx, req) } }) } +// Helper func isPublicEndpoint(procedure string) bool { publicEndpoints := map[string]bool{ mantraev1connect.UserServiceLoginUserProcedure: true, @@ -121,7 +122,6 @@ func isPublicEndpoint(procedure string) bool { return publicEndpoints[procedure] } -// Helper functions to get auth info from context func GetUserIDFromContext(ctx context.Context) (string, bool) { id, ok := ctx.Value(AuthUserIDKey).(string) return id, ok diff --git a/internal/api/middlewares/cors.go b/internal/api/middlewares/cors.go index a9600bc..8c74e43 100644 --- a/internal/api/middlewares/cors.go +++ b/internal/api/middlewares/cors.go @@ -1,10 +1,7 @@ package middlewares import ( - "context" - "log/slog" "net/http" - "strings" connectcors "connectrpc.com/cors" "github.com/mizuchilabs/mantrae/internal/config" @@ -12,63 +9,26 @@ import ( "github.com/rs/cors" ) -const ( - defaultDevOrigin = "http://127.0.0.1:5173" -) - -func CORS(allowedOrigins ...string) func(http.Handler) http.Handler { - // Default to dev origin if none provided - if len(allowedOrigins) == 0 { - allowedOrigins = []string{defaultDevOrigin} - } - - // Create a map for faster origin lookup - originMap := make(map[string]bool) - for _, origin := range allowedOrigins { - originMap[strings.TrimSpace(origin)] = true - } - - return func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - origin := r.Header.Get("Origin") - - // Set CORS headers - if origin != "" && originMap[origin] { - w.Header().Set("Access-Control-Allow-Origin", origin) - w.Header().Set("Access-Control-Allow-Credentials", "true") - } - - w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") - w.Header(). - Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") - - // Handle preflight requests - if r.Method == "OPTIONS" { - w.WriteHeader(http.StatusNoContent) - return - } - - next.ServeHTTP(w, r) - }) - } -} - // WithCORS adds CORS support to a Connect HTTP handler. -func WithCORS(h http.Handler, app *config.App) http.Handler { - serverURL, err := app.Conn.GetQuery().GetSetting(context.Background(), settings.KeyServerURL) - if err != nil { - slog.Error("Failed to get server URL", "error", err) - return h +func WithCORS(h http.Handler, app *config.App, port string) http.Handler { + // Always include safe localhost dev URLs + allowedOrigins := []string{ + "http://localhost:5173", + "http://127.0.0.1:5173", + "http://localhost:" + port, + "http://127.0.0.1:" + port, } - if serverURL.Value == "" { - slog.Error("Server URL not set") - return h + + serverURL, ok := app.SM.Get(settings.KeyServerURL) + if ok { + allowedOrigins = append(allowedOrigins, serverURL) } - middleware := cors.New(cors.Options{ - AllowedOrigins: []string{serverURL.Value}, - AllowedMethods: connectcors.AllowedMethods(), - AllowedHeaders: connectcors.AllowedHeaders(), - ExposedHeaders: connectcors.ExposedHeaders(), - }) - return middleware.Handler(h) + + return cors.New(cors.Options{ + AllowedOrigins: allowedOrigins, + AllowedMethods: connectcors.AllowedMethods(), + AllowedHeaders: connectcors.AllowedHeaders(), + ExposedHeaders: connectcors.ExposedHeaders(), + AllowCredentials: true, + }).Handler(h) } diff --git a/internal/api/middlewares/middlewares.go b/internal/api/middlewares/middlewares.go index abf18cd..d5dad50 100644 --- a/internal/api/middlewares/middlewares.go +++ b/internal/api/middlewares/middlewares.go @@ -12,7 +12,7 @@ type MiddlewareHandler struct { app *config.App } -// NewMiddleware creates a new middleware set with configuration +// NewMiddlewareHandler creates a new middleware set with configuration func NewMiddlewareHandler(app *config.App) *MiddlewareHandler { return &MiddlewareHandler{app: app} } diff --git a/internal/api/server/server.go b/internal/api/server/server.go index 2e2e7e7..9ab2bcf 100644 --- a/internal/api/server/server.go +++ b/internal/api/server/server.go @@ -69,7 +69,7 @@ func (s *Server) Start(ctx context.Context) error { server := &http.Server{ Addr: s.Host + ":" + s.Port, - Handler: middlewares.WithCORS(s.mux, s.app), + Handler: middlewares.WithCORS(s.mux, s.app, s.Port), ReadHeaderTimeout: 3 * time.Second, ReadTimeout: 5 * time.Minute, WriteTimeout: 5 * time.Minute, @@ -138,11 +138,13 @@ func (s *Server) registerServices() { mantraev1connect.UserServiceName, mantraev1connect.EntryPointServiceName, mantraev1connect.SettingServiceName, + mantraev1connect.DnsProviderServiceName, mantraev1connect.AgentServiceName, mantraev1connect.AgentManagementServiceName, mantraev1connect.RouterServiceName, mantraev1connect.ServiceServiceName, mantraev1connect.MiddlewareServiceName, + mantraev1connect.UtilServiceName, } checker := grpchealth.NewStaticChecker(serviceNames...) @@ -182,6 +184,10 @@ func (s *Server) registerServices() { service.NewSettingService(s.app), opts..., )) + s.mux.Handle(mantraev1connect.NewDnsProviderServiceHandler( + service.NewDnsProviderService(s.app), + opts..., + )) s.mux.Handle(mantraev1connect.NewAgentServiceHandler( service.NewAgentService(s.app), opts..., @@ -202,6 +208,10 @@ func (s *Server) registerServices() { service.NewMiddlewareService(s.app), opts..., )) + s.mux.Handle(mantraev1connect.NewUtilServiceHandler( + service.NewUtilService(s.app), + opts..., + )) // Traefik endpoint (HTTP) ------------------------------------------------ mw := middlewares.NewMiddlewareHandler(s.app) diff --git a/internal/api/service/dnsProvider.go b/internal/api/service/dnsProvider.go new file mode 100644 index 0000000..e345ace --- /dev/null +++ b/internal/api/service/dnsProvider.go @@ -0,0 +1,193 @@ +package service + +import ( + "context" + + "connectrpc.com/connect" + + "github.com/mizuchilabs/mantrae/internal/config" + "github.com/mizuchilabs/mantrae/internal/store/db" + "github.com/mizuchilabs/mantrae/internal/store/schema" + mantraev1 "github.com/mizuchilabs/mantrae/proto/gen/mantrae/v1" +) + +type DnsProviderService struct { + app *config.App +} + +func NewDnsProviderService(app *config.App) *DnsProviderService { + return &DnsProviderService{app: app} +} + +func (s *DnsProviderService) GetDnsProvider( + ctx context.Context, + req *connect.Request[mantraev1.GetDnsProviderRequest], +) (*connect.Response[mantraev1.GetDnsProviderResponse], error) { + dnsProvider, err := s.app.Conn.GetQuery().GetDnsProvider(ctx, req.Msg.Id) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + return connect.NewResponse(&mantraev1.GetDnsProviderResponse{ + DnsProvider: &mantraev1.DnsProvider{ + Id: dnsProvider.ID, + Name: dnsProvider.Name, + Type: dnsProvider.Type, + Config: &mantraev1.DnsProviderConfig{ + ApiKey: dnsProvider.Config.APIKey, + ApiUrl: dnsProvider.Config.APIUrl, + Ip: dnsProvider.Config.IP, + Proxied: dnsProvider.Config.Proxied, + AutoUpdate: dnsProvider.Config.AutoUpdate, + ZoneType: dnsProvider.Config.ZoneType, + }, + IsActive: dnsProvider.IsActive, + CreatedAt: SafeTimestamp(dnsProvider.CreatedAt), + UpdatedAt: SafeTimestamp(dnsProvider.UpdatedAt), + }, + }), nil +} + +func (s *DnsProviderService) CreateDnsProvider( + ctx context.Context, + req *connect.Request[mantraev1.CreateDnsProviderRequest], +) (*connect.Response[mantraev1.CreateDnsProviderResponse], error) { + params := db.CreateDnsProviderParams{ + Name: req.Msg.Name, + Type: req.Msg.Type, + Config: &schema.DNSProviderConfig{ + APIKey: req.Msg.Config.ApiKey, + APIUrl: req.Msg.Config.ApiUrl, + IP: req.Msg.Config.Ip, + Proxied: req.Msg.Config.Proxied, + AutoUpdate: req.Msg.Config.AutoUpdate, + ZoneType: req.Msg.Config.ZoneType, + }, + IsActive: req.Msg.IsActive, + } + + dnsProvider, err := s.app.Conn.GetQuery().CreateDnsProvider(ctx, params) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + return connect.NewResponse(&mantraev1.CreateDnsProviderResponse{ + DnsProvider: &mantraev1.DnsProvider{ + Id: dnsProvider.ID, + Name: dnsProvider.Name, + Type: dnsProvider.Type, + Config: &mantraev1.DnsProviderConfig{ + ApiKey: dnsProvider.Config.APIKey, + ApiUrl: dnsProvider.Config.APIUrl, + Ip: dnsProvider.Config.IP, + Proxied: dnsProvider.Config.Proxied, + AutoUpdate: dnsProvider.Config.AutoUpdate, + ZoneType: dnsProvider.Config.ZoneType, + }, + IsActive: dnsProvider.IsActive, + CreatedAt: SafeTimestamp(dnsProvider.CreatedAt), + UpdatedAt: SafeTimestamp(dnsProvider.UpdatedAt), + }, + }), nil +} + +func (s *DnsProviderService) UpdateDnsProvider( + ctx context.Context, + req *connect.Request[mantraev1.UpdateDnsProviderRequest], +) (*connect.Response[mantraev1.UpdateDnsProviderResponse], error) { + params := db.UpdateDnsProviderParams{ + Name: req.Msg.Name, + Type: req.Msg.Type, + Config: &schema.DNSProviderConfig{ + APIKey: req.Msg.Config.ApiKey, + APIUrl: req.Msg.Config.ApiUrl, + IP: req.Msg.Config.Ip, + Proxied: req.Msg.Config.Proxied, + AutoUpdate: req.Msg.Config.AutoUpdate, + ZoneType: req.Msg.Config.ZoneType, + }, + IsActive: req.Msg.IsActive, + } + + dnsProvider, err := s.app.Conn.GetQuery().UpdateDnsProvider(ctx, params) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + return connect.NewResponse(&mantraev1.UpdateDnsProviderResponse{ + DnsProvider: &mantraev1.DnsProvider{ + Id: dnsProvider.ID, + Name: dnsProvider.Name, + Type: dnsProvider.Type, + Config: &mantraev1.DnsProviderConfig{ + ApiKey: dnsProvider.Config.APIKey, + ApiUrl: dnsProvider.Config.APIUrl, + Ip: dnsProvider.Config.IP, + Proxied: dnsProvider.Config.Proxied, + AutoUpdate: dnsProvider.Config.AutoUpdate, + ZoneType: dnsProvider.Config.ZoneType, + }, + IsActive: dnsProvider.IsActive, + CreatedAt: SafeTimestamp(dnsProvider.CreatedAt), + UpdatedAt: SafeTimestamp(dnsProvider.UpdatedAt), + }, + }), nil +} + +func (s *DnsProviderService) DeleteDnsProvider( + ctx context.Context, + req *connect.Request[mantraev1.DeleteDnsProviderRequest], +) (*connect.Response[mantraev1.DeleteDnsProviderResponse], error) { + err := s.app.Conn.GetQuery().DeleteDnsProvider(ctx, req.Msg.Id) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + return connect.NewResponse(&mantraev1.DeleteDnsProviderResponse{}), nil +} + +func (s *DnsProviderService) ListDnsProviders( + ctx context.Context, + req *connect.Request[mantraev1.ListDnsProvidersRequest], +) (*connect.Response[mantraev1.ListDnsProvidersResponse], error) { + var params db.ListDnsProvidersParams + if req.Msg.Limit == nil { + params.Limit = 100 + } else { + params.Limit = *req.Msg.Limit + } + if req.Msg.Offset == nil { + params.Offset = 0 + } else { + params.Offset = *req.Msg.Offset + } + + dbDNSProviders, err := s.app.Conn.GetQuery().ListDnsProviders(ctx, params) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + totalCount, err := s.app.Conn.GetQuery().CountDnsProviders(ctx) + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + var dnsProviders []*mantraev1.DnsProvider + for _, dnsProvider := range dbDNSProviders { + dnsProviders = append(dnsProviders, &mantraev1.DnsProvider{ + Id: dnsProvider.ID, + Name: dnsProvider.Name, + Type: dnsProvider.Type, + Config: &mantraev1.DnsProviderConfig{ + ApiKey: dnsProvider.Config.APIKey, + ApiUrl: dnsProvider.Config.APIUrl, + Ip: dnsProvider.Config.IP, + Proxied: dnsProvider.Config.Proxied, + AutoUpdate: dnsProvider.Config.AutoUpdate, + ZoneType: dnsProvider.Config.ZoneType, + }, + IsActive: dnsProvider.IsActive, + CreatedAt: SafeTimestamp(dnsProvider.CreatedAt), + UpdatedAt: SafeTimestamp(dnsProvider.UpdatedAt), + }) + } + return connect.NewResponse(&mantraev1.ListDnsProvidersResponse{ + DnsProviders: dnsProviders, + TotalCount: totalCount, + }), nil +} diff --git a/internal/api/service/util.go b/internal/api/service/util.go new file mode 100644 index 0000000..4fc8ad4 --- /dev/null +++ b/internal/api/service/util.go @@ -0,0 +1,44 @@ +package service + +import ( + "context" + + "connectrpc.com/connect" + + "github.com/mizuchilabs/mantrae/internal/config" + "github.com/mizuchilabs/mantrae/internal/util" + "github.com/mizuchilabs/mantrae/pkg/build" + mantraev1 "github.com/mizuchilabs/mantrae/proto/gen/mantrae/v1" +) + +type UtilService struct { + app *config.App +} + +func NewUtilService(app *config.App) *UtilService { + return &UtilService{app: app} +} + +func (s *UtilService) GetVersion( + ctx context.Context, + req *connect.Request[mantraev1.GetVersionRequest], +) (*connect.Response[mantraev1.GetVersionResponse], error) { + return connect.NewResponse(&mantraev1.GetVersionResponse{ + Version: build.Version, + }), nil +} + +func (s *UtilService) GetPublicIP( + ctx context.Context, + req *connect.Request[mantraev1.GetPublicIPRequest], +) (*connect.Response[mantraev1.GetPublicIPResponse], error) { + ips, err := util.GetPublicIPsCached() + if err != nil { + return nil, connect.NewError(connect.CodeInternal, err) + } + + return connect.NewResponse(&mantraev1.GetPublicIPResponse{ + Ipv4: ips.IPv4, + Ipv6: ips.IPv6, + }), nil +} diff --git a/internal/config/setup.go b/internal/config/setup.go index 9c540d5..10028c0 100644 --- a/internal/config/setup.go +++ b/internal/config/setup.go @@ -46,7 +46,6 @@ func Setup(ctx context.Context) (*App, error) { if err := app.setupDefaultData(ctx); err != nil { return nil, err } - slog.Info("Default data initialized") // Start background jobs app.setupBackgroundJobs(ctx) diff --git a/internal/dns/client.go b/internal/dns/client.go index 1549d86..5399efb 100644 --- a/internal/dns/client.go +++ b/internal/dns/client.go @@ -52,9 +52,9 @@ func getProvider(id int64, q *db.Queries) (DNSProvider, error) { return nil, err } if machineIPs.IPv4 != "" { - provider.Config.TraefikIP = machineIPs.IPv4 + provider.Config.IP = machineIPs.IPv4 } else if machineIPs.IPv6 != "" { - provider.Config.TraefikIP = machineIPs.IPv6 + provider.Config.IP = machineIPs.IPv6 } } diff --git a/internal/dns/cloudflare.go b/internal/dns/cloudflare.go index 9525918..5878f29 100644 --- a/internal/dns/cloudflare.go +++ b/internal/dns/cloudflare.go @@ -29,7 +29,7 @@ func NewCloudflareProvider(d *schema.DNSProviderConfig) *CloudflareProvider { return &CloudflareProvider{ Client: client, - ExternalIP: d.TraefikIP, + ExternalIP: d.IP, Proxied: &d.Proxied, } } diff --git a/internal/dns/powerdns.go b/internal/dns/powerdns.go index 7ddf713..da72b54 100644 --- a/internal/dns/powerdns.go +++ b/internal/dns/powerdns.go @@ -20,7 +20,7 @@ func NewPowerDNSProvider(d *schema.DNSProviderConfig) *PowerDNSProvider { return &PowerDNSProvider{ Client: client, - ExternalIP: d.TraefikIP, + ExternalIP: d.IP, } } diff --git a/internal/dns/technitium.go b/internal/dns/technitium.go index ef7daf8..19146f0 100644 --- a/internal/dns/technitium.go +++ b/internal/dns/technitium.go @@ -29,7 +29,7 @@ func NewTechnitiumProvider(d *schema.DNSProviderConfig) *TechnitiumProvider { return &TechnitiumProvider{ BaseURL: d.APIUrl, APIKey: d.APIKey, - ExternalIP: d.TraefikIP, + ExternalIP: d.IP, ZoneType: d.ZoneType, } } diff --git a/internal/store/db/dns_providers.sql.go b/internal/store/db/dns_providers.sql.go index 639ceed..c694691 100644 --- a/internal/store/db/dns_providers.sql.go +++ b/internal/store/db/dns_providers.sql.go @@ -28,7 +28,6 @@ func (q *Queries) CountDnsProviders(ctx context.Context) (int64, error) { const createDnsProvider = `-- name: CreateDnsProvider :one INSERT INTO dns_providers ( - id, name, type, config, @@ -37,19 +36,10 @@ INSERT INTO updated_at ) VALUES - ( - ?, - ?, - ?, - ?, - ?, - CURRENT_TIMESTAMP, - CURRENT_TIMESTAMP - ) RETURNING id, name, type, config, is_active, created_at, updated_at + (?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) RETURNING id, name, type, config, is_active, created_at, updated_at ` type CreateDnsProviderParams struct { - ID int64 `json:"id"` Name string `json:"name"` Type string `json:"type"` Config *schema.DNSProviderConfig `json:"config"` @@ -58,7 +48,6 @@ type CreateDnsProviderParams struct { func (q *Queries) CreateDnsProvider(ctx context.Context, arg CreateDnsProviderParams) (DnsProvider, error) { row := q.queryRow(ctx, q.createDnsProviderStmt, createDnsProvider, - arg.ID, arg.Name, arg.Type, arg.Config, diff --git a/internal/store/db/entry_points.sql.go b/internal/store/db/entry_points.sql.go index a6f7ec9..bf28a9f 100644 --- a/internal/store/db/entry_points.sql.go +++ b/internal/store/db/entry_points.sql.go @@ -26,7 +26,6 @@ func (q *Queries) CountEntryPoints(ctx context.Context) (int64, error) { const createEntryPoint = `-- name: CreateEntryPoint :one INSERT INTO entry_points ( - id, profile_id, name, address, @@ -35,19 +34,10 @@ INSERT INTO updated_at ) VALUES - ( - ?, - ?, - ?, - ?, - ?, - CURRENT_TIMESTAMP, - CURRENT_TIMESTAMP - ) RETURNING id, profile_id, name, address, is_default, created_at, updated_at + (?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) RETURNING id, profile_id, name, address, is_default, created_at, updated_at ` type CreateEntryPointParams struct { - ID int64 `json:"id"` ProfileID int64 `json:"profileId"` Name string `json:"name"` Address string `json:"address"` @@ -56,7 +46,6 @@ type CreateEntryPointParams struct { func (q *Queries) CreateEntryPoint(ctx context.Context, arg CreateEntryPointParams) (EntryPoint, error) { row := q.queryRow(ctx, q.createEntryPointStmt, createEntryPoint, - arg.ID, arg.ProfileID, arg.Name, arg.Address, diff --git a/internal/store/db/traefik_instances.sql.go b/internal/store/db/traefik_instances.sql.go index b6ca924..a4a4f26 100644 --- a/internal/store/db/traefik_instances.sql.go +++ b/internal/store/db/traefik_instances.sql.go @@ -28,7 +28,6 @@ func (q *Queries) CountTraefikInstances(ctx context.Context) (int64, error) { const createTraefikInstance = `-- name: CreateTraefikInstance :one INSERT INTO traefik_instances ( - id, profile_id, url, username, @@ -44,14 +43,12 @@ VALUES ?, ?, ?, - ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP ) RETURNING id, profile_id, entrypoints, overview, config, version, url, username, password, tls, created_at, updated_at ` type CreateTraefikInstanceParams struct { - ID int64 `json:"id"` ProfileID int64 `json:"profileId"` Url string `json:"url"` Username *string `json:"username"` @@ -61,7 +58,6 @@ type CreateTraefikInstanceParams struct { func (q *Queries) CreateTraefikInstance(ctx context.Context, arg CreateTraefikInstanceParams) (TraefikInstance, error) { row := q.queryRow(ctx, q.createTraefikInstanceStmt, createTraefikInstance, - arg.ID, arg.ProfileID, arg.Url, arg.Username, diff --git a/internal/store/queries/dns_providers.sql b/internal/store/queries/dns_providers.sql index c8f76e5..32badef 100644 --- a/internal/store/queries/dns_providers.sql +++ b/internal/store/queries/dns_providers.sql @@ -1,7 +1,6 @@ -- name: CreateDnsProvider :one INSERT INTO dns_providers ( - id, name, type, config, @@ -10,15 +9,7 @@ INSERT INTO updated_at ) VALUES - ( - ?, - ?, - ?, - ?, - ?, - CURRENT_TIMESTAMP, - CURRENT_TIMESTAMP - ) RETURNING *; + (?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) RETURNING *; -- name: GetDnsProvider :one SELECT diff --git a/internal/store/queries/entry_points.sql b/internal/store/queries/entry_points.sql index 8d18c24..6a1c13a 100644 --- a/internal/store/queries/entry_points.sql +++ b/internal/store/queries/entry_points.sql @@ -1,7 +1,6 @@ -- name: CreateEntryPoint :one INSERT INTO entry_points ( - id, profile_id, name, address, @@ -10,15 +9,7 @@ INSERT INTO updated_at ) VALUES - ( - ?, - ?, - ?, - ?, - ?, - CURRENT_TIMESTAMP, - CURRENT_TIMESTAMP - ) RETURNING *; + (?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) RETURNING *; -- name: GetEntryPoint :one SELECT diff --git a/internal/store/queries/traefik_instances.sql b/internal/store/queries/traefik_instances.sql index cd5af78..90b6e97 100644 --- a/internal/store/queries/traefik_instances.sql +++ b/internal/store/queries/traefik_instances.sql @@ -1,7 +1,6 @@ -- name: CreateTraefikInstance :one INSERT INTO traefik_instances ( - id, profile_id, url, username, @@ -17,7 +16,6 @@ VALUES ?, ?, ?, - ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP ) RETURNING *; diff --git a/internal/store/schema/dns.go b/internal/store/schema/dns.go index e545f8f..a409fc8 100644 --- a/internal/store/schema/dns.go +++ b/internal/store/schema/dns.go @@ -3,7 +3,7 @@ package schema type DNSProviderConfig struct { APIKey string `json:"apiKey"` APIUrl string `json:"apiUrl"` - TraefikIP string `json:"traefikIp"` + IP string `json:"ip"` Proxied bool `json:"proxied"` AutoUpdate bool `json:"autoUpdate"` ZoneType string `json:"zoneType"` diff --git a/proto/gen/mantrae/v1/dns_provider.pb.go b/proto/gen/mantrae/v1/dns_provider.pb.go new file mode 100644 index 0000000..1f72e70 --- /dev/null +++ b/proto/gen/mantrae/v1/dns_provider.pb.go @@ -0,0 +1,839 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc (unknown) +// source: mantrae/v1/dns_provider.proto + +package mantraev1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type DnsProvider struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"` + Config *DnsProviderConfig `protobuf:"bytes,4,opt,name=config,proto3" json:"config,omitempty"` + IsActive bool `protobuf:"varint,5,opt,name=is_active,json=isActive,proto3" json:"is_active,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DnsProvider) Reset() { + *x = DnsProvider{} + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DnsProvider) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DnsProvider) ProtoMessage() {} + +func (x *DnsProvider) ProtoReflect() protoreflect.Message { + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DnsProvider.ProtoReflect.Descriptor instead. +func (*DnsProvider) Descriptor() ([]byte, []int) { + return file_mantrae_v1_dns_provider_proto_rawDescGZIP(), []int{0} +} + +func (x *DnsProvider) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *DnsProvider) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *DnsProvider) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *DnsProvider) GetConfig() *DnsProviderConfig { + if x != nil { + return x.Config + } + return nil +} + +func (x *DnsProvider) GetIsActive() bool { + if x != nil { + return x.IsActive + } + return false +} + +func (x *DnsProvider) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *DnsProvider) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +type DnsProviderConfig struct { + state protoimpl.MessageState `protogen:"open.v1"` + ApiKey string `protobuf:"bytes,1,opt,name=api_key,json=apiKey,proto3" json:"api_key,omitempty"` + ApiUrl string `protobuf:"bytes,2,opt,name=api_url,json=apiUrl,proto3" json:"api_url,omitempty"` + Ip string `protobuf:"bytes,3,opt,name=ip,proto3" json:"ip,omitempty"` + Proxied bool `protobuf:"varint,4,opt,name=proxied,proto3" json:"proxied,omitempty"` + AutoUpdate bool `protobuf:"varint,5,opt,name=auto_update,json=autoUpdate,proto3" json:"auto_update,omitempty"` + ZoneType string `protobuf:"bytes,6,opt,name=zone_type,json=zoneType,proto3" json:"zone_type,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DnsProviderConfig) Reset() { + *x = DnsProviderConfig{} + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DnsProviderConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DnsProviderConfig) ProtoMessage() {} + +func (x *DnsProviderConfig) ProtoReflect() protoreflect.Message { + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DnsProviderConfig.ProtoReflect.Descriptor instead. +func (*DnsProviderConfig) Descriptor() ([]byte, []int) { + return file_mantrae_v1_dns_provider_proto_rawDescGZIP(), []int{1} +} + +func (x *DnsProviderConfig) GetApiKey() string { + if x != nil { + return x.ApiKey + } + return "" +} + +func (x *DnsProviderConfig) GetApiUrl() string { + if x != nil { + return x.ApiUrl + } + return "" +} + +func (x *DnsProviderConfig) GetIp() string { + if x != nil { + return x.Ip + } + return "" +} + +func (x *DnsProviderConfig) GetProxied() bool { + if x != nil { + return x.Proxied + } + return false +} + +func (x *DnsProviderConfig) GetAutoUpdate() bool { + if x != nil { + return x.AutoUpdate + } + return false +} + +func (x *DnsProviderConfig) GetZoneType() string { + if x != nil { + return x.ZoneType + } + return "" +} + +type GetDnsProviderRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetDnsProviderRequest) Reset() { + *x = GetDnsProviderRequest{} + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetDnsProviderRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetDnsProviderRequest) ProtoMessage() {} + +func (x *GetDnsProviderRequest) ProtoReflect() protoreflect.Message { + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetDnsProviderRequest.ProtoReflect.Descriptor instead. +func (*GetDnsProviderRequest) Descriptor() ([]byte, []int) { + return file_mantrae_v1_dns_provider_proto_rawDescGZIP(), []int{2} +} + +func (x *GetDnsProviderRequest) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +type GetDnsProviderResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + DnsProvider *DnsProvider `protobuf:"bytes,1,opt,name=dns_provider,json=dnsProvider,proto3" json:"dns_provider,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetDnsProviderResponse) Reset() { + *x = GetDnsProviderResponse{} + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetDnsProviderResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetDnsProviderResponse) ProtoMessage() {} + +func (x *GetDnsProviderResponse) ProtoReflect() protoreflect.Message { + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetDnsProviderResponse.ProtoReflect.Descriptor instead. +func (*GetDnsProviderResponse) Descriptor() ([]byte, []int) { + return file_mantrae_v1_dns_provider_proto_rawDescGZIP(), []int{3} +} + +func (x *GetDnsProviderResponse) GetDnsProvider() *DnsProvider { + if x != nil { + return x.DnsProvider + } + return nil +} + +type CreateDnsProviderRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + Config *DnsProviderConfig `protobuf:"bytes,3,opt,name=config,proto3" json:"config,omitempty"` + IsActive bool `protobuf:"varint,4,opt,name=is_active,json=isActive,proto3" json:"is_active,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateDnsProviderRequest) Reset() { + *x = CreateDnsProviderRequest{} + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateDnsProviderRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateDnsProviderRequest) ProtoMessage() {} + +func (x *CreateDnsProviderRequest) ProtoReflect() protoreflect.Message { + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateDnsProviderRequest.ProtoReflect.Descriptor instead. +func (*CreateDnsProviderRequest) Descriptor() ([]byte, []int) { + return file_mantrae_v1_dns_provider_proto_rawDescGZIP(), []int{4} +} + +func (x *CreateDnsProviderRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *CreateDnsProviderRequest) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *CreateDnsProviderRequest) GetConfig() *DnsProviderConfig { + if x != nil { + return x.Config + } + return nil +} + +func (x *CreateDnsProviderRequest) GetIsActive() bool { + if x != nil { + return x.IsActive + } + return false +} + +type CreateDnsProviderResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + DnsProvider *DnsProvider `protobuf:"bytes,1,opt,name=dns_provider,json=dnsProvider,proto3" json:"dns_provider,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *CreateDnsProviderResponse) Reset() { + *x = CreateDnsProviderResponse{} + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateDnsProviderResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateDnsProviderResponse) ProtoMessage() {} + +func (x *CreateDnsProviderResponse) ProtoReflect() protoreflect.Message { + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateDnsProviderResponse.ProtoReflect.Descriptor instead. +func (*CreateDnsProviderResponse) Descriptor() ([]byte, []int) { + return file_mantrae_v1_dns_provider_proto_rawDescGZIP(), []int{5} +} + +func (x *CreateDnsProviderResponse) GetDnsProvider() *DnsProvider { + if x != nil { + return x.DnsProvider + } + return nil +} + +type UpdateDnsProviderRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"` + Config *DnsProviderConfig `protobuf:"bytes,4,opt,name=config,proto3" json:"config,omitempty"` + IsActive bool `protobuf:"varint,5,opt,name=is_active,json=isActive,proto3" json:"is_active,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateDnsProviderRequest) Reset() { + *x = UpdateDnsProviderRequest{} + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateDnsProviderRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateDnsProviderRequest) ProtoMessage() {} + +func (x *UpdateDnsProviderRequest) ProtoReflect() protoreflect.Message { + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateDnsProviderRequest.ProtoReflect.Descriptor instead. +func (*UpdateDnsProviderRequest) Descriptor() ([]byte, []int) { + return file_mantrae_v1_dns_provider_proto_rawDescGZIP(), []int{6} +} + +func (x *UpdateDnsProviderRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *UpdateDnsProviderRequest) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *UpdateDnsProviderRequest) GetConfig() *DnsProviderConfig { + if x != nil { + return x.Config + } + return nil +} + +func (x *UpdateDnsProviderRequest) GetIsActive() bool { + if x != nil { + return x.IsActive + } + return false +} + +type UpdateDnsProviderResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + DnsProvider *DnsProvider `protobuf:"bytes,1,opt,name=dns_provider,json=dnsProvider,proto3" json:"dns_provider,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UpdateDnsProviderResponse) Reset() { + *x = UpdateDnsProviderResponse{} + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *UpdateDnsProviderResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateDnsProviderResponse) ProtoMessage() {} + +func (x *UpdateDnsProviderResponse) ProtoReflect() protoreflect.Message { + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateDnsProviderResponse.ProtoReflect.Descriptor instead. +func (*UpdateDnsProviderResponse) Descriptor() ([]byte, []int) { + return file_mantrae_v1_dns_provider_proto_rawDescGZIP(), []int{7} +} + +func (x *UpdateDnsProviderResponse) GetDnsProvider() *DnsProvider { + if x != nil { + return x.DnsProvider + } + return nil +} + +type DeleteDnsProviderRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DeleteDnsProviderRequest) Reset() { + *x = DeleteDnsProviderRequest{} + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteDnsProviderRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteDnsProviderRequest) ProtoMessage() {} + +func (x *DeleteDnsProviderRequest) ProtoReflect() protoreflect.Message { + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteDnsProviderRequest.ProtoReflect.Descriptor instead. +func (*DeleteDnsProviderRequest) Descriptor() ([]byte, []int) { + return file_mantrae_v1_dns_provider_proto_rawDescGZIP(), []int{8} +} + +func (x *DeleteDnsProviderRequest) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +type DeleteDnsProviderResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *DeleteDnsProviderResponse) Reset() { + *x = DeleteDnsProviderResponse{} + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *DeleteDnsProviderResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteDnsProviderResponse) ProtoMessage() {} + +func (x *DeleteDnsProviderResponse) ProtoReflect() protoreflect.Message { + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteDnsProviderResponse.ProtoReflect.Descriptor instead. +func (*DeleteDnsProviderResponse) Descriptor() ([]byte, []int) { + return file_mantrae_v1_dns_provider_proto_rawDescGZIP(), []int{9} +} + +type ListDnsProvidersRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Limit *int64 `protobuf:"varint,1,opt,name=limit,proto3,oneof" json:"limit,omitempty"` + Offset *int64 `protobuf:"varint,2,opt,name=offset,proto3,oneof" json:"offset,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListDnsProvidersRequest) Reset() { + *x = ListDnsProvidersRequest{} + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListDnsProvidersRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListDnsProvidersRequest) ProtoMessage() {} + +func (x *ListDnsProvidersRequest) ProtoReflect() protoreflect.Message { + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListDnsProvidersRequest.ProtoReflect.Descriptor instead. +func (*ListDnsProvidersRequest) Descriptor() ([]byte, []int) { + return file_mantrae_v1_dns_provider_proto_rawDescGZIP(), []int{10} +} + +func (x *ListDnsProvidersRequest) GetLimit() int64 { + if x != nil && x.Limit != nil { + return *x.Limit + } + return 0 +} + +func (x *ListDnsProvidersRequest) GetOffset() int64 { + if x != nil && x.Offset != nil { + return *x.Offset + } + return 0 +} + +type ListDnsProvidersResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + DnsProviders []*DnsProvider `protobuf:"bytes,1,rep,name=dns_providers,json=dnsProviders,proto3" json:"dns_providers,omitempty"` + TotalCount int64 `protobuf:"varint,2,opt,name=total_count,json=totalCount,proto3" json:"total_count,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListDnsProvidersResponse) Reset() { + *x = ListDnsProvidersResponse{} + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListDnsProvidersResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListDnsProvidersResponse) ProtoMessage() {} + +func (x *ListDnsProvidersResponse) ProtoReflect() protoreflect.Message { + mi := &file_mantrae_v1_dns_provider_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListDnsProvidersResponse.ProtoReflect.Descriptor instead. +func (*ListDnsProvidersResponse) Descriptor() ([]byte, []int) { + return file_mantrae_v1_dns_provider_proto_rawDescGZIP(), []int{11} +} + +func (x *ListDnsProvidersResponse) GetDnsProviders() []*DnsProvider { + if x != nil { + return x.DnsProviders + } + return nil +} + +func (x *ListDnsProvidersResponse) GetTotalCount() int64 { + if x != nil { + return x.TotalCount + } + return 0 +} + +var File_mantrae_v1_dns_provider_proto protoreflect.FileDescriptor + +const file_mantrae_v1_dns_provider_proto_rawDesc = "" + + "\n" + + "\x1dmantrae/v1/dns_provider.proto\x12\n" + + "mantrae.v1\x1a\x1fgoogle/protobuf/timestamp.proto\"\x8f\x02\n" + + "\vDnsProvider\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12\x12\n" + + "\x04type\x18\x03 \x01(\tR\x04type\x125\n" + + "\x06config\x18\x04 \x01(\v2\x1d.mantrae.v1.DnsProviderConfigR\x06config\x12\x1b\n" + + "\tis_active\x18\x05 \x01(\bR\bisActive\x129\n" + + "\n" + + "created_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x129\n" + + "\n" + + "updated_at\x18\a \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt\"\xad\x01\n" + + "\x11DnsProviderConfig\x12\x17\n" + + "\aapi_key\x18\x01 \x01(\tR\x06apiKey\x12\x17\n" + + "\aapi_url\x18\x02 \x01(\tR\x06apiUrl\x12\x0e\n" + + "\x02ip\x18\x03 \x01(\tR\x02ip\x12\x18\n" + + "\aproxied\x18\x04 \x01(\bR\aproxied\x12\x1f\n" + + "\vauto_update\x18\x05 \x01(\bR\n" + + "autoUpdate\x12\x1b\n" + + "\tzone_type\x18\x06 \x01(\tR\bzoneType\"'\n" + + "\x15GetDnsProviderRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\"T\n" + + "\x16GetDnsProviderResponse\x12:\n" + + "\fdns_provider\x18\x01 \x01(\v2\x17.mantrae.v1.DnsProviderR\vdnsProvider\"\x96\x01\n" + + "\x18CreateDnsProviderRequest\x12\x12\n" + + "\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n" + + "\x04type\x18\x02 \x01(\tR\x04type\x125\n" + + "\x06config\x18\x03 \x01(\v2\x1d.mantrae.v1.DnsProviderConfigR\x06config\x12\x1b\n" + + "\tis_active\x18\x04 \x01(\bR\bisActive\"W\n" + + "\x19CreateDnsProviderResponse\x12:\n" + + "\fdns_provider\x18\x01 \x01(\v2\x17.mantrae.v1.DnsProviderR\vdnsProvider\"\x96\x01\n" + + "\x18UpdateDnsProviderRequest\x12\x12\n" + + "\x04name\x18\x02 \x01(\tR\x04name\x12\x12\n" + + "\x04type\x18\x03 \x01(\tR\x04type\x125\n" + + "\x06config\x18\x04 \x01(\v2\x1d.mantrae.v1.DnsProviderConfigR\x06config\x12\x1b\n" + + "\tis_active\x18\x05 \x01(\bR\bisActive\"W\n" + + "\x19UpdateDnsProviderResponse\x12:\n" + + "\fdns_provider\x18\x01 \x01(\v2\x17.mantrae.v1.DnsProviderR\vdnsProvider\"*\n" + + "\x18DeleteDnsProviderRequest\x12\x0e\n" + + "\x02id\x18\x01 \x01(\x03R\x02id\"\x1b\n" + + "\x19DeleteDnsProviderResponse\"f\n" + + "\x17ListDnsProvidersRequest\x12\x19\n" + + "\x05limit\x18\x01 \x01(\x03H\x00R\x05limit\x88\x01\x01\x12\x1b\n" + + "\x06offset\x18\x02 \x01(\x03H\x01R\x06offset\x88\x01\x01B\b\n" + + "\x06_limitB\t\n" + + "\a_offset\"y\n" + + "\x18ListDnsProvidersResponse\x12<\n" + + "\rdns_providers\x18\x01 \x03(\v2\x17.mantrae.v1.DnsProviderR\fdnsProviders\x12\x1f\n" + + "\vtotal_count\x18\x02 \x01(\x03R\n" + + "totalCount2\xfc\x03\n" + + "\x12DnsProviderService\x12\\\n" + + "\x0eGetDnsProvider\x12!.mantrae.v1.GetDnsProviderRequest\x1a\".mantrae.v1.GetDnsProviderResponse\"\x03\x90\x02\x01\x12`\n" + + "\x11CreateDnsProvider\x12$.mantrae.v1.CreateDnsProviderRequest\x1a%.mantrae.v1.CreateDnsProviderResponse\x12`\n" + + "\x11UpdateDnsProvider\x12$.mantrae.v1.UpdateDnsProviderRequest\x1a%.mantrae.v1.UpdateDnsProviderResponse\x12`\n" + + "\x11DeleteDnsProvider\x12$.mantrae.v1.DeleteDnsProviderRequest\x1a%.mantrae.v1.DeleteDnsProviderResponse\x12b\n" + + "\x10ListDnsProviders\x12#.mantrae.v1.ListDnsProvidersRequest\x1a$.mantrae.v1.ListDnsProvidersResponse\"\x03\x90\x02\x01B\xaa\x01\n" + + "\x0ecom.mantrae.v1B\x10DnsProviderProtoP\x01Z=github.com/mizuchilabs/mantrae/proto/gen/mantrae/v1;mantraev1\xa2\x02\x03MXX\xaa\x02\n" + + "Mantrae.V1\xca\x02\n" + + "Mantrae\\V1\xe2\x02\x16Mantrae\\V1\\GPBMetadata\xea\x02\vMantrae::V1b\x06proto3" + +var ( + file_mantrae_v1_dns_provider_proto_rawDescOnce sync.Once + file_mantrae_v1_dns_provider_proto_rawDescData []byte +) + +func file_mantrae_v1_dns_provider_proto_rawDescGZIP() []byte { + file_mantrae_v1_dns_provider_proto_rawDescOnce.Do(func() { + file_mantrae_v1_dns_provider_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_mantrae_v1_dns_provider_proto_rawDesc), len(file_mantrae_v1_dns_provider_proto_rawDesc))) + }) + return file_mantrae_v1_dns_provider_proto_rawDescData +} + +var file_mantrae_v1_dns_provider_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_mantrae_v1_dns_provider_proto_goTypes = []any{ + (*DnsProvider)(nil), // 0: mantrae.v1.DnsProvider + (*DnsProviderConfig)(nil), // 1: mantrae.v1.DnsProviderConfig + (*GetDnsProviderRequest)(nil), // 2: mantrae.v1.GetDnsProviderRequest + (*GetDnsProviderResponse)(nil), // 3: mantrae.v1.GetDnsProviderResponse + (*CreateDnsProviderRequest)(nil), // 4: mantrae.v1.CreateDnsProviderRequest + (*CreateDnsProviderResponse)(nil), // 5: mantrae.v1.CreateDnsProviderResponse + (*UpdateDnsProviderRequest)(nil), // 6: mantrae.v1.UpdateDnsProviderRequest + (*UpdateDnsProviderResponse)(nil), // 7: mantrae.v1.UpdateDnsProviderResponse + (*DeleteDnsProviderRequest)(nil), // 8: mantrae.v1.DeleteDnsProviderRequest + (*DeleteDnsProviderResponse)(nil), // 9: mantrae.v1.DeleteDnsProviderResponse + (*ListDnsProvidersRequest)(nil), // 10: mantrae.v1.ListDnsProvidersRequest + (*ListDnsProvidersResponse)(nil), // 11: mantrae.v1.ListDnsProvidersResponse + (*timestamppb.Timestamp)(nil), // 12: google.protobuf.Timestamp +} +var file_mantrae_v1_dns_provider_proto_depIdxs = []int32{ + 1, // 0: mantrae.v1.DnsProvider.config:type_name -> mantrae.v1.DnsProviderConfig + 12, // 1: mantrae.v1.DnsProvider.created_at:type_name -> google.protobuf.Timestamp + 12, // 2: mantrae.v1.DnsProvider.updated_at:type_name -> google.protobuf.Timestamp + 0, // 3: mantrae.v1.GetDnsProviderResponse.dns_provider:type_name -> mantrae.v1.DnsProvider + 1, // 4: mantrae.v1.CreateDnsProviderRequest.config:type_name -> mantrae.v1.DnsProviderConfig + 0, // 5: mantrae.v1.CreateDnsProviderResponse.dns_provider:type_name -> mantrae.v1.DnsProvider + 1, // 6: mantrae.v1.UpdateDnsProviderRequest.config:type_name -> mantrae.v1.DnsProviderConfig + 0, // 7: mantrae.v1.UpdateDnsProviderResponse.dns_provider:type_name -> mantrae.v1.DnsProvider + 0, // 8: mantrae.v1.ListDnsProvidersResponse.dns_providers:type_name -> mantrae.v1.DnsProvider + 2, // 9: mantrae.v1.DnsProviderService.GetDnsProvider:input_type -> mantrae.v1.GetDnsProviderRequest + 4, // 10: mantrae.v1.DnsProviderService.CreateDnsProvider:input_type -> mantrae.v1.CreateDnsProviderRequest + 6, // 11: mantrae.v1.DnsProviderService.UpdateDnsProvider:input_type -> mantrae.v1.UpdateDnsProviderRequest + 8, // 12: mantrae.v1.DnsProviderService.DeleteDnsProvider:input_type -> mantrae.v1.DeleteDnsProviderRequest + 10, // 13: mantrae.v1.DnsProviderService.ListDnsProviders:input_type -> mantrae.v1.ListDnsProvidersRequest + 3, // 14: mantrae.v1.DnsProviderService.GetDnsProvider:output_type -> mantrae.v1.GetDnsProviderResponse + 5, // 15: mantrae.v1.DnsProviderService.CreateDnsProvider:output_type -> mantrae.v1.CreateDnsProviderResponse + 7, // 16: mantrae.v1.DnsProviderService.UpdateDnsProvider:output_type -> mantrae.v1.UpdateDnsProviderResponse + 9, // 17: mantrae.v1.DnsProviderService.DeleteDnsProvider:output_type -> mantrae.v1.DeleteDnsProviderResponse + 11, // 18: mantrae.v1.DnsProviderService.ListDnsProviders:output_type -> mantrae.v1.ListDnsProvidersResponse + 14, // [14:19] is the sub-list for method output_type + 9, // [9:14] is the sub-list for method input_type + 9, // [9:9] is the sub-list for extension type_name + 9, // [9:9] is the sub-list for extension extendee + 0, // [0:9] is the sub-list for field type_name +} + +func init() { file_mantrae_v1_dns_provider_proto_init() } +func file_mantrae_v1_dns_provider_proto_init() { + if File_mantrae_v1_dns_provider_proto != nil { + return + } + file_mantrae_v1_dns_provider_proto_msgTypes[10].OneofWrappers = []any{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_mantrae_v1_dns_provider_proto_rawDesc), len(file_mantrae_v1_dns_provider_proto_rawDesc)), + NumEnums: 0, + NumMessages: 12, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_mantrae_v1_dns_provider_proto_goTypes, + DependencyIndexes: file_mantrae_v1_dns_provider_proto_depIdxs, + MessageInfos: file_mantrae_v1_dns_provider_proto_msgTypes, + }.Build() + File_mantrae_v1_dns_provider_proto = out.File + file_mantrae_v1_dns_provider_proto_goTypes = nil + file_mantrae_v1_dns_provider_proto_depIdxs = nil +} diff --git a/proto/gen/mantrae/v1/mantraev1connect/dns_provider.connect.go b/proto/gen/mantrae/v1/mantraev1connect/dns_provider.connect.go new file mode 100644 index 0000000..0d73b43 --- /dev/null +++ b/proto/gen/mantrae/v1/mantraev1connect/dns_provider.connect.go @@ -0,0 +1,229 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: mantrae/v1/dns_provider.proto + +package mantraev1connect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + v1 "github.com/mizuchilabs/mantrae/proto/gen/mantrae/v1" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // DnsProviderServiceName is the fully-qualified name of the DnsProviderService service. + DnsProviderServiceName = "mantrae.v1.DnsProviderService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // DnsProviderServiceGetDnsProviderProcedure is the fully-qualified name of the DnsProviderService's + // GetDnsProvider RPC. + DnsProviderServiceGetDnsProviderProcedure = "/mantrae.v1.DnsProviderService/GetDnsProvider" + // DnsProviderServiceCreateDnsProviderProcedure is the fully-qualified name of the + // DnsProviderService's CreateDnsProvider RPC. + DnsProviderServiceCreateDnsProviderProcedure = "/mantrae.v1.DnsProviderService/CreateDnsProvider" + // DnsProviderServiceUpdateDnsProviderProcedure is the fully-qualified name of the + // DnsProviderService's UpdateDnsProvider RPC. + DnsProviderServiceUpdateDnsProviderProcedure = "/mantrae.v1.DnsProviderService/UpdateDnsProvider" + // DnsProviderServiceDeleteDnsProviderProcedure is the fully-qualified name of the + // DnsProviderService's DeleteDnsProvider RPC. + DnsProviderServiceDeleteDnsProviderProcedure = "/mantrae.v1.DnsProviderService/DeleteDnsProvider" + // DnsProviderServiceListDnsProvidersProcedure is the fully-qualified name of the + // DnsProviderService's ListDnsProviders RPC. + DnsProviderServiceListDnsProvidersProcedure = "/mantrae.v1.DnsProviderService/ListDnsProviders" +) + +// DnsProviderServiceClient is a client for the mantrae.v1.DnsProviderService service. +type DnsProviderServiceClient interface { + GetDnsProvider(context.Context, *connect.Request[v1.GetDnsProviderRequest]) (*connect.Response[v1.GetDnsProviderResponse], error) + CreateDnsProvider(context.Context, *connect.Request[v1.CreateDnsProviderRequest]) (*connect.Response[v1.CreateDnsProviderResponse], error) + UpdateDnsProvider(context.Context, *connect.Request[v1.UpdateDnsProviderRequest]) (*connect.Response[v1.UpdateDnsProviderResponse], error) + DeleteDnsProvider(context.Context, *connect.Request[v1.DeleteDnsProviderRequest]) (*connect.Response[v1.DeleteDnsProviderResponse], error) + ListDnsProviders(context.Context, *connect.Request[v1.ListDnsProvidersRequest]) (*connect.Response[v1.ListDnsProvidersResponse], error) +} + +// NewDnsProviderServiceClient constructs a client for the mantrae.v1.DnsProviderService service. By +// default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, +// and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the +// connect.WithGRPC() or connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewDnsProviderServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) DnsProviderServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + dnsProviderServiceMethods := v1.File_mantrae_v1_dns_provider_proto.Services().ByName("DnsProviderService").Methods() + return &dnsProviderServiceClient{ + getDnsProvider: connect.NewClient[v1.GetDnsProviderRequest, v1.GetDnsProviderResponse]( + httpClient, + baseURL+DnsProviderServiceGetDnsProviderProcedure, + connect.WithSchema(dnsProviderServiceMethods.ByName("GetDnsProvider")), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), + connect.WithClientOptions(opts...), + ), + createDnsProvider: connect.NewClient[v1.CreateDnsProviderRequest, v1.CreateDnsProviderResponse]( + httpClient, + baseURL+DnsProviderServiceCreateDnsProviderProcedure, + connect.WithSchema(dnsProviderServiceMethods.ByName("CreateDnsProvider")), + connect.WithClientOptions(opts...), + ), + updateDnsProvider: connect.NewClient[v1.UpdateDnsProviderRequest, v1.UpdateDnsProviderResponse]( + httpClient, + baseURL+DnsProviderServiceUpdateDnsProviderProcedure, + connect.WithSchema(dnsProviderServiceMethods.ByName("UpdateDnsProvider")), + connect.WithClientOptions(opts...), + ), + deleteDnsProvider: connect.NewClient[v1.DeleteDnsProviderRequest, v1.DeleteDnsProviderResponse]( + httpClient, + baseURL+DnsProviderServiceDeleteDnsProviderProcedure, + connect.WithSchema(dnsProviderServiceMethods.ByName("DeleteDnsProvider")), + connect.WithClientOptions(opts...), + ), + listDnsProviders: connect.NewClient[v1.ListDnsProvidersRequest, v1.ListDnsProvidersResponse]( + httpClient, + baseURL+DnsProviderServiceListDnsProvidersProcedure, + connect.WithSchema(dnsProviderServiceMethods.ByName("ListDnsProviders")), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), + connect.WithClientOptions(opts...), + ), + } +} + +// dnsProviderServiceClient implements DnsProviderServiceClient. +type dnsProviderServiceClient struct { + getDnsProvider *connect.Client[v1.GetDnsProviderRequest, v1.GetDnsProviderResponse] + createDnsProvider *connect.Client[v1.CreateDnsProviderRequest, v1.CreateDnsProviderResponse] + updateDnsProvider *connect.Client[v1.UpdateDnsProviderRequest, v1.UpdateDnsProviderResponse] + deleteDnsProvider *connect.Client[v1.DeleteDnsProviderRequest, v1.DeleteDnsProviderResponse] + listDnsProviders *connect.Client[v1.ListDnsProvidersRequest, v1.ListDnsProvidersResponse] +} + +// GetDnsProvider calls mantrae.v1.DnsProviderService.GetDnsProvider. +func (c *dnsProviderServiceClient) GetDnsProvider(ctx context.Context, req *connect.Request[v1.GetDnsProviderRequest]) (*connect.Response[v1.GetDnsProviderResponse], error) { + return c.getDnsProvider.CallUnary(ctx, req) +} + +// CreateDnsProvider calls mantrae.v1.DnsProviderService.CreateDnsProvider. +func (c *dnsProviderServiceClient) CreateDnsProvider(ctx context.Context, req *connect.Request[v1.CreateDnsProviderRequest]) (*connect.Response[v1.CreateDnsProviderResponse], error) { + return c.createDnsProvider.CallUnary(ctx, req) +} + +// UpdateDnsProvider calls mantrae.v1.DnsProviderService.UpdateDnsProvider. +func (c *dnsProviderServiceClient) UpdateDnsProvider(ctx context.Context, req *connect.Request[v1.UpdateDnsProviderRequest]) (*connect.Response[v1.UpdateDnsProviderResponse], error) { + return c.updateDnsProvider.CallUnary(ctx, req) +} + +// DeleteDnsProvider calls mantrae.v1.DnsProviderService.DeleteDnsProvider. +func (c *dnsProviderServiceClient) DeleteDnsProvider(ctx context.Context, req *connect.Request[v1.DeleteDnsProviderRequest]) (*connect.Response[v1.DeleteDnsProviderResponse], error) { + return c.deleteDnsProvider.CallUnary(ctx, req) +} + +// ListDnsProviders calls mantrae.v1.DnsProviderService.ListDnsProviders. +func (c *dnsProviderServiceClient) ListDnsProviders(ctx context.Context, req *connect.Request[v1.ListDnsProvidersRequest]) (*connect.Response[v1.ListDnsProvidersResponse], error) { + return c.listDnsProviders.CallUnary(ctx, req) +} + +// DnsProviderServiceHandler is an implementation of the mantrae.v1.DnsProviderService service. +type DnsProviderServiceHandler interface { + GetDnsProvider(context.Context, *connect.Request[v1.GetDnsProviderRequest]) (*connect.Response[v1.GetDnsProviderResponse], error) + CreateDnsProvider(context.Context, *connect.Request[v1.CreateDnsProviderRequest]) (*connect.Response[v1.CreateDnsProviderResponse], error) + UpdateDnsProvider(context.Context, *connect.Request[v1.UpdateDnsProviderRequest]) (*connect.Response[v1.UpdateDnsProviderResponse], error) + DeleteDnsProvider(context.Context, *connect.Request[v1.DeleteDnsProviderRequest]) (*connect.Response[v1.DeleteDnsProviderResponse], error) + ListDnsProviders(context.Context, *connect.Request[v1.ListDnsProvidersRequest]) (*connect.Response[v1.ListDnsProvidersResponse], error) +} + +// NewDnsProviderServiceHandler builds an HTTP handler from the service implementation. It returns +// the path on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewDnsProviderServiceHandler(svc DnsProviderServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + dnsProviderServiceMethods := v1.File_mantrae_v1_dns_provider_proto.Services().ByName("DnsProviderService").Methods() + dnsProviderServiceGetDnsProviderHandler := connect.NewUnaryHandler( + DnsProviderServiceGetDnsProviderProcedure, + svc.GetDnsProvider, + connect.WithSchema(dnsProviderServiceMethods.ByName("GetDnsProvider")), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), + connect.WithHandlerOptions(opts...), + ) + dnsProviderServiceCreateDnsProviderHandler := connect.NewUnaryHandler( + DnsProviderServiceCreateDnsProviderProcedure, + svc.CreateDnsProvider, + connect.WithSchema(dnsProviderServiceMethods.ByName("CreateDnsProvider")), + connect.WithHandlerOptions(opts...), + ) + dnsProviderServiceUpdateDnsProviderHandler := connect.NewUnaryHandler( + DnsProviderServiceUpdateDnsProviderProcedure, + svc.UpdateDnsProvider, + connect.WithSchema(dnsProviderServiceMethods.ByName("UpdateDnsProvider")), + connect.WithHandlerOptions(opts...), + ) + dnsProviderServiceDeleteDnsProviderHandler := connect.NewUnaryHandler( + DnsProviderServiceDeleteDnsProviderProcedure, + svc.DeleteDnsProvider, + connect.WithSchema(dnsProviderServiceMethods.ByName("DeleteDnsProvider")), + connect.WithHandlerOptions(opts...), + ) + dnsProviderServiceListDnsProvidersHandler := connect.NewUnaryHandler( + DnsProviderServiceListDnsProvidersProcedure, + svc.ListDnsProviders, + connect.WithSchema(dnsProviderServiceMethods.ByName("ListDnsProviders")), + connect.WithIdempotency(connect.IdempotencyNoSideEffects), + connect.WithHandlerOptions(opts...), + ) + return "/mantrae.v1.DnsProviderService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case DnsProviderServiceGetDnsProviderProcedure: + dnsProviderServiceGetDnsProviderHandler.ServeHTTP(w, r) + case DnsProviderServiceCreateDnsProviderProcedure: + dnsProviderServiceCreateDnsProviderHandler.ServeHTTP(w, r) + case DnsProviderServiceUpdateDnsProviderProcedure: + dnsProviderServiceUpdateDnsProviderHandler.ServeHTTP(w, r) + case DnsProviderServiceDeleteDnsProviderProcedure: + dnsProviderServiceDeleteDnsProviderHandler.ServeHTTP(w, r) + case DnsProviderServiceListDnsProvidersProcedure: + dnsProviderServiceListDnsProvidersHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedDnsProviderServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedDnsProviderServiceHandler struct{} + +func (UnimplementedDnsProviderServiceHandler) GetDnsProvider(context.Context, *connect.Request[v1.GetDnsProviderRequest]) (*connect.Response[v1.GetDnsProviderResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.DnsProviderService.GetDnsProvider is not implemented")) +} + +func (UnimplementedDnsProviderServiceHandler) CreateDnsProvider(context.Context, *connect.Request[v1.CreateDnsProviderRequest]) (*connect.Response[v1.CreateDnsProviderResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.DnsProviderService.CreateDnsProvider is not implemented")) +} + +func (UnimplementedDnsProviderServiceHandler) UpdateDnsProvider(context.Context, *connect.Request[v1.UpdateDnsProviderRequest]) (*connect.Response[v1.UpdateDnsProviderResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.DnsProviderService.UpdateDnsProvider is not implemented")) +} + +func (UnimplementedDnsProviderServiceHandler) DeleteDnsProvider(context.Context, *connect.Request[v1.DeleteDnsProviderRequest]) (*connect.Response[v1.DeleteDnsProviderResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.DnsProviderService.DeleteDnsProvider is not implemented")) +} + +func (UnimplementedDnsProviderServiceHandler) ListDnsProviders(context.Context, *connect.Request[v1.ListDnsProvidersRequest]) (*connect.Response[v1.ListDnsProvidersResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.DnsProviderService.ListDnsProviders is not implemented")) +} diff --git a/proto/gen/mantrae/v1/mantraev1connect/util.connect.go b/proto/gen/mantrae/v1/mantraev1connect/util.connect.go new file mode 100644 index 0000000..c66215a --- /dev/null +++ b/proto/gen/mantrae/v1/mantraev1connect/util.connect.go @@ -0,0 +1,136 @@ +// Code generated by protoc-gen-connect-go. DO NOT EDIT. +// +// Source: mantrae/v1/util.proto + +package mantraev1connect + +import ( + connect "connectrpc.com/connect" + context "context" + errors "errors" + v1 "github.com/mizuchilabs/mantrae/proto/gen/mantrae/v1" + http "net/http" + strings "strings" +) + +// This is a compile-time assertion to ensure that this generated file and the connect package are +// compatible. If you get a compiler error that this constant is not defined, this code was +// generated with a version of connect newer than the one compiled into your binary. You can fix the +// problem by either regenerating this code with an older version of connect or updating the connect +// version compiled into your binary. +const _ = connect.IsAtLeastVersion1_13_0 + +const ( + // UtilServiceName is the fully-qualified name of the UtilService service. + UtilServiceName = "mantrae.v1.UtilService" +) + +// These constants are the fully-qualified names of the RPCs defined in this package. They're +// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. +// +// Note that these are different from the fully-qualified method names used by +// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to +// reflection-formatted method names, remove the leading slash and convert the remaining slash to a +// period. +const ( + // UtilServiceGetVersionProcedure is the fully-qualified name of the UtilService's GetVersion RPC. + UtilServiceGetVersionProcedure = "/mantrae.v1.UtilService/GetVersion" + // UtilServiceGetPublicIPProcedure is the fully-qualified name of the UtilService's GetPublicIP RPC. + UtilServiceGetPublicIPProcedure = "/mantrae.v1.UtilService/GetPublicIP" +) + +// UtilServiceClient is a client for the mantrae.v1.UtilService service. +type UtilServiceClient interface { + GetVersion(context.Context, *connect.Request[v1.GetVersionRequest]) (*connect.Response[v1.GetVersionResponse], error) + GetPublicIP(context.Context, *connect.Request[v1.GetPublicIPRequest]) (*connect.Response[v1.GetPublicIPResponse], error) +} + +// NewUtilServiceClient constructs a client for the mantrae.v1.UtilService service. By default, it +// uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and sends +// uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or +// connect.WithGRPCWeb() options. +// +// The URL supplied here should be the base URL for the Connect or gRPC server (for example, +// http://api.acme.com or https://acme.com/grpc). +func NewUtilServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) UtilServiceClient { + baseURL = strings.TrimRight(baseURL, "/") + utilServiceMethods := v1.File_mantrae_v1_util_proto.Services().ByName("UtilService").Methods() + return &utilServiceClient{ + getVersion: connect.NewClient[v1.GetVersionRequest, v1.GetVersionResponse]( + httpClient, + baseURL+UtilServiceGetVersionProcedure, + connect.WithSchema(utilServiceMethods.ByName("GetVersion")), + connect.WithClientOptions(opts...), + ), + getPublicIP: connect.NewClient[v1.GetPublicIPRequest, v1.GetPublicIPResponse]( + httpClient, + baseURL+UtilServiceGetPublicIPProcedure, + connect.WithSchema(utilServiceMethods.ByName("GetPublicIP")), + connect.WithClientOptions(opts...), + ), + } +} + +// utilServiceClient implements UtilServiceClient. +type utilServiceClient struct { + getVersion *connect.Client[v1.GetVersionRequest, v1.GetVersionResponse] + getPublicIP *connect.Client[v1.GetPublicIPRequest, v1.GetPublicIPResponse] +} + +// GetVersion calls mantrae.v1.UtilService.GetVersion. +func (c *utilServiceClient) GetVersion(ctx context.Context, req *connect.Request[v1.GetVersionRequest]) (*connect.Response[v1.GetVersionResponse], error) { + return c.getVersion.CallUnary(ctx, req) +} + +// GetPublicIP calls mantrae.v1.UtilService.GetPublicIP. +func (c *utilServiceClient) GetPublicIP(ctx context.Context, req *connect.Request[v1.GetPublicIPRequest]) (*connect.Response[v1.GetPublicIPResponse], error) { + return c.getPublicIP.CallUnary(ctx, req) +} + +// UtilServiceHandler is an implementation of the mantrae.v1.UtilService service. +type UtilServiceHandler interface { + GetVersion(context.Context, *connect.Request[v1.GetVersionRequest]) (*connect.Response[v1.GetVersionResponse], error) + GetPublicIP(context.Context, *connect.Request[v1.GetPublicIPRequest]) (*connect.Response[v1.GetPublicIPResponse], error) +} + +// NewUtilServiceHandler builds an HTTP handler from the service implementation. It returns the path +// on which to mount the handler and the handler itself. +// +// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf +// and JSON codecs. They also support gzip compression. +func NewUtilServiceHandler(svc UtilServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { + utilServiceMethods := v1.File_mantrae_v1_util_proto.Services().ByName("UtilService").Methods() + utilServiceGetVersionHandler := connect.NewUnaryHandler( + UtilServiceGetVersionProcedure, + svc.GetVersion, + connect.WithSchema(utilServiceMethods.ByName("GetVersion")), + connect.WithHandlerOptions(opts...), + ) + utilServiceGetPublicIPHandler := connect.NewUnaryHandler( + UtilServiceGetPublicIPProcedure, + svc.GetPublicIP, + connect.WithSchema(utilServiceMethods.ByName("GetPublicIP")), + connect.WithHandlerOptions(opts...), + ) + return "/mantrae.v1.UtilService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case UtilServiceGetVersionProcedure: + utilServiceGetVersionHandler.ServeHTTP(w, r) + case UtilServiceGetPublicIPProcedure: + utilServiceGetPublicIPHandler.ServeHTTP(w, r) + default: + http.NotFound(w, r) + } + }) +} + +// UnimplementedUtilServiceHandler returns CodeUnimplemented from all methods. +type UnimplementedUtilServiceHandler struct{} + +func (UnimplementedUtilServiceHandler) GetVersion(context.Context, *connect.Request[v1.GetVersionRequest]) (*connect.Response[v1.GetVersionResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.UtilService.GetVersion is not implemented")) +} + +func (UnimplementedUtilServiceHandler) GetPublicIP(context.Context, *connect.Request[v1.GetPublicIPRequest]) (*connect.Response[v1.GetPublicIPResponse], error) { + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("mantrae.v1.UtilService.GetPublicIP is not implemented")) +} diff --git a/proto/gen/mantrae/v1/util.pb.go b/proto/gen/mantrae/v1/util.pb.go new file mode 100644 index 0000000..1e9684d --- /dev/null +++ b/proto/gen/mantrae/v1/util.pb.go @@ -0,0 +1,267 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.6 +// protoc (unknown) +// source: mantrae/v1/util.proto + +package mantraev1 + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + _ "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type GetVersionRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetVersionRequest) Reset() { + *x = GetVersionRequest{} + mi := &file_mantrae_v1_util_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetVersionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetVersionRequest) ProtoMessage() {} + +func (x *GetVersionRequest) ProtoReflect() protoreflect.Message { + mi := &file_mantrae_v1_util_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetVersionRequest.ProtoReflect.Descriptor instead. +func (*GetVersionRequest) Descriptor() ([]byte, []int) { + return file_mantrae_v1_util_proto_rawDescGZIP(), []int{0} +} + +type GetVersionResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetVersionResponse) Reset() { + *x = GetVersionResponse{} + mi := &file_mantrae_v1_util_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetVersionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetVersionResponse) ProtoMessage() {} + +func (x *GetVersionResponse) ProtoReflect() protoreflect.Message { + mi := &file_mantrae_v1_util_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetVersionResponse.ProtoReflect.Descriptor instead. +func (*GetVersionResponse) Descriptor() ([]byte, []int) { + return file_mantrae_v1_util_proto_rawDescGZIP(), []int{1} +} + +func (x *GetVersionResponse) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +type GetPublicIPRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetPublicIPRequest) Reset() { + *x = GetPublicIPRequest{} + mi := &file_mantrae_v1_util_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetPublicIPRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetPublicIPRequest) ProtoMessage() {} + +func (x *GetPublicIPRequest) ProtoReflect() protoreflect.Message { + mi := &file_mantrae_v1_util_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetPublicIPRequest.ProtoReflect.Descriptor instead. +func (*GetPublicIPRequest) Descriptor() ([]byte, []int) { + return file_mantrae_v1_util_proto_rawDescGZIP(), []int{2} +} + +type GetPublicIPResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Ipv4 string `protobuf:"bytes,1,opt,name=ipv4,proto3" json:"ipv4,omitempty"` + Ipv6 string `protobuf:"bytes,2,opt,name=ipv6,proto3" json:"ipv6,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetPublicIPResponse) Reset() { + *x = GetPublicIPResponse{} + mi := &file_mantrae_v1_util_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetPublicIPResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetPublicIPResponse) ProtoMessage() {} + +func (x *GetPublicIPResponse) ProtoReflect() protoreflect.Message { + mi := &file_mantrae_v1_util_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetPublicIPResponse.ProtoReflect.Descriptor instead. +func (*GetPublicIPResponse) Descriptor() ([]byte, []int) { + return file_mantrae_v1_util_proto_rawDescGZIP(), []int{3} +} + +func (x *GetPublicIPResponse) GetIpv4() string { + if x != nil { + return x.Ipv4 + } + return "" +} + +func (x *GetPublicIPResponse) GetIpv6() string { + if x != nil { + return x.Ipv6 + } + return "" +} + +var File_mantrae_v1_util_proto protoreflect.FileDescriptor + +const file_mantrae_v1_util_proto_rawDesc = "" + + "\n" + + "\x15mantrae/v1/util.proto\x12\n" + + "mantrae.v1\x1a\x1fgoogle/protobuf/timestamp.proto\"\x13\n" + + "\x11GetVersionRequest\".\n" + + "\x12GetVersionResponse\x12\x18\n" + + "\aversion\x18\x01 \x01(\tR\aversion\"\x14\n" + + "\x12GetPublicIPRequest\"=\n" + + "\x13GetPublicIPResponse\x12\x12\n" + + "\x04ipv4\x18\x01 \x01(\tR\x04ipv4\x12\x12\n" + + "\x04ipv6\x18\x02 \x01(\tR\x04ipv62\xaa\x01\n" + + "\vUtilService\x12K\n" + + "\n" + + "GetVersion\x12\x1d.mantrae.v1.GetVersionRequest\x1a\x1e.mantrae.v1.GetVersionResponse\x12N\n" + + "\vGetPublicIP\x12\x1e.mantrae.v1.GetPublicIPRequest\x1a\x1f.mantrae.v1.GetPublicIPResponseB\xa3\x01\n" + + "\x0ecom.mantrae.v1B\tUtilProtoP\x01Z=github.com/mizuchilabs/mantrae/proto/gen/mantrae/v1;mantraev1\xa2\x02\x03MXX\xaa\x02\n" + + "Mantrae.V1\xca\x02\n" + + "Mantrae\\V1\xe2\x02\x16Mantrae\\V1\\GPBMetadata\xea\x02\vMantrae::V1b\x06proto3" + +var ( + file_mantrae_v1_util_proto_rawDescOnce sync.Once + file_mantrae_v1_util_proto_rawDescData []byte +) + +func file_mantrae_v1_util_proto_rawDescGZIP() []byte { + file_mantrae_v1_util_proto_rawDescOnce.Do(func() { + file_mantrae_v1_util_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_mantrae_v1_util_proto_rawDesc), len(file_mantrae_v1_util_proto_rawDesc))) + }) + return file_mantrae_v1_util_proto_rawDescData +} + +var file_mantrae_v1_util_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_mantrae_v1_util_proto_goTypes = []any{ + (*GetVersionRequest)(nil), // 0: mantrae.v1.GetVersionRequest + (*GetVersionResponse)(nil), // 1: mantrae.v1.GetVersionResponse + (*GetPublicIPRequest)(nil), // 2: mantrae.v1.GetPublicIPRequest + (*GetPublicIPResponse)(nil), // 3: mantrae.v1.GetPublicIPResponse +} +var file_mantrae_v1_util_proto_depIdxs = []int32{ + 0, // 0: mantrae.v1.UtilService.GetVersion:input_type -> mantrae.v1.GetVersionRequest + 2, // 1: mantrae.v1.UtilService.GetPublicIP:input_type -> mantrae.v1.GetPublicIPRequest + 1, // 2: mantrae.v1.UtilService.GetVersion:output_type -> mantrae.v1.GetVersionResponse + 3, // 3: mantrae.v1.UtilService.GetPublicIP:output_type -> mantrae.v1.GetPublicIPResponse + 2, // [2:4] is the sub-list for method output_type + 0, // [0:2] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_mantrae_v1_util_proto_init() } +func file_mantrae_v1_util_proto_init() { + if File_mantrae_v1_util_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_mantrae_v1_util_proto_rawDesc), len(file_mantrae_v1_util_proto_rawDesc)), + NumEnums: 0, + NumMessages: 4, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_mantrae_v1_util_proto_goTypes, + DependencyIndexes: file_mantrae_v1_util_proto_depIdxs, + MessageInfos: file_mantrae_v1_util_proto_msgTypes, + }.Build() + File_mantrae_v1_util_proto = out.File + file_mantrae_v1_util_proto_goTypes = nil + file_mantrae_v1_util_proto_depIdxs = nil +} diff --git a/proto/gen/openapi/openapi.yaml b/proto/gen/openapi/openapi.yaml index f130170..8417441 100644 --- a/proto/gen/openapi/openapi.yaml +++ b/proto/gen/openapi/openapi.yaml @@ -569,6 +569,177 @@ components: type: object title: UploadBackupResponse additionalProperties: false + mantrae.v1.CreateDnsProviderRequest: + type: object + properties: + name: + type: string + title: name + type: + type: string + title: type + config: + title: config + $ref: '#/components/schemas/mantrae.v1.DnsProviderConfig' + isActive: + type: boolean + title: is_active + title: CreateDnsProviderRequest + additionalProperties: false + mantrae.v1.CreateDnsProviderResponse: + type: object + properties: + dnsProvider: + title: dns_provider + $ref: '#/components/schemas/mantrae.v1.DnsProvider' + title: CreateDnsProviderResponse + additionalProperties: false + mantrae.v1.DeleteDnsProviderRequest: + type: object + properties: + id: + type: + - integer + - string + title: id + format: int64 + title: DeleteDnsProviderRequest + additionalProperties: false + mantrae.v1.DeleteDnsProviderResponse: + type: object + title: DeleteDnsProviderResponse + additionalProperties: false + mantrae.v1.DnsProvider: + type: object + properties: + id: + type: + - integer + - string + title: id + format: int64 + name: + type: string + title: name + type: + type: string + title: type + config: + title: config + $ref: '#/components/schemas/mantrae.v1.DnsProviderConfig' + isActive: + type: boolean + title: is_active + createdAt: + title: created_at + $ref: '#/components/schemas/google.protobuf.Timestamp' + updatedAt: + title: updated_at + $ref: '#/components/schemas/google.protobuf.Timestamp' + title: DnsProvider + additionalProperties: false + mantrae.v1.DnsProviderConfig: + type: object + properties: + apiKey: + type: string + title: api_key + apiUrl: + type: string + title: api_url + ip: + type: string + title: ip + proxied: + type: boolean + title: proxied + autoUpdate: + type: boolean + title: auto_update + zoneType: + type: string + title: zone_type + title: DnsProviderConfig + additionalProperties: false + mantrae.v1.GetDnsProviderRequest: + type: object + properties: + id: + type: + - integer + - string + title: id + format: int64 + title: GetDnsProviderRequest + additionalProperties: false + mantrae.v1.GetDnsProviderResponse: + type: object + properties: + dnsProvider: + title: dns_provider + $ref: '#/components/schemas/mantrae.v1.DnsProvider' + title: GetDnsProviderResponse + additionalProperties: false + mantrae.v1.ListDnsProvidersRequest: + type: object + properties: + limit: + type: + - integer + - string + title: limit + format: int64 + nullable: true + offset: + type: + - integer + - string + title: offset + format: int64 + nullable: true + title: ListDnsProvidersRequest + additionalProperties: false + mantrae.v1.ListDnsProvidersResponse: + type: object + properties: + dnsProviders: + type: array + items: + $ref: '#/components/schemas/mantrae.v1.DnsProvider' + title: dns_providers + totalCount: + type: + - integer + - string + title: total_count + format: int64 + title: ListDnsProvidersResponse + additionalProperties: false + mantrae.v1.UpdateDnsProviderRequest: + type: object + properties: + name: + type: string + title: name + type: + type: string + title: type + config: + title: config + $ref: '#/components/schemas/mantrae.v1.DnsProviderConfig' + isActive: + type: boolean + title: is_active + title: UpdateDnsProviderRequest + additionalProperties: false + mantrae.v1.UpdateDnsProviderResponse: + type: object + properties: + dnsProvider: + title: dns_provider + $ref: '#/components/schemas/mantrae.v1.DnsProvider' + title: UpdateDnsProviderResponse + additionalProperties: false mantrae.v1.CreateEntryPointRequest: type: object properties: @@ -1804,6 +1975,33 @@ components: title: token title: VerifyOTPResponse additionalProperties: false + mantrae.v1.GetPublicIPRequest: + type: object + title: GetPublicIPRequest + additionalProperties: false + mantrae.v1.GetPublicIPResponse: + type: object + properties: + ipv4: + type: string + title: ipv4 + ipv6: + type: string + title: ipv6 + title: GetPublicIPResponse + additionalProperties: false + mantrae.v1.GetVersionRequest: + type: object + title: GetVersionRequest + additionalProperties: false + mantrae.v1.GetVersionResponse: + type: object + properties: + version: + type: string + title: version + title: GetVersionResponse + additionalProperties: false security: - BearerAuth: [] paths: @@ -2576,6 +2774,283 @@ paths: application/grpc-web+json: schema: $ref: '#/components/schemas/mantrae.v1.UploadBackupResponse' + /mantrae.v1.DnsProviderService/GetDnsProvider: + get: + tags: + - mantrae.v1.DnsProviderService + summary: GetDnsProvider + operationId: mantrae.v1.DnsProviderService.GetDnsProvider.get + parameters: + - name: Connect-Protocol-Version + in: header + required: true + schema: + $ref: '#/components/schemas/connect-protocol-version' + - name: Connect-Timeout-Ms + in: header + schema: + $ref: '#/components/schemas/connect-timeout-header' + - name: message + in: query + content: + application/json: + schema: + $ref: '#/components/schemas/mantrae.v1.GetDnsProviderRequest' + - name: encoding + in: query + required: true + schema: + $ref: '#/components/schemas/encoding' + - name: base64 + in: query + schema: + $ref: '#/components/schemas/base64' + - name: compression + in: query + schema: + $ref: '#/components/schemas/compression' + - name: connect + in: query + schema: + $ref: '#/components/schemas/connect' + responses: + default: + description: Error + content: + application/json: + schema: + $ref: '#/components/schemas/connect.error' + "200": + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/mantrae.v1.GetDnsProviderResponse' + post: + tags: + - mantrae.v1.DnsProviderService + summary: GetDnsProvider + operationId: mantrae.v1.DnsProviderService.GetDnsProvider + parameters: + - name: Connect-Protocol-Version + in: header + required: true + schema: + $ref: '#/components/schemas/connect-protocol-version' + - name: Connect-Timeout-Ms + in: header + schema: + $ref: '#/components/schemas/connect-timeout-header' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/mantrae.v1.GetDnsProviderRequest' + required: true + responses: + default: + description: Error + content: + application/json: + schema: + $ref: '#/components/schemas/connect.error' + "200": + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/mantrae.v1.GetDnsProviderResponse' + /mantrae.v1.DnsProviderService/CreateDnsProvider: + post: + tags: + - mantrae.v1.DnsProviderService + summary: CreateDnsProvider + operationId: mantrae.v1.DnsProviderService.CreateDnsProvider + parameters: + - name: Connect-Protocol-Version + in: header + required: true + schema: + $ref: '#/components/schemas/connect-protocol-version' + - name: Connect-Timeout-Ms + in: header + schema: + $ref: '#/components/schemas/connect-timeout-header' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/mantrae.v1.CreateDnsProviderRequest' + required: true + responses: + default: + description: Error + content: + application/json: + schema: + $ref: '#/components/schemas/connect.error' + "200": + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/mantrae.v1.CreateDnsProviderResponse' + /mantrae.v1.DnsProviderService/UpdateDnsProvider: + post: + tags: + - mantrae.v1.DnsProviderService + summary: UpdateDnsProvider + operationId: mantrae.v1.DnsProviderService.UpdateDnsProvider + parameters: + - name: Connect-Protocol-Version + in: header + required: true + schema: + $ref: '#/components/schemas/connect-protocol-version' + - name: Connect-Timeout-Ms + in: header + schema: + $ref: '#/components/schemas/connect-timeout-header' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/mantrae.v1.UpdateDnsProviderRequest' + required: true + responses: + default: + description: Error + content: + application/json: + schema: + $ref: '#/components/schemas/connect.error' + "200": + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/mantrae.v1.UpdateDnsProviderResponse' + /mantrae.v1.DnsProviderService/DeleteDnsProvider: + post: + tags: + - mantrae.v1.DnsProviderService + summary: DeleteDnsProvider + operationId: mantrae.v1.DnsProviderService.DeleteDnsProvider + parameters: + - name: Connect-Protocol-Version + in: header + required: true + schema: + $ref: '#/components/schemas/connect-protocol-version' + - name: Connect-Timeout-Ms + in: header + schema: + $ref: '#/components/schemas/connect-timeout-header' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/mantrae.v1.DeleteDnsProviderRequest' + required: true + responses: + default: + description: Error + content: + application/json: + schema: + $ref: '#/components/schemas/connect.error' + "200": + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/mantrae.v1.DeleteDnsProviderResponse' + /mantrae.v1.DnsProviderService/ListDnsProviders: + get: + tags: + - mantrae.v1.DnsProviderService + summary: ListDnsProviders + operationId: mantrae.v1.DnsProviderService.ListDnsProviders.get + parameters: + - name: Connect-Protocol-Version + in: header + required: true + schema: + $ref: '#/components/schemas/connect-protocol-version' + - name: Connect-Timeout-Ms + in: header + schema: + $ref: '#/components/schemas/connect-timeout-header' + - name: message + in: query + content: + application/json: + schema: + $ref: '#/components/schemas/mantrae.v1.ListDnsProvidersRequest' + - name: encoding + in: query + required: true + schema: + $ref: '#/components/schemas/encoding' + - name: base64 + in: query + schema: + $ref: '#/components/schemas/base64' + - name: compression + in: query + schema: + $ref: '#/components/schemas/compression' + - name: connect + in: query + schema: + $ref: '#/components/schemas/connect' + responses: + default: + description: Error + content: + application/json: + schema: + $ref: '#/components/schemas/connect.error' + "200": + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/mantrae.v1.ListDnsProvidersResponse' + post: + tags: + - mantrae.v1.DnsProviderService + summary: ListDnsProviders + operationId: mantrae.v1.DnsProviderService.ListDnsProviders + parameters: + - name: Connect-Protocol-Version + in: header + required: true + schema: + $ref: '#/components/schemas/connect-protocol-version' + - name: Connect-Timeout-Ms + in: header + schema: + $ref: '#/components/schemas/connect-timeout-header' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/mantrae.v1.ListDnsProvidersRequest' + required: true + responses: + default: + description: Error + content: + application/json: + schema: + $ref: '#/components/schemas/connect.error' + "200": + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/mantrae.v1.ListDnsProvidersResponse' /mantrae.v1.EntryPointService/GetEntryPoint: get: tags: @@ -4671,10 +5146,81 @@ paths: application/json: schema: $ref: '#/components/schemas/mantrae.v1.ListUsersResponse' + /mantrae.v1.UtilService/GetVersion: + post: + tags: + - mantrae.v1.UtilService + summary: GetVersion + operationId: mantrae.v1.UtilService.GetVersion + parameters: + - name: Connect-Protocol-Version + in: header + required: true + schema: + $ref: '#/components/schemas/connect-protocol-version' + - name: Connect-Timeout-Ms + in: header + schema: + $ref: '#/components/schemas/connect-timeout-header' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/mantrae.v1.GetVersionRequest' + required: true + responses: + default: + description: Error + content: + application/json: + schema: + $ref: '#/components/schemas/connect.error' + "200": + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/mantrae.v1.GetVersionResponse' + /mantrae.v1.UtilService/GetPublicIP: + post: + tags: + - mantrae.v1.UtilService + summary: GetPublicIP + operationId: mantrae.v1.UtilService.GetPublicIP + parameters: + - name: Connect-Protocol-Version + in: header + required: true + schema: + $ref: '#/components/schemas/connect-protocol-version' + - name: Connect-Timeout-Ms + in: header + schema: + $ref: '#/components/schemas/connect-timeout-header' + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/mantrae.v1.GetPublicIPRequest' + required: true + responses: + default: + description: Error + content: + application/json: + schema: + $ref: '#/components/schemas/connect.error' + "200": + description: Success + content: + application/json: + schema: + $ref: '#/components/schemas/mantrae.v1.GetPublicIPResponse' tags: - name: mantrae.v1.AgentService - name: mantrae.v1.AgentManagementService - name: mantrae.v1.BackupService + - name: mantrae.v1.DnsProviderService - name: mantrae.v1.EntryPointService - name: mantrae.v1.MiddlewareService - name: mantrae.v1.ProfileService @@ -4682,3 +5228,4 @@ tags: - name: mantrae.v1.ServiceService - name: mantrae.v1.SettingService - name: mantrae.v1.UserService + - name: mantrae.v1.UtilService diff --git a/proto/mantrae/v1/dns_provider.proto b/proto/mantrae/v1/dns_provider.proto new file mode 100644 index 0000000..a0326c8 --- /dev/null +++ b/proto/mantrae/v1/dns_provider.proto @@ -0,0 +1,77 @@ +syntax = "proto3"; + +package mantrae.v1; + +import "google/protobuf/timestamp.proto"; + +service DnsProviderService { + rpc GetDnsProvider(GetDnsProviderRequest) returns (GetDnsProviderResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } + rpc CreateDnsProvider(CreateDnsProviderRequest) returns (CreateDnsProviderResponse); + rpc UpdateDnsProvider(UpdateDnsProviderRequest) returns (UpdateDnsProviderResponse); + rpc DeleteDnsProvider(DeleteDnsProviderRequest) returns (DeleteDnsProviderResponse); + rpc ListDnsProviders(ListDnsProvidersRequest) returns (ListDnsProvidersResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } +} + +message DnsProvider { + int64 id = 1; + string name = 2; + string type = 3; + DnsProviderConfig config = 4; + bool is_active = 5; + google.protobuf.Timestamp created_at = 6; + google.protobuf.Timestamp updated_at = 7; +} + +message DnsProviderConfig { + string api_key = 1; + string api_url = 2; + string ip = 3; + bool proxied = 4; + bool auto_update = 5; + string zone_type = 6; +} + +message GetDnsProviderRequest { + int64 id = 1; +} +message GetDnsProviderResponse { + DnsProvider dns_provider = 1; +} + +message CreateDnsProviderRequest { + string name = 1; + string type = 2; + DnsProviderConfig config = 3; + bool is_active = 4; +} +message CreateDnsProviderResponse { + DnsProvider dns_provider = 1; +} + +message UpdateDnsProviderRequest { + string name = 2; + string type = 3; + DnsProviderConfig config = 4; + bool is_active = 5; +} +message UpdateDnsProviderResponse { + DnsProvider dns_provider = 1; +} + +message DeleteDnsProviderRequest { + int64 id = 1; +} +message DeleteDnsProviderResponse {} + +message ListDnsProvidersRequest { + optional int64 limit = 1; + optional int64 offset = 2; +} +message ListDnsProvidersResponse { + repeated DnsProvider dns_providers = 1; + int64 total_count = 2; +} diff --git a/proto/mantrae/v1/util.proto b/proto/mantrae/v1/util.proto new file mode 100644 index 0000000..48894c5 --- /dev/null +++ b/proto/mantrae/v1/util.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; + +package mantrae.v1; + +import "google/protobuf/timestamp.proto"; + +service UtilService { + rpc GetVersion(GetVersionRequest) returns (GetVersionResponse); + rpc GetPublicIP(GetPublicIPRequest) returns (GetPublicIPResponse); +} + +message GetVersionRequest {} +message GetVersionResponse { + string version = 1; +} + +message GetPublicIPRequest {} +message GetPublicIPResponse { + string ipv4 = 1; + string ipv6 = 2; +} diff --git a/web/package.json b/web/package.json index e8e6bd0..1912672 100644 --- a/web/package.json +++ b/web/package.json @@ -11,39 +11,42 @@ "format": "prettier --write ." }, "devDependencies": { - "@eslint/js": "^9.28.0", + "@bufbuild/protobuf": "^2.5.2", + "@connectrpc/connect": "^2.0.2", + "@connectrpc/connect-web": "^2.0.2", + "@eslint/js": "^9.29.0", "@lucide/svelte": "^0.488.0", "@sveltejs/adapter-static": "^3.0.8", - "@sveltejs/kit": "^2.21.2", + "@sveltejs/kit": "^2.21.5", "@sveltejs/vite-plugin-svelte": "^5.1.0", - "@tailwindcss/postcss": "^4.1.8", + "@tailwindcss/postcss": "^4.1.10", "@types/eslint": "^9.6.1", - "@types/node": "^22.15.30", + "@types/node": "^22.15.32", "bits-ui": "1.0.0-next.98", "clsx": "^2.1.1", - "eslint": "^9.28.0", + "eslint": "^9.29.0", "eslint-config-prettier": "^10.1.5", - "eslint-plugin-svelte": "^3.9.1", + "eslint-plugin-svelte": "^3.9.2", "formsnap": "^2.0.1", "globals": "^16.2.0", "mode-watcher": "^0.5.1", "prettier": "^3.5.3", "prettier-plugin-svelte": "^3.4.0", "prettier-plugin-tailwindcss": "^0.6.12", - "svelte": "^5.33.15", + "svelte": "^5.34.5", "svelte-check": "^4.2.1", "svelte-highlight": "^7.8.3", "svelte-sonner": "^0.3.28", - "sveltekit-superforms": "^2.26.1", - "tailwind-merge": "^3.3.0", + "sveltekit-superforms": "^2.27.0", + "tailwind-merge": "^3.3.1", "tailwind-variants": "^1.0.0", - "tailwindcss": "^4.1.8", + "tailwindcss": "^4.1.10", "tailwindcss-animate": "^1.0.7", "typescript": "^5.8.3", - "typescript-eslint": "^8.33.1", + "typescript-eslint": "^8.34.1", "vite": "^6.3.5", "yaml": "^2.8.0", - "zod": "^3.25.56" + "zod": "^3.25.67" }, "type": "module", "dependencies": { diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index fc624e6..df5a443 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -15,105 +15,114 @@ importers: specifier: ^8.21.3 version: 8.21.3 devDependencies: + '@bufbuild/protobuf': + specifier: ^2.5.2 + version: 2.5.2 + '@connectrpc/connect': + specifier: ^2.0.2 + version: 2.0.2(@bufbuild/protobuf@2.5.2) + '@connectrpc/connect-web': + specifier: ^2.0.2 + version: 2.0.2(@bufbuild/protobuf@2.5.2)(@connectrpc/connect@2.0.2(@bufbuild/protobuf@2.5.2)) '@eslint/js': - specifier: ^9.28.0 - version: 9.28.0 + specifier: ^9.29.0 + version: 9.29.0 '@lucide/svelte': specifier: ^0.488.0 - version: 0.488.0(svelte@5.33.15) + version: 0.488.0(svelte@5.34.5) '@sveltejs/adapter-static': specifier: ^3.0.8 - version: 3.0.8(@sveltejs/kit@2.21.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))) + version: 3.0.8(@sveltejs/kit@2.21.5(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))) '@sveltejs/kit': - specifier: ^2.21.2 - version: 2.21.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + specifier: ^2.21.5 + version: 2.21.5(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) '@sveltejs/vite-plugin-svelte': specifier: ^5.1.0 - version: 5.1.0(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 5.1.0(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) '@tailwindcss/postcss': - specifier: ^4.1.8 - version: 4.1.8 + specifier: ^4.1.10 + version: 4.1.10 '@types/eslint': specifier: ^9.6.1 version: 9.6.1 '@types/node': - specifier: ^22.15.30 - version: 22.15.30 + specifier: ^22.15.32 + version: 22.15.32 bits-ui: specifier: 1.0.0-next.98 - version: 1.0.0-next.98(svelte@5.33.15) + version: 1.0.0-next.98(svelte@5.34.5) clsx: specifier: ^2.1.1 version: 2.1.1 eslint: - specifier: ^9.28.0 - version: 9.28.0(jiti@2.4.2) + specifier: ^9.29.0 + version: 9.29.0(jiti@2.4.2) eslint-config-prettier: specifier: ^10.1.5 - version: 10.1.5(eslint@9.28.0(jiti@2.4.2)) + version: 10.1.5(eslint@9.29.0(jiti@2.4.2)) eslint-plugin-svelte: - specifier: ^3.9.1 - version: 3.9.1(eslint@9.28.0(jiti@2.4.2))(svelte@5.33.15) + specifier: ^3.9.2 + version: 3.9.2(eslint@9.29.0(jiti@2.4.2))(svelte@5.34.5) formsnap: specifier: ^2.0.1 - version: 2.0.1(svelte@5.33.15)(sveltekit-superforms@2.26.1(@sveltejs/kit@2.21.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(@types/json-schema@7.0.15)(svelte@5.33.15)(typescript@5.8.3)) + version: 2.0.1(svelte@5.34.5)(sveltekit-superforms@2.27.0(@sveltejs/kit@2.21.5(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.34.5)(typescript@5.8.3)) globals: specifier: ^16.2.0 version: 16.2.0 mode-watcher: specifier: ^0.5.1 - version: 0.5.1(svelte@5.33.15) + version: 0.5.1(svelte@5.34.5) prettier: specifier: ^3.5.3 version: 3.5.3 prettier-plugin-svelte: specifier: ^3.4.0 - version: 3.4.0(prettier@3.5.3)(svelte@5.33.15) + version: 3.4.0(prettier@3.5.3)(svelte@5.34.5) prettier-plugin-tailwindcss: specifier: ^0.6.12 - version: 0.6.12(prettier-plugin-svelte@3.4.0(prettier@3.5.3)(svelte@5.33.15))(prettier@3.5.3) + version: 0.6.12(prettier-plugin-svelte@3.4.0(prettier@3.5.3)(svelte@5.34.5))(prettier@3.5.3) svelte: - specifier: ^5.33.15 - version: 5.33.15 + specifier: ^5.34.5 + version: 5.34.5 svelte-check: specifier: ^4.2.1 - version: 4.2.1(picomatch@4.0.2)(svelte@5.33.15)(typescript@5.8.3) + version: 4.2.1(picomatch@4.0.2)(svelte@5.34.5)(typescript@5.8.3) svelte-highlight: specifier: ^7.8.3 version: 7.8.3 svelte-sonner: specifier: ^0.3.28 - version: 0.3.28(svelte@5.33.15) + version: 0.3.28(svelte@5.34.5) sveltekit-superforms: - specifier: ^2.26.1 - version: 2.26.1(@sveltejs/kit@2.21.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(@types/json-schema@7.0.15)(svelte@5.33.15)(typescript@5.8.3) + specifier: ^2.27.0 + version: 2.27.0(@sveltejs/kit@2.21.5(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.34.5)(typescript@5.8.3) tailwind-merge: - specifier: ^3.3.0 - version: 3.3.0 + specifier: ^3.3.1 + version: 3.3.1 tailwind-variants: specifier: ^1.0.0 - version: 1.0.0(tailwindcss@4.1.8) + version: 1.0.0(tailwindcss@4.1.10) tailwindcss: - specifier: ^4.1.8 - version: 4.1.8 + specifier: ^4.1.10 + version: 4.1.10 tailwindcss-animate: specifier: ^1.0.7 - version: 1.0.7(tailwindcss@4.1.8) + version: 1.0.7(tailwindcss@4.1.10) typescript: specifier: ^5.8.3 version: 5.8.3 typescript-eslint: - specifier: ^8.33.1 - version: 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + specifier: ^8.34.1 + version: 8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) vite: specifier: ^6.3.5 - version: 6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) yaml: specifier: ^2.8.0 version: 2.8.0 zod: - specifier: ^3.25.56 - version: 3.25.56 + specifier: ^3.25.67 + version: 3.25.67 packages: @@ -135,6 +144,20 @@ packages: resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} engines: {node: '>=6.9.0'} + '@bufbuild/protobuf@2.5.2': + resolution: {integrity: sha512-foZ7qr0IsUBjzWIq+SuBLfdQCpJ1j8cTuNNT4owngTHoN5KsJb8L9t65fzz7SCeSWzescoOil/0ldqiL041ABg==} + + '@connectrpc/connect-web@2.0.2': + resolution: {integrity: sha512-QANMFPiL2o66BdBEctg4TsQLe5ozsBLqcle3dCBp7BwGlNGTY6NnNnqmt+YRnpeMW88GgomJwWNMGCrRD9pRKA==} + peerDependencies: + '@bufbuild/protobuf': ^2.2.0 + '@connectrpc/connect': 2.0.2 + + '@connectrpc/connect@2.0.2': + resolution: {integrity: sha512-xZuylIUNvNlH52e/4eQsZvY4QZyDJRtEFEDnn/yBrv5Xi5ZZI/p8X+GAHH35ucVaBvv9u7OzHZo8+tEh1EFTxA==} + peerDependencies: + '@bufbuild/protobuf': ^2.2.0 + '@esbuild/aix-ppc64@0.25.5': resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==} engines: {node: '>=18'} @@ -295,32 +318,36 @@ packages: resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/config-array@0.20.0': - resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==} + '@eslint/config-array@0.20.1': + resolution: {integrity: sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/config-helpers@0.2.2': - resolution: {integrity: sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==} + '@eslint/config-helpers@0.2.3': + resolution: {integrity: sha512-u180qk2Um1le4yf0ruXH3PYFeEZeYC3p/4wCTKrr2U1CmGdzGi3KtY0nuPDH48UJxlKCC5RDzbcbh4X0XlqgHg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/core@0.14.0': resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@0.15.0': + resolution: {integrity: sha512-b7ePw78tEWWkpgZCDYkbqDOP8dmM6qe+AOC6iuJqlq1R/0ahMAeH3qynpnqKFGkMltrp44ohV4ubGyvLX28tzw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/eslintrc@3.3.1': resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.28.0': - resolution: {integrity: sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==} + '@eslint/js@9.29.0': + resolution: {integrity: sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.6': resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.3.1': - resolution: {integrity: sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==} + '@eslint/plugin-kit@0.3.2': + resolution: {integrity: sha512-4SaFZCNfJqvk/kenHpI8xvN42DMaoycy4PzKc5otHxRswww1kAt82OlBuwRVLofCACCTZEcla2Ydxv8scMXaTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@exodus/schemasafe@1.3.0': @@ -335,8 +362,8 @@ packages: '@floating-ui/utils@0.2.9': resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} - '@gcornut/valibot-json-schema@0.31.0': - resolution: {integrity: sha512-3xGptCurm23e7nuPQkdrE5rEs1FeTPHhAUsBuwwqG4/YeZLwJOoYZv+fmsppUEfo5y9lzUwNQrNqLS/q7HMc7g==} + '@gcornut/valibot-json-schema@0.42.0': + resolution: {integrity: sha512-4Et4AN6wmqeA0PfU5Clkv/IS27wiefsWf6TemAZrb75uzkClYEFavim7SboeKwbll9Nbsn2Iv0LT/HS5H7orZg==} hasBin: true '@hapi/hoek@9.3.0': @@ -414,103 +441,103 @@ packages: resolution: {integrity: sha512-ct43jurbe7lsUX5eIrj4ijO3j/6zIPp7CDnFWXDs7UPAbw1Pu1iH3oAmFdP4jcskKJBURH5M9oTtyeiUXyHX8Q==} engines: {node: '>=18.16.0'} - '@rollup/rollup-android-arm-eabi@4.42.0': - resolution: {integrity: sha512-gldmAyS9hpj+H6LpRNlcjQWbuKUtb94lodB9uCz71Jm+7BxK1VIOo7y62tZZwxhA7j1ylv/yQz080L5WkS+LoQ==} + '@rollup/rollup-android-arm-eabi@4.43.0': + resolution: {integrity: sha512-Krjy9awJl6rKbruhQDgivNbD1WuLb8xAclM4IR4cN5pHGAs2oIMMQJEiC3IC/9TZJ+QZkmZhlMO/6MBGxPidpw==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.42.0': - resolution: {integrity: sha512-bpRipfTgmGFdCZDFLRvIkSNO1/3RGS74aWkJJTFJBH7h3MRV4UijkaEUeOMbi9wxtxYmtAbVcnMtHTPBhLEkaw==} + '@rollup/rollup-android-arm64@4.43.0': + resolution: {integrity: sha512-ss4YJwRt5I63454Rpj+mXCXicakdFmKnUNxr1dLK+5rv5FJgAxnN7s31a5VchRYxCFWdmnDWKd0wbAdTr0J5EA==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.42.0': - resolution: {integrity: sha512-JxHtA081izPBVCHLKnl6GEA0w3920mlJPLh89NojpU2GsBSB6ypu4erFg/Wx1qbpUbepn0jY4dVWMGZM8gplgA==} + '@rollup/rollup-darwin-arm64@4.43.0': + resolution: {integrity: sha512-eKoL8ykZ7zz8MjgBenEF2OoTNFAPFz1/lyJ5UmmFSz5jW+7XbH1+MAgCVHy72aG59rbuQLcJeiMrP8qP5d/N0A==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.42.0': - resolution: {integrity: sha512-rv5UZaWVIJTDMyQ3dCEK+m0SAn6G7H3PRc2AZmExvbDvtaDc+qXkei0knQWcI3+c9tEs7iL/4I4pTQoPbNL2SA==} + '@rollup/rollup-darwin-x64@4.43.0': + resolution: {integrity: sha512-SYwXJgaBYW33Wi/q4ubN+ldWC4DzQY62S4Ll2dgfr/dbPoF50dlQwEaEHSKrQdSjC6oIe1WgzosoaNoHCdNuMg==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.42.0': - resolution: {integrity: sha512-fJcN4uSGPWdpVmvLuMtALUFwCHgb2XiQjuECkHT3lWLZhSQ3MBQ9pq+WoWeJq2PrNxr9rPM1Qx+IjyGj8/c6zQ==} + '@rollup/rollup-freebsd-arm64@4.43.0': + resolution: {integrity: sha512-SV+U5sSo0yujrjzBF7/YidieK2iF6E7MdF6EbYxNz94lA+R0wKl3SiixGyG/9Klab6uNBIqsN7j4Y/Fya7wAjQ==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.42.0': - resolution: {integrity: sha512-CziHfyzpp8hJpCVE/ZdTizw58gr+m7Y2Xq5VOuCSrZR++th2xWAz4Nqk52MoIIrV3JHtVBhbBsJcAxs6NammOQ==} + '@rollup/rollup-freebsd-x64@4.43.0': + resolution: {integrity: sha512-J7uCsiV13L/VOeHJBo5SjasKiGxJ0g+nQTrBkAsmQBIdil3KhPnSE9GnRon4ejX1XDdsmK/l30IYLiAaQEO0Cg==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.42.0': - resolution: {integrity: sha512-UsQD5fyLWm2Fe5CDM7VPYAo+UC7+2Px4Y+N3AcPh/LdZu23YcuGPegQly++XEVaC8XUTFVPscl5y5Cl1twEI4A==} + '@rollup/rollup-linux-arm-gnueabihf@4.43.0': + resolution: {integrity: sha512-gTJ/JnnjCMc15uwB10TTATBEhK9meBIY+gXP4s0sHD1zHOaIh4Dmy1X9wup18IiY9tTNk5gJc4yx9ctj/fjrIw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.42.0': - resolution: {integrity: sha512-/i8NIrlgc/+4n1lnoWl1zgH7Uo0XK5xK3EDqVTf38KvyYgCU/Rm04+o1VvvzJZnVS5/cWSd07owkzcVasgfIkQ==} + '@rollup/rollup-linux-arm-musleabihf@4.43.0': + resolution: {integrity: sha512-ZJ3gZynL1LDSIvRfz0qXtTNs56n5DI2Mq+WACWZ7yGHFUEirHBRt7fyIk0NsCKhmRhn7WAcjgSkSVVxKlPNFFw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.42.0': - resolution: {integrity: sha512-eoujJFOvoIBjZEi9hJnXAbWg+Vo1Ov8n/0IKZZcPZ7JhBzxh2A+2NFyeMZIRkY9iwBvSjloKgcvnjTbGKHE44Q==} + '@rollup/rollup-linux-arm64-gnu@4.43.0': + resolution: {integrity: sha512-8FnkipasmOOSSlfucGYEu58U8cxEdhziKjPD2FIa0ONVMxvl/hmONtX/7y4vGjdUhjcTHlKlDhw3H9t98fPvyA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.42.0': - resolution: {integrity: sha512-/3NrcOWFSR7RQUQIuZQChLND36aTU9IYE4j+TB40VU78S+RA0IiqHR30oSh6P1S9f9/wVOenHQnacs/Byb824g==} + '@rollup/rollup-linux-arm64-musl@4.43.0': + resolution: {integrity: sha512-KPPyAdlcIZ6S9C3S2cndXDkV0Bb1OSMsX0Eelr2Bay4EsF9yi9u9uzc9RniK3mcUGCLhWY9oLr6er80P5DE6XA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.42.0': - resolution: {integrity: sha512-O8AplvIeavK5ABmZlKBq9/STdZlnQo7Sle0LLhVA7QT+CiGpNVe197/t8Aph9bhJqbDVGCHpY2i7QyfEDDStDg==} + '@rollup/rollup-linux-loongarch64-gnu@4.43.0': + resolution: {integrity: sha512-HPGDIH0/ZzAZjvtlXj6g+KDQ9ZMHfSP553za7o2Odegb/BEfwJcR0Sw0RLNpQ9nC6Gy8s+3mSS9xjZ0n3rhcYg==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.42.0': - resolution: {integrity: sha512-6Qb66tbKVN7VyQrekhEzbHRxXXFFD8QKiFAwX5v9Xt6FiJ3BnCVBuyBxa2fkFGqxOCSGGYNejxd8ht+q5SnmtA==} + '@rollup/rollup-linux-powerpc64le-gnu@4.43.0': + resolution: {integrity: sha512-gEmwbOws4U4GLAJDhhtSPWPXUzDfMRedT3hFMyRAvM9Mrnj+dJIFIeL7otsv2WF3D7GrV0GIewW0y28dOYWkmw==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.42.0': - resolution: {integrity: sha512-KQETDSEBamQFvg/d8jajtRwLNBlGc3aKpaGiP/LvEbnmVUKlFta1vqJqTrvPtsYsfbE/DLg5CC9zyXRX3fnBiA==} + '@rollup/rollup-linux-riscv64-gnu@4.43.0': + resolution: {integrity: sha512-XXKvo2e+wFtXZF/9xoWohHg+MuRnvO29TI5Hqe9xwN5uN8NKUYy7tXUG3EZAlfchufNCTHNGjEx7uN78KsBo0g==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.42.0': - resolution: {integrity: sha512-qMvnyjcU37sCo/tuC+JqeDKSuukGAd+pVlRl/oyDbkvPJ3awk6G6ua7tyum02O3lI+fio+eM5wsVd66X0jQtxw==} + '@rollup/rollup-linux-riscv64-musl@4.43.0': + resolution: {integrity: sha512-ruf3hPWhjw6uDFsOAzmbNIvlXFXlBQ4nk57Sec8E8rUxs/AI4HD6xmiiasOOx/3QxS2f5eQMKTAwk7KHwpzr/Q==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.42.0': - resolution: {integrity: sha512-I2Y1ZUgTgU2RLddUHXTIgyrdOwljjkmcZ/VilvaEumtS3Fkuhbw4p4hgHc39Ypwvo2o7sBFNl2MquNvGCa55Iw==} + '@rollup/rollup-linux-s390x-gnu@4.43.0': + resolution: {integrity: sha512-QmNIAqDiEMEvFV15rsSnjoSmO0+eJLoKRD9EAa9rrYNwO/XRCtOGM3A5A0X+wmG+XRrw9Fxdsw+LnyYiZWWcVw==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.42.0': - resolution: {integrity: sha512-Gfm6cV6mj3hCUY8TqWa63DB8Mx3NADoFwiJrMpoZ1uESbK8FQV3LXkhfry+8bOniq9pqY1OdsjFWNsSbfjPugw==} + '@rollup/rollup-linux-x64-gnu@4.43.0': + resolution: {integrity: sha512-jAHr/S0iiBtFyzjhOkAics/2SrXE092qyqEg96e90L3t9Op8OTzS6+IX0Fy5wCt2+KqeHAkti+eitV0wvblEoQ==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.42.0': - resolution: {integrity: sha512-g86PF8YZ9GRqkdi0VoGlcDUb4rYtQKyTD1IVtxxN4Hpe7YqLBShA7oHMKU6oKTCi3uxwW4VkIGnOaH/El8de3w==} + '@rollup/rollup-linux-x64-musl@4.43.0': + resolution: {integrity: sha512-3yATWgdeXyuHtBhrLt98w+5fKurdqvs8B53LaoKD7P7H7FKOONLsBVMNl9ghPQZQuYcceV5CDyPfyfGpMWD9mQ==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.42.0': - resolution: {integrity: sha512-+axkdyDGSp6hjyzQ5m1pgcvQScfHnMCcsXkx8pTgy/6qBmWVhtRVlgxjWwDp67wEXXUr0x+vD6tp5W4x6V7u1A==} + '@rollup/rollup-win32-arm64-msvc@4.43.0': + resolution: {integrity: sha512-wVzXp2qDSCOpcBCT5WRWLmpJRIzv23valvcTwMHEobkjippNf+C3ys/+wf07poPkeNix0paTNemB2XrHr2TnGw==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.42.0': - resolution: {integrity: sha512-F+5J9pelstXKwRSDq92J0TEBXn2nfUrQGg+HK1+Tk7VOL09e0gBqUHugZv7SW4MGrYj41oNCUe3IKCDGVlis2g==} + '@rollup/rollup-win32-ia32-msvc@4.43.0': + resolution: {integrity: sha512-fYCTEyzf8d+7diCw8b+asvWDCLMjsCEA8alvtAutqJOJp/wL5hs1rWSqJ1vkjgW0L2NB4bsYJrpKkiIPRR9dvw==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.42.0': - resolution: {integrity: sha512-LpHiJRwkaVz/LqjHjK8LCi8osq7elmpwujwbXKNW88bM8eeGxavJIKKjkjpMHAh/2xfnrt1ZSnhTv41WYUHYmA==} + '@rollup/rollup-win32-x64-msvc@4.43.0': + resolution: {integrity: sha512-SnGhLiE5rlK0ofq8kzuDkM0g7FN1s5VYY+YSMTibP7CqShxCQvqtNxTARS4xX4PFJfHjG0ZQYX9iGzI3FQh5Aw==} cpu: [x64] os: [win32] @@ -523,8 +550,8 @@ packages: '@sideway/pinpoint@2.0.0': resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} - '@sinclair/typebox@0.34.33': - resolution: {integrity: sha512-5HAV9exOMcXRUxo+9iYB5n09XxzCXnfy4VTNW4xnDv+FgjzAGY989C28BIdljKqmF+ZltUwujE3aossvcVtq6g==} + '@sinclair/typebox@0.34.35': + resolution: {integrity: sha512-C6ypdODf2VZkgRT6sFM8E1F8vR+HcffniX0Kp8MsU8PIfrlXbNCBz0jzj17GjdmjTx1OtZzdH8+iALL21UjF5A==} '@standard-schema/spec@1.0.0': resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} @@ -539,8 +566,8 @@ packages: peerDependencies: '@sveltejs/kit': ^2.0.0 - '@sveltejs/kit@2.21.2': - resolution: {integrity: sha512-EMYTY4+rNa7TaRZYzCqhQslEkACEZzWc363jOYuc90oJrgvlWTcgqTxcGSIJim48hPaXwYlHyatRnnMmTFf5tA==} + '@sveltejs/kit@2.21.5': + resolution: {integrity: sha512-P5m7yZtvD1Kx/Z6JcjgJtdMqef/tCGMDrd9B9S2q8j+FMnkeKTMxW1nidnjVzk4HEDRGf4IlBI94/niy6t3hLA==} engines: {node: '>=18.13'} hasBin: true peerDependencies: @@ -566,65 +593,65 @@ packages: '@swc/helpers@0.5.17': resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} - '@tailwindcss/node@4.1.8': - resolution: {integrity: sha512-OWwBsbC9BFAJelmnNcrKuf+bka2ZxCE2A4Ft53Tkg4uoiE67r/PMEYwCsourC26E+kmxfwE0hVzMdxqeW+xu7Q==} + '@tailwindcss/node@4.1.10': + resolution: {integrity: sha512-2ACf1znY5fpRBwRhMgj9ZXvb2XZW8qs+oTfotJ2C5xR0/WNL7UHZ7zXl6s+rUqedL1mNi+0O+WQr5awGowS3PQ==} - '@tailwindcss/oxide-android-arm64@4.1.8': - resolution: {integrity: sha512-Fbz7qni62uKYceWYvUjRqhGfZKwhZDQhlrJKGtnZfuNtHFqa8wmr+Wn74CTWERiW2hn3mN5gTpOoxWKk0jRxjg==} + '@tailwindcss/oxide-android-arm64@4.1.10': + resolution: {integrity: sha512-VGLazCoRQ7rtsCzThaI1UyDu/XRYVyH4/EWiaSX6tFglE+xZB5cvtC5Omt0OQ+FfiIVP98su16jDVHDEIuH4iQ==} engines: {node: '>= 10'} cpu: [arm64] os: [android] - '@tailwindcss/oxide-darwin-arm64@4.1.8': - resolution: {integrity: sha512-RdRvedGsT0vwVVDztvyXhKpsU2ark/BjgG0huo4+2BluxdXo8NDgzl77qh0T1nUxmM11eXwR8jA39ibvSTbi7A==} + '@tailwindcss/oxide-darwin-arm64@4.1.10': + resolution: {integrity: sha512-ZIFqvR1irX2yNjWJzKCqTCcHZbgkSkSkZKbRM3BPzhDL/18idA8uWCoopYA2CSDdSGFlDAxYdU2yBHwAwx8euQ==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@tailwindcss/oxide-darwin-x64@4.1.8': - resolution: {integrity: sha512-t6PgxjEMLp5Ovf7uMb2OFmb3kqzVTPPakWpBIFzppk4JE4ix0yEtbtSjPbU8+PZETpaYMtXvss2Sdkx8Vs4XRw==} + '@tailwindcss/oxide-darwin-x64@4.1.10': + resolution: {integrity: sha512-eCA4zbIhWUFDXoamNztmS0MjXHSEJYlvATzWnRiTqJkcUteSjO94PoRHJy1Xbwp9bptjeIxxBHh+zBWFhttbrQ==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@tailwindcss/oxide-freebsd-x64@4.1.8': - resolution: {integrity: sha512-g8C8eGEyhHTqwPStSwZNSrOlyx0bhK/V/+zX0Y+n7DoRUzyS8eMbVshVOLJTDDC+Qn9IJnilYbIKzpB9n4aBsg==} + '@tailwindcss/oxide-freebsd-x64@4.1.10': + resolution: {integrity: sha512-8/392Xu12R0cc93DpiJvNpJ4wYVSiciUlkiOHOSOQNH3adq9Gi/dtySK7dVQjXIOzlpSHjeCL89RUUI8/GTI6g==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.8': - resolution: {integrity: sha512-Jmzr3FA4S2tHhaC6yCjac3rGf7hG9R6Gf2z9i9JFcuyy0u79HfQsh/thifbYTF2ic82KJovKKkIB6Z9TdNhCXQ==} + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.10': + resolution: {integrity: sha512-t9rhmLT6EqeuPT+MXhWhlRYIMSfh5LZ6kBrC4FS6/+M1yXwfCtp24UumgCWOAJVyjQwG+lYva6wWZxrfvB+NhQ==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@tailwindcss/oxide-linux-arm64-gnu@4.1.8': - resolution: {integrity: sha512-qq7jXtO1+UEtCmCeBBIRDrPFIVI4ilEQ97qgBGdwXAARrUqSn/L9fUrkb1XP/mvVtoVeR2bt/0L77xx53bPZ/Q==} + '@tailwindcss/oxide-linux-arm64-gnu@4.1.10': + resolution: {integrity: sha512-3oWrlNlxLRxXejQ8zImzrVLuZ/9Z2SeKoLhtCu0hpo38hTO2iL86eFOu4sVR8cZc6n3z7eRXXqtHJECa6mFOvA==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-arm64-musl@4.1.8': - resolution: {integrity: sha512-O6b8QesPbJCRshsNApsOIpzKt3ztG35gfX9tEf4arD7mwNinsoCKxkj8TgEE0YRjmjtO3r9FlJnT/ENd9EVefQ==} + '@tailwindcss/oxide-linux-arm64-musl@4.1.10': + resolution: {integrity: sha512-saScU0cmWvg/Ez4gUmQWr9pvY9Kssxt+Xenfx1LG7LmqjcrvBnw4r9VjkFcqmbBb7GCBwYNcZi9X3/oMda9sqQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-x64-gnu@4.1.8': - resolution: {integrity: sha512-32iEXX/pXwikshNOGnERAFwFSfiltmijMIAbUhnNyjFr3tmWmMJWQKU2vNcFX0DACSXJ3ZWcSkzNbaKTdngH6g==} + '@tailwindcss/oxide-linux-x64-gnu@4.1.10': + resolution: {integrity: sha512-/G3ao/ybV9YEEgAXeEg28dyH6gs1QG8tvdN9c2MNZdUXYBaIY/Gx0N6RlJzfLy/7Nkdok4kaxKPHKJUlAaoTdA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-linux-x64-musl@4.1.8': - resolution: {integrity: sha512-s+VSSD+TfZeMEsCaFaHTaY5YNj3Dri8rST09gMvYQKwPphacRG7wbuQ5ZJMIJXN/puxPcg/nU+ucvWguPpvBDg==} + '@tailwindcss/oxide-linux-x64-musl@4.1.10': + resolution: {integrity: sha512-LNr7X8fTiKGRtQGOerSayc2pWJp/9ptRYAa4G+U+cjw9kJZvkopav1AQc5HHD+U364f71tZv6XamaHKgrIoVzA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-wasm32-wasi@4.1.8': - resolution: {integrity: sha512-CXBPVFkpDjM67sS1psWohZ6g/2/cd+cq56vPxK4JeawelxwK4YECgl9Y9TjkE2qfF+9/s1tHHJqrC4SS6cVvSg==} + '@tailwindcss/oxide-wasm32-wasi@4.1.10': + resolution: {integrity: sha512-d6ekQpopFQJAcIK2i7ZzWOYGZ+A6NzzvQ3ozBvWFdeyqfOZdYHU66g5yr+/HC4ipP1ZgWsqa80+ISNILk+ae/Q==} engines: {node: '>=14.0.0'} cpu: [wasm32] bundledDependencies: @@ -635,24 +662,24 @@ packages: - '@emnapi/wasi-threads' - tslib - '@tailwindcss/oxide-win32-arm64-msvc@4.1.8': - resolution: {integrity: sha512-7GmYk1n28teDHUjPlIx4Z6Z4hHEgvP5ZW2QS9ygnDAdI/myh3HTHjDqtSqgu1BpRoI4OiLx+fThAyA1JePoENA==} + '@tailwindcss/oxide-win32-arm64-msvc@4.1.10': + resolution: {integrity: sha512-i1Iwg9gRbwNVOCYmnigWCCgow8nDWSFmeTUU5nbNx3rqbe4p0kRbEqLwLJbYZKmSSp23g4N6rCDmm7OuPBXhDA==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@tailwindcss/oxide-win32-x64-msvc@4.1.8': - resolution: {integrity: sha512-fou+U20j+Jl0EHwK92spoWISON2OBnCazIc038Xj2TdweYV33ZRkS9nwqiUi2d/Wba5xg5UoHfvynnb/UB49cQ==} + '@tailwindcss/oxide-win32-x64-msvc@4.1.10': + resolution: {integrity: sha512-sGiJTjcBSfGq2DVRtaSljq5ZgZS2SDHSIfhOylkBvHVjwOsodBhnb3HdmiKkVuUGKD0I7G63abMOVaskj1KpOA==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@tailwindcss/oxide@4.1.8': - resolution: {integrity: sha512-d7qvv9PsM5N3VNKhwVUhpK6r4h9wtLkJ6lz9ZY9aeZgrUWk1Z8VPyqyDT9MZlem7GTGseRQHkeB1j3tC7W1P+A==} + '@tailwindcss/oxide@4.1.10': + resolution: {integrity: sha512-v0C43s7Pjw+B9w21htrQwuFObSkio2aV/qPx/mhrRldbqxbWJK6KizM+q7BF1/1CmuLqZqX3CeYF7s7P9fbA8Q==} engines: {node: '>= 10'} - '@tailwindcss/postcss@4.1.8': - resolution: {integrity: sha512-vB/vlf7rIky+w94aWMw34bWW1ka6g6C3xIOdICKX2GC0VcLtL6fhlLiafF0DVIwa9V6EHz8kbWMkS2s2QvvNlw==} + '@tailwindcss/postcss@4.1.10': + resolution: {integrity: sha512-B+7r7ABZbkXJwpvt2VMnS6ujcDoR2OOcFaqrLIo1xbcdxje4Vf+VgJdBzNNbrAjBj/rLZ66/tlQ1knIGNLKOBQ==} '@tanstack/match-sorter-utils@8.19.4': resolution: {integrity: sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==} @@ -677,11 +704,11 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/node@22.15.30': - resolution: {integrity: sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA==} + '@types/node@22.15.32': + resolution: {integrity: sha512-3jigKqgSjsH6gYZv2nEsqdXfZqIFGAV36XYYjf9KGZ3PSG+IhLecqPnI310RvjutyMwifE2hhhNEklOUrvx/wA==} - '@types/validator@13.15.1': - resolution: {integrity: sha512-9gG6ogYcoI2mCMLdcO0NYI0AYrbxIjv0MDmy/5Ywo6CpWWrqYayc+mmgxRsCgtcGJm9BSbXkMsmxGah1iGHAAQ==} + '@types/validator@13.15.2': + resolution: {integrity: sha512-y7pa/oEJJ4iGYBxOpfAKn5b9+xuihvzDVnC/OSvlVnGxVg0pOqmjiMafiJ1KVNQEaPZf9HsEp5icEwGg8uIe5Q==} '@typeschema/class-validator@0.3.0': resolution: {integrity: sha512-OJSFeZDIQ8EK1HTljKLT5CItM2wsbgczLN8tMEfz3I1Lmhc5TBfkZ0eikFzUC16tI3d1Nag7um6TfCgp2I2Bww==} @@ -699,63 +726,63 @@ packages: '@types/json-schema': optional: true - '@typescript-eslint/eslint-plugin@8.33.1': - resolution: {integrity: sha512-TDCXj+YxLgtvxvFlAvpoRv9MAncDLBV2oT9Bd7YBGC/b/sEURoOYuIwLI99rjWOfY3QtDzO+mk0n4AmdFExW8A==} + '@typescript-eslint/eslint-plugin@8.34.1': + resolution: {integrity: sha512-STXcN6ebF6li4PxwNeFnqF8/2BNDvBupf2OPx2yWNzr6mKNGF7q49VM00Pz5FaomJyqvbXpY6PhO+T9w139YEQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.33.1 + '@typescript-eslint/parser': ^8.34.1 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/parser@8.33.1': - resolution: {integrity: sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA==} + '@typescript-eslint/parser@8.34.1': + resolution: {integrity: sha512-4O3idHxhyzjClSMJ0a29AcoK0+YwnEqzI6oz3vlRf3xw0zbzt15MzXwItOlnr5nIth6zlY2RENLsOPvhyrKAQA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/project-service@8.33.1': - resolution: {integrity: sha512-DZR0efeNklDIHHGRpMpR5gJITQpu6tLr9lDJnKdONTC7vvzOlLAG/wcfxcdxEWrbiZApcoBCzXqU/Z458Za5Iw==} + '@typescript-eslint/project-service@8.34.1': + resolution: {integrity: sha512-nuHlOmFZfuRwLJKDGQOVc0xnQrAmuq1Mj/ISou5044y1ajGNp2BNliIqp7F2LPQ5sForz8lempMFCovfeS1XoA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/scope-manager@8.33.1': - resolution: {integrity: sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==} + '@typescript-eslint/scope-manager@8.34.1': + resolution: {integrity: sha512-beu6o6QY4hJAgL1E8RaXNC071G4Kso2MGmJskCFQhRhg8VOH/FDbC8soP8NHN7e/Hdphwp8G8cE6OBzC8o41ZA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.33.1': - resolution: {integrity: sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g==} + '@typescript-eslint/tsconfig-utils@8.34.1': + resolution: {integrity: sha512-K4Sjdo4/xF9NEeA2khOb7Y5nY6NSXBnod87uniVYW9kHP+hNlDV8trUSFeynA2uxWam4gIWgWoygPrv9VMWrYg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/type-utils@8.33.1': - resolution: {integrity: sha512-1cG37d9xOkhlykom55WVwG2QRNC7YXlxMaMzqw2uPeJixBFfKWZgaP/hjAObqMN/u3fr5BrTwTnc31/L9jQ2ww==} + '@typescript-eslint/type-utils@8.34.1': + resolution: {integrity: sha512-Tv7tCCr6e5m8hP4+xFugcrwTOucB8lshffJ6zf1mF1TbU67R+ntCc6DzLNKM+s/uzDyv8gLq7tufaAhIBYeV8g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/types@8.33.1': - resolution: {integrity: sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==} + '@typescript-eslint/types@8.34.1': + resolution: {integrity: sha512-rjLVbmE7HR18kDsjNIZQHxmv9RZwlgzavryL5Lnj2ujIRTeXlKtILHgRNmQ3j4daw7zd+mQgy+uyt6Zo6I0IGA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.33.1': - resolution: {integrity: sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==} + '@typescript-eslint/typescript-estree@8.34.1': + resolution: {integrity: sha512-rjCNqqYPuMUF5ODD+hWBNmOitjBWghkGKJg6hiCHzUvXRy6rK22Jd3rwbP2Xi+R7oYVvIKhokHVhH41BxPV5mA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/utils@8.33.1': - resolution: {integrity: sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==} + '@typescript-eslint/utils@8.34.1': + resolution: {integrity: sha512-mqOwUdZ3KjtGk7xJJnLbHxTuWVn3GO2WZZuM+Slhkun4+qthLdXx32C8xIXbO1kfCECb3jIs3eoxK3eryk7aoQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/visitor-keys@8.33.1': - resolution: {integrity: sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==} + '@typescript-eslint/visitor-keys@8.34.1': + resolution: {integrity: sha512-xoh5rJ+tgsRKoXnkBPFRLZ7rjKM0AfVbC68UZ/ECXoDbfggb9RbEySN359acY1vS3qZ0jVTVWzbtfapwm5ztxw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@vinejs/compiler@3.0.0': @@ -771,8 +798,8 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@8.14.1: - resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} engines: {node: '>=0.4.0'} hasBin: true @@ -806,11 +833,11 @@ packages: peerDependencies: svelte: ^5.11.0 - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} @@ -898,8 +925,8 @@ packages: dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} - effect@3.16.4: - resolution: {integrity: sha512-zJo5MRPEMROLjTHyrOJs0PUeEnRLy0ABwum3+HWlP8Y9LNF+NjipIRldVAcjSVQpJ7vY/OEGBxzw0USPzTfWag==} + effect@3.16.8: + resolution: {integrity: sha512-E4U0MZFBun99myxOogy9ZZ1c3IYR47L/A5GqCP9Lp+6ORag0YLmGHOrYxQ3agN1FOMTrElgtJmciicwnHdE+Ug==} enhanced-resolve@5.18.1: resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} @@ -926,8 +953,8 @@ packages: peerDependencies: eslint: '>=7.0.0' - eslint-plugin-svelte@3.9.1: - resolution: {integrity: sha512-mXFulSdD/0/p+zwENjPNsiVwAqmSRp90sy5zvVQBX1yAXhJbdhIn6C/tn8BZYjU94Ia7Y87d1Xdbvi49DeWyHQ==} + eslint-plugin-svelte@3.9.2: + resolution: {integrity: sha512-aqzfHtG9RPaFhCUFm5QFC6eFY/yHFQIT8VYYFe7/mT2A9mbgVR3XV2keCqU19LN8iVD9mdvRvqHU+4+CzJImvg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.1 || ^9.0.0 @@ -936,20 +963,20 @@ packages: svelte: optional: true - eslint-scope@8.3.0: - resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint-visitor-keys@4.2.0: - resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.28.0: - resolution: {integrity: sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ==} + eslint@9.29.0: + resolution: {integrity: sha512-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -961,16 +988,16 @@ packages: esm-env@1.2.2: resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} - espree@10.3.0: - resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} esquery@1.6.0: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} - esrap@1.4.7: - resolution: {integrity: sha512-0ZxW6guTF/AeKeKi7he93lmgv7Hx7giD1tBrOeVqkqsZGQJd2/kfnL7LdIsr9FT/AtkBK9XeDTov+gxprBqdEg==} + esrap@1.4.9: + resolution: {integrity: sha512-3OMlcd0a03UGuZpPeUC1HxR3nA23l+HEyCiZw3b3FumJIN9KphoGzDJKMXI1S72jVS1dsenDyQC0kJlO1U9E1g==} esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} @@ -1004,8 +1031,8 @@ packages: fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} - fdir@6.4.5: - resolution: {integrity: sha512-4BG7puHpVsIYxZUbiUE3RqGloLaSSwzYie5jvasC4LWuBWzZawynvYouhjbQKw2JuIGYdm0DzIxl8iVidKlUEw==} + fdir@6.4.6: + resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -1287,8 +1314,8 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - normalize-url@8.0.1: - resolution: {integrity: sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==} + normalize-url@8.0.2: + resolution: {integrity: sha512-Ee/R3SyN4BuynXcnTaekmaVdbDAEiNrHqjQIA37mHU8G9pf7aaAD4ZX3XjBLo6rsdcxA/gtkcNYZLt30ACgynw==} engines: {node: '>=14.16'} optionator@0.9.4: @@ -1354,8 +1381,8 @@ packages: resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} engines: {node: '>=4'} - postcss@8.5.4: - resolution: {integrity: sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==} + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: @@ -1456,8 +1483,8 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rollup@4.42.0: - resolution: {integrity: sha512-LW+Vse3BJPyGJGAJt1j8pWDKPd73QM8cRXYK1IxOBgL2AGLu7Xd2YOW0M2sLUBCkF5MshXXtMApyEAEzMVMsnw==} + rollup@4.43.0: + resolution: {integrity: sha512-wdN2Kd3Twh8MAEOEJZsuxuLKCsBEo4PVNLK6tQWAn10VhsVewQLzcucMgLolRlhFybGxfclbPeEYBaP6RvUFGg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -1556,12 +1583,12 @@ packages: peerDependencies: svelte: ^5.0.0 - svelte@5.33.15: - resolution: {integrity: sha512-068mFjz25qg+UTaWlnGEUfCX3VtypcODx3SbRUBvMfAnVim0jGs5q7M50SFKeI4EPvTe87cB1GJgMZhXAAc6OQ==} + svelte@5.34.5: + resolution: {integrity: sha512-MMqhT/iTdwExPcyBCt+Bqxv7FV+LpSciej/gVgd/Vj7zRF9iPgRWGBxiVAwfzPYAOgwgFigIAQV8VJfhyB08/w==} engines: {node: '>=18'} - sveltekit-superforms@2.26.1: - resolution: {integrity: sha512-DALfzbIsF+KV2pjsnVDzA6fe021ffn/oo6hCwa+oSdnH8ANhhUI6vZBafxyTRqRBojsUNZ/pvFkuY9UwHyiUDA==} + sveltekit-superforms@2.27.0: + resolution: {integrity: sha512-FXIdUg4VRVZeAdVH/zB7JtHvuoC6RmHDw032meEasqB5v+i1ud4pwU/Big+6eJ2SysqrzCahBbCvLN2qzRPVUw==} peerDependencies: '@sveltejs/kit': 1.x || 2.x svelte: 3.x || 4.x || >=5.0.0-next.51 @@ -1572,8 +1599,8 @@ packages: tailwind-merge@3.0.2: resolution: {integrity: sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw==} - tailwind-merge@3.3.0: - resolution: {integrity: sha512-fyW/pEfcQSiigd5SNn0nApUOxx0zB/dm6UDU/rEwc2c3sX2smWUNbapHv+QRqLGVp9GWX3THIa7MUGPo+YkDzQ==} + tailwind-merge@3.3.1: + resolution: {integrity: sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==} tailwind-variants@1.0.0: resolution: {integrity: sha512-2WSbv4ulEEyuBKomOunut65D8UZwxrHoRfYnxGcQNnHqlSCp2+B7Yz2W+yrNDrxRodOXtGD/1oCcKGNBnUqMqA==} @@ -1586,8 +1613,8 @@ packages: peerDependencies: tailwindcss: '>=3.0.0 || insiders' - tailwindcss@4.1.8: - resolution: {integrity: sha512-kjeW8gjdxasbmFKpVGrGd5T4i40mV5J2Rasw48QARfYeQ8YS9x02ON9SFWax3Qf616rt4Cp3nVNIj6Hd1mP3og==} + tailwindcss@4.1.10: + resolution: {integrity: sha512-P3nr6WkvKV/ONsTzj6Gb57sWPMX29EPNPopo7+FcpkQaNsrNpZ1pv8QmrYI2RqEKD7mlGqLnGovlcYnBK0IqUA==} tapable@2.2.2: resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==} @@ -1642,8 +1669,8 @@ packages: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} engines: {node: '>=12.20'} - typescript-eslint@8.33.1: - resolution: {integrity: sha512-AgRnV4sKkWOiZ0Kjbnf5ytTJXMUZQ0qhSVdQtDNYLPLnjsATEYhaO94GlRQwi4t4gO8FfjM6NnikHeKjUm8D7A==} + typescript-eslint@8.34.1: + resolution: {integrity: sha512-XjS+b6Vg9oT1BaIUfkW3M3LvqZE++rbzAMEHuccCfO/YkP43ha6w3jTEMilQxMF92nVOYCcdjv1ZUhAa1D/0ow==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -1663,8 +1690,13 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - valibot@0.31.1: - resolution: {integrity: sha512-2YYIhPrnVSz/gfT2/iXVTrSj92HwchCt9Cga/6hX4B26iCz9zkIsGTS0HjDYTZfTi1Un0X6aRvhBi1cfqs/i0Q==} + valibot@0.42.1: + resolution: {integrity: sha512-3keXV29Ar5b//Hqi4MbSdV7lfVp6zuYLZuA9V1PvQUsXqogr+u5lvLPLk3A4f74VUXDnf/JfWMN6sB+koJ/FFw==} + peerDependencies: + typescript: '>=5' + peerDependenciesMeta: + typescript: + optional: true valibot@1.1.0: resolution: {integrity: sha512-Nk8lX30Qhu+9txPYTwM0cFlWLdPFsFr6LblzqIySfbZph9+BFsAHsNvHOymEviUepeIW6KFHzpX8TKhbptBXXw==} @@ -1763,8 +1795,8 @@ packages: peerDependencies: zod: ^3.24.1 - zod@3.25.56: - resolution: {integrity: sha512-rd6eEF3BTNvQnR2e2wwolfTmUTnp70aUTqr0oaGbHifzC3BKJsoV+Gat8vxUMR1hwOKBs6El+qWehrHbCpW6SQ==} + zod@3.25.67: + resolution: {integrity: sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==} snapshots: @@ -1786,6 +1818,17 @@ snapshots: '@babel/runtime@7.27.6': optional: true + '@bufbuild/protobuf@2.5.2': {} + + '@connectrpc/connect-web@2.0.2(@bufbuild/protobuf@2.5.2)(@connectrpc/connect@2.0.2(@bufbuild/protobuf@2.5.2))': + dependencies: + '@bufbuild/protobuf': 2.5.2 + '@connectrpc/connect': 2.0.2(@bufbuild/protobuf@2.5.2) + + '@connectrpc/connect@2.0.2(@bufbuild/protobuf@2.5.2)': + dependencies: + '@bufbuild/protobuf': 2.5.2 + '@esbuild/aix-ppc64@0.25.5': optional: true @@ -1861,14 +1904,14 @@ snapshots: '@esbuild/win32-x64@0.25.5': optional: true - '@eslint-community/eslint-utils@4.7.0(eslint@9.28.0(jiti@2.4.2))': + '@eslint-community/eslint-utils@4.7.0(eslint@9.29.0(jiti@2.4.2))': dependencies: - eslint: 9.28.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.4.2) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} - '@eslint/config-array@0.20.0': + '@eslint/config-array@0.20.1': dependencies: '@eslint/object-schema': 2.1.6 debug: 4.4.1 @@ -1876,17 +1919,21 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.2.2': {} + '@eslint/config-helpers@0.2.3': {} '@eslint/core@0.14.0': dependencies: '@types/json-schema': 7.0.15 + '@eslint/core@0.15.0': + dependencies: + '@types/json-schema': 7.0.15 + '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 debug: 4.4.1 - espree: 10.3.0 + espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.1 @@ -1896,13 +1943,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.28.0': {} + '@eslint/js@9.29.0': {} '@eslint/object-schema@2.1.6': {} - '@eslint/plugin-kit@0.3.1': + '@eslint/plugin-kit@0.3.2': dependencies: - '@eslint/core': 0.14.0 + '@eslint/core': 0.15.0 levn: 0.4.1 '@exodus/schemasafe@1.3.0': @@ -1919,13 +1966,15 @@ snapshots: '@floating-ui/utils@0.2.9': {} - '@gcornut/valibot-json-schema@0.31.0': + '@gcornut/valibot-json-schema@0.42.0(esbuild@0.25.5)(typescript@5.8.3)': dependencies: - valibot: 0.31.1 + valibot: 0.42.1(typescript@5.8.3) optionalDependencies: '@types/json-schema': 7.0.15 - esbuild: 0.25.5 esbuild-runner: 2.2.2(esbuild@0.25.5) + transitivePeerDependencies: + - esbuild + - typescript optional: true '@hapi/hoek@9.3.0': @@ -1974,9 +2023,9 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 - '@lucide/svelte@0.488.0(svelte@5.33.15)': + '@lucide/svelte@0.488.0(svelte@5.34.5)': dependencies: - svelte: 5.33.15 + svelte: 5.34.5 '@nodelib/fs.scandir@2.1.5': dependencies: @@ -1995,64 +2044,64 @@ snapshots: '@poppinss/macroable@1.0.4': optional: true - '@rollup/rollup-android-arm-eabi@4.42.0': + '@rollup/rollup-android-arm-eabi@4.43.0': optional: true - '@rollup/rollup-android-arm64@4.42.0': + '@rollup/rollup-android-arm64@4.43.0': optional: true - '@rollup/rollup-darwin-arm64@4.42.0': + '@rollup/rollup-darwin-arm64@4.43.0': optional: true - '@rollup/rollup-darwin-x64@4.42.0': + '@rollup/rollup-darwin-x64@4.43.0': optional: true - '@rollup/rollup-freebsd-arm64@4.42.0': + '@rollup/rollup-freebsd-arm64@4.43.0': optional: true - '@rollup/rollup-freebsd-x64@4.42.0': + '@rollup/rollup-freebsd-x64@4.43.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.42.0': + '@rollup/rollup-linux-arm-gnueabihf@4.43.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.42.0': + '@rollup/rollup-linux-arm-musleabihf@4.43.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.42.0': + '@rollup/rollup-linux-arm64-gnu@4.43.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.42.0': + '@rollup/rollup-linux-arm64-musl@4.43.0': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.42.0': + '@rollup/rollup-linux-loongarch64-gnu@4.43.0': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.42.0': + '@rollup/rollup-linux-powerpc64le-gnu@4.43.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.42.0': + '@rollup/rollup-linux-riscv64-gnu@4.43.0': optional: true - '@rollup/rollup-linux-riscv64-musl@4.42.0': + '@rollup/rollup-linux-riscv64-musl@4.43.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.42.0': + '@rollup/rollup-linux-s390x-gnu@4.43.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.42.0': + '@rollup/rollup-linux-x64-gnu@4.43.0': optional: true - '@rollup/rollup-linux-x64-musl@4.42.0': + '@rollup/rollup-linux-x64-musl@4.43.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.42.0': + '@rollup/rollup-win32-arm64-msvc@4.43.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.42.0': + '@rollup/rollup-win32-ia32-msvc@4.43.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.42.0': + '@rollup/rollup-win32-x64-msvc@4.43.0': optional: true '@sideway/address@4.1.5': @@ -2066,26 +2115,26 @@ snapshots: '@sideway/pinpoint@2.0.0': optional: true - '@sinclair/typebox@0.34.33': + '@sinclair/typebox@0.34.35': optional: true '@standard-schema/spec@1.0.0': optional: true - '@sveltejs/acorn-typescript@1.0.5(acorn@8.14.1)': + '@sveltejs/acorn-typescript@1.0.5(acorn@8.15.0)': dependencies: - acorn: 8.14.1 + acorn: 8.15.0 - '@sveltejs/adapter-static@3.0.8(@sveltejs/kit@2.21.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))': + '@sveltejs/adapter-static@3.0.8(@sveltejs/kit@2.21.5(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))': dependencies: - '@sveltejs/kit': 2.21.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + '@sveltejs/kit': 2.21.5(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) - '@sveltejs/kit@2.21.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))': + '@sveltejs/kit@2.21.5(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))': dependencies: - '@sveltejs/acorn-typescript': 1.0.5(acorn@8.14.1) - '@sveltejs/vite-plugin-svelte': 5.1.0(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + '@sveltejs/acorn-typescript': 1.0.5(acorn@8.15.0) + '@sveltejs/vite-plugin-svelte': 5.1.0(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) '@types/cookie': 0.6.0 - acorn: 8.14.1 + acorn: 8.15.0 cookie: 0.6.0 devalue: 5.1.1 esm-env: 1.2.2 @@ -2095,28 +2144,29 @@ snapshots: sade: 1.8.1 set-cookie-parser: 2.7.1 sirv: 3.0.1 - svelte: 5.33.15 - vite: 6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + svelte: 5.34.5 + vite: 6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + vitefu: 1.0.6(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) - '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))': + '@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))': dependencies: - '@sveltejs/vite-plugin-svelte': 5.1.0(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + '@sveltejs/vite-plugin-svelte': 5.1.0(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) debug: 4.4.1 - svelte: 5.33.15 - vite: 6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + svelte: 5.34.5 + vite: 6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))': + '@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + '@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) debug: 4.4.1 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.17 - svelte: 5.33.15 - vite: 6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) - vitefu: 1.0.6(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + svelte: 5.34.5 + vite: 6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + vitefu: 1.0.6(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) transitivePeerDependencies: - supports-color @@ -2124,7 +2174,7 @@ snapshots: dependencies: tslib: 2.8.1 - '@tailwindcss/node@4.1.8': + '@tailwindcss/node@4.1.10': dependencies: '@ampproject/remapping': 2.3.0 enhanced-resolve: 5.18.1 @@ -2132,69 +2182,69 @@ snapshots: lightningcss: 1.30.1 magic-string: 0.30.17 source-map-js: 1.2.1 - tailwindcss: 4.1.8 + tailwindcss: 4.1.10 - '@tailwindcss/oxide-android-arm64@4.1.8': + '@tailwindcss/oxide-android-arm64@4.1.10': optional: true - '@tailwindcss/oxide-darwin-arm64@4.1.8': + '@tailwindcss/oxide-darwin-arm64@4.1.10': optional: true - '@tailwindcss/oxide-darwin-x64@4.1.8': + '@tailwindcss/oxide-darwin-x64@4.1.10': optional: true - '@tailwindcss/oxide-freebsd-x64@4.1.8': + '@tailwindcss/oxide-freebsd-x64@4.1.10': optional: true - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.8': + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.10': optional: true - '@tailwindcss/oxide-linux-arm64-gnu@4.1.8': + '@tailwindcss/oxide-linux-arm64-gnu@4.1.10': optional: true - '@tailwindcss/oxide-linux-arm64-musl@4.1.8': + '@tailwindcss/oxide-linux-arm64-musl@4.1.10': optional: true - '@tailwindcss/oxide-linux-x64-gnu@4.1.8': + '@tailwindcss/oxide-linux-x64-gnu@4.1.10': optional: true - '@tailwindcss/oxide-linux-x64-musl@4.1.8': + '@tailwindcss/oxide-linux-x64-musl@4.1.10': optional: true - '@tailwindcss/oxide-wasm32-wasi@4.1.8': + '@tailwindcss/oxide-wasm32-wasi@4.1.10': optional: true - '@tailwindcss/oxide-win32-arm64-msvc@4.1.8': + '@tailwindcss/oxide-win32-arm64-msvc@4.1.10': optional: true - '@tailwindcss/oxide-win32-x64-msvc@4.1.8': + '@tailwindcss/oxide-win32-x64-msvc@4.1.10': optional: true - '@tailwindcss/oxide@4.1.8': + '@tailwindcss/oxide@4.1.10': dependencies: detect-libc: 2.0.4 tar: 7.4.3 optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.1.8 - '@tailwindcss/oxide-darwin-arm64': 4.1.8 - '@tailwindcss/oxide-darwin-x64': 4.1.8 - '@tailwindcss/oxide-freebsd-x64': 4.1.8 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.8 - '@tailwindcss/oxide-linux-arm64-gnu': 4.1.8 - '@tailwindcss/oxide-linux-arm64-musl': 4.1.8 - '@tailwindcss/oxide-linux-x64-gnu': 4.1.8 - '@tailwindcss/oxide-linux-x64-musl': 4.1.8 - '@tailwindcss/oxide-wasm32-wasi': 4.1.8 - '@tailwindcss/oxide-win32-arm64-msvc': 4.1.8 - '@tailwindcss/oxide-win32-x64-msvc': 4.1.8 + '@tailwindcss/oxide-android-arm64': 4.1.10 + '@tailwindcss/oxide-darwin-arm64': 4.1.10 + '@tailwindcss/oxide-darwin-x64': 4.1.10 + '@tailwindcss/oxide-freebsd-x64': 4.1.10 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.10 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.10 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.10 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.10 + '@tailwindcss/oxide-linux-x64-musl': 4.1.10 + '@tailwindcss/oxide-wasm32-wasi': 4.1.10 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.10 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.10 - '@tailwindcss/postcss@4.1.8': + '@tailwindcss/postcss@4.1.10': dependencies: '@alloc/quick-lru': 5.2.0 - '@tailwindcss/node': 4.1.8 - '@tailwindcss/oxide': 4.1.8 - postcss: 8.5.4 - tailwindcss: 4.1.8 + '@tailwindcss/node': 4.1.10 + '@tailwindcss/oxide': 4.1.10 + postcss: 8.5.6 + tailwindcss: 4.1.10 '@tanstack/match-sorter-utils@8.19.4': dependencies: @@ -2215,11 +2265,11 @@ snapshots: '@types/json-schema@7.0.15': {} - '@types/node@22.15.30': + '@types/node@22.15.32': dependencies: undici-types: 6.21.0 - '@types/validator@13.15.1': + '@types/validator@13.15.2': optional: true '@typeschema/class-validator@0.3.0(@types/json-schema@7.0.15)(class-validator@0.14.2)': @@ -2236,15 +2286,15 @@ snapshots: '@types/json-schema': 7.0.15 optional: true - '@typescript-eslint/eslint-plugin@8.33.1(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@8.34.1(@typescript-eslint/parser@8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/scope-manager': 8.33.1 - '@typescript-eslint/type-utils': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/utils': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.33.1 - eslint: 9.28.0(jiti@2.4.2) + '@typescript-eslint/parser': 8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.34.1 + '@typescript-eslint/type-utils': 8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.34.1 + eslint: 9.29.0(jiti@2.4.2) graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 @@ -2253,55 +2303,55 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/parser@8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@typescript-eslint/scope-manager': 8.33.1 - '@typescript-eslint/types': 8.33.1 - '@typescript-eslint/typescript-estree': 8.33.1(typescript@5.8.3) - '@typescript-eslint/visitor-keys': 8.33.1 + '@typescript-eslint/scope-manager': 8.34.1 + '@typescript-eslint/types': 8.34.1 + '@typescript-eslint/typescript-estree': 8.34.1(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.34.1 debug: 4.4.1 - eslint: 9.28.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.33.1(typescript@5.8.3)': + '@typescript-eslint/project-service@8.34.1(typescript@5.8.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.33.1(typescript@5.8.3) - '@typescript-eslint/types': 8.33.1 + '@typescript-eslint/tsconfig-utils': 8.34.1(typescript@5.8.3) + '@typescript-eslint/types': 8.34.1 debug: 4.4.1 typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.33.1': + '@typescript-eslint/scope-manager@8.34.1': dependencies: - '@typescript-eslint/types': 8.33.1 - '@typescript-eslint/visitor-keys': 8.33.1 + '@typescript-eslint/types': 8.34.1 + '@typescript-eslint/visitor-keys': 8.34.1 - '@typescript-eslint/tsconfig-utils@8.33.1(typescript@5.8.3)': + '@typescript-eslint/tsconfig-utils@8.34.1(typescript@5.8.3)': dependencies: typescript: 5.8.3 - '@typescript-eslint/type-utils@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/type-utils@8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.33.1(typescript@5.8.3) - '@typescript-eslint/utils': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.34.1(typescript@5.8.3) + '@typescript-eslint/utils': 8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) debug: 4.4.1 - eslint: 9.28.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.4.2) ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.33.1': {} + '@typescript-eslint/types@8.34.1': {} - '@typescript-eslint/typescript-estree@8.33.1(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@8.34.1(typescript@5.8.3)': dependencies: - '@typescript-eslint/project-service': 8.33.1(typescript@5.8.3) - '@typescript-eslint/tsconfig-utils': 8.33.1(typescript@5.8.3) - '@typescript-eslint/types': 8.33.1 - '@typescript-eslint/visitor-keys': 8.33.1 + '@typescript-eslint/project-service': 8.34.1(typescript@5.8.3) + '@typescript-eslint/tsconfig-utils': 8.34.1(typescript@5.8.3) + '@typescript-eslint/types': 8.34.1 + '@typescript-eslint/visitor-keys': 8.34.1 debug: 4.4.1 fast-glob: 3.3.3 is-glob: 4.0.3 @@ -2312,21 +2362,21 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/utils@8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0(jiti@2.4.2)) - '@typescript-eslint/scope-manager': 8.33.1 - '@typescript-eslint/types': 8.33.1 - '@typescript-eslint/typescript-estree': 8.33.1(typescript@5.8.3) - eslint: 9.28.0(jiti@2.4.2) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2)) + '@typescript-eslint/scope-manager': 8.34.1 + '@typescript-eslint/types': 8.34.1 + '@typescript-eslint/typescript-estree': 8.34.1(typescript@5.8.3) + eslint: 9.29.0(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.33.1': + '@typescript-eslint/visitor-keys@8.34.1': dependencies: - '@typescript-eslint/types': 8.33.1 - eslint-visitor-keys: 4.2.0 + '@typescript-eslint/types': 8.34.1 + eslint-visitor-keys: 4.2.1 '@vinejs/compiler@3.0.0': optional: true @@ -2334,20 +2384,20 @@ snapshots: '@vinejs/vine@3.0.1': dependencies: '@poppinss/macroable': 1.0.4 - '@types/validator': 13.15.1 + '@types/validator': 13.15.2 '@vinejs/compiler': 3.0.0 camelcase: 8.0.0 dayjs: 1.11.13 dlv: 1.1.3 - normalize-url: 8.0.1 + normalize-url: 8.0.2 validator: 13.15.15 optional: true - acorn-jsx@5.3.2(acorn@8.14.1): + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: - acorn: 8.14.1 + acorn: 8.15.0 - acorn@8.14.1: {} + acorn@8.15.0: {} ajv@6.12.6: dependencies: @@ -2374,23 +2424,23 @@ snapshots: balanced-match@1.0.2: {} - bits-ui@1.0.0-next.98(svelte@5.33.15): + bits-ui@1.0.0-next.98(svelte@5.34.5): dependencies: '@floating-ui/core': 1.7.1 '@floating-ui/dom': 1.7.1 '@internationalized/date': 3.8.2 esm-env: 1.2.2 - runed: 0.23.4(svelte@5.33.15) - svelte: 5.33.15 - svelte-toolbelt: 0.7.1(svelte@5.33.15) + runed: 0.23.4(svelte@5.34.5) + svelte: 5.34.5 + svelte-toolbelt: 0.7.1(svelte@5.34.5) tabbable: 6.2.0 - brace-expansion@1.1.11: + brace-expansion@1.1.12: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@2.0.1: + brace-expansion@2.0.2: dependencies: balanced-match: 1.0.2 @@ -2419,7 +2469,7 @@ snapshots: class-validator@0.14.2: dependencies: - '@types/validator': 13.15.1 + '@types/validator': 13.15.2 libphonenumber-js: 1.12.9 validator: 13.15.15 optional: true @@ -2462,7 +2512,7 @@ snapshots: dlv@1.1.3: optional: true - effect@3.16.4: + effect@3.16.8: dependencies: '@standard-schema/spec': 1.0.0 fast-check: 3.23.2 @@ -2510,47 +2560,47 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.5(eslint@9.28.0(jiti@2.4.2)): + eslint-config-prettier@10.1.5(eslint@9.29.0(jiti@2.4.2)): dependencies: - eslint: 9.28.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.4.2) - eslint-plugin-svelte@3.9.1(eslint@9.28.0(jiti@2.4.2))(svelte@5.33.15): + eslint-plugin-svelte@3.9.2(eslint@9.29.0(jiti@2.4.2))(svelte@5.34.5): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2)) '@jridgewell/sourcemap-codec': 1.5.0 - eslint: 9.28.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.4.2) esutils: 2.0.3 globals: 16.2.0 known-css-properties: 0.36.0 - postcss: 8.5.4 - postcss-load-config: 3.1.4(postcss@8.5.4) - postcss-safe-parser: 7.0.1(postcss@8.5.4) + postcss: 8.5.6 + postcss-load-config: 3.1.4(postcss@8.5.6) + postcss-safe-parser: 7.0.1(postcss@8.5.6) semver: 7.7.2 - svelte-eslint-parser: 1.2.0(svelte@5.33.15) + svelte-eslint-parser: 1.2.0(svelte@5.34.5) optionalDependencies: - svelte: 5.33.15 + svelte: 5.34.5 transitivePeerDependencies: - ts-node - eslint-scope@8.3.0: + eslint-scope@8.4.0: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 eslint-visitor-keys@3.4.3: {} - eslint-visitor-keys@4.2.0: {} + eslint-visitor-keys@4.2.1: {} - eslint@9.28.0(jiti@2.4.2): + eslint@9.29.0(jiti@2.4.2): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2)) '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.20.0 - '@eslint/config-helpers': 0.2.2 + '@eslint/config-array': 0.20.1 + '@eslint/config-helpers': 0.2.3 '@eslint/core': 0.14.0 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.28.0 - '@eslint/plugin-kit': 0.3.1 + '@eslint/js': 9.29.0 + '@eslint/plugin-kit': 0.3.2 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 @@ -2561,9 +2611,9 @@ snapshots: cross-spawn: 7.0.6 debug: 4.4.1 escape-string-regexp: 4.0.0 - eslint-scope: 8.3.0 - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 @@ -2585,17 +2635,17 @@ snapshots: esm-env@1.2.2: {} - espree@10.3.0: + espree@10.4.0: dependencies: - acorn: 8.14.1 - acorn-jsx: 5.3.2(acorn@8.14.1) - eslint-visitor-keys: 4.2.0 + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 esquery@1.6.0: dependencies: estraverse: 5.3.0 - esrap@1.4.7: + esrap@1.4.9: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 @@ -2630,7 +2680,7 @@ snapshots: dependencies: reusify: 1.1.0 - fdir@6.4.5(picomatch@4.0.2): + fdir@6.4.6(picomatch@4.0.2): optionalDependencies: picomatch: 4.0.2 @@ -2654,11 +2704,11 @@ snapshots: flatted@3.3.3: {} - formsnap@2.0.1(svelte@5.33.15)(sveltekit-superforms@2.26.1(@sveltejs/kit@2.21.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(@types/json-schema@7.0.15)(svelte@5.33.15)(typescript@5.8.3)): + formsnap@2.0.1(svelte@5.34.5)(sveltekit-superforms@2.27.0(@sveltejs/kit@2.21.5(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.34.5)(typescript@5.8.3)): dependencies: - svelte: 5.33.15 - svelte-toolbelt: 0.5.0(svelte@5.33.15) - sveltekit-superforms: 2.26.1(@sveltejs/kit@2.21.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(@types/json-schema@7.0.15)(svelte@5.33.15)(typescript@5.8.3) + svelte: 5.34.5 + svelte-toolbelt: 0.5.0(svelte@5.34.5) + sveltekit-superforms: 2.27.0(@sveltejs/kit@2.21.5(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.34.5)(typescript@5.8.3) fsevents@2.3.3: optional: true @@ -2823,11 +2873,11 @@ snapshots: minimatch@3.1.2: dependencies: - brace-expansion: 1.1.11 + brace-expansion: 1.1.12 minimatch@9.0.5: dependencies: - brace-expansion: 2.0.1 + brace-expansion: 2.0.2 minipass@7.1.2: {} @@ -2837,9 +2887,9 @@ snapshots: mkdirp@3.0.1: {} - mode-watcher@0.5.1(svelte@5.33.15): + mode-watcher@0.5.1(svelte@5.34.5): dependencies: - svelte: 5.33.15 + svelte: 5.34.5 mri@1.2.0: {} @@ -2851,7 +2901,7 @@ snapshots: natural-compare@1.4.0: {} - normalize-url@8.0.1: + normalize-url@8.0.2: optional: true optionator@0.9.4: @@ -2885,27 +2935,27 @@ snapshots: picomatch@4.0.2: {} - postcss-load-config@3.1.4(postcss@8.5.4): + postcss-load-config@3.1.4(postcss@8.5.6): dependencies: lilconfig: 2.1.0 yaml: 1.10.2 optionalDependencies: - postcss: 8.5.4 + postcss: 8.5.6 - postcss-safe-parser@7.0.1(postcss@8.5.4): + postcss-safe-parser@7.0.1(postcss@8.5.6): dependencies: - postcss: 8.5.4 + postcss: 8.5.6 - postcss-scss@4.0.9(postcss@8.5.4): + postcss-scss@4.0.9(postcss@8.5.6): dependencies: - postcss: 8.5.4 + postcss: 8.5.6 postcss-selector-parser@7.1.0: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss@8.5.4: + postcss@8.5.6: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 @@ -2913,16 +2963,16 @@ snapshots: prelude-ls@1.2.1: {} - prettier-plugin-svelte@3.4.0(prettier@3.5.3)(svelte@5.33.15): + prettier-plugin-svelte@3.4.0(prettier@3.5.3)(svelte@5.34.5): dependencies: prettier: 3.5.3 - svelte: 5.33.15 + svelte: 5.34.5 - prettier-plugin-tailwindcss@0.6.12(prettier-plugin-svelte@3.4.0(prettier@3.5.3)(svelte@5.33.15))(prettier@3.5.3): + prettier-plugin-tailwindcss@0.6.12(prettier-plugin-svelte@3.4.0(prettier@3.5.3)(svelte@5.34.5))(prettier@3.5.3): dependencies: prettier: 3.5.3 optionalDependencies: - prettier-plugin-svelte: 3.4.0(prettier@3.5.3)(svelte@5.33.15) + prettier-plugin-svelte: 3.4.0(prettier@3.5.3)(svelte@5.34.5) prettier@3.5.3: {} @@ -2944,40 +2994,40 @@ snapshots: reusify@1.1.0: {} - rollup@4.42.0: + rollup@4.43.0: dependencies: '@types/estree': 1.0.7 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.42.0 - '@rollup/rollup-android-arm64': 4.42.0 - '@rollup/rollup-darwin-arm64': 4.42.0 - '@rollup/rollup-darwin-x64': 4.42.0 - '@rollup/rollup-freebsd-arm64': 4.42.0 - '@rollup/rollup-freebsd-x64': 4.42.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.42.0 - '@rollup/rollup-linux-arm-musleabihf': 4.42.0 - '@rollup/rollup-linux-arm64-gnu': 4.42.0 - '@rollup/rollup-linux-arm64-musl': 4.42.0 - '@rollup/rollup-linux-loongarch64-gnu': 4.42.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.42.0 - '@rollup/rollup-linux-riscv64-gnu': 4.42.0 - '@rollup/rollup-linux-riscv64-musl': 4.42.0 - '@rollup/rollup-linux-s390x-gnu': 4.42.0 - '@rollup/rollup-linux-x64-gnu': 4.42.0 - '@rollup/rollup-linux-x64-musl': 4.42.0 - '@rollup/rollup-win32-arm64-msvc': 4.42.0 - '@rollup/rollup-win32-ia32-msvc': 4.42.0 - '@rollup/rollup-win32-x64-msvc': 4.42.0 + '@rollup/rollup-android-arm-eabi': 4.43.0 + '@rollup/rollup-android-arm64': 4.43.0 + '@rollup/rollup-darwin-arm64': 4.43.0 + '@rollup/rollup-darwin-x64': 4.43.0 + '@rollup/rollup-freebsd-arm64': 4.43.0 + '@rollup/rollup-freebsd-x64': 4.43.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.43.0 + '@rollup/rollup-linux-arm-musleabihf': 4.43.0 + '@rollup/rollup-linux-arm64-gnu': 4.43.0 + '@rollup/rollup-linux-arm64-musl': 4.43.0 + '@rollup/rollup-linux-loongarch64-gnu': 4.43.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.43.0 + '@rollup/rollup-linux-riscv64-gnu': 4.43.0 + '@rollup/rollup-linux-riscv64-musl': 4.43.0 + '@rollup/rollup-linux-s390x-gnu': 4.43.0 + '@rollup/rollup-linux-x64-gnu': 4.43.0 + '@rollup/rollup-linux-x64-musl': 4.43.0 + '@rollup/rollup-win32-arm64-msvc': 4.43.0 + '@rollup/rollup-win32-ia32-msvc': 4.43.0 + '@rollup/rollup-win32-x64-msvc': 4.43.0 fsevents: 2.3.3 run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 - runed@0.23.4(svelte@5.33.15): + runed@0.23.4(svelte@5.34.5): dependencies: esm-env: 1.2.2 - svelte: 5.33.15 + svelte: 5.34.5 sade@1.8.1: dependencies: @@ -3023,110 +3073,111 @@ snapshots: dependencies: has-flag: 4.0.0 - svelte-check@4.2.1(picomatch@4.0.2)(svelte@5.33.15)(typescript@5.8.3): + svelte-check@4.2.1(picomatch@4.0.2)(svelte@5.34.5)(typescript@5.8.3): dependencies: '@jridgewell/trace-mapping': 0.3.25 chokidar: 4.0.3 - fdir: 6.4.5(picomatch@4.0.2) + fdir: 6.4.6(picomatch@4.0.2) picocolors: 1.1.1 sade: 1.8.1 - svelte: 5.33.15 + svelte: 5.34.5 typescript: 5.8.3 transitivePeerDependencies: - picomatch - svelte-eslint-parser@1.2.0(svelte@5.33.15): + svelte-eslint-parser@1.2.0(svelte@5.34.5): dependencies: - eslint-scope: 8.3.0 - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 - postcss: 8.5.4 - postcss-scss: 4.0.9(postcss@8.5.4) + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + postcss: 8.5.6 + postcss-scss: 4.0.9(postcss@8.5.6) postcss-selector-parser: 7.1.0 optionalDependencies: - svelte: 5.33.15 + svelte: 5.34.5 svelte-highlight@7.8.3: dependencies: highlight.js: 11.11.1 - svelte-sonner@0.3.28(svelte@5.33.15): + svelte-sonner@0.3.28(svelte@5.34.5): dependencies: - svelte: 5.33.15 + svelte: 5.34.5 - svelte-toolbelt@0.5.0(svelte@5.33.15): + svelte-toolbelt@0.5.0(svelte@5.34.5): dependencies: clsx: 2.1.1 style-to-object: 1.0.9 - svelte: 5.33.15 + svelte: 5.34.5 - svelte-toolbelt@0.7.1(svelte@5.33.15): + svelte-toolbelt@0.7.1(svelte@5.34.5): dependencies: clsx: 2.1.1 - runed: 0.23.4(svelte@5.33.15) + runed: 0.23.4(svelte@5.34.5) style-to-object: 1.0.9 - svelte: 5.33.15 + svelte: 5.34.5 - svelte@5.33.15: + svelte@5.34.5: dependencies: '@ampproject/remapping': 2.3.0 '@jridgewell/sourcemap-codec': 1.5.0 - '@sveltejs/acorn-typescript': 1.0.5(acorn@8.14.1) + '@sveltejs/acorn-typescript': 1.0.5(acorn@8.15.0) '@types/estree': 1.0.8 - acorn: 8.14.1 + acorn: 8.15.0 aria-query: 5.3.2 axobject-query: 4.1.0 clsx: 2.1.1 esm-env: 1.2.2 - esrap: 1.4.7 + esrap: 1.4.9 is-reference: 3.0.3 locate-character: 3.0.0 magic-string: 0.30.17 zimmerframe: 1.1.2 - sveltekit-superforms@2.26.1(@sveltejs/kit@2.21.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(@types/json-schema@7.0.15)(svelte@5.33.15)(typescript@5.8.3): + sveltekit-superforms@2.27.0(@sveltejs/kit@2.21.5(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(@types/json-schema@7.0.15)(esbuild@0.25.5)(svelte@5.34.5)(typescript@5.8.3): dependencies: - '@sveltejs/kit': 2.21.2(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.33.15)(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + '@sveltejs/kit': 2.21.5(@sveltejs/vite-plugin-svelte@5.1.0(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.34.5)(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) devalue: 5.1.1 memoize-weak: 1.0.2 - svelte: 5.33.15 + svelte: 5.34.5 ts-deepmerge: 7.0.3 optionalDependencies: '@exodus/schemasafe': 1.3.0 - '@gcornut/valibot-json-schema': 0.31.0 - '@sinclair/typebox': 0.34.33 + '@gcornut/valibot-json-schema': 0.42.0(esbuild@0.25.5)(typescript@5.8.3) + '@sinclair/typebox': 0.34.35 '@typeschema/class-validator': 0.3.0(@types/json-schema@7.0.15)(class-validator@0.14.2) '@vinejs/vine': 3.0.1 arktype: 2.1.20 class-validator: 0.14.2 - effect: 3.16.4 + effect: 3.16.8 joi: 17.13.3 json-schema-to-ts: 3.1.1 superstruct: 2.0.2 valibot: 1.1.0(typescript@5.8.3) yup: 1.6.1 - zod: 3.25.56 - zod-to-json-schema: 3.24.5(zod@3.25.56) + zod: 3.25.67 + zod-to-json-schema: 3.24.5(zod@3.25.67) transitivePeerDependencies: - '@types/json-schema' + - esbuild - typescript tabbable@6.2.0: {} tailwind-merge@3.0.2: {} - tailwind-merge@3.3.0: {} + tailwind-merge@3.3.1: {} - tailwind-variants@1.0.0(tailwindcss@4.1.8): + tailwind-variants@1.0.0(tailwindcss@4.1.10): dependencies: tailwind-merge: 3.0.2 - tailwindcss: 4.1.8 + tailwindcss: 4.1.10 - tailwindcss-animate@1.0.7(tailwindcss@4.1.8): + tailwindcss-animate@1.0.7(tailwindcss@4.1.10): dependencies: - tailwindcss: 4.1.8 + tailwindcss: 4.1.10 - tailwindcss@4.1.8: {} + tailwindcss@4.1.10: {} tapable@2.2.2: {} @@ -3144,7 +3195,7 @@ snapshots: tinyglobby@0.2.14: dependencies: - fdir: 6.4.5(picomatch@4.0.2) + fdir: 6.4.6(picomatch@4.0.2) picomatch: 4.0.2 to-regex-range@5.0.1: @@ -3177,12 +3228,12 @@ snapshots: type-fest@2.19.0: optional: true - typescript-eslint@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3): + typescript-eslint@8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.33.1(@typescript-eslint/parser@8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/parser': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/utils': 8.33.1(eslint@9.28.0(jiti@2.4.2))(typescript@5.8.3) - eslint: 9.28.0(jiti@2.4.2) + '@typescript-eslint/eslint-plugin': 8.34.1(@typescript-eslint/parser@8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/parser': 8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.34.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.29.0(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -3197,7 +3248,9 @@ snapshots: util-deprecate@1.0.2: {} - valibot@0.31.1: + valibot@0.42.1(typescript@5.8.3): + optionalDependencies: + typescript: 5.8.3 optional: true valibot@1.1.0(typescript@5.8.3): @@ -3208,24 +3261,24 @@ snapshots: validator@13.15.15: optional: true - vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0): + vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0): dependencies: esbuild: 0.25.5 - fdir: 6.4.5(picomatch@4.0.2) + fdir: 6.4.6(picomatch@4.0.2) picomatch: 4.0.2 - postcss: 8.5.4 - rollup: 4.42.0 + postcss: 8.5.6 + rollup: 4.43.0 tinyglobby: 0.2.14 optionalDependencies: - '@types/node': 22.15.30 + '@types/node': 22.15.32 fsevents: 2.3.3 jiti: 2.4.2 lightningcss: 1.30.1 yaml: 2.8.0 - vitefu@1.0.6(vite@6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)): + vitefu@1.0.6(vite@6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)): optionalDependencies: - vite: 6.3.5(@types/node@22.15.30)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + vite: 6.3.5(@types/node@22.15.32)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) which@2.0.2: dependencies: @@ -3251,9 +3304,9 @@ snapshots: zimmerframe@1.1.2: {} - zod-to-json-schema@3.24.5(zod@3.25.56): + zod-to-json-schema@3.24.5(zod@3.25.67): dependencies: - zod: 3.25.56 + zod: 3.25.67 optional: true - zod@3.25.56: {} + zod@3.25.67: {} diff --git a/web/src/lib/api.ts b/web/src/lib/api.ts index e7e073a..c68d970 100644 --- a/web/src/lib/api.ts +++ b/web/src/lib/api.ts @@ -1,857 +1,56 @@ +import type { DescService } from '@bufbuild/protobuf'; +import { createClient, type Client } from '@connectrpc/connect'; +import { createConnectTransport } from '@connectrpc/connect-web'; import { goto } from '$app/navigation'; -import { toast } from 'svelte-sonner'; -import { get, writable, type Writable } from 'svelte/store'; -import YAML from 'yaml'; -import { profile } from './stores/profile'; -import { source } from './stores/source'; -import { user } from './stores/user'; -import { - TraefikSource, - type Agent, - type BackupFile, - type DNSProvider, - type OAuthStatus, - type Plugin, - type Profile, - type PublicIP, - type RouterDNSProvider, - type Settings, - type Stats, - type SystemError, - type TraefikConfig, - type UpdateAgentIPParams, - type UpsertSettingsParams, - type User -} from './types'; -import type { EntryPoints } from './types/entrypoints'; -import { - flattenMiddlewareData, - type DeleteMiddlewareParams, - type Middleware, - type UpsertMiddlewareParams -} from './types/middlewares'; -import type { Overview } from './types/overview'; -import { - flattenRouterData, - flattenServiceData, - type DeleteRouterParams, - type Router, - type Service, - type UpsertRouterParams -} from './types/router'; -import { tryLoad } from './utils'; - -export type RouterWithService = { router: Router; service: Service }; +import { token } from './stores/common'; +import { ProfileService } from './gen/mantrae/v1/profile_pb'; +import { UserService } from './gen/mantrae/v1/user_pb'; +import { RouterService } from './gen/mantrae/v1/router_pb'; +import { ServiceService } from './gen/mantrae/v1/service_pb'; +import { MiddlewareService } from './gen/mantrae/v1/middleware_pb'; +import { SettingService } from './gen/mantrae/v1/setting_pb'; +import { BackupService } from './gen/mantrae/v1/backup_pb'; +import { AgentManagementService } from './gen/mantrae/v1/agent_management_pb'; +import { EntryPointService } from './gen/mantrae/v1/entry_point_pb'; +import { DnsProviderService } from './gen/mantrae/v1/dns_provider_pb'; // Global state variables export const BACKEND_PORT = import.meta.env.PORT || 3000; -export const BASE_URL = import.meta.env.PROD ? '/api' : `http://127.0.0.1:${BACKEND_PORT}/api`; +export const BASE_URL = import.meta.env.PROD ? '' : `http://127.0.0.1:${BACKEND_PORT}`; -// DB Stores -export const profiles: Writable = writable(); -export const traefik: Writable = writable(); -export const entrypoints: Writable = writable([]); -export const overview: Writable = writable({} as Overview); -export const version: Writable = writable(''); -export const routers: Writable = writable([]); -export const services: Writable = writable([]); -export const routerServiceMerge: Writable = writable([]); -export const middlewares: Writable = writable([]); -export const users: Writable = writable([]); -export const rdps: Writable = writable([]); -export const dnsProviders: Writable = writable([]); -export const agents: Writable = writable([]); -export const settings: Writable = writable({} as Settings); -export const plugins: Writable = writable([]); -export const backups: Writable = writable([]); -export const errors: Writable = writable([]); - -// App state -export const stats: Writable = writable({} as Stats); -export const mwNames: Writable = writable([]); -export const dynamicJSON: Writable = writable(''); -export const dynamicYAML: Writable = writable(''); - -// Loading and error states -export const loading = writable(false); -export const error = writable(null); - -interface APIOptions { - method?: string; - // eslint-disable-next-line - body?: any; - headers?: Record; -} - -async function send(endpoint: string, options: APIOptions = {}, fetch?: typeof window.fetch) { +export function useClient( + service: T, + fetch?: typeof window.fetch +): Client { // Custom fetch function that adds the Authorization header const customFetch: typeof window.fetch = async (url, options) => { const headers = new Headers(options?.headers); // Get existing headers - - // Don't set Content-Type for FormData - const isFormData = options?.body instanceof FormData; - if (!isFormData) { - headers.set('Content-Type', 'application/json'); + if (token.value) { + headers.set('Authorization', 'Bearer ' + token.value); // Add the Authorization header } const customOptions = { ...options, - headers, - credentials: 'include' as RequestCredentials, // Include cookies - body: isFormData ? options?.body : options?.body ? JSON.stringify(options.body) : undefined + headers }; return fetch ? fetch(url, customOptions) : window.fetch(url, customOptions); // Use custom fetch or default }; - try { - loading.set(true); - const response = await customFetch(`${BASE_URL}${endpoint}`, { - method: options.method || 'GET', - body: options.body, - headers: options.headers, - credentials: 'include' - }); - - if (!response.ok) { - throw new Error(await response.text()); - } - if (response.headers.get('Content-Type') === 'application/json') { - return await response.json(); - } else { - return response; - } - } catch (err: unknown) { - error.set(err instanceof Error ? err.message : String(err)); - throw err; - } finally { - loading.set(false); - } + const transport = createConnectTransport({ baseUrl: BASE_URL, fetch: customFetch }); + return createClient(service, transport); } -export const api = { - // Auth ---------------------------------------------------------------------- - async login(username: string, password: string, remember: boolean = false) { - const endpoint = remember ? `/login?remember=true` : `/login`; - const data = await send(endpoint, { - method: 'POST', - body: { username, password } - }); - if (data.user) { - user.value = data.user; - } - goto('/'); - }, - - async verify(fetch: typeof window.fetch = window.fetch) { - try { - const data = await send('/verify', {}, fetch); - if (data.user) { - user.value = data.user; - } - return true; - } catch (_) { - return false; - } - }, - - async sendResetEmail(username: string) { - await send(`/reset/${username}`, { method: 'POST' }); - }, - - async verifyOTP(username: string, otp: string) { - const data = await send('/verify/otp', { - method: 'POST', - body: { username, token: otp } - }); - - if (data.user) { - user.value = data.user; - } - goto('/'); - }, - - async oauthStatus() { - const data: OAuthStatus = await send('/oidc/status'); - if (!data) { - throw new Error('Failed to fetch OAuth status'); - } - return data; - }, - - async load() { - if (!user.isLoggedIn()) return; - - // Load profiles - await api.listProfiles(); - if (get(profiles) && !profile.id) { - profile.value = get(profiles)[0]; - } - - // Load Traefik Config - if (profile.value && source.value) { - await api.getTraefikConfig(source.value); - } - }, - - async logout() { - await send('/logout', { method: 'POST' }); - user.clear(); - goto('/login'); - }, - - async loadStats() { - const [dns, usersList, profilesList, agents] = await Promise.all([ - tryLoad(() => api.listDNSProviders(), [] as DNSProvider[]), - tryLoad(() => api.listUsers(), [] as User[]), - tryLoad(() => api.listProfiles(), [] as Profile[]), - tryLoad(() => api.listAgents(), [] as Agent[]) - ]); - - stats.set({ - profiles: profilesList?.length ?? 0, - agents: agents?.length ?? 0, - users: usersList?.length ?? 0, - dnsProviders: dns?.length ?? 0, - activeDNS: dns?.find((item) => item.isActive)?.name ?? 'None' - }); - }, - - async getTraefikStats() { - const allProfiles = get(profiles); - const results = []; - - for (const profile of allProfiles) { - if (!profile.id) continue; - - const res = await send(`/traefik/${profile.id}/${TraefikSource.LOCAL}`); - const agents = await send(`/agent/list/${profile.id}`); - - const routers = flattenRouterData(res); - const services = flattenServiceData(res); - const middlewares = flattenMiddlewareData(res); - - results.push({ - id: profile?.id, - name: profile?.name, - url: profile?.url, - routers: routers?.length || 0, - services: services?.length || 0, - middlewares: middlewares?.length || 0, - agents: agents?.length || 0 - }); - } - - return results; - }, - - // Profiles ------------------------------------------------------------------ - async listProfiles(): Promise { - const data: Profile[] = await send('/profile'); - profiles.set(data); - if (profile.isValid()) { - profile.value = data.find((item) => item.id === profile.value?.id) ?? data[0]; - } - return data; - }, - - async getProfile(id: number) { - return await send(`/profile/${id}`); - }, - - async createProfile(profile: Omit) { - await send('/profile', { - method: 'POST', - body: profile - }); - await api.listProfiles(); // Refresh the list - }, - - async updateProfile(p: Profile) { - await send('/profile', { - method: 'PUT', - body: p - }); - await api.listProfiles(); // Refresh the list - if (p.id === profile.id) { - await api.getTraefikConfig(TraefikSource.API); - } - }, - - async deleteProfile(id: number) { - await send(`/profile/${id}`, { method: 'DELETE' }); - if (id === profile.value?.id) { - profile.value = {} as Profile; - } - await api.listProfiles(); // Refresh the list - }, - - // Traefik ------------------------------------------------------------------- - async getTraefikConfig(source: TraefikSource) { - await fetchTraefikMetadata(); - await fetchTraefikConfig(source); - }, - - async getDynamicConfig() { - if (!profile.hasValidName()) { - toast.error('Profile name is required'); - return; - } - const data = await send(`/${profile.name}`); - if (!data || (typeof data === 'object' && Object.keys(data).length === 0)) { - dynamicJSON.set(''); - dynamicYAML.set(''); - return; - } - dynamicJSON.set(JSON.stringify(data, null, 2)); - dynamicYAML.set(YAML.stringify(data)); - }, - - // Routers ------------------------------------------------------------------- - async upsertRouter(data: UpsertRouterParams) { - if (!profile.hasValidId()) { - toast.error('Invalid profile ID'); - return; - } - - await send(`/router/${profile.id}`, { - method: 'POST', - body: data - }); - await api.getTraefikConfig(TraefikSource.LOCAL); - }, - - async deleteRouter(data: DeleteRouterParams) { - await send(`/router`, { - method: 'DELETE', - body: data - }); - await api.getTraefikConfig(TraefikSource.LOCAL); - }, - - async bulkDeleteRouter(items: Omit[]) { - if (!profile.hasValidId()) { - toast.error('Invalid profile ID'); - return; - } - await send(`/router/bulk`, { - method: 'DELETE', - body: { profileId: profile.id, items } - }); - await api.getTraefikConfig(TraefikSource.LOCAL); - }, - - async shareRouter(data: UpsertRouterParams, profileId: number) { - await send(`/router/${profileId}`, { - method: 'POST', - body: data - }); - await api.getTraefikConfig(TraefikSource.LOCAL); - }, - - // Middlewares --------------------------------------------------------------- - async upsertMiddleware(data: UpsertMiddlewareParams) { - if (!profile.hasValidId()) { - toast.error('Invalid profile ID'); - return; - } - await send(`/middleware/${profile.id}`, { - method: 'POST', - body: data - }); - await api.getTraefikConfig(TraefikSource.LOCAL); - }, - - async deleteMiddleware(data: DeleteMiddlewareParams) { - if (!profile.hasValidId()) { - toast.error('Invalid profile ID'); - return; - } - await send(`/middleware`, { - method: 'DELETE', - body: data - }); - await api.getTraefikConfig(TraefikSource.LOCAL); - }, - - async bulkDeleteMiddleware(items: Omit[]) { - if (!profile.hasValidId()) { - toast.error('Invalid profile ID'); - return; - } - await send(`/middleware/bulk`, { - method: 'DELETE', - body: { profileId: profile.id, items } - }); - await api.getTraefikConfig(TraefikSource.LOCAL); - }, - - async shareMiddleware(data: UpsertMiddlewareParams, profileId: number) { - await send(`/middleware/${profileId}`, { - method: 'POST', - body: data - }); - await api.getTraefikConfig(TraefikSource.LOCAL); - }, - - // DNS Providers ------------------------------------------------------------- - async listDNSProviders(): Promise { - const data = await send('/dns'); - dnsProviders.set(data); - return data; - }, - - async getDNSProvider(id: number) { - return await send(`/dns/${id}`); - }, - - async createDNSProvider(provider: Omit) { - await send('/dns', { - method: 'POST', - body: provider - }); - await api.listDNSProviders(); - }, - - async updateDNSProvider(provider: Omit) { - await send(`/dns`, { - method: 'PUT', - body: provider - }); - await api.listDNSProviders(); - }, - - async deleteDNSProvider(id: number) { - if (!id) return; - await send(`/dns/${id}`, { - method: 'DELETE' - }); - await api.listDNSProviders(); - }, - - async getRouterDNSProvider(traefikId: number, routerName: string) { - if (!traefikId || !routerName) return; - return await send(`/dns/router`, { - method: 'GET', - body: { traefikId, routerName } - }); - }, - - async listRouterDNSProviders() { - const configs = get(traefik); - if (!configs?.length) return; - - // Get unique traefik IDs - const uniqueIds = [...new Set(configs.map((t) => t.id))]; - - try { - // Fetch data for all unique IDs in parallel - const results = await Promise.all( - uniqueIds.map((id) => - send(`/dns/router/${id}`, { method: 'GET' }) - .then((data) => ({ id, data })) - .catch(() => ({ id, data: [] })) - ) - ); - - // Combine and update store - rdps.set(results.filter((result) => result.data).flatMap((result) => result.data)); - } catch (err: unknown) { - const error = err instanceof Error ? err : new Error(String(err)); - toast.error('Failed to fetch router DNS providers', { description: error.message }); - } - }, - - async setRouterDNSProvider(providerIds: string[], routerName: string) { - const configs = get(traefik); - if (!configs?.length) return; - const params = { - providerIds, - traefikId: configs[0].id, - routerName - }; - - await send(`/dns/router`, { - method: 'POST', - body: params - }); - await api.listRouterDNSProviders(); - }, - - async deleteRouterDNSProvider(traefikId: number, providerId: number, routerName: string) { - await send(`/dns/router`, { - method: 'DELETE', - body: { traefikId, providerId, routerName } - }); - await api.listRouterDNSProviders(); - }, - - // Users --------------------------------------------------------------------- - async listUsers(): Promise { - const data = await send('/user'); - users.set(data); - return data; - }, - - async getUser(id: number) { - const data = await send(`/user/${id}`); - return data; - }, - - async createUser(user: Omit) { - await send('/user', { - method: 'POST', - body: user - }); - await api.listUsers(); - }, - - async updateUser(user: Omit) { - await send(`/user`, { - method: 'PUT', - body: user - }); - await api.listUsers(); - }, - - async deleteUser(id: number) { - await send(`/user/${id}`, { - method: 'DELETE' - }); - await api.listUsers(); - }, - - async updateUserPassword(user: Omit) { - await send(`/user/password`, { - method: 'POST', - body: user - }); - }, - - // Agents - async listAgents(): Promise { - const data = await send(`/agent`); - return data; - }, - - async listAgentsByProfile(): Promise { - if (!profile.hasValidId()) { - toast.error('Invalid profile ID'); - return []; - } - const data = await send(`/agent/list/${profile.id}`); - agents.set(data); - return data; - }, - - async getAgent(id: string) { - return await send(`/agent/${id}`); - }, - - async createAgent() { - if (!profile.hasValidId()) { - toast.error('Invalid profile ID'); - return; - } - await send(`/agent/${profile.id}`, { - method: 'POST' - }); - await api.listAgentsByProfile(); - }, - - async updateAgentIP(params: UpdateAgentIPParams) { - await send(`/agent`, { - method: 'PUT', - body: params - }); - await api.listAgentsByProfile(); - }, - - async rotateAgentToken(id: string) { - const token = await send(`/agent/token/${id}`, { - method: 'POST' - }); - await api.listAgentsByProfile(); - return token; - }, - - async deleteAgent(id: string) { - await send(`/agent/${id}`, { - method: 'DELETE' - }); - await api.listAgentsByProfile(); - }, - - // Settings ------------------------------------------------------------------ - async listSettings() { - const data = await send('/settings'); - settings.set(data); - }, - - async getSetting(id: number) { - return await send(`/settings/${id}`); - }, - - async upsertSetting(setting: UpsertSettingsParams) { - await send(`/settings`, { - method: 'POST', - body: setting - }); - await api.listSettings(); - }, - - // Backups ------------------------------------------------------------------- - async listBackups() { - try { - const data = await send('/backups'); - backups.set(data); - } catch (err: unknown) { - const error = err instanceof Error ? err.message : String(err); - toast.error(error, { duration: 5000 }); - } - }, - - async createBackup() { - try { - await send('/backups', { method: 'POST' }); - } catch (err: unknown) { - const error = err instanceof Error ? err.message : String(err); - toast.error(error, { duration: 5000 }); - } - - await api.listBackups(); - }, - - async downloadBackup() { - try { - const response = await send('/backups/download', { method: 'GET' }); - - const blob = await response.blob(); - const filename = - response.headers.get('content-disposition')?.split('filename=')[1] || 'backup.db'; - const url = window.URL.createObjectURL(blob); - const a = document.createElement('a'); - a.href = url; - a.download = filename; - document.body.appendChild(a); - a.click(); - window.URL.revokeObjectURL(url); - document.body.removeChild(a); - } catch (err: unknown) { - const error = err instanceof Error ? err.message : String(err); - toast.error('Failed to download backup', { description: error, duration: 5000 }); - } - }, - - async downloadBackupByName(name: string) { - try { - const response = await send(`/backups/download/${name}`, { method: 'GET' }); - const blob = await response.blob(); - const filename = response.headers.get('content-disposition')?.split('filename=')[1] || name; - const url = window.URL.createObjectURL(blob); - const a = document.createElement('a'); - a.href = url; - a.download = filename; - document.body.appendChild(a); - a.click(); - window.URL.revokeObjectURL(url); - document.body.removeChild(a); - } catch (err: unknown) { - const error = err instanceof Error ? err.message : String(err); - toast.error('Failed to download backup', { description: error, duration: 5000 }); - } - }, - - async restoreBackup(files: FileList | null) { - if (!files?.length) return; - const formData = new FormData(); - formData.append('file', files[0]); - - try { - await send(`/backups/restore`, { - method: 'POST', - body: formData - }); - toast.success('Backup restored successfully'); - } catch (err: unknown) { - const error = err instanceof Error ? err.message : String(err); - toast.error('Failed to restore backup', { description: error, duration: 5000 }); - } - }, - - async restoreBackupByName(filename: string) { - try { - await send(`/backups/restore/${filename}`, { - method: 'POST' - }); - toast.success('Backup restored successfully'); - } catch (err: unknown) { - const error = err instanceof Error ? err.message : String(err); - toast.error('Failed to restore backup', { description: error, duration: 5000 }); - } - }, - - async restoreDynamicConfig(files: FileList | null) { - if (!files?.length) return; - const formData = new FormData(); - formData.append('file', files[0]); - - try { - await send(`/dynamic/restore/${profile.id}`, { - method: 'POST', - body: formData - }); - toast.success('Config restored successfully'); - } catch (err: unknown) { - const error = err instanceof Error ? err.message : String(err); - toast.error('Failed to restore config', { description: error, duration: 5000 }); - } - }, - - async deleteBackup(name: string) { - if (!name) return; - try { - await send(`/backups/${name}`, { method: 'DELETE' }); - toast.success('Backup deleted successfully'); - } catch (err: unknown) { - const error = err instanceof Error ? err.message : String(err); - toast.error('Failed to delete backup', { description: error, duration: 5000 }); - } - await api.listBackups(); - }, - - // Errors - async listErrors() { - const data = await send('/errors'); - errors.set(data); - }, - - async getError() { - if (!profile.hasValidId()) { - toast.error('Invalid profile ID'); - return; - } - return await send(`/errors/${profile.id}`); - }, - - async deleteError(id: string) { - await send(`/errors/${id}`, { - method: 'DELETE' - }); - await api.listErrors(); - }, - - async deleteErrorsByProfile() { - if (!profile.hasValidId()) { - toast.error('Invalid profile ID'); - return; - } - await send(`/errors/profile/${profile.id}`, { - method: 'DELETE' - }); - await api.listErrors(); - }, - - // Plugins - async getMiddlewarePlugins() { - const data = await send('/middleware/plugins'); - plugins.set(data); - }, - - async getIP(): Promise { - return await send('/ip'); - }, - - async getVersion() { - return await send('/version'); - } -}; - -// Helper -async function fetchTraefikMetadata() { - if (!profile.isValid()) { - toast.error('No valid profile selected'); - return; - } - const res = await send(`/traefik/${profile.id}/${TraefikSource.API}`); - if (!res) { - // Reset metadata stores - overview.set({} as Overview); - entrypoints.set([]); - version.set(''); - return false; - } - - // Set metadata stores - const meta = res[0]; - overview.set(meta.overview); - entrypoints.set(meta.entrypoints); - version.set(meta.version); - - // Set middleware names (used for chain) - const middlewares = flattenMiddlewareData(res); - mwNames.set(middlewares.map((mw) => mw.name)); - return true; +export function logout() { + token.value = null; + goto('/login'); } -async function fetchTraefikConfig(src: TraefikSource) { - if (!profile.isValid() || !source.isValid(src)) { - toast.error('No valid profile selected'); - return; - } - - const res = await send(`/traefik/${profile.id}/${src}`); - if (!res) { - // Reset stores - traefik.set([]); - routers.set([]); - services.set([]); - middlewares.set([]); - routerServiceMerge.set([]); - return; - } - - // Update stores with proper diffing - traefik.update((current) => { - return JSON.stringify(current) === JSON.stringify(res) ? current : res; - }); - - const newRouters = flattenRouterData(res); - const newServices = flattenServiceData(res); - const newMiddlewares = flattenMiddlewareData(res); - const newMerge = newRouters.map((router) => { - let service = newServices.find((service) => service.name === router.service); - if (!service) { - service = newServices.find((service) => service.name === router.name); - } - return { router, service: service || ({} as Service) }; - }); - - routers.update((current) => { - if (!current || current.length === 0) return newRouters; - if (JSON.stringify(current) === JSON.stringify(newRouters)) return current; - return newRouters; - }); - - services.update((current) => { - if (!current || current.length === 0) return newServices; - if (JSON.stringify(current) === JSON.stringify(newServices)) return current; - return newServices; - }); - - middlewares.update((current) => { - if (!current || current.length === 0) return newMiddlewares; - if (JSON.stringify(current) === JSON.stringify(newMiddlewares)) return current; - return newMiddlewares; - }); - - routerServiceMerge.update((current) => { - if (!current || current.length === 0) return newMerge; - if (JSON.stringify(current) === JSON.stringify(newMerge)) return current; - return newMerge; - }); - - // Fetch the router dns relations - await api.listRouterDNSProviders(); - - // Fetch dynamic config - await api.getDynamicConfig(); -} +export const profileClient = useClient(ProfileService); +export const userClient = useClient(UserService); +export const entryPointClient = useClient(EntryPointService); +export const dnsClient = useClient(DnsProviderService); +export const agentClient = useClient(AgentManagementService); +export const routerClient = useClient(RouterService); +export const serviceClient = useClient(ServiceService); +export const middlewareClient = useClient(MiddlewareService); +export const settingClient = useClient(SettingService); +export const backupClient = useClient(BackupService); diff --git a/web/src/lib/components/modals/info.svelte b/web/src/lib/components/modals/info.svelte index d401d37..41f29e2 100644 --- a/web/src/lib/components/modals/info.svelte +++ b/web/src/lib/components/modals/info.svelte @@ -5,7 +5,6 @@ import * as Tooltip from '$lib/components/ui/tooltip/index.js'; import { Button } from '$lib/components/ui/button/index.js'; import { Badge } from '$lib/components/ui/badge/index.js'; - import { entrypoints, overview, version, dynamicJSON, dynamicYAML, api } from '$lib/api'; import Highlight, { LineNumbers } from 'svelte-highlight'; import { json, yaml } from 'svelte-highlight/languages'; import CopyButton from '../ui/copy-button/copy-button.svelte'; diff --git a/web/src/lib/components/modals/profile.svelte b/web/src/lib/components/modals/profile.svelte index dd5d429..4134077 100644 --- a/web/src/lib/components/modals/profile.svelte +++ b/web/src/lib/components/modals/profile.svelte @@ -3,12 +3,10 @@ import { Button } from '$lib/components/ui/button/index.js'; import { Input } from '$lib/components/ui/input'; import { Label } from '$lib/components/ui/label'; - import { Checkbox } from '$lib/components/ui/checkbox'; - import { api, loading } from '$lib/api'; - import type { Profile } from '$lib/types'; import { toast } from 'svelte-sonner'; - import PasswordInput from '../ui/password-input/password-input.svelte'; import Separator from '../ui/separator/separator.svelte'; + import type { Profile } from '$lib/gen/mantrae/v1/profile_pb'; + import { profileClient } from '$lib/api'; interface Props { profile?: Profile; @@ -19,16 +17,11 @@ const handleSubmit = async () => { try { - // Strip trailing slashes from URL - if (profile.url?.endsWith('/')) { - profile.url = profile.url.slice(0, -1); - } - if (profile.id) { - await api.updateProfile(profile as Profile); + await profileClient.updateProfile({ name: profile.name, description: profile.description }); toast.success('Profile updated successfully'); } else { - await api.createProfile(profile as Profile); + await profileClient.createProfile({ name: profile.name, description: profile.description }); toast.success('Profile created successfully'); } open = false; @@ -44,7 +37,7 @@ if (!profile.id) return; try { - await api.deleteProfile(profile.id); + await profileClient.deleteProfile({ id: profile.id }); toast.success('Profile deleted successfully'); open = false; } catch (err: unknown) { @@ -70,34 +63,21 @@
- - -
- -
- - -
- -
- - -
- -
- - + +
{#if profile.id} - + {/if} - +
diff --git a/web/src/lib/components/nav/AppCenter.svelte b/web/src/lib/components/nav/AppCenter.svelte index c8300b0..d9d1ae9 100644 --- a/web/src/lib/components/nav/AppCenter.svelte +++ b/web/src/lib/components/nav/AppCenter.svelte @@ -5,7 +5,6 @@ import { Layers, Route } from '@lucide/svelte'; import type { Router, Service } from '$lib/types/router'; import type { Middleware } from '$lib/types/middlewares'; - import { middlewares, routerServiceMerge } from '$lib/api'; import { source } from '$lib/stores/source'; import { TraefikSource } from '$lib/types'; diff --git a/web/src/lib/components/nav/AppFooter.svelte b/web/src/lib/components/nav/AppFooter.svelte index 9d6b483..96f96e1 100644 --- a/web/src/lib/components/nav/AppFooter.svelte +++ b/web/src/lib/components/nav/AppFooter.svelte @@ -2,13 +2,15 @@ import { BookText } from '@lucide/svelte'; import { Button } from '../ui/button'; import { onMount } from 'svelte'; - import { api } from '$lib/api'; + import { useClient } from '$lib/api'; import Separator from '../ui/separator/separator.svelte'; + import { UtilService } from '$lib/gen/mantrae/v1/util_pb'; let version = $state(''); onMount(async () => { - const data = await api.getVersion(); - version = data.version; + const client = useClient(UtilService); + const res = await client.getVersion({}); + version = res.version; }); diff --git a/web/src/lib/components/nav/AppSidebar.svelte b/web/src/lib/components/nav/AppSidebar.svelte index 5a896bf..a33f830 100644 --- a/web/src/lib/components/nav/AppSidebar.svelte +++ b/web/src/lib/components/nav/AppSidebar.svelte @@ -25,18 +25,14 @@ CircleUserRound, Sun, Moon, - Zap, type IconProps } from '@lucide/svelte'; - import InfoModal from '../modals/info.svelte'; - import ProfileModal from '../modals/profile.svelte'; - import UserModal from '../modals/user.svelte'; - import { profiles, api } from '$lib/api'; import { slide } from 'svelte/transition'; import type { Profile } from '$lib/types'; import { theme } from '$lib/stores/theme'; import { profile } from '$lib/stores/profile'; import { user } from '$lib/stores/user'; + import { logout, profileClient } from '$lib/api'; let { ref = $bindable(null), @@ -99,14 +95,15 @@ let modalState = $state(initialModalState); let infoModalOpen = $state(false); let userModalOpen = $state(false); + // let profiles = $derived(client.listProfiles({}).then((res) => res.profiles)); - - - -{#if user.isLoggedIn() && user.value} - -{/if} + + + + + + @@ -130,7 +127,7 @@ {profile.name ? profile.name : 'Select Profile'} - {profile.value?.url ?? ''} + {profile.value?.description ?? ''} @@ -143,26 +140,28 @@ sideOffset={4} > Profiles - {#each $profiles as p (p.name)} - (profile.value = p)} - class="flex justify-between gap-2" - > -
-
- -
- {p.name} -
- -
- {/each} +
+
+ +
+ {p.name} +
+ + + {/each} + {/await} (modalState = { isOpen: true })}>
@@ -240,25 +239,25 @@ - - - Status - - {#if $profiles} - - - {#snippet child({ props })} - - {/snippet} - - - {/if} - - - + + + + + + + + + + + + + + + + + + + @@ -324,7 +323,7 @@ - api.logout()}> + logout()}> Log out diff --git a/web/src/lib/gen/mantrae/v1/dns_provider_pb.ts b/web/src/lib/gen/mantrae/v1/dns_provider_pb.ts new file mode 100644 index 0000000..f0da704 --- /dev/null +++ b/web/src/lib/gen/mantrae/v1/dns_provider_pb.ts @@ -0,0 +1,358 @@ +// @generated by protoc-gen-es v2.5.2 with parameter "target=ts" +// @generated from file mantrae/v1/dns_provider.proto (package mantrae.v1, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2"; +import { fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2"; +import type { Timestamp } from "@bufbuild/protobuf/wkt"; +import { file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file mantrae/v1/dns_provider.proto. + */ +export const file_mantrae_v1_dns_provider: GenFile = /*@__PURE__*/ + fileDesc("Ch1tYW50cmFlL3YxL2Ruc19wcm92aWRlci5wcm90bxIKbWFudHJhZS52MSLXAQoLRG5zUHJvdmlkZXISCgoCaWQYASABKAMSDAoEbmFtZRgCIAEoCRIMCgR0eXBlGAMgASgJEi0KBmNvbmZpZxgEIAEoCzIdLm1hbnRyYWUudjEuRG5zUHJvdmlkZXJDb25maWcSEQoJaXNfYWN0aXZlGAUgASgIEi4KCmNyZWF0ZWRfYXQYBiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEi4KCnVwZGF0ZWRfYXQYByABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wInoKEURuc1Byb3ZpZGVyQ29uZmlnEg8KB2FwaV9rZXkYASABKAkSDwoHYXBpX3VybBgCIAEoCRIKCgJpcBgDIAEoCRIPCgdwcm94aWVkGAQgASgIEhMKC2F1dG9fdXBkYXRlGAUgASgIEhEKCXpvbmVfdHlwZRgGIAEoCSIjChVHZXREbnNQcm92aWRlclJlcXVlc3QSCgoCaWQYASABKAMiRwoWR2V0RG5zUHJvdmlkZXJSZXNwb25zZRItCgxkbnNfcHJvdmlkZXIYASABKAsyFy5tYW50cmFlLnYxLkRuc1Byb3ZpZGVyIngKGENyZWF0ZURuc1Byb3ZpZGVyUmVxdWVzdBIMCgRuYW1lGAEgASgJEgwKBHR5cGUYAiABKAkSLQoGY29uZmlnGAMgASgLMh0ubWFudHJhZS52MS5EbnNQcm92aWRlckNvbmZpZxIRCglpc19hY3RpdmUYBCABKAgiSgoZQ3JlYXRlRG5zUHJvdmlkZXJSZXNwb25zZRItCgxkbnNfcHJvdmlkZXIYASABKAsyFy5tYW50cmFlLnYxLkRuc1Byb3ZpZGVyIngKGFVwZGF0ZURuc1Byb3ZpZGVyUmVxdWVzdBIMCgRuYW1lGAIgASgJEgwKBHR5cGUYAyABKAkSLQoGY29uZmlnGAQgASgLMh0ubWFudHJhZS52MS5EbnNQcm92aWRlckNvbmZpZxIRCglpc19hY3RpdmUYBSABKAgiSgoZVXBkYXRlRG5zUHJvdmlkZXJSZXNwb25zZRItCgxkbnNfcHJvdmlkZXIYASABKAsyFy5tYW50cmFlLnYxLkRuc1Byb3ZpZGVyIiYKGERlbGV0ZURuc1Byb3ZpZGVyUmVxdWVzdBIKCgJpZBgBIAEoAyIbChlEZWxldGVEbnNQcm92aWRlclJlc3BvbnNlIlcKF0xpc3REbnNQcm92aWRlcnNSZXF1ZXN0EhIKBWxpbWl0GAEgASgDSACIAQESEwoGb2Zmc2V0GAIgASgDSAGIAQFCCAoGX2xpbWl0QgkKB19vZmZzZXQiXwoYTGlzdERuc1Byb3ZpZGVyc1Jlc3BvbnNlEi4KDWRuc19wcm92aWRlcnMYASADKAsyFy5tYW50cmFlLnYxLkRuc1Byb3ZpZGVyEhMKC3RvdGFsX2NvdW50GAIgASgDMvwDChJEbnNQcm92aWRlclNlcnZpY2USXAoOR2V0RG5zUHJvdmlkZXISIS5tYW50cmFlLnYxLkdldERuc1Byb3ZpZGVyUmVxdWVzdBoiLm1hbnRyYWUudjEuR2V0RG5zUHJvdmlkZXJSZXNwb25zZSIDkAIBEmAKEUNyZWF0ZURuc1Byb3ZpZGVyEiQubWFudHJhZS52MS5DcmVhdGVEbnNQcm92aWRlclJlcXVlc3QaJS5tYW50cmFlLnYxLkNyZWF0ZURuc1Byb3ZpZGVyUmVzcG9uc2USYAoRVXBkYXRlRG5zUHJvdmlkZXISJC5tYW50cmFlLnYxLlVwZGF0ZURuc1Byb3ZpZGVyUmVxdWVzdBolLm1hbnRyYWUudjEuVXBkYXRlRG5zUHJvdmlkZXJSZXNwb25zZRJgChFEZWxldGVEbnNQcm92aWRlchIkLm1hbnRyYWUudjEuRGVsZXRlRG5zUHJvdmlkZXJSZXF1ZXN0GiUubWFudHJhZS52MS5EZWxldGVEbnNQcm92aWRlclJlc3BvbnNlEmIKEExpc3REbnNQcm92aWRlcnMSIy5tYW50cmFlLnYxLkxpc3REbnNQcm92aWRlcnNSZXF1ZXN0GiQubWFudHJhZS52MS5MaXN0RG5zUHJvdmlkZXJzUmVzcG9uc2UiA5ACAUKqAQoOY29tLm1hbnRyYWUudjFCEERuc1Byb3ZpZGVyUHJvdG9QAVo9Z2l0aHViLmNvbS9taXp1Y2hpbGFicy9tYW50cmFlL3Byb3RvL2dlbi9tYW50cmFlL3YxO21hbnRyYWV2MaICA01YWKoCCk1hbnRyYWUuVjHKAgpNYW50cmFlXFYx4gIWTWFudHJhZVxWMVxHUEJNZXRhZGF0YeoCC01hbnRyYWU6OlYxYgZwcm90bzM", [file_google_protobuf_timestamp]); + +/** + * @generated from message mantrae.v1.DnsProvider + */ +export type DnsProvider = Message<"mantrae.v1.DnsProvider"> & { + /** + * @generated from field: int64 id = 1; + */ + id: bigint; + + /** + * @generated from field: string name = 2; + */ + name: string; + + /** + * @generated from field: string type = 3; + */ + type: string; + + /** + * @generated from field: mantrae.v1.DnsProviderConfig config = 4; + */ + config?: DnsProviderConfig; + + /** + * @generated from field: bool is_active = 5; + */ + isActive: boolean; + + /** + * @generated from field: google.protobuf.Timestamp created_at = 6; + */ + createdAt?: Timestamp; + + /** + * @generated from field: google.protobuf.Timestamp updated_at = 7; + */ + updatedAt?: Timestamp; +}; + +/** + * Describes the message mantrae.v1.DnsProvider. + * Use `create(DnsProviderSchema)` to create a new message. + */ +export const DnsProviderSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_mantrae_v1_dns_provider, 0); + +/** + * @generated from message mantrae.v1.DnsProviderConfig + */ +export type DnsProviderConfig = Message<"mantrae.v1.DnsProviderConfig"> & { + /** + * @generated from field: string api_key = 1; + */ + apiKey: string; + + /** + * @generated from field: string api_url = 2; + */ + apiUrl: string; + + /** + * @generated from field: string ip = 3; + */ + ip: string; + + /** + * @generated from field: bool proxied = 4; + */ + proxied: boolean; + + /** + * @generated from field: bool auto_update = 5; + */ + autoUpdate: boolean; + + /** + * @generated from field: string zone_type = 6; + */ + zoneType: string; +}; + +/** + * Describes the message mantrae.v1.DnsProviderConfig. + * Use `create(DnsProviderConfigSchema)` to create a new message. + */ +export const DnsProviderConfigSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_mantrae_v1_dns_provider, 1); + +/** + * @generated from message mantrae.v1.GetDnsProviderRequest + */ +export type GetDnsProviderRequest = Message<"mantrae.v1.GetDnsProviderRequest"> & { + /** + * @generated from field: int64 id = 1; + */ + id: bigint; +}; + +/** + * Describes the message mantrae.v1.GetDnsProviderRequest. + * Use `create(GetDnsProviderRequestSchema)` to create a new message. + */ +export const GetDnsProviderRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_mantrae_v1_dns_provider, 2); + +/** + * @generated from message mantrae.v1.GetDnsProviderResponse + */ +export type GetDnsProviderResponse = Message<"mantrae.v1.GetDnsProviderResponse"> & { + /** + * @generated from field: mantrae.v1.DnsProvider dns_provider = 1; + */ + dnsProvider?: DnsProvider; +}; + +/** + * Describes the message mantrae.v1.GetDnsProviderResponse. + * Use `create(GetDnsProviderResponseSchema)` to create a new message. + */ +export const GetDnsProviderResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_mantrae_v1_dns_provider, 3); + +/** + * @generated from message mantrae.v1.CreateDnsProviderRequest + */ +export type CreateDnsProviderRequest = Message<"mantrae.v1.CreateDnsProviderRequest"> & { + /** + * @generated from field: string name = 1; + */ + name: string; + + /** + * @generated from field: string type = 2; + */ + type: string; + + /** + * @generated from field: mantrae.v1.DnsProviderConfig config = 3; + */ + config?: DnsProviderConfig; + + /** + * @generated from field: bool is_active = 4; + */ + isActive: boolean; +}; + +/** + * Describes the message mantrae.v1.CreateDnsProviderRequest. + * Use `create(CreateDnsProviderRequestSchema)` to create a new message. + */ +export const CreateDnsProviderRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_mantrae_v1_dns_provider, 4); + +/** + * @generated from message mantrae.v1.CreateDnsProviderResponse + */ +export type CreateDnsProviderResponse = Message<"mantrae.v1.CreateDnsProviderResponse"> & { + /** + * @generated from field: mantrae.v1.DnsProvider dns_provider = 1; + */ + dnsProvider?: DnsProvider; +}; + +/** + * Describes the message mantrae.v1.CreateDnsProviderResponse. + * Use `create(CreateDnsProviderResponseSchema)` to create a new message. + */ +export const CreateDnsProviderResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_mantrae_v1_dns_provider, 5); + +/** + * @generated from message mantrae.v1.UpdateDnsProviderRequest + */ +export type UpdateDnsProviderRequest = Message<"mantrae.v1.UpdateDnsProviderRequest"> & { + /** + * @generated from field: string name = 2; + */ + name: string; + + /** + * @generated from field: string type = 3; + */ + type: string; + + /** + * @generated from field: mantrae.v1.DnsProviderConfig config = 4; + */ + config?: DnsProviderConfig; + + /** + * @generated from field: bool is_active = 5; + */ + isActive: boolean; +}; + +/** + * Describes the message mantrae.v1.UpdateDnsProviderRequest. + * Use `create(UpdateDnsProviderRequestSchema)` to create a new message. + */ +export const UpdateDnsProviderRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_mantrae_v1_dns_provider, 6); + +/** + * @generated from message mantrae.v1.UpdateDnsProviderResponse + */ +export type UpdateDnsProviderResponse = Message<"mantrae.v1.UpdateDnsProviderResponse"> & { + /** + * @generated from field: mantrae.v1.DnsProvider dns_provider = 1; + */ + dnsProvider?: DnsProvider; +}; + +/** + * Describes the message mantrae.v1.UpdateDnsProviderResponse. + * Use `create(UpdateDnsProviderResponseSchema)` to create a new message. + */ +export const UpdateDnsProviderResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_mantrae_v1_dns_provider, 7); + +/** + * @generated from message mantrae.v1.DeleteDnsProviderRequest + */ +export type DeleteDnsProviderRequest = Message<"mantrae.v1.DeleteDnsProviderRequest"> & { + /** + * @generated from field: int64 id = 1; + */ + id: bigint; +}; + +/** + * Describes the message mantrae.v1.DeleteDnsProviderRequest. + * Use `create(DeleteDnsProviderRequestSchema)` to create a new message. + */ +export const DeleteDnsProviderRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_mantrae_v1_dns_provider, 8); + +/** + * @generated from message mantrae.v1.DeleteDnsProviderResponse + */ +export type DeleteDnsProviderResponse = Message<"mantrae.v1.DeleteDnsProviderResponse"> & { +}; + +/** + * Describes the message mantrae.v1.DeleteDnsProviderResponse. + * Use `create(DeleteDnsProviderResponseSchema)` to create a new message. + */ +export const DeleteDnsProviderResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_mantrae_v1_dns_provider, 9); + +/** + * @generated from message mantrae.v1.ListDnsProvidersRequest + */ +export type ListDnsProvidersRequest = Message<"mantrae.v1.ListDnsProvidersRequest"> & { + /** + * @generated from field: optional int64 limit = 1; + */ + limit?: bigint; + + /** + * @generated from field: optional int64 offset = 2; + */ + offset?: bigint; +}; + +/** + * Describes the message mantrae.v1.ListDnsProvidersRequest. + * Use `create(ListDnsProvidersRequestSchema)` to create a new message. + */ +export const ListDnsProvidersRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_mantrae_v1_dns_provider, 10); + +/** + * @generated from message mantrae.v1.ListDnsProvidersResponse + */ +export type ListDnsProvidersResponse = Message<"mantrae.v1.ListDnsProvidersResponse"> & { + /** + * @generated from field: repeated mantrae.v1.DnsProvider dns_providers = 1; + */ + dnsProviders: DnsProvider[]; + + /** + * @generated from field: int64 total_count = 2; + */ + totalCount: bigint; +}; + +/** + * Describes the message mantrae.v1.ListDnsProvidersResponse. + * Use `create(ListDnsProvidersResponseSchema)` to create a new message. + */ +export const ListDnsProvidersResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_mantrae_v1_dns_provider, 11); + +/** + * @generated from service mantrae.v1.DnsProviderService + */ +export const DnsProviderService: GenService<{ + /** + * @generated from rpc mantrae.v1.DnsProviderService.GetDnsProvider + */ + getDnsProvider: { + methodKind: "unary"; + input: typeof GetDnsProviderRequestSchema; + output: typeof GetDnsProviderResponseSchema; + }, + /** + * @generated from rpc mantrae.v1.DnsProviderService.CreateDnsProvider + */ + createDnsProvider: { + methodKind: "unary"; + input: typeof CreateDnsProviderRequestSchema; + output: typeof CreateDnsProviderResponseSchema; + }, + /** + * @generated from rpc mantrae.v1.DnsProviderService.UpdateDnsProvider + */ + updateDnsProvider: { + methodKind: "unary"; + input: typeof UpdateDnsProviderRequestSchema; + output: typeof UpdateDnsProviderResponseSchema; + }, + /** + * @generated from rpc mantrae.v1.DnsProviderService.DeleteDnsProvider + */ + deleteDnsProvider: { + methodKind: "unary"; + input: typeof DeleteDnsProviderRequestSchema; + output: typeof DeleteDnsProviderResponseSchema; + }, + /** + * @generated from rpc mantrae.v1.DnsProviderService.ListDnsProviders + */ + listDnsProviders: { + methodKind: "unary"; + input: typeof ListDnsProvidersRequestSchema; + output: typeof ListDnsProvidersResponseSchema; + }, +}> = /*@__PURE__*/ + serviceDesc(file_mantrae_v1_dns_provider, 0); + diff --git a/web/src/lib/gen/mantrae/v1/util_pb.ts b/web/src/lib/gen/mantrae/v1/util_pb.ts new file mode 100644 index 0000000..aebd2bd --- /dev/null +++ b/web/src/lib/gen/mantrae/v1/util_pb.ts @@ -0,0 +1,103 @@ +// @generated by protoc-gen-es v2.5.2 with parameter "target=ts" +// @generated from file mantrae/v1/util.proto (package mantrae.v1, syntax proto3) +/* eslint-disable */ + +import type { GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2"; +import { fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv2"; +import { file_google_protobuf_timestamp } from "@bufbuild/protobuf/wkt"; +import type { Message } from "@bufbuild/protobuf"; + +/** + * Describes the file mantrae/v1/util.proto. + */ +export const file_mantrae_v1_util: GenFile = /*@__PURE__*/ + fileDesc("ChVtYW50cmFlL3YxL3V0aWwucHJvdG8SCm1hbnRyYWUudjEiEwoRR2V0VmVyc2lvblJlcXVlc3QiJQoSR2V0VmVyc2lvblJlc3BvbnNlEg8KB3ZlcnNpb24YASABKAkiFAoSR2V0UHVibGljSVBSZXF1ZXN0IjEKE0dldFB1YmxpY0lQUmVzcG9uc2USDAoEaXB2NBgBIAEoCRIMCgRpcHY2GAIgASgJMqoBCgtVdGlsU2VydmljZRJLCgpHZXRWZXJzaW9uEh0ubWFudHJhZS52MS5HZXRWZXJzaW9uUmVxdWVzdBoeLm1hbnRyYWUudjEuR2V0VmVyc2lvblJlc3BvbnNlEk4KC0dldFB1YmxpY0lQEh4ubWFudHJhZS52MS5HZXRQdWJsaWNJUFJlcXVlc3QaHy5tYW50cmFlLnYxLkdldFB1YmxpY0lQUmVzcG9uc2VCowEKDmNvbS5tYW50cmFlLnYxQglVdGlsUHJvdG9QAVo9Z2l0aHViLmNvbS9taXp1Y2hpbGFicy9tYW50cmFlL3Byb3RvL2dlbi9tYW50cmFlL3YxO21hbnRyYWV2MaICA01YWKoCCk1hbnRyYWUuVjHKAgpNYW50cmFlXFYx4gIWTWFudHJhZVxWMVxHUEJNZXRhZGF0YeoCC01hbnRyYWU6OlYxYgZwcm90bzM", [file_google_protobuf_timestamp]); + +/** + * @generated from message mantrae.v1.GetVersionRequest + */ +export type GetVersionRequest = Message<"mantrae.v1.GetVersionRequest"> & { +}; + +/** + * Describes the message mantrae.v1.GetVersionRequest. + * Use `create(GetVersionRequestSchema)` to create a new message. + */ +export const GetVersionRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_mantrae_v1_util, 0); + +/** + * @generated from message mantrae.v1.GetVersionResponse + */ +export type GetVersionResponse = Message<"mantrae.v1.GetVersionResponse"> & { + /** + * @generated from field: string version = 1; + */ + version: string; +}; + +/** + * Describes the message mantrae.v1.GetVersionResponse. + * Use `create(GetVersionResponseSchema)` to create a new message. + */ +export const GetVersionResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_mantrae_v1_util, 1); + +/** + * @generated from message mantrae.v1.GetPublicIPRequest + */ +export type GetPublicIPRequest = Message<"mantrae.v1.GetPublicIPRequest"> & { +}; + +/** + * Describes the message mantrae.v1.GetPublicIPRequest. + * Use `create(GetPublicIPRequestSchema)` to create a new message. + */ +export const GetPublicIPRequestSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_mantrae_v1_util, 2); + +/** + * @generated from message mantrae.v1.GetPublicIPResponse + */ +export type GetPublicIPResponse = Message<"mantrae.v1.GetPublicIPResponse"> & { + /** + * @generated from field: string ipv4 = 1; + */ + ipv4: string; + + /** + * @generated from field: string ipv6 = 2; + */ + ipv6: string; +}; + +/** + * Describes the message mantrae.v1.GetPublicIPResponse. + * Use `create(GetPublicIPResponseSchema)` to create a new message. + */ +export const GetPublicIPResponseSchema: GenMessage = /*@__PURE__*/ + messageDesc(file_mantrae_v1_util, 3); + +/** + * @generated from service mantrae.v1.UtilService + */ +export const UtilService: GenService<{ + /** + * @generated from rpc mantrae.v1.UtilService.GetVersion + */ + getVersion: { + methodKind: "unary"; + input: typeof GetVersionRequestSchema; + output: typeof GetVersionResponseSchema; + }, + /** + * @generated from rpc mantrae.v1.UtilService.GetPublicIP + */ + getPublicIP: { + methodKind: "unary"; + input: typeof GetPublicIPRequestSchema; + output: typeof GetPublicIPResponseSchema; + }, +}> = /*@__PURE__*/ + serviceDesc(file_mantrae_v1_util, 0); + diff --git a/web/src/lib/stores/common.ts b/web/src/lib/stores/common.ts index d399a52..7699446 100644 --- a/web/src/lib/stores/common.ts +++ b/web/src/lib/stores/common.ts @@ -1,5 +1,6 @@ -import { createLocalStorage } from '$lib/storage.svelte'; +import { createLocalStorage, LocalStorage } from '$lib/storage.svelte'; +export const token: LocalStorage = createLocalStorage('auth_token', null); export const limit = createLocalStorage('limit', '10'); export const routerColumns = createLocalStorage('router_columns', []); export const middlewareColumns = createLocalStorage('middleware_columns', []); diff --git a/web/src/lib/stores/profile.ts b/web/src/lib/stores/profile.ts index 481363d..151e50d 100644 --- a/web/src/lib/stores/profile.ts +++ b/web/src/lib/stores/profile.ts @@ -1,5 +1,5 @@ +import type { Profile } from '$lib/gen/mantrae/v1/profile_pb'; import { createLocalStorage } from '$lib/storage.svelte'; -import type { Profile } from '$lib/types'; class ProfileStore { private store = createLocalStorage('selected_profile', null); @@ -13,7 +13,7 @@ class ProfileStore { } // Helper methods for safe access - get id(): number | undefined { + get id(): bigint | undefined { return this.value?.id; } @@ -21,9 +21,13 @@ class ProfileStore { return this.value?.name; } + get description(): string | undefined { + return this.value?.description; + } + // Validation methods hasValidId(): boolean { - return typeof this.id === 'number' && !isNaN(this.id); + return typeof this.id === 'bigint' && this.id > 0n; } hasValidName(): boolean { diff --git a/web/src/lib/stores/source.ts b/web/src/lib/stores/source.ts deleted file mode 100644 index 2d0639c..0000000 --- a/web/src/lib/stores/source.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { createLocalStorage } from '$lib/storage.svelte'; -import { TraefikSource } from '$lib/types'; - -class TraefikSourceStore { - private store = createLocalStorage('selected_source', TraefikSource.API); - - get value(): TraefikSource { - return this.store.value ?? TraefikSource.API; - } - - set value(source: TraefikSource) { - if (this.isValid(source)) { - this.store.value = source; - } - } - - isValid(source: string): source is TraefikSource { - return Object.values(TraefikSource).includes(source as TraefikSource); - } - - isApi(): boolean { - return this.value === TraefikSource.API; - } - - isLocal(): boolean { - return this.value === TraefikSource.LOCAL; - } - - isAgent(): boolean { - return this.value === TraefikSource.AGENT; - } - - // Reset to default - reset(): void { - this.store.value = TraefikSource.API; - } -} - -export const source = new TraefikSourceStore(); diff --git a/web/src/lib/stores/user.ts b/web/src/lib/stores/user.ts index 9162e43..d931e03 100644 --- a/web/src/lib/stores/user.ts +++ b/web/src/lib/stores/user.ts @@ -1,5 +1,6 @@ +import type { User } from '$lib/gen/mantrae/v1/user_pb'; +import type { Timestamp } from '@bufbuild/protobuf/wkt'; import { createLocalStorage } from '$lib/storage.svelte'; -import type { User } from '$lib/types'; class UserStore { private store = createLocalStorage('current_user', null); @@ -12,8 +13,7 @@ class UserStore { this.store.value = user; } - // Safe getters for required fields - get id(): number | undefined { + get id(): string | undefined { return this.value?.id; } @@ -25,20 +25,19 @@ class UserStore { return this.value?.isAdmin ?? false; } - // Optional field getters get email(): string | undefined { return this.value?.email; } - get lastLogin(): string | undefined { + get lastLogin(): Timestamp | undefined { return this.value?.lastLogin; } - get createdAt(): string | undefined { + get createdAt(): Timestamp | undefined { return this.value?.createdAt; } - get updatedAt(): string | undefined { + get updatedAt(): Timestamp | undefined { return this.value?.updatedAt; } diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 5bf5152..1c099c8 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -1,42 +1,26 @@ - + - {#if user.isLoggedIn()} + {#if token.value}
diff --git a/web/src/routes/+layout.ts b/web/src/routes/+layout.ts index bd2e204..af26501 100644 --- a/web/src/routes/+layout.ts +++ b/web/src/routes/+layout.ts @@ -1,7 +1,9 @@ import type { LayoutLoad } from './$types'; -import { api } from '$lib/api'; +import { logout, useClient } from '$lib/api'; import { goto } from '$app/navigation'; import { user } from '$lib/stores/user'; +import { UserService } from '$lib/gen/mantrae/v1/user_pb'; +import { token } from '$lib/stores/common'; export const ssr = false; export const prerender = true; @@ -12,35 +14,43 @@ const isPublicRoute = (path: string) => { }; export const load: LayoutLoad = async ({ url, fetch }) => { - const currentPath = url.pathname; - const isPublic = isPublicRoute(currentPath); - - // Try to verify authentication via cookie - try { - const isVerified = await api.verify(fetch); - - if (isVerified) { - // User is authenticated - if (isPublic) { - // Authenticated user trying to access login page - redirect to home - await goto('/'); - return; - } - // Continue to protected route - return; - } else { - // Verification failed but no exception thrown - throw new Error('Authentication failed'); - } - } catch (_) { - // Authentication failed + // Case 1: No token and accessing protected route + if (!token.value && !isPublicRoute(url.pathname)) { + await goto('/login/'); user.clear(); - - if (!isPublic) { - // User trying to access protected route without auth - redirect to login - await goto('/login'); - } - // If already on public route, stay there return; } + + // If we have a token, verify it + if (token.value) { + try { + const client = useClient(UserService, fetch); + const userId = (await client.verifyJWT({ token: token.value })).userId; + if (!userId) { + throw new Error('Invalid token'); + } + const data = await client.getUser({ identifier: { value: userId, case: 'id' } }); + if (!data.user || !data.user.id) { + throw new Error('User not found'); + } + + // Redirect to home if trying to access login page while authenticated + if (isPublicRoute(url.pathname) && user.isLoggedIn()) { + await goto('/'); + } + return; + } catch (error) { + // Token verification failed, clean up + logout(); + user.clear(); + throw new Error('Token verification failed: ' + error); + } + } + + // No token and trying to access protected route + if (!isPublicRoute) { + await goto('/login'); + } + + return; }; diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte index fe91fe3..3b464f1 100644 --- a/web/src/routes/+page.svelte +++ b/web/src/routes/+page.svelte @@ -1,58 +1,53 @@
@@ -71,7 +66,9 @@ -
{$stats.profiles}
+ {#await profileClient.listProfiles({}) then result} +
{result.totalCount}
+ {/await}
@@ -81,7 +78,9 @@ -
{$stats.agents}
+ {#await agentClient.listAgents({}) then result} +
{result.totalCount}
+ {/await}

Across all profiles

@@ -92,12 +91,14 @@ -
- {$stats.activeDNS || 'None'} -
-

- {$stats.dnsProviders} providers configured -

+ {#await dnsClient.listDnsProviders({}) then result} + + + +

+ {result.totalCount}providers configured +

+ {/await}
@@ -107,7 +108,9 @@ -
{$stats.users}
+ {#await userClient.listUsers({}) then result} +
{result.totalCount}
+ {/await}

@@ -121,35 +124,49 @@
- {#each profileStats as profile (profile.id)} -
-
- -
-

- {profile.name} -

-

- {profile.url} -

+ {#await profileClient.listProfiles({}) then result} + {#each result.profiles || [] as profile (profile.id)} +
+
+ +
+

+ {profile.name} +

+

+ {profile.description} +

+
+
+
+ {#await agentClient.listAgents({}) then result} + 0 ? 'default' : 'secondary'}> + {result.totalCount} + {result.totalCount === 1n ? 'Agent' : 'Agents'} + + {/await} + {#await routerClient.listRouters({}) then result} + 0 ? 'default' : 'secondary'}> + {result.totalCount} + {result.totalCount === 1n ? 'Router' : 'Routers'} + + {/await} + {#await serviceClient.listServices({}) then result} + 0 ? 'default' : 'secondary'}> + {result.totalCount} + {result.totalCount === 1n ? 'Service' : 'Services'} + + {/await} + {#await middlewareClient.listMiddlewares({}) then result} + 0 ? 'default' : 'secondary'}> + {result.totalCount} + {result.totalCount === 1n ? 'Middleware' : 'Middlewares'} + + {/await}
-
- 0 ? 'default' : 'secondary'}> - {profile.agents} - {profile.agents === 1 ? 'Agent' : 'Agents'} - - 0 ? 'default' : 'secondary'}> - {profile.routers} - {profile.routers === 1 ? 'Router' : 'Routers'} - - 0 ? 'default' : 'secondary'}> - {profile.middlewares} - {profile.middlewares === 1 ? 'Middleware' : 'Middlewares'} - -
-
- {/each} + {/each} + {/await}
@@ -159,33 +176,35 @@ System Errors - + + + + + + + +
- {#each $errors as error (error.id)} -
-
- -
-
-

- {error.message} -

-

- {error.details} -

-
-
- {/each} + + + + + + + + + + + + + + + + +
diff --git a/web/src/routes/login/+page.svelte b/web/src/routes/login/+page.svelte index 6126f0b..c628126 100644 --- a/web/src/routes/login/+page.svelte +++ b/web/src/routes/login/+page.svelte @@ -5,61 +5,75 @@ import { Label } from '$lib/components/ui/label/index.js'; import { Checkbox } from '$lib/components/ui/checkbox'; import { toast } from 'svelte-sonner'; - import { api, loading } from '$lib/api'; + import { userClient } from '$lib/api'; import PasswordInput from '$lib/components/ui/password-input/password-input.svelte'; import Separator from '$lib/components/ui/separator/separator.svelte'; import { goto } from '$app/navigation'; import { user } from '$lib/stores/user'; import type { OAuthStatus } from '$lib/types'; - import { onMount } from 'svelte'; + import { token } from '$lib/stores/common'; + import { ConnectError } from '@connectrpc/connect'; let username = $state(''); let password = $state(''); let remember = $state(false); - let oauthStatus: OAuthStatus = $state({ enabled: false, provider: '' }); + // let oauthStatus: OAuthStatus = $state({ enabled: false, provider: '' }); const handleReset = async () => { if (username.length > 0) { - const resetPromise = api - .sendResetEmail(username) - .then(() => { - goto(`/login/reset?username=${username}`); - return 'Reset email sent successfully!'; - }) - .catch((error) => { - throw new Error(error.message || 'Failed to send reset email'); - }); - - toast.promise(resetPromise, { - loading: 'Sending reset email...', - success: (message) => message, - error: (error) => (error as Error).message - }); - } else { toast.error('Please enter a username!'); + return; + } + const isEmail = username.includes('@'); + + try { + await userClient.sendOTP({ + identifier: { + case: isEmail ? 'email' : 'username', + value: username + } + }); + + await goto(`/login/reset?username=${username}`); + toast.success('Code sent successfully!'); + } catch (err) { + const e = ConnectError.from(err); + toast.error('Failed to send reset code', { description: e.message }); } }; const handleSubmit = async () => { - const loginPromise = api - .login(username, password, remember) - .then(() => { - return 'Logged in successfully!'; - }) - .catch((error) => { - throw new Error(error.message || 'Login failed'); - }); + const isEmail = username.includes('@'); - toast.promise(loginPromise, { - loading: 'Logging in...', - success: (message) => message, - error: (error) => (error as Error).message - }); + try { + const res = await userClient.loginUser({ + identifier: { + case: isEmail ? 'email' : 'username', + value: username + }, + password: password, + remember: remember + }); + token.value = res.token ?? null; + + if (!token.value) { + throw new Error('No token received'); + } + + const verified = await userClient.verifyJWT({ token: token.value }); + if (verified.userId) { + await goto('/'); + } + toast.success('Logged in successfully!'); + } catch (err) { + const e = ConnectError.from(err); + toast.error('Failed to login', { description: e.message }); + } }; - const handleOIDCLogin = () => { - window.location.href = '/api/oidc/login'; - }; - onMount(async () => { - oauthStatus = await api.oauthStatus(); - }); + // const handleOIDCLogin = () => { + // window.location.href = '/api/oidc/login'; + // }; + // onMount(async () => { + // oauthStatus = await api.oauthStatus(); + // }); {#if !user.isLoggedIn()} @@ -70,38 +84,38 @@
- {#if !oauthStatus.loginDisabled} -
- - -
+ +
+ + +
-
- - -
-
- -
- -
+
+ + +
+
+ +
+
-
+
+
- + - - {/if} + + - {#if oauthStatus.enabled} - - {/if} + + + + +