mirror of https://github.com/usememos/memos.git
refactor: migrate to connect-rpc (#5338)
This commit is contained in:
parent
8af8b9d238
commit
edd3ced9bf
6
go.mod
6
go.mod
|
|
@ -3,6 +3,7 @@ module github.com/usememos/memos
|
|||
go 1.25
|
||||
|
||||
require (
|
||||
connectrpc.com/connect v1.19.1
|
||||
github.com/aws/aws-sdk-go-v2 v1.39.2
|
||||
github.com/aws/aws-sdk-go-v2/config v1.31.12
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.18.16
|
||||
|
|
@ -14,7 +15,6 @@ require (
|
|||
github.com/gorilla/feeds v1.2.0
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2
|
||||
github.com/improbable-eng/grpc-web v0.15.0
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/labstack/echo/v4 v4.13.4
|
||||
github.com/lib/pq v1.10.9
|
||||
|
|
@ -38,8 +38,6 @@ require (
|
|||
cel.dev/expr v0.24.0 // indirect
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||
github.com/desertbit/timer v1.0.1 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.8.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
|
||||
|
|
@ -48,7 +46,6 @@ require (
|
|||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/rogpeppe/go-internal v1.11.0 // indirect
|
||||
github.com/rs/cors v1.11.1 // indirect
|
||||
github.com/sagikazarmark/locafero v0.7.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.12.0 // indirect
|
||||
|
|
@ -64,7 +61,6 @@ require (
|
|||
modernc.org/libc v1.66.8 // indirect
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
modernc.org/memory v1.11.0 // indirect
|
||||
nhooyr.io/websocket v1.8.17 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
|
|
|
|||
383
go.sum
383
go.sum
|
|
@ -1,33 +1,13 @@
|
|||
cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY=
|
||||
cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
connectrpc.com/connect v1.19.1 h1:R5M57z05+90EfEvCY1b7hBxDVOUl45PrtXtAV2fOC14=
|
||||
connectrpc.com/connect v1.19.1/go.mod h1:tN20fjdGlewnSFeZxLKb0xwIZ6ozc3OQs2hTXy4du9w=
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ=
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
||||
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
||||
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
github.com/aws/aws-sdk-go-v2 v1.39.2 h1:EJLg8IdbzgeD7xgvZ+I8M1e0fL0ptn/M47lianzth0I=
|
||||
github.com/aws/aws-sdk-go-v2 v1.39.2/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.1 h1:i8p8P4diljCr60PpJp6qZXNlgX4m2yQFpYk+9ZT+J4E=
|
||||
|
|
@ -67,196 +47,69 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.38.6/go.mod h1:WtKK+ppze5yKPkZ0XwqIV
|
|||
github.com/aws/smithy-go v1.23.0 h1:8n6I3gXzWJB2DxBDnfxgBaSX6oe0d/t10qGz7OKqMCE=
|
||||
github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
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/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE=
|
||||
github.com/desertbit/timer v1.0.1 h1:yRpYNn5Vaaj6QXecdLMPMJsW81JLiI1eokUft5nBmeo=
|
||||
github.com/desertbit/timer v1.0.1/go.mod h1:htRrYeY5V/t4iu1xCJ5XsQvp4xve8QulXXctAzxqcwE=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
||||
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
|
||||
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo=
|
||||
github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
|
||||
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
|
||||
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
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/cel-go v0.26.1 h1:iPbVVEdkhTX++hpe3lzSk7D3G3QSYqLGoHOcEio+UXQ=
|
||||
github.com/google/cel-go v0.26.1/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM=
|
||||
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=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
|
||||
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/feeds v1.2.0 h1:O6pBiXJ5JHhPvqy53NsjKOThq+dNFm8+DFrxBEdzSCc=
|
||||
github.com/gorilla/feeds v1.2.0/go.mod h1:WMib8uJP3BbY+X8Szd1rA5Pzhdfh+HCCAYT2z7Fza6Y=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs=
|
||||
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
||||
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||
github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ=
|
||||
github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
|
|
@ -268,151 +121,50 @@ github.com/labstack/echo/v4 v4.13.4 h1:oTZZW+T3s9gAu5L8vmzihV7/lkXGZuITzTQkTEhcX
|
|||
github.com/labstack/echo/v4 v4.13.4/go.mod h1:g63b33BZ5vZzcIUF8AtRH40DrTlXnx4UMC8rBdndmjQ=
|
||||
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
||||
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
|
||||
github.com/lithammer/shortuuid/v4 v4.2.0 h1:LMFOzVB3996a7b8aBuEXxqOBflbfPQAiVzkIcHO0h8c=
|
||||
github.com/lithammer/shortuuid/v4 v4.2.0/go.mod h1:D5noHZ2oFw/YaKCfGy0YxyE7M0wMbezmMjPdhyEFe6Y=
|
||||
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
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=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo=
|
||||
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
||||
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
|
||||
github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
|
||||
github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
|
||||
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
||||
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
||||
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
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=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
|
||||
github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo=
|
||||
github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k=
|
||||
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
|
||||
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
|
||||
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||
github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
|
||||
github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
|
||||
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
|
||||
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
|
||||
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
|
||||
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4=
|
||||
github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4=
|
||||
github.com/stoewer/go-strcase v1.3.1 h1:iS0MdW+kVTxgMoE1LAZyMiYJFKlOzLooE4MxjirtkAs=
|
||||
github.com/stoewer/go-strcase v1.3.1/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
|
||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
|
|
@ -428,25 +180,14 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
|
|||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.7.13 h1:GPddIs617DnBLFFVJFgpo1aBfe/4xcvMc3SB5t/D0pA=
|
||||
github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
|
||||
|
|
@ -459,150 +200,76 @@ go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFh
|
|||
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
|
||||
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
||||
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
|
||||
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI=
|
||||
golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
|
||||
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-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b h1:DXr+pvt3nC887026GRP39Ej11UATqWDmWuS99x26cD0=
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.30.0 h1:jD5RhkmVAnjqaCUXfbGBrn3lpxbknfN9w2UhHHU+5B4=
|
||||
golang.org/x/image v0.30.0/go.mod h1:SAEUTxCCMWSrJcCy/4HwavEsfZZJlYxeHLc6tTiAe/c=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
|
||||
golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
|
||||
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=
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||
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.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
||||
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=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
|
||||
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
|
||||
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
|
||||
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/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.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
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=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
|
||||
|
|
@ -613,77 +280,36 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
|
|||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
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=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250826171959-ef028d996bc1 h1:APHvLLYBhtZvsbnpkfknDZ7NyH4z5+ub/I0u8L3Oz6g=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250826171959-ef028d996bc1/go.mod h1:xUjFWUnWDpZ/C0Gu0qloASKFb6f8/QXiiXhSPFsD668=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1 h1:pmJpJEvT846VzausCQ5d7KreSROcDqmO388w5YbnltA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250826171959-ef028d996bc1/go.mod h1:GmFNa4BdJZ2a8G+wCe9Bg3wwThLrJun751XstdJt5Og=
|
||||
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=
|
||||
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI=
|
||||
google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
|
||||
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=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
|
||||
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
modernc.org/cc/v4 v4.26.4 h1:jPhG8oNjtTYuP2FA4YefTJ/wioNUGALmGuEWt7SUR6s=
|
||||
modernc.org/cc/v4 v4.26.4/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
|
||||
modernc.org/ccgo/v4 v4.28.1 h1:wPKYn5EC/mYTqBO373jKjvX2n+3+aK7+sICCv4Fjy1A=
|
||||
|
|
@ -710,8 +336,3 @@ modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
|
|||
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
|
||||
nhooyr.io/websocket v1.8.17 h1:KEVeLJkUywCKVsnLIDlD/5gtayKp8VoCkksHCGGfT9Y=
|
||||
nhooyr.io/websocket v1.8.17/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
||||
|
|
|
|||
|
|
@ -7,6 +7,15 @@ managed:
|
|||
override:
|
||||
- file_option: go_package_prefix
|
||||
value: github.com/usememos/memos/proto/gen
|
||||
inputs:
|
||||
- directory: .
|
||||
- module: buf.build/googleapis/googleapis
|
||||
paths:
|
||||
- google/api/annotations.proto
|
||||
- google/api/client.proto
|
||||
- google/api/field_behavior.proto
|
||||
- google/api/http.proto
|
||||
- google/api/resource.proto
|
||||
plugins:
|
||||
- remote: buf.build/protocolbuffers/go
|
||||
out: gen
|
||||
|
|
@ -14,19 +23,17 @@ plugins:
|
|||
- remote: buf.build/grpc/go
|
||||
out: gen
|
||||
opt: paths=source_relative
|
||||
- remote: buf.build/connectrpc/go
|
||||
out: gen
|
||||
opt: paths=source_relative
|
||||
- remote: buf.build/grpc-ecosystem/gateway
|
||||
out: gen
|
||||
opt: paths=source_relative
|
||||
- remote: buf.build/community/google-gnostic-openapi
|
||||
out: gen
|
||||
opt: paths=source_relative,enum_type=string
|
||||
- remote: buf.build/community/stephenh-ts-proto
|
||||
- remote: buf.build/bufbuild/es
|
||||
out: ../web/src/types/proto
|
||||
opt:
|
||||
- env=browser
|
||||
- useOptionals=messages
|
||||
- outputServices=generic-definitions
|
||||
- outputJsonMethods=false
|
||||
- useExactTypes=false
|
||||
- esModuleInterop=true
|
||||
- stringEnums=true
|
||||
- target=ts
|
||||
include_imports: true
|
||||
|
|
|
|||
|
|
@ -0,0 +1,142 @@
|
|||
// Code generated by protoc-gen-connect-go. DO NOT EDIT.
|
||||
//
|
||||
// Source: api/v1/activity_service.proto
|
||||
|
||||
package apiv1connect
|
||||
|
||||
import (
|
||||
connect "connectrpc.com/connect"
|
||||
context "context"
|
||||
errors "errors"
|
||||
v1 "github.com/usememos/memos/proto/gen/api/v1"
|
||||
http "net/http"
|
||||
strings "strings"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file and the connect package are
|
||||
// compatible. If you get a compiler error that this constant is not defined, this code was
|
||||
// generated with a version of connect newer than the one compiled into your binary. You can fix the
|
||||
// problem by either regenerating this code with an older version of connect or updating the connect
|
||||
// version compiled into your binary.
|
||||
const _ = connect.IsAtLeastVersion1_13_0
|
||||
|
||||
const (
|
||||
// ActivityServiceName is the fully-qualified name of the ActivityService service.
|
||||
ActivityServiceName = "memos.api.v1.ActivityService"
|
||||
)
|
||||
|
||||
// These constants are the fully-qualified names of the RPCs defined in this package. They're
|
||||
// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
|
||||
//
|
||||
// Note that these are different from the fully-qualified method names used by
|
||||
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
|
||||
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
|
||||
// period.
|
||||
const (
|
||||
// ActivityServiceListActivitiesProcedure is the fully-qualified name of the ActivityService's
|
||||
// ListActivities RPC.
|
||||
ActivityServiceListActivitiesProcedure = "/memos.api.v1.ActivityService/ListActivities"
|
||||
// ActivityServiceGetActivityProcedure is the fully-qualified name of the ActivityService's
|
||||
// GetActivity RPC.
|
||||
ActivityServiceGetActivityProcedure = "/memos.api.v1.ActivityService/GetActivity"
|
||||
)
|
||||
|
||||
// ActivityServiceClient is a client for the memos.api.v1.ActivityService service.
|
||||
type ActivityServiceClient interface {
|
||||
// ListActivities returns a list of activities.
|
||||
ListActivities(context.Context, *connect.Request[v1.ListActivitiesRequest]) (*connect.Response[v1.ListActivitiesResponse], error)
|
||||
// GetActivity returns the activity with the given id.
|
||||
GetActivity(context.Context, *connect.Request[v1.GetActivityRequest]) (*connect.Response[v1.Activity], error)
|
||||
}
|
||||
|
||||
// NewActivityServiceClient constructs a client for the memos.api.v1.ActivityService service. By
|
||||
// default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses,
|
||||
// and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the
|
||||
// connect.WithGRPC() or connect.WithGRPCWeb() options.
|
||||
//
|
||||
// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
|
||||
// http://api.acme.com or https://acme.com/grpc).
|
||||
func NewActivityServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) ActivityServiceClient {
|
||||
baseURL = strings.TrimRight(baseURL, "/")
|
||||
activityServiceMethods := v1.File_api_v1_activity_service_proto.Services().ByName("ActivityService").Methods()
|
||||
return &activityServiceClient{
|
||||
listActivities: connect.NewClient[v1.ListActivitiesRequest, v1.ListActivitiesResponse](
|
||||
httpClient,
|
||||
baseURL+ActivityServiceListActivitiesProcedure,
|
||||
connect.WithSchema(activityServiceMethods.ByName("ListActivities")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
getActivity: connect.NewClient[v1.GetActivityRequest, v1.Activity](
|
||||
httpClient,
|
||||
baseURL+ActivityServiceGetActivityProcedure,
|
||||
connect.WithSchema(activityServiceMethods.ByName("GetActivity")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// activityServiceClient implements ActivityServiceClient.
|
||||
type activityServiceClient struct {
|
||||
listActivities *connect.Client[v1.ListActivitiesRequest, v1.ListActivitiesResponse]
|
||||
getActivity *connect.Client[v1.GetActivityRequest, v1.Activity]
|
||||
}
|
||||
|
||||
// ListActivities calls memos.api.v1.ActivityService.ListActivities.
|
||||
func (c *activityServiceClient) ListActivities(ctx context.Context, req *connect.Request[v1.ListActivitiesRequest]) (*connect.Response[v1.ListActivitiesResponse], error) {
|
||||
return c.listActivities.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// GetActivity calls memos.api.v1.ActivityService.GetActivity.
|
||||
func (c *activityServiceClient) GetActivity(ctx context.Context, req *connect.Request[v1.GetActivityRequest]) (*connect.Response[v1.Activity], error) {
|
||||
return c.getActivity.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// ActivityServiceHandler is an implementation of the memos.api.v1.ActivityService service.
|
||||
type ActivityServiceHandler interface {
|
||||
// ListActivities returns a list of activities.
|
||||
ListActivities(context.Context, *connect.Request[v1.ListActivitiesRequest]) (*connect.Response[v1.ListActivitiesResponse], error)
|
||||
// GetActivity returns the activity with the given id.
|
||||
GetActivity(context.Context, *connect.Request[v1.GetActivityRequest]) (*connect.Response[v1.Activity], error)
|
||||
}
|
||||
|
||||
// NewActivityServiceHandler builds an HTTP handler from the service implementation. It returns the
|
||||
// path on which to mount the handler and the handler itself.
|
||||
//
|
||||
// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
|
||||
// and JSON codecs. They also support gzip compression.
|
||||
func NewActivityServiceHandler(svc ActivityServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
|
||||
activityServiceMethods := v1.File_api_v1_activity_service_proto.Services().ByName("ActivityService").Methods()
|
||||
activityServiceListActivitiesHandler := connect.NewUnaryHandler(
|
||||
ActivityServiceListActivitiesProcedure,
|
||||
svc.ListActivities,
|
||||
connect.WithSchema(activityServiceMethods.ByName("ListActivities")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
activityServiceGetActivityHandler := connect.NewUnaryHandler(
|
||||
ActivityServiceGetActivityProcedure,
|
||||
svc.GetActivity,
|
||||
connect.WithSchema(activityServiceMethods.ByName("GetActivity")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
return "/memos.api.v1.ActivityService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case ActivityServiceListActivitiesProcedure:
|
||||
activityServiceListActivitiesHandler.ServeHTTP(w, r)
|
||||
case ActivityServiceGetActivityProcedure:
|
||||
activityServiceGetActivityHandler.ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// UnimplementedActivityServiceHandler returns CodeUnimplemented from all methods.
|
||||
type UnimplementedActivityServiceHandler struct{}
|
||||
|
||||
func (UnimplementedActivityServiceHandler) ListActivities(context.Context, *connect.Request[v1.ListActivitiesRequest]) (*connect.Response[v1.ListActivitiesResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.ActivityService.ListActivities is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedActivityServiceHandler) GetActivity(context.Context, *connect.Request[v1.GetActivityRequest]) (*connect.Response[v1.Activity], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.ActivityService.GetActivity is not implemented"))
|
||||
}
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
// Code generated by protoc-gen-connect-go. DO NOT EDIT.
|
||||
//
|
||||
// Source: api/v1/attachment_service.proto
|
||||
|
||||
package apiv1connect
|
||||
|
||||
import (
|
||||
connect "connectrpc.com/connect"
|
||||
context "context"
|
||||
errors "errors"
|
||||
v1 "github.com/usememos/memos/proto/gen/api/v1"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
http "net/http"
|
||||
strings "strings"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file and the connect package are
|
||||
// compatible. If you get a compiler error that this constant is not defined, this code was
|
||||
// generated with a version of connect newer than the one compiled into your binary. You can fix the
|
||||
// problem by either regenerating this code with an older version of connect or updating the connect
|
||||
// version compiled into your binary.
|
||||
const _ = connect.IsAtLeastVersion1_13_0
|
||||
|
||||
const (
|
||||
// AttachmentServiceName is the fully-qualified name of the AttachmentService service.
|
||||
AttachmentServiceName = "memos.api.v1.AttachmentService"
|
||||
)
|
||||
|
||||
// These constants are the fully-qualified names of the RPCs defined in this package. They're
|
||||
// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
|
||||
//
|
||||
// Note that these are different from the fully-qualified method names used by
|
||||
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
|
||||
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
|
||||
// period.
|
||||
const (
|
||||
// AttachmentServiceCreateAttachmentProcedure is the fully-qualified name of the AttachmentService's
|
||||
// CreateAttachment RPC.
|
||||
AttachmentServiceCreateAttachmentProcedure = "/memos.api.v1.AttachmentService/CreateAttachment"
|
||||
// AttachmentServiceListAttachmentsProcedure is the fully-qualified name of the AttachmentService's
|
||||
// ListAttachments RPC.
|
||||
AttachmentServiceListAttachmentsProcedure = "/memos.api.v1.AttachmentService/ListAttachments"
|
||||
// AttachmentServiceGetAttachmentProcedure is the fully-qualified name of the AttachmentService's
|
||||
// GetAttachment RPC.
|
||||
AttachmentServiceGetAttachmentProcedure = "/memos.api.v1.AttachmentService/GetAttachment"
|
||||
// AttachmentServiceUpdateAttachmentProcedure is the fully-qualified name of the AttachmentService's
|
||||
// UpdateAttachment RPC.
|
||||
AttachmentServiceUpdateAttachmentProcedure = "/memos.api.v1.AttachmentService/UpdateAttachment"
|
||||
// AttachmentServiceDeleteAttachmentProcedure is the fully-qualified name of the AttachmentService's
|
||||
// DeleteAttachment RPC.
|
||||
AttachmentServiceDeleteAttachmentProcedure = "/memos.api.v1.AttachmentService/DeleteAttachment"
|
||||
)
|
||||
|
||||
// AttachmentServiceClient is a client for the memos.api.v1.AttachmentService service.
|
||||
type AttachmentServiceClient interface {
|
||||
// CreateAttachment creates a new attachment.
|
||||
CreateAttachment(context.Context, *connect.Request[v1.CreateAttachmentRequest]) (*connect.Response[v1.Attachment], error)
|
||||
// ListAttachments lists all attachments.
|
||||
ListAttachments(context.Context, *connect.Request[v1.ListAttachmentsRequest]) (*connect.Response[v1.ListAttachmentsResponse], error)
|
||||
// GetAttachment returns a attachment by name.
|
||||
GetAttachment(context.Context, *connect.Request[v1.GetAttachmentRequest]) (*connect.Response[v1.Attachment], error)
|
||||
// UpdateAttachment updates a attachment.
|
||||
UpdateAttachment(context.Context, *connect.Request[v1.UpdateAttachmentRequest]) (*connect.Response[v1.Attachment], error)
|
||||
// DeleteAttachment deletes a attachment by name.
|
||||
DeleteAttachment(context.Context, *connect.Request[v1.DeleteAttachmentRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
}
|
||||
|
||||
// NewAttachmentServiceClient constructs a client for the memos.api.v1.AttachmentService service. By
|
||||
// default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses,
|
||||
// and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the
|
||||
// connect.WithGRPC() or connect.WithGRPCWeb() options.
|
||||
//
|
||||
// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
|
||||
// http://api.acme.com or https://acme.com/grpc).
|
||||
func NewAttachmentServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) AttachmentServiceClient {
|
||||
baseURL = strings.TrimRight(baseURL, "/")
|
||||
attachmentServiceMethods := v1.File_api_v1_attachment_service_proto.Services().ByName("AttachmentService").Methods()
|
||||
return &attachmentServiceClient{
|
||||
createAttachment: connect.NewClient[v1.CreateAttachmentRequest, v1.Attachment](
|
||||
httpClient,
|
||||
baseURL+AttachmentServiceCreateAttachmentProcedure,
|
||||
connect.WithSchema(attachmentServiceMethods.ByName("CreateAttachment")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
listAttachments: connect.NewClient[v1.ListAttachmentsRequest, v1.ListAttachmentsResponse](
|
||||
httpClient,
|
||||
baseURL+AttachmentServiceListAttachmentsProcedure,
|
||||
connect.WithSchema(attachmentServiceMethods.ByName("ListAttachments")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
getAttachment: connect.NewClient[v1.GetAttachmentRequest, v1.Attachment](
|
||||
httpClient,
|
||||
baseURL+AttachmentServiceGetAttachmentProcedure,
|
||||
connect.WithSchema(attachmentServiceMethods.ByName("GetAttachment")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
updateAttachment: connect.NewClient[v1.UpdateAttachmentRequest, v1.Attachment](
|
||||
httpClient,
|
||||
baseURL+AttachmentServiceUpdateAttachmentProcedure,
|
||||
connect.WithSchema(attachmentServiceMethods.ByName("UpdateAttachment")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
deleteAttachment: connect.NewClient[v1.DeleteAttachmentRequest, emptypb.Empty](
|
||||
httpClient,
|
||||
baseURL+AttachmentServiceDeleteAttachmentProcedure,
|
||||
connect.WithSchema(attachmentServiceMethods.ByName("DeleteAttachment")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// attachmentServiceClient implements AttachmentServiceClient.
|
||||
type attachmentServiceClient struct {
|
||||
createAttachment *connect.Client[v1.CreateAttachmentRequest, v1.Attachment]
|
||||
listAttachments *connect.Client[v1.ListAttachmentsRequest, v1.ListAttachmentsResponse]
|
||||
getAttachment *connect.Client[v1.GetAttachmentRequest, v1.Attachment]
|
||||
updateAttachment *connect.Client[v1.UpdateAttachmentRequest, v1.Attachment]
|
||||
deleteAttachment *connect.Client[v1.DeleteAttachmentRequest, emptypb.Empty]
|
||||
}
|
||||
|
||||
// CreateAttachment calls memos.api.v1.AttachmentService.CreateAttachment.
|
||||
func (c *attachmentServiceClient) CreateAttachment(ctx context.Context, req *connect.Request[v1.CreateAttachmentRequest]) (*connect.Response[v1.Attachment], error) {
|
||||
return c.createAttachment.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// ListAttachments calls memos.api.v1.AttachmentService.ListAttachments.
|
||||
func (c *attachmentServiceClient) ListAttachments(ctx context.Context, req *connect.Request[v1.ListAttachmentsRequest]) (*connect.Response[v1.ListAttachmentsResponse], error) {
|
||||
return c.listAttachments.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// GetAttachment calls memos.api.v1.AttachmentService.GetAttachment.
|
||||
func (c *attachmentServiceClient) GetAttachment(ctx context.Context, req *connect.Request[v1.GetAttachmentRequest]) (*connect.Response[v1.Attachment], error) {
|
||||
return c.getAttachment.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// UpdateAttachment calls memos.api.v1.AttachmentService.UpdateAttachment.
|
||||
func (c *attachmentServiceClient) UpdateAttachment(ctx context.Context, req *connect.Request[v1.UpdateAttachmentRequest]) (*connect.Response[v1.Attachment], error) {
|
||||
return c.updateAttachment.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// DeleteAttachment calls memos.api.v1.AttachmentService.DeleteAttachment.
|
||||
func (c *attachmentServiceClient) DeleteAttachment(ctx context.Context, req *connect.Request[v1.DeleteAttachmentRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return c.deleteAttachment.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// AttachmentServiceHandler is an implementation of the memos.api.v1.AttachmentService service.
|
||||
type AttachmentServiceHandler interface {
|
||||
// CreateAttachment creates a new attachment.
|
||||
CreateAttachment(context.Context, *connect.Request[v1.CreateAttachmentRequest]) (*connect.Response[v1.Attachment], error)
|
||||
// ListAttachments lists all attachments.
|
||||
ListAttachments(context.Context, *connect.Request[v1.ListAttachmentsRequest]) (*connect.Response[v1.ListAttachmentsResponse], error)
|
||||
// GetAttachment returns a attachment by name.
|
||||
GetAttachment(context.Context, *connect.Request[v1.GetAttachmentRequest]) (*connect.Response[v1.Attachment], error)
|
||||
// UpdateAttachment updates a attachment.
|
||||
UpdateAttachment(context.Context, *connect.Request[v1.UpdateAttachmentRequest]) (*connect.Response[v1.Attachment], error)
|
||||
// DeleteAttachment deletes a attachment by name.
|
||||
DeleteAttachment(context.Context, *connect.Request[v1.DeleteAttachmentRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
}
|
||||
|
||||
// NewAttachmentServiceHandler builds an HTTP handler from the service implementation. It returns
|
||||
// the path on which to mount the handler and the handler itself.
|
||||
//
|
||||
// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
|
||||
// and JSON codecs. They also support gzip compression.
|
||||
func NewAttachmentServiceHandler(svc AttachmentServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
|
||||
attachmentServiceMethods := v1.File_api_v1_attachment_service_proto.Services().ByName("AttachmentService").Methods()
|
||||
attachmentServiceCreateAttachmentHandler := connect.NewUnaryHandler(
|
||||
AttachmentServiceCreateAttachmentProcedure,
|
||||
svc.CreateAttachment,
|
||||
connect.WithSchema(attachmentServiceMethods.ByName("CreateAttachment")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
attachmentServiceListAttachmentsHandler := connect.NewUnaryHandler(
|
||||
AttachmentServiceListAttachmentsProcedure,
|
||||
svc.ListAttachments,
|
||||
connect.WithSchema(attachmentServiceMethods.ByName("ListAttachments")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
attachmentServiceGetAttachmentHandler := connect.NewUnaryHandler(
|
||||
AttachmentServiceGetAttachmentProcedure,
|
||||
svc.GetAttachment,
|
||||
connect.WithSchema(attachmentServiceMethods.ByName("GetAttachment")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
attachmentServiceUpdateAttachmentHandler := connect.NewUnaryHandler(
|
||||
AttachmentServiceUpdateAttachmentProcedure,
|
||||
svc.UpdateAttachment,
|
||||
connect.WithSchema(attachmentServiceMethods.ByName("UpdateAttachment")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
attachmentServiceDeleteAttachmentHandler := connect.NewUnaryHandler(
|
||||
AttachmentServiceDeleteAttachmentProcedure,
|
||||
svc.DeleteAttachment,
|
||||
connect.WithSchema(attachmentServiceMethods.ByName("DeleteAttachment")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
return "/memos.api.v1.AttachmentService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case AttachmentServiceCreateAttachmentProcedure:
|
||||
attachmentServiceCreateAttachmentHandler.ServeHTTP(w, r)
|
||||
case AttachmentServiceListAttachmentsProcedure:
|
||||
attachmentServiceListAttachmentsHandler.ServeHTTP(w, r)
|
||||
case AttachmentServiceGetAttachmentProcedure:
|
||||
attachmentServiceGetAttachmentHandler.ServeHTTP(w, r)
|
||||
case AttachmentServiceUpdateAttachmentProcedure:
|
||||
attachmentServiceUpdateAttachmentHandler.ServeHTTP(w, r)
|
||||
case AttachmentServiceDeleteAttachmentProcedure:
|
||||
attachmentServiceDeleteAttachmentHandler.ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// UnimplementedAttachmentServiceHandler returns CodeUnimplemented from all methods.
|
||||
type UnimplementedAttachmentServiceHandler struct{}
|
||||
|
||||
func (UnimplementedAttachmentServiceHandler) CreateAttachment(context.Context, *connect.Request[v1.CreateAttachmentRequest]) (*connect.Response[v1.Attachment], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.AttachmentService.CreateAttachment is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAttachmentServiceHandler) ListAttachments(context.Context, *connect.Request[v1.ListAttachmentsRequest]) (*connect.Response[v1.ListAttachmentsResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.AttachmentService.ListAttachments is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAttachmentServiceHandler) GetAttachment(context.Context, *connect.Request[v1.GetAttachmentRequest]) (*connect.Response[v1.Attachment], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.AttachmentService.GetAttachment is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAttachmentServiceHandler) UpdateAttachment(context.Context, *connect.Request[v1.UpdateAttachmentRequest]) (*connect.Response[v1.Attachment], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.AttachmentService.UpdateAttachment is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAttachmentServiceHandler) DeleteAttachment(context.Context, *connect.Request[v1.DeleteAttachmentRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.AttachmentService.DeleteAttachment is not implemented"))
|
||||
}
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
// Code generated by protoc-gen-connect-go. DO NOT EDIT.
|
||||
//
|
||||
// Source: api/v1/auth_service.proto
|
||||
|
||||
package apiv1connect
|
||||
|
||||
import (
|
||||
connect "connectrpc.com/connect"
|
||||
context "context"
|
||||
errors "errors"
|
||||
v1 "github.com/usememos/memos/proto/gen/api/v1"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
http "net/http"
|
||||
strings "strings"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file and the connect package are
|
||||
// compatible. If you get a compiler error that this constant is not defined, this code was
|
||||
// generated with a version of connect newer than the one compiled into your binary. You can fix the
|
||||
// problem by either regenerating this code with an older version of connect or updating the connect
|
||||
// version compiled into your binary.
|
||||
const _ = connect.IsAtLeastVersion1_13_0
|
||||
|
||||
const (
|
||||
// AuthServiceName is the fully-qualified name of the AuthService service.
|
||||
AuthServiceName = "memos.api.v1.AuthService"
|
||||
)
|
||||
|
||||
// These constants are the fully-qualified names of the RPCs defined in this package. They're
|
||||
// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
|
||||
//
|
||||
// Note that these are different from the fully-qualified method names used by
|
||||
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
|
||||
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
|
||||
// period.
|
||||
const (
|
||||
// AuthServiceGetCurrentSessionProcedure is the fully-qualified name of the AuthService's
|
||||
// GetCurrentSession RPC.
|
||||
AuthServiceGetCurrentSessionProcedure = "/memos.api.v1.AuthService/GetCurrentSession"
|
||||
// AuthServiceCreateSessionProcedure is the fully-qualified name of the AuthService's CreateSession
|
||||
// RPC.
|
||||
AuthServiceCreateSessionProcedure = "/memos.api.v1.AuthService/CreateSession"
|
||||
// AuthServiceDeleteSessionProcedure is the fully-qualified name of the AuthService's DeleteSession
|
||||
// RPC.
|
||||
AuthServiceDeleteSessionProcedure = "/memos.api.v1.AuthService/DeleteSession"
|
||||
)
|
||||
|
||||
// AuthServiceClient is a client for the memos.api.v1.AuthService service.
|
||||
type AuthServiceClient interface {
|
||||
// GetCurrentSession returns the current active session information.
|
||||
// This method is idempotent and safe, suitable for checking current session state.
|
||||
GetCurrentSession(context.Context, *connect.Request[v1.GetCurrentSessionRequest]) (*connect.Response[v1.GetCurrentSessionResponse], error)
|
||||
// CreateSession authenticates a user and creates a new session.
|
||||
// Returns the authenticated user information upon successful authentication.
|
||||
CreateSession(context.Context, *connect.Request[v1.CreateSessionRequest]) (*connect.Response[v1.CreateSessionResponse], error)
|
||||
// DeleteSession terminates the current user session.
|
||||
// This is an idempotent operation that invalidates the user's authentication.
|
||||
DeleteSession(context.Context, *connect.Request[v1.DeleteSessionRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
}
|
||||
|
||||
// NewAuthServiceClient constructs a client for the memos.api.v1.AuthService service. By default, it
|
||||
// uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and sends
|
||||
// uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or
|
||||
// connect.WithGRPCWeb() options.
|
||||
//
|
||||
// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
|
||||
// http://api.acme.com or https://acme.com/grpc).
|
||||
func NewAuthServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) AuthServiceClient {
|
||||
baseURL = strings.TrimRight(baseURL, "/")
|
||||
authServiceMethods := v1.File_api_v1_auth_service_proto.Services().ByName("AuthService").Methods()
|
||||
return &authServiceClient{
|
||||
getCurrentSession: connect.NewClient[v1.GetCurrentSessionRequest, v1.GetCurrentSessionResponse](
|
||||
httpClient,
|
||||
baseURL+AuthServiceGetCurrentSessionProcedure,
|
||||
connect.WithSchema(authServiceMethods.ByName("GetCurrentSession")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
createSession: connect.NewClient[v1.CreateSessionRequest, v1.CreateSessionResponse](
|
||||
httpClient,
|
||||
baseURL+AuthServiceCreateSessionProcedure,
|
||||
connect.WithSchema(authServiceMethods.ByName("CreateSession")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
deleteSession: connect.NewClient[v1.DeleteSessionRequest, emptypb.Empty](
|
||||
httpClient,
|
||||
baseURL+AuthServiceDeleteSessionProcedure,
|
||||
connect.WithSchema(authServiceMethods.ByName("DeleteSession")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// authServiceClient implements AuthServiceClient.
|
||||
type authServiceClient struct {
|
||||
getCurrentSession *connect.Client[v1.GetCurrentSessionRequest, v1.GetCurrentSessionResponse]
|
||||
createSession *connect.Client[v1.CreateSessionRequest, v1.CreateSessionResponse]
|
||||
deleteSession *connect.Client[v1.DeleteSessionRequest, emptypb.Empty]
|
||||
}
|
||||
|
||||
// GetCurrentSession calls memos.api.v1.AuthService.GetCurrentSession.
|
||||
func (c *authServiceClient) GetCurrentSession(ctx context.Context, req *connect.Request[v1.GetCurrentSessionRequest]) (*connect.Response[v1.GetCurrentSessionResponse], error) {
|
||||
return c.getCurrentSession.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// CreateSession calls memos.api.v1.AuthService.CreateSession.
|
||||
func (c *authServiceClient) CreateSession(ctx context.Context, req *connect.Request[v1.CreateSessionRequest]) (*connect.Response[v1.CreateSessionResponse], error) {
|
||||
return c.createSession.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// DeleteSession calls memos.api.v1.AuthService.DeleteSession.
|
||||
func (c *authServiceClient) DeleteSession(ctx context.Context, req *connect.Request[v1.DeleteSessionRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return c.deleteSession.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// AuthServiceHandler is an implementation of the memos.api.v1.AuthService service.
|
||||
type AuthServiceHandler interface {
|
||||
// GetCurrentSession returns the current active session information.
|
||||
// This method is idempotent and safe, suitable for checking current session state.
|
||||
GetCurrentSession(context.Context, *connect.Request[v1.GetCurrentSessionRequest]) (*connect.Response[v1.GetCurrentSessionResponse], error)
|
||||
// CreateSession authenticates a user and creates a new session.
|
||||
// Returns the authenticated user information upon successful authentication.
|
||||
CreateSession(context.Context, *connect.Request[v1.CreateSessionRequest]) (*connect.Response[v1.CreateSessionResponse], error)
|
||||
// DeleteSession terminates the current user session.
|
||||
// This is an idempotent operation that invalidates the user's authentication.
|
||||
DeleteSession(context.Context, *connect.Request[v1.DeleteSessionRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
}
|
||||
|
||||
// NewAuthServiceHandler builds an HTTP handler from the service implementation. It returns the path
|
||||
// on which to mount the handler and the handler itself.
|
||||
//
|
||||
// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
|
||||
// and JSON codecs. They also support gzip compression.
|
||||
func NewAuthServiceHandler(svc AuthServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
|
||||
authServiceMethods := v1.File_api_v1_auth_service_proto.Services().ByName("AuthService").Methods()
|
||||
authServiceGetCurrentSessionHandler := connect.NewUnaryHandler(
|
||||
AuthServiceGetCurrentSessionProcedure,
|
||||
svc.GetCurrentSession,
|
||||
connect.WithSchema(authServiceMethods.ByName("GetCurrentSession")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
authServiceCreateSessionHandler := connect.NewUnaryHandler(
|
||||
AuthServiceCreateSessionProcedure,
|
||||
svc.CreateSession,
|
||||
connect.WithSchema(authServiceMethods.ByName("CreateSession")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
authServiceDeleteSessionHandler := connect.NewUnaryHandler(
|
||||
AuthServiceDeleteSessionProcedure,
|
||||
svc.DeleteSession,
|
||||
connect.WithSchema(authServiceMethods.ByName("DeleteSession")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
return "/memos.api.v1.AuthService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case AuthServiceGetCurrentSessionProcedure:
|
||||
authServiceGetCurrentSessionHandler.ServeHTTP(w, r)
|
||||
case AuthServiceCreateSessionProcedure:
|
||||
authServiceCreateSessionHandler.ServeHTTP(w, r)
|
||||
case AuthServiceDeleteSessionProcedure:
|
||||
authServiceDeleteSessionHandler.ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// UnimplementedAuthServiceHandler returns CodeUnimplemented from all methods.
|
||||
type UnimplementedAuthServiceHandler struct{}
|
||||
|
||||
func (UnimplementedAuthServiceHandler) GetCurrentSession(context.Context, *connect.Request[v1.GetCurrentSessionRequest]) (*connect.Response[v1.GetCurrentSessionResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.AuthService.GetCurrentSession is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAuthServiceHandler) CreateSession(context.Context, *connect.Request[v1.CreateSessionRequest]) (*connect.Response[v1.CreateSessionResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.AuthService.CreateSession is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedAuthServiceHandler) DeleteSession(context.Context, *connect.Request[v1.DeleteSessionRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.AuthService.DeleteSession is not implemented"))
|
||||
}
|
||||
|
|
@ -0,0 +1,237 @@
|
|||
// Code generated by protoc-gen-connect-go. DO NOT EDIT.
|
||||
//
|
||||
// Source: api/v1/idp_service.proto
|
||||
|
||||
package apiv1connect
|
||||
|
||||
import (
|
||||
connect "connectrpc.com/connect"
|
||||
context "context"
|
||||
errors "errors"
|
||||
v1 "github.com/usememos/memos/proto/gen/api/v1"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
http "net/http"
|
||||
strings "strings"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file and the connect package are
|
||||
// compatible. If you get a compiler error that this constant is not defined, this code was
|
||||
// generated with a version of connect newer than the one compiled into your binary. You can fix the
|
||||
// problem by either regenerating this code with an older version of connect or updating the connect
|
||||
// version compiled into your binary.
|
||||
const _ = connect.IsAtLeastVersion1_13_0
|
||||
|
||||
const (
|
||||
// IdentityProviderServiceName is the fully-qualified name of the IdentityProviderService service.
|
||||
IdentityProviderServiceName = "memos.api.v1.IdentityProviderService"
|
||||
)
|
||||
|
||||
// These constants are the fully-qualified names of the RPCs defined in this package. They're
|
||||
// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
|
||||
//
|
||||
// Note that these are different from the fully-qualified method names used by
|
||||
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
|
||||
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
|
||||
// period.
|
||||
const (
|
||||
// IdentityProviderServiceListIdentityProvidersProcedure is the fully-qualified name of the
|
||||
// IdentityProviderService's ListIdentityProviders RPC.
|
||||
IdentityProviderServiceListIdentityProvidersProcedure = "/memos.api.v1.IdentityProviderService/ListIdentityProviders"
|
||||
// IdentityProviderServiceGetIdentityProviderProcedure is the fully-qualified name of the
|
||||
// IdentityProviderService's GetIdentityProvider RPC.
|
||||
IdentityProviderServiceGetIdentityProviderProcedure = "/memos.api.v1.IdentityProviderService/GetIdentityProvider"
|
||||
// IdentityProviderServiceCreateIdentityProviderProcedure is the fully-qualified name of the
|
||||
// IdentityProviderService's CreateIdentityProvider RPC.
|
||||
IdentityProviderServiceCreateIdentityProviderProcedure = "/memos.api.v1.IdentityProviderService/CreateIdentityProvider"
|
||||
// IdentityProviderServiceUpdateIdentityProviderProcedure is the fully-qualified name of the
|
||||
// IdentityProviderService's UpdateIdentityProvider RPC.
|
||||
IdentityProviderServiceUpdateIdentityProviderProcedure = "/memos.api.v1.IdentityProviderService/UpdateIdentityProvider"
|
||||
// IdentityProviderServiceDeleteIdentityProviderProcedure is the fully-qualified name of the
|
||||
// IdentityProviderService's DeleteIdentityProvider RPC.
|
||||
IdentityProviderServiceDeleteIdentityProviderProcedure = "/memos.api.v1.IdentityProviderService/DeleteIdentityProvider"
|
||||
)
|
||||
|
||||
// IdentityProviderServiceClient is a client for the memos.api.v1.IdentityProviderService service.
|
||||
type IdentityProviderServiceClient interface {
|
||||
// ListIdentityProviders lists identity providers.
|
||||
ListIdentityProviders(context.Context, *connect.Request[v1.ListIdentityProvidersRequest]) (*connect.Response[v1.ListIdentityProvidersResponse], error)
|
||||
// GetIdentityProvider gets an identity provider.
|
||||
GetIdentityProvider(context.Context, *connect.Request[v1.GetIdentityProviderRequest]) (*connect.Response[v1.IdentityProvider], error)
|
||||
// CreateIdentityProvider creates an identity provider.
|
||||
CreateIdentityProvider(context.Context, *connect.Request[v1.CreateIdentityProviderRequest]) (*connect.Response[v1.IdentityProvider], error)
|
||||
// UpdateIdentityProvider updates an identity provider.
|
||||
UpdateIdentityProvider(context.Context, *connect.Request[v1.UpdateIdentityProviderRequest]) (*connect.Response[v1.IdentityProvider], error)
|
||||
// DeleteIdentityProvider deletes an identity provider.
|
||||
DeleteIdentityProvider(context.Context, *connect.Request[v1.DeleteIdentityProviderRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
}
|
||||
|
||||
// NewIdentityProviderServiceClient constructs a client for the memos.api.v1.IdentityProviderService
|
||||
// service. By default, it uses the Connect protocol with the binary Protobuf Codec, asks for
|
||||
// gzipped responses, and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply
|
||||
// the connect.WithGRPC() or connect.WithGRPCWeb() options.
|
||||
//
|
||||
// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
|
||||
// http://api.acme.com or https://acme.com/grpc).
|
||||
func NewIdentityProviderServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) IdentityProviderServiceClient {
|
||||
baseURL = strings.TrimRight(baseURL, "/")
|
||||
identityProviderServiceMethods := v1.File_api_v1_idp_service_proto.Services().ByName("IdentityProviderService").Methods()
|
||||
return &identityProviderServiceClient{
|
||||
listIdentityProviders: connect.NewClient[v1.ListIdentityProvidersRequest, v1.ListIdentityProvidersResponse](
|
||||
httpClient,
|
||||
baseURL+IdentityProviderServiceListIdentityProvidersProcedure,
|
||||
connect.WithSchema(identityProviderServiceMethods.ByName("ListIdentityProviders")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
getIdentityProvider: connect.NewClient[v1.GetIdentityProviderRequest, v1.IdentityProvider](
|
||||
httpClient,
|
||||
baseURL+IdentityProviderServiceGetIdentityProviderProcedure,
|
||||
connect.WithSchema(identityProviderServiceMethods.ByName("GetIdentityProvider")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
createIdentityProvider: connect.NewClient[v1.CreateIdentityProviderRequest, v1.IdentityProvider](
|
||||
httpClient,
|
||||
baseURL+IdentityProviderServiceCreateIdentityProviderProcedure,
|
||||
connect.WithSchema(identityProviderServiceMethods.ByName("CreateIdentityProvider")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
updateIdentityProvider: connect.NewClient[v1.UpdateIdentityProviderRequest, v1.IdentityProvider](
|
||||
httpClient,
|
||||
baseURL+IdentityProviderServiceUpdateIdentityProviderProcedure,
|
||||
connect.WithSchema(identityProviderServiceMethods.ByName("UpdateIdentityProvider")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
deleteIdentityProvider: connect.NewClient[v1.DeleteIdentityProviderRequest, emptypb.Empty](
|
||||
httpClient,
|
||||
baseURL+IdentityProviderServiceDeleteIdentityProviderProcedure,
|
||||
connect.WithSchema(identityProviderServiceMethods.ByName("DeleteIdentityProvider")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// identityProviderServiceClient implements IdentityProviderServiceClient.
|
||||
type identityProviderServiceClient struct {
|
||||
listIdentityProviders *connect.Client[v1.ListIdentityProvidersRequest, v1.ListIdentityProvidersResponse]
|
||||
getIdentityProvider *connect.Client[v1.GetIdentityProviderRequest, v1.IdentityProvider]
|
||||
createIdentityProvider *connect.Client[v1.CreateIdentityProviderRequest, v1.IdentityProvider]
|
||||
updateIdentityProvider *connect.Client[v1.UpdateIdentityProviderRequest, v1.IdentityProvider]
|
||||
deleteIdentityProvider *connect.Client[v1.DeleteIdentityProviderRequest, emptypb.Empty]
|
||||
}
|
||||
|
||||
// ListIdentityProviders calls memos.api.v1.IdentityProviderService.ListIdentityProviders.
|
||||
func (c *identityProviderServiceClient) ListIdentityProviders(ctx context.Context, req *connect.Request[v1.ListIdentityProvidersRequest]) (*connect.Response[v1.ListIdentityProvidersResponse], error) {
|
||||
return c.listIdentityProviders.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// GetIdentityProvider calls memos.api.v1.IdentityProviderService.GetIdentityProvider.
|
||||
func (c *identityProviderServiceClient) GetIdentityProvider(ctx context.Context, req *connect.Request[v1.GetIdentityProviderRequest]) (*connect.Response[v1.IdentityProvider], error) {
|
||||
return c.getIdentityProvider.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// CreateIdentityProvider calls memos.api.v1.IdentityProviderService.CreateIdentityProvider.
|
||||
func (c *identityProviderServiceClient) CreateIdentityProvider(ctx context.Context, req *connect.Request[v1.CreateIdentityProviderRequest]) (*connect.Response[v1.IdentityProvider], error) {
|
||||
return c.createIdentityProvider.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// UpdateIdentityProvider calls memos.api.v1.IdentityProviderService.UpdateIdentityProvider.
|
||||
func (c *identityProviderServiceClient) UpdateIdentityProvider(ctx context.Context, req *connect.Request[v1.UpdateIdentityProviderRequest]) (*connect.Response[v1.IdentityProvider], error) {
|
||||
return c.updateIdentityProvider.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// DeleteIdentityProvider calls memos.api.v1.IdentityProviderService.DeleteIdentityProvider.
|
||||
func (c *identityProviderServiceClient) DeleteIdentityProvider(ctx context.Context, req *connect.Request[v1.DeleteIdentityProviderRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return c.deleteIdentityProvider.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// IdentityProviderServiceHandler is an implementation of the memos.api.v1.IdentityProviderService
|
||||
// service.
|
||||
type IdentityProviderServiceHandler interface {
|
||||
// ListIdentityProviders lists identity providers.
|
||||
ListIdentityProviders(context.Context, *connect.Request[v1.ListIdentityProvidersRequest]) (*connect.Response[v1.ListIdentityProvidersResponse], error)
|
||||
// GetIdentityProvider gets an identity provider.
|
||||
GetIdentityProvider(context.Context, *connect.Request[v1.GetIdentityProviderRequest]) (*connect.Response[v1.IdentityProvider], error)
|
||||
// CreateIdentityProvider creates an identity provider.
|
||||
CreateIdentityProvider(context.Context, *connect.Request[v1.CreateIdentityProviderRequest]) (*connect.Response[v1.IdentityProvider], error)
|
||||
// UpdateIdentityProvider updates an identity provider.
|
||||
UpdateIdentityProvider(context.Context, *connect.Request[v1.UpdateIdentityProviderRequest]) (*connect.Response[v1.IdentityProvider], error)
|
||||
// DeleteIdentityProvider deletes an identity provider.
|
||||
DeleteIdentityProvider(context.Context, *connect.Request[v1.DeleteIdentityProviderRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
}
|
||||
|
||||
// NewIdentityProviderServiceHandler builds an HTTP handler from the service implementation. It
|
||||
// returns the path on which to mount the handler and the handler itself.
|
||||
//
|
||||
// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
|
||||
// and JSON codecs. They also support gzip compression.
|
||||
func NewIdentityProviderServiceHandler(svc IdentityProviderServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
|
||||
identityProviderServiceMethods := v1.File_api_v1_idp_service_proto.Services().ByName("IdentityProviderService").Methods()
|
||||
identityProviderServiceListIdentityProvidersHandler := connect.NewUnaryHandler(
|
||||
IdentityProviderServiceListIdentityProvidersProcedure,
|
||||
svc.ListIdentityProviders,
|
||||
connect.WithSchema(identityProviderServiceMethods.ByName("ListIdentityProviders")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
identityProviderServiceGetIdentityProviderHandler := connect.NewUnaryHandler(
|
||||
IdentityProviderServiceGetIdentityProviderProcedure,
|
||||
svc.GetIdentityProvider,
|
||||
connect.WithSchema(identityProviderServiceMethods.ByName("GetIdentityProvider")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
identityProviderServiceCreateIdentityProviderHandler := connect.NewUnaryHandler(
|
||||
IdentityProviderServiceCreateIdentityProviderProcedure,
|
||||
svc.CreateIdentityProvider,
|
||||
connect.WithSchema(identityProviderServiceMethods.ByName("CreateIdentityProvider")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
identityProviderServiceUpdateIdentityProviderHandler := connect.NewUnaryHandler(
|
||||
IdentityProviderServiceUpdateIdentityProviderProcedure,
|
||||
svc.UpdateIdentityProvider,
|
||||
connect.WithSchema(identityProviderServiceMethods.ByName("UpdateIdentityProvider")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
identityProviderServiceDeleteIdentityProviderHandler := connect.NewUnaryHandler(
|
||||
IdentityProviderServiceDeleteIdentityProviderProcedure,
|
||||
svc.DeleteIdentityProvider,
|
||||
connect.WithSchema(identityProviderServiceMethods.ByName("DeleteIdentityProvider")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
return "/memos.api.v1.IdentityProviderService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case IdentityProviderServiceListIdentityProvidersProcedure:
|
||||
identityProviderServiceListIdentityProvidersHandler.ServeHTTP(w, r)
|
||||
case IdentityProviderServiceGetIdentityProviderProcedure:
|
||||
identityProviderServiceGetIdentityProviderHandler.ServeHTTP(w, r)
|
||||
case IdentityProviderServiceCreateIdentityProviderProcedure:
|
||||
identityProviderServiceCreateIdentityProviderHandler.ServeHTTP(w, r)
|
||||
case IdentityProviderServiceUpdateIdentityProviderProcedure:
|
||||
identityProviderServiceUpdateIdentityProviderHandler.ServeHTTP(w, r)
|
||||
case IdentityProviderServiceDeleteIdentityProviderProcedure:
|
||||
identityProviderServiceDeleteIdentityProviderHandler.ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// UnimplementedIdentityProviderServiceHandler returns CodeUnimplemented from all methods.
|
||||
type UnimplementedIdentityProviderServiceHandler struct{}
|
||||
|
||||
func (UnimplementedIdentityProviderServiceHandler) ListIdentityProviders(context.Context, *connect.Request[v1.ListIdentityProvidersRequest]) (*connect.Response[v1.ListIdentityProvidersResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.IdentityProviderService.ListIdentityProviders is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedIdentityProviderServiceHandler) GetIdentityProvider(context.Context, *connect.Request[v1.GetIdentityProviderRequest]) (*connect.Response[v1.IdentityProvider], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.IdentityProviderService.GetIdentityProvider is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedIdentityProviderServiceHandler) CreateIdentityProvider(context.Context, *connect.Request[v1.CreateIdentityProviderRequest]) (*connect.Response[v1.IdentityProvider], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.IdentityProviderService.CreateIdentityProvider is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedIdentityProviderServiceHandler) UpdateIdentityProvider(context.Context, *connect.Request[v1.UpdateIdentityProviderRequest]) (*connect.Response[v1.IdentityProvider], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.IdentityProviderService.UpdateIdentityProvider is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedIdentityProviderServiceHandler) DeleteIdentityProvider(context.Context, *connect.Request[v1.DeleteIdentityProviderRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.IdentityProviderService.DeleteIdentityProvider is not implemented"))
|
||||
}
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
// Code generated by protoc-gen-connect-go. DO NOT EDIT.
|
||||
//
|
||||
// Source: api/v1/instance_service.proto
|
||||
|
||||
package apiv1connect
|
||||
|
||||
import (
|
||||
connect "connectrpc.com/connect"
|
||||
context "context"
|
||||
errors "errors"
|
||||
v1 "github.com/usememos/memos/proto/gen/api/v1"
|
||||
http "net/http"
|
||||
strings "strings"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file and the connect package are
|
||||
// compatible. If you get a compiler error that this constant is not defined, this code was
|
||||
// generated with a version of connect newer than the one compiled into your binary. You can fix the
|
||||
// problem by either regenerating this code with an older version of connect or updating the connect
|
||||
// version compiled into your binary.
|
||||
const _ = connect.IsAtLeastVersion1_13_0
|
||||
|
||||
const (
|
||||
// InstanceServiceName is the fully-qualified name of the InstanceService service.
|
||||
InstanceServiceName = "memos.api.v1.InstanceService"
|
||||
)
|
||||
|
||||
// These constants are the fully-qualified names of the RPCs defined in this package. They're
|
||||
// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
|
||||
//
|
||||
// Note that these are different from the fully-qualified method names used by
|
||||
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
|
||||
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
|
||||
// period.
|
||||
const (
|
||||
// InstanceServiceGetInstanceProfileProcedure is the fully-qualified name of the InstanceService's
|
||||
// GetInstanceProfile RPC.
|
||||
InstanceServiceGetInstanceProfileProcedure = "/memos.api.v1.InstanceService/GetInstanceProfile"
|
||||
// InstanceServiceGetInstanceSettingProcedure is the fully-qualified name of the InstanceService's
|
||||
// GetInstanceSetting RPC.
|
||||
InstanceServiceGetInstanceSettingProcedure = "/memos.api.v1.InstanceService/GetInstanceSetting"
|
||||
// InstanceServiceUpdateInstanceSettingProcedure is the fully-qualified name of the
|
||||
// InstanceService's UpdateInstanceSetting RPC.
|
||||
InstanceServiceUpdateInstanceSettingProcedure = "/memos.api.v1.InstanceService/UpdateInstanceSetting"
|
||||
)
|
||||
|
||||
// InstanceServiceClient is a client for the memos.api.v1.InstanceService service.
|
||||
type InstanceServiceClient interface {
|
||||
// Gets the instance profile.
|
||||
GetInstanceProfile(context.Context, *connect.Request[v1.GetInstanceProfileRequest]) (*connect.Response[v1.InstanceProfile], error)
|
||||
// Gets an instance setting.
|
||||
GetInstanceSetting(context.Context, *connect.Request[v1.GetInstanceSettingRequest]) (*connect.Response[v1.InstanceSetting], error)
|
||||
// Updates an instance setting.
|
||||
UpdateInstanceSetting(context.Context, *connect.Request[v1.UpdateInstanceSettingRequest]) (*connect.Response[v1.InstanceSetting], error)
|
||||
}
|
||||
|
||||
// NewInstanceServiceClient constructs a client for the memos.api.v1.InstanceService service. By
|
||||
// default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses,
|
||||
// and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the
|
||||
// connect.WithGRPC() or connect.WithGRPCWeb() options.
|
||||
//
|
||||
// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
|
||||
// http://api.acme.com or https://acme.com/grpc).
|
||||
func NewInstanceServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) InstanceServiceClient {
|
||||
baseURL = strings.TrimRight(baseURL, "/")
|
||||
instanceServiceMethods := v1.File_api_v1_instance_service_proto.Services().ByName("InstanceService").Methods()
|
||||
return &instanceServiceClient{
|
||||
getInstanceProfile: connect.NewClient[v1.GetInstanceProfileRequest, v1.InstanceProfile](
|
||||
httpClient,
|
||||
baseURL+InstanceServiceGetInstanceProfileProcedure,
|
||||
connect.WithSchema(instanceServiceMethods.ByName("GetInstanceProfile")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
getInstanceSetting: connect.NewClient[v1.GetInstanceSettingRequest, v1.InstanceSetting](
|
||||
httpClient,
|
||||
baseURL+InstanceServiceGetInstanceSettingProcedure,
|
||||
connect.WithSchema(instanceServiceMethods.ByName("GetInstanceSetting")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
updateInstanceSetting: connect.NewClient[v1.UpdateInstanceSettingRequest, v1.InstanceSetting](
|
||||
httpClient,
|
||||
baseURL+InstanceServiceUpdateInstanceSettingProcedure,
|
||||
connect.WithSchema(instanceServiceMethods.ByName("UpdateInstanceSetting")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// instanceServiceClient implements InstanceServiceClient.
|
||||
type instanceServiceClient struct {
|
||||
getInstanceProfile *connect.Client[v1.GetInstanceProfileRequest, v1.InstanceProfile]
|
||||
getInstanceSetting *connect.Client[v1.GetInstanceSettingRequest, v1.InstanceSetting]
|
||||
updateInstanceSetting *connect.Client[v1.UpdateInstanceSettingRequest, v1.InstanceSetting]
|
||||
}
|
||||
|
||||
// GetInstanceProfile calls memos.api.v1.InstanceService.GetInstanceProfile.
|
||||
func (c *instanceServiceClient) GetInstanceProfile(ctx context.Context, req *connect.Request[v1.GetInstanceProfileRequest]) (*connect.Response[v1.InstanceProfile], error) {
|
||||
return c.getInstanceProfile.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// GetInstanceSetting calls memos.api.v1.InstanceService.GetInstanceSetting.
|
||||
func (c *instanceServiceClient) GetInstanceSetting(ctx context.Context, req *connect.Request[v1.GetInstanceSettingRequest]) (*connect.Response[v1.InstanceSetting], error) {
|
||||
return c.getInstanceSetting.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// UpdateInstanceSetting calls memos.api.v1.InstanceService.UpdateInstanceSetting.
|
||||
func (c *instanceServiceClient) UpdateInstanceSetting(ctx context.Context, req *connect.Request[v1.UpdateInstanceSettingRequest]) (*connect.Response[v1.InstanceSetting], error) {
|
||||
return c.updateInstanceSetting.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// InstanceServiceHandler is an implementation of the memos.api.v1.InstanceService service.
|
||||
type InstanceServiceHandler interface {
|
||||
// Gets the instance profile.
|
||||
GetInstanceProfile(context.Context, *connect.Request[v1.GetInstanceProfileRequest]) (*connect.Response[v1.InstanceProfile], error)
|
||||
// Gets an instance setting.
|
||||
GetInstanceSetting(context.Context, *connect.Request[v1.GetInstanceSettingRequest]) (*connect.Response[v1.InstanceSetting], error)
|
||||
// Updates an instance setting.
|
||||
UpdateInstanceSetting(context.Context, *connect.Request[v1.UpdateInstanceSettingRequest]) (*connect.Response[v1.InstanceSetting], error)
|
||||
}
|
||||
|
||||
// NewInstanceServiceHandler builds an HTTP handler from the service implementation. It returns the
|
||||
// path on which to mount the handler and the handler itself.
|
||||
//
|
||||
// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
|
||||
// and JSON codecs. They also support gzip compression.
|
||||
func NewInstanceServiceHandler(svc InstanceServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
|
||||
instanceServiceMethods := v1.File_api_v1_instance_service_proto.Services().ByName("InstanceService").Methods()
|
||||
instanceServiceGetInstanceProfileHandler := connect.NewUnaryHandler(
|
||||
InstanceServiceGetInstanceProfileProcedure,
|
||||
svc.GetInstanceProfile,
|
||||
connect.WithSchema(instanceServiceMethods.ByName("GetInstanceProfile")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
instanceServiceGetInstanceSettingHandler := connect.NewUnaryHandler(
|
||||
InstanceServiceGetInstanceSettingProcedure,
|
||||
svc.GetInstanceSetting,
|
||||
connect.WithSchema(instanceServiceMethods.ByName("GetInstanceSetting")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
instanceServiceUpdateInstanceSettingHandler := connect.NewUnaryHandler(
|
||||
InstanceServiceUpdateInstanceSettingProcedure,
|
||||
svc.UpdateInstanceSetting,
|
||||
connect.WithSchema(instanceServiceMethods.ByName("UpdateInstanceSetting")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
return "/memos.api.v1.InstanceService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case InstanceServiceGetInstanceProfileProcedure:
|
||||
instanceServiceGetInstanceProfileHandler.ServeHTTP(w, r)
|
||||
case InstanceServiceGetInstanceSettingProcedure:
|
||||
instanceServiceGetInstanceSettingHandler.ServeHTTP(w, r)
|
||||
case InstanceServiceUpdateInstanceSettingProcedure:
|
||||
instanceServiceUpdateInstanceSettingHandler.ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// UnimplementedInstanceServiceHandler returns CodeUnimplemented from all methods.
|
||||
type UnimplementedInstanceServiceHandler struct{}
|
||||
|
||||
func (UnimplementedInstanceServiceHandler) GetInstanceProfile(context.Context, *connect.Request[v1.GetInstanceProfileRequest]) (*connect.Response[v1.InstanceProfile], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.InstanceService.GetInstanceProfile is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedInstanceServiceHandler) GetInstanceSetting(context.Context, *connect.Request[v1.GetInstanceSettingRequest]) (*connect.Response[v1.InstanceSetting], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.InstanceService.GetInstanceSetting is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedInstanceServiceHandler) UpdateInstanceSetting(context.Context, *connect.Request[v1.UpdateInstanceSettingRequest]) (*connect.Response[v1.InstanceSetting], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.InstanceService.UpdateInstanceSetting is not implemented"))
|
||||
}
|
||||
|
|
@ -0,0 +1,510 @@
|
|||
// Code generated by protoc-gen-connect-go. DO NOT EDIT.
|
||||
//
|
||||
// Source: api/v1/memo_service.proto
|
||||
|
||||
package apiv1connect
|
||||
|
||||
import (
|
||||
connect "connectrpc.com/connect"
|
||||
context "context"
|
||||
errors "errors"
|
||||
v1 "github.com/usememos/memos/proto/gen/api/v1"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
http "net/http"
|
||||
strings "strings"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file and the connect package are
|
||||
// compatible. If you get a compiler error that this constant is not defined, this code was
|
||||
// generated with a version of connect newer than the one compiled into your binary. You can fix the
|
||||
// problem by either regenerating this code with an older version of connect or updating the connect
|
||||
// version compiled into your binary.
|
||||
const _ = connect.IsAtLeastVersion1_13_0
|
||||
|
||||
const (
|
||||
// MemoServiceName is the fully-qualified name of the MemoService service.
|
||||
MemoServiceName = "memos.api.v1.MemoService"
|
||||
)
|
||||
|
||||
// These constants are the fully-qualified names of the RPCs defined in this package. They're
|
||||
// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
|
||||
//
|
||||
// Note that these are different from the fully-qualified method names used by
|
||||
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
|
||||
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
|
||||
// period.
|
||||
const (
|
||||
// MemoServiceCreateMemoProcedure is the fully-qualified name of the MemoService's CreateMemo RPC.
|
||||
MemoServiceCreateMemoProcedure = "/memos.api.v1.MemoService/CreateMemo"
|
||||
// MemoServiceListMemosProcedure is the fully-qualified name of the MemoService's ListMemos RPC.
|
||||
MemoServiceListMemosProcedure = "/memos.api.v1.MemoService/ListMemos"
|
||||
// MemoServiceGetMemoProcedure is the fully-qualified name of the MemoService's GetMemo RPC.
|
||||
MemoServiceGetMemoProcedure = "/memos.api.v1.MemoService/GetMemo"
|
||||
// MemoServiceUpdateMemoProcedure is the fully-qualified name of the MemoService's UpdateMemo RPC.
|
||||
MemoServiceUpdateMemoProcedure = "/memos.api.v1.MemoService/UpdateMemo"
|
||||
// MemoServiceDeleteMemoProcedure is the fully-qualified name of the MemoService's DeleteMemo RPC.
|
||||
MemoServiceDeleteMemoProcedure = "/memos.api.v1.MemoService/DeleteMemo"
|
||||
// MemoServiceSetMemoAttachmentsProcedure is the fully-qualified name of the MemoService's
|
||||
// SetMemoAttachments RPC.
|
||||
MemoServiceSetMemoAttachmentsProcedure = "/memos.api.v1.MemoService/SetMemoAttachments"
|
||||
// MemoServiceListMemoAttachmentsProcedure is the fully-qualified name of the MemoService's
|
||||
// ListMemoAttachments RPC.
|
||||
MemoServiceListMemoAttachmentsProcedure = "/memos.api.v1.MemoService/ListMemoAttachments"
|
||||
// MemoServiceSetMemoRelationsProcedure is the fully-qualified name of the MemoService's
|
||||
// SetMemoRelations RPC.
|
||||
MemoServiceSetMemoRelationsProcedure = "/memos.api.v1.MemoService/SetMemoRelations"
|
||||
// MemoServiceListMemoRelationsProcedure is the fully-qualified name of the MemoService's
|
||||
// ListMemoRelations RPC.
|
||||
MemoServiceListMemoRelationsProcedure = "/memos.api.v1.MemoService/ListMemoRelations"
|
||||
// MemoServiceCreateMemoCommentProcedure is the fully-qualified name of the MemoService's
|
||||
// CreateMemoComment RPC.
|
||||
MemoServiceCreateMemoCommentProcedure = "/memos.api.v1.MemoService/CreateMemoComment"
|
||||
// MemoServiceListMemoCommentsProcedure is the fully-qualified name of the MemoService's
|
||||
// ListMemoComments RPC.
|
||||
MemoServiceListMemoCommentsProcedure = "/memos.api.v1.MemoService/ListMemoComments"
|
||||
// MemoServiceListMemoReactionsProcedure is the fully-qualified name of the MemoService's
|
||||
// ListMemoReactions RPC.
|
||||
MemoServiceListMemoReactionsProcedure = "/memos.api.v1.MemoService/ListMemoReactions"
|
||||
// MemoServiceUpsertMemoReactionProcedure is the fully-qualified name of the MemoService's
|
||||
// UpsertMemoReaction RPC.
|
||||
MemoServiceUpsertMemoReactionProcedure = "/memos.api.v1.MemoService/UpsertMemoReaction"
|
||||
// MemoServiceDeleteMemoReactionProcedure is the fully-qualified name of the MemoService's
|
||||
// DeleteMemoReaction RPC.
|
||||
MemoServiceDeleteMemoReactionProcedure = "/memos.api.v1.MemoService/DeleteMemoReaction"
|
||||
)
|
||||
|
||||
// MemoServiceClient is a client for the memos.api.v1.MemoService service.
|
||||
type MemoServiceClient interface {
|
||||
// CreateMemo creates a memo.
|
||||
CreateMemo(context.Context, *connect.Request[v1.CreateMemoRequest]) (*connect.Response[v1.Memo], error)
|
||||
// ListMemos lists memos with pagination and filter.
|
||||
ListMemos(context.Context, *connect.Request[v1.ListMemosRequest]) (*connect.Response[v1.ListMemosResponse], error)
|
||||
// GetMemo gets a memo.
|
||||
GetMemo(context.Context, *connect.Request[v1.GetMemoRequest]) (*connect.Response[v1.Memo], error)
|
||||
// UpdateMemo updates a memo.
|
||||
UpdateMemo(context.Context, *connect.Request[v1.UpdateMemoRequest]) (*connect.Response[v1.Memo], error)
|
||||
// DeleteMemo deletes a memo.
|
||||
DeleteMemo(context.Context, *connect.Request[v1.DeleteMemoRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
// SetMemoAttachments sets attachments for a memo.
|
||||
SetMemoAttachments(context.Context, *connect.Request[v1.SetMemoAttachmentsRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
// ListMemoAttachments lists attachments for a memo.
|
||||
ListMemoAttachments(context.Context, *connect.Request[v1.ListMemoAttachmentsRequest]) (*connect.Response[v1.ListMemoAttachmentsResponse], error)
|
||||
// SetMemoRelations sets relations for a memo.
|
||||
SetMemoRelations(context.Context, *connect.Request[v1.SetMemoRelationsRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
// ListMemoRelations lists relations for a memo.
|
||||
ListMemoRelations(context.Context, *connect.Request[v1.ListMemoRelationsRequest]) (*connect.Response[v1.ListMemoRelationsResponse], error)
|
||||
// CreateMemoComment creates a comment for a memo.
|
||||
CreateMemoComment(context.Context, *connect.Request[v1.CreateMemoCommentRequest]) (*connect.Response[v1.Memo], error)
|
||||
// ListMemoComments lists comments for a memo.
|
||||
ListMemoComments(context.Context, *connect.Request[v1.ListMemoCommentsRequest]) (*connect.Response[v1.ListMemoCommentsResponse], error)
|
||||
// ListMemoReactions lists reactions for a memo.
|
||||
ListMemoReactions(context.Context, *connect.Request[v1.ListMemoReactionsRequest]) (*connect.Response[v1.ListMemoReactionsResponse], error)
|
||||
// UpsertMemoReaction upserts a reaction for a memo.
|
||||
UpsertMemoReaction(context.Context, *connect.Request[v1.UpsertMemoReactionRequest]) (*connect.Response[v1.Reaction], error)
|
||||
// DeleteMemoReaction deletes a reaction for a memo.
|
||||
DeleteMemoReaction(context.Context, *connect.Request[v1.DeleteMemoReactionRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
}
|
||||
|
||||
// NewMemoServiceClient constructs a client for the memos.api.v1.MemoService service. By default, it
|
||||
// uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and sends
|
||||
// uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or
|
||||
// connect.WithGRPCWeb() options.
|
||||
//
|
||||
// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
|
||||
// http://api.acme.com or https://acme.com/grpc).
|
||||
func NewMemoServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) MemoServiceClient {
|
||||
baseURL = strings.TrimRight(baseURL, "/")
|
||||
memoServiceMethods := v1.File_api_v1_memo_service_proto.Services().ByName("MemoService").Methods()
|
||||
return &memoServiceClient{
|
||||
createMemo: connect.NewClient[v1.CreateMemoRequest, v1.Memo](
|
||||
httpClient,
|
||||
baseURL+MemoServiceCreateMemoProcedure,
|
||||
connect.WithSchema(memoServiceMethods.ByName("CreateMemo")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
listMemos: connect.NewClient[v1.ListMemosRequest, v1.ListMemosResponse](
|
||||
httpClient,
|
||||
baseURL+MemoServiceListMemosProcedure,
|
||||
connect.WithSchema(memoServiceMethods.ByName("ListMemos")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
getMemo: connect.NewClient[v1.GetMemoRequest, v1.Memo](
|
||||
httpClient,
|
||||
baseURL+MemoServiceGetMemoProcedure,
|
||||
connect.WithSchema(memoServiceMethods.ByName("GetMemo")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
updateMemo: connect.NewClient[v1.UpdateMemoRequest, v1.Memo](
|
||||
httpClient,
|
||||
baseURL+MemoServiceUpdateMemoProcedure,
|
||||
connect.WithSchema(memoServiceMethods.ByName("UpdateMemo")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
deleteMemo: connect.NewClient[v1.DeleteMemoRequest, emptypb.Empty](
|
||||
httpClient,
|
||||
baseURL+MemoServiceDeleteMemoProcedure,
|
||||
connect.WithSchema(memoServiceMethods.ByName("DeleteMemo")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
setMemoAttachments: connect.NewClient[v1.SetMemoAttachmentsRequest, emptypb.Empty](
|
||||
httpClient,
|
||||
baseURL+MemoServiceSetMemoAttachmentsProcedure,
|
||||
connect.WithSchema(memoServiceMethods.ByName("SetMemoAttachments")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
listMemoAttachments: connect.NewClient[v1.ListMemoAttachmentsRequest, v1.ListMemoAttachmentsResponse](
|
||||
httpClient,
|
||||
baseURL+MemoServiceListMemoAttachmentsProcedure,
|
||||
connect.WithSchema(memoServiceMethods.ByName("ListMemoAttachments")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
setMemoRelations: connect.NewClient[v1.SetMemoRelationsRequest, emptypb.Empty](
|
||||
httpClient,
|
||||
baseURL+MemoServiceSetMemoRelationsProcedure,
|
||||
connect.WithSchema(memoServiceMethods.ByName("SetMemoRelations")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
listMemoRelations: connect.NewClient[v1.ListMemoRelationsRequest, v1.ListMemoRelationsResponse](
|
||||
httpClient,
|
||||
baseURL+MemoServiceListMemoRelationsProcedure,
|
||||
connect.WithSchema(memoServiceMethods.ByName("ListMemoRelations")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
createMemoComment: connect.NewClient[v1.CreateMemoCommentRequest, v1.Memo](
|
||||
httpClient,
|
||||
baseURL+MemoServiceCreateMemoCommentProcedure,
|
||||
connect.WithSchema(memoServiceMethods.ByName("CreateMemoComment")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
listMemoComments: connect.NewClient[v1.ListMemoCommentsRequest, v1.ListMemoCommentsResponse](
|
||||
httpClient,
|
||||
baseURL+MemoServiceListMemoCommentsProcedure,
|
||||
connect.WithSchema(memoServiceMethods.ByName("ListMemoComments")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
listMemoReactions: connect.NewClient[v1.ListMemoReactionsRequest, v1.ListMemoReactionsResponse](
|
||||
httpClient,
|
||||
baseURL+MemoServiceListMemoReactionsProcedure,
|
||||
connect.WithSchema(memoServiceMethods.ByName("ListMemoReactions")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
upsertMemoReaction: connect.NewClient[v1.UpsertMemoReactionRequest, v1.Reaction](
|
||||
httpClient,
|
||||
baseURL+MemoServiceUpsertMemoReactionProcedure,
|
||||
connect.WithSchema(memoServiceMethods.ByName("UpsertMemoReaction")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
deleteMemoReaction: connect.NewClient[v1.DeleteMemoReactionRequest, emptypb.Empty](
|
||||
httpClient,
|
||||
baseURL+MemoServiceDeleteMemoReactionProcedure,
|
||||
connect.WithSchema(memoServiceMethods.ByName("DeleteMemoReaction")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// memoServiceClient implements MemoServiceClient.
|
||||
type memoServiceClient struct {
|
||||
createMemo *connect.Client[v1.CreateMemoRequest, v1.Memo]
|
||||
listMemos *connect.Client[v1.ListMemosRequest, v1.ListMemosResponse]
|
||||
getMemo *connect.Client[v1.GetMemoRequest, v1.Memo]
|
||||
updateMemo *connect.Client[v1.UpdateMemoRequest, v1.Memo]
|
||||
deleteMemo *connect.Client[v1.DeleteMemoRequest, emptypb.Empty]
|
||||
setMemoAttachments *connect.Client[v1.SetMemoAttachmentsRequest, emptypb.Empty]
|
||||
listMemoAttachments *connect.Client[v1.ListMemoAttachmentsRequest, v1.ListMemoAttachmentsResponse]
|
||||
setMemoRelations *connect.Client[v1.SetMemoRelationsRequest, emptypb.Empty]
|
||||
listMemoRelations *connect.Client[v1.ListMemoRelationsRequest, v1.ListMemoRelationsResponse]
|
||||
createMemoComment *connect.Client[v1.CreateMemoCommentRequest, v1.Memo]
|
||||
listMemoComments *connect.Client[v1.ListMemoCommentsRequest, v1.ListMemoCommentsResponse]
|
||||
listMemoReactions *connect.Client[v1.ListMemoReactionsRequest, v1.ListMemoReactionsResponse]
|
||||
upsertMemoReaction *connect.Client[v1.UpsertMemoReactionRequest, v1.Reaction]
|
||||
deleteMemoReaction *connect.Client[v1.DeleteMemoReactionRequest, emptypb.Empty]
|
||||
}
|
||||
|
||||
// CreateMemo calls memos.api.v1.MemoService.CreateMemo.
|
||||
func (c *memoServiceClient) CreateMemo(ctx context.Context, req *connect.Request[v1.CreateMemoRequest]) (*connect.Response[v1.Memo], error) {
|
||||
return c.createMemo.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// ListMemos calls memos.api.v1.MemoService.ListMemos.
|
||||
func (c *memoServiceClient) ListMemos(ctx context.Context, req *connect.Request[v1.ListMemosRequest]) (*connect.Response[v1.ListMemosResponse], error) {
|
||||
return c.listMemos.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// GetMemo calls memos.api.v1.MemoService.GetMemo.
|
||||
func (c *memoServiceClient) GetMemo(ctx context.Context, req *connect.Request[v1.GetMemoRequest]) (*connect.Response[v1.Memo], error) {
|
||||
return c.getMemo.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// UpdateMemo calls memos.api.v1.MemoService.UpdateMemo.
|
||||
func (c *memoServiceClient) UpdateMemo(ctx context.Context, req *connect.Request[v1.UpdateMemoRequest]) (*connect.Response[v1.Memo], error) {
|
||||
return c.updateMemo.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// DeleteMemo calls memos.api.v1.MemoService.DeleteMemo.
|
||||
func (c *memoServiceClient) DeleteMemo(ctx context.Context, req *connect.Request[v1.DeleteMemoRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return c.deleteMemo.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// SetMemoAttachments calls memos.api.v1.MemoService.SetMemoAttachments.
|
||||
func (c *memoServiceClient) SetMemoAttachments(ctx context.Context, req *connect.Request[v1.SetMemoAttachmentsRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return c.setMemoAttachments.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// ListMemoAttachments calls memos.api.v1.MemoService.ListMemoAttachments.
|
||||
func (c *memoServiceClient) ListMemoAttachments(ctx context.Context, req *connect.Request[v1.ListMemoAttachmentsRequest]) (*connect.Response[v1.ListMemoAttachmentsResponse], error) {
|
||||
return c.listMemoAttachments.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// SetMemoRelations calls memos.api.v1.MemoService.SetMemoRelations.
|
||||
func (c *memoServiceClient) SetMemoRelations(ctx context.Context, req *connect.Request[v1.SetMemoRelationsRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return c.setMemoRelations.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// ListMemoRelations calls memos.api.v1.MemoService.ListMemoRelations.
|
||||
func (c *memoServiceClient) ListMemoRelations(ctx context.Context, req *connect.Request[v1.ListMemoRelationsRequest]) (*connect.Response[v1.ListMemoRelationsResponse], error) {
|
||||
return c.listMemoRelations.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// CreateMemoComment calls memos.api.v1.MemoService.CreateMemoComment.
|
||||
func (c *memoServiceClient) CreateMemoComment(ctx context.Context, req *connect.Request[v1.CreateMemoCommentRequest]) (*connect.Response[v1.Memo], error) {
|
||||
return c.createMemoComment.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// ListMemoComments calls memos.api.v1.MemoService.ListMemoComments.
|
||||
func (c *memoServiceClient) ListMemoComments(ctx context.Context, req *connect.Request[v1.ListMemoCommentsRequest]) (*connect.Response[v1.ListMemoCommentsResponse], error) {
|
||||
return c.listMemoComments.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// ListMemoReactions calls memos.api.v1.MemoService.ListMemoReactions.
|
||||
func (c *memoServiceClient) ListMemoReactions(ctx context.Context, req *connect.Request[v1.ListMemoReactionsRequest]) (*connect.Response[v1.ListMemoReactionsResponse], error) {
|
||||
return c.listMemoReactions.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// UpsertMemoReaction calls memos.api.v1.MemoService.UpsertMemoReaction.
|
||||
func (c *memoServiceClient) UpsertMemoReaction(ctx context.Context, req *connect.Request[v1.UpsertMemoReactionRequest]) (*connect.Response[v1.Reaction], error) {
|
||||
return c.upsertMemoReaction.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// DeleteMemoReaction calls memos.api.v1.MemoService.DeleteMemoReaction.
|
||||
func (c *memoServiceClient) DeleteMemoReaction(ctx context.Context, req *connect.Request[v1.DeleteMemoReactionRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return c.deleteMemoReaction.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// MemoServiceHandler is an implementation of the memos.api.v1.MemoService service.
|
||||
type MemoServiceHandler interface {
|
||||
// CreateMemo creates a memo.
|
||||
CreateMemo(context.Context, *connect.Request[v1.CreateMemoRequest]) (*connect.Response[v1.Memo], error)
|
||||
// ListMemos lists memos with pagination and filter.
|
||||
ListMemos(context.Context, *connect.Request[v1.ListMemosRequest]) (*connect.Response[v1.ListMemosResponse], error)
|
||||
// GetMemo gets a memo.
|
||||
GetMemo(context.Context, *connect.Request[v1.GetMemoRequest]) (*connect.Response[v1.Memo], error)
|
||||
// UpdateMemo updates a memo.
|
||||
UpdateMemo(context.Context, *connect.Request[v1.UpdateMemoRequest]) (*connect.Response[v1.Memo], error)
|
||||
// DeleteMemo deletes a memo.
|
||||
DeleteMemo(context.Context, *connect.Request[v1.DeleteMemoRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
// SetMemoAttachments sets attachments for a memo.
|
||||
SetMemoAttachments(context.Context, *connect.Request[v1.SetMemoAttachmentsRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
// ListMemoAttachments lists attachments for a memo.
|
||||
ListMemoAttachments(context.Context, *connect.Request[v1.ListMemoAttachmentsRequest]) (*connect.Response[v1.ListMemoAttachmentsResponse], error)
|
||||
// SetMemoRelations sets relations for a memo.
|
||||
SetMemoRelations(context.Context, *connect.Request[v1.SetMemoRelationsRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
// ListMemoRelations lists relations for a memo.
|
||||
ListMemoRelations(context.Context, *connect.Request[v1.ListMemoRelationsRequest]) (*connect.Response[v1.ListMemoRelationsResponse], error)
|
||||
// CreateMemoComment creates a comment for a memo.
|
||||
CreateMemoComment(context.Context, *connect.Request[v1.CreateMemoCommentRequest]) (*connect.Response[v1.Memo], error)
|
||||
// ListMemoComments lists comments for a memo.
|
||||
ListMemoComments(context.Context, *connect.Request[v1.ListMemoCommentsRequest]) (*connect.Response[v1.ListMemoCommentsResponse], error)
|
||||
// ListMemoReactions lists reactions for a memo.
|
||||
ListMemoReactions(context.Context, *connect.Request[v1.ListMemoReactionsRequest]) (*connect.Response[v1.ListMemoReactionsResponse], error)
|
||||
// UpsertMemoReaction upserts a reaction for a memo.
|
||||
UpsertMemoReaction(context.Context, *connect.Request[v1.UpsertMemoReactionRequest]) (*connect.Response[v1.Reaction], error)
|
||||
// DeleteMemoReaction deletes a reaction for a memo.
|
||||
DeleteMemoReaction(context.Context, *connect.Request[v1.DeleteMemoReactionRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
}
|
||||
|
||||
// NewMemoServiceHandler builds an HTTP handler from the service implementation. It returns the path
|
||||
// on which to mount the handler and the handler itself.
|
||||
//
|
||||
// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
|
||||
// and JSON codecs. They also support gzip compression.
|
||||
func NewMemoServiceHandler(svc MemoServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
|
||||
memoServiceMethods := v1.File_api_v1_memo_service_proto.Services().ByName("MemoService").Methods()
|
||||
memoServiceCreateMemoHandler := connect.NewUnaryHandler(
|
||||
MemoServiceCreateMemoProcedure,
|
||||
svc.CreateMemo,
|
||||
connect.WithSchema(memoServiceMethods.ByName("CreateMemo")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
memoServiceListMemosHandler := connect.NewUnaryHandler(
|
||||
MemoServiceListMemosProcedure,
|
||||
svc.ListMemos,
|
||||
connect.WithSchema(memoServiceMethods.ByName("ListMemos")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
memoServiceGetMemoHandler := connect.NewUnaryHandler(
|
||||
MemoServiceGetMemoProcedure,
|
||||
svc.GetMemo,
|
||||
connect.WithSchema(memoServiceMethods.ByName("GetMemo")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
memoServiceUpdateMemoHandler := connect.NewUnaryHandler(
|
||||
MemoServiceUpdateMemoProcedure,
|
||||
svc.UpdateMemo,
|
||||
connect.WithSchema(memoServiceMethods.ByName("UpdateMemo")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
memoServiceDeleteMemoHandler := connect.NewUnaryHandler(
|
||||
MemoServiceDeleteMemoProcedure,
|
||||
svc.DeleteMemo,
|
||||
connect.WithSchema(memoServiceMethods.ByName("DeleteMemo")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
memoServiceSetMemoAttachmentsHandler := connect.NewUnaryHandler(
|
||||
MemoServiceSetMemoAttachmentsProcedure,
|
||||
svc.SetMemoAttachments,
|
||||
connect.WithSchema(memoServiceMethods.ByName("SetMemoAttachments")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
memoServiceListMemoAttachmentsHandler := connect.NewUnaryHandler(
|
||||
MemoServiceListMemoAttachmentsProcedure,
|
||||
svc.ListMemoAttachments,
|
||||
connect.WithSchema(memoServiceMethods.ByName("ListMemoAttachments")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
memoServiceSetMemoRelationsHandler := connect.NewUnaryHandler(
|
||||
MemoServiceSetMemoRelationsProcedure,
|
||||
svc.SetMemoRelations,
|
||||
connect.WithSchema(memoServiceMethods.ByName("SetMemoRelations")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
memoServiceListMemoRelationsHandler := connect.NewUnaryHandler(
|
||||
MemoServiceListMemoRelationsProcedure,
|
||||
svc.ListMemoRelations,
|
||||
connect.WithSchema(memoServiceMethods.ByName("ListMemoRelations")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
memoServiceCreateMemoCommentHandler := connect.NewUnaryHandler(
|
||||
MemoServiceCreateMemoCommentProcedure,
|
||||
svc.CreateMemoComment,
|
||||
connect.WithSchema(memoServiceMethods.ByName("CreateMemoComment")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
memoServiceListMemoCommentsHandler := connect.NewUnaryHandler(
|
||||
MemoServiceListMemoCommentsProcedure,
|
||||
svc.ListMemoComments,
|
||||
connect.WithSchema(memoServiceMethods.ByName("ListMemoComments")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
memoServiceListMemoReactionsHandler := connect.NewUnaryHandler(
|
||||
MemoServiceListMemoReactionsProcedure,
|
||||
svc.ListMemoReactions,
|
||||
connect.WithSchema(memoServiceMethods.ByName("ListMemoReactions")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
memoServiceUpsertMemoReactionHandler := connect.NewUnaryHandler(
|
||||
MemoServiceUpsertMemoReactionProcedure,
|
||||
svc.UpsertMemoReaction,
|
||||
connect.WithSchema(memoServiceMethods.ByName("UpsertMemoReaction")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
memoServiceDeleteMemoReactionHandler := connect.NewUnaryHandler(
|
||||
MemoServiceDeleteMemoReactionProcedure,
|
||||
svc.DeleteMemoReaction,
|
||||
connect.WithSchema(memoServiceMethods.ByName("DeleteMemoReaction")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
return "/memos.api.v1.MemoService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case MemoServiceCreateMemoProcedure:
|
||||
memoServiceCreateMemoHandler.ServeHTTP(w, r)
|
||||
case MemoServiceListMemosProcedure:
|
||||
memoServiceListMemosHandler.ServeHTTP(w, r)
|
||||
case MemoServiceGetMemoProcedure:
|
||||
memoServiceGetMemoHandler.ServeHTTP(w, r)
|
||||
case MemoServiceUpdateMemoProcedure:
|
||||
memoServiceUpdateMemoHandler.ServeHTTP(w, r)
|
||||
case MemoServiceDeleteMemoProcedure:
|
||||
memoServiceDeleteMemoHandler.ServeHTTP(w, r)
|
||||
case MemoServiceSetMemoAttachmentsProcedure:
|
||||
memoServiceSetMemoAttachmentsHandler.ServeHTTP(w, r)
|
||||
case MemoServiceListMemoAttachmentsProcedure:
|
||||
memoServiceListMemoAttachmentsHandler.ServeHTTP(w, r)
|
||||
case MemoServiceSetMemoRelationsProcedure:
|
||||
memoServiceSetMemoRelationsHandler.ServeHTTP(w, r)
|
||||
case MemoServiceListMemoRelationsProcedure:
|
||||
memoServiceListMemoRelationsHandler.ServeHTTP(w, r)
|
||||
case MemoServiceCreateMemoCommentProcedure:
|
||||
memoServiceCreateMemoCommentHandler.ServeHTTP(w, r)
|
||||
case MemoServiceListMemoCommentsProcedure:
|
||||
memoServiceListMemoCommentsHandler.ServeHTTP(w, r)
|
||||
case MemoServiceListMemoReactionsProcedure:
|
||||
memoServiceListMemoReactionsHandler.ServeHTTP(w, r)
|
||||
case MemoServiceUpsertMemoReactionProcedure:
|
||||
memoServiceUpsertMemoReactionHandler.ServeHTTP(w, r)
|
||||
case MemoServiceDeleteMemoReactionProcedure:
|
||||
memoServiceDeleteMemoReactionHandler.ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// UnimplementedMemoServiceHandler returns CodeUnimplemented from all methods.
|
||||
type UnimplementedMemoServiceHandler struct{}
|
||||
|
||||
func (UnimplementedMemoServiceHandler) CreateMemo(context.Context, *connect.Request[v1.CreateMemoRequest]) (*connect.Response[v1.Memo], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.MemoService.CreateMemo is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedMemoServiceHandler) ListMemos(context.Context, *connect.Request[v1.ListMemosRequest]) (*connect.Response[v1.ListMemosResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.MemoService.ListMemos is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedMemoServiceHandler) GetMemo(context.Context, *connect.Request[v1.GetMemoRequest]) (*connect.Response[v1.Memo], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.MemoService.GetMemo is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedMemoServiceHandler) UpdateMemo(context.Context, *connect.Request[v1.UpdateMemoRequest]) (*connect.Response[v1.Memo], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.MemoService.UpdateMemo is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedMemoServiceHandler) DeleteMemo(context.Context, *connect.Request[v1.DeleteMemoRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.MemoService.DeleteMemo is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedMemoServiceHandler) SetMemoAttachments(context.Context, *connect.Request[v1.SetMemoAttachmentsRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.MemoService.SetMemoAttachments is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedMemoServiceHandler) ListMemoAttachments(context.Context, *connect.Request[v1.ListMemoAttachmentsRequest]) (*connect.Response[v1.ListMemoAttachmentsResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.MemoService.ListMemoAttachments is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedMemoServiceHandler) SetMemoRelations(context.Context, *connect.Request[v1.SetMemoRelationsRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.MemoService.SetMemoRelations is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedMemoServiceHandler) ListMemoRelations(context.Context, *connect.Request[v1.ListMemoRelationsRequest]) (*connect.Response[v1.ListMemoRelationsResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.MemoService.ListMemoRelations is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedMemoServiceHandler) CreateMemoComment(context.Context, *connect.Request[v1.CreateMemoCommentRequest]) (*connect.Response[v1.Memo], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.MemoService.CreateMemoComment is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedMemoServiceHandler) ListMemoComments(context.Context, *connect.Request[v1.ListMemoCommentsRequest]) (*connect.Response[v1.ListMemoCommentsResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.MemoService.ListMemoComments is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedMemoServiceHandler) ListMemoReactions(context.Context, *connect.Request[v1.ListMemoReactionsRequest]) (*connect.Response[v1.ListMemoReactionsResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.MemoService.ListMemoReactions is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedMemoServiceHandler) UpsertMemoReaction(context.Context, *connect.Request[v1.UpsertMemoReactionRequest]) (*connect.Response[v1.Reaction], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.MemoService.UpsertMemoReaction is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedMemoServiceHandler) DeleteMemoReaction(context.Context, *connect.Request[v1.DeleteMemoReactionRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.MemoService.DeleteMemoReaction is not implemented"))
|
||||
}
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
// Code generated by protoc-gen-connect-go. DO NOT EDIT.
|
||||
//
|
||||
// Source: api/v1/shortcut_service.proto
|
||||
|
||||
package apiv1connect
|
||||
|
||||
import (
|
||||
connect "connectrpc.com/connect"
|
||||
context "context"
|
||||
errors "errors"
|
||||
v1 "github.com/usememos/memos/proto/gen/api/v1"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
http "net/http"
|
||||
strings "strings"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file and the connect package are
|
||||
// compatible. If you get a compiler error that this constant is not defined, this code was
|
||||
// generated with a version of connect newer than the one compiled into your binary. You can fix the
|
||||
// problem by either regenerating this code with an older version of connect or updating the connect
|
||||
// version compiled into your binary.
|
||||
const _ = connect.IsAtLeastVersion1_13_0
|
||||
|
||||
const (
|
||||
// ShortcutServiceName is the fully-qualified name of the ShortcutService service.
|
||||
ShortcutServiceName = "memos.api.v1.ShortcutService"
|
||||
)
|
||||
|
||||
// These constants are the fully-qualified names of the RPCs defined in this package. They're
|
||||
// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
|
||||
//
|
||||
// Note that these are different from the fully-qualified method names used by
|
||||
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
|
||||
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
|
||||
// period.
|
||||
const (
|
||||
// ShortcutServiceListShortcutsProcedure is the fully-qualified name of the ShortcutService's
|
||||
// ListShortcuts RPC.
|
||||
ShortcutServiceListShortcutsProcedure = "/memos.api.v1.ShortcutService/ListShortcuts"
|
||||
// ShortcutServiceGetShortcutProcedure is the fully-qualified name of the ShortcutService's
|
||||
// GetShortcut RPC.
|
||||
ShortcutServiceGetShortcutProcedure = "/memos.api.v1.ShortcutService/GetShortcut"
|
||||
// ShortcutServiceCreateShortcutProcedure is the fully-qualified name of the ShortcutService's
|
||||
// CreateShortcut RPC.
|
||||
ShortcutServiceCreateShortcutProcedure = "/memos.api.v1.ShortcutService/CreateShortcut"
|
||||
// ShortcutServiceUpdateShortcutProcedure is the fully-qualified name of the ShortcutService's
|
||||
// UpdateShortcut RPC.
|
||||
ShortcutServiceUpdateShortcutProcedure = "/memos.api.v1.ShortcutService/UpdateShortcut"
|
||||
// ShortcutServiceDeleteShortcutProcedure is the fully-qualified name of the ShortcutService's
|
||||
// DeleteShortcut RPC.
|
||||
ShortcutServiceDeleteShortcutProcedure = "/memos.api.v1.ShortcutService/DeleteShortcut"
|
||||
)
|
||||
|
||||
// ShortcutServiceClient is a client for the memos.api.v1.ShortcutService service.
|
||||
type ShortcutServiceClient interface {
|
||||
// ListShortcuts returns a list of shortcuts for a user.
|
||||
ListShortcuts(context.Context, *connect.Request[v1.ListShortcutsRequest]) (*connect.Response[v1.ListShortcutsResponse], error)
|
||||
// GetShortcut gets a shortcut by name.
|
||||
GetShortcut(context.Context, *connect.Request[v1.GetShortcutRequest]) (*connect.Response[v1.Shortcut], error)
|
||||
// CreateShortcut creates a new shortcut for a user.
|
||||
CreateShortcut(context.Context, *connect.Request[v1.CreateShortcutRequest]) (*connect.Response[v1.Shortcut], error)
|
||||
// UpdateShortcut updates a shortcut for a user.
|
||||
UpdateShortcut(context.Context, *connect.Request[v1.UpdateShortcutRequest]) (*connect.Response[v1.Shortcut], error)
|
||||
// DeleteShortcut deletes a shortcut for a user.
|
||||
DeleteShortcut(context.Context, *connect.Request[v1.DeleteShortcutRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
}
|
||||
|
||||
// NewShortcutServiceClient constructs a client for the memos.api.v1.ShortcutService service. By
|
||||
// default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses,
|
||||
// and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the
|
||||
// connect.WithGRPC() or connect.WithGRPCWeb() options.
|
||||
//
|
||||
// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
|
||||
// http://api.acme.com or https://acme.com/grpc).
|
||||
func NewShortcutServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) ShortcutServiceClient {
|
||||
baseURL = strings.TrimRight(baseURL, "/")
|
||||
shortcutServiceMethods := v1.File_api_v1_shortcut_service_proto.Services().ByName("ShortcutService").Methods()
|
||||
return &shortcutServiceClient{
|
||||
listShortcuts: connect.NewClient[v1.ListShortcutsRequest, v1.ListShortcutsResponse](
|
||||
httpClient,
|
||||
baseURL+ShortcutServiceListShortcutsProcedure,
|
||||
connect.WithSchema(shortcutServiceMethods.ByName("ListShortcuts")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
getShortcut: connect.NewClient[v1.GetShortcutRequest, v1.Shortcut](
|
||||
httpClient,
|
||||
baseURL+ShortcutServiceGetShortcutProcedure,
|
||||
connect.WithSchema(shortcutServiceMethods.ByName("GetShortcut")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
createShortcut: connect.NewClient[v1.CreateShortcutRequest, v1.Shortcut](
|
||||
httpClient,
|
||||
baseURL+ShortcutServiceCreateShortcutProcedure,
|
||||
connect.WithSchema(shortcutServiceMethods.ByName("CreateShortcut")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
updateShortcut: connect.NewClient[v1.UpdateShortcutRequest, v1.Shortcut](
|
||||
httpClient,
|
||||
baseURL+ShortcutServiceUpdateShortcutProcedure,
|
||||
connect.WithSchema(shortcutServiceMethods.ByName("UpdateShortcut")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
deleteShortcut: connect.NewClient[v1.DeleteShortcutRequest, emptypb.Empty](
|
||||
httpClient,
|
||||
baseURL+ShortcutServiceDeleteShortcutProcedure,
|
||||
connect.WithSchema(shortcutServiceMethods.ByName("DeleteShortcut")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// shortcutServiceClient implements ShortcutServiceClient.
|
||||
type shortcutServiceClient struct {
|
||||
listShortcuts *connect.Client[v1.ListShortcutsRequest, v1.ListShortcutsResponse]
|
||||
getShortcut *connect.Client[v1.GetShortcutRequest, v1.Shortcut]
|
||||
createShortcut *connect.Client[v1.CreateShortcutRequest, v1.Shortcut]
|
||||
updateShortcut *connect.Client[v1.UpdateShortcutRequest, v1.Shortcut]
|
||||
deleteShortcut *connect.Client[v1.DeleteShortcutRequest, emptypb.Empty]
|
||||
}
|
||||
|
||||
// ListShortcuts calls memos.api.v1.ShortcutService.ListShortcuts.
|
||||
func (c *shortcutServiceClient) ListShortcuts(ctx context.Context, req *connect.Request[v1.ListShortcutsRequest]) (*connect.Response[v1.ListShortcutsResponse], error) {
|
||||
return c.listShortcuts.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// GetShortcut calls memos.api.v1.ShortcutService.GetShortcut.
|
||||
func (c *shortcutServiceClient) GetShortcut(ctx context.Context, req *connect.Request[v1.GetShortcutRequest]) (*connect.Response[v1.Shortcut], error) {
|
||||
return c.getShortcut.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// CreateShortcut calls memos.api.v1.ShortcutService.CreateShortcut.
|
||||
func (c *shortcutServiceClient) CreateShortcut(ctx context.Context, req *connect.Request[v1.CreateShortcutRequest]) (*connect.Response[v1.Shortcut], error) {
|
||||
return c.createShortcut.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// UpdateShortcut calls memos.api.v1.ShortcutService.UpdateShortcut.
|
||||
func (c *shortcutServiceClient) UpdateShortcut(ctx context.Context, req *connect.Request[v1.UpdateShortcutRequest]) (*connect.Response[v1.Shortcut], error) {
|
||||
return c.updateShortcut.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// DeleteShortcut calls memos.api.v1.ShortcutService.DeleteShortcut.
|
||||
func (c *shortcutServiceClient) DeleteShortcut(ctx context.Context, req *connect.Request[v1.DeleteShortcutRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return c.deleteShortcut.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// ShortcutServiceHandler is an implementation of the memos.api.v1.ShortcutService service.
|
||||
type ShortcutServiceHandler interface {
|
||||
// ListShortcuts returns a list of shortcuts for a user.
|
||||
ListShortcuts(context.Context, *connect.Request[v1.ListShortcutsRequest]) (*connect.Response[v1.ListShortcutsResponse], error)
|
||||
// GetShortcut gets a shortcut by name.
|
||||
GetShortcut(context.Context, *connect.Request[v1.GetShortcutRequest]) (*connect.Response[v1.Shortcut], error)
|
||||
// CreateShortcut creates a new shortcut for a user.
|
||||
CreateShortcut(context.Context, *connect.Request[v1.CreateShortcutRequest]) (*connect.Response[v1.Shortcut], error)
|
||||
// UpdateShortcut updates a shortcut for a user.
|
||||
UpdateShortcut(context.Context, *connect.Request[v1.UpdateShortcutRequest]) (*connect.Response[v1.Shortcut], error)
|
||||
// DeleteShortcut deletes a shortcut for a user.
|
||||
DeleteShortcut(context.Context, *connect.Request[v1.DeleteShortcutRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
}
|
||||
|
||||
// NewShortcutServiceHandler builds an HTTP handler from the service implementation. It returns the
|
||||
// path on which to mount the handler and the handler itself.
|
||||
//
|
||||
// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
|
||||
// and JSON codecs. They also support gzip compression.
|
||||
func NewShortcutServiceHandler(svc ShortcutServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
|
||||
shortcutServiceMethods := v1.File_api_v1_shortcut_service_proto.Services().ByName("ShortcutService").Methods()
|
||||
shortcutServiceListShortcutsHandler := connect.NewUnaryHandler(
|
||||
ShortcutServiceListShortcutsProcedure,
|
||||
svc.ListShortcuts,
|
||||
connect.WithSchema(shortcutServiceMethods.ByName("ListShortcuts")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
shortcutServiceGetShortcutHandler := connect.NewUnaryHandler(
|
||||
ShortcutServiceGetShortcutProcedure,
|
||||
svc.GetShortcut,
|
||||
connect.WithSchema(shortcutServiceMethods.ByName("GetShortcut")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
shortcutServiceCreateShortcutHandler := connect.NewUnaryHandler(
|
||||
ShortcutServiceCreateShortcutProcedure,
|
||||
svc.CreateShortcut,
|
||||
connect.WithSchema(shortcutServiceMethods.ByName("CreateShortcut")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
shortcutServiceUpdateShortcutHandler := connect.NewUnaryHandler(
|
||||
ShortcutServiceUpdateShortcutProcedure,
|
||||
svc.UpdateShortcut,
|
||||
connect.WithSchema(shortcutServiceMethods.ByName("UpdateShortcut")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
shortcutServiceDeleteShortcutHandler := connect.NewUnaryHandler(
|
||||
ShortcutServiceDeleteShortcutProcedure,
|
||||
svc.DeleteShortcut,
|
||||
connect.WithSchema(shortcutServiceMethods.ByName("DeleteShortcut")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
return "/memos.api.v1.ShortcutService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case ShortcutServiceListShortcutsProcedure:
|
||||
shortcutServiceListShortcutsHandler.ServeHTTP(w, r)
|
||||
case ShortcutServiceGetShortcutProcedure:
|
||||
shortcutServiceGetShortcutHandler.ServeHTTP(w, r)
|
||||
case ShortcutServiceCreateShortcutProcedure:
|
||||
shortcutServiceCreateShortcutHandler.ServeHTTP(w, r)
|
||||
case ShortcutServiceUpdateShortcutProcedure:
|
||||
shortcutServiceUpdateShortcutHandler.ServeHTTP(w, r)
|
||||
case ShortcutServiceDeleteShortcutProcedure:
|
||||
shortcutServiceDeleteShortcutHandler.ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// UnimplementedShortcutServiceHandler returns CodeUnimplemented from all methods.
|
||||
type UnimplementedShortcutServiceHandler struct{}
|
||||
|
||||
func (UnimplementedShortcutServiceHandler) ListShortcuts(context.Context, *connect.Request[v1.ListShortcutsRequest]) (*connect.Response[v1.ListShortcutsResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.ShortcutService.ListShortcuts is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedShortcutServiceHandler) GetShortcut(context.Context, *connect.Request[v1.GetShortcutRequest]) (*connect.Response[v1.Shortcut], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.ShortcutService.GetShortcut is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedShortcutServiceHandler) CreateShortcut(context.Context, *connect.Request[v1.CreateShortcutRequest]) (*connect.Response[v1.Shortcut], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.ShortcutService.CreateShortcut is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedShortcutServiceHandler) UpdateShortcut(context.Context, *connect.Request[v1.UpdateShortcutRequest]) (*connect.Response[v1.Shortcut], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.ShortcutService.UpdateShortcut is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedShortcutServiceHandler) DeleteShortcut(context.Context, *connect.Request[v1.DeleteShortcutRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.ShortcutService.DeleteShortcut is not implemented"))
|
||||
}
|
||||
|
|
@ -0,0 +1,764 @@
|
|||
// Code generated by protoc-gen-connect-go. DO NOT EDIT.
|
||||
//
|
||||
// Source: api/v1/user_service.proto
|
||||
|
||||
package apiv1connect
|
||||
|
||||
import (
|
||||
connect "connectrpc.com/connect"
|
||||
context "context"
|
||||
errors "errors"
|
||||
v1 "github.com/usememos/memos/proto/gen/api/v1"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
http "net/http"
|
||||
strings "strings"
|
||||
)
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file and the connect package are
|
||||
// compatible. If you get a compiler error that this constant is not defined, this code was
|
||||
// generated with a version of connect newer than the one compiled into your binary. You can fix the
|
||||
// problem by either regenerating this code with an older version of connect or updating the connect
|
||||
// version compiled into your binary.
|
||||
const _ = connect.IsAtLeastVersion1_13_0
|
||||
|
||||
const (
|
||||
// UserServiceName is the fully-qualified name of the UserService service.
|
||||
UserServiceName = "memos.api.v1.UserService"
|
||||
)
|
||||
|
||||
// These constants are the fully-qualified names of the RPCs defined in this package. They're
|
||||
// exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route.
|
||||
//
|
||||
// Note that these are different from the fully-qualified method names used by
|
||||
// google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to
|
||||
// reflection-formatted method names, remove the leading slash and convert the remaining slash to a
|
||||
// period.
|
||||
const (
|
||||
// UserServiceListUsersProcedure is the fully-qualified name of the UserService's ListUsers RPC.
|
||||
UserServiceListUsersProcedure = "/memos.api.v1.UserService/ListUsers"
|
||||
// UserServiceGetUserProcedure is the fully-qualified name of the UserService's GetUser RPC.
|
||||
UserServiceGetUserProcedure = "/memos.api.v1.UserService/GetUser"
|
||||
// UserServiceCreateUserProcedure is the fully-qualified name of the UserService's CreateUser RPC.
|
||||
UserServiceCreateUserProcedure = "/memos.api.v1.UserService/CreateUser"
|
||||
// UserServiceUpdateUserProcedure is the fully-qualified name of the UserService's UpdateUser RPC.
|
||||
UserServiceUpdateUserProcedure = "/memos.api.v1.UserService/UpdateUser"
|
||||
// UserServiceDeleteUserProcedure is the fully-qualified name of the UserService's DeleteUser RPC.
|
||||
UserServiceDeleteUserProcedure = "/memos.api.v1.UserService/DeleteUser"
|
||||
// UserServiceListAllUserStatsProcedure is the fully-qualified name of the UserService's
|
||||
// ListAllUserStats RPC.
|
||||
UserServiceListAllUserStatsProcedure = "/memos.api.v1.UserService/ListAllUserStats"
|
||||
// UserServiceGetUserStatsProcedure is the fully-qualified name of the UserService's GetUserStats
|
||||
// RPC.
|
||||
UserServiceGetUserStatsProcedure = "/memos.api.v1.UserService/GetUserStats"
|
||||
// UserServiceGetUserSettingProcedure is the fully-qualified name of the UserService's
|
||||
// GetUserSetting RPC.
|
||||
UserServiceGetUserSettingProcedure = "/memos.api.v1.UserService/GetUserSetting"
|
||||
// UserServiceUpdateUserSettingProcedure is the fully-qualified name of the UserService's
|
||||
// UpdateUserSetting RPC.
|
||||
UserServiceUpdateUserSettingProcedure = "/memos.api.v1.UserService/UpdateUserSetting"
|
||||
// UserServiceListUserSettingsProcedure is the fully-qualified name of the UserService's
|
||||
// ListUserSettings RPC.
|
||||
UserServiceListUserSettingsProcedure = "/memos.api.v1.UserService/ListUserSettings"
|
||||
// UserServiceListUserAccessTokensProcedure is the fully-qualified name of the UserService's
|
||||
// ListUserAccessTokens RPC.
|
||||
UserServiceListUserAccessTokensProcedure = "/memos.api.v1.UserService/ListUserAccessTokens"
|
||||
// UserServiceCreateUserAccessTokenProcedure is the fully-qualified name of the UserService's
|
||||
// CreateUserAccessToken RPC.
|
||||
UserServiceCreateUserAccessTokenProcedure = "/memos.api.v1.UserService/CreateUserAccessToken"
|
||||
// UserServiceDeleteUserAccessTokenProcedure is the fully-qualified name of the UserService's
|
||||
// DeleteUserAccessToken RPC.
|
||||
UserServiceDeleteUserAccessTokenProcedure = "/memos.api.v1.UserService/DeleteUserAccessToken"
|
||||
// UserServiceListUserSessionsProcedure is the fully-qualified name of the UserService's
|
||||
// ListUserSessions RPC.
|
||||
UserServiceListUserSessionsProcedure = "/memos.api.v1.UserService/ListUserSessions"
|
||||
// UserServiceRevokeUserSessionProcedure is the fully-qualified name of the UserService's
|
||||
// RevokeUserSession RPC.
|
||||
UserServiceRevokeUserSessionProcedure = "/memos.api.v1.UserService/RevokeUserSession"
|
||||
// UserServiceListUserWebhooksProcedure is the fully-qualified name of the UserService's
|
||||
// ListUserWebhooks RPC.
|
||||
UserServiceListUserWebhooksProcedure = "/memos.api.v1.UserService/ListUserWebhooks"
|
||||
// UserServiceCreateUserWebhookProcedure is the fully-qualified name of the UserService's
|
||||
// CreateUserWebhook RPC.
|
||||
UserServiceCreateUserWebhookProcedure = "/memos.api.v1.UserService/CreateUserWebhook"
|
||||
// UserServiceUpdateUserWebhookProcedure is the fully-qualified name of the UserService's
|
||||
// UpdateUserWebhook RPC.
|
||||
UserServiceUpdateUserWebhookProcedure = "/memos.api.v1.UserService/UpdateUserWebhook"
|
||||
// UserServiceDeleteUserWebhookProcedure is the fully-qualified name of the UserService's
|
||||
// DeleteUserWebhook RPC.
|
||||
UserServiceDeleteUserWebhookProcedure = "/memos.api.v1.UserService/DeleteUserWebhook"
|
||||
// UserServiceListUserNotificationsProcedure is the fully-qualified name of the UserService's
|
||||
// ListUserNotifications RPC.
|
||||
UserServiceListUserNotificationsProcedure = "/memos.api.v1.UserService/ListUserNotifications"
|
||||
// UserServiceUpdateUserNotificationProcedure is the fully-qualified name of the UserService's
|
||||
// UpdateUserNotification RPC.
|
||||
UserServiceUpdateUserNotificationProcedure = "/memos.api.v1.UserService/UpdateUserNotification"
|
||||
// UserServiceDeleteUserNotificationProcedure is the fully-qualified name of the UserService's
|
||||
// DeleteUserNotification RPC.
|
||||
UserServiceDeleteUserNotificationProcedure = "/memos.api.v1.UserService/DeleteUserNotification"
|
||||
)
|
||||
|
||||
// UserServiceClient is a client for the memos.api.v1.UserService service.
|
||||
type UserServiceClient interface {
|
||||
// ListUsers returns a list of users.
|
||||
ListUsers(context.Context, *connect.Request[v1.ListUsersRequest]) (*connect.Response[v1.ListUsersResponse], error)
|
||||
// GetUser gets a user by ID or username.
|
||||
// Supports both numeric IDs and username strings:
|
||||
// - users/{id} (e.g., users/101)
|
||||
// - users/{username} (e.g., users/steven)
|
||||
GetUser(context.Context, *connect.Request[v1.GetUserRequest]) (*connect.Response[v1.User], error)
|
||||
// CreateUser creates a new user.
|
||||
CreateUser(context.Context, *connect.Request[v1.CreateUserRequest]) (*connect.Response[v1.User], error)
|
||||
// UpdateUser updates a user.
|
||||
UpdateUser(context.Context, *connect.Request[v1.UpdateUserRequest]) (*connect.Response[v1.User], error)
|
||||
// DeleteUser deletes a user.
|
||||
DeleteUser(context.Context, *connect.Request[v1.DeleteUserRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
// ListAllUserStats returns statistics for all users.
|
||||
ListAllUserStats(context.Context, *connect.Request[v1.ListAllUserStatsRequest]) (*connect.Response[v1.ListAllUserStatsResponse], error)
|
||||
// GetUserStats returns statistics for a specific user.
|
||||
GetUserStats(context.Context, *connect.Request[v1.GetUserStatsRequest]) (*connect.Response[v1.UserStats], error)
|
||||
// GetUserSetting returns the user setting.
|
||||
GetUserSetting(context.Context, *connect.Request[v1.GetUserSettingRequest]) (*connect.Response[v1.UserSetting], error)
|
||||
// UpdateUserSetting updates the user setting.
|
||||
UpdateUserSetting(context.Context, *connect.Request[v1.UpdateUserSettingRequest]) (*connect.Response[v1.UserSetting], error)
|
||||
// ListUserSettings returns a list of user settings.
|
||||
ListUserSettings(context.Context, *connect.Request[v1.ListUserSettingsRequest]) (*connect.Response[v1.ListUserSettingsResponse], error)
|
||||
// ListUserAccessTokens returns a list of access tokens for a user.
|
||||
ListUserAccessTokens(context.Context, *connect.Request[v1.ListUserAccessTokensRequest]) (*connect.Response[v1.ListUserAccessTokensResponse], error)
|
||||
// CreateUserAccessToken creates a new access token for a user.
|
||||
CreateUserAccessToken(context.Context, *connect.Request[v1.CreateUserAccessTokenRequest]) (*connect.Response[v1.UserAccessToken], error)
|
||||
// DeleteUserAccessToken deletes an access token.
|
||||
DeleteUserAccessToken(context.Context, *connect.Request[v1.DeleteUserAccessTokenRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
// ListUserSessions returns a list of active sessions for a user.
|
||||
ListUserSessions(context.Context, *connect.Request[v1.ListUserSessionsRequest]) (*connect.Response[v1.ListUserSessionsResponse], error)
|
||||
// RevokeUserSession revokes a specific session for a user.
|
||||
RevokeUserSession(context.Context, *connect.Request[v1.RevokeUserSessionRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
// ListUserWebhooks returns a list of webhooks for a user.
|
||||
ListUserWebhooks(context.Context, *connect.Request[v1.ListUserWebhooksRequest]) (*connect.Response[v1.ListUserWebhooksResponse], error)
|
||||
// CreateUserWebhook creates a new webhook for a user.
|
||||
CreateUserWebhook(context.Context, *connect.Request[v1.CreateUserWebhookRequest]) (*connect.Response[v1.UserWebhook], error)
|
||||
// UpdateUserWebhook updates an existing webhook for a user.
|
||||
UpdateUserWebhook(context.Context, *connect.Request[v1.UpdateUserWebhookRequest]) (*connect.Response[v1.UserWebhook], error)
|
||||
// DeleteUserWebhook deletes a webhook for a user.
|
||||
DeleteUserWebhook(context.Context, *connect.Request[v1.DeleteUserWebhookRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
// ListUserNotifications lists notifications for a user.
|
||||
ListUserNotifications(context.Context, *connect.Request[v1.ListUserNotificationsRequest]) (*connect.Response[v1.ListUserNotificationsResponse], error)
|
||||
// UpdateUserNotification updates a notification.
|
||||
UpdateUserNotification(context.Context, *connect.Request[v1.UpdateUserNotificationRequest]) (*connect.Response[v1.UserNotification], error)
|
||||
// DeleteUserNotification deletes a notification.
|
||||
DeleteUserNotification(context.Context, *connect.Request[v1.DeleteUserNotificationRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
}
|
||||
|
||||
// NewUserServiceClient constructs a client for the memos.api.v1.UserService service. By default, it
|
||||
// uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and sends
|
||||
// uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or
|
||||
// connect.WithGRPCWeb() options.
|
||||
//
|
||||
// The URL supplied here should be the base URL for the Connect or gRPC server (for example,
|
||||
// http://api.acme.com or https://acme.com/grpc).
|
||||
func NewUserServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) UserServiceClient {
|
||||
baseURL = strings.TrimRight(baseURL, "/")
|
||||
userServiceMethods := v1.File_api_v1_user_service_proto.Services().ByName("UserService").Methods()
|
||||
return &userServiceClient{
|
||||
listUsers: connect.NewClient[v1.ListUsersRequest, v1.ListUsersResponse](
|
||||
httpClient,
|
||||
baseURL+UserServiceListUsersProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("ListUsers")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
getUser: connect.NewClient[v1.GetUserRequest, v1.User](
|
||||
httpClient,
|
||||
baseURL+UserServiceGetUserProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("GetUser")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
createUser: connect.NewClient[v1.CreateUserRequest, v1.User](
|
||||
httpClient,
|
||||
baseURL+UserServiceCreateUserProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("CreateUser")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
updateUser: connect.NewClient[v1.UpdateUserRequest, v1.User](
|
||||
httpClient,
|
||||
baseURL+UserServiceUpdateUserProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("UpdateUser")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
deleteUser: connect.NewClient[v1.DeleteUserRequest, emptypb.Empty](
|
||||
httpClient,
|
||||
baseURL+UserServiceDeleteUserProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("DeleteUser")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
listAllUserStats: connect.NewClient[v1.ListAllUserStatsRequest, v1.ListAllUserStatsResponse](
|
||||
httpClient,
|
||||
baseURL+UserServiceListAllUserStatsProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("ListAllUserStats")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
getUserStats: connect.NewClient[v1.GetUserStatsRequest, v1.UserStats](
|
||||
httpClient,
|
||||
baseURL+UserServiceGetUserStatsProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("GetUserStats")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
getUserSetting: connect.NewClient[v1.GetUserSettingRequest, v1.UserSetting](
|
||||
httpClient,
|
||||
baseURL+UserServiceGetUserSettingProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("GetUserSetting")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
updateUserSetting: connect.NewClient[v1.UpdateUserSettingRequest, v1.UserSetting](
|
||||
httpClient,
|
||||
baseURL+UserServiceUpdateUserSettingProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("UpdateUserSetting")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
listUserSettings: connect.NewClient[v1.ListUserSettingsRequest, v1.ListUserSettingsResponse](
|
||||
httpClient,
|
||||
baseURL+UserServiceListUserSettingsProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("ListUserSettings")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
listUserAccessTokens: connect.NewClient[v1.ListUserAccessTokensRequest, v1.ListUserAccessTokensResponse](
|
||||
httpClient,
|
||||
baseURL+UserServiceListUserAccessTokensProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("ListUserAccessTokens")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
createUserAccessToken: connect.NewClient[v1.CreateUserAccessTokenRequest, v1.UserAccessToken](
|
||||
httpClient,
|
||||
baseURL+UserServiceCreateUserAccessTokenProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("CreateUserAccessToken")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
deleteUserAccessToken: connect.NewClient[v1.DeleteUserAccessTokenRequest, emptypb.Empty](
|
||||
httpClient,
|
||||
baseURL+UserServiceDeleteUserAccessTokenProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("DeleteUserAccessToken")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
listUserSessions: connect.NewClient[v1.ListUserSessionsRequest, v1.ListUserSessionsResponse](
|
||||
httpClient,
|
||||
baseURL+UserServiceListUserSessionsProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("ListUserSessions")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
revokeUserSession: connect.NewClient[v1.RevokeUserSessionRequest, emptypb.Empty](
|
||||
httpClient,
|
||||
baseURL+UserServiceRevokeUserSessionProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("RevokeUserSession")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
listUserWebhooks: connect.NewClient[v1.ListUserWebhooksRequest, v1.ListUserWebhooksResponse](
|
||||
httpClient,
|
||||
baseURL+UserServiceListUserWebhooksProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("ListUserWebhooks")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
createUserWebhook: connect.NewClient[v1.CreateUserWebhookRequest, v1.UserWebhook](
|
||||
httpClient,
|
||||
baseURL+UserServiceCreateUserWebhookProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("CreateUserWebhook")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
updateUserWebhook: connect.NewClient[v1.UpdateUserWebhookRequest, v1.UserWebhook](
|
||||
httpClient,
|
||||
baseURL+UserServiceUpdateUserWebhookProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("UpdateUserWebhook")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
deleteUserWebhook: connect.NewClient[v1.DeleteUserWebhookRequest, emptypb.Empty](
|
||||
httpClient,
|
||||
baseURL+UserServiceDeleteUserWebhookProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("DeleteUserWebhook")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
listUserNotifications: connect.NewClient[v1.ListUserNotificationsRequest, v1.ListUserNotificationsResponse](
|
||||
httpClient,
|
||||
baseURL+UserServiceListUserNotificationsProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("ListUserNotifications")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
updateUserNotification: connect.NewClient[v1.UpdateUserNotificationRequest, v1.UserNotification](
|
||||
httpClient,
|
||||
baseURL+UserServiceUpdateUserNotificationProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("UpdateUserNotification")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
deleteUserNotification: connect.NewClient[v1.DeleteUserNotificationRequest, emptypb.Empty](
|
||||
httpClient,
|
||||
baseURL+UserServiceDeleteUserNotificationProcedure,
|
||||
connect.WithSchema(userServiceMethods.ByName("DeleteUserNotification")),
|
||||
connect.WithClientOptions(opts...),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// userServiceClient implements UserServiceClient.
|
||||
type userServiceClient struct {
|
||||
listUsers *connect.Client[v1.ListUsersRequest, v1.ListUsersResponse]
|
||||
getUser *connect.Client[v1.GetUserRequest, v1.User]
|
||||
createUser *connect.Client[v1.CreateUserRequest, v1.User]
|
||||
updateUser *connect.Client[v1.UpdateUserRequest, v1.User]
|
||||
deleteUser *connect.Client[v1.DeleteUserRequest, emptypb.Empty]
|
||||
listAllUserStats *connect.Client[v1.ListAllUserStatsRequest, v1.ListAllUserStatsResponse]
|
||||
getUserStats *connect.Client[v1.GetUserStatsRequest, v1.UserStats]
|
||||
getUserSetting *connect.Client[v1.GetUserSettingRequest, v1.UserSetting]
|
||||
updateUserSetting *connect.Client[v1.UpdateUserSettingRequest, v1.UserSetting]
|
||||
listUserSettings *connect.Client[v1.ListUserSettingsRequest, v1.ListUserSettingsResponse]
|
||||
listUserAccessTokens *connect.Client[v1.ListUserAccessTokensRequest, v1.ListUserAccessTokensResponse]
|
||||
createUserAccessToken *connect.Client[v1.CreateUserAccessTokenRequest, v1.UserAccessToken]
|
||||
deleteUserAccessToken *connect.Client[v1.DeleteUserAccessTokenRequest, emptypb.Empty]
|
||||
listUserSessions *connect.Client[v1.ListUserSessionsRequest, v1.ListUserSessionsResponse]
|
||||
revokeUserSession *connect.Client[v1.RevokeUserSessionRequest, emptypb.Empty]
|
||||
listUserWebhooks *connect.Client[v1.ListUserWebhooksRequest, v1.ListUserWebhooksResponse]
|
||||
createUserWebhook *connect.Client[v1.CreateUserWebhookRequest, v1.UserWebhook]
|
||||
updateUserWebhook *connect.Client[v1.UpdateUserWebhookRequest, v1.UserWebhook]
|
||||
deleteUserWebhook *connect.Client[v1.DeleteUserWebhookRequest, emptypb.Empty]
|
||||
listUserNotifications *connect.Client[v1.ListUserNotificationsRequest, v1.ListUserNotificationsResponse]
|
||||
updateUserNotification *connect.Client[v1.UpdateUserNotificationRequest, v1.UserNotification]
|
||||
deleteUserNotification *connect.Client[v1.DeleteUserNotificationRequest, emptypb.Empty]
|
||||
}
|
||||
|
||||
// ListUsers calls memos.api.v1.UserService.ListUsers.
|
||||
func (c *userServiceClient) ListUsers(ctx context.Context, req *connect.Request[v1.ListUsersRequest]) (*connect.Response[v1.ListUsersResponse], error) {
|
||||
return c.listUsers.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// GetUser calls memos.api.v1.UserService.GetUser.
|
||||
func (c *userServiceClient) GetUser(ctx context.Context, req *connect.Request[v1.GetUserRequest]) (*connect.Response[v1.User], error) {
|
||||
return c.getUser.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// CreateUser calls memos.api.v1.UserService.CreateUser.
|
||||
func (c *userServiceClient) CreateUser(ctx context.Context, req *connect.Request[v1.CreateUserRequest]) (*connect.Response[v1.User], error) {
|
||||
return c.createUser.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// UpdateUser calls memos.api.v1.UserService.UpdateUser.
|
||||
func (c *userServiceClient) UpdateUser(ctx context.Context, req *connect.Request[v1.UpdateUserRequest]) (*connect.Response[v1.User], error) {
|
||||
return c.updateUser.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// DeleteUser calls memos.api.v1.UserService.DeleteUser.
|
||||
func (c *userServiceClient) DeleteUser(ctx context.Context, req *connect.Request[v1.DeleteUserRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return c.deleteUser.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// ListAllUserStats calls memos.api.v1.UserService.ListAllUserStats.
|
||||
func (c *userServiceClient) ListAllUserStats(ctx context.Context, req *connect.Request[v1.ListAllUserStatsRequest]) (*connect.Response[v1.ListAllUserStatsResponse], error) {
|
||||
return c.listAllUserStats.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// GetUserStats calls memos.api.v1.UserService.GetUserStats.
|
||||
func (c *userServiceClient) GetUserStats(ctx context.Context, req *connect.Request[v1.GetUserStatsRequest]) (*connect.Response[v1.UserStats], error) {
|
||||
return c.getUserStats.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// GetUserSetting calls memos.api.v1.UserService.GetUserSetting.
|
||||
func (c *userServiceClient) GetUserSetting(ctx context.Context, req *connect.Request[v1.GetUserSettingRequest]) (*connect.Response[v1.UserSetting], error) {
|
||||
return c.getUserSetting.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// UpdateUserSetting calls memos.api.v1.UserService.UpdateUserSetting.
|
||||
func (c *userServiceClient) UpdateUserSetting(ctx context.Context, req *connect.Request[v1.UpdateUserSettingRequest]) (*connect.Response[v1.UserSetting], error) {
|
||||
return c.updateUserSetting.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// ListUserSettings calls memos.api.v1.UserService.ListUserSettings.
|
||||
func (c *userServiceClient) ListUserSettings(ctx context.Context, req *connect.Request[v1.ListUserSettingsRequest]) (*connect.Response[v1.ListUserSettingsResponse], error) {
|
||||
return c.listUserSettings.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// ListUserAccessTokens calls memos.api.v1.UserService.ListUserAccessTokens.
|
||||
func (c *userServiceClient) ListUserAccessTokens(ctx context.Context, req *connect.Request[v1.ListUserAccessTokensRequest]) (*connect.Response[v1.ListUserAccessTokensResponse], error) {
|
||||
return c.listUserAccessTokens.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// CreateUserAccessToken calls memos.api.v1.UserService.CreateUserAccessToken.
|
||||
func (c *userServiceClient) CreateUserAccessToken(ctx context.Context, req *connect.Request[v1.CreateUserAccessTokenRequest]) (*connect.Response[v1.UserAccessToken], error) {
|
||||
return c.createUserAccessToken.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// DeleteUserAccessToken calls memos.api.v1.UserService.DeleteUserAccessToken.
|
||||
func (c *userServiceClient) DeleteUserAccessToken(ctx context.Context, req *connect.Request[v1.DeleteUserAccessTokenRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return c.deleteUserAccessToken.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// ListUserSessions calls memos.api.v1.UserService.ListUserSessions.
|
||||
func (c *userServiceClient) ListUserSessions(ctx context.Context, req *connect.Request[v1.ListUserSessionsRequest]) (*connect.Response[v1.ListUserSessionsResponse], error) {
|
||||
return c.listUserSessions.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// RevokeUserSession calls memos.api.v1.UserService.RevokeUserSession.
|
||||
func (c *userServiceClient) RevokeUserSession(ctx context.Context, req *connect.Request[v1.RevokeUserSessionRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return c.revokeUserSession.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// ListUserWebhooks calls memos.api.v1.UserService.ListUserWebhooks.
|
||||
func (c *userServiceClient) ListUserWebhooks(ctx context.Context, req *connect.Request[v1.ListUserWebhooksRequest]) (*connect.Response[v1.ListUserWebhooksResponse], error) {
|
||||
return c.listUserWebhooks.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// CreateUserWebhook calls memos.api.v1.UserService.CreateUserWebhook.
|
||||
func (c *userServiceClient) CreateUserWebhook(ctx context.Context, req *connect.Request[v1.CreateUserWebhookRequest]) (*connect.Response[v1.UserWebhook], error) {
|
||||
return c.createUserWebhook.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// UpdateUserWebhook calls memos.api.v1.UserService.UpdateUserWebhook.
|
||||
func (c *userServiceClient) UpdateUserWebhook(ctx context.Context, req *connect.Request[v1.UpdateUserWebhookRequest]) (*connect.Response[v1.UserWebhook], error) {
|
||||
return c.updateUserWebhook.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// DeleteUserWebhook calls memos.api.v1.UserService.DeleteUserWebhook.
|
||||
func (c *userServiceClient) DeleteUserWebhook(ctx context.Context, req *connect.Request[v1.DeleteUserWebhookRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return c.deleteUserWebhook.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// ListUserNotifications calls memos.api.v1.UserService.ListUserNotifications.
|
||||
func (c *userServiceClient) ListUserNotifications(ctx context.Context, req *connect.Request[v1.ListUserNotificationsRequest]) (*connect.Response[v1.ListUserNotificationsResponse], error) {
|
||||
return c.listUserNotifications.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// UpdateUserNotification calls memos.api.v1.UserService.UpdateUserNotification.
|
||||
func (c *userServiceClient) UpdateUserNotification(ctx context.Context, req *connect.Request[v1.UpdateUserNotificationRequest]) (*connect.Response[v1.UserNotification], error) {
|
||||
return c.updateUserNotification.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// DeleteUserNotification calls memos.api.v1.UserService.DeleteUserNotification.
|
||||
func (c *userServiceClient) DeleteUserNotification(ctx context.Context, req *connect.Request[v1.DeleteUserNotificationRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return c.deleteUserNotification.CallUnary(ctx, req)
|
||||
}
|
||||
|
||||
// UserServiceHandler is an implementation of the memos.api.v1.UserService service.
|
||||
type UserServiceHandler interface {
|
||||
// ListUsers returns a list of users.
|
||||
ListUsers(context.Context, *connect.Request[v1.ListUsersRequest]) (*connect.Response[v1.ListUsersResponse], error)
|
||||
// GetUser gets a user by ID or username.
|
||||
// Supports both numeric IDs and username strings:
|
||||
// - users/{id} (e.g., users/101)
|
||||
// - users/{username} (e.g., users/steven)
|
||||
GetUser(context.Context, *connect.Request[v1.GetUserRequest]) (*connect.Response[v1.User], error)
|
||||
// CreateUser creates a new user.
|
||||
CreateUser(context.Context, *connect.Request[v1.CreateUserRequest]) (*connect.Response[v1.User], error)
|
||||
// UpdateUser updates a user.
|
||||
UpdateUser(context.Context, *connect.Request[v1.UpdateUserRequest]) (*connect.Response[v1.User], error)
|
||||
// DeleteUser deletes a user.
|
||||
DeleteUser(context.Context, *connect.Request[v1.DeleteUserRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
// ListAllUserStats returns statistics for all users.
|
||||
ListAllUserStats(context.Context, *connect.Request[v1.ListAllUserStatsRequest]) (*connect.Response[v1.ListAllUserStatsResponse], error)
|
||||
// GetUserStats returns statistics for a specific user.
|
||||
GetUserStats(context.Context, *connect.Request[v1.GetUserStatsRequest]) (*connect.Response[v1.UserStats], error)
|
||||
// GetUserSetting returns the user setting.
|
||||
GetUserSetting(context.Context, *connect.Request[v1.GetUserSettingRequest]) (*connect.Response[v1.UserSetting], error)
|
||||
// UpdateUserSetting updates the user setting.
|
||||
UpdateUserSetting(context.Context, *connect.Request[v1.UpdateUserSettingRequest]) (*connect.Response[v1.UserSetting], error)
|
||||
// ListUserSettings returns a list of user settings.
|
||||
ListUserSettings(context.Context, *connect.Request[v1.ListUserSettingsRequest]) (*connect.Response[v1.ListUserSettingsResponse], error)
|
||||
// ListUserAccessTokens returns a list of access tokens for a user.
|
||||
ListUserAccessTokens(context.Context, *connect.Request[v1.ListUserAccessTokensRequest]) (*connect.Response[v1.ListUserAccessTokensResponse], error)
|
||||
// CreateUserAccessToken creates a new access token for a user.
|
||||
CreateUserAccessToken(context.Context, *connect.Request[v1.CreateUserAccessTokenRequest]) (*connect.Response[v1.UserAccessToken], error)
|
||||
// DeleteUserAccessToken deletes an access token.
|
||||
DeleteUserAccessToken(context.Context, *connect.Request[v1.DeleteUserAccessTokenRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
// ListUserSessions returns a list of active sessions for a user.
|
||||
ListUserSessions(context.Context, *connect.Request[v1.ListUserSessionsRequest]) (*connect.Response[v1.ListUserSessionsResponse], error)
|
||||
// RevokeUserSession revokes a specific session for a user.
|
||||
RevokeUserSession(context.Context, *connect.Request[v1.RevokeUserSessionRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
// ListUserWebhooks returns a list of webhooks for a user.
|
||||
ListUserWebhooks(context.Context, *connect.Request[v1.ListUserWebhooksRequest]) (*connect.Response[v1.ListUserWebhooksResponse], error)
|
||||
// CreateUserWebhook creates a new webhook for a user.
|
||||
CreateUserWebhook(context.Context, *connect.Request[v1.CreateUserWebhookRequest]) (*connect.Response[v1.UserWebhook], error)
|
||||
// UpdateUserWebhook updates an existing webhook for a user.
|
||||
UpdateUserWebhook(context.Context, *connect.Request[v1.UpdateUserWebhookRequest]) (*connect.Response[v1.UserWebhook], error)
|
||||
// DeleteUserWebhook deletes a webhook for a user.
|
||||
DeleteUserWebhook(context.Context, *connect.Request[v1.DeleteUserWebhookRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
// ListUserNotifications lists notifications for a user.
|
||||
ListUserNotifications(context.Context, *connect.Request[v1.ListUserNotificationsRequest]) (*connect.Response[v1.ListUserNotificationsResponse], error)
|
||||
// UpdateUserNotification updates a notification.
|
||||
UpdateUserNotification(context.Context, *connect.Request[v1.UpdateUserNotificationRequest]) (*connect.Response[v1.UserNotification], error)
|
||||
// DeleteUserNotification deletes a notification.
|
||||
DeleteUserNotification(context.Context, *connect.Request[v1.DeleteUserNotificationRequest]) (*connect.Response[emptypb.Empty], error)
|
||||
}
|
||||
|
||||
// NewUserServiceHandler builds an HTTP handler from the service implementation. It returns the path
|
||||
// on which to mount the handler and the handler itself.
|
||||
//
|
||||
// By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf
|
||||
// and JSON codecs. They also support gzip compression.
|
||||
func NewUserServiceHandler(svc UserServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) {
|
||||
userServiceMethods := v1.File_api_v1_user_service_proto.Services().ByName("UserService").Methods()
|
||||
userServiceListUsersHandler := connect.NewUnaryHandler(
|
||||
UserServiceListUsersProcedure,
|
||||
svc.ListUsers,
|
||||
connect.WithSchema(userServiceMethods.ByName("ListUsers")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceGetUserHandler := connect.NewUnaryHandler(
|
||||
UserServiceGetUserProcedure,
|
||||
svc.GetUser,
|
||||
connect.WithSchema(userServiceMethods.ByName("GetUser")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceCreateUserHandler := connect.NewUnaryHandler(
|
||||
UserServiceCreateUserProcedure,
|
||||
svc.CreateUser,
|
||||
connect.WithSchema(userServiceMethods.ByName("CreateUser")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceUpdateUserHandler := connect.NewUnaryHandler(
|
||||
UserServiceUpdateUserProcedure,
|
||||
svc.UpdateUser,
|
||||
connect.WithSchema(userServiceMethods.ByName("UpdateUser")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceDeleteUserHandler := connect.NewUnaryHandler(
|
||||
UserServiceDeleteUserProcedure,
|
||||
svc.DeleteUser,
|
||||
connect.WithSchema(userServiceMethods.ByName("DeleteUser")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceListAllUserStatsHandler := connect.NewUnaryHandler(
|
||||
UserServiceListAllUserStatsProcedure,
|
||||
svc.ListAllUserStats,
|
||||
connect.WithSchema(userServiceMethods.ByName("ListAllUserStats")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceGetUserStatsHandler := connect.NewUnaryHandler(
|
||||
UserServiceGetUserStatsProcedure,
|
||||
svc.GetUserStats,
|
||||
connect.WithSchema(userServiceMethods.ByName("GetUserStats")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceGetUserSettingHandler := connect.NewUnaryHandler(
|
||||
UserServiceGetUserSettingProcedure,
|
||||
svc.GetUserSetting,
|
||||
connect.WithSchema(userServiceMethods.ByName("GetUserSetting")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceUpdateUserSettingHandler := connect.NewUnaryHandler(
|
||||
UserServiceUpdateUserSettingProcedure,
|
||||
svc.UpdateUserSetting,
|
||||
connect.WithSchema(userServiceMethods.ByName("UpdateUserSetting")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceListUserSettingsHandler := connect.NewUnaryHandler(
|
||||
UserServiceListUserSettingsProcedure,
|
||||
svc.ListUserSettings,
|
||||
connect.WithSchema(userServiceMethods.ByName("ListUserSettings")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceListUserAccessTokensHandler := connect.NewUnaryHandler(
|
||||
UserServiceListUserAccessTokensProcedure,
|
||||
svc.ListUserAccessTokens,
|
||||
connect.WithSchema(userServiceMethods.ByName("ListUserAccessTokens")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceCreateUserAccessTokenHandler := connect.NewUnaryHandler(
|
||||
UserServiceCreateUserAccessTokenProcedure,
|
||||
svc.CreateUserAccessToken,
|
||||
connect.WithSchema(userServiceMethods.ByName("CreateUserAccessToken")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceDeleteUserAccessTokenHandler := connect.NewUnaryHandler(
|
||||
UserServiceDeleteUserAccessTokenProcedure,
|
||||
svc.DeleteUserAccessToken,
|
||||
connect.WithSchema(userServiceMethods.ByName("DeleteUserAccessToken")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceListUserSessionsHandler := connect.NewUnaryHandler(
|
||||
UserServiceListUserSessionsProcedure,
|
||||
svc.ListUserSessions,
|
||||
connect.WithSchema(userServiceMethods.ByName("ListUserSessions")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceRevokeUserSessionHandler := connect.NewUnaryHandler(
|
||||
UserServiceRevokeUserSessionProcedure,
|
||||
svc.RevokeUserSession,
|
||||
connect.WithSchema(userServiceMethods.ByName("RevokeUserSession")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceListUserWebhooksHandler := connect.NewUnaryHandler(
|
||||
UserServiceListUserWebhooksProcedure,
|
||||
svc.ListUserWebhooks,
|
||||
connect.WithSchema(userServiceMethods.ByName("ListUserWebhooks")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceCreateUserWebhookHandler := connect.NewUnaryHandler(
|
||||
UserServiceCreateUserWebhookProcedure,
|
||||
svc.CreateUserWebhook,
|
||||
connect.WithSchema(userServiceMethods.ByName("CreateUserWebhook")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceUpdateUserWebhookHandler := connect.NewUnaryHandler(
|
||||
UserServiceUpdateUserWebhookProcedure,
|
||||
svc.UpdateUserWebhook,
|
||||
connect.WithSchema(userServiceMethods.ByName("UpdateUserWebhook")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceDeleteUserWebhookHandler := connect.NewUnaryHandler(
|
||||
UserServiceDeleteUserWebhookProcedure,
|
||||
svc.DeleteUserWebhook,
|
||||
connect.WithSchema(userServiceMethods.ByName("DeleteUserWebhook")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceListUserNotificationsHandler := connect.NewUnaryHandler(
|
||||
UserServiceListUserNotificationsProcedure,
|
||||
svc.ListUserNotifications,
|
||||
connect.WithSchema(userServiceMethods.ByName("ListUserNotifications")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceUpdateUserNotificationHandler := connect.NewUnaryHandler(
|
||||
UserServiceUpdateUserNotificationProcedure,
|
||||
svc.UpdateUserNotification,
|
||||
connect.WithSchema(userServiceMethods.ByName("UpdateUserNotification")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
userServiceDeleteUserNotificationHandler := connect.NewUnaryHandler(
|
||||
UserServiceDeleteUserNotificationProcedure,
|
||||
svc.DeleteUserNotification,
|
||||
connect.WithSchema(userServiceMethods.ByName("DeleteUserNotification")),
|
||||
connect.WithHandlerOptions(opts...),
|
||||
)
|
||||
return "/memos.api.v1.UserService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case UserServiceListUsersProcedure:
|
||||
userServiceListUsersHandler.ServeHTTP(w, r)
|
||||
case UserServiceGetUserProcedure:
|
||||
userServiceGetUserHandler.ServeHTTP(w, r)
|
||||
case UserServiceCreateUserProcedure:
|
||||
userServiceCreateUserHandler.ServeHTTP(w, r)
|
||||
case UserServiceUpdateUserProcedure:
|
||||
userServiceUpdateUserHandler.ServeHTTP(w, r)
|
||||
case UserServiceDeleteUserProcedure:
|
||||
userServiceDeleteUserHandler.ServeHTTP(w, r)
|
||||
case UserServiceListAllUserStatsProcedure:
|
||||
userServiceListAllUserStatsHandler.ServeHTTP(w, r)
|
||||
case UserServiceGetUserStatsProcedure:
|
||||
userServiceGetUserStatsHandler.ServeHTTP(w, r)
|
||||
case UserServiceGetUserSettingProcedure:
|
||||
userServiceGetUserSettingHandler.ServeHTTP(w, r)
|
||||
case UserServiceUpdateUserSettingProcedure:
|
||||
userServiceUpdateUserSettingHandler.ServeHTTP(w, r)
|
||||
case UserServiceListUserSettingsProcedure:
|
||||
userServiceListUserSettingsHandler.ServeHTTP(w, r)
|
||||
case UserServiceListUserAccessTokensProcedure:
|
||||
userServiceListUserAccessTokensHandler.ServeHTTP(w, r)
|
||||
case UserServiceCreateUserAccessTokenProcedure:
|
||||
userServiceCreateUserAccessTokenHandler.ServeHTTP(w, r)
|
||||
case UserServiceDeleteUserAccessTokenProcedure:
|
||||
userServiceDeleteUserAccessTokenHandler.ServeHTTP(w, r)
|
||||
case UserServiceListUserSessionsProcedure:
|
||||
userServiceListUserSessionsHandler.ServeHTTP(w, r)
|
||||
case UserServiceRevokeUserSessionProcedure:
|
||||
userServiceRevokeUserSessionHandler.ServeHTTP(w, r)
|
||||
case UserServiceListUserWebhooksProcedure:
|
||||
userServiceListUserWebhooksHandler.ServeHTTP(w, r)
|
||||
case UserServiceCreateUserWebhookProcedure:
|
||||
userServiceCreateUserWebhookHandler.ServeHTTP(w, r)
|
||||
case UserServiceUpdateUserWebhookProcedure:
|
||||
userServiceUpdateUserWebhookHandler.ServeHTTP(w, r)
|
||||
case UserServiceDeleteUserWebhookProcedure:
|
||||
userServiceDeleteUserWebhookHandler.ServeHTTP(w, r)
|
||||
case UserServiceListUserNotificationsProcedure:
|
||||
userServiceListUserNotificationsHandler.ServeHTTP(w, r)
|
||||
case UserServiceUpdateUserNotificationProcedure:
|
||||
userServiceUpdateUserNotificationHandler.ServeHTTP(w, r)
|
||||
case UserServiceDeleteUserNotificationProcedure:
|
||||
userServiceDeleteUserNotificationHandler.ServeHTTP(w, r)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// UnimplementedUserServiceHandler returns CodeUnimplemented from all methods.
|
||||
type UnimplementedUserServiceHandler struct{}
|
||||
|
||||
func (UnimplementedUserServiceHandler) ListUsers(context.Context, *connect.Request[v1.ListUsersRequest]) (*connect.Response[v1.ListUsersResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.ListUsers is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) GetUser(context.Context, *connect.Request[v1.GetUserRequest]) (*connect.Response[v1.User], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.GetUser is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) CreateUser(context.Context, *connect.Request[v1.CreateUserRequest]) (*connect.Response[v1.User], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.CreateUser is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) UpdateUser(context.Context, *connect.Request[v1.UpdateUserRequest]) (*connect.Response[v1.User], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.UpdateUser is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) DeleteUser(context.Context, *connect.Request[v1.DeleteUserRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.DeleteUser is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) ListAllUserStats(context.Context, *connect.Request[v1.ListAllUserStatsRequest]) (*connect.Response[v1.ListAllUserStatsResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.ListAllUserStats is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) GetUserStats(context.Context, *connect.Request[v1.GetUserStatsRequest]) (*connect.Response[v1.UserStats], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.GetUserStats is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) GetUserSetting(context.Context, *connect.Request[v1.GetUserSettingRequest]) (*connect.Response[v1.UserSetting], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.GetUserSetting is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) UpdateUserSetting(context.Context, *connect.Request[v1.UpdateUserSettingRequest]) (*connect.Response[v1.UserSetting], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.UpdateUserSetting is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) ListUserSettings(context.Context, *connect.Request[v1.ListUserSettingsRequest]) (*connect.Response[v1.ListUserSettingsResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.ListUserSettings is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) ListUserAccessTokens(context.Context, *connect.Request[v1.ListUserAccessTokensRequest]) (*connect.Response[v1.ListUserAccessTokensResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.ListUserAccessTokens is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) CreateUserAccessToken(context.Context, *connect.Request[v1.CreateUserAccessTokenRequest]) (*connect.Response[v1.UserAccessToken], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.CreateUserAccessToken is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) DeleteUserAccessToken(context.Context, *connect.Request[v1.DeleteUserAccessTokenRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.DeleteUserAccessToken is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) ListUserSessions(context.Context, *connect.Request[v1.ListUserSessionsRequest]) (*connect.Response[v1.ListUserSessionsResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.ListUserSessions is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) RevokeUserSession(context.Context, *connect.Request[v1.RevokeUserSessionRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.RevokeUserSession is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) ListUserWebhooks(context.Context, *connect.Request[v1.ListUserWebhooksRequest]) (*connect.Response[v1.ListUserWebhooksResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.ListUserWebhooks is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) CreateUserWebhook(context.Context, *connect.Request[v1.CreateUserWebhookRequest]) (*connect.Response[v1.UserWebhook], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.CreateUserWebhook is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) UpdateUserWebhook(context.Context, *connect.Request[v1.UpdateUserWebhookRequest]) (*connect.Response[v1.UserWebhook], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.UpdateUserWebhook is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) DeleteUserWebhook(context.Context, *connect.Request[v1.DeleteUserWebhookRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.DeleteUserWebhook is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) ListUserNotifications(context.Context, *connect.Request[v1.ListUserNotificationsRequest]) (*connect.Response[v1.ListUserNotificationsResponse], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.ListUserNotifications is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) UpdateUserNotification(context.Context, *connect.Request[v1.UpdateUserNotificationRequest]) (*connect.Response[v1.UserNotification], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.UpdateUserNotification is not implemented"))
|
||||
}
|
||||
|
||||
func (UnimplementedUserServiceHandler) DeleteUserNotification(context.Context, *connect.Request[v1.DeleteUserNotificationRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
return nil, connect.NewError(connect.CodeUnimplemented, errors.New("memos.api.v1.UserService.DeleteUserNotification is not implemented"))
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.10
|
||||
// protoc (unknown)
|
||||
// source: google/api/annotations.proto
|
||||
|
||||
package annotations
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
descriptorpb "google.golang.org/protobuf/types/descriptorpb"
|
||||
reflect "reflect"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
var file_google_api_annotations_proto_extTypes = []protoimpl.ExtensionInfo{
|
||||
{
|
||||
ExtendedType: (*descriptorpb.MethodOptions)(nil),
|
||||
ExtensionType: (*HttpRule)(nil),
|
||||
Field: 72295728,
|
||||
Name: "google.api.http",
|
||||
Tag: "bytes,72295728,opt,name=http",
|
||||
Filename: "google/api/annotations.proto",
|
||||
},
|
||||
}
|
||||
|
||||
// Extension fields to descriptorpb.MethodOptions.
|
||||
var (
|
||||
// See `HttpRule`.
|
||||
//
|
||||
// optional google.api.HttpRule http = 72295728;
|
||||
E_Http = &file_google_api_annotations_proto_extTypes[0]
|
||||
)
|
||||
|
||||
var File_google_api_annotations_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_google_api_annotations_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x1cgoogle/api/annotations.proto\x12\n" +
|
||||
"google.api\x1a\x15google/api/http.proto\x1a google/protobuf/descriptor.proto:K\n" +
|
||||
"\x04http\x12\x1e.google.protobuf.MethodOptions\x18\xb0ʼ\" \x01(\v2\x14.google.api.HttpRuleR\x04httpB\xae\x01\n" +
|
||||
"\x0ecom.google.apiB\x10AnnotationsProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x03GAX\xaa\x02\n" +
|
||||
"Google.Api\xca\x02\n" +
|
||||
"Google\\Api\xe2\x02\x16Google\\Api\\GPBMetadata\xea\x02\vGoogle::Apib\x06proto3"
|
||||
|
||||
var file_google_api_annotations_proto_goTypes = []any{
|
||||
(*descriptorpb.MethodOptions)(nil), // 0: google.protobuf.MethodOptions
|
||||
(*HttpRule)(nil), // 1: google.api.HttpRule
|
||||
}
|
||||
var file_google_api_annotations_proto_depIdxs = []int32{
|
||||
0, // 0: google.api.http:extendee -> google.protobuf.MethodOptions
|
||||
1, // 1: google.api.http:type_name -> google.api.HttpRule
|
||||
2, // [2:2] is the sub-list for method output_type
|
||||
2, // [2:2] is the sub-list for method input_type
|
||||
1, // [1:2] is the sub-list for extension type_name
|
||||
0, // [0:1] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_google_api_annotations_proto_init() }
|
||||
func file_google_api_annotations_proto_init() {
|
||||
if File_google_api_annotations_proto != nil {
|
||||
return
|
||||
}
|
||||
file_google_api_http_proto_init()
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_api_annotations_proto_rawDesc), len(file_google_api_annotations_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 1,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_google_api_annotations_proto_goTypes,
|
||||
DependencyIndexes: file_google_api_annotations_proto_depIdxs,
|
||||
ExtensionInfos: file_google_api_annotations_proto_extTypes,
|
||||
}.Build()
|
||||
File_google_api_annotations_proto = out.File
|
||||
file_google_api_annotations_proto_goTypes = nil
|
||||
file_google_api_annotations_proto_depIdxs = nil
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,252 @@
|
|||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.10
|
||||
// protoc (unknown)
|
||||
// source: google/api/field_behavior.proto
|
||||
|
||||
package annotations
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
descriptorpb "google.golang.org/protobuf/types/descriptorpb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// An indicator of the behavior of a given field (for example, that a field
|
||||
// is required in requests, or given as output but ignored as input).
|
||||
// This **does not** change the behavior in protocol buffers itself; it only
|
||||
// denotes the behavior and may affect how API tooling handles the field.
|
||||
//
|
||||
// Note: This enum **may** receive new values in the future.
|
||||
type FieldBehavior int32
|
||||
|
||||
const (
|
||||
// Conventional default for enums. Do not use this.
|
||||
FieldBehavior_FIELD_BEHAVIOR_UNSPECIFIED FieldBehavior = 0
|
||||
// Specifically denotes a field as optional.
|
||||
// While all fields in protocol buffers are optional, this may be specified
|
||||
// for emphasis if appropriate.
|
||||
FieldBehavior_OPTIONAL FieldBehavior = 1
|
||||
// Denotes a field as required.
|
||||
// This indicates that the field **must** be provided as part of the request,
|
||||
// and failure to do so will cause an error (usually `INVALID_ARGUMENT`).
|
||||
FieldBehavior_REQUIRED FieldBehavior = 2
|
||||
// Denotes a field as output only.
|
||||
// This indicates that the field is provided in responses, but including the
|
||||
// field in a request does nothing (the server *must* ignore it and
|
||||
// *must not* throw an error as a result of the field's presence).
|
||||
FieldBehavior_OUTPUT_ONLY FieldBehavior = 3
|
||||
// Denotes a field as input only.
|
||||
// This indicates that the field is provided in requests, and the
|
||||
// corresponding field is not included in output.
|
||||
FieldBehavior_INPUT_ONLY FieldBehavior = 4
|
||||
// Denotes a field as immutable.
|
||||
// This indicates that the field may be set once in a request to create a
|
||||
// resource, but may not be changed thereafter.
|
||||
FieldBehavior_IMMUTABLE FieldBehavior = 5
|
||||
// Denotes that a (repeated) field is an unordered list.
|
||||
// This indicates that the service may provide the elements of the list
|
||||
// in any arbitrary order, rather than the order the user originally
|
||||
// provided. Additionally, the list's order may or may not be stable.
|
||||
FieldBehavior_UNORDERED_LIST FieldBehavior = 6
|
||||
// Denotes that this field returns a non-empty default value if not set.
|
||||
// This indicates that if the user provides the empty value in a request,
|
||||
// a non-empty value will be returned. The user will not be aware of what
|
||||
// non-empty value to expect.
|
||||
FieldBehavior_NON_EMPTY_DEFAULT FieldBehavior = 7
|
||||
// Denotes that the field in a resource (a message annotated with
|
||||
// google.api.resource) is used in the resource name to uniquely identify the
|
||||
// resource. For AIP-compliant APIs, this should only be applied to the
|
||||
// `name` field on the resource.
|
||||
//
|
||||
// This behavior should not be applied to references to other resources within
|
||||
// the message.
|
||||
//
|
||||
// The identifier field of resources often have different field behavior
|
||||
// depending on the request it is embedded in (e.g. for Create methods name
|
||||
// is optional and unused, while for Update methods it is required). Instead
|
||||
// of method-specific annotations, only `IDENTIFIER` is required.
|
||||
FieldBehavior_IDENTIFIER FieldBehavior = 8
|
||||
)
|
||||
|
||||
// Enum value maps for FieldBehavior.
|
||||
var (
|
||||
FieldBehavior_name = map[int32]string{
|
||||
0: "FIELD_BEHAVIOR_UNSPECIFIED",
|
||||
1: "OPTIONAL",
|
||||
2: "REQUIRED",
|
||||
3: "OUTPUT_ONLY",
|
||||
4: "INPUT_ONLY",
|
||||
5: "IMMUTABLE",
|
||||
6: "UNORDERED_LIST",
|
||||
7: "NON_EMPTY_DEFAULT",
|
||||
8: "IDENTIFIER",
|
||||
}
|
||||
FieldBehavior_value = map[string]int32{
|
||||
"FIELD_BEHAVIOR_UNSPECIFIED": 0,
|
||||
"OPTIONAL": 1,
|
||||
"REQUIRED": 2,
|
||||
"OUTPUT_ONLY": 3,
|
||||
"INPUT_ONLY": 4,
|
||||
"IMMUTABLE": 5,
|
||||
"UNORDERED_LIST": 6,
|
||||
"NON_EMPTY_DEFAULT": 7,
|
||||
"IDENTIFIER": 8,
|
||||
}
|
||||
)
|
||||
|
||||
func (x FieldBehavior) Enum() *FieldBehavior {
|
||||
p := new(FieldBehavior)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x FieldBehavior) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (FieldBehavior) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_google_api_field_behavior_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (FieldBehavior) Type() protoreflect.EnumType {
|
||||
return &file_google_api_field_behavior_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x FieldBehavior) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use FieldBehavior.Descriptor instead.
|
||||
func (FieldBehavior) EnumDescriptor() ([]byte, []int) {
|
||||
return file_google_api_field_behavior_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
var file_google_api_field_behavior_proto_extTypes = []protoimpl.ExtensionInfo{
|
||||
{
|
||||
ExtendedType: (*descriptorpb.FieldOptions)(nil),
|
||||
ExtensionType: ([]FieldBehavior)(nil),
|
||||
Field: 1052,
|
||||
Name: "google.api.field_behavior",
|
||||
Tag: "varint,1052,rep,name=field_behavior,enum=google.api.FieldBehavior",
|
||||
Filename: "google/api/field_behavior.proto",
|
||||
},
|
||||
}
|
||||
|
||||
// Extension fields to descriptorpb.FieldOptions.
|
||||
var (
|
||||
// A designation of a specific field behavior (required, output only, etc.)
|
||||
// in protobuf messages.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// string name = 1 [(google.api.field_behavior) = REQUIRED];
|
||||
// State state = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
|
||||
// google.protobuf.Duration ttl = 1
|
||||
// [(google.api.field_behavior) = INPUT_ONLY];
|
||||
// google.protobuf.Timestamp expire_time = 1
|
||||
// [(google.api.field_behavior) = OUTPUT_ONLY,
|
||||
// (google.api.field_behavior) = IMMUTABLE];
|
||||
//
|
||||
// repeated google.api.FieldBehavior field_behavior = 1052;
|
||||
E_FieldBehavior = &file_google_api_field_behavior_proto_extTypes[0]
|
||||
)
|
||||
|
||||
var File_google_api_field_behavior_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_google_api_field_behavior_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x1fgoogle/api/field_behavior.proto\x12\n" +
|
||||
"google.api\x1a google/protobuf/descriptor.proto*\xb6\x01\n" +
|
||||
"\rFieldBehavior\x12\x1e\n" +
|
||||
"\x1aFIELD_BEHAVIOR_UNSPECIFIED\x10\x00\x12\f\n" +
|
||||
"\bOPTIONAL\x10\x01\x12\f\n" +
|
||||
"\bREQUIRED\x10\x02\x12\x0f\n" +
|
||||
"\vOUTPUT_ONLY\x10\x03\x12\x0e\n" +
|
||||
"\n" +
|
||||
"INPUT_ONLY\x10\x04\x12\r\n" +
|
||||
"\tIMMUTABLE\x10\x05\x12\x12\n" +
|
||||
"\x0eUNORDERED_LIST\x10\x06\x12\x15\n" +
|
||||
"\x11NON_EMPTY_DEFAULT\x10\a\x12\x0e\n" +
|
||||
"\n" +
|
||||
"IDENTIFIER\x10\b:d\n" +
|
||||
"\x0efield_behavior\x12\x1d.google.protobuf.FieldOptions\x18\x9c\b \x03(\x0e2\x19.google.api.FieldBehaviorB\x02\x10\x00R\rfieldBehaviorB\xb0\x01\n" +
|
||||
"\x0ecom.google.apiB\x12FieldBehaviorProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x03GAX\xaa\x02\n" +
|
||||
"Google.Api\xca\x02\n" +
|
||||
"Google\\Api\xe2\x02\x16Google\\Api\\GPBMetadata\xea\x02\vGoogle::Apib\x06proto3"
|
||||
|
||||
var (
|
||||
file_google_api_field_behavior_proto_rawDescOnce sync.Once
|
||||
file_google_api_field_behavior_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_google_api_field_behavior_proto_rawDescGZIP() []byte {
|
||||
file_google_api_field_behavior_proto_rawDescOnce.Do(func() {
|
||||
file_google_api_field_behavior_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_api_field_behavior_proto_rawDesc), len(file_google_api_field_behavior_proto_rawDesc)))
|
||||
})
|
||||
return file_google_api_field_behavior_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_google_api_field_behavior_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_google_api_field_behavior_proto_goTypes = []any{
|
||||
(FieldBehavior)(0), // 0: google.api.FieldBehavior
|
||||
(*descriptorpb.FieldOptions)(nil), // 1: google.protobuf.FieldOptions
|
||||
}
|
||||
var file_google_api_field_behavior_proto_depIdxs = []int32{
|
||||
1, // 0: google.api.field_behavior:extendee -> google.protobuf.FieldOptions
|
||||
0, // 1: google.api.field_behavior:type_name -> google.api.FieldBehavior
|
||||
2, // [2:2] is the sub-list for method output_type
|
||||
2, // [2:2] is the sub-list for method input_type
|
||||
1, // [1:2] is the sub-list for extension type_name
|
||||
0, // [0:1] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_google_api_field_behavior_proto_init() }
|
||||
func file_google_api_field_behavior_proto_init() {
|
||||
if File_google_api_field_behavior_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_api_field_behavior_proto_rawDesc), len(file_google_api_field_behavior_proto_rawDesc)),
|
||||
NumEnums: 1,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 1,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_google_api_field_behavior_proto_goTypes,
|
||||
DependencyIndexes: file_google_api_field_behavior_proto_depIdxs,
|
||||
EnumInfos: file_google_api_field_behavior_proto_enumTypes,
|
||||
ExtensionInfos: file_google_api_field_behavior_proto_extTypes,
|
||||
}.Build()
|
||||
File_google_api_field_behavior_proto = out.File
|
||||
file_google_api_field_behavior_proto_goTypes = nil
|
||||
file_google_api_field_behavior_proto_depIdxs = nil
|
||||
}
|
||||
|
|
@ -0,0 +1,718 @@
|
|||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.10
|
||||
// protoc (unknown)
|
||||
// source: google/api/http.proto
|
||||
|
||||
package annotations
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// Defines the HTTP configuration for an API service. It contains a list of
|
||||
// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method
|
||||
// to one or more HTTP REST API methods.
|
||||
type Http struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// A list of HTTP configuration rules that apply to individual API methods.
|
||||
//
|
||||
// **NOTE:** All service configuration rules follow "last one wins" order.
|
||||
Rules []*HttpRule `protobuf:"bytes,1,rep,name=rules,proto3" json:"rules,omitempty"`
|
||||
// When set to true, URL path parameters will be fully URI-decoded except in
|
||||
// cases of single segment matches in reserved expansion, where "%2F" will be
|
||||
// left encoded.
|
||||
//
|
||||
// The default behavior is to not decode RFC 6570 reserved characters in multi
|
||||
// segment matches.
|
||||
FullyDecodeReservedExpansion bool `protobuf:"varint,2,opt,name=fully_decode_reserved_expansion,json=fullyDecodeReservedExpansion,proto3" json:"fully_decode_reserved_expansion,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Http) Reset() {
|
||||
*x = Http{}
|
||||
mi := &file_google_api_http_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *Http) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Http) ProtoMessage() {}
|
||||
|
||||
func (x *Http) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_google_api_http_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Http.ProtoReflect.Descriptor instead.
|
||||
func (*Http) Descriptor() ([]byte, []int) {
|
||||
return file_google_api_http_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Http) GetRules() []*HttpRule {
|
||||
if x != nil {
|
||||
return x.Rules
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Http) GetFullyDecodeReservedExpansion() bool {
|
||||
if x != nil {
|
||||
return x.FullyDecodeReservedExpansion
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// gRPC Transcoding
|
||||
//
|
||||
// gRPC Transcoding is a feature for mapping between a gRPC method and one or
|
||||
// more HTTP REST endpoints. It allows developers to build a single API service
|
||||
// that supports both gRPC APIs and REST APIs. Many systems, including [Google
|
||||
// APIs](https://github.com/googleapis/googleapis),
|
||||
// [Cloud Endpoints](https://cloud.google.com/endpoints), [gRPC
|
||||
// Gateway](https://github.com/grpc-ecosystem/grpc-gateway),
|
||||
// and [Envoy](https://github.com/envoyproxy/envoy) proxy support this feature
|
||||
// and use it for large scale production services.
|
||||
//
|
||||
// `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies
|
||||
// how different portions of the gRPC request message are mapped to the URL
|
||||
// path, URL query parameters, and HTTP request body. It also controls how the
|
||||
// gRPC response message is mapped to the HTTP response body. `HttpRule` is
|
||||
// typically specified as an `google.api.http` annotation on the gRPC method.
|
||||
//
|
||||
// Each mapping specifies a URL path template and an HTTP method. The path
|
||||
// template may refer to one or more fields in the gRPC request message, as long
|
||||
// as each field is a non-repeated field with a primitive (non-message) type.
|
||||
// The path template controls how fields of the request message are mapped to
|
||||
// the URL path.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// service Messaging {
|
||||
// rpc GetMessage(GetMessageRequest) returns (Message) {
|
||||
// option (google.api.http) = {
|
||||
// get: "/v1/{name=messages/*}"
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// message GetMessageRequest {
|
||||
// string name = 1; // Mapped to URL path.
|
||||
// }
|
||||
// message Message {
|
||||
// string text = 1; // The resource content.
|
||||
// }
|
||||
//
|
||||
// This enables an HTTP REST to gRPC mapping as below:
|
||||
//
|
||||
// - HTTP: `GET /v1/messages/123456`
|
||||
// - gRPC: `GetMessage(name: "messages/123456")`
|
||||
//
|
||||
// Any fields in the request message which are not bound by the path template
|
||||
// automatically become HTTP query parameters if there is no HTTP request body.
|
||||
// For example:
|
||||
//
|
||||
// service Messaging {
|
||||
// rpc GetMessage(GetMessageRequest) returns (Message) {
|
||||
// option (google.api.http) = {
|
||||
// get:"/v1/messages/{message_id}"
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// message GetMessageRequest {
|
||||
// message SubMessage {
|
||||
// string subfield = 1;
|
||||
// }
|
||||
// string message_id = 1; // Mapped to URL path.
|
||||
// int64 revision = 2; // Mapped to URL query parameter `revision`.
|
||||
// SubMessage sub = 3; // Mapped to URL query parameter `sub.subfield`.
|
||||
// }
|
||||
//
|
||||
// This enables a HTTP JSON to RPC mapping as below:
|
||||
//
|
||||
// - HTTP: `GET /v1/messages/123456?revision=2&sub.subfield=foo`
|
||||
// - gRPC: `GetMessage(message_id: "123456" revision: 2 sub:
|
||||
// SubMessage(subfield: "foo"))`
|
||||
//
|
||||
// Note that fields which are mapped to URL query parameters must have a
|
||||
// primitive type or a repeated primitive type or a non-repeated message type.
|
||||
// In the case of a repeated type, the parameter can be repeated in the URL
|
||||
// as `...?param=A¶m=B`. In the case of a message type, each field of the
|
||||
// message is mapped to a separate parameter, such as
|
||||
// `...?foo.a=A&foo.b=B&foo.c=C`.
|
||||
//
|
||||
// For HTTP methods that allow a request body, the `body` field
|
||||
// specifies the mapping. Consider a REST update method on the
|
||||
// message resource collection:
|
||||
//
|
||||
// service Messaging {
|
||||
// rpc UpdateMessage(UpdateMessageRequest) returns (Message) {
|
||||
// option (google.api.http) = {
|
||||
// patch: "/v1/messages/{message_id}"
|
||||
// body: "message"
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// message UpdateMessageRequest {
|
||||
// string message_id = 1; // mapped to the URL
|
||||
// Message message = 2; // mapped to the body
|
||||
// }
|
||||
//
|
||||
// The following HTTP JSON to RPC mapping is enabled, where the
|
||||
// representation of the JSON in the request body is determined by
|
||||
// protos JSON encoding:
|
||||
//
|
||||
// - HTTP: `PATCH /v1/messages/123456 { "text": "Hi!" }`
|
||||
// - gRPC: `UpdateMessage(message_id: "123456" message { text: "Hi!" })`
|
||||
//
|
||||
// The special name `*` can be used in the body mapping to define that
|
||||
// every field not bound by the path template should be mapped to the
|
||||
// request body. This enables the following alternative definition of
|
||||
// the update method:
|
||||
//
|
||||
// service Messaging {
|
||||
// rpc UpdateMessage(Message) returns (Message) {
|
||||
// option (google.api.http) = {
|
||||
// patch: "/v1/messages/{message_id}"
|
||||
// body: "*"
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// message Message {
|
||||
// string message_id = 1;
|
||||
// string text = 2;
|
||||
// }
|
||||
//
|
||||
// The following HTTP JSON to RPC mapping is enabled:
|
||||
//
|
||||
// - HTTP: `PATCH /v1/messages/123456 { "text": "Hi!" }`
|
||||
// - gRPC: `UpdateMessage(message_id: "123456" text: "Hi!")`
|
||||
//
|
||||
// Note that when using `*` in the body mapping, it is not possible to
|
||||
// have HTTP parameters, as all fields not bound by the path end in
|
||||
// the body. This makes this option more rarely used in practice when
|
||||
// defining REST APIs. The common usage of `*` is in custom methods
|
||||
// which don't use the URL at all for transferring data.
|
||||
//
|
||||
// It is possible to define multiple HTTP methods for one RPC by using
|
||||
// the `additional_bindings` option. Example:
|
||||
//
|
||||
// service Messaging {
|
||||
// rpc GetMessage(GetMessageRequest) returns (Message) {
|
||||
// option (google.api.http) = {
|
||||
// get: "/v1/messages/{message_id}"
|
||||
// additional_bindings {
|
||||
// get: "/v1/users/{user_id}/messages/{message_id}"
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
// }
|
||||
// message GetMessageRequest {
|
||||
// string message_id = 1;
|
||||
// string user_id = 2;
|
||||
// }
|
||||
//
|
||||
// This enables the following two alternative HTTP JSON to RPC mappings:
|
||||
//
|
||||
// - HTTP: `GET /v1/messages/123456`
|
||||
// - gRPC: `GetMessage(message_id: "123456")`
|
||||
//
|
||||
// - HTTP: `GET /v1/users/me/messages/123456`
|
||||
// - gRPC: `GetMessage(user_id: "me" message_id: "123456")`
|
||||
//
|
||||
// # Rules for HTTP mapping
|
||||
//
|
||||
// 1. Leaf request fields (recursive expansion nested messages in the request
|
||||
// message) are classified into three categories:
|
||||
// - Fields referred by the path template. They are passed via the URL path.
|
||||
// - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They
|
||||
// are passed via the HTTP
|
||||
// request body.
|
||||
// - All other fields are passed via the URL query parameters, and the
|
||||
// parameter name is the field path in the request message. A repeated
|
||||
// field can be represented as multiple query parameters under the same
|
||||
// name.
|
||||
// 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL
|
||||
// query parameter, all fields
|
||||
// are passed via URL path and HTTP request body.
|
||||
// 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP
|
||||
// request body, all
|
||||
// fields are passed via URL path and URL query parameters.
|
||||
//
|
||||
// Path template syntax
|
||||
//
|
||||
// Template = "/" Segments [ Verb ] ;
|
||||
// Segments = Segment { "/" Segment } ;
|
||||
// Segment = "*" | "**" | LITERAL | Variable ;
|
||||
// Variable = "{" FieldPath [ "=" Segments ] "}" ;
|
||||
// FieldPath = IDENT { "." IDENT } ;
|
||||
// Verb = ":" LITERAL ;
|
||||
//
|
||||
// The syntax `*` matches a single URL path segment. The syntax `**` matches
|
||||
// zero or more URL path segments, which must be the last part of the URL path
|
||||
// except the `Verb`.
|
||||
//
|
||||
// The syntax `Variable` matches part of the URL path as specified by its
|
||||
// template. A variable template must not contain other variables. If a variable
|
||||
// matches a single path segment, its template may be omitted, e.g. `{var}`
|
||||
// is equivalent to `{var=*}`.
|
||||
//
|
||||
// The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL`
|
||||
// contains any reserved character, such characters should be percent-encoded
|
||||
// before the matching.
|
||||
//
|
||||
// If a variable contains exactly one path segment, such as `"{var}"` or
|
||||
// `"{var=*}"`, when such a variable is expanded into a URL path on the client
|
||||
// side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The
|
||||
// server side does the reverse decoding. Such variables show up in the
|
||||
// [Discovery
|
||||
// Document](https://developers.google.com/discovery/v1/reference/apis) as
|
||||
// `{var}`.
|
||||
//
|
||||
// If a variable contains multiple path segments, such as `"{var=foo/*}"`
|
||||
// or `"{var=**}"`, when such a variable is expanded into a URL path on the
|
||||
// client side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded.
|
||||
// The server side does the reverse decoding, except "%2F" and "%2f" are left
|
||||
// unchanged. Such variables show up in the
|
||||
// [Discovery
|
||||
// Document](https://developers.google.com/discovery/v1/reference/apis) as
|
||||
// `{+var}`.
|
||||
//
|
||||
// # Using gRPC API Service Configuration
|
||||
//
|
||||
// gRPC API Service Configuration (service config) is a configuration language
|
||||
// for configuring a gRPC service to become a user-facing product. The
|
||||
// service config is simply the YAML representation of the `google.api.Service`
|
||||
// proto message.
|
||||
//
|
||||
// As an alternative to annotating your proto file, you can configure gRPC
|
||||
// transcoding in your service config YAML files. You do this by specifying a
|
||||
// `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same
|
||||
// effect as the proto annotation. This can be particularly useful if you
|
||||
// have a proto that is reused in multiple services. Note that any transcoding
|
||||
// specified in the service config will override any matching transcoding
|
||||
// configuration in the proto.
|
||||
//
|
||||
// The following example selects a gRPC method and applies an `HttpRule` to it:
|
||||
//
|
||||
// http:
|
||||
// rules:
|
||||
// - selector: example.v1.Messaging.GetMessage
|
||||
// get: /v1/messages/{message_id}/{sub.subfield}
|
||||
//
|
||||
// # Special notes
|
||||
//
|
||||
// When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the
|
||||
// proto to JSON conversion must follow the [proto3
|
||||
// specification](https://developers.google.com/protocol-buffers/docs/proto3#json).
|
||||
//
|
||||
// While the single segment variable follows the semantics of
|
||||
// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String
|
||||
// Expansion, the multi segment variable **does not** follow RFC 6570 Section
|
||||
// 3.2.3 Reserved Expansion. The reason is that the Reserved Expansion
|
||||
// does not expand special characters like `?` and `#`, which would lead
|
||||
// to invalid URLs. As the result, gRPC Transcoding uses a custom encoding
|
||||
// for multi segment variables.
|
||||
//
|
||||
// The path variables **must not** refer to any repeated or mapped field,
|
||||
// because client libraries are not capable of handling such variable expansion.
|
||||
//
|
||||
// The path variables **must not** capture the leading "/" character. The reason
|
||||
// is that the most common use case "{var}" does not capture the leading "/"
|
||||
// character. For consistency, all path variables must share the same behavior.
|
||||
//
|
||||
// Repeated message fields must not be mapped to URL query parameters, because
|
||||
// no client library can support such complicated mapping.
|
||||
//
|
||||
// If an API needs to use a JSON array for request or response body, it can map
|
||||
// the request or response body to a repeated field. However, some gRPC
|
||||
// Transcoding implementations may not support this feature.
|
||||
type HttpRule struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// Selects a method to which this rule applies.
|
||||
//
|
||||
// Refer to [selector][google.api.DocumentationRule.selector] for syntax
|
||||
// details.
|
||||
Selector string `protobuf:"bytes,1,opt,name=selector,proto3" json:"selector,omitempty"`
|
||||
// Determines the URL pattern is matched by this rules. This pattern can be
|
||||
// used with any of the {get|put|post|delete|patch} methods. A custom method
|
||||
// can be defined using the 'custom' field.
|
||||
//
|
||||
// Types that are valid to be assigned to Pattern:
|
||||
//
|
||||
// *HttpRule_Get
|
||||
// *HttpRule_Put
|
||||
// *HttpRule_Post
|
||||
// *HttpRule_Delete
|
||||
// *HttpRule_Patch
|
||||
// *HttpRule_Custom
|
||||
Pattern isHttpRule_Pattern `protobuf_oneof:"pattern"`
|
||||
// The name of the request field whose value is mapped to the HTTP request
|
||||
// body, or `*` for mapping all request fields not captured by the path
|
||||
// pattern to the HTTP body, or omitted for not having any HTTP request body.
|
||||
//
|
||||
// NOTE: the referred field must be present at the top-level of the request
|
||||
// message type.
|
||||
Body string `protobuf:"bytes,7,opt,name=body,proto3" json:"body,omitempty"`
|
||||
// Optional. The name of the response field whose value is mapped to the HTTP
|
||||
// response body. When omitted, the entire response message will be used
|
||||
// as the HTTP response body.
|
||||
//
|
||||
// NOTE: The referred field must be present at the top-level of the response
|
||||
// message type.
|
||||
ResponseBody string `protobuf:"bytes,12,opt,name=response_body,json=responseBody,proto3" json:"response_body,omitempty"`
|
||||
// Additional HTTP bindings for the selector. Nested bindings must
|
||||
// not contain an `additional_bindings` field themselves (that is,
|
||||
// the nesting may only be one level deep).
|
||||
AdditionalBindings []*HttpRule `protobuf:"bytes,11,rep,name=additional_bindings,json=additionalBindings,proto3" json:"additional_bindings,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *HttpRule) Reset() {
|
||||
*x = HttpRule{}
|
||||
mi := &file_google_api_http_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *HttpRule) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*HttpRule) ProtoMessage() {}
|
||||
|
||||
func (x *HttpRule) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_google_api_http_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use HttpRule.ProtoReflect.Descriptor instead.
|
||||
func (*HttpRule) Descriptor() ([]byte, []int) {
|
||||
return file_google_api_http_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *HttpRule) GetSelector() string {
|
||||
if x != nil {
|
||||
return x.Selector
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *HttpRule) GetPattern() isHttpRule_Pattern {
|
||||
if x != nil {
|
||||
return x.Pattern
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *HttpRule) GetGet() string {
|
||||
if x != nil {
|
||||
if x, ok := x.Pattern.(*HttpRule_Get); ok {
|
||||
return x.Get
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *HttpRule) GetPut() string {
|
||||
if x != nil {
|
||||
if x, ok := x.Pattern.(*HttpRule_Put); ok {
|
||||
return x.Put
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *HttpRule) GetPost() string {
|
||||
if x != nil {
|
||||
if x, ok := x.Pattern.(*HttpRule_Post); ok {
|
||||
return x.Post
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *HttpRule) GetDelete() string {
|
||||
if x != nil {
|
||||
if x, ok := x.Pattern.(*HttpRule_Delete); ok {
|
||||
return x.Delete
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *HttpRule) GetPatch() string {
|
||||
if x != nil {
|
||||
if x, ok := x.Pattern.(*HttpRule_Patch); ok {
|
||||
return x.Patch
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *HttpRule) GetCustom() *CustomHttpPattern {
|
||||
if x != nil {
|
||||
if x, ok := x.Pattern.(*HttpRule_Custom); ok {
|
||||
return x.Custom
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *HttpRule) GetBody() string {
|
||||
if x != nil {
|
||||
return x.Body
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *HttpRule) GetResponseBody() string {
|
||||
if x != nil {
|
||||
return x.ResponseBody
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *HttpRule) GetAdditionalBindings() []*HttpRule {
|
||||
if x != nil {
|
||||
return x.AdditionalBindings
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type isHttpRule_Pattern interface {
|
||||
isHttpRule_Pattern()
|
||||
}
|
||||
|
||||
type HttpRule_Get struct {
|
||||
// Maps to HTTP GET. Used for listing and getting information about
|
||||
// resources.
|
||||
Get string `protobuf:"bytes,2,opt,name=get,proto3,oneof"`
|
||||
}
|
||||
|
||||
type HttpRule_Put struct {
|
||||
// Maps to HTTP PUT. Used for replacing a resource.
|
||||
Put string `protobuf:"bytes,3,opt,name=put,proto3,oneof"`
|
||||
}
|
||||
|
||||
type HttpRule_Post struct {
|
||||
// Maps to HTTP POST. Used for creating a resource or performing an action.
|
||||
Post string `protobuf:"bytes,4,opt,name=post,proto3,oneof"`
|
||||
}
|
||||
|
||||
type HttpRule_Delete struct {
|
||||
// Maps to HTTP DELETE. Used for deleting a resource.
|
||||
Delete string `protobuf:"bytes,5,opt,name=delete,proto3,oneof"`
|
||||
}
|
||||
|
||||
type HttpRule_Patch struct {
|
||||
// Maps to HTTP PATCH. Used for updating a resource.
|
||||
Patch string `protobuf:"bytes,6,opt,name=patch,proto3,oneof"`
|
||||
}
|
||||
|
||||
type HttpRule_Custom struct {
|
||||
// The custom pattern is used for specifying an HTTP method that is not
|
||||
// included in the `pattern` field, such as HEAD, or "*" to leave the
|
||||
// HTTP method unspecified for this rule. The wild-card rule is useful
|
||||
// for services that provide content to Web (HTML) clients.
|
||||
Custom *CustomHttpPattern `protobuf:"bytes,8,opt,name=custom,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*HttpRule_Get) isHttpRule_Pattern() {}
|
||||
|
||||
func (*HttpRule_Put) isHttpRule_Pattern() {}
|
||||
|
||||
func (*HttpRule_Post) isHttpRule_Pattern() {}
|
||||
|
||||
func (*HttpRule_Delete) isHttpRule_Pattern() {}
|
||||
|
||||
func (*HttpRule_Patch) isHttpRule_Pattern() {}
|
||||
|
||||
func (*HttpRule_Custom) isHttpRule_Pattern() {}
|
||||
|
||||
// A custom pattern is used for defining custom HTTP verb.
|
||||
type CustomHttpPattern struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// The name of this custom HTTP verb.
|
||||
Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"`
|
||||
// The path matched by this custom verb.
|
||||
Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *CustomHttpPattern) Reset() {
|
||||
*x = CustomHttpPattern{}
|
||||
mi := &file_google_api_http_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *CustomHttpPattern) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*CustomHttpPattern) ProtoMessage() {}
|
||||
|
||||
func (x *CustomHttpPattern) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_google_api_http_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use CustomHttpPattern.ProtoReflect.Descriptor instead.
|
||||
func (*CustomHttpPattern) Descriptor() ([]byte, []int) {
|
||||
return file_google_api_http_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *CustomHttpPattern) GetKind() string {
|
||||
if x != nil {
|
||||
return x.Kind
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *CustomHttpPattern) GetPath() string {
|
||||
if x != nil {
|
||||
return x.Path
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_google_api_http_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_google_api_http_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x15google/api/http.proto\x12\n" +
|
||||
"google.api\"y\n" +
|
||||
"\x04Http\x12*\n" +
|
||||
"\x05rules\x18\x01 \x03(\v2\x14.google.api.HttpRuleR\x05rules\x12E\n" +
|
||||
"\x1ffully_decode_reserved_expansion\x18\x02 \x01(\bR\x1cfullyDecodeReservedExpansion\"\xda\x02\n" +
|
||||
"\bHttpRule\x12\x1a\n" +
|
||||
"\bselector\x18\x01 \x01(\tR\bselector\x12\x12\n" +
|
||||
"\x03get\x18\x02 \x01(\tH\x00R\x03get\x12\x12\n" +
|
||||
"\x03put\x18\x03 \x01(\tH\x00R\x03put\x12\x14\n" +
|
||||
"\x04post\x18\x04 \x01(\tH\x00R\x04post\x12\x18\n" +
|
||||
"\x06delete\x18\x05 \x01(\tH\x00R\x06delete\x12\x16\n" +
|
||||
"\x05patch\x18\x06 \x01(\tH\x00R\x05patch\x127\n" +
|
||||
"\x06custom\x18\b \x01(\v2\x1d.google.api.CustomHttpPatternH\x00R\x06custom\x12\x12\n" +
|
||||
"\x04body\x18\a \x01(\tR\x04body\x12#\n" +
|
||||
"\rresponse_body\x18\f \x01(\tR\fresponseBody\x12E\n" +
|
||||
"\x13additional_bindings\x18\v \x03(\v2\x14.google.api.HttpRuleR\x12additionalBindingsB\t\n" +
|
||||
"\apattern\";\n" +
|
||||
"\x11CustomHttpPattern\x12\x12\n" +
|
||||
"\x04kind\x18\x01 \x01(\tR\x04kind\x12\x12\n" +
|
||||
"\x04path\x18\x02 \x01(\tR\x04pathB\xa7\x01\n" +
|
||||
"\x0ecom.google.apiB\tHttpProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x03GAX\xaa\x02\n" +
|
||||
"Google.Api\xca\x02\n" +
|
||||
"Google\\Api\xe2\x02\x16Google\\Api\\GPBMetadata\xea\x02\vGoogle::Apib\x06proto3"
|
||||
|
||||
var (
|
||||
file_google_api_http_proto_rawDescOnce sync.Once
|
||||
file_google_api_http_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_google_api_http_proto_rawDescGZIP() []byte {
|
||||
file_google_api_http_proto_rawDescOnce.Do(func() {
|
||||
file_google_api_http_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_api_http_proto_rawDesc), len(file_google_api_http_proto_rawDesc)))
|
||||
})
|
||||
return file_google_api_http_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_google_api_http_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
||||
var file_google_api_http_proto_goTypes = []any{
|
||||
(*Http)(nil), // 0: google.api.Http
|
||||
(*HttpRule)(nil), // 1: google.api.HttpRule
|
||||
(*CustomHttpPattern)(nil), // 2: google.api.CustomHttpPattern
|
||||
}
|
||||
var file_google_api_http_proto_depIdxs = []int32{
|
||||
1, // 0: google.api.Http.rules:type_name -> google.api.HttpRule
|
||||
2, // 1: google.api.HttpRule.custom:type_name -> google.api.CustomHttpPattern
|
||||
1, // 2: google.api.HttpRule.additional_bindings:type_name -> google.api.HttpRule
|
||||
3, // [3:3] is the sub-list for method output_type
|
||||
3, // [3:3] is the sub-list for method input_type
|
||||
3, // [3:3] is the sub-list for extension type_name
|
||||
3, // [3:3] is the sub-list for extension extendee
|
||||
0, // [0:3] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_google_api_http_proto_init() }
|
||||
func file_google_api_http_proto_init() {
|
||||
if File_google_api_http_proto != nil {
|
||||
return
|
||||
}
|
||||
file_google_api_http_proto_msgTypes[1].OneofWrappers = []any{
|
||||
(*HttpRule_Get)(nil),
|
||||
(*HttpRule_Put)(nil),
|
||||
(*HttpRule_Post)(nil),
|
||||
(*HttpRule_Delete)(nil),
|
||||
(*HttpRule_Patch)(nil),
|
||||
(*HttpRule_Custom)(nil),
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_api_http_proto_rawDesc), len(file_google_api_http_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 3,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_google_api_http_proto_goTypes,
|
||||
DependencyIndexes: file_google_api_http_proto_depIdxs,
|
||||
MessageInfos: file_google_api_http_proto_msgTypes,
|
||||
}.Build()
|
||||
File_google_api_http_proto = out.File
|
||||
file_google_api_http_proto_goTypes = nil
|
||||
file_google_api_http_proto_depIdxs = nil
|
||||
}
|
||||
|
|
@ -0,0 +1,592 @@
|
|||
// Copyright 2025 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.10
|
||||
// protoc (unknown)
|
||||
// source: google/api/resource.proto
|
||||
|
||||
package annotations
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
descriptorpb "google.golang.org/protobuf/types/descriptorpb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// A description of the historical or future-looking state of the
|
||||
// resource pattern.
|
||||
type ResourceDescriptor_History int32
|
||||
|
||||
const (
|
||||
// The "unset" value.
|
||||
ResourceDescriptor_HISTORY_UNSPECIFIED ResourceDescriptor_History = 0
|
||||
// The resource originally had one pattern and launched as such, and
|
||||
// additional patterns were added later.
|
||||
ResourceDescriptor_ORIGINALLY_SINGLE_PATTERN ResourceDescriptor_History = 1
|
||||
// The resource has one pattern, but the API owner expects to add more
|
||||
// later. (This is the inverse of ORIGINALLY_SINGLE_PATTERN, and prevents
|
||||
// that from being necessary once there are multiple patterns.)
|
||||
ResourceDescriptor_FUTURE_MULTI_PATTERN ResourceDescriptor_History = 2
|
||||
)
|
||||
|
||||
// Enum value maps for ResourceDescriptor_History.
|
||||
var (
|
||||
ResourceDescriptor_History_name = map[int32]string{
|
||||
0: "HISTORY_UNSPECIFIED",
|
||||
1: "ORIGINALLY_SINGLE_PATTERN",
|
||||
2: "FUTURE_MULTI_PATTERN",
|
||||
}
|
||||
ResourceDescriptor_History_value = map[string]int32{
|
||||
"HISTORY_UNSPECIFIED": 0,
|
||||
"ORIGINALLY_SINGLE_PATTERN": 1,
|
||||
"FUTURE_MULTI_PATTERN": 2,
|
||||
}
|
||||
)
|
||||
|
||||
func (x ResourceDescriptor_History) Enum() *ResourceDescriptor_History {
|
||||
p := new(ResourceDescriptor_History)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x ResourceDescriptor_History) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (ResourceDescriptor_History) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_google_api_resource_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (ResourceDescriptor_History) Type() protoreflect.EnumType {
|
||||
return &file_google_api_resource_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x ResourceDescriptor_History) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ResourceDescriptor_History.Descriptor instead.
|
||||
func (ResourceDescriptor_History) EnumDescriptor() ([]byte, []int) {
|
||||
return file_google_api_resource_proto_rawDescGZIP(), []int{0, 0}
|
||||
}
|
||||
|
||||
// A flag representing a specific style that a resource claims to conform to.
|
||||
type ResourceDescriptor_Style int32
|
||||
|
||||
const (
|
||||
// The unspecified value. Do not use.
|
||||
ResourceDescriptor_STYLE_UNSPECIFIED ResourceDescriptor_Style = 0
|
||||
// This resource is intended to be "declarative-friendly".
|
||||
//
|
||||
// Declarative-friendly resources must be more strictly consistent, and
|
||||
// setting this to true communicates to tools that this resource should
|
||||
// adhere to declarative-friendly expectations.
|
||||
//
|
||||
// Note: This is used by the API linter (linter.aip.dev) to enable
|
||||
// additional checks.
|
||||
ResourceDescriptor_DECLARATIVE_FRIENDLY ResourceDescriptor_Style = 1
|
||||
)
|
||||
|
||||
// Enum value maps for ResourceDescriptor_Style.
|
||||
var (
|
||||
ResourceDescriptor_Style_name = map[int32]string{
|
||||
0: "STYLE_UNSPECIFIED",
|
||||
1: "DECLARATIVE_FRIENDLY",
|
||||
}
|
||||
ResourceDescriptor_Style_value = map[string]int32{
|
||||
"STYLE_UNSPECIFIED": 0,
|
||||
"DECLARATIVE_FRIENDLY": 1,
|
||||
}
|
||||
)
|
||||
|
||||
func (x ResourceDescriptor_Style) Enum() *ResourceDescriptor_Style {
|
||||
p := new(ResourceDescriptor_Style)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x ResourceDescriptor_Style) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (ResourceDescriptor_Style) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_google_api_resource_proto_enumTypes[1].Descriptor()
|
||||
}
|
||||
|
||||
func (ResourceDescriptor_Style) Type() protoreflect.EnumType {
|
||||
return &file_google_api_resource_proto_enumTypes[1]
|
||||
}
|
||||
|
||||
func (x ResourceDescriptor_Style) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ResourceDescriptor_Style.Descriptor instead.
|
||||
func (ResourceDescriptor_Style) EnumDescriptor() ([]byte, []int) {
|
||||
return file_google_api_resource_proto_rawDescGZIP(), []int{0, 1}
|
||||
}
|
||||
|
||||
// A simple descriptor of a resource type.
|
||||
//
|
||||
// ResourceDescriptor annotates a resource message (either by means of a
|
||||
// protobuf annotation or use in the service config), and associates the
|
||||
// resource's schema, the resource type, and the pattern of the resource name.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// message Topic {
|
||||
// // Indicates this message defines a resource schema.
|
||||
// // Declares the resource type in the format of {service}/{kind}.
|
||||
// // For Kubernetes resources, the format is {api group}/{kind}.
|
||||
// option (google.api.resource) = {
|
||||
// type: "pubsub.googleapis.com/Topic"
|
||||
// pattern: "projects/{project}/topics/{topic}"
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// The ResourceDescriptor Yaml config will look like:
|
||||
//
|
||||
// resources:
|
||||
// - type: "pubsub.googleapis.com/Topic"
|
||||
// pattern: "projects/{project}/topics/{topic}"
|
||||
//
|
||||
// Sometimes, resources have multiple patterns, typically because they can
|
||||
// live under multiple parents.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// message LogEntry {
|
||||
// option (google.api.resource) = {
|
||||
// type: "logging.googleapis.com/LogEntry"
|
||||
// pattern: "projects/{project}/logs/{log}"
|
||||
// pattern: "folders/{folder}/logs/{log}"
|
||||
// pattern: "organizations/{organization}/logs/{log}"
|
||||
// pattern: "billingAccounts/{billing_account}/logs/{log}"
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// The ResourceDescriptor Yaml config will look like:
|
||||
//
|
||||
// resources:
|
||||
// - type: 'logging.googleapis.com/LogEntry'
|
||||
// pattern: "projects/{project}/logs/{log}"
|
||||
// pattern: "folders/{folder}/logs/{log}"
|
||||
// pattern: "organizations/{organization}/logs/{log}"
|
||||
// pattern: "billingAccounts/{billing_account}/logs/{log}"
|
||||
type ResourceDescriptor struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// The resource type. It must be in the format of
|
||||
// {service_name}/{resource_type_kind}. The `resource_type_kind` must be
|
||||
// singular and must not include version numbers.
|
||||
//
|
||||
// Example: `storage.googleapis.com/Bucket`
|
||||
//
|
||||
// The value of the resource_type_kind must follow the regular expression
|
||||
// /[A-Za-z][a-zA-Z0-9]+/. It should start with an upper case character and
|
||||
// should use PascalCase (UpperCamelCase). The maximum number of
|
||||
// characters allowed for the `resource_type_kind` is 100.
|
||||
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
|
||||
// Optional. The relative resource name pattern associated with this resource
|
||||
// type. The DNS prefix of the full resource name shouldn't be specified here.
|
||||
//
|
||||
// The path pattern must follow the syntax, which aligns with HTTP binding
|
||||
// syntax:
|
||||
//
|
||||
// Template = Segment { "/" Segment } ;
|
||||
// Segment = LITERAL | Variable ;
|
||||
// Variable = "{" LITERAL "}" ;
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// - "projects/{project}/topics/{topic}"
|
||||
// - "projects/{project}/knowledgeBases/{knowledge_base}"
|
||||
//
|
||||
// The components in braces correspond to the IDs for each resource in the
|
||||
// hierarchy. It is expected that, if multiple patterns are provided,
|
||||
// the same component name (e.g. "project") refers to IDs of the same
|
||||
// type of resource.
|
||||
Pattern []string `protobuf:"bytes,2,rep,name=pattern,proto3" json:"pattern,omitempty"`
|
||||
// Optional. The field on the resource that designates the resource name
|
||||
// field. If omitted, this is assumed to be "name".
|
||||
NameField string `protobuf:"bytes,3,opt,name=name_field,json=nameField,proto3" json:"name_field,omitempty"`
|
||||
// Optional. The historical or future-looking state of the resource pattern.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// // The InspectTemplate message originally only supported resource
|
||||
// // names with organization, and project was added later.
|
||||
// message InspectTemplate {
|
||||
// option (google.api.resource) = {
|
||||
// type: "dlp.googleapis.com/InspectTemplate"
|
||||
// pattern:
|
||||
// "organizations/{organization}/inspectTemplates/{inspect_template}"
|
||||
// pattern: "projects/{project}/inspectTemplates/{inspect_template}"
|
||||
// history: ORIGINALLY_SINGLE_PATTERN
|
||||
// };
|
||||
// }
|
||||
History ResourceDescriptor_History `protobuf:"varint,4,opt,name=history,proto3,enum=google.api.ResourceDescriptor_History" json:"history,omitempty"`
|
||||
// The plural name used in the resource name and permission names, such as
|
||||
// 'projects' for the resource name of 'projects/{project}' and the permission
|
||||
// name of 'cloudresourcemanager.googleapis.com/projects.get'. One exception
|
||||
// to this is for Nested Collections that have stuttering names, as defined
|
||||
// in [AIP-122](https://google.aip.dev/122#nested-collections), where the
|
||||
// collection ID in the resource name pattern does not necessarily directly
|
||||
// match the `plural` value.
|
||||
//
|
||||
// It is the same concept of the `plural` field in k8s CRD spec
|
||||
// https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/
|
||||
//
|
||||
// Note: The plural form is required even for singleton resources. See
|
||||
// https://aip.dev/156
|
||||
Plural string `protobuf:"bytes,5,opt,name=plural,proto3" json:"plural,omitempty"`
|
||||
// The same concept of the `singular` field in k8s CRD spec
|
||||
// https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/
|
||||
// Such as "project" for the `resourcemanager.googleapis.com/Project` type.
|
||||
Singular string `protobuf:"bytes,6,opt,name=singular,proto3" json:"singular,omitempty"`
|
||||
// Style flag(s) for this resource.
|
||||
// These indicate that a resource is expected to conform to a given
|
||||
// style. See the specific style flags for additional information.
|
||||
Style []ResourceDescriptor_Style `protobuf:"varint,10,rep,packed,name=style,proto3,enum=google.api.ResourceDescriptor_Style" json:"style,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ResourceDescriptor) Reset() {
|
||||
*x = ResourceDescriptor{}
|
||||
mi := &file_google_api_resource_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ResourceDescriptor) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ResourceDescriptor) ProtoMessage() {}
|
||||
|
||||
func (x *ResourceDescriptor) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_google_api_resource_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ResourceDescriptor.ProtoReflect.Descriptor instead.
|
||||
func (*ResourceDescriptor) Descriptor() ([]byte, []int) {
|
||||
return file_google_api_resource_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *ResourceDescriptor) GetType() string {
|
||||
if x != nil {
|
||||
return x.Type
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ResourceDescriptor) GetPattern() []string {
|
||||
if x != nil {
|
||||
return x.Pattern
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *ResourceDescriptor) GetNameField() string {
|
||||
if x != nil {
|
||||
return x.NameField
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ResourceDescriptor) GetHistory() ResourceDescriptor_History {
|
||||
if x != nil {
|
||||
return x.History
|
||||
}
|
||||
return ResourceDescriptor_HISTORY_UNSPECIFIED
|
||||
}
|
||||
|
||||
func (x *ResourceDescriptor) GetPlural() string {
|
||||
if x != nil {
|
||||
return x.Plural
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ResourceDescriptor) GetSingular() string {
|
||||
if x != nil {
|
||||
return x.Singular
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ResourceDescriptor) GetStyle() []ResourceDescriptor_Style {
|
||||
if x != nil {
|
||||
return x.Style
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Defines a proto annotation that describes a string field that refers to
|
||||
// an API resource.
|
||||
type ResourceReference struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// The resource type that the annotated field references.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// message Subscription {
|
||||
// string topic = 2 [(google.api.resource_reference) = {
|
||||
// type: "pubsub.googleapis.com/Topic"
|
||||
// }];
|
||||
// }
|
||||
//
|
||||
// Occasionally, a field may reference an arbitrary resource. In this case,
|
||||
// APIs use the special value * in their resource reference.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// message GetIamPolicyRequest {
|
||||
// string resource = 2 [(google.api.resource_reference) = {
|
||||
// type: "*"
|
||||
// }];
|
||||
// }
|
||||
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
|
||||
// The resource type of a child collection that the annotated field
|
||||
// references. This is useful for annotating the `parent` field that
|
||||
// doesn't have a fixed resource type.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// message ListLogEntriesRequest {
|
||||
// string parent = 1 [(google.api.resource_reference) = {
|
||||
// child_type: "logging.googleapis.com/LogEntry"
|
||||
// };
|
||||
// }
|
||||
ChildType string `protobuf:"bytes,2,opt,name=child_type,json=childType,proto3" json:"child_type,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ResourceReference) Reset() {
|
||||
*x = ResourceReference{}
|
||||
mi := &file_google_api_resource_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *ResourceReference) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ResourceReference) ProtoMessage() {}
|
||||
|
||||
func (x *ResourceReference) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_google_api_resource_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ResourceReference.ProtoReflect.Descriptor instead.
|
||||
func (*ResourceReference) Descriptor() ([]byte, []int) {
|
||||
return file_google_api_resource_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *ResourceReference) GetType() string {
|
||||
if x != nil {
|
||||
return x.Type
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ResourceReference) GetChildType() string {
|
||||
if x != nil {
|
||||
return x.ChildType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var file_google_api_resource_proto_extTypes = []protoimpl.ExtensionInfo{
|
||||
{
|
||||
ExtendedType: (*descriptorpb.FieldOptions)(nil),
|
||||
ExtensionType: (*ResourceReference)(nil),
|
||||
Field: 1055,
|
||||
Name: "google.api.resource_reference",
|
||||
Tag: "bytes,1055,opt,name=resource_reference",
|
||||
Filename: "google/api/resource.proto",
|
||||
},
|
||||
{
|
||||
ExtendedType: (*descriptorpb.FileOptions)(nil),
|
||||
ExtensionType: ([]*ResourceDescriptor)(nil),
|
||||
Field: 1053,
|
||||
Name: "google.api.resource_definition",
|
||||
Tag: "bytes,1053,rep,name=resource_definition",
|
||||
Filename: "google/api/resource.proto",
|
||||
},
|
||||
{
|
||||
ExtendedType: (*descriptorpb.MessageOptions)(nil),
|
||||
ExtensionType: (*ResourceDescriptor)(nil),
|
||||
Field: 1053,
|
||||
Name: "google.api.resource",
|
||||
Tag: "bytes,1053,opt,name=resource",
|
||||
Filename: "google/api/resource.proto",
|
||||
},
|
||||
}
|
||||
|
||||
// Extension fields to descriptorpb.FieldOptions.
|
||||
var (
|
||||
// An annotation that describes a resource reference, see
|
||||
// [ResourceReference][].
|
||||
//
|
||||
// optional google.api.ResourceReference resource_reference = 1055;
|
||||
E_ResourceReference = &file_google_api_resource_proto_extTypes[0]
|
||||
)
|
||||
|
||||
// Extension fields to descriptorpb.FileOptions.
|
||||
var (
|
||||
// An annotation that describes a resource definition without a corresponding
|
||||
// message; see [ResourceDescriptor][].
|
||||
//
|
||||
// repeated google.api.ResourceDescriptor resource_definition = 1053;
|
||||
E_ResourceDefinition = &file_google_api_resource_proto_extTypes[1]
|
||||
)
|
||||
|
||||
// Extension fields to descriptorpb.MessageOptions.
|
||||
var (
|
||||
// An annotation that describes a resource definition, see
|
||||
// [ResourceDescriptor][].
|
||||
//
|
||||
// optional google.api.ResourceDescriptor resource = 1053;
|
||||
E_Resource = &file_google_api_resource_proto_extTypes[2]
|
||||
)
|
||||
|
||||
var File_google_api_resource_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_google_api_resource_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x19google/api/resource.proto\x12\n" +
|
||||
"google.api\x1a google/protobuf/descriptor.proto\"\xaa\x03\n" +
|
||||
"\x12ResourceDescriptor\x12\x12\n" +
|
||||
"\x04type\x18\x01 \x01(\tR\x04type\x12\x18\n" +
|
||||
"\apattern\x18\x02 \x03(\tR\apattern\x12\x1d\n" +
|
||||
"\n" +
|
||||
"name_field\x18\x03 \x01(\tR\tnameField\x12@\n" +
|
||||
"\ahistory\x18\x04 \x01(\x0e2&.google.api.ResourceDescriptor.HistoryR\ahistory\x12\x16\n" +
|
||||
"\x06plural\x18\x05 \x01(\tR\x06plural\x12\x1a\n" +
|
||||
"\bsingular\x18\x06 \x01(\tR\bsingular\x12:\n" +
|
||||
"\x05style\x18\n" +
|
||||
" \x03(\x0e2$.google.api.ResourceDescriptor.StyleR\x05style\"[\n" +
|
||||
"\aHistory\x12\x17\n" +
|
||||
"\x13HISTORY_UNSPECIFIED\x10\x00\x12\x1d\n" +
|
||||
"\x19ORIGINALLY_SINGLE_PATTERN\x10\x01\x12\x18\n" +
|
||||
"\x14FUTURE_MULTI_PATTERN\x10\x02\"8\n" +
|
||||
"\x05Style\x12\x15\n" +
|
||||
"\x11STYLE_UNSPECIFIED\x10\x00\x12\x18\n" +
|
||||
"\x14DECLARATIVE_FRIENDLY\x10\x01\"F\n" +
|
||||
"\x11ResourceReference\x12\x12\n" +
|
||||
"\x04type\x18\x01 \x01(\tR\x04type\x12\x1d\n" +
|
||||
"\n" +
|
||||
"child_type\x18\x02 \x01(\tR\tchildType:l\n" +
|
||||
"\x12resource_reference\x12\x1d.google.protobuf.FieldOptions\x18\x9f\b \x01(\v2\x1d.google.api.ResourceReferenceR\x11resourceReference:n\n" +
|
||||
"\x13resource_definition\x12\x1c.google.protobuf.FileOptions\x18\x9d\b \x03(\v2\x1e.google.api.ResourceDescriptorR\x12resourceDefinition:\\\n" +
|
||||
"\bresource\x12\x1f.google.protobuf.MessageOptions\x18\x9d\b \x01(\v2\x1e.google.api.ResourceDescriptorR\bresourceB\xab\x01\n" +
|
||||
"\x0ecom.google.apiB\rResourceProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x03GAX\xaa\x02\n" +
|
||||
"Google.Api\xca\x02\n" +
|
||||
"Google\\Api\xe2\x02\x16Google\\Api\\GPBMetadata\xea\x02\vGoogle::Apib\x06proto3"
|
||||
|
||||
var (
|
||||
file_google_api_resource_proto_rawDescOnce sync.Once
|
||||
file_google_api_resource_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_google_api_resource_proto_rawDescGZIP() []byte {
|
||||
file_google_api_resource_proto_rawDescOnce.Do(func() {
|
||||
file_google_api_resource_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_google_api_resource_proto_rawDesc), len(file_google_api_resource_proto_rawDesc)))
|
||||
})
|
||||
return file_google_api_resource_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_google_api_resource_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
|
||||
var file_google_api_resource_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_google_api_resource_proto_goTypes = []any{
|
||||
(ResourceDescriptor_History)(0), // 0: google.api.ResourceDescriptor.History
|
||||
(ResourceDescriptor_Style)(0), // 1: google.api.ResourceDescriptor.Style
|
||||
(*ResourceDescriptor)(nil), // 2: google.api.ResourceDescriptor
|
||||
(*ResourceReference)(nil), // 3: google.api.ResourceReference
|
||||
(*descriptorpb.FieldOptions)(nil), // 4: google.protobuf.FieldOptions
|
||||
(*descriptorpb.FileOptions)(nil), // 5: google.protobuf.FileOptions
|
||||
(*descriptorpb.MessageOptions)(nil), // 6: google.protobuf.MessageOptions
|
||||
}
|
||||
var file_google_api_resource_proto_depIdxs = []int32{
|
||||
0, // 0: google.api.ResourceDescriptor.history:type_name -> google.api.ResourceDescriptor.History
|
||||
1, // 1: google.api.ResourceDescriptor.style:type_name -> google.api.ResourceDescriptor.Style
|
||||
4, // 2: google.api.resource_reference:extendee -> google.protobuf.FieldOptions
|
||||
5, // 3: google.api.resource_definition:extendee -> google.protobuf.FileOptions
|
||||
6, // 4: google.api.resource:extendee -> google.protobuf.MessageOptions
|
||||
3, // 5: google.api.resource_reference:type_name -> google.api.ResourceReference
|
||||
2, // 6: google.api.resource_definition:type_name -> google.api.ResourceDescriptor
|
||||
2, // 7: google.api.resource:type_name -> google.api.ResourceDescriptor
|
||||
8, // [8:8] is the sub-list for method output_type
|
||||
8, // [8:8] is the sub-list for method input_type
|
||||
5, // [5:8] is the sub-list for extension type_name
|
||||
2, // [2:5] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_google_api_resource_proto_init() }
|
||||
func file_google_api_resource_proto_init() {
|
||||
if File_google_api_resource_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_google_api_resource_proto_rawDesc), len(file_google_api_resource_proto_rawDesc)),
|
||||
NumEnums: 2,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 3,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_google_api_resource_proto_goTypes,
|
||||
DependencyIndexes: file_google_api_resource_proto_depIdxs,
|
||||
EnumInfos: file_google_api_resource_proto_enumTypes,
|
||||
MessageInfos: file_google_api_resource_proto_msgTypes,
|
||||
ExtensionInfos: file_google_api_resource_proto_extTypes,
|
||||
}.Build()
|
||||
File_google_api_resource_proto = out.File
|
||||
file_google_api_resource_proto_goTypes = nil
|
||||
file_google_api_resource_proto_depIdxs = nil
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,197 @@
|
|||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/usememos/memos/internal/util"
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
|
||||
// Authenticator provides shared authentication and authorization logic.
|
||||
// Used by gRPC interceptor, Connect interceptor, and file server to ensure
|
||||
// consistent authentication behavior across all API endpoints.
|
||||
//
|
||||
// Authentication methods:
|
||||
// - Session cookie: Browser-based authentication with sliding expiration
|
||||
// - JWT token: API token authentication for programmatic access
|
||||
//
|
||||
// This struct is safe for concurrent use.
|
||||
type Authenticator struct {
|
||||
store *store.Store
|
||||
secret string
|
||||
}
|
||||
|
||||
// NewAuthenticator creates a new Authenticator instance.
|
||||
func NewAuthenticator(store *store.Store, secret string) *Authenticator {
|
||||
return &Authenticator{
|
||||
store: store,
|
||||
secret: secret,
|
||||
}
|
||||
}
|
||||
|
||||
// AuthenticateBySession validates a session cookie and returns the authenticated user.
|
||||
//
|
||||
// Validation steps:
|
||||
// 1. Parse cookie value to extract userID and sessionID
|
||||
// 2. Verify user exists and is not archived
|
||||
// 3. Verify session exists in user's sessions list
|
||||
// 4. Check session hasn't expired (sliding expiration: 14 days from last access)
|
||||
//
|
||||
// Returns the user if authentication succeeds, or an error describing the failure.
|
||||
func (a *Authenticator) AuthenticateBySession(ctx context.Context, sessionCookieValue string) (*store.User, error) {
|
||||
if sessionCookieValue == "" {
|
||||
return nil, errors.New("session cookie value not found")
|
||||
}
|
||||
|
||||
userID, sessionID, err := ParseSessionCookieValue(sessionCookieValue)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "invalid session cookie format")
|
||||
}
|
||||
|
||||
user, err := a.store.GetUser(ctx, &store.FindUser{ID: &userID})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get user")
|
||||
}
|
||||
if user == nil {
|
||||
return nil, errors.New("user not found")
|
||||
}
|
||||
if user.RowStatus == store.Archived {
|
||||
return nil, errors.New("user is archived")
|
||||
}
|
||||
|
||||
sessions, err := a.store.GetUserSessions(ctx, user.ID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get user sessions")
|
||||
}
|
||||
|
||||
if !validateSession(sessionID, sessions) {
|
||||
return nil, errors.New("invalid or expired session")
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// AuthenticateByJWT validates a JWT access token and returns the authenticated user.
|
||||
//
|
||||
// Validation steps:
|
||||
// 1. Parse and verify JWT signature using server secret
|
||||
// 2. Verify key ID matches expected version
|
||||
// 3. Extract user ID from JWT claims (subject field)
|
||||
// 4. Verify user exists and is not archived
|
||||
// 5. Verify token exists in user's access_tokens list (for revocation support)
|
||||
//
|
||||
// Returns the user if authentication succeeds, or an error describing the failure.
|
||||
func (a *Authenticator) AuthenticateByJWT(ctx context.Context, accessToken string) (*store.User, error) {
|
||||
if accessToken == "" {
|
||||
return nil, errors.New("access token not found")
|
||||
}
|
||||
|
||||
claims := &ClaimsMessage{}
|
||||
_, err := jwt.ParseWithClaims(accessToken, claims, func(t *jwt.Token) (any, error) {
|
||||
if t.Method.Alg() != jwt.SigningMethodHS256.Name {
|
||||
return nil, errors.Errorf("unexpected signing method: %v", t.Header["alg"])
|
||||
}
|
||||
kid, ok := t.Header["kid"].(string)
|
||||
if !ok || kid != KeyID {
|
||||
return nil, errors.Errorf("unexpected kid: %v", t.Header["kid"])
|
||||
}
|
||||
return []byte(a.secret), nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.New("invalid or expired access token")
|
||||
}
|
||||
|
||||
userID, err := util.ConvertStringToInt32(claims.Subject)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "malformed ID in token")
|
||||
}
|
||||
|
||||
user, err := a.store.GetUser(ctx, &store.FindUser{ID: &userID})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get user")
|
||||
}
|
||||
if user == nil {
|
||||
return nil, errors.Errorf("user %d not found", userID)
|
||||
}
|
||||
if user.RowStatus == store.Archived {
|
||||
return nil, errors.Errorf("user %d is archived", userID)
|
||||
}
|
||||
|
||||
accessTokens, err := a.store.GetUserAccessTokens(ctx, user.ID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get user access tokens")
|
||||
}
|
||||
if !validateAccessToken(accessToken, accessTokens) {
|
||||
return nil, errors.New("invalid access token")
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// AuthorizeAndSetContext checks user authorization for the given procedure and sets context values.
|
||||
//
|
||||
// Authorization checks:
|
||||
// - Admin-only methods require Host or Admin role (checked via isAdminOnly function)
|
||||
//
|
||||
// Context values set:
|
||||
// - UserIDContextKey: Always set with the user's ID
|
||||
// - SessionIDContextKey: Set if authenticated via session cookie
|
||||
// - AccessTokenContextKey: Set if authenticated via JWT token
|
||||
//
|
||||
// Also updates session last accessed time for session-based auth (sliding expiration).
|
||||
//
|
||||
// Returns the updated context or an error if authorization fails.
|
||||
func (a *Authenticator) AuthorizeAndSetContext(ctx context.Context, procedure string, user *store.User, sessionID, accessToken string, isAdminOnly func(string) bool) (context.Context, error) {
|
||||
// Check admin-only method authorization
|
||||
if isAdminOnly != nil && isAdminOnly(procedure) && user.Role != store.RoleHost && user.Role != store.RoleAdmin {
|
||||
return nil, errors.Errorf("user %q is not authorized for this operation", user.Username)
|
||||
}
|
||||
|
||||
// Set user ID in context (always)
|
||||
ctx = context.WithValue(ctx, UserIDContextKey, user.ID)
|
||||
|
||||
// Set authentication method specific context values
|
||||
if sessionID != "" {
|
||||
ctx = context.WithValue(ctx, SessionIDContextKey, sessionID)
|
||||
// Update session last accessed time for sliding expiration
|
||||
_ = a.store.UpdateUserSessionLastAccessed(ctx, user.ID, sessionID, timestamppb.Now())
|
||||
} else if accessToken != "" {
|
||||
ctx = context.WithValue(ctx, AccessTokenContextKey, accessToken)
|
||||
}
|
||||
|
||||
return ctx, nil
|
||||
}
|
||||
|
||||
// validateSession checks if a session exists and is still valid.
|
||||
// Uses sliding expiration: session is valid if last accessed within SessionSlidingDuration.
|
||||
func validateSession(sessionID string, sessions []*storepb.SessionsUserSetting_Session) bool {
|
||||
for _, session := range sessions {
|
||||
if sessionID == session.SessionId {
|
||||
if session.LastAccessedTime != nil {
|
||||
expiration := session.LastAccessedTime.AsTime().Add(SessionSlidingDuration)
|
||||
if expiration.Before(time.Now()) {
|
||||
return false // Session expired
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false // Session not found
|
||||
}
|
||||
|
||||
// validateAccessToken checks if the token exists in the user's access tokens list.
|
||||
// This enables token revocation: deleted tokens are removed from the list.
|
||||
func validateAccessToken(token string, tokens []*storepb.AccessTokensUserSetting_AccessToken) bool {
|
||||
for _, t := range tokens {
|
||||
if token == t.AccessToken {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package auth
|
||||
|
||||
import "context"
|
||||
|
||||
// ContextKey is the key type for context values.
|
||||
// Using a custom type prevents collisions with other packages.
|
||||
type ContextKey int
|
||||
|
||||
const (
|
||||
// UserIDContextKey stores the authenticated user's ID.
|
||||
// Set for both session-based and token-based authentication.
|
||||
// Use GetUserID(ctx) to retrieve this value.
|
||||
UserIDContextKey ContextKey = iota
|
||||
|
||||
// SessionIDContextKey stores the session ID for session-based auth.
|
||||
// Only set when authenticated via session cookie.
|
||||
SessionIDContextKey
|
||||
|
||||
// AccessTokenContextKey stores the JWT token for token-based auth.
|
||||
// Only set when authenticated via Bearer token.
|
||||
AccessTokenContextKey
|
||||
)
|
||||
|
||||
// GetUserID retrieves the authenticated user's ID from the context.
|
||||
// Returns 0 if no user ID is set (unauthenticated request).
|
||||
func GetUserID(ctx context.Context) int32 {
|
||||
if v, ok := ctx.Value(UserIDContextKey).(int32); ok {
|
||||
return v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// GetSessionID retrieves the session ID from the context.
|
||||
// Returns empty string if not authenticated via session cookie.
|
||||
func GetSessionID(ctx context.Context) string {
|
||||
if v, ok := ctx.Value(SessionIDContextKey).(string); ok {
|
||||
return v
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetAccessToken retrieves the JWT access token from the context.
|
||||
// Returns empty string if not authenticated via bearer token.
|
||||
func GetAccessToken(ctx context.Context) string {
|
||||
if v, ok := ctx.Value(AccessTokenContextKey).(string); ok {
|
||||
return v
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package auth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ExtractSessionCookieFromHeader extracts the session cookie value from an HTTP Cookie header.
|
||||
// Returns empty string if the session cookie is not found.
|
||||
func ExtractSessionCookieFromHeader(cookieHeader string) string {
|
||||
if cookieHeader == "" {
|
||||
return ""
|
||||
}
|
||||
// Use http.Request to parse cookies properly
|
||||
req := &http.Request{Header: http.Header{"Cookie": []string{cookieHeader}}}
|
||||
cookie, err := req.Cookie(SessionCookieName)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return cookie.Value
|
||||
}
|
||||
|
||||
// ExtractBearerToken extracts the JWT token from an Authorization header value.
|
||||
// Expected format: "Bearer {token}"
|
||||
// Returns empty string if no valid bearer token is found.
|
||||
func ExtractBearerToken(authHeader string) string {
|
||||
if authHeader == "" {
|
||||
return ""
|
||||
}
|
||||
parts := strings.Fields(authHeader)
|
||||
if len(parts) != 2 || !strings.EqualFold(parts[0], "bearer") {
|
||||
return ""
|
||||
}
|
||||
return parts[1]
|
||||
}
|
||||
|
|
@ -1,4 +1,13 @@
|
|||
package v1
|
||||
// Package auth provides authentication and authorization for the Memos server.
|
||||
//
|
||||
// This package is used by:
|
||||
// - server/router/api/v1: gRPC and Connect API interceptors
|
||||
// - server/router/fileserver: HTTP file server authentication
|
||||
//
|
||||
// Authentication methods supported:
|
||||
// - Session cookie: Browser-based authentication with sliding expiration
|
||||
// - JWT token: API token authentication for programmatic access
|
||||
package auth
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
|
@ -99,8 +108,8 @@ func generateToken(username string, userID int32, audience string, expirationTim
|
|||
//
|
||||
// Uses UUID v4 (random) for high entropy and uniqueness.
|
||||
// Session IDs are stored in user settings and used to identify browser sessions.
|
||||
func GenerateSessionID() (string, error) {
|
||||
return util.GenUUID(), nil
|
||||
func GenerateSessionID() string {
|
||||
return util.GenUUID()
|
||||
}
|
||||
|
||||
// BuildSessionCookieValue creates the session cookie value.
|
||||
|
|
@ -1,315 +1,125 @@
|
|||
package v1
|
||||
|
||||
// gRPC Authentication Interceptor
|
||||
//
|
||||
// This file implements the authentication interceptor for gRPC requests.
|
||||
// It extracts credentials from gRPC metadata and delegates to the shared Authenticator.
|
||||
//
|
||||
// Authentication flow:
|
||||
// 1. Extract session cookie or bearer token from metadata
|
||||
// 2. Validate credentials using Authenticator
|
||||
// 3. Check authorization (admin-only methods)
|
||||
// 4. Set user context and proceed with request
|
||||
//
|
||||
// For public methods (defined in acl_config.go), authentication is skipped.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/usememos/memos/internal/util"
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
"github.com/usememos/memos/server/auth"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
|
||||
// ContextKey is the key type of context value.
|
||||
type ContextKey int
|
||||
|
||||
const (
|
||||
// UserIDContextKey stores the authenticated user's ID in the context.
|
||||
// Set for both session-based and token-based authentication.
|
||||
UserIDContextKey ContextKey = iota
|
||||
|
||||
// sessionIDContextKey stores the session ID in the context.
|
||||
// Only set for session-based authentication (cookie auth).
|
||||
sessionIDContextKey
|
||||
|
||||
// accessTokenContextKey stores the JWT access token in the context.
|
||||
// Only set for token-based authentication (Bearer token).
|
||||
accessTokenContextKey
|
||||
)
|
||||
|
||||
// GRPCAuthInterceptor is the auth interceptor for gRPC server.
|
||||
// GRPCAuthInterceptor is the authentication interceptor for gRPC server.
|
||||
// It validates incoming requests and sets user context for authenticated requests.
|
||||
type GRPCAuthInterceptor struct {
|
||||
Store *store.Store
|
||||
secret string
|
||||
authenticator *auth.Authenticator
|
||||
}
|
||||
|
||||
// NewGRPCAuthInterceptor returns a new API auth interceptor.
|
||||
// NewGRPCAuthInterceptor creates a new gRPC authentication interceptor.
|
||||
func NewGRPCAuthInterceptor(store *store.Store, secret string) *GRPCAuthInterceptor {
|
||||
return &GRPCAuthInterceptor{
|
||||
Store: store,
|
||||
secret: secret,
|
||||
authenticator: auth.NewAuthenticator(store, secret),
|
||||
}
|
||||
}
|
||||
|
||||
// AuthenticationInterceptor is the unary interceptor for gRPC API.
|
||||
//
|
||||
// Authentication Strategy (in priority order):
|
||||
// 1. Session Cookie: Check for "user_session" cookie with format "{userID}-{sessionID}"
|
||||
// 2. Access Token: Check for "Authorization: Bearer {token}" header with JWT
|
||||
// 3. Public Endpoints: Allow if method is in public allowlist
|
||||
// 4. Reject: Return 401 Unauthenticated if none of the above succeed
|
||||
// Authentication strategy (in priority order):
|
||||
// 1. Session Cookie: "user_session" cookie with format "{userID}-{sessionID}"
|
||||
// 2. Bearer Token: "Authorization: Bearer {jwt_token}" header
|
||||
// 3. Public Methods: Allow without auth if method is in public allowlist
|
||||
// 4. Reject: Return Unauthenticated error
|
||||
//
|
||||
// On successful authentication, sets context values:
|
||||
// - UserIDContextKey: The authenticated user's ID (always set)
|
||||
// - sessionIDContextKey: Session ID (only for cookie auth)
|
||||
// - accessTokenContextKey: JWT token (only for Bearer token auth).
|
||||
// On successful authentication, context values are set:
|
||||
// - auth.UserIDContextKey: The authenticated user's ID
|
||||
// - auth.SessionIDContextKey: Session ID (cookie auth only)
|
||||
// - auth.AccessTokenContextKey: JWT token (bearer auth only).
|
||||
func (in *GRPCAuthInterceptor) AuthenticationInterceptor(ctx context.Context, request any, serverInfo *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (any, error) {
|
||||
md, ok := metadata.FromIncomingContext(ctx)
|
||||
if !ok {
|
||||
return nil, status.Errorf(codes.Unauthenticated, "failed to parse metadata from incoming context")
|
||||
}
|
||||
|
||||
// Authentication Method 1: Session-based authentication (Cookie)
|
||||
// Format: Cookie: user_session={userID}-{sessionID}
|
||||
// Used by: Web browsers
|
||||
if sessionCookieValue, err := getSessionIDFromMetadata(md); err == nil && sessionCookieValue != "" {
|
||||
user, err := in.authenticateBySession(ctx, sessionCookieValue)
|
||||
// Try session cookie authentication
|
||||
if sessionCookie := extractSessionCookieFromMetadata(md); sessionCookie != "" {
|
||||
user, err := in.authenticator.AuthenticateBySession(ctx, sessionCookie)
|
||||
if err == nil && user != nil {
|
||||
// Extract just the sessionID part for context storage
|
||||
_, sessionID, parseErr := ParseSessionCookieValue(sessionCookieValue)
|
||||
if parseErr != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to parse session cookie: %v", parseErr)
|
||||
_, sessionID, _ := auth.ParseSessionCookieValue(sessionCookie)
|
||||
ctx, err = in.authenticator.AuthorizeAndSetContext(ctx, serverInfo.FullMethod, user, sessionID, "", IsAdminOnlyMethod)
|
||||
if err != nil {
|
||||
return nil, toGRPCError(err, codes.PermissionDenied)
|
||||
}
|
||||
return in.handleAuthenticatedRequest(ctx, request, serverInfo, handler, user, sessionID, "")
|
||||
return handler(ctx, request)
|
||||
}
|
||||
}
|
||||
|
||||
// Authentication Method 2: Token-based authentication (JWT)
|
||||
// Format: Authorization: Bearer {jwt_token}
|
||||
// Used by: Mobile apps, CLI tools, API clients
|
||||
if accessToken, err := getAccessTokenFromMetadata(md); err == nil && accessToken != "" {
|
||||
user, err := in.authenticateByJWT(ctx, accessToken)
|
||||
// Try bearer token authentication
|
||||
if token := extractBearerTokenFromMetadata(md); token != "" {
|
||||
user, err := in.authenticator.AuthenticateByJWT(ctx, token)
|
||||
if err == nil && user != nil {
|
||||
return in.handleAuthenticatedRequest(ctx, request, serverInfo, handler, user, "", accessToken)
|
||||
ctx, err = in.authenticator.AuthorizeAndSetContext(ctx, serverInfo.FullMethod, user, "", token, IsAdminOnlyMethod)
|
||||
if err != nil {
|
||||
return nil, toGRPCError(err, codes.PermissionDenied)
|
||||
}
|
||||
return handler(ctx, request)
|
||||
}
|
||||
}
|
||||
|
||||
// Authentication Method 3: Public endpoints
|
||||
// Some endpoints don't require authentication (e.g., login, signup)
|
||||
// Check if this method is in the allowlist
|
||||
if isUnauthorizeAllowedMethod(serverInfo.FullMethod) {
|
||||
// Allow public methods without authentication
|
||||
if IsPublicMethod(serverInfo.FullMethod) {
|
||||
return handler(ctx, request)
|
||||
}
|
||||
|
||||
// If authentication is required but not found, reject the request
|
||||
return nil, status.Errorf(codes.Unauthenticated, "authentication required")
|
||||
}
|
||||
|
||||
// handleAuthenticatedRequest processes an authenticated request with the given user and auth info.
|
||||
func (in *GRPCAuthInterceptor) handleAuthenticatedRequest(ctx context.Context, request any, serverInfo *grpc.UnaryServerInfo, handler grpc.UnaryHandler, user *store.User, sessionID, accessToken string) (any, error) {
|
||||
// Check user status
|
||||
if user.RowStatus == store.Archived {
|
||||
return nil, errors.Errorf("user %q is archived", user.Username)
|
||||
// toGRPCError converts an error to a gRPC status error with the given code.
|
||||
// If the error is already a gRPC status error, it is returned as-is.
|
||||
func toGRPCError(err error, code codes.Code) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if isOnlyForAdminAllowedMethod(serverInfo.FullMethod) && user.Role != store.RoleHost && user.Role != store.RoleAdmin {
|
||||
return nil, errors.Errorf("user %q is not admin", user.Username)
|
||||
if _, ok := status.FromError(err); ok {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set context values
|
||||
ctx = context.WithValue(ctx, UserIDContextKey, user.ID)
|
||||
|
||||
if sessionID != "" {
|
||||
// Session-based authentication
|
||||
ctx = context.WithValue(ctx, sessionIDContextKey, sessionID)
|
||||
// Update session last accessed time
|
||||
_ = in.updateSessionLastAccessed(ctx, user.ID, sessionID)
|
||||
} else if accessToken != "" {
|
||||
// JWT access token-based authentication
|
||||
ctx = context.WithValue(ctx, accessTokenContextKey, accessToken)
|
||||
}
|
||||
|
||||
return handler(ctx, request)
|
||||
return status.Errorf(code, "%v", err)
|
||||
}
|
||||
|
||||
// authenticateByJWT authenticates a user using JWT access token from Authorization header.
|
||||
//
|
||||
// Validation steps:
|
||||
// 1. Parse and verify JWT signature using server secret
|
||||
// 2. Extract user ID from JWT claims (subject field)
|
||||
// 3. Verify user exists and is not archived
|
||||
// 4. Verify token exists in user's access_tokens list (for revocation support)
|
||||
//
|
||||
// Returns the authenticated user or an error.
|
||||
func (in *GRPCAuthInterceptor) authenticateByJWT(ctx context.Context, accessToken string) (*store.User, error) {
|
||||
if accessToken == "" {
|
||||
return nil, status.Errorf(codes.Unauthenticated, "access token not found")
|
||||
}
|
||||
claims := &ClaimsMessage{}
|
||||
_, err := jwt.ParseWithClaims(accessToken, claims, func(t *jwt.Token) (any, error) {
|
||||
if t.Method.Alg() != jwt.SigningMethodHS256.Name {
|
||||
return nil, status.Errorf(codes.Unauthenticated, "unexpected access token signing method=%v, expect %v", t.Header["alg"], jwt.SigningMethodHS256)
|
||||
}
|
||||
if kid, ok := t.Header["kid"].(string); ok {
|
||||
if kid == "v1" {
|
||||
return []byte(in.secret), nil
|
||||
}
|
||||
}
|
||||
return nil, status.Errorf(codes.Unauthenticated, "unexpected access token kid=%v", t.Header["kid"])
|
||||
})
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Unauthenticated, "Invalid or expired access token")
|
||||
}
|
||||
|
||||
// Get user from JWT claims
|
||||
userID, err := util.ConvertStringToInt32(claims.Subject)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "malformed ID in the token")
|
||||
}
|
||||
user, err := in.Store.GetUser(ctx, &store.FindUser{
|
||||
ID: &userID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get user")
|
||||
}
|
||||
if user == nil {
|
||||
return nil, errors.Errorf("user %q not exists", userID)
|
||||
}
|
||||
if user.RowStatus == store.Archived {
|
||||
return nil, errors.Errorf("user %q is archived", userID)
|
||||
}
|
||||
|
||||
// Validate that this access token exists in the user's access tokens
|
||||
accessTokens, err := in.Store.GetUserAccessTokens(ctx, user.ID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get user access tokens")
|
||||
}
|
||||
if !validateAccessToken(accessToken, accessTokens) {
|
||||
return nil, status.Errorf(codes.Unauthenticated, "invalid access token")
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// authenticateBySession authenticates a user using session ID from cookie.
|
||||
//
|
||||
// Validation steps:
|
||||
// 1. Parse cookie value to extract userID and sessionID
|
||||
// 2. Verify user exists and is not archived
|
||||
// 3. Verify session exists in user's sessions list
|
||||
// 4. Check session hasn't expired (sliding expiration: 14 days from last access)
|
||||
//
|
||||
// Returns the authenticated user or an error.
|
||||
func (in *GRPCAuthInterceptor) authenticateBySession(ctx context.Context, sessionCookieValue string) (*store.User, error) {
|
||||
if sessionCookieValue == "" {
|
||||
return nil, status.Errorf(codes.Unauthenticated, "session cookie value not found")
|
||||
}
|
||||
|
||||
// Parse the cookie value to extract userID and sessionID
|
||||
userID, sessionID, err := ParseSessionCookieValue(sessionCookieValue)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Unauthenticated, "invalid session cookie format: %v", err)
|
||||
}
|
||||
|
||||
// Get the user directly using the userID from the cookie
|
||||
user, err := in.Store.GetUser(ctx, &store.FindUser{
|
||||
ID: &userID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get user")
|
||||
}
|
||||
if user == nil {
|
||||
return nil, status.Errorf(codes.Unauthenticated, "user not found")
|
||||
}
|
||||
if user.RowStatus == store.Archived {
|
||||
return nil, status.Errorf(codes.Unauthenticated, "user is archived")
|
||||
}
|
||||
|
||||
// Get user sessions and validate the sessionID
|
||||
sessions, err := in.Store.GetUserSessions(ctx, user.ID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get user sessions")
|
||||
}
|
||||
|
||||
if !validateUserSession(sessionID, sessions) {
|
||||
return nil, status.Errorf(codes.Unauthenticated, "invalid or expired session")
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// updateSessionLastAccessed updates the last accessed time for a user session.
|
||||
func (in *GRPCAuthInterceptor) updateSessionLastAccessed(ctx context.Context, userID int32, sessionID string) error {
|
||||
return in.Store.UpdateUserSessionLastAccessed(ctx, userID, sessionID, timestamppb.Now())
|
||||
}
|
||||
|
||||
// validateUserSession checks if a session exists and is still valid using sliding expiration.
|
||||
//
|
||||
// Sliding expiration logic:
|
||||
// - Session is valid if: last_accessed_time + 14 days > current_time
|
||||
// - Each API call updates last_accessed_time, extending the session
|
||||
// - This provides better UX than fixed expiration (users stay logged in while active).
|
||||
func validateUserSession(sessionID string, userSessions []*storepb.SessionsUserSetting_Session) bool {
|
||||
for _, session := range userSessions {
|
||||
if sessionID == session.SessionId {
|
||||
// Use sliding expiration: check if last_accessed_time + 2 weeks > current_time
|
||||
if session.LastAccessedTime != nil {
|
||||
expirationTime := session.LastAccessedTime.AsTime().Add(SessionSlidingDuration)
|
||||
if expirationTime.Before(time.Now()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
// extractSessionCookieFromMetadata extracts the session cookie value from gRPC metadata.
|
||||
// Checks both "grpcgateway-cookie" (from gRPC-Gateway) and "cookie" (native gRPC).
|
||||
// Returns empty string if no session cookie is found.
|
||||
func extractSessionCookieFromMetadata(md metadata.MD) string {
|
||||
// gRPC-Gateway puts cookies in "grpcgateway-cookie", native gRPC uses "cookie"
|
||||
for _, cookieHeader := range append(md.Get("grpcgateway-cookie"), md.Get("cookie")...) {
|
||||
if cookie := auth.ExtractSessionCookieFromHeader(cookieHeader); cookie != "" {
|
||||
return cookie
|
||||
}
|
||||
}
|
||||
return false
|
||||
return ""
|
||||
}
|
||||
|
||||
// getSessionIDFromMetadata extracts session cookie value from metadata.
|
||||
//
|
||||
// Checks both "grpcgateway-cookie" (set by gRPC-Gateway) and "cookie" (set by native gRPC).
|
||||
// Cookie format: user_session={userID}-{sessionID}.
|
||||
func getSessionIDFromMetadata(md metadata.MD) (string, error) {
|
||||
// Check the cookie header for session cookie value
|
||||
var sessionCookieValue string
|
||||
for _, t := range append(md.Get("grpcgateway-cookie"), md.Get("cookie")...) {
|
||||
header := http.Header{}
|
||||
header.Add("Cookie", t)
|
||||
request := http.Request{Header: header}
|
||||
if v, _ := request.Cookie(SessionCookieName); v != nil {
|
||||
sessionCookieValue = v.Value
|
||||
}
|
||||
// extractBearerTokenFromMetadata extracts JWT token from Authorization header in gRPC metadata.
|
||||
// Returns empty string if no valid bearer token is found.
|
||||
func extractBearerTokenFromMetadata(md metadata.MD) string {
|
||||
authHeaders := md.Get("Authorization")
|
||||
if len(authHeaders) == 0 {
|
||||
return ""
|
||||
}
|
||||
if sessionCookieValue == "" {
|
||||
return "", errors.New("session cookie not found")
|
||||
}
|
||||
return sessionCookieValue, nil
|
||||
}
|
||||
|
||||
// getAccessTokenFromMetadata extracts JWT access token from Authorization header.
|
||||
//
|
||||
// Expected header format: Authorization: Bearer {jwt_token}
|
||||
// This follows the OAuth 2.0 Bearer token specification (RFC 6750).
|
||||
func getAccessTokenFromMetadata(md metadata.MD) (string, error) {
|
||||
// Check the HTTP request Authorization header.
|
||||
authorizationHeaders := md.Get("Authorization")
|
||||
if len(authorizationHeaders) == 0 {
|
||||
return "", errors.New("authorization header not found")
|
||||
}
|
||||
authHeaderParts := strings.Fields(authorizationHeaders[0])
|
||||
if len(authHeaderParts) != 2 || strings.ToLower(authHeaderParts[0]) != "bearer" {
|
||||
return "", errors.New("authorization header format must be Bearer {token}")
|
||||
}
|
||||
return authHeaderParts[1], nil
|
||||
}
|
||||
|
||||
// validateAccessToken checks if the provided JWT token exists in the user's access tokens list.
|
||||
//
|
||||
// This enables token revocation: when a user deletes a token from their settings,
|
||||
// it's removed from this list and subsequent API calls with that token will fail.
|
||||
func validateAccessToken(accessTokenString string, userAccessTokens []*storepb.AccessTokensUserSetting_AccessToken) bool {
|
||||
for _, userAccessToken := range userAccessTokens {
|
||||
if accessTokenString == userAccessToken.AccessToken {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
return auth.ExtractBearerToken(authHeaders[0])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,33 +1,56 @@
|
|||
package v1
|
||||
|
||||
var authenticationAllowlistMethods = map[string]bool{
|
||||
"/memos.api.v1.InstanceService/GetInstanceProfile": true,
|
||||
"/memos.api.v1.InstanceService/GetInstanceSetting": true,
|
||||
// Access Control List (ACL) Configuration
|
||||
//
|
||||
// This file defines which API methods require authentication and which require admin privileges.
|
||||
// Used by both gRPC and Connect interceptors to enforce access control.
|
||||
//
|
||||
// Method names follow the gRPC full method format: "/{package}.{service}/{method}"
|
||||
// Example: "/memos.api.v1.MemoService/CreateMemo"
|
||||
|
||||
// publicMethods lists methods that can be called without authentication.
|
||||
// These are typically read-only endpoints for public content or login-related endpoints.
|
||||
var publicMethods = map[string]bool{
|
||||
// Instance info - needed before login
|
||||
"/memos.api.v1.InstanceService/GetInstanceProfile": true,
|
||||
"/memos.api.v1.InstanceService/GetInstanceSetting": true,
|
||||
|
||||
// Auth - login/session endpoints
|
||||
"/memos.api.v1.AuthService/CreateSession": true,
|
||||
"/memos.api.v1.AuthService/GetCurrentSession": true,
|
||||
|
||||
// User - public user info and registration
|
||||
"/memos.api.v1.UserService/CreateUser": true, // Registration (also admin-only when not first user)
|
||||
"/memos.api.v1.UserService/GetUser": true,
|
||||
"/memos.api.v1.UserService/GetUserAvatar": true,
|
||||
"/memos.api.v1.UserService/GetUserStats": true,
|
||||
"/memos.api.v1.UserService/ListAllUserStats": true,
|
||||
"/memos.api.v1.UserService/SearchUsers": true,
|
||||
|
||||
// Identity providers - needed for SSO login
|
||||
"/memos.api.v1.IdentityProviderService/ListIdentityProviders": true,
|
||||
"/memos.api.v1.AuthService/CreateSession": true,
|
||||
"/memos.api.v1.AuthService/GetCurrentSession": true,
|
||||
"/memos.api.v1.UserService/CreateUser": true,
|
||||
"/memos.api.v1.UserService/GetUser": true,
|
||||
"/memos.api.v1.UserService/GetUserAvatar": true,
|
||||
"/memos.api.v1.UserService/GetUserStats": true,
|
||||
"/memos.api.v1.UserService/ListAllUserStats": true,
|
||||
"/memos.api.v1.UserService/SearchUsers": true,
|
||||
"/memos.api.v1.MemoService/GetMemo": true,
|
||||
"/memos.api.v1.MemoService/ListMemos": true,
|
||||
"/memos.api.v1.AttachmentService/GetAttachmentBinary": true,
|
||||
|
||||
// Memo - public memo access
|
||||
"/memos.api.v1.MemoService/GetMemo": true,
|
||||
"/memos.api.v1.MemoService/ListMemos": true,
|
||||
|
||||
// Attachment - public attachment access
|
||||
"/memos.api.v1.AttachmentService/GetAttachmentBinary": true,
|
||||
}
|
||||
|
||||
// isUnauthorizeAllowedMethod returns whether the method is exempted from authentication.
|
||||
func isUnauthorizeAllowedMethod(fullMethodName string) bool {
|
||||
return authenticationAllowlistMethods[fullMethodName]
|
||||
}
|
||||
|
||||
var allowedMethodsOnlyForAdmin = map[string]bool{
|
||||
"/memos.api.v1.UserService/CreateUser": true,
|
||||
// adminOnlyMethods lists methods that require admin (Host or Admin role) privileges.
|
||||
// Regular users cannot call these methods even if authenticated.
|
||||
var adminOnlyMethods = map[string]bool{
|
||||
"/memos.api.v1.UserService/CreateUser": true, // Admin creates users (except first user registration)
|
||||
"/memos.api.v1.InstanceService/UpdateInstanceSetting": true,
|
||||
}
|
||||
|
||||
// isOnlyForAdminAllowedMethod returns true if the method is allowed to be called only by admin.
|
||||
func isOnlyForAdminAllowedMethod(methodName string) bool {
|
||||
return allowedMethodsOnlyForAdmin[methodName]
|
||||
// IsPublicMethod returns true if the method can be called without authentication.
|
||||
func IsPublicMethod(fullMethodName string) bool {
|
||||
return publicMethods[fullMethodName]
|
||||
}
|
||||
|
||||
// IsAdminOnlyMethod returns true if the method requires admin privileges.
|
||||
func IsAdminOnlyMethod(fullMethodName string) bool {
|
||||
return adminOnlyMethods[fullMethodName]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import (
|
|||
"github.com/usememos/memos/plugin/idp/oauth2"
|
||||
v1pb "github.com/usememos/memos/proto/gen/api/v1"
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
"github.com/usememos/memos/server/auth"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
|
||||
|
|
@ -53,7 +54,7 @@ func (s *APIV1Service) GetCurrentSession(ctx context.Context, _ *v1pb.GetCurrent
|
|||
|
||||
var lastAccessedAt *timestamppb.Timestamp
|
||||
// Update session last accessed time if we have a session ID and get the current session info
|
||||
if sessionID, ok := ctx.Value(sessionIDContextKey).(string); ok && sessionID != "" {
|
||||
if sessionID := auth.GetSessionID(ctx); sessionID != "" {
|
||||
now := timestamppb.Now()
|
||||
if err := s.Store.UpdateUserSessionLastAccessed(ctx, user.ID, sessionID, now); err != nil {
|
||||
// Log error but don't fail the request
|
||||
|
|
@ -221,10 +222,7 @@ func (s *APIV1Service) CreateSession(ctx context.Context, request *v1pb.CreateSe
|
|||
// sliding expiration (14 days from last access) checked during authentication.
|
||||
func (s *APIV1Service) doSignIn(ctx context.Context, user *store.User, expireTime time.Time) error {
|
||||
// Generate unique session ID for web use
|
||||
sessionID, err := GenerateSessionID()
|
||||
if err != nil {
|
||||
return status.Errorf(codes.Internal, "failed to generate session ID, error: %v", err)
|
||||
}
|
||||
sessionID := auth.GenerateSessionID()
|
||||
|
||||
// Track session in user settings
|
||||
if err := s.trackUserSession(ctx, user.ID, sessionID); err != nil {
|
||||
|
|
@ -234,7 +232,7 @@ func (s *APIV1Service) doSignIn(ctx context.Context, user *store.User, expireTim
|
|||
}
|
||||
|
||||
// Set session cookie for web use (format: userID-sessionID)
|
||||
sessionCookieValue := BuildSessionCookieValue(user.ID, sessionID)
|
||||
sessionCookieValue := auth.BuildSessionCookieValue(user.ID, sessionID)
|
||||
sessionCookie, err := s.buildSessionCookie(ctx, sessionCookieValue, expireTime)
|
||||
if err != nil {
|
||||
return status.Errorf(codes.Internal, "failed to build session cookie, error: %v", err)
|
||||
|
|
@ -266,7 +264,7 @@ func (s *APIV1Service) DeleteSession(ctx context.Context, _ *v1pb.DeleteSessionR
|
|||
}
|
||||
|
||||
// Check if we have a session ID (from cookie-based auth)
|
||||
if sessionID, ok := ctx.Value(sessionIDContextKey).(string); ok && sessionID != "" {
|
||||
if sessionID := auth.GetSessionID(ctx); sessionID != "" {
|
||||
// Remove session from user settings
|
||||
if err := s.Store.RemoveUserSession(ctx, user.ID, sessionID); err != nil {
|
||||
slog.Error("failed to remove user session", "error", err)
|
||||
|
|
@ -297,7 +295,7 @@ func (s *APIV1Service) clearAuthCookies(ctx context.Context) error {
|
|||
|
||||
func (*APIV1Service) buildSessionCookie(ctx context.Context, sessionCookieValue string, expireTime time.Time) (string, error) {
|
||||
attrs := []string{
|
||||
fmt.Sprintf("%s=%s", SessionCookieName, sessionCookieValue),
|
||||
fmt.Sprintf("%s=%s", auth.SessionCookieName, sessionCookieValue),
|
||||
"Path=/",
|
||||
"HttpOnly",
|
||||
}
|
||||
|
|
@ -326,8 +324,8 @@ func (*APIV1Service) buildSessionCookie(ctx context.Context, sessionCookieValue
|
|||
}
|
||||
|
||||
func (s *APIV1Service) GetCurrentUser(ctx context.Context) (*store.User, error) {
|
||||
userID, ok := ctx.Value(UserIDContextKey).(int32)
|
||||
if !ok {
|
||||
userID := auth.GetUserID(ctx)
|
||||
if userID == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
user, err := s.Store.GetUser(ctx, &store.FindUser{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"github.com/usememos/memos/proto/gen/api/v1/apiv1connect"
|
||||
)
|
||||
|
||||
// ConnectServiceHandler wraps APIV1Service to implement Connect handler interfaces.
|
||||
// It adapts the existing gRPC service implementations to work with Connect's
|
||||
// request/response wrapper types.
|
||||
//
|
||||
// This wrapper pattern allows us to:
|
||||
// - Reuse existing gRPC service implementations
|
||||
// - Support both native gRPC and Connect protocols
|
||||
// - Maintain a single source of truth for business logic.
|
||||
type ConnectServiceHandler struct {
|
||||
*APIV1Service
|
||||
}
|
||||
|
||||
// NewConnectServiceHandler creates a new Connect service handler.
|
||||
func NewConnectServiceHandler(svc *APIV1Service) *ConnectServiceHandler {
|
||||
return &ConnectServiceHandler{APIV1Service: svc}
|
||||
}
|
||||
|
||||
// RegisterConnectHandlers registers all Connect service handlers on the given mux.
|
||||
func (s *ConnectServiceHandler) RegisterConnectHandlers(mux *http.ServeMux, opts ...connect.HandlerOption) {
|
||||
// Register all service handlers
|
||||
handlers := []struct {
|
||||
path string
|
||||
handler http.Handler
|
||||
}{
|
||||
wrap(apiv1connect.NewInstanceServiceHandler(s, opts...)),
|
||||
wrap(apiv1connect.NewAuthServiceHandler(s, opts...)),
|
||||
wrap(apiv1connect.NewUserServiceHandler(s, opts...)),
|
||||
wrap(apiv1connect.NewMemoServiceHandler(s, opts...)),
|
||||
wrap(apiv1connect.NewAttachmentServiceHandler(s, opts...)),
|
||||
wrap(apiv1connect.NewShortcutServiceHandler(s, opts...)),
|
||||
wrap(apiv1connect.NewActivityServiceHandler(s, opts...)),
|
||||
wrap(apiv1connect.NewIdentityProviderServiceHandler(s, opts...)),
|
||||
}
|
||||
|
||||
for _, h := range handlers {
|
||||
mux.Handle(h.path, h.handler)
|
||||
}
|
||||
}
|
||||
|
||||
// wrap converts (path, handler) return value to a struct for cleaner iteration.
|
||||
func wrap(path string, handler http.Handler) struct {
|
||||
path string
|
||||
handler http.Handler
|
||||
} {
|
||||
return struct {
|
||||
path string
|
||||
handler http.Handler
|
||||
}{path, handler}
|
||||
}
|
||||
|
||||
// convertGRPCError converts gRPC status errors to Connect errors.
|
||||
// This preserves the error code semantics between the two protocols.
|
||||
func convertGRPCError(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if st, ok := status.FromError(err); ok {
|
||||
return connect.NewError(grpcCodeToConnectCode(st.Code()), err)
|
||||
}
|
||||
return connect.NewError(connect.CodeInternal, err)
|
||||
}
|
||||
|
||||
// grpcCodeToConnectCode converts gRPC status codes to Connect error codes.
|
||||
// gRPC and Connect use the same error code semantics, so this is a direct cast.
|
||||
// See: https://connectrpc.com/docs/protocol/#error-codes
|
||||
func grpcCodeToConnectCode(code codes.Code) connect.Code {
|
||||
return connect.Code(code)
|
||||
}
|
||||
|
|
@ -0,0 +1,203 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"runtime/debug"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/usememos/memos/server/auth"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
|
||||
// LoggingInterceptor logs Connect RPC requests with appropriate log levels.
|
||||
//
|
||||
// Log levels:
|
||||
// - INFO: Successful requests and expected client errors (not found, permission denied, etc.)
|
||||
// - ERROR: Server errors (internal, unavailable, etc.)
|
||||
type LoggingInterceptor struct {
|
||||
logStacktrace bool
|
||||
}
|
||||
|
||||
// NewLoggingInterceptor creates a new logging interceptor.
|
||||
func NewLoggingInterceptor(logStacktrace bool) *LoggingInterceptor {
|
||||
return &LoggingInterceptor{logStacktrace: logStacktrace}
|
||||
}
|
||||
|
||||
func (in *LoggingInterceptor) WrapUnary(next connect.UnaryFunc) connect.UnaryFunc {
|
||||
return func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) {
|
||||
resp, err := next(ctx, req)
|
||||
in.log(req.Spec().Procedure, err)
|
||||
return resp, err
|
||||
}
|
||||
}
|
||||
|
||||
func (*LoggingInterceptor) WrapStreamingClient(next connect.StreamingClientFunc) connect.StreamingClientFunc {
|
||||
return next // No-op for server-side interceptor
|
||||
}
|
||||
|
||||
func (*LoggingInterceptor) WrapStreamingHandler(next connect.StreamingHandlerFunc) connect.StreamingHandlerFunc {
|
||||
return next // Streaming not used in this service
|
||||
}
|
||||
|
||||
func (in *LoggingInterceptor) log(procedure string, err error) {
|
||||
level, msg := in.classifyError(err)
|
||||
attrs := []slog.Attr{slog.String("method", procedure)}
|
||||
if err != nil {
|
||||
attrs = append(attrs, slog.String("error", err.Error()))
|
||||
if in.logStacktrace {
|
||||
attrs = append(attrs, slog.String("stacktrace", fmt.Sprintf("%+v", err)))
|
||||
}
|
||||
}
|
||||
slog.LogAttrs(context.Background(), level, msg, attrs...)
|
||||
}
|
||||
|
||||
func (*LoggingInterceptor) classifyError(err error) (slog.Level, string) {
|
||||
if err == nil {
|
||||
return slog.LevelInfo, "OK"
|
||||
}
|
||||
|
||||
var connectErr *connect.Error
|
||||
if !errors.As(err, &connectErr) {
|
||||
return slog.LevelError, "unknown error"
|
||||
}
|
||||
|
||||
// Client errors (expected, log at INFO)
|
||||
switch connectErr.Code() {
|
||||
case connect.CodeCanceled,
|
||||
connect.CodeInvalidArgument,
|
||||
connect.CodeNotFound,
|
||||
connect.CodeAlreadyExists,
|
||||
connect.CodePermissionDenied,
|
||||
connect.CodeUnauthenticated,
|
||||
connect.CodeResourceExhausted,
|
||||
connect.CodeFailedPrecondition,
|
||||
connect.CodeAborted,
|
||||
connect.CodeOutOfRange:
|
||||
return slog.LevelInfo, "client error"
|
||||
default:
|
||||
// Server errors
|
||||
return slog.LevelError, "server error"
|
||||
}
|
||||
}
|
||||
|
||||
// RecoveryInterceptor recovers from panics in Connect handlers and returns an internal error.
|
||||
type RecoveryInterceptor struct {
|
||||
logStacktrace bool
|
||||
}
|
||||
|
||||
// NewRecoveryInterceptor creates a new recovery interceptor.
|
||||
func NewRecoveryInterceptor(logStacktrace bool) *RecoveryInterceptor {
|
||||
return &RecoveryInterceptor{logStacktrace: logStacktrace}
|
||||
}
|
||||
|
||||
func (in *RecoveryInterceptor) WrapUnary(next connect.UnaryFunc) connect.UnaryFunc {
|
||||
return func(ctx context.Context, req connect.AnyRequest) (resp connect.AnyResponse, err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
in.logPanic(req.Spec().Procedure, r)
|
||||
err = connect.NewError(connect.CodeInternal, errors.New("internal server error"))
|
||||
}
|
||||
}()
|
||||
return next(ctx, req)
|
||||
}
|
||||
}
|
||||
|
||||
func (*RecoveryInterceptor) WrapStreamingClient(next connect.StreamingClientFunc) connect.StreamingClientFunc {
|
||||
return next
|
||||
}
|
||||
|
||||
func (*RecoveryInterceptor) WrapStreamingHandler(next connect.StreamingHandlerFunc) connect.StreamingHandlerFunc {
|
||||
return next
|
||||
}
|
||||
|
||||
func (in *RecoveryInterceptor) logPanic(procedure string, panicValue any) {
|
||||
attrs := []slog.Attr{
|
||||
slog.String("method", procedure),
|
||||
slog.Any("panic", panicValue),
|
||||
}
|
||||
if in.logStacktrace {
|
||||
attrs = append(attrs, slog.String("stacktrace", string(debug.Stack())))
|
||||
}
|
||||
slog.LogAttrs(context.Background(), slog.LevelError, "panic recovered in Connect handler", attrs...)
|
||||
}
|
||||
|
||||
// AuthInterceptor handles authentication for Connect handlers.
|
||||
//
|
||||
// It reuses the same authentication logic as GRPCAuthInterceptor by delegating
|
||||
// to a shared Authenticator instance. This ensures consistent authentication
|
||||
// behavior across both gRPC and Connect protocols.
|
||||
type AuthInterceptor struct {
|
||||
authenticator *auth.Authenticator
|
||||
}
|
||||
|
||||
// NewAuthInterceptor creates a new auth interceptor.
|
||||
func NewAuthInterceptor(store *store.Store, secret string) *AuthInterceptor {
|
||||
return &AuthInterceptor{
|
||||
authenticator: auth.NewAuthenticator(store, secret),
|
||||
}
|
||||
}
|
||||
|
||||
func (in *AuthInterceptor) WrapUnary(next connect.UnaryFunc) connect.UnaryFunc {
|
||||
return func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) {
|
||||
procedure := req.Spec().Procedure
|
||||
header := req.Header()
|
||||
|
||||
// Try session cookie authentication first
|
||||
if sessionCookie := auth.ExtractSessionCookieFromHeader(header.Get("Cookie")); sessionCookie != "" {
|
||||
user, err := in.authenticator.AuthenticateBySession(ctx, sessionCookie)
|
||||
if err == nil && user != nil {
|
||||
_, sessionID, _ := auth.ParseSessionCookieValue(sessionCookie)
|
||||
ctx, err = in.authenticator.AuthorizeAndSetContext(ctx, procedure, user, sessionID, "", IsAdminOnlyMethod)
|
||||
if err != nil {
|
||||
return nil, convertAuthError(err)
|
||||
}
|
||||
return next(ctx, req)
|
||||
}
|
||||
}
|
||||
|
||||
// Try JWT token authentication
|
||||
if accessToken := auth.ExtractBearerToken(header.Get("Authorization")); accessToken != "" {
|
||||
user, err := in.authenticator.AuthenticateByJWT(ctx, accessToken)
|
||||
if err == nil && user != nil {
|
||||
ctx, err = in.authenticator.AuthorizeAndSetContext(ctx, procedure, user, "", accessToken, IsAdminOnlyMethod)
|
||||
if err != nil {
|
||||
return nil, convertAuthError(err)
|
||||
}
|
||||
return next(ctx, req)
|
||||
}
|
||||
}
|
||||
|
||||
// Allow public methods without authentication
|
||||
if IsPublicMethod(procedure) {
|
||||
return next(ctx, req)
|
||||
}
|
||||
|
||||
return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("authentication required"))
|
||||
}
|
||||
}
|
||||
|
||||
func (*AuthInterceptor) WrapStreamingClient(next connect.StreamingClientFunc) connect.StreamingClientFunc {
|
||||
return next
|
||||
}
|
||||
|
||||
func (*AuthInterceptor) WrapStreamingHandler(next connect.StreamingHandlerFunc) connect.StreamingHandlerFunc {
|
||||
return next
|
||||
}
|
||||
|
||||
// convertAuthError converts authentication/authorization errors to Connect errors.
|
||||
func convertAuthError(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
// Check if it's already a Connect error
|
||||
var connectErr *connect.Error
|
||||
if errors.As(err, &connectErr) {
|
||||
return err
|
||||
}
|
||||
// Default to permission denied for auth errors
|
||||
return connect.NewError(connect.CodePermissionDenied, err)
|
||||
}
|
||||
|
|
@ -0,0 +1,502 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
|
||||
v1pb "github.com/usememos/memos/proto/gen/api/v1"
|
||||
)
|
||||
|
||||
// This file contains all Connect service handler method implementations.
|
||||
// Each method delegates to the underlying gRPC service implementation,
|
||||
// converting between Connect and gRPC request/response types.
|
||||
|
||||
// InstanceService
|
||||
|
||||
func (s *ConnectServiceHandler) GetInstanceProfile(ctx context.Context, req *connect.Request[v1pb.GetInstanceProfileRequest]) (*connect.Response[v1pb.InstanceProfile], error) {
|
||||
resp, err := s.APIV1Service.GetInstanceProfile(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) GetInstanceSetting(ctx context.Context, req *connect.Request[v1pb.GetInstanceSettingRequest]) (*connect.Response[v1pb.InstanceSetting], error) {
|
||||
resp, err := s.APIV1Service.GetInstanceSetting(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) UpdateInstanceSetting(ctx context.Context, req *connect.Request[v1pb.UpdateInstanceSettingRequest]) (*connect.Response[v1pb.InstanceSetting], error) {
|
||||
resp, err := s.APIV1Service.UpdateInstanceSetting(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
// AuthService
|
||||
|
||||
func (s *ConnectServiceHandler) GetCurrentSession(ctx context.Context, req *connect.Request[v1pb.GetCurrentSessionRequest]) (*connect.Response[v1pb.GetCurrentSessionResponse], error) {
|
||||
resp, err := s.APIV1Service.GetCurrentSession(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) CreateSession(ctx context.Context, req *connect.Request[v1pb.CreateSessionRequest]) (*connect.Response[v1pb.CreateSessionResponse], error) {
|
||||
resp, err := s.APIV1Service.CreateSession(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) DeleteSession(ctx context.Context, req *connect.Request[v1pb.DeleteSessionRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
resp, err := s.APIV1Service.DeleteSession(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
// UserService
|
||||
|
||||
func (s *ConnectServiceHandler) ListUsers(ctx context.Context, req *connect.Request[v1pb.ListUsersRequest]) (*connect.Response[v1pb.ListUsersResponse], error) {
|
||||
resp, err := s.APIV1Service.ListUsers(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) GetUser(ctx context.Context, req *connect.Request[v1pb.GetUserRequest]) (*connect.Response[v1pb.User], error) {
|
||||
resp, err := s.APIV1Service.GetUser(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) CreateUser(ctx context.Context, req *connect.Request[v1pb.CreateUserRequest]) (*connect.Response[v1pb.User], error) {
|
||||
resp, err := s.APIV1Service.CreateUser(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) UpdateUser(ctx context.Context, req *connect.Request[v1pb.UpdateUserRequest]) (*connect.Response[v1pb.User], error) {
|
||||
resp, err := s.APIV1Service.UpdateUser(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) DeleteUser(ctx context.Context, req *connect.Request[v1pb.DeleteUserRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
resp, err := s.APIV1Service.DeleteUser(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) ListAllUserStats(ctx context.Context, req *connect.Request[v1pb.ListAllUserStatsRequest]) (*connect.Response[v1pb.ListAllUserStatsResponse], error) {
|
||||
resp, err := s.APIV1Service.ListAllUserStats(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) GetUserStats(ctx context.Context, req *connect.Request[v1pb.GetUserStatsRequest]) (*connect.Response[v1pb.UserStats], error) {
|
||||
resp, err := s.APIV1Service.GetUserStats(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) GetUserSetting(ctx context.Context, req *connect.Request[v1pb.GetUserSettingRequest]) (*connect.Response[v1pb.UserSetting], error) {
|
||||
resp, err := s.APIV1Service.GetUserSetting(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) UpdateUserSetting(ctx context.Context, req *connect.Request[v1pb.UpdateUserSettingRequest]) (*connect.Response[v1pb.UserSetting], error) {
|
||||
resp, err := s.APIV1Service.UpdateUserSetting(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) ListUserSettings(ctx context.Context, req *connect.Request[v1pb.ListUserSettingsRequest]) (*connect.Response[v1pb.ListUserSettingsResponse], error) {
|
||||
resp, err := s.APIV1Service.ListUserSettings(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) ListUserAccessTokens(ctx context.Context, req *connect.Request[v1pb.ListUserAccessTokensRequest]) (*connect.Response[v1pb.ListUserAccessTokensResponse], error) {
|
||||
resp, err := s.APIV1Service.ListUserAccessTokens(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) CreateUserAccessToken(ctx context.Context, req *connect.Request[v1pb.CreateUserAccessTokenRequest]) (*connect.Response[v1pb.UserAccessToken], error) {
|
||||
resp, err := s.APIV1Service.CreateUserAccessToken(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) DeleteUserAccessToken(ctx context.Context, req *connect.Request[v1pb.DeleteUserAccessTokenRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
resp, err := s.APIV1Service.DeleteUserAccessToken(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) ListUserSessions(ctx context.Context, req *connect.Request[v1pb.ListUserSessionsRequest]) (*connect.Response[v1pb.ListUserSessionsResponse], error) {
|
||||
resp, err := s.APIV1Service.ListUserSessions(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) RevokeUserSession(ctx context.Context, req *connect.Request[v1pb.RevokeUserSessionRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
resp, err := s.APIV1Service.RevokeUserSession(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) ListUserWebhooks(ctx context.Context, req *connect.Request[v1pb.ListUserWebhooksRequest]) (*connect.Response[v1pb.ListUserWebhooksResponse], error) {
|
||||
resp, err := s.APIV1Service.ListUserWebhooks(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) CreateUserWebhook(ctx context.Context, req *connect.Request[v1pb.CreateUserWebhookRequest]) (*connect.Response[v1pb.UserWebhook], error) {
|
||||
resp, err := s.APIV1Service.CreateUserWebhook(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) UpdateUserWebhook(ctx context.Context, req *connect.Request[v1pb.UpdateUserWebhookRequest]) (*connect.Response[v1pb.UserWebhook], error) {
|
||||
resp, err := s.APIV1Service.UpdateUserWebhook(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) DeleteUserWebhook(ctx context.Context, req *connect.Request[v1pb.DeleteUserWebhookRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
resp, err := s.APIV1Service.DeleteUserWebhook(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) ListUserNotifications(ctx context.Context, req *connect.Request[v1pb.ListUserNotificationsRequest]) (*connect.Response[v1pb.ListUserNotificationsResponse], error) {
|
||||
resp, err := s.APIV1Service.ListUserNotifications(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) UpdateUserNotification(ctx context.Context, req *connect.Request[v1pb.UpdateUserNotificationRequest]) (*connect.Response[v1pb.UserNotification], error) {
|
||||
resp, err := s.APIV1Service.UpdateUserNotification(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) DeleteUserNotification(ctx context.Context, req *connect.Request[v1pb.DeleteUserNotificationRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
resp, err := s.APIV1Service.DeleteUserNotification(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
// MemoService
|
||||
|
||||
func (s *ConnectServiceHandler) CreateMemo(ctx context.Context, req *connect.Request[v1pb.CreateMemoRequest]) (*connect.Response[v1pb.Memo], error) {
|
||||
resp, err := s.APIV1Service.CreateMemo(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) ListMemos(ctx context.Context, req *connect.Request[v1pb.ListMemosRequest]) (*connect.Response[v1pb.ListMemosResponse], error) {
|
||||
resp, err := s.APIV1Service.ListMemos(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) GetMemo(ctx context.Context, req *connect.Request[v1pb.GetMemoRequest]) (*connect.Response[v1pb.Memo], error) {
|
||||
resp, err := s.APIV1Service.GetMemo(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) UpdateMemo(ctx context.Context, req *connect.Request[v1pb.UpdateMemoRequest]) (*connect.Response[v1pb.Memo], error) {
|
||||
resp, err := s.APIV1Service.UpdateMemo(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) DeleteMemo(ctx context.Context, req *connect.Request[v1pb.DeleteMemoRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
resp, err := s.APIV1Service.DeleteMemo(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) SetMemoAttachments(ctx context.Context, req *connect.Request[v1pb.SetMemoAttachmentsRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
resp, err := s.APIV1Service.SetMemoAttachments(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) ListMemoAttachments(ctx context.Context, req *connect.Request[v1pb.ListMemoAttachmentsRequest]) (*connect.Response[v1pb.ListMemoAttachmentsResponse], error) {
|
||||
resp, err := s.APIV1Service.ListMemoAttachments(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) SetMemoRelations(ctx context.Context, req *connect.Request[v1pb.SetMemoRelationsRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
resp, err := s.APIV1Service.SetMemoRelations(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) ListMemoRelations(ctx context.Context, req *connect.Request[v1pb.ListMemoRelationsRequest]) (*connect.Response[v1pb.ListMemoRelationsResponse], error) {
|
||||
resp, err := s.APIV1Service.ListMemoRelations(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) CreateMemoComment(ctx context.Context, req *connect.Request[v1pb.CreateMemoCommentRequest]) (*connect.Response[v1pb.Memo], error) {
|
||||
resp, err := s.APIV1Service.CreateMemoComment(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) ListMemoComments(ctx context.Context, req *connect.Request[v1pb.ListMemoCommentsRequest]) (*connect.Response[v1pb.ListMemoCommentsResponse], error) {
|
||||
resp, err := s.APIV1Service.ListMemoComments(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) ListMemoReactions(ctx context.Context, req *connect.Request[v1pb.ListMemoReactionsRequest]) (*connect.Response[v1pb.ListMemoReactionsResponse], error) {
|
||||
resp, err := s.APIV1Service.ListMemoReactions(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) UpsertMemoReaction(ctx context.Context, req *connect.Request[v1pb.UpsertMemoReactionRequest]) (*connect.Response[v1pb.Reaction], error) {
|
||||
resp, err := s.APIV1Service.UpsertMemoReaction(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) DeleteMemoReaction(ctx context.Context, req *connect.Request[v1pb.DeleteMemoReactionRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
resp, err := s.APIV1Service.DeleteMemoReaction(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
// AttachmentService
|
||||
|
||||
func (s *ConnectServiceHandler) CreateAttachment(ctx context.Context, req *connect.Request[v1pb.CreateAttachmentRequest]) (*connect.Response[v1pb.Attachment], error) {
|
||||
resp, err := s.APIV1Service.CreateAttachment(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) ListAttachments(ctx context.Context, req *connect.Request[v1pb.ListAttachmentsRequest]) (*connect.Response[v1pb.ListAttachmentsResponse], error) {
|
||||
resp, err := s.APIV1Service.ListAttachments(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) GetAttachment(ctx context.Context, req *connect.Request[v1pb.GetAttachmentRequest]) (*connect.Response[v1pb.Attachment], error) {
|
||||
resp, err := s.APIV1Service.GetAttachment(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) UpdateAttachment(ctx context.Context, req *connect.Request[v1pb.UpdateAttachmentRequest]) (*connect.Response[v1pb.Attachment], error) {
|
||||
resp, err := s.APIV1Service.UpdateAttachment(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) DeleteAttachment(ctx context.Context, req *connect.Request[v1pb.DeleteAttachmentRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
resp, err := s.APIV1Service.DeleteAttachment(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
// ShortcutService
|
||||
|
||||
func (s *ConnectServiceHandler) ListShortcuts(ctx context.Context, req *connect.Request[v1pb.ListShortcutsRequest]) (*connect.Response[v1pb.ListShortcutsResponse], error) {
|
||||
resp, err := s.APIV1Service.ListShortcuts(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) GetShortcut(ctx context.Context, req *connect.Request[v1pb.GetShortcutRequest]) (*connect.Response[v1pb.Shortcut], error) {
|
||||
resp, err := s.APIV1Service.GetShortcut(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) CreateShortcut(ctx context.Context, req *connect.Request[v1pb.CreateShortcutRequest]) (*connect.Response[v1pb.Shortcut], error) {
|
||||
resp, err := s.APIV1Service.CreateShortcut(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) UpdateShortcut(ctx context.Context, req *connect.Request[v1pb.UpdateShortcutRequest]) (*connect.Response[v1pb.Shortcut], error) {
|
||||
resp, err := s.APIV1Service.UpdateShortcut(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) DeleteShortcut(ctx context.Context, req *connect.Request[v1pb.DeleteShortcutRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
resp, err := s.APIV1Service.DeleteShortcut(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
// ActivityService
|
||||
|
||||
func (s *ConnectServiceHandler) ListActivities(ctx context.Context, req *connect.Request[v1pb.ListActivitiesRequest]) (*connect.Response[v1pb.ListActivitiesResponse], error) {
|
||||
resp, err := s.APIV1Service.ListActivities(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) GetActivity(ctx context.Context, req *connect.Request[v1pb.GetActivityRequest]) (*connect.Response[v1pb.Activity], error) {
|
||||
resp, err := s.APIV1Service.GetActivity(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
// IdentityProviderService
|
||||
|
||||
func (s *ConnectServiceHandler) ListIdentityProviders(ctx context.Context, req *connect.Request[v1pb.ListIdentityProvidersRequest]) (*connect.Response[v1pb.ListIdentityProvidersResponse], error) {
|
||||
resp, err := s.APIV1Service.ListIdentityProviders(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) GetIdentityProvider(ctx context.Context, req *connect.Request[v1pb.GetIdentityProviderRequest]) (*connect.Response[v1pb.IdentityProvider], error) {
|
||||
resp, err := s.APIV1Service.GetIdentityProvider(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) CreateIdentityProvider(ctx context.Context, req *connect.Request[v1pb.CreateIdentityProviderRequest]) (*connect.Response[v1pb.IdentityProvider], error) {
|
||||
resp, err := s.APIV1Service.CreateIdentityProvider(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) UpdateIdentityProvider(ctx context.Context, req *connect.Request[v1pb.UpdateIdentityProviderRequest]) (*connect.Response[v1pb.IdentityProvider], error) {
|
||||
resp, err := s.APIV1Service.UpdateIdentityProvider(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
||||
func (s *ConnectServiceHandler) DeleteIdentityProvider(ctx context.Context, req *connect.Request[v1pb.DeleteIdentityProviderRequest]) (*connect.Response[emptypb.Empty], error) {
|
||||
resp, err := s.APIV1Service.DeleteIdentityProvider(ctx, req.Msg)
|
||||
if err != nil {
|
||||
return nil, convertGRPCError(err)
|
||||
}
|
||||
return connect.NewResponse(resp), nil
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/usememos/memos/internal/profile"
|
||||
"github.com/usememos/memos/plugin/markdown"
|
||||
"github.com/usememos/memos/server/auth"
|
||||
apiv1 "github.com/usememos/memos/server/router/api/v1"
|
||||
"github.com/usememos/memos/store"
|
||||
teststore "github.com/usememos/memos/store/test"
|
||||
|
|
@ -81,6 +82,6 @@ func (ts *TestService) CreateRegularUser(ctx context.Context, username string) (
|
|||
|
||||
// CreateUserContext creates a context with the given user's ID for authentication.
|
||||
func (*TestService) CreateUserContext(ctx context.Context, userID int32) context.Context {
|
||||
// Use the real context key from the parent package
|
||||
return context.WithValue(ctx, apiv1.UserIDContextKey, userID)
|
||||
// Use the context key from the auth package
|
||||
return context.WithValue(ctx, auth.UserIDContextKey, userID)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import (
|
|||
"github.com/usememos/memos/internal/util"
|
||||
v1pb "github.com/usememos/memos/proto/gen/api/v1"
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
"github.com/usememos/memos/server/auth"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
|
||||
|
|
@ -536,7 +537,7 @@ func (s *APIV1Service) ListUserAccessTokens(ctx context.Context, request *v1pb.L
|
|||
|
||||
accessTokens := []*v1pb.UserAccessToken{}
|
||||
for _, userAccessToken := range userAccessTokens {
|
||||
claims := &ClaimsMessage{}
|
||||
claims := &auth.ClaimsMessage{}
|
||||
_, err := jwt.ParseWithClaims(userAccessToken.AccessToken, claims, func(t *jwt.Token) (any, error) {
|
||||
if t.Method.Alg() != jwt.SigningMethodHS256.Name {
|
||||
return nil, errors.Errorf("unexpected access token signing method=%v, expect %v", t.Header["alg"], jwt.SigningMethodHS256)
|
||||
|
|
@ -616,12 +617,12 @@ func (s *APIV1Service) CreateUserAccessToken(ctx context.Context, request *v1pb.
|
|||
expiresAt = request.AccessToken.ExpiresAt.AsTime()
|
||||
}
|
||||
|
||||
accessToken, err := GenerateAccessToken(currentUser.Username, currentUser.ID, expiresAt, []byte(s.Secret))
|
||||
accessToken, err := auth.GenerateAccessToken(currentUser.Username, currentUser.ID, expiresAt, []byte(s.Secret))
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to generate access token: %v", err)
|
||||
}
|
||||
|
||||
claims := &ClaimsMessage{}
|
||||
claims := &auth.ClaimsMessage{}
|
||||
_, err = jwt.ParseWithClaims(accessToken, claims, func(t *jwt.Token) (any, error) {
|
||||
if t.Method.Alg() != jwt.SigningMethodHS256.Name {
|
||||
return nil, errors.Errorf("unexpected access token signing method=%v, expect %v", t.Header["alg"], jwt.SigningMethodHS256)
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"net/http"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"github.com/improbable-eng/grpc-web/go/grpcweb"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
"golang.org/x/sync/semaphore"
|
||||
|
|
@ -123,15 +124,28 @@ func (s *APIV1Service) RegisterGateway(ctx context.Context, echoServer *echo.Ech
|
|||
gwGroup.Any("/api/v1/*", handler)
|
||||
gwGroup.Any("/file/*", handler)
|
||||
|
||||
// GRPC web proxy.
|
||||
options := []grpcweb.Option{
|
||||
grpcweb.WithCorsForRegisteredEndpointsOnly(false),
|
||||
grpcweb.WithOriginFunc(func(_ string) bool {
|
||||
return true
|
||||
}),
|
||||
}
|
||||
wrappedGrpc := grpcweb.WrapServer(s.grpcServer, options...)
|
||||
echoServer.Any("/memos.api.v1.*", echo.WrapHandler(wrappedGrpc))
|
||||
// Connect handlers for browser clients (replaces grpc-web).
|
||||
logStacktraces := s.Profile.IsDev()
|
||||
connectInterceptors := connect.WithInterceptors(
|
||||
NewLoggingInterceptor(logStacktraces),
|
||||
NewRecoveryInterceptor(logStacktraces),
|
||||
NewAuthInterceptor(s.Store, s.Secret),
|
||||
)
|
||||
connectMux := http.NewServeMux()
|
||||
connectHandler := NewConnectServiceHandler(s)
|
||||
connectHandler.RegisterConnectHandlers(connectMux, connectInterceptors)
|
||||
|
||||
// Wrap with CORS for browser access
|
||||
corsHandler := middleware.CORSWithConfig(middleware.CORSConfig{
|
||||
AllowOriginFunc: func(_ string) (bool, error) {
|
||||
return true, nil
|
||||
},
|
||||
AllowMethods: []string{http.MethodGet, http.MethodPost, http.MethodOptions},
|
||||
AllowHeaders: []string{"*"},
|
||||
AllowCredentials: true,
|
||||
})
|
||||
connectGroup := echoServer.Group("", corsHandler)
|
||||
connectGroup.Any("/memos.api.v1.*", echo.WrapHandler(connectMux))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/disintegration/imaging"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sync/semaphore"
|
||||
|
|
@ -23,7 +22,7 @@ import (
|
|||
"github.com/usememos/memos/internal/util"
|
||||
"github.com/usememos/memos/plugin/storage/s3"
|
||||
storepb "github.com/usememos/memos/proto/gen/store"
|
||||
apiv1 "github.com/usememos/memos/server/router/api/v1"
|
||||
"github.com/usememos/memos/server/auth"
|
||||
"github.com/usememos/memos/store"
|
||||
)
|
||||
|
||||
|
|
@ -43,9 +42,9 @@ var SupportedThumbnailMimeTypes = []string{
|
|||
// This service bypasses gRPC-Gateway to use native HTTP serving via http.ServeContent(),
|
||||
// which is required for Safari video/audio playback.
|
||||
type FileServerService struct {
|
||||
Profile *profile.Profile
|
||||
Store *store.Store
|
||||
Secret string
|
||||
Profile *profile.Profile
|
||||
Store *store.Store
|
||||
authenticator *auth.Authenticator
|
||||
|
||||
// thumbnailSemaphore limits concurrent thumbnail generation to prevent memory exhaustion
|
||||
thumbnailSemaphore *semaphore.Weighted
|
||||
|
|
@ -56,7 +55,7 @@ func NewFileServerService(profile *profile.Profile, store *store.Store, secret s
|
|||
return &FileServerService{
|
||||
Profile: profile,
|
||||
Store: store,
|
||||
Secret: secret,
|
||||
authenticator: auth.NewAuthenticator(store, secret),
|
||||
thumbnailSemaphore: semaphore.NewWeighted(3), // Limit to 3 concurrent thumbnail generations
|
||||
}
|
||||
}
|
||||
|
|
@ -249,10 +248,11 @@ func (s *FileServerService) checkAttachmentPermission(ctx context.Context, c ech
|
|||
|
||||
// getCurrentUser retrieves the current authenticated user from the Echo context.
|
||||
// It checks both session cookies and Bearer tokens for authentication.
|
||||
// Uses the shared Authenticator for consistent authentication logic.
|
||||
func (s *FileServerService) getCurrentUser(ctx context.Context, c echo.Context) (*store.User, error) {
|
||||
// Try session cookie authentication first
|
||||
if cookie, err := c.Cookie(apiv1.SessionCookieName); err == nil && cookie.Value != "" {
|
||||
user, err := s.authenticateBySession(ctx, cookie.Value)
|
||||
if cookie, err := c.Cookie(auth.SessionCookieName); err == nil && cookie.Value != "" {
|
||||
user, err := s.authenticator.AuthenticateBySession(ctx, cookie.Value)
|
||||
if err == nil && user != nil {
|
||||
return user, nil
|
||||
}
|
||||
|
|
@ -262,8 +262,8 @@ func (s *FileServerService) getCurrentUser(ctx context.Context, c echo.Context)
|
|||
authHeader := c.Request().Header.Get("Authorization")
|
||||
if authHeader != "" {
|
||||
parts := strings.Fields(authHeader)
|
||||
if len(parts) == 2 && strings.ToLower(parts[0]) == "bearer" {
|
||||
user, err := s.authenticateByJWT(ctx, parts[1])
|
||||
if len(parts) == 2 && strings.EqualFold(parts[0], "bearer") {
|
||||
user, err := s.authenticator.AuthenticateByJWT(ctx, parts[1])
|
||||
if err == nil && user != nil {
|
||||
return user, nil
|
||||
}
|
||||
|
|
@ -274,139 +274,6 @@ func (s *FileServerService) getCurrentUser(ctx context.Context, c echo.Context)
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
// authenticateBySession authenticates a user using session ID from cookie.
|
||||
func (s *FileServerService) authenticateBySession(ctx context.Context, sessionCookieValue string) (*store.User, error) {
|
||||
if sessionCookieValue == "" {
|
||||
return nil, errors.New("session cookie value not found")
|
||||
}
|
||||
|
||||
// Parse the cookie value to extract userID and sessionID
|
||||
userID, sessionID, err := s.parseSessionCookieValue(sessionCookieValue)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "invalid session cookie format")
|
||||
}
|
||||
|
||||
// Get the user
|
||||
user, err := s.Store.GetUser(ctx, &store.FindUser{
|
||||
ID: &userID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get user")
|
||||
}
|
||||
if user == nil {
|
||||
return nil, errors.New("user not found")
|
||||
}
|
||||
if user.RowStatus == store.Archived {
|
||||
return nil, errors.New("user is archived")
|
||||
}
|
||||
|
||||
// Get user sessions and validate the sessionID
|
||||
sessions, err := s.Store.GetUserSessions(ctx, user.ID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get user sessions")
|
||||
}
|
||||
|
||||
if !s.validateUserSession(sessionID, sessions) {
|
||||
return nil, errors.New("invalid or expired session")
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// authenticateByJWT authenticates a user using JWT access token from Authorization header.
|
||||
func (s *FileServerService) authenticateByJWT(ctx context.Context, accessToken string) (*store.User, error) {
|
||||
if accessToken == "" {
|
||||
return nil, errors.New("access token not found")
|
||||
}
|
||||
|
||||
claims := &apiv1.ClaimsMessage{}
|
||||
_, err := jwt.ParseWithClaims(accessToken, claims, func(t *jwt.Token) (any, error) {
|
||||
if t.Method.Alg() != jwt.SigningMethodHS256.Name {
|
||||
return nil, errors.Errorf("unexpected access token signing method=%v, expect %v", t.Header["alg"], jwt.SigningMethodHS256)
|
||||
}
|
||||
if kid, ok := t.Header["kid"].(string); ok {
|
||||
if kid == apiv1.KeyID {
|
||||
return []byte(s.Secret), nil
|
||||
}
|
||||
}
|
||||
return nil, errors.Errorf("unexpected access token kid=%v", t.Header["kid"])
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Invalid or expired access token")
|
||||
}
|
||||
|
||||
// Get user from JWT claims
|
||||
userID, err := util.ConvertStringToInt32(claims.Subject)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "malformed ID in the token")
|
||||
}
|
||||
user, err := s.Store.GetUser(ctx, &store.FindUser{
|
||||
ID: &userID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get user")
|
||||
}
|
||||
if user == nil {
|
||||
return nil, errors.Errorf("user %q not exists", userID)
|
||||
}
|
||||
if user.RowStatus == store.Archived {
|
||||
return nil, errors.Errorf("user %q is archived", userID)
|
||||
}
|
||||
|
||||
// Validate that this access token exists in the user's access tokens
|
||||
accessTokens, err := s.Store.GetUserAccessTokens(ctx, user.ID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get user access tokens")
|
||||
}
|
||||
if !s.validateAccessToken(accessToken, accessTokens) {
|
||||
return nil, errors.New("invalid access token")
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// parseSessionCookieValue parses the session cookie value to extract userID and sessionID.
|
||||
func (*FileServerService) parseSessionCookieValue(cookieValue string) (int32, string, error) {
|
||||
parts := strings.SplitN(cookieValue, "-", 2)
|
||||
if len(parts) != 2 {
|
||||
return 0, "", errors.New("invalid session cookie format")
|
||||
}
|
||||
|
||||
userID, err := util.ConvertStringToInt32(parts[0])
|
||||
if err != nil {
|
||||
return 0, "", errors.Errorf("invalid user ID in session cookie: %v", err)
|
||||
}
|
||||
|
||||
return userID, parts[1], nil
|
||||
}
|
||||
|
||||
// validateUserSession checks if a session exists and is still valid using sliding expiration.
|
||||
func (*FileServerService) validateUserSession(sessionID string, userSessions []*storepb.SessionsUserSetting_Session) bool {
|
||||
for _, session := range userSessions {
|
||||
if sessionID == session.SessionId {
|
||||
// Use sliding expiration: check if last_accessed_time + 14 days > current_time
|
||||
if session.LastAccessedTime != nil {
|
||||
expirationTime := session.LastAccessedTime.AsTime().Add(apiv1.SessionSlidingDuration)
|
||||
if expirationTime.Before(time.Now()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// validateAccessToken checks if the provided JWT token exists in the user's access tokens list.
|
||||
func (*FileServerService) validateAccessToken(accessTokenString string, userAccessTokens []*storepb.AccessTokensUserSetting_AccessToken) bool {
|
||||
for _, userAccessToken := range userAccessTokens {
|
||||
if accessTokenString == userAccessToken.AccessToken {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// isImageType checks if the mime type is an image that supports thumbnails.
|
||||
func (*FileServerService) isImageType(mimeType string) bool {
|
||||
return mimeType == "image/png" || mimeType == "image/jpeg"
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
"format": "biome format --write src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@connectrpc/connect": "^2.1.1",
|
||||
"@connectrpc/connect-web": "^2.1.1",
|
||||
"@dnd-kit/core": "^6.3.1",
|
||||
"@dnd-kit/sortable": "^10.0.0",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
|
|
@ -84,7 +86,6 @@
|
|||
"@types/uuid": "^10.0.0",
|
||||
"@vitejs/plugin-react": "^4.7.0",
|
||||
"long": "^5.3.2",
|
||||
"nice-grpc-web": "^3.3.9",
|
||||
"terser": "^5.44.1",
|
||||
"tw-animate-css": "^1.4.0",
|
||||
"typescript": "^5.9.3",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,12 @@ importers:
|
|||
|
||||
.:
|
||||
dependencies:
|
||||
'@connectrpc/connect':
|
||||
specifier: ^2.1.1
|
||||
version: 2.1.1(@bufbuild/protobuf@2.10.1)
|
||||
'@connectrpc/connect-web':
|
||||
specifier: ^2.1.1
|
||||
version: 2.1.1(@bufbuild/protobuf@2.10.1)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.10.1))
|
||||
'@dnd-kit/core':
|
||||
specifier: ^6.3.1
|
||||
version: 6.3.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
|
|
@ -225,9 +231,6 @@ importers:
|
|||
long:
|
||||
specifier: ^5.3.2
|
||||
version: 5.3.2
|
||||
nice-grpc-web:
|
||||
specifier: ^3.3.9
|
||||
version: 3.3.9(ws@8.18.3)
|
||||
terser:
|
||||
specifier: ^5.44.1
|
||||
version: 5.44.1
|
||||
|
|
@ -410,6 +413,17 @@ packages:
|
|||
'@chevrotain/utils@11.0.3':
|
||||
resolution: {integrity: sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==}
|
||||
|
||||
'@connectrpc/connect-web@2.1.1':
|
||||
resolution: {integrity: sha512-J8317Q2MaFRCT1jzVR1o06bZhDIBmU0UAzWx6xOIXzOq8+k71/+k7MUF7AwcBUX+34WIvbm5syRgC5HXQA8fOg==}
|
||||
peerDependencies:
|
||||
'@bufbuild/protobuf': ^2.7.0
|
||||
'@connectrpc/connect': 2.1.1
|
||||
|
||||
'@connectrpc/connect@2.1.1':
|
||||
resolution: {integrity: sha512-JzhkaTvM73m2K1URT6tv53k2RwngSmCXLZJgK580qNQOXRzZRR/BCMfZw3h+90JpnG6XksP5bYT+cz0rpUzUWQ==}
|
||||
peerDependencies:
|
||||
'@bufbuild/protobuf': ^2.7.0
|
||||
|
||||
'@dnd-kit/accessibility@3.1.1':
|
||||
resolution: {integrity: sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==}
|
||||
peerDependencies:
|
||||
|
|
@ -1519,9 +1533,6 @@ packages:
|
|||
'@xobotyi/scrollbar-width@1.9.5':
|
||||
resolution: {integrity: sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==}
|
||||
|
||||
abort-controller-x@0.4.3:
|
||||
resolution: {integrity: sha512-VtUwTNU8fpMwvWGn4xE93ywbogTYsuT+AUxAXOeelbXuQVIwNmC5YLeho9sH4vZ4ITW8414TTAOG1nW6uIVHCA==}
|
||||
|
||||
accessor-fn@1.5.3:
|
||||
resolution: {integrity: sha512-rkAofCwe/FvYFUlMB0v0gWmhqtfAtV1IUkdPbfhTUyYniu5LrC0A0UJkTH0Jv3S8SvwkmfuAlY+mQIJATdocMA==}
|
||||
engines: {node: '>=12'}
|
||||
|
|
@ -2077,11 +2088,6 @@ packages:
|
|||
resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
isomorphic-ws@5.0.0:
|
||||
resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==}
|
||||
peerDependencies:
|
||||
ws: '*'
|
||||
|
||||
jerrypick@1.1.2:
|
||||
resolution: {integrity: sha512-YKnxXEekXKzhpf7CLYA0A+oDP8V0OhICNCr5lv96FvSsDEmrb0GKM776JgQvHTMjr7DTTPEVv/1Ciaw0uEWzBA==}
|
||||
engines: {node: '>=12'}
|
||||
|
|
@ -2090,9 +2096,6 @@ packages:
|
|||
resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
|
||||
hasBin: true
|
||||
|
||||
js-base64@3.7.8:
|
||||
resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==}
|
||||
|
||||
js-cookie@2.2.1:
|
||||
resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==}
|
||||
|
||||
|
|
@ -2430,12 +2433,6 @@ packages:
|
|||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||
hasBin: true
|
||||
|
||||
nice-grpc-common@2.0.2:
|
||||
resolution: {integrity: sha512-7RNWbls5kAL1QVUOXvBsv1uO0wPQK3lHv+cY1gwkTzirnG1Nop4cBJZubpgziNbaVc/bl9QJcyvsf/NQxa3rjQ==}
|
||||
|
||||
nice-grpc-web@3.3.9:
|
||||
resolution: {integrity: sha512-CiCQLdLTux9D4try8XlHW9tHIP/uLB+aciNKErDNLUM6kzhPFaVh8q+oTkoVGOjxOacEzlOwQRRjwQETAx5lVw==}
|
||||
|
||||
node-releases@2.0.27:
|
||||
resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==}
|
||||
|
||||
|
|
@ -2819,9 +2816,6 @@ packages:
|
|||
ts-easing@0.2.0:
|
||||
resolution: {integrity: sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==}
|
||||
|
||||
ts-error@1.0.6:
|
||||
resolution: {integrity: sha512-tLJxacIQUM82IR7JO1UUkKlYuUTmoY9HBJAmNWFzheSlDS5SPMcNIepejHJa4BpPQLAcbRhRf3GDJzyj6rbKvA==}
|
||||
|
||||
tslib@2.8.1:
|
||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||
|
||||
|
|
@ -2974,18 +2968,6 @@ packages:
|
|||
web-namespaces@2.0.1:
|
||||
resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
|
||||
|
||||
ws@8.18.3:
|
||||
resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: '>=5.0.2'
|
||||
peerDependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
|
||||
yallist@3.1.1:
|
||||
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
|
||||
|
||||
|
|
@ -3175,6 +3157,15 @@ snapshots:
|
|||
|
||||
'@chevrotain/utils@11.0.3': {}
|
||||
|
||||
'@connectrpc/connect-web@2.1.1(@bufbuild/protobuf@2.10.1)(@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.10.1))':
|
||||
dependencies:
|
||||
'@bufbuild/protobuf': 2.10.1
|
||||
'@connectrpc/connect': 2.1.1(@bufbuild/protobuf@2.10.1)
|
||||
|
||||
'@connectrpc/connect@2.1.1(@bufbuild/protobuf@2.10.1)':
|
||||
dependencies:
|
||||
'@bufbuild/protobuf': 2.10.1
|
||||
|
||||
'@dnd-kit/accessibility@3.1.1(react@18.3.1)':
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
|
|
@ -4221,8 +4212,6 @@ snapshots:
|
|||
|
||||
'@xobotyi/scrollbar-width@1.9.5': {}
|
||||
|
||||
abort-controller-x@0.4.3: {}
|
||||
|
||||
accessor-fn@1.5.3: {}
|
||||
|
||||
acorn@8.15.0: {}
|
||||
|
|
@ -4857,16 +4846,10 @@ snapshots:
|
|||
|
||||
is-plain-obj@4.1.0: {}
|
||||
|
||||
isomorphic-ws@5.0.0(ws@8.18.3):
|
||||
dependencies:
|
||||
ws: 8.18.3
|
||||
|
||||
jerrypick@1.1.2: {}
|
||||
|
||||
jiti@2.6.1: {}
|
||||
|
||||
js-base64@3.7.8: {}
|
||||
|
||||
js-cookie@2.2.1: {}
|
||||
|
||||
js-tokens@4.0.0: {}
|
||||
|
|
@ -5420,19 +5403,6 @@ snapshots:
|
|||
|
||||
nanoid@3.3.11: {}
|
||||
|
||||
nice-grpc-common@2.0.2:
|
||||
dependencies:
|
||||
ts-error: 1.0.6
|
||||
|
||||
nice-grpc-web@3.3.9(ws@8.18.3):
|
||||
dependencies:
|
||||
abort-controller-x: 0.4.3
|
||||
isomorphic-ws: 5.0.0(ws@8.18.3)
|
||||
js-base64: 3.7.8
|
||||
nice-grpc-common: 2.0.2
|
||||
transitivePeerDependencies:
|
||||
- ws
|
||||
|
||||
node-releases@2.0.27: {}
|
||||
|
||||
object-assign@4.1.1: {}
|
||||
|
|
@ -5877,8 +5847,6 @@ snapshots:
|
|||
|
||||
ts-easing@0.2.0: {}
|
||||
|
||||
ts-error@1.0.6: {}
|
||||
|
||||
tslib@2.8.1: {}
|
||||
|
||||
tw-animate-css@1.4.0: {}
|
||||
|
|
@ -6010,8 +5978,6 @@ snapshots:
|
|||
|
||||
web-namespaces@2.0.1: {}
|
||||
|
||||
ws@8.18.3: {}
|
||||
|
||||
yallist@3.1.1: {}
|
||||
|
||||
yaml@1.10.2: {}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import {
|
|||
} from "lucide-react";
|
||||
import React, { useState } from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Attachment } from "@/types/proto/api/v1/attachment_service";
|
||||
import { Attachment } from "@/types/proto/api/v1/attachment_service_pb";
|
||||
import { getAttachmentThumbnailUrl, getAttachmentType, getAttachmentUrl } from "@/utils/attachment";
|
||||
import SquareDiv from "./kit/SquareDiv";
|
||||
import PreviewImageDialog from "./PreviewImageDialog";
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "
|
|||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { userStore } from "@/store";
|
||||
import { User } from "@/types/proto/api/v1/user_service";
|
||||
import { User } from "@/types/proto/api/v1/user_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
|
||||
interface Props {
|
||||
|
|
@ -61,7 +61,7 @@ function ChangeMemberPasswordDialog({ open, onOpenChange, user, onSuccess }: Pro
|
|||
onOpenChange(false);
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
toast.error(error.details);
|
||||
toast.error(error.message);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { timestampFromDate } from "@bufbuild/protobuf/wkt";
|
||||
import React, { useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
|
@ -8,7 +9,7 @@ import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
|||
import { userServiceClient } from "@/grpcweb";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import useLoading from "@/hooks/useLoading";
|
||||
import { UserAccessToken } from "@/types/proto/api/v1/user_service";
|
||||
import { UserAccessToken } from "@/types/proto/api/v1/user_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
|
||||
interface Props {
|
||||
|
|
@ -77,7 +78,7 @@ function CreateAccessTokenDialog({ open, onOpenChange, onSuccess }: Props) {
|
|||
parent: currentUser.name,
|
||||
accessToken: {
|
||||
description: state.description,
|
||||
expiresAt: state.expiration ? new Date(Date.now() + state.expiration * 1000) : undefined,
|
||||
expiresAt: state.expiration ? timestampFromDate(new Date(Date.now() + state.expiration * 1000)) : undefined,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -85,7 +86,7 @@ function CreateAccessTokenDialog({ open, onOpenChange, onSuccess }: Props) {
|
|||
onSuccess(created);
|
||||
onOpenChange(false);
|
||||
} catch (error: any) {
|
||||
toast.error(error.details);
|
||||
toast.error(error.message);
|
||||
console.error(error);
|
||||
requestState.setError();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { create } from "@bufbuild/protobuf";
|
||||
import { FieldMaskSchema } from "@bufbuild/protobuf/wkt";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
|
@ -7,94 +9,115 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@
|
|||
import { Separator } from "@/components/ui/separator";
|
||||
import { identityProviderServiceClient } from "@/grpcweb";
|
||||
import { absolutifyLink } from "@/helpers/utils";
|
||||
import { FieldMapping, IdentityProvider, IdentityProvider_Type, OAuth2Config } from "@/types/proto/api/v1/idp_service";
|
||||
import {
|
||||
FieldMapping,
|
||||
FieldMappingSchema,
|
||||
IdentityProvider,
|
||||
IdentityProvider_Type,
|
||||
IdentityProviderConfigSchema,
|
||||
IdentityProviderSchema,
|
||||
OAuth2Config,
|
||||
OAuth2ConfigSchema,
|
||||
} from "@/types/proto/api/v1/idp_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
|
||||
const templateList: IdentityProvider[] = [
|
||||
{
|
||||
create(IdentityProviderSchema, {
|
||||
name: "",
|
||||
title: "GitHub",
|
||||
type: IdentityProvider_Type.OAUTH2,
|
||||
identifierFilter: "",
|
||||
config: {
|
||||
oauth2Config: {
|
||||
clientId: "",
|
||||
clientSecret: "",
|
||||
authUrl: "https://github.com/login/oauth/authorize",
|
||||
tokenUrl: "https://github.com/login/oauth/access_token",
|
||||
userInfoUrl: "https://api.github.com/user",
|
||||
scopes: ["read:user"],
|
||||
fieldMapping: FieldMapping.fromPartial({
|
||||
identifier: "login",
|
||||
displayName: "name",
|
||||
email: "email",
|
||||
config: create(IdentityProviderConfigSchema, {
|
||||
config: {
|
||||
case: "oauth2Config",
|
||||
value: create(OAuth2ConfigSchema, {
|
||||
clientId: "",
|
||||
clientSecret: "",
|
||||
authUrl: "https://github.com/login/oauth/authorize",
|
||||
tokenUrl: "https://github.com/login/oauth/access_token",
|
||||
userInfoUrl: "https://api.github.com/user",
|
||||
scopes: ["read:user"],
|
||||
fieldMapping: create(FieldMappingSchema, {
|
||||
identifier: "login",
|
||||
displayName: "name",
|
||||
email: "email",
|
||||
}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
}),
|
||||
}),
|
||||
create(IdentityProviderSchema, {
|
||||
name: "",
|
||||
title: "GitLab",
|
||||
type: IdentityProvider_Type.OAUTH2,
|
||||
identifierFilter: "",
|
||||
config: {
|
||||
oauth2Config: {
|
||||
clientId: "",
|
||||
clientSecret: "",
|
||||
authUrl: "https://gitlab.com/oauth/authorize",
|
||||
tokenUrl: "https://gitlab.com/oauth/token",
|
||||
userInfoUrl: "https://gitlab.com/oauth/userinfo",
|
||||
scopes: ["openid"],
|
||||
fieldMapping: FieldMapping.fromPartial({
|
||||
identifier: "name",
|
||||
displayName: "name",
|
||||
email: "email",
|
||||
config: create(IdentityProviderConfigSchema, {
|
||||
config: {
|
||||
case: "oauth2Config",
|
||||
value: create(OAuth2ConfigSchema, {
|
||||
clientId: "",
|
||||
clientSecret: "",
|
||||
authUrl: "https://gitlab.com/oauth/authorize",
|
||||
tokenUrl: "https://gitlab.com/oauth/token",
|
||||
userInfoUrl: "https://gitlab.com/oauth/userinfo",
|
||||
scopes: ["openid"],
|
||||
fieldMapping: create(FieldMappingSchema, {
|
||||
identifier: "name",
|
||||
displayName: "name",
|
||||
email: "email",
|
||||
}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
}),
|
||||
}),
|
||||
create(IdentityProviderSchema, {
|
||||
name: "",
|
||||
title: "Google",
|
||||
type: IdentityProvider_Type.OAUTH2,
|
||||
identifierFilter: "",
|
||||
config: {
|
||||
oauth2Config: {
|
||||
clientId: "",
|
||||
clientSecret: "",
|
||||
authUrl: "https://accounts.google.com/o/oauth2/v2/auth",
|
||||
tokenUrl: "https://oauth2.googleapis.com/token",
|
||||
userInfoUrl: "https://www.googleapis.com/oauth2/v2/userinfo",
|
||||
scopes: ["https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"],
|
||||
fieldMapping: FieldMapping.fromPartial({
|
||||
identifier: "email",
|
||||
displayName: "name",
|
||||
email: "email",
|
||||
config: create(IdentityProviderConfigSchema, {
|
||||
config: {
|
||||
case: "oauth2Config",
|
||||
value: create(OAuth2ConfigSchema, {
|
||||
clientId: "",
|
||||
clientSecret: "",
|
||||
authUrl: "https://accounts.google.com/o/oauth2/v2/auth",
|
||||
tokenUrl: "https://oauth2.googleapis.com/token",
|
||||
userInfoUrl: "https://www.googleapis.com/oauth2/v2/userinfo",
|
||||
scopes: ["https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"],
|
||||
fieldMapping: create(FieldMappingSchema, {
|
||||
identifier: "email",
|
||||
displayName: "name",
|
||||
email: "email",
|
||||
}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
}),
|
||||
}),
|
||||
create(IdentityProviderSchema, {
|
||||
name: "",
|
||||
title: "Custom",
|
||||
type: IdentityProvider_Type.OAUTH2,
|
||||
identifierFilter: "",
|
||||
config: {
|
||||
oauth2Config: {
|
||||
clientId: "",
|
||||
clientSecret: "",
|
||||
authUrl: "",
|
||||
tokenUrl: "",
|
||||
userInfoUrl: "",
|
||||
scopes: [],
|
||||
fieldMapping: FieldMapping.fromPartial({
|
||||
identifier: "",
|
||||
displayName: "",
|
||||
email: "",
|
||||
config: create(IdentityProviderConfigSchema, {
|
||||
config: {
|
||||
case: "oauth2Config",
|
||||
value: create(OAuth2ConfigSchema, {
|
||||
clientId: "",
|
||||
clientSecret: "",
|
||||
authUrl: "",
|
||||
tokenUrl: "",
|
||||
userInfoUrl: "",
|
||||
scopes: [],
|
||||
fieldMapping: create(FieldMappingSchema, {
|
||||
identifier: "",
|
||||
displayName: "",
|
||||
email: "",
|
||||
}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}),
|
||||
];
|
||||
|
||||
interface Props {
|
||||
|
|
@ -112,19 +135,21 @@ function CreateIdentityProviderDialog({ open, onOpenChange, identityProvider, on
|
|||
identifierFilter: "",
|
||||
});
|
||||
const [type, setType] = useState<IdentityProvider_Type>(IdentityProvider_Type.OAUTH2);
|
||||
const [oauth2Config, setOAuth2Config] = useState<OAuth2Config>({
|
||||
clientId: "",
|
||||
clientSecret: "",
|
||||
authUrl: "",
|
||||
tokenUrl: "",
|
||||
userInfoUrl: "",
|
||||
scopes: [],
|
||||
fieldMapping: FieldMapping.fromPartial({
|
||||
identifier: "",
|
||||
displayName: "",
|
||||
email: "",
|
||||
const [oauth2Config, setOAuth2Config] = useState<OAuth2Config>(
|
||||
create(OAuth2ConfigSchema, {
|
||||
clientId: "",
|
||||
clientSecret: "",
|
||||
authUrl: "",
|
||||
tokenUrl: "",
|
||||
userInfoUrl: "",
|
||||
scopes: [],
|
||||
fieldMapping: create(FieldMappingSchema, {
|
||||
identifier: "",
|
||||
displayName: "",
|
||||
email: "",
|
||||
}),
|
||||
}),
|
||||
});
|
||||
);
|
||||
const [oauth2Scopes, setOAuth2Scopes] = useState<string>("");
|
||||
const [selectedTemplate, setSelectedTemplate] = useState<string>("GitHub");
|
||||
const isCreating = identityProvider === undefined;
|
||||
|
|
@ -138,19 +163,21 @@ function CreateIdentityProviderDialog({ open, onOpenChange, identityProvider, on
|
|||
identifierFilter: "",
|
||||
});
|
||||
setType(IdentityProvider_Type.OAUTH2);
|
||||
setOAuth2Config({
|
||||
clientId: "",
|
||||
clientSecret: "",
|
||||
authUrl: "",
|
||||
tokenUrl: "",
|
||||
userInfoUrl: "",
|
||||
scopes: [],
|
||||
fieldMapping: FieldMapping.fromPartial({
|
||||
identifier: "",
|
||||
displayName: "",
|
||||
email: "",
|
||||
setOAuth2Config(
|
||||
create(OAuth2ConfigSchema, {
|
||||
clientId: "",
|
||||
clientSecret: "",
|
||||
authUrl: "",
|
||||
tokenUrl: "",
|
||||
userInfoUrl: "",
|
||||
scopes: [],
|
||||
fieldMapping: create(FieldMappingSchema, {
|
||||
identifier: "",
|
||||
displayName: "",
|
||||
email: "",
|
||||
}),
|
||||
}),
|
||||
});
|
||||
);
|
||||
setOAuth2Scopes("");
|
||||
setSelectedTemplate("GitHub");
|
||||
}
|
||||
|
|
@ -164,8 +191,8 @@ function CreateIdentityProviderDialog({ open, onOpenChange, identityProvider, on
|
|||
identifierFilter: identityProvider.identifierFilter,
|
||||
});
|
||||
setType(identityProvider.type);
|
||||
if (identityProvider.type === IdentityProvider_Type.OAUTH2) {
|
||||
const oauth2Config = OAuth2Config.fromPartial(identityProvider.config?.oauth2Config || {});
|
||||
if (identityProvider.type === IdentityProvider_Type.OAUTH2 && identityProvider.config?.config?.case === "oauth2Config") {
|
||||
const oauth2Config = create(OAuth2ConfigSchema, identityProvider.config.config.value || {});
|
||||
setOAuth2Config(oauth2Config);
|
||||
setOAuth2Scopes(oauth2Config.scopes.join(" "));
|
||||
}
|
||||
|
|
@ -185,8 +212,8 @@ function CreateIdentityProviderDialog({ open, onOpenChange, identityProvider, on
|
|||
identifierFilter: template.identifierFilter,
|
||||
});
|
||||
setType(template.type);
|
||||
if (template.type === IdentityProvider_Type.OAUTH2) {
|
||||
const oauth2Config = OAuth2Config.fromPartial(template.config?.oauth2Config || {});
|
||||
if (template.type === IdentityProvider_Type.OAUTH2 && template.config?.config?.case === "oauth2Config") {
|
||||
const oauth2Config = create(OAuth2ConfigSchema, template.config.config.value || {});
|
||||
setOAuth2Config(oauth2Config);
|
||||
setOAuth2Scopes(oauth2Config.scopes.join(" "));
|
||||
}
|
||||
|
|
@ -201,7 +228,7 @@ function CreateIdentityProviderDialog({ open, onOpenChange, identityProvider, on
|
|||
if (basicInfo.title === "") {
|
||||
return false;
|
||||
}
|
||||
if (type === "OAUTH2") {
|
||||
if (type === IdentityProvider_Type.OAUTH2) {
|
||||
if (
|
||||
oauth2Config.clientId === "" ||
|
||||
oauth2Config.authUrl === "" ||
|
||||
|
|
@ -226,37 +253,43 @@ function CreateIdentityProviderDialog({ open, onOpenChange, identityProvider, on
|
|||
try {
|
||||
if (isCreating) {
|
||||
await identityProviderServiceClient.createIdentityProvider({
|
||||
identityProvider: {
|
||||
identityProvider: create(IdentityProviderSchema, {
|
||||
...basicInfo,
|
||||
type: type,
|
||||
config: {
|
||||
oauth2Config: {
|
||||
...oauth2Config,
|
||||
scopes: oauth2Scopes.split(" "),
|
||||
config: create(IdentityProviderConfigSchema, {
|
||||
config: {
|
||||
case: "oauth2Config",
|
||||
value: {
|
||||
...oauth2Config,
|
||||
scopes: oauth2Scopes.split(" "),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
}),
|
||||
});
|
||||
toast.success(t("setting.sso-section.sso-created", { name: basicInfo.title }));
|
||||
} else {
|
||||
await identityProviderServiceClient.updateIdentityProvider({
|
||||
identityProvider: {
|
||||
identityProvider: create(IdentityProviderSchema, {
|
||||
...basicInfo,
|
||||
name: identityProvider!.name,
|
||||
type: type,
|
||||
config: {
|
||||
oauth2Config: {
|
||||
...oauth2Config,
|
||||
scopes: oauth2Scopes.split(" "),
|
||||
config: create(IdentityProviderConfigSchema, {
|
||||
config: {
|
||||
case: "oauth2Config",
|
||||
value: {
|
||||
...oauth2Config,
|
||||
scopes: oauth2Scopes.split(" "),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
updateMask: ["title", "identifier_filter", "config"],
|
||||
}),
|
||||
}),
|
||||
updateMask: create(FieldMaskSchema, { paths: ["title", "identifier_filter", "config"] }),
|
||||
});
|
||||
toast.success(t("setting.sso-section.sso-updated", { name: basicInfo.title }));
|
||||
}
|
||||
} catch (error: any) {
|
||||
toast.error(error.details);
|
||||
toast.error(error.message);
|
||||
console.error(error);
|
||||
}
|
||||
onSuccess?.();
|
||||
|
|
@ -336,7 +369,7 @@ function CreateIdentityProviderDialog({ open, onOpenChange, identityProvider, on
|
|||
}
|
||||
/>
|
||||
<Separator className="my-2" />
|
||||
{type === "OAUTH2" && (
|
||||
{type === IdentityProvider_Type.OAUTH2 && (
|
||||
<>
|
||||
{isCreating && (
|
||||
<p className="border border-border rounded-md p-2 text-sm w-full mb-2 break-all">
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { create } from "@bufbuild/protobuf";
|
||||
import { FieldMaskSchema } from "@bufbuild/protobuf/wkt";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
|
@ -9,7 +11,7 @@ import { shortcutServiceClient } from "@/grpcweb";
|
|||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import useLoading from "@/hooks/useLoading";
|
||||
import { userStore } from "@/store";
|
||||
import { Shortcut } from "@/types/proto/api/v1/shortcut_service";
|
||||
import { Shortcut, ShortcutSchema } from "@/types/proto/api/v1/shortcut_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
|
||||
interface Props {
|
||||
|
|
@ -22,23 +24,27 @@ interface Props {
|
|||
function CreateShortcutDialog({ open, onOpenChange, shortcut: initialShortcut, onSuccess }: Props) {
|
||||
const t = useTranslate();
|
||||
const user = useCurrentUser();
|
||||
const [shortcut, setShortcut] = useState<Shortcut>({
|
||||
name: initialShortcut?.name || "",
|
||||
title: initialShortcut?.title || "",
|
||||
filter: initialShortcut?.filter || "",
|
||||
});
|
||||
const [shortcut, setShortcut] = useState<Shortcut>(
|
||||
create(ShortcutSchema, {
|
||||
name: initialShortcut?.name || "",
|
||||
title: initialShortcut?.title || "",
|
||||
filter: initialShortcut?.filter || "",
|
||||
}),
|
||||
);
|
||||
const requestState = useLoading(false);
|
||||
const isCreating = !initialShortcut;
|
||||
|
||||
useEffect(() => {
|
||||
if (initialShortcut) {
|
||||
setShortcut({
|
||||
name: initialShortcut.name,
|
||||
title: initialShortcut.title,
|
||||
filter: initialShortcut.filter,
|
||||
});
|
||||
setShortcut(
|
||||
create(ShortcutSchema, {
|
||||
name: initialShortcut.name,
|
||||
title: initialShortcut.title,
|
||||
filter: initialShortcut.filter,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
setShortcut({ name: "", title: "", filter: "" });
|
||||
setShortcut(create(ShortcutSchema, { name: "", title: "", filter: "" }));
|
||||
}
|
||||
}, [initialShortcut]);
|
||||
|
||||
|
|
@ -74,7 +80,7 @@ function CreateShortcutDialog({ open, onOpenChange, shortcut: initialShortcut, o
|
|||
...shortcut,
|
||||
name: initialShortcut!.name, // Keep the original resource name
|
||||
},
|
||||
updateMask: ["title", "filter"],
|
||||
updateMask: create(FieldMaskSchema, { paths: ["title", "filter"] }),
|
||||
});
|
||||
toast.success("Update shortcut successfully");
|
||||
}
|
||||
|
|
@ -85,7 +91,7 @@ function CreateShortcutDialog({ open, onOpenChange, shortcut: initialShortcut, o
|
|||
onOpenChange(false);
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
toast.error(error.details);
|
||||
toast.error(error.message);
|
||||
requestState.setError();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { create } from "@bufbuild/protobuf";
|
||||
import { FieldMaskSchema } from "@bufbuild/protobuf/wkt";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
|
@ -7,7 +9,7 @@ import { Label } from "@/components/ui/label";
|
|||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
|
||||
import { userServiceClient } from "@/grpcweb";
|
||||
import useLoading from "@/hooks/useLoading";
|
||||
import { User, User_Role } from "@/types/proto/api/v1/user_service";
|
||||
import { User, User_Role, UserSchema } from "@/types/proto/api/v1/user_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
|
||||
interface Props {
|
||||
|
|
@ -19,15 +21,15 @@ interface Props {
|
|||
|
||||
function CreateUserDialog({ open, onOpenChange, user: initialUser, onSuccess }: Props) {
|
||||
const t = useTranslate();
|
||||
const [user, setUser] = useState(User.fromPartial({ ...initialUser }));
|
||||
const [user, setUser] = useState(create(UserSchema, initialUser ? { username: initialUser.username, role: initialUser.role } : {}));
|
||||
const requestState = useLoading(false);
|
||||
const isCreating = !initialUser;
|
||||
|
||||
useEffect(() => {
|
||||
if (initialUser) {
|
||||
setUser(User.fromPartial(initialUser));
|
||||
setUser(create(UserSchema, { username: initialUser.username, role: initialUser.role }));
|
||||
} else {
|
||||
setUser(User.fromPartial({}));
|
||||
setUser(create(UserSchema, {}));
|
||||
}
|
||||
}, [initialUser]);
|
||||
|
||||
|
|
@ -60,7 +62,7 @@ function CreateUserDialog({ open, onOpenChange, user: initialUser, onSuccess }:
|
|||
if (user.role !== initialUser?.role) {
|
||||
updateMask.push("role");
|
||||
}
|
||||
await userServiceClient.updateUser({ user, updateMask });
|
||||
await userServiceClient.updateUser({ user, updateMask: create(FieldMaskSchema, { paths: updateMask }) });
|
||||
toast.success("Update user successfully");
|
||||
}
|
||||
requestState.setFinish();
|
||||
|
|
@ -68,7 +70,7 @@ function CreateUserDialog({ open, onOpenChange, user: initialUser, onSuccess }:
|
|||
onOpenChange(false);
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
toast.error(error.details);
|
||||
toast.error(error.message);
|
||||
requestState.setError();
|
||||
}
|
||||
};
|
||||
|
|
@ -112,16 +114,16 @@ function CreateUserDialog({ open, onOpenChange, user: initialUser, onSuccess }:
|
|||
<div className="grid gap-2">
|
||||
<Label>{t("common.role")}</Label>
|
||||
<RadioGroup
|
||||
value={user.role}
|
||||
onValueChange={(value) => setPartialUser({ role: value as User_Role })}
|
||||
value={String(user.role)}
|
||||
onValueChange={(value) => setPartialUser({ role: Number(value) as User_Role })}
|
||||
className="flex flex-row gap-4"
|
||||
>
|
||||
<div className="flex items-center space-x-2">
|
||||
<RadioGroupItem value={User_Role.USER} id="user" />
|
||||
<RadioGroupItem value={String(User_Role.USER)} id="user" />
|
||||
<Label htmlFor="user">{t("setting.member-section.user")}</Label>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<RadioGroupItem value={User_Role.ADMIN} id="admin" />
|
||||
<RadioGroupItem value={String(User_Role.ADMIN)} id="admin" />
|
||||
<Label htmlFor="admin">{t("setting.member-section.admin")}</Label>
|
||||
</div>
|
||||
</RadioGroup>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { create } from "@bufbuild/protobuf";
|
||||
import { FieldMaskSchema } from "@bufbuild/protobuf/wkt";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
|
@ -98,7 +100,7 @@ function CreateWebhookDialog({ open, onOpenChange, webhookName, onSuccess }: Pro
|
|||
displayName: state.displayName,
|
||||
url: state.url,
|
||||
},
|
||||
updateMask: ["display_name", "url"],
|
||||
updateMask: create(FieldMaskSchema, { paths: ["display_name", "url"] }),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -107,7 +109,7 @@ function CreateWebhookDialog({ open, onOpenChange, webhookName, onSuccess }: Pro
|
|||
requestState.setFinish();
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
toast.error(error.details);
|
||||
toast.error(error.message);
|
||||
requestState.setError();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { timestampDate } from "@bufbuild/protobuf/wkt";
|
||||
import { CheckIcon, MessageCircleIcon, TrashIcon, XIcon } from "lucide-react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { useState } from "react";
|
||||
|
|
@ -9,8 +10,8 @@ import useNavigateTo from "@/hooks/useNavigateTo";
|
|||
import { cn } from "@/lib/utils";
|
||||
import { memoStore, userStore } from "@/store";
|
||||
import { activityNamePrefix } from "@/store/common";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { User, UserNotification, UserNotification_Status } from "@/types/proto/api/v1/user_service";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { User, UserNotification, UserNotification_Status } from "@/types/proto/api/v1/user_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
|
||||
interface Props {
|
||||
|
|
@ -36,8 +37,8 @@ const MemoCommentMessage = observer(({ notification }: Props) => {
|
|||
name: `${activityNamePrefix}${notification.activityId}`,
|
||||
});
|
||||
|
||||
if (activity.payload?.memoComment) {
|
||||
const memoCommentPayload = activity.payload.memoComment;
|
||||
if (activity.payload?.payload?.case === "memoComment") {
|
||||
const memoCommentPayload = activity.payload.payload.value;
|
||||
const memo = await memoStore.getOrFetchMemoByName(memoCommentPayload.relatedMemo, {
|
||||
skipStore: true,
|
||||
});
|
||||
|
|
@ -160,8 +161,11 @@ const MemoCommentMessage = observer(({ notification }: Props) => {
|
|||
<span className="font-semibold text-sm text-foreground/95">{sender?.displayName || sender?.username}</span>
|
||||
<span className="text-sm text-muted-foreground/80">commented on your memo</span>
|
||||
<span className="text-xs text-muted-foreground/60">
|
||||
{notification.createTime?.toLocaleDateString([], { month: "short", day: "numeric" })} at{" "}
|
||||
{notification.createTime?.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}
|
||||
{notification.createTime &&
|
||||
timestampDate(notification.createTime)?.toLocaleDateString([], { month: "short", day: "numeric" })}{" "}
|
||||
at{" "}
|
||||
{notification.createTime &&
|
||||
timestampDate(notification.createTime)?.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-1 shrink-0">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { DistributionResult } from "./types";
|
||||
|
||||
export function distributeItemsToColumns(
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
|
||||
export interface MemoRenderContext {
|
||||
compact: boolean;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { MINIMUM_MEMO_VIEWPORT_WIDTH, REDISTRIBUTION_DEBOUNCE_MS } from "./constants";
|
||||
import { distributeItemsToColumns } from "./distributeItems";
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import {
|
|||
DropdownMenuSubTrigger,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { State } from "@/types/proto/api/v1/common";
|
||||
import { State } from "@/types/proto/api/v1/common_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { hasCompletedTasks } from "@/utils/markdown-manipulation";
|
||||
import { useMemoActionHandlers } from "./hooks";
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ import toast from "react-hot-toast";
|
|||
import { useLocation } from "react-router-dom";
|
||||
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||
import { instanceStore, memoStore, userStore } from "@/store";
|
||||
import { State } from "@/types/proto/api/v1/common";
|
||||
import type { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { State } from "@/types/proto/api/v1/common_pb";
|
||||
import type { Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { removeCompletedTasks } from "@/utils/markdown-manipulation";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import type { Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
|
||||
export interface MemoActionMenuProps {
|
||||
memo: Memo;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Attachment } from "@/types/proto/api/v1/attachment_service";
|
||||
import { Attachment } from "@/types/proto/api/v1/attachment_service_pb";
|
||||
import { getAttachmentUrl, isMidiFile } from "@/utils/attachment";
|
||||
import AttachmentIcon from "./AttachmentIcon";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import { create } from "@bufbuild/protobuf";
|
||||
import { isEqual } from "lodash-es";
|
||||
import { CheckCircleIcon, Code2Icon, HashIcon, LinkIcon } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Memo, Memo_Property, MemoRelation_Type } from "@/types/proto/api/v1/memo_service";
|
||||
import { Memo, Memo_Property, Memo_PropertySchema, MemoRelation_Type } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import MemoRelationForceGraph from "../MemoRelationForceGraph";
|
||||
|
||||
|
|
@ -13,7 +14,7 @@ interface Props {
|
|||
|
||||
const MemoDetailSidebar = ({ memo, className, parentPage }: Props) => {
|
||||
const t = useTranslate();
|
||||
const property = Memo_Property.fromPartial(memo.property || {});
|
||||
const property = create(Memo_PropertySchema, memo.property || {});
|
||||
const hasSpecialProperty = property.hasLink || property.hasTaskList || property.hasCode || property.hasIncompleteTasks;
|
||||
const shouldShowRelationGraph = memo.relations.filter((r) => r.type === MemoRelation_Type.REFERENCE).length > 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { useEffect, useState } from "react";
|
|||
import { useLocation } from "react-router-dom";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import MemoDetailSidebar from "./MemoDetailSidebar";
|
||||
|
||||
interface Props {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import {
|
|||
DropdownMenuSubTrigger,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import type { Location, MemoRelation } from "@/types/proto/api/v1/memo_service";
|
||||
import type { Location, MemoRelation } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { LinkMemoDialog, LocationDialog } from "../components";
|
||||
import { GEOCODING } from "../constants";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { CheckIcon, ChevronDownIcon } from "lucide-react";
|
||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
||||
import VisibilityIcon from "@/components/VisibilityIcon";
|
||||
import { Visibility } from "@/types/proto/api/v1/memo_service";
|
||||
import { Visibility } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
|
||||
interface Props {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
|
||||
function highlightSearchText(content: string, searchText: string): React.ReactNode {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,18 @@
|
|||
import { create } from "@bufbuild/protobuf";
|
||||
import { useState } from "react";
|
||||
import useDebounce from "react-use/lib/useDebounce";
|
||||
import { memoServiceClient } from "@/grpcweb";
|
||||
import { DEFAULT_LIST_MEMOS_PAGE_SIZE } from "@/helpers/consts";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { extractUserIdFromName } from "@/store/common";
|
||||
import { Memo, MemoRelation, MemoRelation_Memo, MemoRelation_Type } from "@/types/proto/api/v1/memo_service";
|
||||
import {
|
||||
Memo,
|
||||
MemoRelation,
|
||||
MemoRelation_Memo,
|
||||
MemoRelation_MemoSchema,
|
||||
MemoRelation_Type,
|
||||
MemoRelationSchema,
|
||||
} from "@/types/proto/api/v1/memo_service_pb";
|
||||
|
||||
interface UseLinkMemoParams {
|
||||
isOpen: boolean;
|
||||
|
|
@ -49,9 +57,9 @@ export const useLinkMemo = ({ isOpen, currentMemoName, existingRelations, onAddR
|
|||
);
|
||||
|
||||
const addMemoRelation = (memo: Memo) => {
|
||||
const relation = MemoRelation.fromPartial({
|
||||
const relation = create(MemoRelationSchema, {
|
||||
type: MemoRelation_Type.REFERENCE,
|
||||
relatedMemo: MemoRelation_Memo.fromPartial({
|
||||
relatedMemo: create(MemoRelation_MemoSchema, {
|
||||
name: memo.name,
|
||||
snippet: memo.snippet,
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { create } from "@bufbuild/protobuf";
|
||||
import { LatLng } from "leaflet";
|
||||
import { useState } from "react";
|
||||
import { Location } from "@/types/proto/api/v1/memo_service";
|
||||
import { Location, LocationSchema } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { LocationState } from "../types/insert-menu";
|
||||
|
||||
export const useLocation = (initialLocation?: Location) => {
|
||||
|
|
@ -62,7 +63,7 @@ export const useLocation = (initialLocation?: Location) => {
|
|||
if (!state.position || !state.placeholder.trim()) {
|
||||
return undefined;
|
||||
}
|
||||
return Location.fromPartial({
|
||||
return create(LocationSchema, {
|
||||
latitude: state.position.lat,
|
||||
longitude: state.position.lng,
|
||||
placeholder: state.placeholder,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import { timestampDate } from "@bufbuild/protobuf/wkt";
|
||||
import { useEffect, useState } from "react";
|
||||
import useAsyncEffect from "@/hooks/useAsyncEffect";
|
||||
import { instanceStore, memoStore, userStore } from "@/store";
|
||||
import type { Attachment } from "@/types/proto/api/v1/attachment_service";
|
||||
import type { Location, MemoRelation } from "@/types/proto/api/v1/memo_service";
|
||||
import { Visibility } from "@/types/proto/api/v1/memo_service";
|
||||
import type { Attachment } from "@/types/proto/api/v1/attachment_service_pb";
|
||||
import type { Location, MemoRelation } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { Visibility } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { convertVisibilityFromString } from "@/utils/memo";
|
||||
import type { EditorRefActions } from "../Editor";
|
||||
|
||||
|
|
@ -68,7 +69,7 @@ export const useMemoEditorInit = (options: UseMemoEditorInitOptions): UseMemoEdi
|
|||
const parentMemo = await memoStore.getOrFetchMemoByName(parentMemoName);
|
||||
visibility = parentMemo.visibility;
|
||||
}
|
||||
onVisibilityChange(convertVisibilityFromString(visibility));
|
||||
onVisibilityChange(visibility);
|
||||
}, [parentMemoName, userGeneralSetting?.memoVisibility, instanceMemoRelatedSetting.disallowPublicVisibility]);
|
||||
|
||||
// Load existing memo if editing
|
||||
|
|
@ -80,8 +81,8 @@ export const useMemoEditorInit = (options: UseMemoEditorInitOptions): UseMemoEdi
|
|||
const memo = await memoStore.getOrFetchMemoByName(memoName);
|
||||
if (memo) {
|
||||
onEditorFocus();
|
||||
setCreateTime(memo.createTime);
|
||||
setUpdateTime(memo.updateTime);
|
||||
setCreateTime(memo.createTime ? timestampDate(memo.createTime) : undefined);
|
||||
setUpdateTime(memo.updateTime ? timestampDate(memo.updateTime) : undefined);
|
||||
onVisibilityChange(memo.visibility);
|
||||
onAttachmentsChange(memo.attachments);
|
||||
onRelationsChange(memo.relations);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { useCallback, useState } from "react";
|
||||
import type { Attachment } from "@/types/proto/api/v1/attachment_service";
|
||||
import type { Location, MemoRelation } from "@/types/proto/api/v1/memo_service";
|
||||
import { Visibility } from "@/types/proto/api/v1/memo_service";
|
||||
import type { Attachment } from "@/types/proto/api/v1/attachment_service_pb";
|
||||
import type { Location, MemoRelation } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { Visibility } from "@/types/proto/api/v1/memo_service_pb";
|
||||
|
||||
interface MemoEditorState {
|
||||
memoVisibility: Visibility;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
import { create } from "@bufbuild/protobuf";
|
||||
import { timestampDate, timestampFromDate } from "@bufbuild/protobuf/wkt";
|
||||
import { isEqual } from "lodash-es";
|
||||
import { useCallback } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import type { LocalFile } from "@/components/memo-metadata";
|
||||
import { memoServiceClient } from "@/grpcweb";
|
||||
import { attachmentStore, memoStore } from "@/store";
|
||||
import { Attachment } from "@/types/proto/api/v1/attachment_service";
|
||||
import type { Location, Memo, MemoRelation, Visibility } from "@/types/proto/api/v1/memo_service";
|
||||
import { Attachment, AttachmentSchema } from "@/types/proto/api/v1/attachment_service_pb";
|
||||
import type { Location, Memo, MemoRelation, Visibility } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { MemoSchema } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import type { Translations } from "@/utils/i18n";
|
||||
|
||||
interface MemoSaveContext {
|
||||
|
|
@ -37,15 +40,14 @@ async function uploadLocalFiles(localFiles: LocalFile[], onUploadingChange: (upl
|
|||
const attachments: Attachment[] = [];
|
||||
for (const { file } of localFiles) {
|
||||
const buffer = new Uint8Array(await file.arrayBuffer());
|
||||
const attachment = await attachmentStore.createAttachment({
|
||||
attachment: Attachment.fromPartial({
|
||||
const attachment = await attachmentStore.createAttachment(
|
||||
create(AttachmentSchema, {
|
||||
filename: file.name,
|
||||
size: file.size,
|
||||
size: BigInt(file.size),
|
||||
type: file.type,
|
||||
content: buffer,
|
||||
}),
|
||||
attachmentId: "",
|
||||
});
|
||||
);
|
||||
attachments.push(attachment);
|
||||
}
|
||||
return attachments;
|
||||
|
|
@ -93,13 +95,13 @@ function buildUpdateMask(
|
|||
}
|
||||
|
||||
// Handle custom timestamps
|
||||
if (context.createTime && !isEqual(context.createTime, prevMemo.createTime)) {
|
||||
if (context.createTime && !isEqual(context.createTime, prevMemo.createTime ? timestampDate(prevMemo.createTime) : undefined)) {
|
||||
mask.add("create_time");
|
||||
patch.createTime = context.createTime;
|
||||
patch.createTime = timestampFromDate(context.createTime);
|
||||
}
|
||||
if (context.updateTime && !isEqual(context.updateTime, prevMemo.updateTime)) {
|
||||
if (context.updateTime && !isEqual(context.updateTime, prevMemo.updateTime ? timestampDate(prevMemo.updateTime) : undefined)) {
|
||||
mask.add("update_time");
|
||||
patch.updateTime = context.updateTime;
|
||||
patch.updateTime = timestampFromDate(context.updateTime);
|
||||
}
|
||||
|
||||
return { mask, patch };
|
||||
|
|
@ -137,24 +139,23 @@ export function useMemoSave(callbacks: MemoSaveCallbacks) {
|
|||
const memo = context.parentMemoName
|
||||
? await memoServiceClient.createMemoComment({
|
||||
name: context.parentMemoName,
|
||||
comment: {
|
||||
comment: create(MemoSchema, {
|
||||
content,
|
||||
visibility: context.visibility,
|
||||
attachments: context.attachmentList,
|
||||
relations: context.relationList,
|
||||
location: context.location,
|
||||
},
|
||||
}),
|
||||
})
|
||||
: await memoStore.createMemo({
|
||||
memo: {
|
||||
: await memoStore.createMemo(
|
||||
create(MemoSchema, {
|
||||
content,
|
||||
visibility: context.visibility,
|
||||
attachments: allAttachments,
|
||||
relations: context.relationList,
|
||||
location: context.location,
|
||||
} as Memo,
|
||||
memoId: "",
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
onSuccess(memo.name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { Button } from "@/components/ui/button";
|
|||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { extractMemoIdFromName } from "@/store/common";
|
||||
import { MemoRelation_Type } from "@/types/proto/api/v1/memo_service";
|
||||
import { MemoRelation_Type } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import DateTimeInput from "../DateTimeInput";
|
||||
import { AttachmentList, LocationDisplay, RelationList } from "../memo-metadata";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { createContext } from "react";
|
||||
import type { Attachment } from "@/types/proto/api/v1/attachment_service";
|
||||
import type { MemoRelation } from "@/types/proto/api/v1/memo_service";
|
||||
import type { Attachment } from "@/types/proto/api/v1/attachment_service_pb";
|
||||
import type { MemoRelation } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import type { LocalFile } from "../../memo-metadata";
|
||||
|
||||
export interface MemoEditorContextValue {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import useAsyncEffect from "@/hooks/useAsyncEffect";
|
|||
import { cn } from "@/lib/utils";
|
||||
import { userStore } from "@/store";
|
||||
import memoFilterStore from "@/store/memoFilter";
|
||||
import { Shortcut } from "@/types/proto/api/v1/shortcut_service";
|
||||
import { Shortcut } from "@/types/proto/api/v1/shortcut_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import CreateShortcutDialog from "../CreateShortcutDialog";
|
||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../ui/dropdown-menu";
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { observer } from "mobx-react-lite";
|
||||
import { memo } from "react";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { State } from "@/types/proto/api/v1/common";
|
||||
import type { Memo, Reaction } from "@/types/proto/api/v1/memo_service";
|
||||
import { State } from "@/types/proto/api/v1/common_pb";
|
||||
import type { Memo, Reaction } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { useReactionGroups } from "./hooks";
|
||||
import ReactionSelector from "./ReactionSelector";
|
||||
import ReactionView from "./ReactionView";
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { useState } from "react";
|
|||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { instanceStore } from "@/store";
|
||||
import type { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import type { Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { useReactionActions } from "./hooks";
|
||||
|
||||
interface Props {
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ import { observer } from "mobx-react-lite";
|
|||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { State } from "@/types/proto/api/v1/common";
|
||||
import type { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import type { User } from "@/types/proto/api/v1/user_service";
|
||||
import { State } from "@/types/proto/api/v1/common_pb";
|
||||
import type { Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import type { User } from "@/types/proto/api/v1/user_service_pb";
|
||||
import { formatReactionTooltip, useReactionActions } from "./hooks";
|
||||
|
||||
interface Props {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ import { useEffect, useState } from "react";
|
|||
import { memoServiceClient } from "@/grpcweb";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { memoStore, userStore } from "@/store";
|
||||
import type { Memo, Reaction } from "@/types/proto/api/v1/memo_service";
|
||||
import type { User } from "@/types/proto/api/v1/user_service";
|
||||
import type { Memo, Reaction } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import type { User } from "@/types/proto/api/v1/user_service_pb";
|
||||
|
||||
export type ReactionGroup = Map<string, User[]>;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import ForceGraph2D, { ForceGraphMethods, LinkObject, NodeObject } from "react-f
|
|||
import useNavigateTo from "@/hooks/useNavigateTo";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { extractMemoIdFromName } from "@/store/common";
|
||||
import { Memo, MemoRelation_Type } from "@/types/proto/api/v1/memo_service";
|
||||
import { Memo, MemoRelation_Type } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { LinkType, NodeType } from "./types";
|
||||
import { convertMemoRelationsToGraphData } from "./utils";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { MemoRelation_Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { MemoRelation_Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
|
||||
export interface NodeType {
|
||||
memo: MemoRelation_Memo;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { GraphData, LinkObject, NodeObject } from "react-force-graph-2d";
|
||||
import { MemoRelation, MemoRelation_Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { MemoRelation, MemoRelation_Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { LinkType, NodeType } from "./types";
|
||||
|
||||
export const convertMemoRelationsToGraphData = (memoRelations: MemoRelation[]): GraphData<NodeType, LinkType> => {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { observer } from "mobx-react-lite";
|
||||
import { memo, useMemo, useRef, useState } from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import type { Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import MemoEditor from "../MemoEditor";
|
||||
import PreviewImageDialog from "../PreviewImageDialog";
|
||||
import { MemoBody, MemoHeader } from "./components";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { createContext, useContext } from "react";
|
||||
import type { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import type { User } from "@/types/proto/api/v1/user_service";
|
||||
import type { Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import type { User } from "@/types/proto/api/v1/user_service_pb";
|
||||
|
||||
export interface MemoViewContextValue {
|
||||
memo: Memo;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { cn } from "@/lib/utils";
|
||||
import { MemoRelation_Type } from "@/types/proto/api/v1/memo_service";
|
||||
import { MemoRelation_Type } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import MemoContent from "../../MemoContent";
|
||||
import { MemoReactionListView } from "../../MemoReactionListView";
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import { timestampDate } from "@bufbuild/protobuf/wkt";
|
||||
import { BookmarkIcon, EyeOffIcon, MessageCircleMoreIcon } from "lucide-react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
||||
import i18n from "@/i18n";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Visibility } from "@/types/proto/api/v1/memo_service";
|
||||
import type { User } from "@/types/proto/api/v1/user_service";
|
||||
import { Visibility } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import type { User } from "@/types/proto/api/v1/user_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { convertVisibilityToString } from "@/utils/memo";
|
||||
import MemoActionMenu from "../../MemoActionMenu";
|
||||
|
|
@ -43,9 +44,13 @@ const MemoHeader: React.FC<Props> = ({
|
|||
useMemoViewContext();
|
||||
|
||||
const displayTime = isArchived ? (
|
||||
memo.displayTime?.toLocaleString(i18n.language)
|
||||
(memo.displayTime ? timestampDate(memo.displayTime) : undefined)?.toLocaleString(i18n.language)
|
||||
) : (
|
||||
<relative-time datetime={memo.displayTime?.toISOString()} lang={i18n.language} format={relativeTimeFormat}></relative-time>
|
||||
<relative-time
|
||||
datetime={(memo.displayTime ? timestampDate(memo.displayTime) : undefined)?.toISOString()}
|
||||
lang={i18n.language}
|
||||
format={relativeTimeFormat}
|
||||
></relative-time>
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { timestampDate } from "@bufbuild/protobuf/wkt";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { State } from "@/types/proto/api/v1/common";
|
||||
import type { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { MemoRelation_Type } from "@/types/proto/api/v1/memo_service";
|
||||
import { State } from "@/types/proto/api/v1/common_pb";
|
||||
import type { Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { MemoRelation_Type } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { isSuperUser } from "@/utils/user";
|
||||
import { RELATIVE_TIME_THRESHOLD_MS } from "../constants";
|
||||
|
||||
|
|
@ -14,8 +15,9 @@ export const useMemoViewDerivedState = (memo: Memo, parentPageProp?: string) =>
|
|||
(relation) => relation.type === MemoRelation_Type.COMMENT && relation.relatedMemo?.name === memo.name,
|
||||
).length;
|
||||
|
||||
const displayTime = memo.displayTime ? timestampDate(memo.displayTime) : undefined;
|
||||
const relativeTimeFormat: "datetime" | "auto" =
|
||||
memo.displayTime && Date.now() - memo.displayTime.getTime() > RELATIVE_TIME_THRESHOLD_MS ? "datetime" : "auto";
|
||||
displayTime && Date.now() - displayTime.getTime() > RELATIVE_TIME_THRESHOLD_MS ? "datetime" : "auto";
|
||||
|
||||
const isArchived = memo.state === State.ARCHIVED;
|
||||
const readonly = memo.creator !== user?.name && !isSuperUser(user);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { useEffect, useRef, useState } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { instanceStore, memoStore, userStore } from "@/store";
|
||||
import { State } from "@/types/proto/api/v1/common";
|
||||
import type { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { State } from "@/types/proto/api/v1/common_pb";
|
||||
import type { Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import { KEYBOARD_SHORTCUTS, TEXT_INPUT_TYPES } from "../constants";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import type { User } from "@/types/proto/api/v1/user_service";
|
||||
import type { Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import type { User } from "@/types/proto/api/v1/user_service_pb";
|
||||
|
||||
export interface MemoViewProps {
|
||||
memo: Memo;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import useCurrentUser from "@/hooks/useCurrentUser";
|
|||
import { cn } from "@/lib/utils";
|
||||
import { Routes } from "@/router";
|
||||
import { userStore } from "@/store";
|
||||
import { UserNotification_Status } from "@/types/proto/api/v1/user_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import MemosLogo from "./MemosLogo";
|
||||
import UserMenu from "./UserMenu";
|
||||
|
|
@ -54,7 +55,7 @@ const Navigation = observer((props: Props) => {
|
|||
title: t("common.attachments"),
|
||||
icon: <PaperclipIcon className="w-6 h-auto shrink-0" />,
|
||||
};
|
||||
const unreadCount = userStore.state.notifications.filter((n) => n.status === "UNREAD").length;
|
||||
const unreadCount = userStore.state.notifications.filter((n) => n.status === UserNotification_Status.UNREAD).length;
|
||||
const inboxNavLink: NavLinkItem = {
|
||||
id: "header-inbox",
|
||||
path: Routes.INBOX,
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import { DEFAULT_LIST_MEMOS_PAGE_SIZE } from "@/helpers/consts";
|
|||
import useResponsiveWidth from "@/hooks/useResponsiveWidth";
|
||||
import { Routes } from "@/router";
|
||||
import { memoStore, userStore, viewStore } from "@/store";
|
||||
import { State } from "@/types/proto/api/v1/common";
|
||||
import type { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { State } from "@/types/proto/api/v1/common_pb";
|
||||
import type { Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import Empty from "../Empty";
|
||||
import type { MemoRenderContext } from "../MasonryView";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { ConnectError } from "@connectrpc/connect";
|
||||
import { LoaderIcon } from "lucide-react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { ClientError } from "nice-grpc-web";
|
||||
import { useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
|
@ -46,13 +46,16 @@ const PasswordSignInForm = observer(() => {
|
|||
try {
|
||||
actionBtnLoadingState.setLoading();
|
||||
await authServiceClient.createSession({
|
||||
passwordCredentials: { username, password },
|
||||
credentials: {
|
||||
case: "passwordCredentials",
|
||||
value: { username, password },
|
||||
},
|
||||
});
|
||||
await initialUserStore();
|
||||
navigateTo("/");
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
toast.error((error as ClientError).details || "Failed to sign in.");
|
||||
toast.error((error as ConnectError).message || "Failed to sign in.");
|
||||
}
|
||||
actionBtnLoadingState.setFinish();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { timestampDate } from "@bufbuild/protobuf/wkt";
|
||||
import copy from "copy-to-clipboard";
|
||||
import { ClipboardIcon, PlusIcon, TrashIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
|
|
@ -7,14 +8,18 @@ import { Button } from "@/components/ui/button";
|
|||
import { userServiceClient } from "@/grpcweb";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { useDialog } from "@/hooks/useDialog";
|
||||
import { UserAccessToken } from "@/types/proto/api/v1/user_service";
|
||||
import { UserAccessToken } from "@/types/proto/api/v1/user_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import CreateAccessTokenDialog from "../CreateAccessTokenDialog";
|
||||
import SettingTable from "./SettingTable";
|
||||
|
||||
const listAccessTokens = async (parent: string) => {
|
||||
const { accessTokens } = await userServiceClient.listUserAccessTokens({ parent });
|
||||
return accessTokens.sort((a, b) => (b.issuedAt?.getTime() ?? 0) - (a.issuedAt?.getTime() ?? 0));
|
||||
return accessTokens.sort(
|
||||
(a, b) =>
|
||||
((b.issuedAt ? timestampDate(b.issuedAt) : undefined)?.getTime() ?? 0) -
|
||||
((a.issuedAt ? timestampDate(a.issuedAt) : undefined)?.getTime() ?? 0),
|
||||
);
|
||||
};
|
||||
|
||||
const AccessTokenSection = () => {
|
||||
|
|
@ -98,13 +103,14 @@ const AccessTokenSection = () => {
|
|||
{
|
||||
key: "issuedAt",
|
||||
header: t("setting.access-token-section.create-dialog.created-at"),
|
||||
render: (_, token: UserAccessToken) => token.issuedAt?.toLocaleString(),
|
||||
render: (_, token: UserAccessToken) => (token.issuedAt ? timestampDate(token.issuedAt) : undefined)?.toLocaleString(),
|
||||
},
|
||||
{
|
||||
key: "expiresAt",
|
||||
header: t("setting.access-token-section.create-dialog.expires-at"),
|
||||
render: (_, token: UserAccessToken) =>
|
||||
token.expiresAt?.toLocaleString() ?? t("setting.access-token-section.create-dialog.duration-never"),
|
||||
(token.expiresAt ? timestampDate(token.expiresAt) : undefined)?.toLocaleString() ??
|
||||
t("setting.access-token-section.create-dialog.duration-never"),
|
||||
},
|
||||
{
|
||||
key: "actions",
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { create } from "@bufbuild/protobuf";
|
||||
import { isEqual } from "lodash-es";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { useEffect, useState } from "react";
|
||||
|
|
@ -10,19 +11,33 @@ import { identityProviderServiceClient } from "@/grpcweb";
|
|||
import useDialog from "@/hooks/useDialog";
|
||||
import { instanceStore } from "@/store";
|
||||
import { instanceSettingNamePrefix } from "@/store/common";
|
||||
import { IdentityProvider } from "@/types/proto/api/v1/idp_service";
|
||||
import { InstanceSetting_GeneralSetting, InstanceSetting_Key } from "@/types/proto/api/v1/instance_service";
|
||||
import { IdentityProvider } from "@/types/proto/api/v1/idp_service_pb";
|
||||
import {
|
||||
InstanceSetting_GeneralSetting,
|
||||
InstanceSetting_GeneralSettingSchema,
|
||||
InstanceSetting_Key,
|
||||
InstanceSettingSchema,
|
||||
} from "@/types/proto/api/v1/instance_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import UpdateCustomizedProfileDialog from "../UpdateCustomizedProfileDialog";
|
||||
import SettingGroup from "./SettingGroup";
|
||||
import SettingRow from "./SettingRow";
|
||||
import SettingSection from "./SettingSection";
|
||||
|
||||
// Helper to extract general setting value from InstanceSetting oneof
|
||||
function getGeneralSetting(setting: any): InstanceSetting_GeneralSetting | undefined {
|
||||
if (setting?.value?.case === "generalSetting") {
|
||||
return setting.value.value;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const InstanceSection = observer(() => {
|
||||
const t = useTranslate();
|
||||
const customizeDialog = useDialog();
|
||||
const originalSetting = InstanceSetting_GeneralSetting.fromPartial(
|
||||
instanceStore.getInstanceSettingByKey(InstanceSetting_Key.GENERAL)?.generalSetting || {},
|
||||
const originalSetting = create(
|
||||
InstanceSetting_GeneralSettingSchema,
|
||||
getGeneralSetting(instanceStore.getInstanceSettingByKey(InstanceSetting_Key.GENERAL)) || {},
|
||||
);
|
||||
const [instanceGeneralSetting, setInstanceGeneralSetting] = useState<InstanceSetting_GeneralSetting>(originalSetting);
|
||||
const [identityProviderList, setIdentityProviderList] = useState<IdentityProvider[]>([]);
|
||||
|
|
@ -37,7 +52,7 @@ const InstanceSection = observer(() => {
|
|||
|
||||
const updatePartialSetting = (partial: Partial<InstanceSetting_GeneralSetting>) => {
|
||||
setInstanceGeneralSetting(
|
||||
InstanceSetting_GeneralSetting.fromPartial({
|
||||
create(InstanceSetting_GeneralSettingSchema, {
|
||||
...instanceGeneralSetting,
|
||||
...partial,
|
||||
}),
|
||||
|
|
@ -46,12 +61,17 @@ const InstanceSection = observer(() => {
|
|||
|
||||
const handleSaveGeneralSetting = async () => {
|
||||
try {
|
||||
await instanceStore.upsertInstanceSetting({
|
||||
name: `${instanceSettingNamePrefix}${InstanceSetting_Key.GENERAL}`,
|
||||
generalSetting: instanceGeneralSetting,
|
||||
});
|
||||
await instanceStore.upsertInstanceSetting(
|
||||
create(InstanceSettingSchema, {
|
||||
name: `${instanceSettingNamePrefix}${InstanceSetting_Key.GENERAL}`,
|
||||
value: {
|
||||
case: "generalSetting",
|
||||
value: instanceGeneralSetting,
|
||||
},
|
||||
}),
|
||||
);
|
||||
} catch (error: any) {
|
||||
toast.error(error.details);
|
||||
toast.error(error.message);
|
||||
console.error(error);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { create } from "@bufbuild/protobuf";
|
||||
import { FieldMaskSchema } from "@bufbuild/protobuf/wkt";
|
||||
import { sortBy } from "lodash-es";
|
||||
import { MoreVerticalIcon, PlusIcon } from "lucide-react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
|
|
@ -9,8 +11,8 @@ import { userServiceClient } from "@/grpcweb";
|
|||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { useDialog } from "@/hooks/useDialog";
|
||||
import { userStore } from "@/store";
|
||||
import { State } from "@/types/proto/api/v1/common";
|
||||
import { User, User_Role } from "@/types/proto/api/v1/user_service";
|
||||
import { State } from "@/types/proto/api/v1/common_pb";
|
||||
import { User, User_Role } from "@/types/proto/api/v1/user_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import CreateUserDialog from "../CreateUserDialog";
|
||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "../ui/dropdown-menu";
|
||||
|
|
@ -69,7 +71,7 @@ const MemberSection = observer(() => {
|
|||
name: archiveTarget.name,
|
||||
state: State.ARCHIVED,
|
||||
},
|
||||
updateMask: ["state"],
|
||||
updateMask: create(FieldMaskSchema, { paths: ["state"] }),
|
||||
});
|
||||
setArchiveTarget(undefined);
|
||||
toast.success(t("setting.member-section.archive-success", { username }));
|
||||
|
|
@ -83,7 +85,7 @@ const MemberSection = observer(() => {
|
|||
name: user.name,
|
||||
state: State.NORMAL,
|
||||
},
|
||||
updateMask: ["state"],
|
||||
updateMask: create(FieldMaskSchema, { paths: ["state"] }),
|
||||
});
|
||||
toast.success(t("setting.member-section.restore-success", { username }));
|
||||
await fetchUsers();
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { create } from "@bufbuild/protobuf";
|
||||
import { isEqual, uniq } from "lodash-es";
|
||||
import { CheckIcon, X } from "lucide-react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
|
|
@ -9,7 +10,12 @@ import { Input } from "@/components/ui/input";
|
|||
import { Switch } from "@/components/ui/switch";
|
||||
import { instanceStore } from "@/store";
|
||||
import { instanceSettingNamePrefix } from "@/store/common";
|
||||
import { InstanceSetting_Key, InstanceSetting_MemoRelatedSetting } from "@/types/proto/api/v1/instance_service";
|
||||
import {
|
||||
InstanceSetting_Key,
|
||||
InstanceSetting_MemoRelatedSetting,
|
||||
InstanceSetting_MemoRelatedSettingSchema,
|
||||
InstanceSettingSchema,
|
||||
} from "@/types/proto/api/v1/instance_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import SettingGroup from "./SettingGroup";
|
||||
import SettingRow from "./SettingRow";
|
||||
|
|
@ -23,7 +29,7 @@ const MemoRelatedSettings = observer(() => {
|
|||
const [editingNsfwTag, setEditingNsfwTag] = useState<string>("");
|
||||
|
||||
const updatePartialSetting = (partial: Partial<InstanceSetting_MemoRelatedSetting>) => {
|
||||
const newInstanceMemoRelatedSetting = InstanceSetting_MemoRelatedSetting.fromPartial({
|
||||
const newInstanceMemoRelatedSetting = create(InstanceSetting_MemoRelatedSettingSchema, {
|
||||
...memoRelatedSetting,
|
||||
...partial,
|
||||
});
|
||||
|
|
@ -55,14 +61,19 @@ const MemoRelatedSettings = observer(() => {
|
|||
}
|
||||
|
||||
try {
|
||||
await instanceStore.upsertInstanceSetting({
|
||||
name: `${instanceSettingNamePrefix}${InstanceSetting_Key.MEMO_RELATED}`,
|
||||
memoRelatedSetting,
|
||||
});
|
||||
await instanceStore.upsertInstanceSetting(
|
||||
create(InstanceSettingSchema, {
|
||||
name: `${instanceSettingNamePrefix}${InstanceSetting_Key.MEMO_RELATED}`,
|
||||
value: {
|
||||
case: "memoRelatedSetting",
|
||||
value: memoRelatedSetting,
|
||||
},
|
||||
}),
|
||||
);
|
||||
setOriginalSetting(memoRelatedSetting);
|
||||
toast.success(t("message.update-succeed"));
|
||||
} catch (error: any) {
|
||||
toast.error(error.details);
|
||||
toast.error(error.message);
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { create } from "@bufbuild/protobuf";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import { userStore } from "@/store";
|
||||
import { Visibility } from "@/types/proto/api/v1/memo_service";
|
||||
import { UserSetting_GeneralSetting } from "@/types/proto/api/v1/user_service";
|
||||
import { Visibility } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { UserSetting_GeneralSetting, UserSetting_GeneralSettingSchema } from "@/types/proto/api/v1/user_service_pb";
|
||||
import { loadLocale, useTranslate } from "@/utils/i18n";
|
||||
import { convertVisibilityFromString, convertVisibilityToString } from "@/utils/memo";
|
||||
import { loadTheme } from "@/utils/theme";
|
||||
|
|
@ -37,11 +38,13 @@ const PreferencesSection = observer(() => {
|
|||
};
|
||||
|
||||
// Provide default values if setting is not loaded yet
|
||||
const setting: UserSetting_GeneralSetting = generalSetting || {
|
||||
locale: "en",
|
||||
memoVisibility: "PRIVATE",
|
||||
theme: "system",
|
||||
};
|
||||
const setting: UserSetting_GeneralSetting =
|
||||
generalSetting ||
|
||||
create(UserSetting_GeneralSettingSchema, {
|
||||
locale: "en",
|
||||
memoVisibility: "PRIVATE",
|
||||
theme: "system",
|
||||
});
|
||||
|
||||
return (
|
||||
<SettingSection>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import ConfirmDialog from "@/components/ConfirmDialog";
|
|||
import { Button } from "@/components/ui/button";
|
||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
||||
import { identityProviderServiceClient } from "@/grpcweb";
|
||||
import { IdentityProvider } from "@/types/proto/api/v1/idp_service";
|
||||
import { IdentityProvider } from "@/types/proto/api/v1/idp_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import CreateIdentityProviderDialog from "../CreateIdentityProviderDialog";
|
||||
import LearnMore from "../LearnMore";
|
||||
|
|
@ -38,7 +38,7 @@ const SSOSection = () => {
|
|||
await identityProviderServiceClient.deleteIdentityProvider({ name: deleteTarget.name });
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
toast.error(error.details);
|
||||
toast.error(error.message);
|
||||
}
|
||||
await fetchIdentityProviderList();
|
||||
setDeleteTarget(undefined);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { create } from "@bufbuild/protobuf";
|
||||
import { isEqual } from "lodash-es";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
|
|
@ -13,22 +14,39 @@ import {
|
|||
InstanceSetting_Key,
|
||||
InstanceSetting_StorageSetting,
|
||||
InstanceSetting_StorageSetting_S3Config,
|
||||
InstanceSetting_StorageSetting_S3ConfigSchema,
|
||||
InstanceSetting_StorageSetting_StorageType,
|
||||
} from "@/types/proto/api/v1/instance_service";
|
||||
InstanceSetting_StorageSettingSchema,
|
||||
InstanceSettingSchema,
|
||||
} from "@/types/proto/api/v1/instance_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import SettingGroup from "./SettingGroup";
|
||||
import SettingRow from "./SettingRow";
|
||||
import SettingSection from "./SettingSection";
|
||||
|
||||
// Helper to extract storage setting value from InstanceSetting oneof
|
||||
function getStorageSetting(setting: any): InstanceSetting_StorageSetting | undefined {
|
||||
if (setting?.value?.case === "storageSetting") {
|
||||
return setting.value.value;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const StorageSection = observer(() => {
|
||||
const t = useTranslate();
|
||||
const [instanceStorageSetting, setInstanceStorageSetting] = useState<InstanceSetting_StorageSetting>(
|
||||
InstanceSetting_StorageSetting.fromPartial(instanceStore.getInstanceSettingByKey(InstanceSetting_Key.STORAGE)?.storageSetting || {}),
|
||||
create(
|
||||
InstanceSetting_StorageSettingSchema,
|
||||
getStorageSetting(instanceStore.getInstanceSettingByKey(InstanceSetting_Key.STORAGE)) || {},
|
||||
),
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setInstanceStorageSetting(
|
||||
InstanceSetting_StorageSetting.fromPartial(instanceStore.getInstanceSettingByKey(InstanceSetting_Key.STORAGE)?.storageSetting || {}),
|
||||
create(
|
||||
InstanceSetting_StorageSettingSchema,
|
||||
getStorageSetting(instanceStore.getInstanceSettingByKey(InstanceSetting_Key.STORAGE)) || {},
|
||||
),
|
||||
);
|
||||
}, [instanceStore.getInstanceSettingByKey(InstanceSetting_Key.STORAGE)]);
|
||||
|
||||
|
|
@ -37,8 +55,9 @@ const StorageSection = observer(() => {
|
|||
return false;
|
||||
}
|
||||
|
||||
const origin = InstanceSetting_StorageSetting.fromPartial(
|
||||
instanceStore.getInstanceSettingByKey(InstanceSetting_Key.STORAGE)?.storageSetting || {},
|
||||
const origin = create(
|
||||
InstanceSetting_StorageSettingSchema,
|
||||
getStorageSetting(instanceStore.getInstanceSettingByKey(InstanceSetting_Key.STORAGE)) || {},
|
||||
);
|
||||
if (instanceStorageSetting.storageType === InstanceSetting_StorageSetting_StorageType.LOCAL) {
|
||||
if (instanceStorageSetting.filepathTemplate.length === 0) {
|
||||
|
|
@ -63,29 +82,38 @@ const StorageSection = observer(() => {
|
|||
if (Number.isNaN(num)) {
|
||||
num = 0;
|
||||
}
|
||||
const update: InstanceSetting_StorageSetting = {
|
||||
const update = create(InstanceSetting_StorageSettingSchema, {
|
||||
...instanceStorageSetting,
|
||||
uploadSizeLimitMb: num,
|
||||
};
|
||||
uploadSizeLimitMb: BigInt(num),
|
||||
});
|
||||
setInstanceStorageSetting(update);
|
||||
};
|
||||
|
||||
const handleFilepathTemplateChanged = async (event: React.FocusEvent<HTMLInputElement>) => {
|
||||
const update: InstanceSetting_StorageSetting = {
|
||||
const update = create(InstanceSetting_StorageSettingSchema, {
|
||||
...instanceStorageSetting,
|
||||
filepathTemplate: event.target.value,
|
||||
};
|
||||
});
|
||||
setInstanceStorageSetting(update);
|
||||
};
|
||||
|
||||
const handlePartialS3ConfigChanged = async (s3Config: Partial<InstanceSetting_StorageSetting_S3Config>) => {
|
||||
const update: InstanceSetting_StorageSetting = {
|
||||
...instanceStorageSetting,
|
||||
s3Config: InstanceSetting_StorageSetting_S3Config.fromPartial({
|
||||
...instanceStorageSetting.s3Config,
|
||||
...s3Config,
|
||||
}),
|
||||
const existingS3Config = instanceStorageSetting.s3Config;
|
||||
const s3ConfigInit = {
|
||||
accessKeyId: existingS3Config?.accessKeyId ?? "",
|
||||
accessKeySecret: existingS3Config?.accessKeySecret ?? "",
|
||||
endpoint: existingS3Config?.endpoint ?? "",
|
||||
region: existingS3Config?.region ?? "",
|
||||
bucket: existingS3Config?.bucket ?? "",
|
||||
usePathStyle: existingS3Config?.usePathStyle ?? false,
|
||||
...s3Config,
|
||||
};
|
||||
const update = create(InstanceSetting_StorageSettingSchema, {
|
||||
storageType: instanceStorageSetting.storageType,
|
||||
filepathTemplate: instanceStorageSetting.filepathTemplate,
|
||||
uploadSizeLimitMb: instanceStorageSetting.uploadSizeLimitMb,
|
||||
s3Config: create(InstanceSetting_StorageSetting_S3ConfigSchema, s3ConfigInit),
|
||||
});
|
||||
setInstanceStorageSetting(update);
|
||||
};
|
||||
|
||||
|
|
@ -116,18 +144,23 @@ const StorageSection = observer(() => {
|
|||
};
|
||||
|
||||
const handleStorageTypeChanged = async (storageType: InstanceSetting_StorageSetting_StorageType) => {
|
||||
const update: InstanceSetting_StorageSetting = {
|
||||
const update = create(InstanceSetting_StorageSettingSchema, {
|
||||
...instanceStorageSetting,
|
||||
storageType: storageType,
|
||||
};
|
||||
});
|
||||
setInstanceStorageSetting(update);
|
||||
};
|
||||
|
||||
const saveInstanceStorageSetting = async () => {
|
||||
await instanceStore.upsertInstanceSetting({
|
||||
name: `${instanceSettingNamePrefix}${InstanceSetting_Key.STORAGE}`,
|
||||
storageSetting: instanceStorageSetting,
|
||||
});
|
||||
await instanceStore.upsertInstanceSetting(
|
||||
create(InstanceSettingSchema, {
|
||||
name: `${instanceSettingNamePrefix}${InstanceSetting_Key.STORAGE}`,
|
||||
value: {
|
||||
case: "storageSetting",
|
||||
value: instanceStorageSetting,
|
||||
},
|
||||
}),
|
||||
);
|
||||
toast.success("Updated");
|
||||
};
|
||||
|
||||
|
|
@ -136,29 +169,33 @@ const StorageSection = observer(() => {
|
|||
<SettingGroup title={t("setting.storage-section.current-storage")}>
|
||||
<div className="w-full">
|
||||
<RadioGroup
|
||||
value={instanceStorageSetting.storageType}
|
||||
value={String(instanceStorageSetting.storageType)}
|
||||
onValueChange={(value) => {
|
||||
handleStorageTypeChanged(value as InstanceSetting_StorageSetting_StorageType);
|
||||
handleStorageTypeChanged(Number(value) as InstanceSetting_StorageSetting_StorageType);
|
||||
}}
|
||||
className="flex flex-row gap-4"
|
||||
>
|
||||
<div className="flex items-center space-x-2">
|
||||
<RadioGroupItem value={InstanceSetting_StorageSetting_StorageType.DATABASE} id="database" />
|
||||
<RadioGroupItem value={String(InstanceSetting_StorageSetting_StorageType.DATABASE)} id="database" />
|
||||
<Label htmlFor="database">{t("setting.storage-section.type-database")}</Label>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<RadioGroupItem value={InstanceSetting_StorageSetting_StorageType.LOCAL} id="local" />
|
||||
<RadioGroupItem value={String(InstanceSetting_StorageSetting_StorageType.LOCAL)} id="local" />
|
||||
<Label htmlFor="local">{t("setting.storage-section.type-local")}</Label>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<RadioGroupItem value={InstanceSetting_StorageSetting_StorageType.S3} id="s3" />
|
||||
<RadioGroupItem value={String(InstanceSetting_StorageSetting_StorageType.S3)} id="s3" />
|
||||
<Label htmlFor="s3">S3</Label>
|
||||
</div>
|
||||
</RadioGroup>
|
||||
</div>
|
||||
|
||||
<SettingRow label={t("setting.system-section.max-upload-size")} tooltip={t("setting.system-section.max-upload-size-hint")}>
|
||||
<Input className="w-24 font-mono" value={instanceStorageSetting.uploadSizeLimitMb} onChange={handleMaxUploadSizeChanged} />
|
||||
<Input
|
||||
className="w-24 font-mono"
|
||||
value={String(instanceStorageSetting.uploadSizeLimitMb)}
|
||||
onChange={handleMaxUploadSizeChanged}
|
||||
/>
|
||||
</SettingRow>
|
||||
|
||||
{instanceStorageSetting.storageType !== InstanceSetting_StorageSetting_StorageType.DATABASE && (
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { timestampDate } from "@bufbuild/protobuf/wkt";
|
||||
import { ClockIcon, MonitorIcon, SmartphoneIcon, TabletIcon, TrashIcon, WifiIcon } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
|
|
@ -5,13 +6,17 @@ import ConfirmDialog from "@/components/ConfirmDialog";
|
|||
import { Button } from "@/components/ui/button";
|
||||
import { userServiceClient } from "@/grpcweb";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { UserSession } from "@/types/proto/api/v1/user_service";
|
||||
import { UserSession } from "@/types/proto/api/v1/user_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import SettingTable from "./SettingTable";
|
||||
|
||||
const listUserSessions = async (parent: string) => {
|
||||
const { sessions } = await userServiceClient.listUserSessions({ parent });
|
||||
return sessions.sort((a, b) => (b.lastAccessedTime?.getTime() ?? 0) - (a.lastAccessedTime?.getTime() ?? 0));
|
||||
return sessions.sort(
|
||||
(a, b) =>
|
||||
((b.lastAccessedTime ? timestampDate(b.lastAccessedTime) : undefined)?.getTime() ?? 0) -
|
||||
((a.lastAccessedTime ? timestampDate(a.lastAccessedTime) : undefined)?.getTime() ?? 0),
|
||||
);
|
||||
};
|
||||
|
||||
const UserSessionsSection = () => {
|
||||
|
|
@ -107,7 +112,7 @@ const UserSessionsSection = () => {
|
|||
render: (_, session: UserSession) => (
|
||||
<div className="flex items-center space-x-1">
|
||||
<ClockIcon className="w-4 h-4" />
|
||||
<span>{session.lastAccessedTime?.toLocaleString()}</span>
|
||||
<span>{(session.lastAccessedTime ? timestampDate(session.lastAccessedTime) : undefined)?.toLocaleString()}</span>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import ConfirmDialog from "@/components/ConfirmDialog";
|
|||
import { Button } from "@/components/ui/button";
|
||||
import { userServiceClient } from "@/grpcweb";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { UserWebhook } from "@/types/proto/api/v1/user_service";
|
||||
import { UserWebhook } from "@/types/proto/api/v1/user_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import CreateWebhookDialog from "../CreateWebhookDialog";
|
||||
import SettingTable from "./SettingTable";
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { create } from "@bufbuild/protobuf";
|
||||
import { isEqual } from "lodash-es";
|
||||
import { XIcon } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
|
|
@ -10,7 +11,7 @@ import { Textarea } from "@/components/ui/textarea";
|
|||
import { convertFileToBase64 } from "@/helpers/utils";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { instanceStore, userStore } from "@/store";
|
||||
import { User as UserPb } from "@/types/proto/api/v1/user_service";
|
||||
import { User as UserPb, UserSchema } from "@/types/proto/api/v1/user_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import UserAvatar from "./UserAvatar";
|
||||
|
||||
|
|
@ -127,7 +128,7 @@ function UpdateAccountDialog({ open, onOpenChange, onSuccess }: Props) {
|
|||
updateMask.push("description");
|
||||
}
|
||||
await userStore.updateUser(
|
||||
UserPb.fromPartial({
|
||||
create(UserSchema, {
|
||||
name: currentUser.name,
|
||||
username: state.username,
|
||||
displayName: state.displayName,
|
||||
|
|
@ -142,7 +143,7 @@ function UpdateAccountDialog({ open, onOpenChange, onSuccess }: Props) {
|
|||
onOpenChange(false);
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
toast.error(error.details);
|
||||
toast.error(error.message);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { create } from "@bufbuild/protobuf";
|
||||
import { useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
|
@ -7,7 +8,12 @@ import { Label } from "@/components/ui/label";
|
|||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { instanceStore } from "@/store";
|
||||
import { instanceSettingNamePrefix } from "@/store/common";
|
||||
import { InstanceSetting_GeneralSetting_CustomProfile, InstanceSetting_Key } from "@/types/proto/api/v1/instance_service";
|
||||
import {
|
||||
InstanceSetting_GeneralSetting_CustomProfile,
|
||||
InstanceSetting_GeneralSetting_CustomProfileSchema,
|
||||
InstanceSetting_Key,
|
||||
InstanceSettingSchema,
|
||||
} from "@/types/proto/api/v1/instance_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
|
||||
interface Props {
|
||||
|
|
@ -20,7 +26,7 @@ function UpdateCustomizedProfileDialog({ open, onOpenChange, onSuccess }: Props)
|
|||
const t = useTranslate();
|
||||
const instanceGeneralSetting = instanceStore.state.generalSetting;
|
||||
const [customProfile, setCustomProfile] = useState<InstanceSetting_GeneralSetting_CustomProfile>(
|
||||
InstanceSetting_GeneralSetting_CustomProfile.fromPartial(instanceGeneralSetting.customProfile || {}),
|
||||
create(InstanceSetting_GeneralSetting_CustomProfileSchema, instanceGeneralSetting.customProfile || {}),
|
||||
);
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
|
@ -70,13 +76,18 @@ function UpdateCustomizedProfileDialog({ open, onOpenChange, onSuccess }: Props)
|
|||
|
||||
setIsLoading(true);
|
||||
try {
|
||||
await instanceStore.upsertInstanceSetting({
|
||||
name: `${instanceSettingNamePrefix}${InstanceSetting_Key.GENERAL}`,
|
||||
generalSetting: {
|
||||
...instanceGeneralSetting,
|
||||
customProfile: customProfile,
|
||||
},
|
||||
});
|
||||
await instanceStore.upsertInstanceSetting(
|
||||
create(InstanceSettingSchema, {
|
||||
name: `${instanceSettingNamePrefix}${InstanceSetting_Key.GENERAL}`,
|
||||
value: {
|
||||
case: "generalSetting",
|
||||
value: {
|
||||
...instanceGeneralSetting,
|
||||
customProfile: customProfile,
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
toast.success(t("message.update-succeed"));
|
||||
onSuccess?.();
|
||||
onOpenChange(false);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Globe2Icon, LockIcon, UsersIcon } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Visibility } from "@/types/proto/api/v1/memo_service";
|
||||
import { Visibility } from "@/types/proto/api/v1/memo_service_pb";
|
||||
|
||||
interface Props {
|
||||
visibility: Visibility;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { closestCenter, DndContext, type DragEndEvent, MouseSensor, TouchSensor, useSensor, useSensors } from "@dnd-kit/core";
|
||||
import { arrayMove, SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
|
||||
import { useState } from "react";
|
||||
import type { Attachment } from "@/types/proto/api/v1/attachment_service";
|
||||
import type { Attachment } from "@/types/proto/api/v1/attachment_service_pb";
|
||||
import { getAttachmentType, getAttachmentUrl } from "@/utils/attachment";
|
||||
import MemoAttachment from "../MemoAttachment";
|
||||
import PreviewImageDialog from "../PreviewImageDialog";
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { LatLng } from "leaflet";
|
|||
import { MapPinIcon, XIcon } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Location } from "@/types/proto/api/v1/memo_service";
|
||||
import { Location } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import LeafletMap from "../LeafletMap";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
|
||||
import { BaseMetadataProps } from "./types";
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { LinkIcon, XIcon } from "lucide-react";
|
|||
import { Link } from "react-router-dom";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { extractMemoIdFromName } from "@/store/common";
|
||||
import { MemoRelation_Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { MemoRelation_Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { DisplayMode } from "./types";
|
||||
|
||||
interface RelationCardProps {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import { create } from "@bufbuild/protobuf";
|
||||
import { LinkIcon, MilestoneIcon } from "lucide-react";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { useEffect, useState } from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { memoStore } from "@/store";
|
||||
import { Memo, MemoRelation, MemoRelation_Type } from "@/types/proto/api/v1/memo_service";
|
||||
import { Memo, MemoRelation, MemoRelation_MemoSchema, MemoRelation_Type } from "@/types/proto/api/v1/memo_service_pb";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import MetadataCard from "./MetadataCard";
|
||||
import RelationCard from "./RelationCard";
|
||||
|
|
@ -70,7 +71,7 @@ const RelationList = observer(({ relations, currentMemoName, mode, onRelationsCh
|
|||
{referencingMemos.map((memo) => (
|
||||
<RelationCard
|
||||
key={memo.name}
|
||||
memo={{ name: memo.name, snippet: memo.snippet }}
|
||||
memo={create(MemoRelation_MemoSchema, { name: memo.name, snippet: memo.snippet })}
|
||||
mode="edit"
|
||||
onRemove={() => handleDeleteRelation(memo.name)}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { Attachment } from "@/types/proto/api/v1/attachment_service";
|
||||
import type { Attachment } from "@/types/proto/api/v1/attachment_service_pb";
|
||||
import { getAttachmentThumbnailUrl, getAttachmentType, getAttachmentUrl } from "@/utils/attachment";
|
||||
|
||||
export type DisplayMode = "edit" | "view";
|
||||
|
|
@ -39,7 +39,7 @@ export function attachmentToItem(attachment: Attachment): AttachmentItem {
|
|||
mimeType: attachment.type,
|
||||
thumbnailUrl: attachmentType === "image/*" ? getAttachmentThumbnailUrl(attachment) : sourceUrl,
|
||||
sourceUrl,
|
||||
size: attachment.size,
|
||||
size: Number(attachment.size),
|
||||
isLocal: false,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,34 +1,32 @@
|
|||
import { createChannel, createClientFactory, FetchTransport } from "nice-grpc-web";
|
||||
import { ActivityServiceDefinition } from "./types/proto/api/v1/activity_service";
|
||||
import { AttachmentServiceDefinition } from "./types/proto/api/v1/attachment_service";
|
||||
import { AuthServiceDefinition } from "./types/proto/api/v1/auth_service";
|
||||
import { IdentityProviderServiceDefinition } from "./types/proto/api/v1/idp_service";
|
||||
import { InstanceServiceDefinition } from "./types/proto/api/v1/instance_service";
|
||||
import { MemoServiceDefinition } from "./types/proto/api/v1/memo_service";
|
||||
import { ShortcutServiceDefinition } from "./types/proto/api/v1/shortcut_service";
|
||||
import { UserServiceDefinition } from "./types/proto/api/v1/user_service";
|
||||
import { createClient } from "@connectrpc/connect";
|
||||
import { createConnectTransport } from "@connectrpc/connect-web";
|
||||
import { ActivityService } from "./types/proto/api/v1/activity_service_pb";
|
||||
import { AttachmentService } from "./types/proto/api/v1/attachment_service_pb";
|
||||
import { AuthService } from "./types/proto/api/v1/auth_service_pb";
|
||||
import { IdentityProviderService } from "./types/proto/api/v1/idp_service_pb";
|
||||
import { InstanceService } from "./types/proto/api/v1/instance_service_pb";
|
||||
import { MemoService } from "./types/proto/api/v1/memo_service_pb";
|
||||
import { ShortcutService } from "./types/proto/api/v1/shortcut_service_pb";
|
||||
import { UserService } from "./types/proto/api/v1/user_service_pb";
|
||||
|
||||
const channel = createChannel(
|
||||
window.location.origin,
|
||||
FetchTransport({
|
||||
credentials: "include",
|
||||
}),
|
||||
);
|
||||
const transport = createConnectTransport({
|
||||
baseUrl: window.location.origin,
|
||||
// Include cookies in requests for session auth
|
||||
fetch: (input, init) => fetch(input, { ...init, credentials: "include" }),
|
||||
});
|
||||
|
||||
const clientFactory = createClientFactory();
|
||||
export const instanceServiceClient = createClient(InstanceService, transport);
|
||||
|
||||
export const instanceServiceClient = clientFactory.create(InstanceServiceDefinition, channel);
|
||||
export const authServiceClient = createClient(AuthService, transport);
|
||||
|
||||
export const authServiceClient = clientFactory.create(AuthServiceDefinition, channel);
|
||||
export const userServiceClient = createClient(UserService, transport);
|
||||
|
||||
export const userServiceClient = clientFactory.create(UserServiceDefinition, channel);
|
||||
export const memoServiceClient = createClient(MemoService, transport);
|
||||
|
||||
export const memoServiceClient = clientFactory.create(MemoServiceDefinition, channel);
|
||||
export const attachmentServiceClient = createClient(AttachmentService, transport);
|
||||
|
||||
export const attachmentServiceClient = clientFactory.create(AttachmentServiceDefinition, channel);
|
||||
export const shortcutServiceClient = createClient(ShortcutService, transport);
|
||||
|
||||
export const shortcutServiceClient = clientFactory.create(ShortcutServiceDefinition, channel);
|
||||
export const activityServiceClient = createClient(ActivityService, transport);
|
||||
|
||||
export const activityServiceClient = clientFactory.create(ActivityServiceDefinition, channel);
|
||||
|
||||
export const identityProviderServiceClient = clientFactory.create(IdentityProviderServiceDefinition, channel);
|
||||
export const identityProviderServiceClient = createClient(IdentityProviderService, transport);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { timestampDate } from "@bufbuild/protobuf/wkt";
|
||||
import dayjs from "dayjs";
|
||||
import { countBy } from "lodash-es";
|
||||
import { useEffect, useState } from "react";
|
||||
|
|
@ -57,7 +58,12 @@ export const useFilteredMemoStats = (options: UseFilteredMemoStatsOptions = {}):
|
|||
if (userStats) {
|
||||
// Use activity timestamps from user stats
|
||||
if (userStats.memoDisplayTimestamps && userStats.memoDisplayTimestamps.length > 0) {
|
||||
activityStats = countBy(userStats.memoDisplayTimestamps.map((date) => dayjs(date).format("YYYY-MM-DD")));
|
||||
activityStats = countBy(
|
||||
userStats.memoDisplayTimestamps
|
||||
.map((ts) => (ts ? timestampDate(ts) : undefined))
|
||||
.filter((date): date is Date => date !== undefined)
|
||||
.map((date) => dayjs(date).format("YYYY-MM-DD")),
|
||||
);
|
||||
}
|
||||
// Use tag counts from user stats
|
||||
if (userStats.tagCount) {
|
||||
|
|
@ -75,8 +81,9 @@ export const useFilteredMemoStats = (options: UseFilteredMemoStatsOptions = {}):
|
|||
|
||||
for (const memo of memos) {
|
||||
// Collect display timestamps for activity calendar
|
||||
if (memo.displayTime) {
|
||||
displayTimeList.push(memo.displayTime);
|
||||
const displayTime = memo.displayTime ? timestampDate(memo.displayTime) : undefined;
|
||||
if (displayTime) {
|
||||
displayTimeList.push(displayTime);
|
||||
}
|
||||
// Count tags
|
||||
if (memo.tags && memo.tags.length > 0) {
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ import { useMemo } from "react";
|
|||
import { instanceStore, userStore } from "@/store";
|
||||
import { extractUserIdFromName } from "@/store/common";
|
||||
import memoFilterStore from "@/store/memoFilter";
|
||||
import { InstanceSetting_Key } from "@/types/proto/api/v1/instance_service";
|
||||
import { Visibility } from "@/types/proto/api/v1/memo_service";
|
||||
import { InstanceSetting_Key } from "@/types/proto/api/v1/instance_service_pb";
|
||||
import { Visibility } from "@/types/proto/api/v1/memo_service_pb";
|
||||
|
||||
const getShortcutId = (name: string): string => {
|
||||
const parts = name.split("/");
|
||||
|
|
@ -64,8 +64,8 @@ export const useMemoFilters = (options: UseMemoFiltersOptions = {}): string | un
|
|||
conditions.push(`has_code`);
|
||||
} else if (filter.factor === "displayTime") {
|
||||
// Check instance setting for display time factor
|
||||
const displayWithUpdateTime = instanceStore.getInstanceSettingByKey(InstanceSetting_Key.MEMO_RELATED).memoRelatedSetting
|
||||
?.displayWithUpdateTime;
|
||||
const setting = instanceStore.getInstanceSettingByKey(InstanceSetting_Key.MEMO_RELATED);
|
||||
const displayWithUpdateTime = setting?.value.case === "memoRelatedSetting" ? setting.value.value.displayWithUpdateTime : false;
|
||||
const factor = displayWithUpdateTime ? "updated_ts" : "created_ts";
|
||||
|
||||
// Convert date to UTC timestamp range
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { timestampDate } from "@bufbuild/protobuf/wkt";
|
||||
import dayjs from "dayjs";
|
||||
import { useMemo } from "react";
|
||||
import { viewStore } from "@/store";
|
||||
import { State } from "@/types/proto/api/v1/common";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { State } from "@/types/proto/api/v1/common_pb";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
|
||||
export interface UseMemoSortingOptions {
|
||||
pinnedFirst?: boolean;
|
||||
|
|
@ -38,9 +39,9 @@ export const useMemoSorting = (options: UseMemoSortingOptions = {}): UseMemoSort
|
|||
}
|
||||
|
||||
// Then sort by display time
|
||||
return orderByTimeAsc
|
||||
? dayjs(a.displayTime).unix() - dayjs(b.displayTime).unix()
|
||||
: dayjs(b.displayTime).unix() - dayjs(a.displayTime).unix();
|
||||
const aTime = a.displayTime ? timestampDate(a.displayTime) : undefined;
|
||||
const bTime = b.displayTime ? timestampDate(b.displayTime) : undefined;
|
||||
return orderByTimeAsc ? dayjs(aTime).unix() - dayjs(bTime).unix() : dayjs(bTime).unix() - dayjs(aTime).unix();
|
||||
});
|
||||
};
|
||||
}, [pinnedFirst, state, orderByTimeAsc]);
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ import MemoView from "@/components/MemoView";
|
|||
import PagedMemoList from "@/components/PagedMemoList";
|
||||
import { useMemoFilters, useMemoSorting } from "@/hooks";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { State } from "@/types/proto/api/v1/common";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service";
|
||||
import { State } from "@/types/proto/api/v1/common_pb";
|
||||
import { Memo } from "@/types/proto/api/v1/memo_service_pb";
|
||||
|
||||
const Archived = observer(() => {
|
||||
const user = useCurrentUser();
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue