diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9c71401..6971470 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,9 +24,9 @@ jobs: with: go-version: 1.19 - - uses: open-policy-agent/setup-opa@v1 + - uses: open-policy-agent/setup-opa@v2 with: - version: 0.45 + version: 0.46 - name: Build run: make ci diff --git a/README.md b/README.md index 8808a86..ef71616 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ You'll need to set some environment variables to tell pslive how to assign names - SESSIONS_ENCRYPTION_KEY, which should be set to a session encryption key generated by running pslive without the SESSION_ENCRYPTION_KEY set. - ORY_KRATOS_SERVER, which should be set to the URL of your Ory Kratos public API (either self-hosted or hosted on Ory Cloud), including the protocol scheme (e.g. `https://project-id.projects.oryapis.com`). - ORY_ACCESS_TOKEN, which should be set to a personal access token from Ory Cloud for the URL of your Ory Kratos administrative API. -- TURBOSTREAMS_HASH_KEY, which should be set to an HMAC key generated by running Fluitans without the TURBOSTREAMS_HASH_KEY set. +- ACTIONCABLE_HASH_KEY, which should be set to an HMAC key generated by running Fluitans without the ACTIONCABLE_HASH_KEY set. For example, you could generate the session and Turbo Streams hash key using: ``` @@ -42,7 +42,7 @@ which will print a message like: ``` Record this key for future use as SESSIONS_AUTH_KEY: QVG4y5EPPoDZjAzYc6j7I09iJum3w+hXNrB3O4HQvSc= Record this key for future use as SESSIONS_ENCRYPTION_KEY: Z/47Z2Uf6J68VFf7uAjiTfmum3yKWRuR2KoLVhwVdYA= -Record this key for future use as TURBOSTREAMS_HASH_KEY: S+daMZsQxsqjmINunGWJhXvvxcgJtqnACba+sFuC4Tc= +Record this key for future use as ACTIONCABLE_HASH_KEY: S+daMZsQxsqjmINunGWJhXvvxcgJtqnACba+sFuC4Tc= ``` And then you could run the server in development mode using: @@ -52,7 +52,7 @@ SESSION_AUTH_KEY='QVG4y5EPPoDZjAzYc6j7I09iJum3w+hXNrB3O4HQvSc=' \ SESSIONS_ENCRYPTION_KEY='Z/47Z2Uf6J68VFf7uAjiTfmum3yKWRuR2KoLVhwVdYA=' \ ORY_KRATOS_SERVER='https://project-1234.projects.oryapis.com' \ ORY_ACCESS_TOKEN='ory_pat_12345' \ -TURBOSTREAMS_HASH_KEY='S+daMZsQxsqjmINunGWJhXvvxcgJtqnACba+sFuC4Tc=' \ +ACTIONCABLE_HASH_KEY='S+daMZsQxsqjmINunGWJhXvvxcgJtqnACba+sFuC4Tc=' \ make run ``` @@ -62,7 +62,7 @@ DATABASE_URI='file:db.sqlite3' \ SESSION_AUTH_KEY='QVG4y5EPPoDZjAzYc6j7I09iJum3w+hXNrB3O4HQvSc=' \ ORY_KRATOS_SERVER='https://project-1234.projects.oryapis.com' \ ORY_ACCESS_TOKEN='ory_pat_12345' \ -TURBOSTREAMS_HASH_KEY='S+daMZsQxsqjmINunGWJhXvvxcgJtqnACba+sFuC4Tc=' \ +ACTIONCABLE_HASH_KEY='S+daMZsQxsqjmINunGWJhXvvxcgJtqnACba+sFuC4Tc=' \ ./pslive ``` diff --git a/go.mod b/go.mod index ed3c4db..8a09d05 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/ory/client-go v0.2.0-alpha.60 github.com/paulbellamy/ratecounter v0.2.0 github.com/pkg/errors v0.9.1 - github.com/sargassum-world/godest v0.4.3 + github.com/sargassum-world/godest v0.5.0 github.com/unrolled/secure v1.13.0 golang.org/x/image v0.1.0 golang.org/x/sync v0.1.0 @@ -37,6 +37,7 @@ require ( github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang/glog v1.0.0 // indirect github.com/golang/protobuf v1.5.2 // indirect + github.com/google/flatbuffers v22.11.23+incompatible // indirect github.com/google/uuid v1.3.0 // indirect github.com/gorilla/securecookie v1.1.1 // indirect github.com/huandu/xstrings v1.3.2 // indirect @@ -45,6 +46,7 @@ require ( github.com/mattn/go-isatty v0.0.16 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/prometheus/client_golang v1.14.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect github.com/rogpeppe/go-internal v1.8.0 // indirect @@ -59,12 +61,12 @@ require ( github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/yashtewari/glob-intersection v0.1.0 // indirect - golang.org/x/crypto v0.1.0 // indirect + golang.org/x/crypto v0.3.0 // indirect golang.org/x/net v0.2.0 // indirect - golang.org/x/oauth2 v0.1.0 // indirect + golang.org/x/oauth2 v0.2.0 // indirect golang.org/x/sys v0.2.0 // indirect golang.org/x/text v0.4.0 // indirect - golang.org/x/time v0.1.0 // indirect + golang.org/x/time v0.2.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index d4da098..2331d81 100644 --- a/go.sum +++ b/go.sum @@ -128,7 +128,8 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/flatbuffers v22.10.26+incompatible h1:z1QiaMyPu1x3Z6xf2u1dsLj1ZxicdGSeaLpCuIsQNZM= +github.com/google/flatbuffers v22.11.23+incompatible h1:334TygA7iuxt0hoamawsM36xoui01YiouEZnr0qeFMI= +github.com/google/flatbuffers v22.11.23+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -213,7 +214,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.13.1 h1:3gMjIY2+/hzmqhtUC/aQNYldJA6DtH3CgQvwS+02K1c= +github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= @@ -225,8 +227,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qq github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/sargassum-world/godest v0.4.3 h1:xPY1hHGm6Z7CxgknBRtlKeoUADNkqln4ISl8p4S6j3Q= -github.com/sargassum-world/godest v0.4.3/go.mod h1:WP4bplxzGfnRjwhlcfR21FvO/rZDrWA7Kf4pqmHYuS4= +github.com/sargassum-world/godest v0.5.0 h1:ggwHqedyqRL16p/qZiCrDTDPZbaggIi9Yia70SPBSZE= +github.com/sargassum-world/godest v0.5.0/go.mod h1:WP4bplxzGfnRjwhlcfR21FvO/rZDrWA7Kf4pqmHYuS4= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= @@ -280,8 +282,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -353,8 +355,8 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.1.0 h1:isLCZuhj4v+tYv7eskaN4v/TM+A1begWWgyVJDdl1+Y= -golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= +golang.org/x/oauth2 v0.2.0 h1:GtQkldQ9m7yvzCL1V+LrYow3Khe0eJH0w7RbX/VbaIU= +golang.org/x/oauth2 v0.2.0/go.mod h1:Cwn6afJ8jrQwYMxQDTpISoXmXW9I6qF6vDeuuoX3Ibs= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -420,8 +422,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA= -golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.2.0 h1:52I/1L54xyEQAYdtcSuxtiT84KGYTBGXwayxmIpNJhE= +golang.org/x/time v0.2.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= diff --git a/internal/app/pslive/client/globals.go b/internal/app/pslive/client/globals.go index 0552842..fbe4bf7 100644 --- a/internal/app/pslive/client/globals.go +++ b/internal/app/pslive/client/globals.go @@ -34,7 +34,7 @@ type Globals struct { AuthzChecker *auth.AuthzChecker ACCancellers *actioncable.Cancellers - TSSigner turbostreams.Signer + ACSigner actioncable.Signer TSBroker *turbostreams.Broker Instruments *instruments.Store @@ -85,11 +85,11 @@ func NewGlobals( g.AuthzChecker = auth.NewAuthzChecker(g.DB, opc) g.ACCancellers = actioncable.NewCancellers() - tssConfig, err := turbostreams.GetSignerConfig() + acsConfig, err := actioncable.GetSignerConfig() if err != nil { - return nil, errors.Wrap(err, "couldn't set up turbo streams signer config") + return nil, errors.Wrap(err, "couldn't set up action cable signer config") } - g.TSSigner = turbostreams.NewSigner(tssConfig) + g.ACSigner = actioncable.NewSigner(acsConfig) g.TSBroker = turbostreams.NewBroker(l) g.Instruments = instruments.NewStore(g.DB) diff --git a/internal/app/pslive/routes/cable/cable.go b/internal/app/pslive/routes/cable/cable.go index 38df359..f6d252c 100644 --- a/internal/app/pslive/routes/cable/cable.go +++ b/internal/app/pslive/routes/cable/cable.go @@ -2,44 +2,99 @@ package cable import ( "context" + "net/http" "github.com/gorilla/sessions" + "github.com/gorilla/websocket" "github.com/labstack/echo/v4" + "github.com/pkg/errors" + "github.com/sargassum-world/godest" "github.com/sargassum-world/godest/actioncable" + "github.com/sargassum-world/godest/handling" + "github.com/sargassum-world/godest/session" "github.com/sargassum-world/godest/turbostreams" "github.com/sargassum-world/pslive/internal/app/pslive/auth" + "github.com/sargassum-world/pslive/internal/clients/videostreams" ) +func serveWSConn( + r *http.Request, wsc *websocket.Conn, sess *sessions.Session, + channelFactories map[string]actioncable.ChannelFactory, + cc *session.CSRFTokenChecker, acc *actioncable.Cancellers, wsu websocket.Upgrader, + l godest.Logger, +) { + conn, err := actioncable.Upgrade(wsc, actioncable.NewChannelDispatcher( + channelFactories, make(map[string]actioncable.Channel), + actioncable.WithCSRFTokenChecker(func(token string) error { + return cc.Check(r, token) + }), + )) + // We can't return errors after the HTTP request is upgraded to a websocket, so we just log them + if err != nil { + l.Error(errors.Wrapf( + err, + "couldn't upgrade websocket connection to action cable connection "+ + "(client requested subprotocols %v, upgrader supports subprotocols %v)", + websocket.Subprotocols(r), + wsu.Subprotocols, + )) + if cerr := wsc.Close(); cerr != nil { + l.Error(errors.Wrapf(cerr, "couldn't close websocket")) + } + return + } + + ctx, cancel := context.WithCancel(r.Context()) + acc.Add(sess.ID, cancel) + serr := handling.Except(conn.Serve(ctx), context.Canceled) + if serr != nil { + // We can't return errors after the HTTP request is upgraded to a websocket, so we just log them + l.Error(serr) + } + if cerr := conn.Close(serr); err != nil { + // We can't return errors after the HTTP request is upgraded to a websocket, so we just log them + l.Error(cerr) + } +} + func (h *Handlers) HandleCableGet() auth.HTTPHandlerFuncWithSession { return func(c echo.Context, _ auth.Auth, sess *sessions.Session) error { wsc, err := h.wsu.Upgrade(c.Response(), c.Request(), nil) if err != nil { - return err + return errors.Wrap(err, "couldn't upgrade http request to websocket connection") } const wsMaxMessageSize = 512 wsc.SetReadLimit(wsMaxMessageSize) - - acc := actioncable.Upgrade(wsc, actioncable.WithChannels( + serveWSConn( + c.Request(), wsc, sess, map[string]actioncable.ChannelFactory{ - turbostreams.ChannelName: turbostreams.NewChannelFactory(h.tsb, sess.ID, h.tss.Check), + turbostreams.ChannelName: turbostreams.NewChannelFactory(h.tsb, sess.ID, h.acs.Check), }, - make(map[string]actioncable.Channel), - actioncable.WithCSRFTokenChecker(func(token string) error { - return h.cc.Check(c.Request(), token) - }), - )) - ctx, cancel := context.WithCancel(c.Request().Context()) - h.acc.Add(sess.ID, cancel) - serr := acc.Serve(ctx) - // We can't return errors after the HTTP request is upgraded to a websocket, so we just log them - if serr != nil && serr != context.Canceled { - h.l.Error(serr) - } - if err := acc.Close(serr); err != nil { - h.l.Error(err) + h.cc, h.acc, h.wsu, h.l, + ) + return nil + } +} + +func (h *Handlers) HandleVideoCableGet() auth.HTTPHandlerFuncWithSession { + return func(c echo.Context, _ auth.Auth, sess *sessions.Session) error { + wsc, err := h.wsu.Upgrade(c.Response(), c.Request(), nil) + if err != nil { + return errors.Wrap(err, "couldn't upgrade http request to websocket connection") } + + const wsMaxMessageSize = 512 + wsc.SetReadLimit(wsMaxMessageSize) + // TODO: make this action cable connection use msgpack instead of json for efficiency reasons + serveWSConn( + c.Request(), wsc, sess, + map[string]actioncable.ChannelFactory{ + videostreams.ChannelName: videostreams.NewChannelFactory(h.vsb, sess.ID, h.l, h.acs.Check), + }, + h.cc, h.acc, h.wsu, h.l, + ) return nil } } diff --git a/internal/app/pslive/routes/cable/routes.go b/internal/app/pslive/routes/cable/routes.go index 5b7f74c..1b53258 100644 --- a/internal/app/pslive/routes/cable/routes.go +++ b/internal/app/pslive/routes/cable/routes.go @@ -11,6 +11,7 @@ import ( "github.com/sargassum-world/godest/turbostreams" "github.com/sargassum-world/pslive/internal/app/pslive/auth" + "github.com/sargassum-world/pslive/internal/clients/videostreams" ) type Handlers struct { @@ -20,33 +21,37 @@ type Handlers struct { cc *session.CSRFTokenChecker acc *actioncable.Cancellers - tss turbostreams.Signer + acs actioncable.Signer tsb *turbostreams.Broker - - l godest.Logger + vsb *videostreams.Broker wsu websocket.Upgrader + + l godest.Logger } func New( r godest.TemplateRenderer, ss *session.Store, cc *session.CSRFTokenChecker, - acc *actioncable.Cancellers, tss turbostreams.Signer, tsb *turbostreams.Broker, l godest.Logger, + acc *actioncable.Cancellers, acs actioncable.Signer, tsb *turbostreams.Broker, + vsb *videostreams.Broker, l godest.Logger, ) *Handlers { return &Handlers{ r: r, ss: ss, cc: cc, acc: acc, - tss: tss, + acs: acs, tsb: tsb, - l: l, + vsb: vsb, wsu: websocket.Upgrader{ - Subprotocols: actioncable.Subprotocols(), + Subprotocols: actioncable.SupportedSubprotocols(), // TODO: add parameters to the upgrader as needed }, + l: l, } } func (h *Handlers) Register(er godest.EchoRouter) { er.GET("/cable", auth.HandleHTTPWithSession(h.HandleCableGet(), h.ss)) + er.GET("/video-cable", auth.HandleHTTPWithSession(h.HandleVideoCableGet(), h.ss)) } diff --git a/internal/app/pslive/routes/instruments/camera.go b/internal/app/pslive/routes/instruments/camera.go index c4466a7..360262d 100644 --- a/internal/app/pslive/routes/instruments/camera.go +++ b/internal/app/pslive/routes/instruments/camera.go @@ -68,20 +68,61 @@ const ( ) func newErrorJPEG(width, height int, message string) []byte { - output, _, err := newErrorFrame( + frame, err := newErrorFrame( width, height, message, - ).AsJPEG() + ).AsJPEGFrame() if err != nil { panic(err) } - return output + return frame.Im } -var ( - jpegError = newErrorJPEG(errorWidth, errorHeight, "stream failed") - frameError = newErrorFrame(errorWidth, errorHeight, "stream failed") - frameLoading = newErrorFrame(errorWidth, errorHeight, "loading stream...") -) +var jpegError = newErrorJPEG(errorWidth, errorHeight, "stream failed") + +// Sending helpers + +func externalSourceFrameSender( + ss *mjpeg.StreamSender, annotated bool, quality int, + fpsCounter *ratecounter.RateCounter, fpsPeriod float32, +) handling.Consumer[videostreams.Frame] { + return func(frame videostreams.Frame) (done bool, err error) { + if err = frame.Error(); err != nil { + if herr := handling.Except( + ss.Send(jpegError), context.Canceled, syscall.EPIPE, + ); herr != nil { + return false, errors.Wrap(err, "couldn't send mjpeg error frame") + } + return false, err + } + + // Generate output + // Note: without annotation the frame passes through directly, potentially without any + // JPEG decoding/encoding in the pipeline + if annotated { + fpsCounter.Incr(1) + f, err := frame.AsImageFrame() + if err != nil { + return false, errors.Wrap(err, "couldn't read frame as image") + } + f.Meta = f.Meta.WithSettings(videostreams.Settings{ + JPEGEncodeQuality: quality, + }) + metadata := videostreams.AnnotationMetadata{ + FPSCount: fpsCounter.Rate(), + FPSPeriod: fpsPeriod, + }.WithFrameData(f) + f = f.WithAnnotation(metadata.String(), 1) + frame = f + } + // TODO: implement image resizing + + // Send output + if err := handling.Except(ss.SendFrame(frame), context.Canceled, syscall.EPIPE); err != nil { + return false, errors.Wrap(err, "couldn't send mjpeg frame") + } + return false, nil + } +} // Handlers @@ -146,58 +187,16 @@ func (h *Handlers) HandleInstrumentCameraFrameGet() echo.HandlerFunc { frame = f // Produce output - jpeg, _, err := frame.AsJPEG() + jpeg, err := frame.AsJPEGFrame() if err != nil { return errors.Wrap(err, "couldn't jpeg-encode image") } - return c.Blob(http.StatusOK, "image/jpeg", jpeg) - } -} - -func externalSourceFrameSender( - ss *mjpeg.StreamSender, annotated bool, quality int, - fpsCounter *ratecounter.RateCounter, fpsPeriod float32, -) handling.Consumer[videostreams.Frame] { - return func(frame videostreams.Frame) (done bool, err error) { - if err = frame.Error(); err != nil { - if herr := handling.Except( - ss.SendFrame(frameError), context.Canceled, syscall.EPIPE, - ); herr != nil { - return false, errors.Wrap(err, "couldn't send mjpeg error frame") - } - return false, err - } - - // Generate output - // Note: without annotation the frame passes through directly, potentially without any - // JPEG decoding/encoding in the pipeline - if annotated { - fpsCounter.Incr(1) - f, err := frame.AsImageFrame() - if err != nil { - return false, errors.Wrap(err, "couldn't read frame as image") - } - f.Meta = f.Meta.WithSettings(videostreams.Settings{ - JPEGEncodeQuality: quality, - }) - metadata := videostreams.AnnotationMetadata{ - FPSCount: fpsCounter.Rate(), - FPSPeriod: fpsPeriod, - }.WithFrameData(f) - f = f.WithAnnotation(metadata.String(), 1) - frame = f - } - // TODO: implement image resizing - - // Send output - if err := handling.Except(ss.SendFrame(frame), context.Canceled, syscall.EPIPE); err != nil { - return false, errors.Wrap(err, "couldn't send mjpeg frame") - } - return false, nil + return c.Blob(http.StatusOK, "image/jpeg", jpeg.Im) } } func (h *Handlers) HandleInstrumentCameraStreamGet() echo.HandlerFunc { + jpegLoading := newErrorJPEG(errorWidth, errorHeight, "loading stream...") return func(c echo.Context) error { // Parse params id, err := parseID(c.Param("cameraID"), "camera") @@ -222,7 +221,7 @@ func (h *Handlers) HandleInstrumentCameraStreamGet() echo.HandlerFunc { } }() if err := handling.Except( - ss.SendFrame(frameLoading), context.Canceled, syscall.EPIPE, + ss.Send(jpegLoading), context.Canceled, syscall.EPIPE, ); err != nil { return errors.Wrap(err, "couldn't send mjpeg loading frame") } @@ -249,3 +248,52 @@ func (h *Handlers) HandleInstrumentCameraStreamGet() echo.HandlerFunc { return nil } } + +func (h *Handlers) HandleInstrumentCameraStreamPub() videostreams.HandlerFunc { + frameLoading := newErrorFrame(errorWidth, errorHeight, "loading stream...") + return func(c *videostreams.Context) error { + // Parse params + id, err := parseID(c.Param("cameraID"), "camera") + if err != nil { + return err + } + // TODO: implement a max framerate + + // Run queries + ctx := c.Context() + camera, err := h.is.GetCamera(ctx, id) + if err != nil { + return errors.Wrapf(err, "camera %d not found", id) + } + sourceURL := camera.URL + + // Set up output stream + c.Publish(frameLoading) + + // Subscribe to source stream + source := fmt.Sprintf( + "/video-streams/external-stream/source.mjpeg?url=%s", url.QueryEscape(sourceURL), + ) + frameBuffer := h.vsb.Subscribe(ctx, source) + + // Post-process and deliver stream + if err := handling.Except( + handling.Consume(ctx, frameBuffer, func(frame videostreams.Frame) (done bool, err error) { + // Since the source stream emits JPEG frames, we can safely assume that no further JPEG + // encoding is needed after we call c.Publish - but we check here anyways because it's + // cheap to check, and we can ensure that we only perform one JPEG encoding regardless of + // the number of Video Streams subscribers (i.e. the number of web browsers). + jpegFrame, err := frame.AsJPEGFrame() + if err != nil { + return false, errors.Wrap(err, "couldn't convert frame to JPEG for action cable") + } + c.Publish(jpegFrame) + return false, nil + }), + context.Canceled, + ); err != nil { + c.Logger().Error(errors.Wrapf(err, "failed to proxy stream %s", sourceURL)) + } + return nil + } +} diff --git a/internal/app/pslive/routes/instruments/routes.go b/internal/app/pslive/routes/instruments/routes.go index d3d8603..5e3a234 100644 --- a/internal/app/pslive/routes/instruments/routes.go +++ b/internal/app/pslive/routes/instruments/routes.go @@ -50,7 +50,7 @@ func New( } func (h *Handlers) Register( - er godest.EchoRouter, tsr turbostreams.Router, ss *session.Store, + er godest.EchoRouter, tsr turbostreams.Router, vsr videostreams.Router, ss *session.Store, ) { hr := auth.NewHTTPRouter(er, ss) hr.GET("/instruments", h.HandleInstrumentsGet()) @@ -69,6 +69,8 @@ func (h *Handlers) Register( hr.POST("/instruments/:id/cameras/:cameraID", h.HandleInstrumentCameraPost()) er.GET("/instruments/:id/cameras/:cameraID/frame.jpeg", h.HandleInstrumentCameraFrameGet()) er.GET("/instruments/:id/cameras/:cameraID/stream.mjpeg", h.HandleInstrumentCameraStreamGet()) + vsr.SUB("/instruments/:id/cameras/:cameraID/stream.mjpeg", videostreams.EmptyHandler) + vsr.PUB("/instruments/:id/cameras/:cameraID/stream.mjpeg", h.HandleInstrumentCameraStreamPub()) hr.POST("/instruments/:id/controllers", h.HandleInstrumentControllersPost()) hr.POST("/instruments/:id/controllers/:controllerID", h.HandleInstrumentControllerPost()) tsr.SUB("/instruments/:id/controllers/:controllerID/pump", turbostreams.EmptyHandler) diff --git a/internal/app/pslive/routes/routes.go b/internal/app/pslive/routes/routes.go index 4f15b91..03c003a 100644 --- a/internal/app/pslive/routes/routes.go +++ b/internal/app/pslive/routes/routes.go @@ -46,11 +46,11 @@ func (h *Handlers) Register( assets.RegisterStatic(er, em) assets.NewTemplated(h.r).Register(er) cable.New( - h.r, ss, h.globals.CSRFChecker, acc, h.globals.TSSigner, h.globals.TSBroker, l, + h.r, ss, h.globals.CSRFChecker, acc, h.globals.ACSigner, h.globals.TSBroker, vsb, l, ).Register(er) home.New(h.r, oc, is, ps).Register(er, ss) auth.New(h.r, ss, oc, acc, ps, l).Register(er) - instruments.New(h.r, oc, azc, tsh, is, h.globals.Planktoscopes, ps, cs, vsb).Register(er, tsr, ss) + instruments.New(h.r, oc, azc, tsh, is, h.globals.Planktoscopes, ps, cs, vsb).Register(er, tsr, vsr, ss) privatechat.New(h.r, oc, azc, tsh, ps, cs).Register(er, tsr, ss) users.New(h.r, oc, azc, tsh, is, ps, cs).Register(er, tsr, ss) videostreams.New(vsb).Register(er, vsr) diff --git a/internal/app/pslive/routes/videostreams/generated.go b/internal/app/pslive/routes/videostreams/generated.go index 2bc5a82..c40be67 100644 --- a/internal/app/pslive/routes/videostreams/generated.go +++ b/internal/app/pslive/routes/videostreams/generated.go @@ -151,11 +151,11 @@ func (h *Handlers) HandleAnimatedColorFrameGet() echo.HandlerFunc { f.Meta.Settings.JPEGEncodeQuality = quality // Produce output - frameJPEG, _, err := f.AsJPEG() + jpeg, err := f.AsJPEGFrame() if err != nil { return errors.Wrap(err, "couldn't jpeg-encode image") } - return c.Blob(http.StatusOK, "image/jpeg", frameJPEG) + return c.Blob(http.StatusOK, "image/jpeg", jpeg.Im) } } diff --git a/internal/app/pslive/routes/videostreams/proxied.go b/internal/app/pslive/routes/videostreams/proxied.go index f36996f..4483599 100644 --- a/internal/app/pslive/routes/videostreams/proxied.go +++ b/internal/app/pslive/routes/videostreams/proxied.go @@ -71,11 +71,11 @@ func (h *Handlers) HandleExternalSourceFrameGet() echo.HandlerFunc { frame = f // Produce output - jpeg, _, err := frame.AsJPEG() + jpeg, err := frame.AsJPEGFrame() if err != nil { return errors.Wrap(err, "couldn't jpeg-encode image") } - return c.Blob(http.StatusOK, "image/jpeg", jpeg) + return c.Blob(http.StatusOK, "image/jpeg", jpeg.Im) } } @@ -164,15 +164,15 @@ func (h *Handlers) HandleExternalSourceStreamGet() echo.HandlerFunc { func (h *Handlers) HandleExternalSourcePub() videostreams.HandlerFunc { return func(c *videostreams.Context) error { // Parse params from topic - query, err := c.Query() + query, err := c.QueryParams() if err != nil { err = errors.Wrap(err, "couldn't parse topic query params") - c.Publish(mjpeg.NewErrorFrame(err)) + c.Publish(videostreams.NewErrorFrame(err)) return err } source, err := parseURLParam(query.Get("url")) if err != nil { - c.Publish(mjpeg.NewErrorFrame(err)) + c.Publish(videostreams.NewErrorFrame(err)) return err } @@ -181,7 +181,7 @@ func (h *Handlers) HandleExternalSourcePub() videostreams.HandlerFunc { r, err := mjpeg.NewReceiverFromURL(ctx, h.hc, source) if err != nil { err = errors.Wrapf(err, "couldn't start mjpeg receiver for %s", source) - c.Publish(mjpeg.NewErrorFrame(err)) + c.Publish(videostreams.NewErrorFrame(err)) return err } defer r.Close() diff --git a/internal/app/pslive/routes/videostreams/random-color.go b/internal/app/pslive/routes/videostreams/random-color.go index bee3525..403b9ae 100644 --- a/internal/app/pslive/routes/videostreams/random-color.go +++ b/internal/app/pslive/routes/videostreams/random-color.go @@ -98,13 +98,13 @@ func (h *Handlers) HandleRandomColorFrameGet() echo.HandlerFunc { // Generate data frame := newCurrentFrame(newUniformImage(width, height, newRandomColor())) frame.Meta.Settings.JPEGEncodeQuality = quality - jpeg, _, err := frame.AsJPEG() + jpeg, err := frame.AsJPEGFrame() if err != nil { return errors.Wrap(err, "couldn't jpeg-encode image") } // Produce output - return c.Blob(http.StatusOK, "image/jpeg", jpeg) + return c.Blob(http.StatusOK, "image/jpeg", jpeg.Im) } } @@ -121,7 +121,7 @@ func (h *Handlers) HandleRandomColorStreamGet() echo.HandlerFunc { return errors.Wrap(err, "couldn't parse image quality query parameter") } - frames := make(chan mjpeg.JPEGEncodable) + frames := make(chan videostreams.Frame) // TODO: also make it dependent on the server's context! eg, egctx := errgroup.WithContext(c.Request().Context()) eg.Go(func() error { @@ -136,7 +136,7 @@ func (h *Handlers) HandleRandomColorStreamGet() echo.HandlerFunc { }) eg.Go(func() error { // Produce output - return mjpeg.SendStream(egctx, c.Response().Writer, frames) + return mjpeg.SendFrameStream(egctx, c.Response().Writer, frames) }) if err := handling.Except(eg.Wait(), context.Canceled, syscall.EPIPE); err != nil { return err diff --git a/internal/app/pslive/server.go b/internal/app/pslive/server.go index 0f341d6..9c12cc6 100644 --- a/internal/app/pslive/server.go +++ b/internal/app/pslive/server.go @@ -68,7 +68,7 @@ func NewServer(logger godest.Logger) (s *Server, err error) { if s.Renderer, err = godest.NewTemplateRenderer( s.Embeds, s.Inlines, sprig.FuncMap(), tmplfunc.FuncMap( tmplfunc.NewHashedNamers(assets.AppURLPrefix, assets.StaticURLPrefix, s.Embeds), - s.Globals.TSSigner.Sign, + s.Globals.ACSigner.Sign, ), ); err != nil { return nil, errors.Wrap(err, "couldn't make template renderer") @@ -282,6 +282,9 @@ func (s *Server) Run(e *echo.Echo) error { } func (s *Server) Shutdown(ctx context.Context, e *echo.Echo) (err error) { + // FIXME: e.Shutdown calls e.Server.Shutdown, which doesn't wait for WebSocket connections. When + // starting Echo, we need to call e.Server.RegisterOnShutdown with a function to gracefully close + // WebSocket connections! if errEcho := e.Shutdown(ctx); errEcho != nil { s.Globals.Logger.Error(errors.Wrap(errEcho, "couldn't shut down http server")) err = errEcho diff --git a/internal/app/pslive/tmplfunc/funcs.go b/internal/app/pslive/tmplfunc/funcs.go index 724772f..1471182 100644 --- a/internal/app/pslive/tmplfunc/funcs.go +++ b/internal/app/pslive/tmplfunc/funcs.go @@ -18,5 +18,6 @@ func FuncMap(h HashedNamers, tss TurboStreamSigner) template.FuncMap { "appHashed": h.AppHashed, "staticHashed": h.StaticHashed, "signTurboStream": tss, + "signVideoStream": tss, } } diff --git a/internal/clients/mjpeg/http-receiver.go b/internal/clients/mjpeg/http-receiver.go index 5687904..9ea504b 100644 --- a/internal/clients/mjpeg/http-receiver.go +++ b/internal/clients/mjpeg/http-receiver.go @@ -1,11 +1,9 @@ -// Package mjpeg provides receiving and sending of MJPEG streams over HTTP +// Package mjpeg provides functionality for receiving and sending MJPEG streams over HTTP package mjpeg import ( "bytes" "context" - "image" - "image/jpeg" "io" "mime" "mime/multipart" @@ -18,52 +16,6 @@ import ( "github.com/sargassum-world/pslive/internal/clients/videostreams" ) -// JPEG Frame - -type JPEGFrame struct { - jpeg []byte - metadata *videostreams.Metadata - err error -} - -func NewErrorFrame(err error) *JPEGFrame { - return &JPEGFrame{ - err: err, - } -} - -func (f *JPEGFrame) AsImage() (image.Image, videostreams.Operation, error) { - im, err := jpeg.Decode(bytes.NewReader(f.jpeg)) - if err != nil { - return nil, videostreams.Nop, err - } - return im, "decode JPEG", nil -} - -func (f *JPEGFrame) AsImageFrame() (*videostreams.ImageFrame, error) { - im, op, err := f.AsImage() - if err != nil { - return nil, err - } - return &videostreams.ImageFrame{ - Im: im, - Meta: f.Metadata().WithOp(op), - Err: f.err, - }, nil -} - -func (f *JPEGFrame) AsJPEG() ([]byte, videostreams.Operation, error) { - return f.jpeg, videostreams.Nop, f.err -} - -func (f *JPEGFrame) Metadata() *videostreams.Metadata { - return f.metadata -} - -func (f *JPEGFrame) Error() error { - return f.err -} - // Receiver type Receiver struct { @@ -85,7 +37,7 @@ func NewReceiverFromResponse(res *http.Response) (*Receiver, error) { if !strings.HasPrefix(contentType, "multipart/") { return nil, errors.Errorf("unexpected stream content type %s", contentType) } - receiver := NewReceiver(res.Body, param["boundary"]) + receiver := NewReceiver(res.Body, strings.TrimPrefix(param["boundary"], "--")) receiver.closer = res.Body.Close return receiver, nil } @@ -118,7 +70,7 @@ func (r *Receiver) Close() { } } -func (r *Receiver) Receive() (frame *JPEGFrame, err error) { +func (r *Receiver) Receive() (frame *videostreams.JPEGFrame, err error) { part, err := r.reader.NextPart() if err == io.EOF { return nil, err @@ -135,9 +87,9 @@ func (r *Receiver) Receive() (frame *JPEGFrame, err error) { if _, err = io.Copy(buffer, part); err != nil { return nil, errors.Wrap(err, "couldn't jpeg-decode stream part") } - frame = &JPEGFrame{ - jpeg: buffer.Bytes(), - metadata: &videostreams.Metadata{ + frame = &videostreams.JPEGFrame{ + Im: buffer.Bytes(), + Meta: &videostreams.Metadata{ FromSource: make(map[string][]string), ReceiveTime: time.Now(), Operations: &videostreams.OpChain{ @@ -151,7 +103,7 @@ func (r *Receiver) Receive() (frame *JPEGFrame, err error) { if key == "Content-Type" { continue } - frame.metadata.FromSource[key] = values + frame.Meta.FromSource[key] = values } return frame, err } diff --git a/internal/clients/mjpeg/http-sender.go b/internal/clients/mjpeg/http-sender.go index 5e15546..aba3905 100644 --- a/internal/clients/mjpeg/http-sender.go +++ b/internal/clients/mjpeg/http-sender.go @@ -13,12 +13,6 @@ import ( "github.com/sargassum-world/pslive/internal/clients/videostreams" ) -// JPEGEncodable - -type JPEGEncodable interface { - AsJPEG() ([]byte, videostreams.Operation, error) -} - // Sender type StreamSender struct { @@ -35,19 +29,23 @@ func StartStream(w http.ResponseWriter) *StreamSender { } } -func (ss *StreamSender) SendFrame(frame JPEGEncodable) error { - data, _, err := frame.AsJPEG() +func (ss *StreamSender) SendFrame(frame videostreams.Frame) error { + jpeg, err := frame.AsJPEGFrame() if err != nil { return errors.Wrap(err, "couldn't jpeg-encode frame") } + return ss.Send(jpeg.Im) +} + +func (ss *StreamSender) Send(frame []byte) error { h := textproto.MIMEHeader{} h.Set("Content-Type", "image/jpeg") - h.Set("Content-Length", strconv.Itoa(len(data))) + h.Set("Content-Length", strconv.Itoa(len(frame))) pw, err := ss.mw.CreatePart(h) if err != nil { return err } - if _, err := pw.Write(data); err != nil { + if _, err := pw.Write(frame); err != nil { return err } if f, ok := ss.w.(http.Flusher); ok { @@ -60,8 +58,8 @@ func (ss *StreamSender) Close() error { return ss.mw.Close() } -func SendStream( - ctx context.Context, w http.ResponseWriter, frames <-chan JPEGEncodable, +func SendFrameStream( + ctx context.Context, w http.ResponseWriter, frames <-chan videostreams.Frame, ) (err error) { ss := StartStream(w) defer func() { @@ -71,7 +69,23 @@ func SendStream( } }() - return handling.Consume(ctx, frames, func(frame JPEGEncodable) (bool, error) { + return handling.Consume(ctx, frames, func(frame videostreams.Frame) (bool, error) { return false, ss.SendFrame(frame) }) } + +func SendStream( + ctx context.Context, w http.ResponseWriter, frames <-chan []byte, +) (err error) { + ss := StartStream(w) + defer func() { + cerr := ss.mw.Close() + if err == nil && cerr != nil { + err = cerr + } + }() + + return handling.Consume(ctx, frames, func(frame []byte) (bool, error) { + return false, ss.Send(frame) + }) +} diff --git a/internal/clients/videostreams/actioncable-channel.go b/internal/clients/videostreams/actioncable-channel.go new file mode 100644 index 0000000..425a8a8 --- /dev/null +++ b/internal/clients/videostreams/actioncable-channel.go @@ -0,0 +1,109 @@ +package videostreams + +import ( + "context" + "encoding/json" + + "github.com/pkg/errors" + "github.com/sargassum-world/godest/actioncable" + "github.com/sargassum-world/godest/handling" + "github.com/sargassum-world/godest/pubsub" +) + +// ChannelName is the name of the Action Cable channel for Video Streams. +const ChannelName = "Video::StreamsChannel" + +// subscriber creates a subscription for the channel, to integrate [Channel] with [Broker]. +type subscriber func(ctx context.Context, topic string) <-chan Frame + +// Channel represents an Action Cable channel for a Video Streams stream. +type Channel struct { + identifier string + streamName string + h *pubsub.Hub[[]Frame] + subscriber subscriber + sessionID string + logger pubsub.Logger +} + +// parseStreamName parses the Video Streams stream name from the Action Cable subscription +// identifier. +func parseStreamName(identifier string) (string, error) { + var i struct { + Name string `json:"name"` + } + if err := json.Unmarshal([]byte(identifier), &i); err != nil { + return "", errors.Wrap( + err, "couldn't parse stream name from action cable subscription identifier", + ) + } + return i.Name, nil +} + +// NewChannel checks the identifier with the specified checkers and returns a new Channel instance. +func NewChannel( + identifier string, h *pubsub.Hub[[]Frame], subscriber subscriber, sessionID string, + checkers []actioncable.IdentifierChecker, logger pubsub.Logger, +) (*Channel, error) { + name, err := parseStreamName(identifier) + if err != nil { + return nil, err + } + for _, checker := range checkers { + if err := checker(identifier); err != nil { + return nil, errors.Wrap(err, "action cable subscription identifier failed checks") + } + } + return &Channel{ + identifier: identifier, + streamName: name, + h: h, + subscriber: subscriber, + sessionID: sessionID, + logger: logger, + }, nil +} + +// Subscribe handles an Action Cable subscribe command from the client with the provided +// [actioncable.Subscription]. +func (c *Channel) Subscribe(ctx context.Context, sub *actioncable.Subscription) error { + if sub.Identifier() != c.identifier { + return errors.Errorf( + "channel identifier %+v does not match subscription identifier %+v", + c.identifier, sub.Identifier(), + ) + } + + frames := c.subscriber(ctx, c.streamName) + go func() { + for frame := range frames { + encoded, err := frame.AsJPEGFrame() + if err != nil { + c.logger.Error(errors.Wrap(err, "couldn't jpeg-encode frame to send over action cable")) + break + } + // TODO: attach metadata to the frame data (may need struct tags for marshaling) + if err := handling.Except(sub.SendBytes(ctx, encoded.Im), context.Canceled); err != nil { + c.logger.Error(errors.Wrap(err, "couldn't send turbo streams messages over action cable")) + break + } + } + sub.Close() + }() + return nil +} + +// Perform handles an Action Cable action command from the client. +func (c *Channel) Perform(data string) error { + return errors.New("video streams channel cannot perform any actions") +} + +// NewChannelFactory creates an [actioncable.ChannelFactory] for Turbo Streams to create channels +// for different Video Streams streams as needed. +func NewChannelFactory( + b *Broker, sessionID string, logger pubsub.Logger, checkers ...actioncable.IdentifierChecker, +) actioncable.ChannelFactory { + return func(identifier string) (actioncable.Channel, error) { + return NewChannel(identifier, b.Hub(), b.Subscribe, sessionID, checkers, logger) + } +} diff --git a/internal/clients/videostreams/pubsub.go b/internal/clients/videostreams/pubsub.go index 8d62811..25a7e5a 100644 --- a/internal/clients/videostreams/pubsub.go +++ b/internal/clients/videostreams/pubsub.go @@ -51,6 +51,10 @@ func NewBroker(logger pubsub.Logger) *Broker { } } +func (b *Broker) Hub() *Hub { + return b.broker.Hub() +} + func (b *Broker) PUB(topic string, h HandlerFunc, m ...MiddlewareFunc) *Route { return b.broker.Add(pubsub.MethodPub, topic, h, m...) } @@ -67,11 +71,11 @@ func (b *Broker) Use(middleware ...MiddlewareFunc) { b.broker.Use(middleware...) } -type BroadcastReceiver func(ctx context.Context, frames []Frame) (ok bool) +type BroadcastReceiver func(ctx context.Context, frames []Frame) error func (b *Broker) subscribe( ctx context.Context, topic string, broadcastHandler BroadcastReceiver, -) (unsubscriber func(), finished <-chan struct{}) { +) (finished <-chan struct{}) { // we keep this private because we're handling frames and we don't want a slow consumer to block // every other consumer; the public Subscribe method drops frames for busy consumers return b.broker.Subscribe( @@ -87,8 +91,8 @@ func (b *Broker) subscribe( func (b *Broker) Subscribe(ctx context.Context, topic string) <-chan Frame { buffer := make(chan Frame, 1) wg := sync.WaitGroup{} - unsubscribe, finished := b.subscribe( - ctx, topic, func(ctx context.Context, frames []Frame) (ok bool) { + finished := b.subscribe( + ctx, topic, func(ctx context.Context, frames []Frame) error { wg.Add(1) select { case buffer <- frames[len(frames)-1]: @@ -97,15 +101,11 @@ func (b *Broker) Subscribe(ctx context.Context, topic string) <-chan Frame { // TODO: update a frames-dropped-per-sec counter } wg.Done() - return true + return nil }, ) go func() { - select { - case <-ctx.Done(): - case <-finished: - } - unsubscribe() + <-finished wg.Wait() // prevent closing channel with pending sends, which is a data race close(buffer) }() diff --git a/internal/clients/videostreams/stream.go b/internal/clients/videostreams/stream.go index 20e143e..f5484d3 100644 --- a/internal/clients/videostreams/stream.go +++ b/internal/clients/videostreams/stream.go @@ -49,7 +49,7 @@ func (m *Metadata) WithSettings(settings Settings) *Metadata { type Frame interface { AsImageFrame() (*ImageFrame, error) - AsJPEG() ([]byte, Operation, error) + AsJPEGFrame() (*JPEGFrame, error) Error() error } @@ -71,22 +71,25 @@ func (f *ImageFrame) AsImageFrame() (*ImageFrame, error) { return f, errors.Wrap(f.Err, "stream error") } -func (f *ImageFrame) AsJPEG() ([]byte, Operation, error) { +func (f *ImageFrame) AsJPEGFrame() (*JPEGFrame, error) { if f.Meta == nil { - return nil, Nop, errors.Errorf("unspecified jpeg quality due to missing metadata") + return nil, errors.Errorf("unspecified jpeg quality due to missing metadata") } quality := f.Meta.Settings.JPEGEncodeQuality if quality < 1 || quality > 100 { - return nil, Nop, errors.Errorf("invalid jpeg quality %d", quality) + return nil, errors.Errorf("invalid jpeg quality %d", quality) } buf := new(bytes.Buffer) if err := jpeg.Encode(buf, f.Im, &jpeg.Options{ Quality: quality, }); err != nil { - return nil, Nop, errors.Wrap(err, "couldn't jpeg-encode image") + return nil, errors.Wrap(err, "couldn't jpeg-encode image") } - return buf.Bytes(), Operationf("encode JPEG with quality %d", quality), nil + return &JPEGFrame{ + Im: buf.Bytes(), + Meta: f.Meta.WithOp(Operationf("encode as JPEG with quality %d", quality)), + }, nil } func (f *ImageFrame) Error() error { @@ -108,3 +111,31 @@ func (f *ImageFrame) WithAnnotation(annotations string, lines int) *ImageFrame { Meta: f.Meta.WithOp(Operationf("annotate")), } } + +// JPEG Frame + +type JPEGFrame struct { + Im []byte + Meta *Metadata + Err error +} + +func (f *JPEGFrame) AsImageFrame() (*ImageFrame, error) { + im, err := jpeg.Decode(bytes.NewReader(f.Im)) + if err != nil { + return nil, err + } + return &ImageFrame{ + Im: im, + Meta: f.Meta.WithOp("decode JPEG"), + Err: f.Err, + }, nil +} + +func (f *JPEGFrame) AsJPEGFrame() (*JPEGFrame, error) { + return f, f.Err +} + +func (f *JPEGFrame) Error() error { + return f.Err +} diff --git a/tools/go.mod b/tools/go.mod index fceda4d..80a8afa 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -3,30 +3,31 @@ module github.com/sargassum-world/pslive/build go 1.19 require ( - github.com/deepmap/oapi-codegen v1.12.2 + github.com/deepmap/oapi-codegen v1.12.3 github.com/golangci/golangci-lint v1.50.1 - github.com/goreleaser/goreleaser v1.12.3 + github.com/goreleaser/goreleaser v1.13.0 github.com/hairyhenderson/gomplate/v3 v3.11.3 - github.com/open-policy-agent/opa v0.45.0 + github.com/open-policy-agent/opa v0.46.1 mvdan.cc/gofumpt v0.4.0 ) require ( 4d63.com/gochecknoglobals v0.1.0 // indirect - cloud.google.com/go v0.104.0 // indirect - cloud.google.com/go/compute v1.11.0 // indirect - cloud.google.com/go/iam v0.6.0 // indirect - cloud.google.com/go/kms v1.5.0 // indirect - cloud.google.com/go/storage v1.27.0 // indirect + cloud.google.com/go v0.107.0 // indirect + cloud.google.com/go/compute v1.12.1 // indirect + cloud.google.com/go/compute/metadata v0.2.1 // indirect + cloud.google.com/go/iam v0.7.0 // indirect + cloud.google.com/go/kms v1.6.0 // indirect + cloud.google.com/go/storage v1.28.0 // indirect code.gitea.io/sdk/gitea v0.15.1 // indirect github.com/Abirdcfly/dupword v0.0.7 // indirect github.com/AlekSi/pointer v1.2.0 // indirect github.com/Antonboom/errname v0.1.7 // indirect github.com/Antonboom/nilnil v0.1.1 // indirect - github.com/Azure/azure-sdk-for-go v67.0.0+incompatible // indirect - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.4 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.1 // indirect + github.com/Azure/azure-sdk-for-go v67.1.0+incompatible // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.2.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.2.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.4.1 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect @@ -50,7 +51,7 @@ require ( github.com/Microsoft/go-winio v0.6.0 // indirect github.com/OneOfOne/xxhash v1.2.8 // indirect github.com/OpenPeeDeeP/depguard v1.1.1 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad // indirect + github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 // indirect github.com/Shopify/ejson v1.3.3 // indirect github.com/acomagu/bufpipe v1.0.3 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect @@ -62,13 +63,13 @@ require ( github.com/ashanbrown/forbidigo v1.3.0 // indirect github.com/ashanbrown/makezero v1.1.1 // indirect github.com/atc0005/go-teams-notify/v2 v2.6.1 // indirect - github.com/aws/aws-sdk-go v1.44.123 // indirect + github.com/aws/aws-sdk-go v1.44.146 // indirect github.com/aws/aws-sdk-go-v2 v1.17.1 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.9 // indirect - github.com/aws/aws-sdk-go-v2/config v1.17.10 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.12.23 // indirect + github.com/aws/aws-sdk-go-v2/config v1.18.3 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.13.3 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.19 // indirect - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.37 // indirect + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.42 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.25 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.19 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.3.26 // indirect @@ -77,11 +78,11 @@ require ( github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.20 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.19 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.19 // indirect - github.com/aws/aws-sdk-go-v2/service/kms v1.18.15 // indirect - github.com/aws/aws-sdk-go-v2/service/s3 v1.29.1 // indirect + github.com/aws/aws-sdk-go-v2/service/kms v1.18.18 // indirect + github.com/aws/aws-sdk-go-v2/service/s3 v1.29.4 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.11.25 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.8 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.17.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.17.5 // indirect github.com/aws/smithy-go v1.13.4 // indirect github.com/aymanbagabas/go-osc52 v1.2.1 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -100,31 +101,32 @@ require ( github.com/caarlos0/log v0.1.10 // indirect github.com/cavaliergopher/cpio v1.0.1 // indirect github.com/cenkalti/backoff/v3 v3.2.2 // indirect - github.com/cenkalti/backoff/v4 v4.1.3 // indirect + github.com/cenkalti/backoff/v4 v4.2.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/charithe/durationcheck v0.0.9 // indirect github.com/charmbracelet/lipgloss v0.6.1-0.20220911181249-6304a734e792 // indirect github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 // indirect - github.com/cloudflare/circl v1.2.0 // indirect - github.com/containerd/containerd v1.6.8 // indirect + github.com/cloudflare/circl v1.3.0 // indirect + github.com/containerd/containerd v1.6.10 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/curioswitch/go-reassign v0.2.0 // indirect github.com/daixiang0/gci v0.8.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/denis-tingaikin/go-header v0.4.3 // indirect - github.com/dghubble/go-twitter v0.0.0-20221024160433-0cc1e72ed6d8 // indirect + github.com/dghubble/go-twitter v0.0.0-20221104224141-912508c3888b // indirect github.com/dghubble/oauth1 v0.7.1 // indirect github.com/dghubble/sling v1.4.0 // indirect - github.com/dgraph-io/badger/v3 v3.2103.3 // indirect + github.com/dgraph-io/badger/v3 v3.2103.4 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dimchansky/utfbom v1.1.1 // indirect - github.com/disgoorg/disgo v0.13.20 // indirect + github.com/disgoorg/disgo v0.13.22 // indirect + github.com/disgoorg/json v1.0.0 // indirect github.com/disgoorg/log v1.2.0 // indirect github.com/disgoorg/snowflake/v2 v2.0.1 // indirect - github.com/docker/cli v20.10.20+incompatible // indirect + github.com/docker/cli v20.10.21+incompatible // indirect github.com/docker/distribution v2.8.1+incompatible // indirect - github.com/docker/docker v20.10.20+incompatible // indirect + github.com/docker/docker v20.10.21+incompatible // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-metrics v0.0.1 // indirect @@ -178,18 +180,18 @@ require ( github.com/golangci/misspell v0.3.5 // indirect github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 // indirect github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect - github.com/google/flatbuffers v22.9.29+incompatible // indirect + github.com/google/flatbuffers v22.11.23+incompatible // indirect github.com/google/go-cmp v0.5.9 // indirect - github.com/google/go-github/v48 v48.0.0 // indirect + github.com/google/go-github/v48 v48.1.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/uuid v1.3.0 // indirect github.com/google/wire v0.5.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect - github.com/googleapis/gax-go/v2 v2.6.0 // indirect + github.com/googleapis/gax-go/v2 v2.7.0 // indirect github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect github.com/goreleaser/chglog v0.2.2 // indirect github.com/goreleaser/fileglob v1.3.0 // indirect - github.com/goreleaser/nfpm/v2 v2.20.0 // indirect + github.com/goreleaser/nfpm/v2 v2.22.1 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/gosimple/slug v1.12.0 // indirect @@ -198,7 +200,7 @@ require ( github.com/gostaticanalysis/comment v1.4.2 // indirect github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect github.com/gostaticanalysis/nilerr v0.1.1 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.14.0 // indirect github.com/hairyhenderson/go-fsimpl v0.0.0-20220919132154-dc606beb8e19 // indirect github.com/hairyhenderson/toml v0.4.2-0.20210923231440-40456b8e66cf // indirect github.com/hairyhenderson/yaml v0.0.0-20220618171115-2d35fca545ce // indirect @@ -224,11 +226,11 @@ require ( github.com/hashicorp/vault/sdk v0.6.0 // indirect github.com/hashicorp/yamux v0.1.1 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect - github.com/huandu/xstrings v1.3.2 // indirect + github.com/huandu/xstrings v1.3.3 // indirect github.com/iancoleman/orderedmap v0.2.0 // indirect github.com/imdario/mergo v0.3.13 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect - github.com/invopop/jsonschema v0.6.0 // indirect + github.com/invopop/jsonschema v0.7.0 // indirect github.com/invopop/yaml v0.1.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jgautheron/goconst v1.5.1 // indirect @@ -242,7 +244,7 @@ require ( github.com/kisielk/errcheck v1.6.2 // indirect github.com/kisielk/gotool v1.0.0 // indirect github.com/kkHAIKE/contextcheck v1.1.3 // indirect - github.com/klauspost/compress v1.15.11 // indirect + github.com/klauspost/compress v1.15.12 // indirect github.com/klauspost/pgzip v1.2.5 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.6 // indirect @@ -262,8 +264,9 @@ require ( github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-mastodon v0.0.6 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect github.com/mgechev/revive v1.2.4 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect @@ -272,7 +275,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/moby/locker v1.0.1 // indirect - github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect + github.com/moby/term v0.0.0-20221128092401-c43b287e0e0f // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/moricho/tparallel v0.2.1 // indirect github.com/morikuni/aec v1.0.0 // indirect @@ -299,7 +302,7 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polyfloyd/go-errorlint v1.0.5 // indirect - github.com/prometheus/client_golang v1.13.0 // indirect + github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect @@ -308,7 +311,7 @@ require ( github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect - github.com/rivo/uniseg v0.4.2 // indirect + github.com/rivo/uniseg v0.4.3 // indirect github.com/rs/zerolog v1.28.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryancurrah/gomodguard v1.2.4 // indirect @@ -325,7 +328,7 @@ require ( github.com/sivchari/containedctx v1.0.2 // indirect github.com/sivchari/nosnakecase v1.7.0 // indirect github.com/sivchari/tenv v1.7.0 // indirect - github.com/slack-go/slack v0.11.3 // indirect + github.com/slack-go/slack v0.11.4 // indirect github.com/sonatard/noctx v0.0.1 // indirect github.com/sourcegraph/go-diff v0.6.1 // indirect github.com/spf13/afero v1.9.2 // indirect @@ -347,6 +350,7 @@ require ( github.com/timonwong/loggercheck v0.9.3 // indirect github.com/tomarrell/wrapcheck/v2 v2.7.0 // indirect github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect + github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 // indirect github.com/ugorji/go/codec v1.2.7 // indirect github.com/ulikunitz/xz v0.5.10 // indirect github.com/ultraware/funlen v0.0.3 // indirect @@ -355,8 +359,8 @@ require ( github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect github.com/withfig/autocomplete-tools/integrations/cobra v1.2.1 // indirect - github.com/xanzy/go-gitlab v0.73.1 // indirect - github.com/xanzy/ssh-agent v0.3.2 // indirect + github.com/xanzy/go-gitlab v0.76.0 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/yagipy/maintidx v1.0.0 // indirect @@ -366,8 +370,8 @@ require ( gitlab.com/bosi/decorder v0.2.3 // indirect gitlab.com/digitalxero/go-conventional-commit v1.0.7 // indirect go.etcd.io/bbolt v1.3.6 // indirect - go.opencensus.io v0.23.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.36.3 // indirect + go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.36.4 // indirect go.opentelemetry.io/otel v1.11.1 // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.1 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.1 // indirect @@ -383,23 +387,23 @@ require ( go4.org/intern v0.0.0-20220617035311-6925f38cc365 // indirect go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760 // indirect gocloud.dev v0.27.0 // indirect - golang.org/x/crypto v0.1.0 // indirect + golang.org/x/crypto v0.3.0 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 // indirect - golang.org/x/mod v0.6.0 // indirect - golang.org/x/net v0.1.0 // indirect - golang.org/x/oauth2 v0.1.0 // indirect + golang.org/x/mod v0.7.0 // indirect + golang.org/x/net v0.2.0 // indirect + golang.org/x/oauth2 v0.2.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.1.0 // indirect - golang.org/x/term v0.1.0 // indirect + golang.org/x/sys v0.2.0 // indirect + golang.org/x/term v0.2.0 // indirect golang.org/x/text v0.4.0 // indirect - golang.org/x/time v0.1.0 // indirect - golang.org/x/tools v0.2.0 // indirect + golang.org/x/time v0.2.0 // indirect + golang.org/x/tools v0.3.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/api v0.101.0 // indirect + google.golang.org/api v0.103.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71 // indirect - google.golang.org/grpc v1.50.1 // indirect + google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6 // indirect + google.golang.org/grpc v1.51.0 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/tools/go.sum b/tools/go.sum index 5ae50d9..5b1a2f2 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -38,8 +38,8 @@ cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w9 cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= cloud.google.com/go v0.103.0/go.mod h1:vwLx1nqLrzLX/fpwSMOXmFIqBOyHsvHbnAdbGSJ+mKk= -cloud.google.com/go v0.104.0 h1:gSmWO7DY1vOm0MVU6DNXM11BWHHsTUmsC5cv1fuW5X8= -cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= +cloud.google.com/go v0.107.0 h1:qkj22L7bgkl6vIeZDlOY2po43Mx/TIa2Wsa7VR+PEww= +cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -52,19 +52,22 @@ cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6m cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= -cloud.google.com/go/compute v1.11.0 h1:0Xy75Dbf7s/nRAfAXwmunQ/ZFzfxd+bq/Z/WykCFa/M= -cloud.google.com/go/compute v1.11.0/go.mod h1:nTnVHEoJMqp3oVjDINEiIcg/4nbiCcX77sSObqhsUyg= +cloud.google.com/go/compute v1.12.1 h1:gKVJMEyqV5c/UnpzjjQbo3Rjvvqpr9B1DFSbJC4OXr0= +cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute/metadata v0.2.1 h1:efOwf5ymceDhK6PKMnnrTHP4pppY5L22mle96M1yP48= +cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= -cloud.google.com/go/iam v0.6.0 h1:nsqQC88kT5Iwlm4MeNGTpfMWddp6NB/UOLFTH6m1QfQ= -cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= +cloud.google.com/go/iam v0.7.0 h1:k4MuwOsS7zGJJ+QfZ5vBK8SgHBAvYN/23BWsiihJ1vs= +cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= -cloud.google.com/go/kms v1.5.0 h1:uc58n3b/n/F2yDMJzHMbXORkJSh3fzO4/+jju6eR7Zg= -cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg= +cloud.google.com/go/kms v1.6.0 h1:OWRZzrPmOZUzurjI2FBGtgY2mB1WaJkqhw6oIwSj0Yg= +cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0= +cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= cloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4= cloud.google.com/go/monitoring v1.5.0/go.mod h1:/o9y8NYX5j91JjD/JvGLYbi86kL11OjyJXq2XziLJu4= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= @@ -82,8 +85,8 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= cloud.google.com/go/storage v1.24.0/go.mod h1:3xrJEFMXBsQLgxwThyjuD3aYlroL0TMRec1ypGUQ0KE= -cloud.google.com/go/storage v1.27.0 h1:YOO045NZI9RKfCj1c5A/ZtuuENUc8OAW+gHdGnDgyMQ= -cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cloud.google.com/go/storage v1.28.0 h1:DLrIZ6xkeZX6K70fU/boWx5INJumt6f+nwwWSHXzzGY= +cloud.google.com/go/storage v1.28.0/go.mod h1:qlgZML35PXA3zoEnIkiPLY4/TOkUleufRlu6qmcf7sI= cloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A= cloud.google.com/go/trace v1.2.0/go.mod h1:Wc8y/uYyOhPy12KEnXG9XGrvfMz5F5SrYecQlbW1rwM= code.cloudfoundry.org/clock v0.0.0-20180518195852-02e53af36e6c/go.mod h1:QD9Lzhd/ux6eNQVUDVRJX/RKTigpewimNYBi7ivZKY8= @@ -108,21 +111,21 @@ github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9mo github.com/Azure/azure-sdk-for-go v63.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v65.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v66.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v67.0.0+incompatible h1:SVBwznSETB0Sipd0uyGJr7khLhJOFRUEUb+0JgkCvDo= -github.com/Azure/azure-sdk-for-go v67.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v67.1.0+incompatible h1:oziYcaopbnIKfM69DL05wXdypiqfrUKdxUKrKpynJTw= +github.com/Azure/azure-sdk-for-go v67.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.0.0/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.1/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.4 h1:pqrAR74b6EoR4kcxF7L7Wg2B8Jgil9UUZtMvxhEFqWo= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.4/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.2.0 h1:sVW/AFBTGyJxDaMYlq0ct3jUXTtj12tQ6zE2GZUgVQw= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.2.0/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.0.0/go.mod h1:+6sju8gk8FRmSajX3Oz4G5Gm7P+mbqE9FVaXXFYTkCM= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0 h1:QkAcEIAKbNL4KoFr4SathZPhDhF4mVwpBMFlYjyAqy8= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0/go.mod h1:bhXu1AjYL+wutSL/kpSq6s7733q2Rb0yuot9Zgfqa/0= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.2.0 h1:t/W5MYAuQy81cvM8VUNfRLzhtKpXhVUAN7Cd7KVbTyc= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.2.0/go.mod h1:NBanQUfSWiWn3QEpWDTCU0IjBECKOYvl2R8xdRtMtiM= github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8= github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.1 h1:XUNQ4mw+zJmaA2KXzP9JlQiecy1SI+Eog7xVkPiqIbg= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.1/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.1 h1:Oj853U9kG+RLTCQXpjvOnrv0WaZHxgmZz1TlLywgOPY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.1/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus v1.0.2/go.mod h1:LH9XQnMr2ZYxQdVdCrzLO9mxeDyrDFa6wbSI3x5zCZk= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.4.1 h1:QSdcrd/UFJv6Bp/CfoVf2SrENpFn9P6Yh8yb+xNhYMM= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.4.1/go.mod h1:eZ4g6GUvXiGulfIbbhh1Xr4XwUYaYaWMqzGD/284wCA= @@ -215,7 +218,7 @@ github.com/Microsoft/hcsshim v0.8.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwT github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg= github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= -github.com/Microsoft/hcsshim v0.9.4 h1:mnUj0ivWy6UzbB1uLFqKR6F+ZyiDc7j4iGgHTpO+5+I= +github.com/Microsoft/hcsshim v0.9.5 h1:AbV+VPfTrIVffukazHcpxmz/sRiE6YaMDzHWR9BXZHo= github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -226,8 +229,8 @@ github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdII github.com/OpenPeeDeeP/depguard v1.1.1 h1:TSUznLjvp/4IUP+OQ0t/4jF4QUyxIcVX8YnghZdunyA= github.com/OpenPeeDeeP/depguard v1.1.1/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= -github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad h1:QeeqI2zxxgZVe11UrYFXXx6gVxPVF40ygekjBzEg4XY= -github.com/ProtonMail/go-crypto v0.0.0-20220930113650-c6815a8c17ad/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= +github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 h1:ra2OtmuW0AE5csawV4YXMNGNQQXvLRps3z2Z59OPO+I= +github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4/go.mod h1:UBYPn8k0D56RtnR8RFQMjmh4KrZzWJ5o7Z9SYjossQ8= github.com/ProtonMail/go-mime v0.0.0-20220302105931-303f85f7fe0f h1:CGq7OieOz3wyQJ1fO8S0eO9TCW1JyvLrf8fhzz1i8ko= github.com/ProtonMail/gopenpgp/v2 v2.2.2 h1:u2m7xt+CZWj88qK1UUNBoXeJCFJwJCZ/Ff4ymGoxEXs= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -299,8 +302,8 @@ github.com/aws/aws-sdk-go v1.43.11/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4 github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.45/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.68/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go v1.44.123 h1:+vVGJ7+vQU6/wRcgRwSBBrIuG/lLL/0LB3HlN5jFv3c= -github.com/aws/aws-sdk-go v1.44.123/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.146 h1:7YdGgPxDPRJu/yYffzZp/H7yHzQ6AqmuNFZPYraaN8I= +github.com/aws/aws-sdk-go v1.44.146/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aws/aws-sdk-go-v2 v1.16.8/go.mod h1:6CpKuLXg2w7If3ABZCl/qZ6rEgwtjZTn4eAf4RcEyuw= github.com/aws/aws-sdk-go-v2 v1.17.1 h1:02c72fDJr87N8RAC2s3Qu0YuvMRZKNZJ9F+lAehCazk= @@ -309,17 +312,17 @@ github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3/go.mod h1:gNsR5CaXK github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.9 h1:RKci2D7tMwpvGpDNZnGQw9wk6v7o/xSwFcUAuNPoB8k= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.9/go.mod h1:vCmV1q1VK8eoQJ5+aYE7PkK1K6v41qJ5pJdK3ggCDvg= github.com/aws/aws-sdk-go-v2/config v1.15.15/go.mod h1:A1Lzyy/o21I5/s2FbyX5AevQfSVXpvvIDCoVFD0BC4E= -github.com/aws/aws-sdk-go-v2/config v1.17.10 h1:zBy5QQ/mkvHElM1rygHPAzuH+sl8nsdSaxSWj0+rpdE= -github.com/aws/aws-sdk-go-v2/config v1.17.10/go.mod h1:/4np+UiJJKpWHN7Q+LZvqXYgyjgeXm5+lLfDI6TPZao= +github.com/aws/aws-sdk-go-v2/config v1.18.3 h1:3kfBKcX3votFX84dm00U8RGA1sCCh3eRMOGzg5dCWfU= +github.com/aws/aws-sdk-go-v2/config v1.18.3/go.mod h1:BYdrbeCse3ZnOD5+2/VE/nATOK8fEUpBtmPMdKSyhMU= github.com/aws/aws-sdk-go-v2/credentials v1.12.10/go.mod h1:g5eIM5XRs/OzIIK81QMBl+dAuDyoLN0VYaLP+tBqEOk= -github.com/aws/aws-sdk-go-v2/credentials v1.12.23 h1:LctvcJMIb8pxvk5hQhChpCu0WlU6oKQmcYb1HA4IZSA= -github.com/aws/aws-sdk-go-v2/credentials v1.12.23/go.mod h1:0awX9iRr/+UO7OwRQFpV1hNtXxOVuehpjVEzrIAYNcA= +github.com/aws/aws-sdk-go-v2/credentials v1.13.3 h1:ur+FHdp4NbVIv/49bUjBW+FE7e57HOo03ELodttmagk= +github.com/aws/aws-sdk-go-v2/credentials v1.13.3/go.mod h1:/rOMmqYBcFfNbRPU0iN9IgGqD5+V2yp3iWNmIlz0wI4= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.9/go.mod h1:KDCCm4ONIdHtUloDcFvK2+vshZvx4Zmj7UMDfusuz5s= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.19 h1:E3PXZSI3F2bzyj6XxUXdTIfvp425HHhwKsFvmzBwHgs= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.19/go.mod h1:VihW95zQpeKQWVPGkwT+2+WJNQV8UXFfMTWdU6VErL8= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.21/go.mod h1:iIYPrQ2rYfZiB/iADYlhj9HHZ9TTi6PqKQPAqygohbE= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.37 h1:e1VtTBo+cLNjres0wTlMkmwCGGRjDEkkrz3frxxcaCs= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.37/go.mod h1:kdAV1UMnCkyG6tZJUC4mHbPoRjPA3dIK0L8mnsHERiM= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.42 h1:bxgBYvvBh+W1RnNYP4ROXEB8N+HSSucDszfE7Rb+kfU= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.42/go.mod h1:LHOsygMiW/14CkFxdXxvzKyMh3jbk/QfZVaDtCbLkl8= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.15/go.mod h1:pWrr2OoHlT7M/Pd2y4HV3gJyPb3qj5qMmnPkKSNPYK4= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.25 h1:nBO/RFxeq/IS5G9Of+ZrgucRciie2qpLy++3UGZ+q2E= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.25/go.mod h1:Zb29PYkf42vVYQY6pvSyJCJcFHlPIiY+YKdPtwnvMkY= @@ -345,11 +348,11 @@ github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.9/go.mod h1:Rc5+wn2 github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.19 h1:piDBAaWkaxkkVV3xJJbTehXCZRXYs49kvpi/LG6LR2o= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.19/go.mod h1:BmQWRVkLTmyNzYPFAZgon53qKLWBNSvonugD1MrSWUs= github.com/aws/aws-sdk-go-v2/service/kms v1.18.1/go.mod h1:4PZMUkc9rXHWGVB5J9vKaZy3D7Nai79ORworQ3ASMiM= -github.com/aws/aws-sdk-go-v2/service/kms v1.18.15 h1:hWPFd4GjCZLTb9Nvw+GuzZ4qTnvWoaqcLcrgofQGkhw= -github.com/aws/aws-sdk-go-v2/service/kms v1.18.15/go.mod h1:kZodDPTQjSH/qM6/OvyTfM5mms5JHB/EKYp5dhn/vI4= +github.com/aws/aws-sdk-go-v2/service/kms v1.18.18 h1:VEj0VdYbmx12y3GKWSXm8hB/mPuSaYHnECRhokHy4Wo= +github.com/aws/aws-sdk-go-v2/service/kms v1.18.18/go.mod h1:kZodDPTQjSH/qM6/OvyTfM5mms5JHB/EKYp5dhn/vI4= github.com/aws/aws-sdk-go-v2/service/s3 v1.27.2/go.mod h1:u+566cosFI+d+motIz3USXEh6sN8Nq4GrNXSg2RXVMo= -github.com/aws/aws-sdk-go-v2/service/s3 v1.29.1 h1:/EMdFPW/Ppieh0WUtQf1+qCGNLdsq5UWUyevBQ6vMVc= -github.com/aws/aws-sdk-go-v2/service/s3 v1.29.1/go.mod h1:/NHbqPRiwxSPVOB2Xr+StDEH+GWV/64WwnUjv4KYzV0= +github.com/aws/aws-sdk-go-v2/service/s3 v1.29.4 h1:QgmmWifaYZZcpaw3y1+ccRlgH6jAvLm4K/MBGUc7cNM= +github.com/aws/aws-sdk-go-v2/service/s3 v1.29.4/go.mod h1:/NHbqPRiwxSPVOB2Xr+StDEH+GWV/64WwnUjv4KYzV0= github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.15.14/go.mod h1:xakbH8KMsQQKqzX87uyyzTHshc/0/Df8bsTneTS5pFU= github.com/aws/aws-sdk-go-v2/service/sns v1.17.10/go.mod h1:uITsRNVMeCB3MkWpXxXw0eDz8pW4TYLzj+eyQtbhSxM= github.com/aws/aws-sdk-go-v2/service/sqs v1.19.1/go.mod h1:A94o564Gj+Yn+7QO1eLFeI7UVv3riy/YBFOfICVqFvU= @@ -360,8 +363,8 @@ github.com/aws/aws-sdk-go-v2/service/sso v1.11.25/go.mod h1:IARHuzTXmj1C0KS35vbo github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.8 h1:jcw6kKZrtNfBPJkaHrscDOZoe5gvi9wjudnxvozYFJo= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.8/go.mod h1:er2JHN+kBY6FcMfcBBKNGCT3CarImmdFzishsqBmSRI= github.com/aws/aws-sdk-go-v2/service/sts v1.16.10/go.mod h1:cftkHYN6tCDNfkSasAmclSfl4l7cySoay8vz7p/ce0E= -github.com/aws/aws-sdk-go-v2/service/sts v1.17.1 h1:KRAix/KHvjGODaHAMXnxRk9t0D+4IJVUuS/uwXxngXk= -github.com/aws/aws-sdk-go-v2/service/sts v1.17.1/go.mod h1:bXcN3koeVYiJcdDU89n3kCYILob7Y34AeLopUbZgLT4= +github.com/aws/aws-sdk-go-v2/service/sts v1.17.5 h1:60SJ4lhvn///8ygCzYy2l53bFW/Q15bVfyjyAWo6zuw= +github.com/aws/aws-sdk-go-v2/service/sts v1.17.5/go.mod h1:bXcN3koeVYiJcdDU89n3kCYILob7Y34AeLopUbZgLT4= github.com/aws/smithy-go v1.12.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/aws/smithy-go v1.13.4 h1:/RN2z1txIJWeXeOkzX+Hk/4Uuvv7dWtCjbmVJcrskyk= github.com/aws/smithy-go v1.13.4/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= @@ -408,7 +411,6 @@ github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3k github.com/butuzov/ireturn v0.1.1 h1:QvrO2QF2+/Cx1WA/vETCIYBKtRjc30vesdoPUNo1EbY= github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/bwesterb/go-ristretto v1.2.1/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bytecodealliance/wasmtime-go v1.0.0 h1:9u9gqaUiaJeN5IoD1L7egD8atOnTGyJcNp8BhkL9cUU= github.com/bytecodealliance/wasmtime-go v1.0.0/go.mod h1:jjlqQbWUfVSbehpErw3UoWFndBXRRMvfikYH6KsCwOg= github.com/caarlos0/ctrlc v1.2.0 h1:AtbThhmbeYx1WW3WXdWrd94EHKi+0NPRGS4/4pzrjwk= @@ -433,8 +435,9 @@ github.com/cenkalti/backoff/v3 v3.2.2 h1:cfUAAO3yvKMYKPrvhDuHSwQnhZNk/RMHKdZqKTx github.com/cenkalti/backoff/v3 v3.2.2/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= -github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= +github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= @@ -471,8 +474,8 @@ github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= -github.com/cloudflare/circl v1.2.0 h1:NheeISPSUcYftKlfrLuOo4T62FkmD4t4jviLfFFYaec= -github.com/cloudflare/circl v1.2.0/go.mod h1:Ch2UgYr6ti2KTtlejELlROl0YIYj7SLjAC8M+INXlMk= +github.com/cloudflare/circl v1.3.0 h1:Anq00jxDtoyX3+aCaYUZ0vXC5r4k4epberfWGDXV1zE= +github.com/cloudflare/circl v1.3.0/go.mod h1:+CauBF6R70Jqcyl8N2hC8pAXYbWkGIezuSbuGLtRhnw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -528,8 +531,8 @@ github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTV github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= github.com/containerd/containerd v1.5.8/go.mod h1:YdFSv5bTFLpG2HIYmfqDpSYYTDX+mc5qtSuYx1YUb/s= github.com/containerd/containerd v1.6.1/go.mod h1:1nJz5xCZPusx6jJU8Frfct988y0NpumIq9ODB0kLtoE= -github.com/containerd/containerd v1.6.8 h1:h4dOFDwzHmqFEP754PgfgTeVXFnLiRc6kiqC7tplDJs= -github.com/containerd/containerd v1.6.8/go.mod h1:By6p5KqPK0/7/CgO/A6t/Gz+CUYUu2zf1hUaaymVXB0= +github.com/containerd/containerd v1.6.10 h1:8aiav7I2ZyQLbTlNMcBXyAU1FtFvp6VuyuW13qSd6Hk= +github.com/containerd/containerd v1.6.10/go.mod h1:CVqfxdJ95PDgORwA219AwwLrREZgrTFybXu2HfMKRG0= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= @@ -631,22 +634,22 @@ github.com/daixiang0/gci v0.8.1/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+M github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deepmap/oapi-codegen v1.12.2 h1:F7SMEn0UMpJV6kWwDYqfDmnnOYHIcU7ETV8qTVFdyI0= -github.com/deepmap/oapi-codegen v1.12.2/go.mod h1:ao2aFwsl/muMHbez870+KelJ1yusV01RznwAFFrVjDc= +github.com/deepmap/oapi-codegen v1.12.3 h1:+DDYKeIwlKChzHjhVtlISegatFevDDazBhtk/dnp4V4= +github.com/deepmap/oapi-codegen v1.12.3/go.mod h1:ao2aFwsl/muMHbez870+KelJ1yusV01RznwAFFrVjDc= github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU= github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= github.com/denisenkom/go-mssqldb v0.12.2/go.mod h1:lnIw1mZukFRZDJYQ0Pb833QS2IaC3l5HkEfra2LJ+sk= github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA= github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= -github.com/dghubble/go-twitter v0.0.0-20221024160433-0cc1e72ed6d8 h1:ZrkR0vW8jXGy3wxfyEc20au8lqNJU8yn6g19I4AdzfQ= -github.com/dghubble/go-twitter v0.0.0-20221024160433-0cc1e72ed6d8/go.mod h1:B0/qdW5XUupJvcsx40hnVbfjzz9He5YpYXx6eVVdiSY= +github.com/dghubble/go-twitter v0.0.0-20221104224141-912508c3888b h1:XQu6o3AwJx/jsg9LZ41uIeUdXK5be099XFfFn6H9ikk= +github.com/dghubble/go-twitter v0.0.0-20221104224141-912508c3888b/go.mod h1:B0/qdW5XUupJvcsx40hnVbfjzz9He5YpYXx6eVVdiSY= github.com/dghubble/oauth1 v0.7.1 h1:JjbOVSVVkms9A4h/sTQy5Jb2nFuAAVb2qVYgenJPyrE= github.com/dghubble/oauth1 v0.7.1/go.mod h1:0eEzON0UY/OLACQrmnjgJjmvCGXzjBCsZqL1kWDXtF0= github.com/dghubble/sling v1.4.0 h1:/n8MRosVTthvMbwlNZgLx579OGVjUOy3GNEv5BIqAWY= github.com/dghubble/sling v1.4.0/go.mod h1:0r40aNsU9EdDUVBNhfCstAtFgutjgJGYbO1oNzkMoM8= -github.com/dgraph-io/badger/v3 v3.2103.3 h1:s63J1pisDhKpzWslXFe+ChuthuZptpwTE6qEKoczPb4= -github.com/dgraph-io/badger/v3 v3.2103.3/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5jsE0PPFzRiKjtcdw= +github.com/dgraph-io/badger/v3 v3.2103.4 h1:WE1B07YNTTJTtG9xjBcSW2wn0RJLyiV99h959RKZqM4= +github.com/dgraph-io/badger/v3 v3.2103.4/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5jsE0PPFzRiKjtcdw= github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -661,8 +664,10 @@ github.com/digitalocean/godo v1.78.0/go.mod h1:GBmu8MkjZmNARE7IXRPmkbbnocNN8+uBm github.com/digitalocean/godo v1.81.0/go.mod h1:BPCqvwbjbGqxuUnIKB4EvS/AX7IDnNmt5fwvIkWo+ew= github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= -github.com/disgoorg/disgo v0.13.20 h1:8TJndGmgF6ZdbMxlkjWPBDpMMFp5jCfMNgZwesQKwGA= -github.com/disgoorg/disgo v0.13.20/go.mod h1:Cyip4bCYHD3rHgDhBPT9cLo81e9AMbDe8ocM50UNRM4= +github.com/disgoorg/disgo v0.13.22 h1:Vf49TkfC5djuMTbS9qdg/pr/pCNUxHQtx8/dMPu3aWI= +github.com/disgoorg/disgo v0.13.22/go.mod h1:YiVpXSmyXLRalYQHTHUFWEQvolCNzw0zh6nfug07b/M= +github.com/disgoorg/json v1.0.0 h1:kDhSM661fgIuNoZF3BO5/odaR5NSq80AWb937DH+Pdo= +github.com/disgoorg/json v1.0.0/go.mod h1:BHDwdde0rpQFDVsRLKhma6Y7fTbQKub/zdGO5O9NqqA= github.com/disgoorg/log v1.2.0 h1:sqlXnu/ZKAlIlHV9IO+dbMto7/hCQ474vlIdMWk8QKo= github.com/disgoorg/log v1.2.0/go.mod h1:3x1KDG6DI1CE2pDwi3qlwT3wlXpeHW/5rVay+1qDqOo= github.com/disgoorg/snowflake/v2 v2.0.1 h1:CuUxGLwggUxEswZOmZ+mZ5i0xSumQdXW9tXW7uGqe+0= @@ -673,8 +678,8 @@ github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/ github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/cli v20.10.20+incompatible h1:lWQbHSHUFs7KraSN2jOJK7zbMS2jNCHI4mt4xUFUVQ4= -github.com/docker/cli v20.10.20+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v20.10.21+incompatible h1:qVkgyYUnOLQ98LtXBrwd/duVqPT2X4SHndOuGsfwyhU= +github.com/docker/cli v20.10.21+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= @@ -683,8 +688,8 @@ github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4Kfc github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.14+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.17+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.20+incompatible h1:kH9tx6XO+359d+iAkumyKDc5Q1kOwPuAUaeri48nD6E= -github.com/docker/docker v20.10.20+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.21+incompatible h1:UTLdBmHk3bEY+w8qeO5KttOhy6OmXWsl/FEet9Uswog= +github.com/docker/docker v20.10.21+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= @@ -1021,8 +1026,8 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/flatbuffers v22.9.29+incompatible h1:3UBb679lq3V/O9rgzoJmnkP1jJzmC9OdFzITUBkLU/A= -github.com/google/flatbuffers v22.9.29+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/flatbuffers v22.11.23+incompatible h1:334TygA7iuxt0hoamawsM36xoui01YiouEZnr0qeFMI= +github.com/google/flatbuffers v22.11.23+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -1041,8 +1046,8 @@ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= -github.com/google/go-github/v48 v48.0.0 h1:9H5fWVXFK6ZsRriyPbjtnFAkJnoj0WKFtTYfpCRrTm8= -github.com/google/go-github/v48 v48.0.0/go.mod h1:dDlehKBDo850ZPvCTK0sEqTCVWcrGl2LcDiajkYi89Y= +github.com/google/go-github/v48 v48.1.0 h1:nqPqq+0oRY2AMR/SRskGrrP4nnewPB7e/m2+kbT/UvM= +github.com/google/go-github/v48 v48.1.0/go.mod h1:dDlehKBDo850ZPvCTK0sEqTCVWcrGl2LcDiajkYi89Y= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= @@ -1100,8 +1105,8 @@ github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0 github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= -github.com/googleapis/gax-go/v2 v2.6.0 h1:SXk3ABtQYDT/OH8jAyvEOQ58mgawq5C4o/4/89qN2ZU= -github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= +github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= @@ -1117,10 +1122,10 @@ github.com/goreleaser/chglog v0.2.2 h1:V7nf07baXtGAgGevvqgW2MM4kZ6gOr12vKNSAU3VI github.com/goreleaser/chglog v0.2.2/go.mod h1:2s5JwtCOWjZa8AIneL+xdUl9SRuigCjRHNHsX30dupE= github.com/goreleaser/fileglob v1.3.0 h1:/X6J7U8lbDpQtBvGcwwPS6OpzkNVlVEsFUVRx9+k+7I= github.com/goreleaser/fileglob v1.3.0/go.mod h1:Jx6BoXv3mbYkEzwm9THo7xbr5egkAraxkGorbJb4RxU= -github.com/goreleaser/goreleaser v1.12.3 h1:sTJXdkGQO9eAP6pwEUazaD6ERJewZ7yzQexWEGPUVg4= -github.com/goreleaser/goreleaser v1.12.3/go.mod h1:eBdKNaOsGUZWcSgXdMQliud+CiQhhO0m4cgSjb+S1ms= -github.com/goreleaser/nfpm/v2 v2.20.0 h1:Q/CrX54KUMluz6+M/pjTbknFd5Dao8qXi0C6ZuFCtfY= -github.com/goreleaser/nfpm/v2 v2.20.0/go.mod h1:/Fh6XfwT/T+D4qtNC2iXmHSD/1UT20JkvBXyJ6nFmOY= +github.com/goreleaser/goreleaser v1.13.0 h1:wg7KX6osE+qm0ydBw/B00LQGqXD7qbGXPNDTyBPe/p4= +github.com/goreleaser/goreleaser v1.13.0/go.mod h1:JFjB/kuTGFwpL3o9ix09K1ctGpABCk/xGIdoVDr0AJw= +github.com/goreleaser/nfpm/v2 v2.22.1 h1:S5ShUIQYIB4uUiJmBy7S0w5SvZ2CwqBOvXNvRGnO6XE= +github.com/goreleaser/nfpm/v2 v2.22.1/go.mod h1:c5/coiBdrKNdXXgKnSCrqSk8OtltpGwJ2woU/8EtHD4= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= @@ -1165,8 +1170,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.2/go.mod h1:chrfS3YoLAlKTRE5cFWvCbt8uGAjshktT4PveTUpsFQ= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0 h1:kr3j8iIMR4ywO/O0rvksXaJvauGGCMg2zAZIiNZ9uIQ= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.12.0/go.mod h1:ummNFgdgLhhX7aIiy35vVmQNS0rWXknfPE0qe6fmFXg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.14.0 h1:t7uX3JBHdVwAi3G7sSSdbsk8NfgA+LnUS88V/2EKaA0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.14.0/go.mod h1:4OGVnY4qf2+gw+ssiHbW+pq4mo2yko94YxxMmXZ7jCA= github.com/hairyhenderson/go-fsimpl v0.0.0-20220919132154-dc606beb8e19 h1:xR+VCv9O7oed+CEG+2cR+awTfKdl6S40xjB24V8OiUE= github.com/hairyhenderson/go-fsimpl v0.0.0-20220919132154-dc606beb8e19/go.mod h1:LJFs5aPge/vPrwmUugi+uNrGpJGMLZtyl1S6zU8ssXo= github.com/hairyhenderson/gomplate/v3 v3.11.3 h1:ovdPnPzn+T4AfIK7ulpCz6j0MRC+07lvH0A6Eh0tc9Q= @@ -1276,8 +1281,8 @@ github.com/hetznercloud/hcloud-go v1.35.0/go.mod h1:mepQwR6va27S3UQthaEPGS86jtzS github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= -github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= +github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= github.com/iancoleman/orderedmap v0.2.0 h1:sq1N/TFpYH++aViPcaKjys3bDClUEU7s5B+z6jq8pNA= @@ -1299,8 +1304,8 @@ github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7P github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/intel/goresctrl v0.2.0/go.mod h1:+CZdzouYFn5EsxgqAQTEzMfwKwuc0fVdMrT9FCCAVRQ= -github.com/invopop/jsonschema v0.6.0 h1:8e+xY8ZEn8gDHUYylSlLHy22P+SLeIRIHv3nM3hCbmY= -github.com/invopop/jsonschema v0.6.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0= +github.com/invopop/jsonschema v0.7.0 h1:2vgQcBz1n256N+FpX3Jq7Y17AjYt46Ig3zIWyy770So= +github.com/invopop/jsonschema v0.7.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0= github.com/invopop/yaml v0.1.0 h1:YW3WGUoJEXYfzWBjn00zIlrw7brGVD0fUKRYDPAPhrc= github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= github.com/ionos-cloud/sdk-go/v6 v6.1.0/go.mod h1:Ox3W0iiEz0GHnfY9e5LmAxwklsxguuNFEUSu0gVRTME= @@ -1408,8 +1413,8 @@ github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdY github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c= -github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= +github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/kolo/xmlrpc v0.0.0-20201022064351-38db28db192b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= @@ -1509,6 +1514,8 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-mastodon v0.0.6 h1:lqU1sOeeIapaDsDUL6udDZIzMb2Wqapo347VZlaOzf0= +github.com/mattn/go-mastodon v0.0.6/go.mod h1:cg7RFk2pcUfHZw/IvKe1FUzmlq5KnLFqs7eV2PHplV8= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= @@ -1523,8 +1530,8 @@ github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lL github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/matttproud/golang_protobuf_extensions v1.0.2 h1:hAHbPm5IJGijwng3PWk09JkG9WeqChjprR5s9bBZ+OM= -github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= @@ -1575,8 +1582,8 @@ github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6 github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= -github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI= -github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= +github.com/moby/term v0.0.0-20221128092401-c43b287e0e0f h1:J/7hjLaHLD7epG0m6TBMGmp4NQ+ibBYLfeyJWdAIFLA= +github.com/moby/term v0.0.0-20221128092401-c43b287e0e0f/go.mod h1:15ce4BGCFxt7I5NQKT+HV0yEDxmf6fSysfEDiVo3zFM= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -1665,8 +1672,8 @@ github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDs github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= -github.com/open-policy-agent/opa v0.45.0 h1:P5nuhVRtR+e58fk3CMMbiqr6ZFyWQPNOC3otsorGsFs= -github.com/open-policy-agent/opa v0.45.0/go.mod h1:/OnsYljNEWJ6DXeFOOnoGn8CvwZGMUS4iRqzYdJvmBI= +github.com/open-policy-agent/opa v0.46.1 h1:iG998SLK0rzalex7Hyekeq17b9WtUexM0AuyHrQ7fCc= +github.com/open-policy-agent/opa v0.46.1/go.mod h1:DY9ZkCyz+DKoWI5gDuLw5rGC2RSb37QUeEf+9VjsWkI= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -1771,8 +1778,8 @@ github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= -github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= +github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -1839,8 +1846,9 @@ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5X github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8= github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= +github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -1919,8 +1927,8 @@ github.com/sivchari/nosnakecase v1.7.0 h1:7QkpWIRMe8x25gckkFd2A5Pi6Ymo0qgr4JrhGt github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY= github.com/sivchari/tenv v1.7.0 h1:d4laZMBK6jpe5PWepxlV9S+LC0yXqvYHiq8E6ceoVVE= github.com/sivchari/tenv v1.7.0/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= -github.com/slack-go/slack v0.11.3 h1:GN7revxEMax4amCc3El9a+9SGnjmBvSUobs0QnO6ZO8= -github.com/slack-go/slack v0.11.3/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= +github.com/slack-go/slack v0.11.4 h1:ojSa7KlPm3PqY2AomX4VTxEsK5eci5JaxCjlzGV5zoM= +github.com/slack-go/slack v0.11.4/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= @@ -2031,6 +2039,8 @@ github.com/tomarrell/wrapcheck/v2 v2.7.0 h1:J/F8DbSKJC83bAvC6FoZaRjZiZ/iKoueSdrE github.com/tomarrell/wrapcheck/v2 v2.7.0/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg= github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw= github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= +github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 h1:nrZ3ySNYwJbSpD6ce9duiP+QkD3JuLCcWkdaehUS/3Y= +github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80/go.mod h1:iFyPdL66DjUD96XmzVL3ZntbzcflLnznH0fr99w5VqE= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= @@ -2070,11 +2080,11 @@ github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= github.com/withfig/autocomplete-tools/integrations/cobra v1.2.1 h1:+dBg5k7nuTE38VVdoroRsT0Z88fmvdYrI2EjzJst35I= github.com/withfig/autocomplete-tools/integrations/cobra v1.2.1/go.mod h1:nmuySobZb4kFgFy6BptpXp/BBw+xFSyvVPP6auoJB4k= -github.com/xanzy/go-gitlab v0.73.1 h1:UMagqUZLJdjss1SovIC+kJCH4k2AZWXl58gJd38Y/hI= -github.com/xanzy/go-gitlab v0.73.1/go.mod h1:d/a0vswScO7Agg1CZNz15Ic6SSvBG9vfw8egL99t4kA= +github.com/xanzy/go-gitlab v0.76.0 h1:mkmuB27RDVZY/iXR61pEUfIqJ15Iivfu1kc3KZtBICI= +github.com/xanzy/go-gitlab v0.76.0/go.mod h1:d/a0vswScO7Agg1CZNz15Ic6SSvBG9vfw8egL99t4kA= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= -github.com/xanzy/ssh-agent v0.3.2 h1:eKj4SX2Fe7mui28ZgnFW5fmTz1EIr7ugo5s6wDxdHBM= -github.com/xanzy/ssh-agent v0.3.2/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= @@ -2142,16 +2152,17 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0/go.mod h1:vEhqr0m4eTc+DWxfsXoXue2GBgV2uUwVznkGIHW/e5w= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.31.0/go.mod h1:PFmBsWbldL1kiWZk9+0LBZz2brhByaGsvp6pRICMlPE= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0/go.mod h1:5eCOqeGphOyz6TsY3ZDNjE33SM/TFAK3RGuCL2naTgY= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.36.3 h1:SGz6Fnp7blR+sskRZkyuFDb3qI1d8I0ygLh13F+sw6I= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.36.3/go.mod h1:+OXcluxum2GicWQ9lMXLQkLkOWoaw20OrVbYq6kkPks= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.36.4 h1:aUEBEdCa6iamGzg6fuYxDA8ThxvOG240mAvWDU+XLio= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.36.4/go.mod h1:l2MdsbKTocpPS5nQZscqTR9jd8u96VYZdcpF8Sye7mA= go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs= go.opentelemetry.io/otel v1.6.0/go.mod h1:bfJD2DZVw0LBxghOTlgnlI0CV3hLDu9XF/QKOUXMTQQ= @@ -2275,12 +2286,11 @@ golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -2325,8 +2335,8 @@ golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= -golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -2405,8 +2415,9 @@ golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -2432,8 +2443,8 @@ golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7Lm golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= golang.org/x/oauth2 v0.0.0-20220628200809-02e64fa58f26/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= golang.org/x/oauth2 v0.0.0-20220722155238-128564f6959c/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.1.0 h1:isLCZuhj4v+tYv7eskaN4v/TM+A1begWWgyVJDdl1+Y= -golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= +golang.org/x/oauth2 v0.2.0 h1:GtQkldQ9m7yvzCL1V+LrYow3Khe0eJH0w7RbX/VbaIU= +golang.org/x/oauth2 v0.2.0/go.mod h1:Cwn6afJ8jrQwYMxQDTpISoXmXW9I6qF6vDeuuoX3Ibs= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -2585,7 +2596,6 @@ golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2604,15 +2614,17 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220909162455-aba9fc2a8ff2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2636,8 +2648,8 @@ golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA= -golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.2.0 h1:52I/1L54xyEQAYdtcSuxtiT84KGYTBGXwayxmIpNJhE= +golang.org/x/time v0.2.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -2748,8 +2760,8 @@ golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= -golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2809,8 +2821,8 @@ google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6F google.golang.org/api v0.86.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= google.golang.org/api v0.91.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= -google.golang.org/api v0.101.0 h1:lJPPeEBIRxGpGLwnBTam1NPEM8Z2BmmXEd3z812pjwM= -google.golang.org/api v0.101.0/go.mod h1:CjxAAWWt3A3VrUE2IGDY2bgK5qhoG/OkyWVlYcP05MY= +google.golang.org/api v0.103.0 h1:9yuVqlu2JCvcLg9p8S3fcFLZij8EPSyvODIY1rkMizQ= +google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2921,8 +2933,8 @@ google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljW google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220802133213-ce4fa296bf78/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= -google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71 h1:GEgb2jF5zxsFJpJfg9RoDDWm7tiwc/DDSTE2BtLUkXU= -google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6 h1:a2S6M0+660BgMNl++4JPlcAO/CjkqYItDEZwkoDQK7c= +google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -2964,8 +2976,8 @@ google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= -google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/web/app/package.json b/web/app/package.json index ef6af3e..8b551cf 100644 --- a/web/app/package.json +++ b/web/app/package.json @@ -10,16 +10,16 @@ "lint:fix": "prettier --write ./src/**/*.{js,svelte,html} --no-error-on-unmatched-pattern && eslint --fix src/**/*.{js,svelte} --no-error-on-unmatched-pattern" }, "devDependencies": { - "@rollup/plugin-commonjs": "^23.0.2", + "@rollup/plugin-commonjs": "^23.0.3", "@rollup/plugin-node-resolve": "^15.0.1", "@rollup/plugin-replace": "^5.0.1", "@sargassum-world/styles": "^0.2.2", "bulma": "^0.9.4", - "eslint": "^8.27.0", + "eslint": "^8.28.0", "eslint-plugin-import": "^2.24.2", "eslint-plugin-svelte3": "^4.0.0", - "prettier": "^2.7.1", - "prettier-plugin-svelte": "^2.8.0", + "prettier": "^2.8.0", + "prettier-plugin-svelte": "^2.8.1", "purify-css": "^1.2.5", "rollup": "^2.79.0", "rollup-plugin-copy": "^3.4.0", @@ -27,8 +27,8 @@ "rollup-plugin-scss": "^3.0.0", "rollup-plugin-svelte": "^7.0.0", "rollup-plugin-terser": "^7.0.0", - "sass": "^1.56.0", - "svelte": "^3.52.0", + "sass": "^1.56.1", + "svelte": "^3.53.1", "svelte-check": "^2.9.2", "svelte-dark-mode": "^2.0.0", "svelte-preprocess": "^4.10.7" @@ -36,9 +36,9 @@ "dependencies": { "@fontsource/atkinson-hyperlegible": "^4.5.10", "@fontsource/oxygen-mono": "^4.5.10", - "@hotwired/stimulus": "^3.1.1", + "@hotwired/stimulus": "^3.2.0", "@hotwired/turbo": "^7.2.2", - "@sargassum-world/stimulated": "^0.4.5", + "@sargassum-world/stimulated": "^0.5.0", "workbox-expiration": "^6.5.4", "workbox-recipes": "^6.5.4", "workbox-routing": "^6.5.4", diff --git a/web/app/src/main-deferred.js b/web/app/src/main-deferred.js index 0165466..2d7f508 100644 --- a/web/app/src/main-deferred.js +++ b/web/app/src/main-deferred.js @@ -3,6 +3,7 @@ import { DefaultScrollableController, FormSubmissionController, HideableController, + ImageAutoreloadController, LoadFocusController, LoadScrollController, NavigationLinkController, @@ -10,10 +11,10 @@ import { ThemeController, TurboCableStreamSourceElement, TurboCacheController, - ImageAutoreloadController, Turbo, } from '@sargassum-world/stimulated'; import { Application } from '@hotwired/stimulus'; +import { VideoCablePlayerElement } from './sprinkles'; Turbo.session.drive = true; @@ -21,6 +22,9 @@ customElements.define( 'turbo-cable-stream-source', TurboCableStreamSourceElement, ); +customElements.define('video-cable-player', VideoCablePlayerElement, { + extends: 'canvas', +}); const Stimulus = Application.start(); Stimulus.register('csrf', CSRFController); @@ -39,4 +43,10 @@ if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js'); } +// Prevent noscript elements from being processed. Refer to +// https://discuss.hotwired.dev/t/turbo-processes-noscript-children-when-merging-head/2552 +document.addEventListener('turbo:before-render', function (event) { + event.detail.newBody.querySelectorAll('noscript').forEach((e) => e.remove()); +}); + export {}; diff --git a/web/app/src/sprinkles/index.js b/web/app/src/sprinkles/index.js new file mode 100644 index 0000000..8c757a5 --- /dev/null +++ b/web/app/src/sprinkles/index.js @@ -0,0 +1 @@ +export { default as VideoCablePlayerElement } from './video-cable-player.element'; diff --git a/web/app/src/sprinkles/video-cable-player.element.js b/web/app/src/sprinkles/video-cable-player.element.js new file mode 100644 index 0000000..4c66708 --- /dev/null +++ b/web/app/src/sprinkles/video-cable-player.element.js @@ -0,0 +1,48 @@ +import { + getActionCableConsumer, + attachCSRFToken, + makeWebSocketURL, +} from '@sargassum-world/stimulated'; + +export default class VideoCablePlayerElement extends HTMLCanvasElement { + async connectedCallback() { + if (document.documentElement.hasAttribute('data-turbo-preview')) { + return; + } + await attachCSRFToken(this); + + // Initialize channel + const channel = { + channel: this.getAttribute('channel'), + name: this.getAttribute('name'), + integrity: this.getAttribute('integrity'), + }; + if (this.hasAttribute('csrf-token')) { + channel.csrfToken = this.getAttribute('csrf-token'); + } + + // Subscribe + const consumer = getActionCableConsumer( + makeWebSocketURL(this.getAttribute('cable-route')), + // Warning: VideoCablePlayerElement assumes the use of a format which can serialize byte + // arrays, such as MessagePack - but not JSON! + this.getAttribute('websocket-subprotocol'), + ); + this.subscription = consumer.subscriptions.create(channel, { + received: this.dispatchMessageEvent.bind(this), + }); + } + + disconnectedCallback() { + if (this.subscription) this.subscription.unsubscribe(); + } + + async dispatchMessageEvent(data) { + const bitmap = await createImageBitmap( + new Blob([data], { type: 'image/jpeg' }), + ); + this.width = bitmap.width; + this.height = bitmap.height; + this.getContext('2d').drawImage(bitmap, 0, 0); + } +} diff --git a/web/app/yarn.lock b/web/app/yarn.lock index b50e7ee..0194a01 100644 --- a/web/app/yarn.lock +++ b/web/app/yarn.lock @@ -2,6 +2,28 @@ # yarn lockfile v1 +"@anycable/core@^0.5.0": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@anycable/core/-/core-0.5.7.tgz#815460c4d7ed4cb9ca5a96afa13303b5d8e8d3e6" + integrity sha512-CWdr4eMrR3j+VOrVR97lvPywX4tvc7PiW5z7hl1GxhtPMojE36LTid+BQyHvEpQS7eA201W+By8jYNoJ0KpmMw== + dependencies: + nanoevents "^6.0.0" + +"@anycable/msgpack-encoder@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@anycable/msgpack-encoder/-/msgpack-encoder-0.2.0.tgz#47166acd8c731b8273159ee5964d94d2496e3317" + integrity sha512-HUf7tXyqNZ23uwxgtHyNa9Pi984lTPpdZBdSWf7bep3a0PQ4W/YC3UIEGhGW3jvZwf0qO0/AwDECwWOa8Xc14A== + dependencies: + "@anycable/core" "^0.5.0" + "@ygoe/msgpack" "^1.0.0" + +"@anycable/web@^0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@anycable/web/-/web-0.5.2.tgz#bfdb0ae925bd6017052eca0f713ec06fa1fb5d63" + integrity sha512-GveeZMBGpeSF//BB7NAnV6BJUj0DCVO2ORTxr1cun3z7WSHdd0MG6NPICb6EOKrFDbar5YpTq2eRoADnSpXA8g== + dependencies: + "@anycable/core" "^0.5.0" + "@babel/code-frame@^7.10.4": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" @@ -48,11 +70,16 @@ resolved "https://registry.yarnpkg.com/@fontsource/oxygen-mono/-/oxygen-mono-4.5.10.tgz#498362304a9dbcb04343bd562618e97f781a3e74" integrity sha512-+SLEZx+WVbCRnJ3OpzXvjCm+VfbIkl0kOByUpjvT8bYqRegUxdWzSbXG95e8XPGMdK/tLS7gHcddN/1OV/R4SQ== -"@hotwired/stimulus@3.1.1", "@hotwired/stimulus@^3.1.1": +"@hotwired/stimulus@3.1.1": version "3.1.1" resolved "https://registry.yarnpkg.com/@hotwired/stimulus/-/stimulus-3.1.1.tgz#652f08a8e1d5edcb407340e58818fcff463b5848" integrity sha512-e0JpzIaYLsRRXevRDVs0yevabiCvieIWWCwh7VqVXjXM5AOHdjb7AjaKIj34zYFmY1N6HIRRfk915WVMYlHnDA== +"@hotwired/stimulus@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@hotwired/stimulus/-/stimulus-3.2.0.tgz#257272f1348b1f7beb1a8510be88b80aec6c4c5b" + integrity sha512-uAIIdg049qId0lBhyjuMBfcC5uV8JwbhNLoxEyi9vxM3MW6h+mM97G9rNT4ZZMiqnKK9XUHp9SQUrd9rSLEmpQ== + "@hotwired/turbo@^7.0.1", "@hotwired/turbo@^7.2.2": version "7.2.4" resolved "https://registry.yarnpkg.com/@hotwired/turbo/-/turbo-7.2.4.tgz#0d35541be32cfae3b4f78c6ab9138f5b21f28a21" @@ -138,15 +165,10 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@rails/actioncable@^7.0.3-1": - version "7.0.4" - resolved "https://registry.yarnpkg.com/@rails/actioncable/-/actioncable-7.0.4.tgz#70a3ca56809f7aaabb80af2f9c01ae51e1a8ed41" - integrity sha512-tz4oM+Zn9CYsvtyicsa/AwzKZKL+ITHWkhiu7x+xF77clh2b4Rm+s6xnOgY/sGDWoFWZmtKsE95hxBPkgQQNnQ== - -"@rollup/plugin-commonjs@^23.0.2": - version "23.0.2" - resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-23.0.2.tgz#3a3a5b7b1b1cb29037eb4992edcaae997d7ebd92" - integrity sha512-e9ThuiRf93YlVxc4qNIurvv+Hp9dnD+4PjOqQs5vAYfcZ3+AXSrcdzXnVjWxcGQOa6KGJFcRZyUI3ktWLavFjg== +"@rollup/plugin-commonjs@^23.0.3": + version "23.0.3" + resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-23.0.3.tgz#442cd8ccca1b7563a503da86fc84a1a7112b54bb" + integrity sha512-31HxrT5emGfTyIfAs1lDQHj6EfYxTXcwtX5pIIhq+B/xZBNIqQ179d/CkYxlpYmFCxT78AeU4M8aL8Iv/IBxFA== dependencies: "@rollup/pluginutils" "^5.0.1" commondir "^1.0.1" @@ -184,14 +206,15 @@ estree-walker "^2.0.2" picomatch "^2.3.1" -"@sargassum-world/stimulated@^0.4.5": - version "0.4.5" - resolved "https://registry.yarnpkg.com/@sargassum-world/stimulated/-/stimulated-0.4.5.tgz#41d178fc08e670e9d039fba12aadf18d4bef0990" - integrity sha512-VMIbGonCKParTHHxmBLWGaU07mU+n7+Tj6FuRodhX1bOgXG/TcNwgzlNDwyEjLq2df7Uhwfd/fzajsK9ItEflw== +"@sargassum-world/stimulated@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@sargassum-world/stimulated/-/stimulated-0.5.0.tgz#605ea76f487149f9a671d5153c05616873905aa2" + integrity sha512-KnH5ICBc/pzu9poqmrmVq3GjYmje+xWkUNBny+VQl5pTE3oyPUyfKaqo1DBL0ArCXS8jRB8Eopw2MFgzL6t31g== dependencies: + "@anycable/msgpack-encoder" "^0.2.0" + "@anycable/web" "^0.5.2" "@hotwired/stimulus" "3.1.1" "@hotwired/turbo" "^7.0.1" - "@rails/actioncable" "^7.0.3-1" async-mutex "0.4.0" "@sargassum-world/styles@^0.2.2": @@ -256,6 +279,11 @@ dependencies: "@types/node" "*" +"@ygoe/msgpack@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@ygoe/msgpack/-/msgpack-1.0.3.tgz#3889f4c0c2d68b2be83e1f6f4444efab02d6f257" + integrity sha512-Sjp0O/sNgOJxTOO1c2Zuu7nsHRIGu2iGPYyhUedKKbcHyUl73jbCaomEFJZHNb/6i94B+ZNZHVnFgpo0ENSXxQ== + acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" @@ -765,10 +793,10 @@ eslint-visitor-keys@^3.3.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== -eslint@^8.27.0: - version "8.27.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.27.0.tgz#d547e2f7239994ad1faa4bb5d84e5d809db7cf64" - integrity sha512-0y1bfG2ho7mty+SiILVf9PfuRA49ek4Nc60Wmmu62QlobNR+CeXa4xXIJgcuwSQgZiWaPH+5BDsctpIW0PR/wQ== +eslint@^8.28.0: + version "8.28.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.28.0.tgz#81a680732634677cc890134bcdd9fdfea8e63d6e" + integrity sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ== dependencies: "@eslint/eslintrc" "^1.3.3" "@humanwhocodes/config-array" "^0.11.6" @@ -1540,6 +1568,11 @@ ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +nanoevents@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/nanoevents/-/nanoevents-6.0.2.tgz#3824031c7beab754b04ae5a17936c0fc7b6a183c" + integrity sha512-FRS2otuFcPPYDPYViNWQ42+1iZqbXydinkRHTHFxrF4a1CpBfmydR9zkI44WSXAXCyPrkcGtPk5CnpW6Y3lFKQ== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -1743,15 +1776,15 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prettier-plugin-svelte@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/prettier-plugin-svelte/-/prettier-plugin-svelte-2.8.0.tgz#e5681d9867c4ab584c0ccbe43c3684d132b389f2" - integrity sha512-QlXv/U3bUszks3XYDPsk1fsaQC+fo2lshwKbcbO+lrSVdJ+40mB1BfL8OCAk1W9y4pJxpqO/4gqm6NtF3zNGCw== +prettier-plugin-svelte@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/prettier-plugin-svelte/-/prettier-plugin-svelte-2.8.1.tgz#5b7df5bd0d953b133281607295a3e5131052bb8b" + integrity sha512-KA3K1J3/wKDnCxW7ZDRA/QL2Q67N7Xs3gOERqJ5X1qFjq1DdnN3K1R29scSKwh+kA8FF67pXbYytUpvN/i3iQw== -prettier@^2.7.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" - integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== +prettier@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.0.tgz#c7df58393c9ba77d6fba3921ae01faf994fb9dc9" + integrity sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA== pseudomap@^1.0.2: version "1.0.2" @@ -1971,10 +2004,10 @@ sander@^0.5.0: mkdirp "^0.5.1" rimraf "^2.5.2" -sass@^1.56.0: - version "1.56.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.56.0.tgz#134032075a3223c8d49cb5c35e091e5ba1de8e0a" - integrity sha512-WFJ9XrpkcnqZcYuLRJh5qiV6ibQOR4AezleeEjTjMsCocYW59dEG19U3fwTTXxzi2Ed3yjPBp727hbbj53pHFw== +sass@^1.56.1: + version "1.56.1" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.56.1.tgz#94d3910cd468fd075fa87f5bb17437a0b617d8a7" + integrity sha512-VpEyKpyBPCxE7qGDtOcdJ6fFbcpOM+Emu7uZLxVrkX8KVU/Dp5UF7WLvzqRuUhB6mqqQt1xffLoG+AndxTZrCQ== dependencies: chokidar ">=3.0.0 <4.0.0" immutable "^4.0.0" @@ -2241,10 +2274,10 @@ svelte-preprocess@^4.0.0, svelte-preprocess@^4.10.7: sorcery "^0.10.0" strip-indent "^3.0.0" -svelte@^3.52.0: - version "3.52.0" - resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.52.0.tgz#08259eff20904c63882b66a5d409a55e8c6743b8" - integrity sha512-FxcnEUOAVfr10vDU5dVgJN19IvqeHQCS1zfe8vayTfis9A2t5Fhx+JDe5uv/C3j//bB1umpLJ6quhgs9xyUbCQ== +svelte@^3.53.1: + version "3.53.1" + resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.53.1.tgz#db9d7df7a8f570e8e22547444c149208b1914442" + integrity sha512-Q4/hHkktZogGhN5iqxqSi9sjEVoe/NbIxX4hXEHoasTxj+TxEQVAq66LnDMdAZxjmsodkoI5F3slqsS68U7FNw== terser@^5.0.0: version "5.15.0" diff --git a/web/policies/cable/routes.rego b/web/policies/cable/routes.rego index db8293c..29944a6 100644 --- a/web/policies/cable/routes.rego +++ b/web/policies/cable/routes.rego @@ -10,6 +10,10 @@ in_scope if { "/cable" == input.resource.path } +in_scope if { + "/video-cable" == input.resource.path +} + # Policy Result & Error allow if { diff --git a/web/policies/instruments/routes.gen.rego b/web/policies/instruments/routes.gen.rego index 660841b..144b5e9 100644 --- a/web/policies/instruments/routes.gen.rego +++ b/web/policies/instruments/routes.gen.rego @@ -226,6 +226,29 @@ allow if { allow_camera_get(id, camera_id) } +matching_routes contains route if { + "SUB" == input.operation.method + ["instruments", id, "cameras", camera_id, "stream.mjpeg"] = split(trim_prefix(input.resource.path, "/"), "/") + route := "SUB /instruments/:id/cameras/:camera_id/stream.mjpeg" +} + +allow if { + "SUB" == input.operation.method + ["instruments", id, "cameras", camera_id, "stream.mjpeg"] = split(trim_prefix(input.resource.path, "/"), "/") + allow_camera_get(id, camera_id) +} + +matching_routes contains route if { + "UNSUB" == input.operation.method + ["instruments", id, "cameras", camera_id, "stream.mjpeg"] = split(trim_prefix(input.resource.path, "/"), "/") + route := "UNSUB /instruments/:id/cameras/:camera_id/stream.mjpeg" +} + +allow if { + "UNSUB" == input.operation.method + ["instruments", id, "cameras", camera_id, "stream.mjpeg"] = split(trim_prefix(input.resource.path, "/"), "/") +} + matching_routes contains route if { "POST" == input.operation.method ["instruments", id, "controllers"] = split(trim_prefix(input.resource.path, "/"), "/") diff --git a/web/policies/instruments/routes.rego.tmpl b/web/policies/instruments/routes.rego.tmpl index b3370a2..7e89847 100644 --- a/web/policies/instruments/routes.rego.tmpl +++ b/web/policies/instruments/routes.rego.tmpl @@ -53,6 +53,13 @@ in_scope if { coll.Slice "GET" "/instruments/:id/cameras/:camera_id/stream.mjpeg" "allow_camera_get(id, camera_id)" ) + ( + coll.Slice "SUB" "/instruments/:id/cameras/:camera_id/stream.mjpeg" + "allow_camera_get(id, camera_id)" + ) + ( + coll.Slice "UNSUB" "/instruments/:id/cameras/:camera_id/stream.mjpeg" + ) (coll.Slice "POST" "/instruments/:id/controllers" "allow_instrument_post(input.subject, id)") ( coll.Slice "POST" "/instruments/:id/controllers/:controller_id" diff --git a/web/policies/policies.gen.rego b/web/policies/policies.gen.rego index bafb5f7..e945b5a 100644 --- a/web/policies/policies.gen.rego +++ b/web/policies/policies.gen.rego @@ -26,7 +26,7 @@ allow if { assets.allow } -policy_errors["assets"] := error if { +policy_errors.assets := error if { some error in assets.errors } @@ -41,7 +41,7 @@ allow if { auth.allow } -policy_errors["auth"] := error if { +policy_errors.auth := error if { some error in auth.errors } @@ -56,7 +56,7 @@ allow if { cable.allow } -policy_errors["cable"] := error if { +policy_errors.cable := error if { some error in cable.errors } @@ -71,7 +71,7 @@ allow if { home.allow } -policy_errors["home"] := error if { +policy_errors.home := error if { some error in home.errors } @@ -86,7 +86,7 @@ allow if { instruments.allow } -policy_errors["instruments"] := error if { +policy_errors.instruments := error if { some error in instruments.errors } @@ -101,7 +101,7 @@ allow if { privatechat.allow } -policy_errors["privatechat"] := error if { +policy_errors.privatechat := error if { some error in privatechat.errors } @@ -116,7 +116,7 @@ allow if { users.allow } -policy_errors["users"] := error if { +policy_errors.users := error if { some error in users.errors } @@ -131,7 +131,7 @@ allow if { videostreams.allow } -policy_errors["videostreams"] := error if { +policy_errors.videostreams := error if { some error in videostreams.errors } diff --git a/web/policies/shared/policy.partial.tmpl b/web/policies/shared/policy.partial.tmpl index da266e5..81b0fb5 100644 --- a/web/policies/shared/policy.partial.tmpl +++ b/web/policies/shared/policy.partial.tmpl @@ -11,7 +11,7 @@ allow if { {{$policy}}.allow } -policy_errors["{{$policy}}"] := error if { +policy_errors.{{$policy}} := error if { some error in {{$policy}}.errors } {{- /* This comment is just here to delete whitespace */ -}} diff --git a/web/templates/instruments/instrument-live.partial.tmpl b/web/templates/instruments/instrument-live.partial.tmpl index 10a3310..8662536 100644 --- a/web/templates/instruments/instrument-live.partial.tmpl +++ b/web/templates/instruments/instrument-live.partial.tmpl @@ -11,11 +11,10 @@ {{range $camera := $instrument.Cameras}}
{{if eq $camera.Protocol "mjpeg"}} - + {{ + template "shared/videostreams/video-cable-player.partial.tmpl" + (print "/instruments/" $instrument.ID "/cameras/" $camera.ID "/stream") + }} {{else}}
diff --git a/web/templates/shared/base.layout.tmpl b/web/templates/shared/base.layout.tmpl index 7b468f8..7924ef7 100644 --- a/web/templates/shared/base.layout.tmpl +++ b/web/templates/shared/base.layout.tmpl @@ -16,14 +16,12 @@ as="style" rel="preload" href="{{appHashed "theme-light.min.css"}}" - turbo-data-track="reload" > {{block "nav/navbar.assets" .}}{{end}} @@ -48,7 +46,7 @@ - + diff --git a/web/templates/shared/turbo-cable-stream-source.partial.tmpl b/web/templates/shared/turbo-cable-stream-source.partial.tmpl index 72f2d70..460d259 100644 --- a/web/templates/shared/turbo-cable-stream-source.partial.tmpl +++ b/web/templates/shared/turbo-cable-stream-source.partial.tmpl @@ -4,6 +4,7 @@ name="{{.}}" integrity="{{signTurboStream .}}" csrf-token="" - data-csrf-route="/csrf" + csrf-route="/csrf" + websocket-subprotocol="actioncable-v1-msgpack" > diff --git a/web/templates/shared/videostreams/video-cable-player.partial.tmpl b/web/templates/shared/videostreams/video-cable-player.partial.tmpl new file mode 100644 index 0000000..e1589d5 --- /dev/null +++ b/web/templates/shared/videostreams/video-cable-player.partial.tmpl @@ -0,0 +1,17 @@ + + + + +