From e2477e29e939105d3598c612af73158090c03009 Mon Sep 17 00:00:00 2001 From: weoses Date: Sun, 16 Nov 2025 20:02:25 +0300 Subject: [PATCH 01/10] ocrService: - update golang - error-handling - rework specs --- apispec/go.mod | 40 ++- apispec/go.sum | 179 +++++++++++++ apispec/ocr-server/api.yml | 32 ++- apispec/ocr-server/client/api.gen.go | 44 ++-- apispec/ocr-server/server/api.gen.go | 45 ++-- common/commonerror/api_error.go | 13 + common/commonhelper/util.go | 3 + common/commonmiddleware/LoggingMiddleware.go | 7 +- go.work | 2 +- go.work.sum | 239 ++++++++++++++---- ocr-service/src/entity/Entity.go | 6 +- ocr-service/src/go.mod | 1 + ocr-service/src/go.sum | 2 + ocr-service/src/main.go | 14 +- ocr-service/src/service/ImageConvertor.go | 60 +++-- ocr-service/src/service/ImageService.go | 108 +++++--- .../ElasticMetadataStorageServiceImpl.go | 2 - 17 files changed, 631 insertions(+), 166 deletions(-) create mode 100644 common/commonerror/api_error.go create mode 100644 common/commonhelper/util.go diff --git a/apispec/go.mod b/apispec/go.mod index c83dbcd..7c4cbba 100644 --- a/apispec/go.mod +++ b/apispec/go.mod @@ -1,24 +1,48 @@ module mine.local/ocr-gallery/apispec -go 1.23.2 +go 1.24.10 require ( - github.com/labstack/echo/v4 v4.13.3 - github.com/oapi-codegen/runtime v1.1.1 + github.com/labstack/echo/v4 v4.13.4 + github.com/oapi-codegen/runtime v1.1.2 ) require ( github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/dprotaso/go-yit v0.0.0-20250909171706-0a81c39169bc // indirect + github.com/getkin/kin-openapi v0.133.0 // indirect + github.com/go-openapi/jsonpointer v0.22.2 // indirect + github.com/go-openapi/swag v0.25.1 // indirect + github.com/go-openapi/swag/jsonname v0.25.1 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/labstack/gommon v0.4.2 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mailru/easyjson v0.9.1 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/oapi-codegen/oapi-codegen/v2 v2.5.1 // indirect + github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect + github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect + github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/speakeasy-api/jsonpath v0.6.2 // indirect + github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect - golang.org/x/crypto v0.32.0 // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/text v0.21.0 // indirect + github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect + go.yaml.in/yaml/v4 v4.0.0-rc.3 // indirect + golang.org/x/crypto v0.44.0 // indirect + golang.org/x/mod v0.30.0 // indirect + golang.org/x/net v0.47.0 // indirect + golang.org/x/sync v0.18.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/text v0.31.0 // indirect + golang.org/x/tools v0.39.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) + +tool github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen diff --git a/apispec/go.sum b/apispec/go.sum index 354dd30..315cefb 100644 --- a/apispec/go.sum +++ b/apispec/go.sum @@ -2,44 +2,223 @@ github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMz github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 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/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= +github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= +github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= +github.com/dprotaso/go-yit v0.0.0-20250909171706-0a81c39169bc h1:YxqE1wh+qGVXQFinuRq5lT77h6baDtBnAVh61LlXp1o= +github.com/dprotaso/go-yit v0.0.0-20250909171706-0a81c39169bc/go.mod h1:5NQLChvz4dnEIQ8WcHIFbZ1bp0GEUZHiBH+EpTZ4lBc= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= +github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonpointer v0.22.2 h1:JDQEe4B9j6K3tQ7HQQTZfjR59IURhjjLxet2FB4KHyg= +github.com/go-openapi/jsonpointer v0.22.2/go.mod h1:0lBbqeRsQ5lIanv3LHZBrmRGHLHcQoOXQnf88fHlGWo= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-openapi/swag v0.25.1 h1:6uwVsx+/OuvFVPqfQmOOPsqTcm5/GkBhNwLqIR916n8= +github.com/go-openapi/swag v0.25.1/go.mod h1:bzONdGlT0fkStgGPd3bhZf1MnuPkf2YAys6h+jZipOo= +github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= +github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +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.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 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/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY= github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g= +github.com/labstack/echo/v4 v4.13.4 h1:oTZZW+T3s9gAu5L8vmzihV7/lkXGZuITzTQkTEhcXEA= +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/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 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/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oapi-codegen/oapi-codegen/v2 v2.5.1 h1:5vHNY1uuPBRBWqB2Dp0G7YB03phxLQZupZTIZaeorjc= +github.com/oapi-codegen/oapi-codegen/v2 v2.5.1/go.mod h1:ro0npU1BWkcGpCgGD9QwPp44l5OIZ94tB3eabnT7DjQ= github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro= github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= +github.com/oapi-codegen/runtime v1.1.2 h1:P2+CubHq8fO4Q6fV1tqDBZHCwpVpvPg7oKiYzQgXIyI= +github.com/oapi-codegen/runtime v1.1.2/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= +github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= +github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= +github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= +github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= +github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= 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/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= +github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= +github.com/speakeasy-api/jsonpath v0.6.2 h1:Mys71yd6u8kuowNCR0gCVPlVAHCmKtoGXYoAtcEbqXQ= +github.com/speakeasy-api/jsonpath v0.6.2/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= +github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= +github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= +github.com/speakeasy-api/openapi-overlay v0.10.3 h1:70een4vwHyslIp796vM+ox6VISClhtXsCjrQNhxwvWs= +github.com/speakeasy-api/openapi-overlay v0.10.3/go.mod h1:RJjV0jbUHqXLS0/Mxv5XE7LAnJHqHw+01RDdpoGqiyY= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= 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/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= +github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= +github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= +github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.yaml.in/yaml/v4 v4.0.0-rc.3 h1:3h1fjsh1CTAPjW7q/EMe+C8shx5d8ctzZTrLcs/j8Go= +go.yaml.in/yaml/v4 v4.0.0-rc.3/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +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.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= +golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= +golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/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-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.25.1 h1:YeIyhd0M7gStYR9jb2IFXVVT+QJhgXu1ZECOuRwofh4= +golang.org/x/tools v0.25.1/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= +golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= +golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +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.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +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.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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= diff --git a/apispec/ocr-server/api.yml b/apispec/ocr-server/api.yml index a5446cb..bef0876 100644 --- a/apispec/ocr-server/api.yml +++ b/apispec/ocr-server/api.yml @@ -23,14 +23,18 @@ paths: application/json: schema: $ref: "#/components/schemas/OcrResponseDto" + 500: + description: failed + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponseDto" components: schemas: OcrRequestDto: type: object properties: - ImageId: - type: string Image: $ref: "#/components/schemas/ImageDto" @@ -46,9 +50,9 @@ components: type: object properties: ImageThumb: - $ref: "#/components/schemas/ThumbnailDto" - Image: - $ref: "#/components/schemas/ImageDto" + $ref: "#/components/schemas/ImageWithSizeDto" + ImageSource: + $ref: "#/components/schemas/ImageWithSizeDto" Embedding: $ref: "#/components/schemas/EmbeddingDto" ImageText: @@ -66,8 +70,12 @@ components: ModelName: type: string - ThumbnailDto: + ImageWithSizeDto: type: object + required: + - Image + - Width + - Height properties: Image: $ref: "#/components/schemas/ImageDto" @@ -78,8 +86,16 @@ components: ImageDto: type: object + required: + - ImageBase64 properties: - MimeType: - type: string ImageBase64: type: string + + ErrorResponseDto: + type: object + properties: + message: + type: string + error: + type: string \ No newline at end of file diff --git a/apispec/ocr-server/client/api.gen.go b/apispec/ocr-server/client/api.gen.go index 9eecfe8..6124ac6 100644 --- a/apispec/ocr-server/client/api.gen.go +++ b/apispec/ocr-server/client/api.gen.go @@ -1,6 +1,6 @@ // Package client provides primitives to interact with the openapi HTTP API. // -// Code generated by github.com/deepmap/oapi-codegen version v1.16.3 DO NOT EDIT. +// Code generated by github.com/deepmap/oapi-codegen/v2 version v2.2.0 DO NOT EDIT. package client import ( @@ -20,24 +20,35 @@ type EmbeddingDto struct { Data *[]float32 `json:"data,omitempty"` } +// ErrorResponseDto defines model for ErrorResponseDto. +type ErrorResponseDto struct { + Error *string `json:"error,omitempty"` + Message *string `json:"message,omitempty"` +} + // ImageDto defines model for ImageDto. type ImageDto struct { - ImageBase64 *string `json:"ImageBase64,omitempty"` - MimeType *string `json:"MimeType,omitempty"` + ImageBase64 string `json:"ImageBase64"` +} + +// ImageWithSizeDto defines model for ImageWithSizeDto. +type ImageWithSizeDto struct { + Height int `json:"Height"` + Image ImageDto `json:"Image"` + Width int `json:"Width"` } // OcrRequestDto defines model for OcrRequestDto. type OcrRequestDto struct { - Image *ImageDto `json:"Image,omitempty"` - ImageId *string `json:"ImageId,omitempty"` + Image *ImageDto `json:"Image,omitempty"` } // OcrResponseDto defines model for OcrResponseDto. type OcrResponseDto struct { - Embedding *EmbeddingDto `json:"Embedding,omitempty"` - Image *ImageDto `json:"Image,omitempty"` - ImageText *[]OcrResponseItem `json:"ImageText,omitempty"` - ImageThumb *ThumbnailDto `json:"ImageThumb,omitempty"` + Embedding *EmbeddingDto `json:"Embedding,omitempty"` + ImageSource *ImageWithSizeDto `json:"ImageSource,omitempty"` + ImageText *[]OcrResponseItem `json:"ImageText,omitempty"` + ImageThumb *ImageWithSizeDto `json:"ImageThumb,omitempty"` } // OcrResponseItem defines model for OcrResponseItem. @@ -46,13 +57,6 @@ type OcrResponseItem struct { Text *string `json:"Text,omitempty"` } -// ThumbnailDto defines model for ThumbnailDto. -type ThumbnailDto struct { - Height *int `json:"Height,omitempty"` - Image *ImageDto `json:"Image,omitempty"` - Width *int `json:"Width,omitempty"` -} - // PostApiV1OcrProcessJSONRequestBody defines body for PostApiV1OcrProcess for application/json ContentType. type PostApiV1OcrProcessJSONRequestBody = OcrRequestDto @@ -252,6 +256,7 @@ type PostApiV1OcrProcessResponse struct { Body []byte HTTPResponse *http.Response JSON200 *OcrResponseDto + JSON500 *ErrorResponseDto } // Status returns HTTPResponse.Status @@ -308,6 +313,13 @@ func ParsePostApiV1OcrProcessResponse(rsp *http.Response) (*PostApiV1OcrProcessR } response.JSON200 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest ErrorResponseDto + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + } return response, nil diff --git a/apispec/ocr-server/server/api.gen.go b/apispec/ocr-server/server/api.gen.go index e3048bd..f55341f 100644 --- a/apispec/ocr-server/server/api.gen.go +++ b/apispec/ocr-server/server/api.gen.go @@ -1,6 +1,6 @@ // Package server provides primitives to interact with the openapi HTTP API. // -// Code generated by github.com/deepmap/oapi-codegen version v1.16.3 DO NOT EDIT. +// Code generated by github.com/deepmap/oapi-codegen/v2 version v2.2.0 DO NOT EDIT. package server import ( @@ -19,24 +19,35 @@ type EmbeddingDto struct { Data *[]float32 `json:"data,omitempty"` } +// ErrorResponseDto defines model for ErrorResponseDto. +type ErrorResponseDto struct { + Error *string `json:"error,omitempty"` + Message *string `json:"message,omitempty"` +} + // ImageDto defines model for ImageDto. type ImageDto struct { - ImageBase64 *string `json:"ImageBase64,omitempty"` - MimeType *string `json:"MimeType,omitempty"` + ImageBase64 string `json:"ImageBase64"` +} + +// ImageWithSizeDto defines model for ImageWithSizeDto. +type ImageWithSizeDto struct { + Height int `json:"Height"` + Image ImageDto `json:"Image"` + Width int `json:"Width"` } // OcrRequestDto defines model for OcrRequestDto. type OcrRequestDto struct { - Image *ImageDto `json:"Image,omitempty"` - ImageId *string `json:"ImageId,omitempty"` + Image *ImageDto `json:"Image,omitempty"` } // OcrResponseDto defines model for OcrResponseDto. type OcrResponseDto struct { - Embedding *EmbeddingDto `json:"Embedding,omitempty"` - Image *ImageDto `json:"Image,omitempty"` - ImageText *[]OcrResponseItem `json:"ImageText,omitempty"` - ImageThumb *ThumbnailDto `json:"ImageThumb,omitempty"` + Embedding *EmbeddingDto `json:"Embedding,omitempty"` + ImageSource *ImageWithSizeDto `json:"ImageSource,omitempty"` + ImageText *[]OcrResponseItem `json:"ImageText,omitempty"` + ImageThumb *ImageWithSizeDto `json:"ImageThumb,omitempty"` } // OcrResponseItem defines model for OcrResponseItem. @@ -45,13 +56,6 @@ type OcrResponseItem struct { Text *string `json:"Text,omitempty"` } -// ThumbnailDto defines model for ThumbnailDto. -type ThumbnailDto struct { - Height *int `json:"Height,omitempty"` - Image *ImageDto `json:"Image,omitempty"` - Width *int `json:"Width,omitempty"` -} - // PostApiV1OcrProcessJSONRequestBody defines body for PostApiV1OcrProcess for application/json ContentType. type PostApiV1OcrProcessJSONRequestBody = OcrRequestDto @@ -125,6 +129,15 @@ func (response PostApiV1OcrProcess200JSONResponse) VisitPostApiV1OcrProcessRespo return json.NewEncoder(w).Encode(response) } +type PostApiV1OcrProcess500JSONResponse ErrorResponseDto + +func (response PostApiV1OcrProcess500JSONResponse) VisitPostApiV1OcrProcessResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(500) + + return json.NewEncoder(w).Encode(response) +} + // StrictServerInterface represents all server handlers. type StrictServerInterface interface { diff --git a/common/commonerror/api_error.go b/common/commonerror/api_error.go new file mode 100644 index 0000000..949a984 --- /dev/null +++ b/common/commonerror/api_error.go @@ -0,0 +1,13 @@ +package commonerror + +import "fmt" + +type ApiError struct { + StatusCode int + Code string + Message string +} + +func (err ApiError) Error() string { + return fmt.Sprintf("ApiError: %s", err.Message) +} diff --git a/common/commonhelper/util.go b/common/commonhelper/util.go new file mode 100644 index 0000000..dd05f48 --- /dev/null +++ b/common/commonhelper/util.go @@ -0,0 +1,3 @@ +package commonhelper + +func Addr[T any](v T) *T { return &v } diff --git a/common/commonmiddleware/LoggingMiddleware.go b/common/commonmiddleware/LoggingMiddleware.go index 60a4780..76f375e 100644 --- a/common/commonmiddleware/LoggingMiddleware.go +++ b/common/commonmiddleware/LoggingMiddleware.go @@ -3,12 +3,13 @@ package commonmiddleware import ( "log" - "github.com/gdexlab/go-render/render" echoServer "github.com/labstack/echo/v4" oapiEcho "github.com/oapi-codegen/runtime/strictmiddleware/echo" ) -func NewLoggingMiddleware() oapiEcho.StrictEchoMiddlewareFunc { +type LoggingMiddlewareFunc oapiEcho.StrictEchoMiddlewareFunc + +func NewLoggingMiddleware() LoggingMiddlewareFunc { return func(nextChain oapiEcho.StrictEchoHandlerFunc, operationID string) oapiEcho.StrictEchoHandlerFunc { return func(ctx echoServer.Context, request interface{}) (interface{}, error) { method := ctx.Request().Method @@ -19,7 +20,7 @@ func NewLoggingMiddleware() oapiEcho.StrictEchoMiddlewareFunc { response, err := nextChain(ctx, request) if err != nil { - log.Printf("Error [%s] ! %s", operationID, render.Render(err)) + log.Printf("Error [%s] ! %s", operationID, err) } else { status := ctx.Response().Status diff --git a/go.work b/go.work index 6e15657..0899db4 100644 --- a/go.work +++ b/go.work @@ -1,4 +1,4 @@ -go 1.23.2 +go 1.24.10 use ( ./apispec diff --git a/go.work.sum b/go.work.sum index 13dbc74..7cbb879 100644 --- a/go.work.sum +++ b/go.work.sum @@ -484,12 +484,16 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.49 github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.49.0/go.mod h1:6fTWu4m3jocfUZLYF5KsZC1TUfRvEjs7lM4crme/irw= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.49.0 h1:GYUJLfvd++4DMuMhCFLgLXvFwofIxh/qOwoGuS/LTew= github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.49.0/go.mod h1:wRbFgBQUVm1YXrvWKofAEmq9HNJTDphbAaJSSX01KUI= +github.com/Joker/hpp v1.0.0 h1:65+iuJYdRXv/XyN62C1uEmmOx3432rNG/rKlX6V7Kkc= +github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Joker/jade v1.1.3 h1:Qbeh12Vq6BxURXT1qZBRHsDxeURB8ztcL6f3EXSGeHk= github.com/Joker/jade v1.1.3/go.mod h1:T+2WLyt7VH6Lp0TRxQrUYEs64nRc83wkMQrfeIQKduM= github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/RaveNoX/go-jsoncommentstrip v1.0.0 h1:t527LHHE3HmiHrq74QMpNPZpGCIJzTx+apLkMKt4HC0= github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 h1:KkH3I3sJuOLP3TjA/dfr4NAY8bghDwnXiU7cTKxQqo0= github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06/go.mod h1:7erjKLwalezA0k99cWs5L11HWOAPNjdUZ6RxH1BXbbM= +github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= @@ -499,7 +503,11 @@ github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+ github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bmatcuk/doublestar v1.1.1 h1:YroD6BJCZBYx06yYFEWvUuKVWQn3vLLQAVmDmvTSaiQ= +github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= +github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= github.com/bytedance/sonic v1.10.0-rc3 h1:uNSnscRapXTwUgTyOF0GVljYD08p9X/Lbr9MweSV3V0= github.com/bytedance/sonic v1.10.0-rc3/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= @@ -508,6 +516,10 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927 h1:SKI1/fuSdodxmNNyVBR8d7X/HuLnRpvvFO0AgyQk764= +github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U= +github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= +github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA= github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo= @@ -528,8 +540,16 @@ github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzA github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= +github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= +github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= +github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de h1:t0UHb5vdojIDUqktM6+xJAfScFBsVpXZmqC9dsgJmeA= +github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/djherbis/atime v1.1.0 h1:rgwVbP/5by8BvvjBNrbh64Qz33idKT3pSnMSJsxhi0g= +github.com/djherbis/atime v1.1.0/go.mod h1:28OF6Y8s3NQWwacXc5eZTsEsiMzp7LF8MbXE+XJPdBE= github.com/envoyproxy/go-control-plane v0.12.0/go.mod h1:ZBTaoJ23lqITozF0M6G4/IragXCQKCnYbmlmtHvwRG0= github.com/envoyproxy/go-control-plane v0.13.0/go.mod h1:GRaKG3dwvFoTg4nj7aXdZnvMg4d7nvT/wl9WgVXn3Q8= github.com/envoyproxy/go-control-plane v0.13.1 h1:vPfJZCkob6yTMEgS+0TwfTUfbHjfy/6vOJ8hUWX/uXE= @@ -541,12 +561,14 @@ github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6 github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4= github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw= github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/getkin/kin-openapi v0.127.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= @@ -557,16 +579,47 @@ github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SU github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-openapi/swag/cmdutils v0.25.1 h1:nDke3nAFDArAa631aitksFGj2omusks88GF1VwdYqPY= +github.com/go-openapi/swag/cmdutils v0.25.1/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.1 h1:+9o8YUg6QuqqBM5X6rYL/p1dpWeZRhoIt9x7CCP+he0= +github.com/go-openapi/swag/conv v0.25.1/go.mod h1:Z1mFEGPfyIKPu0806khI3zF+/EUXde+fdeksUl2NiDs= +github.com/go-openapi/swag/fileutils v0.25.1 h1:rSRXapjQequt7kqalKXdcpIegIShhTPXx7yw0kek2uU= +github.com/go-openapi/swag/fileutils v0.25.1/go.mod h1:+NXtt5xNZZqmpIpjqcujqojGFek9/w55b3ecmOdtg8M= +github.com/go-openapi/swag/jsonutils v0.25.1 h1:AihLHaD0brrkJoMqEZOBNzTLnk81Kg9cWr+SPtxtgl8= +github.com/go-openapi/swag/jsonutils v0.25.1/go.mod h1:JpEkAjxQXpiaHmRO04N1zE4qbUEg3b7Udll7AMGTNOo= +github.com/go-openapi/swag/loading v0.25.1 h1:6OruqzjWoJyanZOim58iG2vj934TysYVptyaoXS24kw= +github.com/go-openapi/swag/loading v0.25.1/go.mod h1:xoIe2EG32NOYYbqxvXgPzne989bWvSNoWoyQVWEZicc= +github.com/go-openapi/swag/mangling v0.25.1 h1:XzILnLzhZPZNtmxKaz/2xIGPQsBsvmCjrJOWGNz/ync= +github.com/go-openapi/swag/mangling v0.25.1/go.mod h1:CdiMQ6pnfAgyQGSOIYnZkXvqhnnwOn997uXZMAd/7mQ= +github.com/go-openapi/swag/netutils v0.25.1 h1:2wFLYahe40tDUHfKT1GRC4rfa5T1B4GWZ+msEFA4Fl4= +github.com/go-openapi/swag/netutils v0.25.1/go.mod h1:CAkkvqnUJX8NV96tNhEQvKz8SQo2KF0f7LleiJwIeRE= +github.com/go-openapi/swag/stringutils v0.25.1 h1:Xasqgjvk30eUe8VKdmyzKtjkVjeiXx1Iz0zDfMNpPbw= +github.com/go-openapi/swag/stringutils v0.25.1/go.mod h1:JLdSAq5169HaiDUbTvArA2yQxmgn4D6h4A+4HqVvAYg= +github.com/go-openapi/swag/typeutils v0.25.1 h1:rD/9HsEQieewNt6/k+JBwkxuAHktFtH3I3ysiFZqukA= +github.com/go-openapi/swag/typeutils v0.25.1/go.mod h1:9McMC/oCdS4BKwk2shEB7x17P6HmMmA6dQRtAkSnNb8= +github.com/go-openapi/swag/yamlutils v0.25.1 h1:mry5ez8joJwzvMbaTGLhw8pXUnhDK91oSJLDPF1bmGk= +github.com/go-openapi/swag/yamlutils v0.25.1/go.mod h1:cm9ywbzncy3y6uPm/97ysW8+wZ09qsks+9RS8fLWKqg= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= +github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= +github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= +github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.3.0 h1:sbeU3Y4Qzlb+MOzIe6mQGf7QR4Hkv6ZD0qhGkBFL2O0= +github.com/gobwas/ws v1.3.0/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= @@ -580,18 +633,24 @@ github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386/go.mod h1:JDGc github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= github.com/google/go-pkcs11 v0.3.0 h1:PVRnTgtArZ3QQqTGtbtjtnIkzl2iY2kt24yqbrf7td8= github.com/google/go-pkcs11 v0.3.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/googleapis/gax-go/v2 v2.12.1/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= @@ -600,7 +659,12 @@ github.com/googleapis/google-cloud-go-testing v0.0.0-20210719221736-1c9a4c676720 github.com/googleapis/google-cloud-go-testing v0.0.0-20210719221736-1c9a4c676720/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= github.com/hashicorp/consul/api v1.28.2 h1:mXfkRHrpHN4YY3RqL09nXU1eHKLNiuAN4kHvDQ16k/8= @@ -621,16 +685,21 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hybridgroup/mjpeg v0.0.0-20140228234708-4680f319790e/go.mod h1:eagM805MRKrioHYuU7iKLUyFPVKqVV6um5DAvCkUtXs= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 h1:mV02weKRL81bEnm8A0HT1/CAelMQDBuQIfLw8n+d6xI= +github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= +github.com/iris-contrib/go.uuid v2.0.0+incompatible h1:XZubAYg61/JwnJNbZilGjf3b3pB80+OQg2qf6c8BfWE= +github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= +github.com/iris-contrib/httpexpect/v2 v2.15.2 h1:T9THsdP1woyAqKHwjkEsbCnMefsAFvk8iJJKokcJ3Go= +github.com/iris-contrib/httpexpect/v2 v2.15.2/go.mod h1:JLDgIqnFy5loDSUv1OA2j0mb6p/rDhiCqigP22Uq9xE= github.com/iris-contrib/schema v0.0.6 h1:CPSBLyx2e91H2yJzPuhGuifVRnZBBJ3pCOMbOvPZaTw= github.com/iris-contrib/schema v0.0.6/go.mod h1:iYszG0IOsuIsfzjymw1kMzTL8YQcCWlm65f3wX8J5iA= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= @@ -641,6 +710,10 @@ github.com/kataras/golog v0.1.9 h1:vLvSDpP7kihFGKFAvBSofYo7qZNULYSHOH2D7rPTKJk= github.com/kataras/golog v0.1.9/go.mod h1:jlpk/bOaYCyqDqH18pgDHdaJab72yBE6i0O3s30hpWY= github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9 h1:Vx8kDVhO2qepK8w44lBtp+RzN3ld743i+LYPzODJSpQ= github.com/kataras/iris/v12 v12.2.6-0.20230908161203-24ba4e8933b9/go.mod h1:ldkoR3iXABBeqlTibQ3MYaviA1oSlPvim6f55biwBh4= +github.com/kataras/jwt v0.1.10 h1:GBXOF9RVInDPhCFBiDumRG9Tt27l7ugLeLo8HL5SeKQ= +github.com/kataras/jwt v0.1.10/go.mod h1:xkimAtDhU/aGlQqjwvgtg+VyuPwMiyZHaY8LJRh0mYo= +github.com/kataras/neffos v0.0.22 h1:3M4lHrUl//2OKmS9t9z3AKIZqwha6ABeA6WoF03HEv8= +github.com/kataras/neffos v0.0.22/go.mod h1:IIJZcUDvwBxJGlDj942dqQgyznVKYDti91f8Ez+RRxE= github.com/kataras/pio v0.0.12 h1:o52SfVYauS3J5X08fNjlGS5arXHjW/ItLkyLcKjoH6w= github.com/kataras/pio v0.0.12/go.mod h1:ODK/8XBhhQ5WqrAhKy+9lTPS7sBf6O3KcLhc9klfRcY= github.com/kataras/sitemap v0.0.6 h1:w71CRMMKYMJh6LR2wTgnk5hSgjVNB9KL60n5e2KHvLY= @@ -648,26 +721,42 @@ github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIR github.com/kataras/tunnel v0.0.4 h1:sCAqWuJV7nPzGrlb0os3j49lk2JhILT0rID38NHNLpA= github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/knz/go-libedit v1.10.1 h1:0pHpWtx9vcvC0xGZqEQlQdfSQs7WRlAjuPvk3fOZDCo= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= +github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8= +github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lyft/protoc-gen-star/v2 v2.0.3/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= github.com/mailgun/raymond/v2 v2.0.48 h1:5dmlB680ZkFG2RN/0lvTAghrSxIESeu9/2aeDqACtjw= github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2 h1:JAEbJn3j/FrhdWA9jW8B5ajsLIjeuEHLi8xE4fk997o= +github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs= +github.com/mediocregopher/radix/v3 v3.8.1 h1:rOkHflVuulFKlwsLY01/M2cM2tWCjDoETcMqKbAWu1M= +github.com/mediocregopher/radix/v3 v3.8.1/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg= github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE= +github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= +github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/nats-io/jwt/v2 v2.5.0 h1:WQQ40AAlqqfx+f6ku+i0pOVm+ASirD4fUh+oQsiE9Ak= +github.com/nats-io/jwt/v2 v2.5.0/go.mod h1:24BeQtRwxRV8ruvC4CojXlx/WQ/VjuwlYiH+vu/+ibI= github.com/nats-io/nats.go v1.34.0 h1:fnxnPCNiwIG5w08rlMcEKTUw4AV/nKyGCOJE8TdhSPk= github.com/nats-io/nats.go v1.34.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8= github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI= @@ -675,25 +764,23 @@ github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDm github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oapi-codegen/oapi-codegen/v2 v2.4.1/go.mod h1:N5+lY1tiTDV3V1BeHtOxeWXHoPVeApvsvjJqegfoaz8= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= +github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= +github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= +github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -703,31 +790,50 @@ github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/redis/go-redis/v9 v9.1.0 h1:137FnGdk+EQdCbye1FW+qOEcY5S+SpY9T0NiuqvtfMY= +github.com/redis/go-redis/v9 v9.1.0/go.mod h1:urWj3He21Dj5k4TK1y59xH8Uj6ATueP8AH1cY3lZl4c= github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/crypt v0.19.0 h1:WMyLTjHBo64UvNcWqpzY3pbZTYgnemZU8FBZigKc42E= github.com/sagikazarmark/crypt v0.19.0/go.mod h1:c6vimRziqqERhtSe0MhIvzE1w54FrCHtrXb5NH/ja78= +github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo= +github.com/sanity-io/litter v1.5.5/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U= github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiyyjYS17cCYRqP13/SHk= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shirou/gopsutil/v3 v3.23.8 h1:xnATPiybo6GgdRoC4YoGnxXZFRc3dqQTGi73oLvvBrE= +github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ= +github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= github.com/speakeasy-api/openapi-overlay v0.9.0/go.mod h1:f5FloQrHA7MsxYg9djzMD5h6dxrHjVVByWKh7an8TRc= github.com/spf13/afero v1.4.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad h1:fiWzISvDn0Csy5H0iwgAuJGQTUpVfEMJJd4nRFXogbc= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subeshb1/wasm-go-image-to-ascii v0.0.0-20200725121413-d828986df340/go.mod h1:A2X7CsJFb8jEdYaWeCbs2HydXC69J4Iaw4DM+bly5iw= github.com/tdewolff/minify/v2 v2.12.9 h1:dvn5MtmuQ/DFMwqf5j8QhEVpPX6fi3WGImhv8RUB4zA= github.com/tdewolff/minify/v2 v2.12.9/go.mod h1:qOqdlDfL+7v0/fyymB+OP497nIxJYSvX4MQWA8OoiXU= github.com/tdewolff/parse/v2 v2.6.8 h1:mhNZXYCx//xG7Yq2e/kVLNZw4YfYmeHbhx+Zc0OvFMA= github.com/tdewolff/parse/v2 v2.6.8/go.mod h1:XHDhaU6IBgsryfdnpzUXBlT6leW/l25yrFBTEb4eIyM= +github.com/tdewolff/test v1.0.9 h1:SswqJCmeN4B+9gEAi/5uqT0qpi1y2/2O47V/1hhGZT0= +github.com/tdewolff/test v1.0.9/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= @@ -736,16 +842,32 @@ github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9 github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= github.com/yosssi/ace v0.0.5 h1:tUkIP/BLdKqrlrPwcmH0shwEEhTRHoGnc1wFIWmaBUA= github.com/yosssi/ace v0.0.5/go.mod h1:ALfIzm2vT7t5ZE7uoIZqF3TQ7SAOyupFZnkrF5id+K0= github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= +github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= +github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= +github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= go.einride.tech/aip v0.66.0/go.mod h1:qAhMsfT7plxBX+Oy7Huol6YUvZ0ZzdUz26yZsQwfl1M= +go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= +go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.etcd.io/etcd/api/v3 v3.5.12 h1:W4sw5ZoU2Juc9gBWuLk5U6fHfNVyY1WC5g9uiXZio/c= go.etcd.io/etcd/api/v3 v3.5.12/go.mod h1:Ot+o0SWSyT6uHhA56al1oCED0JImsRiU9Dc26+C2a+4= go.etcd.io/etcd/client/pkg/v3 v3.5.12 h1:EYDL6pWwyOsylrQyLp2w+HkQ46ATiOvoEdMarindU2A= @@ -786,63 +908,85 @@ go.opentelemetry.io/proto/otlp v0.7.0 h1:rwOQPCuKAKmwGKq2aVNnYIibI6wnV7EvzgfTCzc go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc= golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= +golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= +golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457 h1:zf5N6UOrA487eEFacMePxjXAJctxKmyjKUsjA11Uzuk= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= +golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54 h1:E2/AqCUMZGgd73TQkxUMcMla25GB9i/5HOdLr+uH7Vo= +golang.org/x/telemetry v0.0.0-20251111182119-bc8e575c7b54/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= +golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= +golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= @@ -886,20 +1030,21 @@ google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFL google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= google.golang.org/grpc v1.67.3 h1:OgPcDAFKHnH8X3O4WcO4XUc8GRDeKsKReqbQtiCj7N8= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8= +moul.io/http2curl/v2 v2.3.0 h1:9r3JfDzWPcbIklMOs2TnIFzDYvfAZvjeavG6EzP7jYs= +moul.io/http2curl/v2 v2.3.0/go.mod h1:RW4hyBjTWSYDOxapodpNEtX0g5Eb16sxklBqmd2RHcE= +nullprogram.com/x/optparse v1.0.0 h1:xGFgVi5ZaWOnYdac2foDT3vg0ZZC9ErXFV57mr4OHrI= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= +rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY= rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= diff --git a/ocr-service/src/entity/Entity.go b/ocr-service/src/entity/Entity.go index 019e088..f87d666 100644 --- a/ocr-service/src/entity/Entity.go +++ b/ocr-service/src/entity/Entity.go @@ -1,11 +1,7 @@ package entity type Image struct { - MimeType string - Data *[]byte -} - -type ImageSizes struct { + Data *[]byte Width int Height int } diff --git a/ocr-service/src/go.mod b/ocr-service/src/go.mod index 317e235..5e20231 100644 --- a/ocr-service/src/go.mod +++ b/ocr-service/src/go.mod @@ -31,6 +31,7 @@ require ( github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect diff --git a/ocr-service/src/go.sum b/ocr-service/src/go.sum index 60c452f..7cb9c8b 100644 --- a/ocr-service/src/go.sum +++ b/ocr-service/src/go.sum @@ -255,6 +255,8 @@ github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmt github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/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= diff --git a/ocr-service/src/main.go b/ocr-service/src/main.go index fffdaff..d157a4a 100644 --- a/ocr-service/src/main.go +++ b/ocr-service/src/main.go @@ -21,6 +21,7 @@ func main() { fx.Provide(conf.NewImageConverterConfig), fx.Provide(conf.NewImageEmbeddingConfig), fx.Provide(api.NewApiHandler), + fx.Provide(commonmiddleware.NewLoggingMiddleware), fx.Provide(service.NewImageEmbeddingExtractor), fx.Provide(service.NewVisionImageClient), fx.Provide(service.NewOcrProcessor), @@ -30,17 +31,22 @@ func main() { ).Run() } -func Startup(handler server.StrictServerInterface, config *commonconfig.ServerConfig) { +func Startup(handler server.StrictServerInterface, + config *commonconfig.ServerConfig, + loggingMiddleware commonmiddleware.LoggingMiddlewareFunc) { srv := echo.New() + srv.Debug = true server.RegisterHandlers( srv, server.NewStrictHandler( handler, []oapiEcho.StrictEchoMiddlewareFunc{ - commonmiddleware.NewLoggingMiddleware(), + oapiEcho.StrictEchoMiddlewareFunc(loggingMiddleware), }), ) - - srv.Start(config.ListenAddress) + err := srv.Start(config.ListenAddress) + if err != nil { + panic(err) + } } diff --git a/ocr-service/src/service/ImageConvertor.go b/ocr-service/src/service/ImageConvertor.go index bd94016..520ac03 100644 --- a/ocr-service/src/service/ImageConvertor.go +++ b/ocr-service/src/service/ImageConvertor.go @@ -4,56 +4,72 @@ import ( "context" "github.com/h2non/bimg" + "github.com/pkg/errors" "mine.local/ocr-gallery/ocr-server/conf" "mine.local/ocr-gallery/ocr-server/entity" ) type ImageConveter interface { - ConvertImage(ctx context.Context, image *entity.Image) (*entity.Image, error) - MakeThumb(ctx context.Context, image *entity.Image) (*entity.Image, *entity.ImageSizes, error) + MakeEntity(ctx context.Context, data *[]byte) (*entity.Image, error) + ConvertImageJPEG(ctx context.Context, image *entity.Image) (*entity.Image, error) + MakeThumb(ctx context.Context, image *entity.Image) (*entity.Image, error) } type ImageConveterImpl struct { config *conf.ImageConverterConfig } -// ConvertImage implements ImageConveter. -func (i *ImageConveterImpl) ConvertImage(ctx context.Context, image *entity.Image) (*entity.Image, error) { +// ConvertImageJPEG implements ImageConveter. +func (i *ImageConveterImpl) ConvertImageJPEG(ctx context.Context, image *entity.Image) (*entity.Image, error) { img := bimg.NewImage(*image.Data) + size, err := img.Size() + if err != nil { + return nil, errors.Wrap(err, "Image Size() failed") + } + bytesData, err := img.Convert(bimg.JPEG) if err != nil { - return nil, err + return nil, errors.Wrap(err, "Image Convert() to JPEG failed") } - retval := new(entity.Image) - retval.MimeType = "image/jpeg" - retval.Data = &bytesData - return retval, nil + retImage := new(entity.Image) + retImage.Data = &bytesData + retImage.Width = size.Width + retImage.Height = size.Height + + return retImage, nil } // MakeThumb implements ImageConveter. -func (i *ImageConveterImpl) MakeThumb(ctx context.Context, image *entity.Image) (*entity.Image, *entity.ImageSizes, error) { +func (i *ImageConveterImpl) MakeThumb(ctx context.Context, image *entity.Image) (*entity.Image, error) { img := bimg.NewImage(*image.Data) + newWidth := i.config.ThumbSize + newHeight := int(float64(i.config.ThumbSize) / float64(image.Width) * float64(image.Height)) - size, err := img.Size() + bytesData, err := img.Resize(newWidth, newHeight) if err != nil { - return nil, nil, err + return nil, errors.Wrap(err, "Image Resize() failed") } - sizes := new(entity.ImageSizes) - - sizes.Width = i.config.ThumbSize - sizes.Height = int(float64(i.config.ThumbSize) / float64(size.Width) * float64(size.Height)) + return &entity.Image{ + Data: &bytesData, + Width: newWidth, + Height: newHeight, + }, nil +} - bytesData, err := img.Resize(size.Width, size.Height) +func (i *ImageConveterImpl) MakeEntity(ctx context.Context, data *[]byte) (*entity.Image, error) { + img := bimg.NewImage(*data) + size, err := img.Size() if err != nil { - return nil, nil, err + return nil, errors.Wrap(err, "Image Size() failed") } - retval := new(entity.Image) - retval.MimeType = image.MimeType - retval.Data = &bytesData - return retval, sizes, nil + return &entity.Image{ + Data: data, + Width: size.Width, + Height: size.Height, + }, nil } func NewImageConverter(config *conf.ImageConverterConfig) (ImageConveter, error) { diff --git a/ocr-service/src/service/ImageService.go b/ocr-service/src/service/ImageService.go index 3d7baee..0940a62 100644 --- a/ocr-service/src/service/ImageService.go +++ b/ocr-service/src/service/ImageService.go @@ -5,9 +5,12 @@ import ( "context" "encoding/base64" "io" + "net/http" "strings" + "github.com/pkg/errors" "mine.local/ocr-gallery/apispec/ocr-server/server" + "mine.local/ocr-gallery/common/commonerror" "mine.local/ocr-gallery/ocr-server/entity" ) @@ -21,46 +24,72 @@ type ImageServiceImpl struct { comarer ImageEmbeddingExtractor } +func (i *ImageServiceImpl) validateProcessImage(ctx context.Context, image server.PostApiV1OcrProcessRequestObject) error { + if image.Body == nil || image.Body.Image == nil || image.Body.Image.ImageBase64 == "" { + return commonerror.ApiError{ + StatusCode: http.StatusBadRequest, + Message: "No request body or image", + } + } + return nil +} + // ProcessImage implements ImageService. func (i *ImageServiceImpl) ProcessImage(ctx context.Context, image server.PostApiV1OcrProcessRequestObject) (server.PostApiV1OcrProcessResponseObject, error) { - imageEnt := imageDtoToEntity(image.Body.Image) - imageEnt, err := i.conv.ConvertImage(ctx, imageEnt) + err := i.validateProcessImage(ctx, image) if err != nil { return nil, err } - imageThumbEnt, imgThumbSizes, err := i.conv.MakeThumb(ctx, imageEnt) + imageEntIncoming, err := i.convertImageDto(ctx, image.Body.Image) if err != nil { - return nil, err + return nil, errors.Wrap(err, "convertImageDto failed") + } + + imageEnt, err := i.conv.ConvertImageJPEG(ctx, imageEntIncoming) + if err != nil { + return nil, errors.Wrap(err, "ConvertImageJPEG failed: ") + } + + imageThumbEnt, err := i.conv.MakeThumb(ctx, imageEnt) + if err != nil { + return nil, errors.Wrap(err, "MakeThumb failed") } processorName := i.ocr.GetName() stringData, err := i.ocr.DoOcr(ctx, imageEnt) if err != nil { - return nil, err + return nil, errors.Wrap(err, "DoOcr failed") } embedding, err := i.comarer.GetImageEmbeddingV1(ctx, imageEnt) if err != nil { - return nil, err + return nil, errors.Wrap(err, "GetImageEmbeddingV1 failed") } - response := new(server.PostApiV1OcrProcess200JSONResponse) - - response.Image = imageEntityToDto(imageEnt) - response.ImageThumb = new(server.ThumbnailDto) - response.ImageThumb.Image = imageEntityToDto(imageThumbEnt) - response.ImageThumb.Height = &imgThumbSizes.Height - response.ImageThumb.Width = &imgThumbSizes.Width - response.ImageText = &[]server.OcrResponseItem{ - { - ProcessorKey: &processorName, - Text: &stringData, - }, + resultImgSource, err := i.imageEntityToDto(imageEnt) + if err != nil { + return nil, errors.Wrap(err, "imageEntityToDto for source image failed") } - response.Embedding = &server.EmbeddingDto{ - ModelName: &embedding.Model, - Data: &embedding.Data, + + resultImgThumb, err := i.imageEntityToDto(imageThumbEnt) + if err != nil { + return nil, errors.Wrap(err, "imageEntityToDto for thumb image failed") + } + + response := &server.PostApiV1OcrProcess200JSONResponse{ + ImageSource: resultImgSource, + ImageThumb: resultImgThumb, + ImageText: &[]server.OcrResponseItem{ + { + ProcessorKey: &processorName, + Text: &stringData, + }, + }, + Embedding: &server.EmbeddingDto{ + ModelName: &embedding.Model, + Data: &embedding.Data, + }, } return response, nil } @@ -73,29 +102,40 @@ func pixels(uintArr []uint16) []int { return intArr } -func imageDtoToEntity(dto *server.ImageDto) *entity.Image { - decoder := base64.NewDecoder(base64.RawStdEncoding, strings.NewReader(*dto.ImageBase64)) - data, _ := io.ReadAll(decoder) +func (i *ImageServiceImpl) convertImageDto(ctx context.Context, dto *server.ImageDto) (*entity.Image, error) { + decoder := base64.NewDecoder(base64.RawStdEncoding, strings.NewReader(dto.ImageBase64)) + data, err := io.ReadAll(decoder) + if err != nil { + return nil, errors.Wrap(err, "image base64 decoding failed") + } + + img, err := i.conv.MakeEntity(ctx, &data) + if err != nil { + return nil, errors.Wrap(err, "MakeEntity failed") + } - retval := new(entity.Image) - retval.Data = &data - retval.MimeType = *dto.MimeType - return retval + return img, nil } -func imageEntityToDto(entity *entity.Image) *server.ImageDto { +func (i *ImageServiceImpl) imageEntityToDto(entity *entity.Image) (*server.ImageWithSizeDto, error) { buff := bytes.NewBufferString("") encoder := base64.NewEncoder(base64.RawStdEncoding, buff) defer encoder.Close() - encoder.Write(*entity.Data) + _, err := encoder.Write(*entity.Data) + if err != nil { + return nil, errors.Wrap(err, "image base64 encoding failed") + } encoder.Close() data := buff.String() - retval := new(server.ImageDto) - retval.ImageBase64 = &data - retval.MimeType = &entity.MimeType - return retval + return &server.ImageWithSizeDto{ + Image: server.ImageDto{ + ImageBase64: data, + }, + Width: entity.Width, + Height: entity.Height, + }, nil } func NewImageService(ocr OcrProcessor, conv ImageConveter, comp ImageEmbeddingExtractor) (ImageService, error) { diff --git a/storage-service/src/service/ElasticMetadataStorageServiceImpl.go b/storage-service/src/service/ElasticMetadataStorageServiceImpl.go index a7b53be..4c11bb8 100644 --- a/storage-service/src/service/ElasticMetadataStorageServiceImpl.go +++ b/storage-service/src/service/ElasticMetadataStorageServiceImpl.go @@ -499,8 +499,6 @@ func unmarhalSourceDocument(result json.RawMessage) (*entity.ElasticImageMetaDat return &document, err } -func addr[T any](v T) *T { return &v } - func NewElasticMetadataStorage( config *conf.MetadataStorageConfig, validate *validator.Validate, From 62ec03f9edfd5ba9d714ef592eb4d6c070225ff5 Mon Sep 17 00:00:00 2001 From: weoses Date: Sun, 16 Nov 2025 20:02:25 +0300 Subject: [PATCH 02/10] ocrService: request example --- ocr-service/request_example/example.md | 5 +++++ .../request_example/request.ocr.process.test-image.json | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 ocr-service/request_example/example.md create mode 100644 ocr-service/request_example/request.ocr.process.test-image.json diff --git a/ocr-service/request_example/example.md b/ocr-service/request_example/example.md new file mode 100644 index 0000000..b2987b1 --- /dev/null +++ b/ocr-service/request_example/example.md @@ -0,0 +1,5 @@ +Process lorem-ipsum png + +```bash + curl http://localhost:7002/api/v1/ocr/process -d @request.ocr.process.test-image.json -X POST -H "Content-Type: application/json" +``` \ No newline at end of file diff --git a/ocr-service/request_example/request.ocr.process.test-image.json b/ocr-service/request_example/request.ocr.process.test-image.json new file mode 100644 index 0000000..d7f3cec --- /dev/null +++ b/ocr-service/request_example/request.ocr.process.test-image.json @@ -0,0 +1,5 @@ +{ + "Image": { + "ImageBase64": "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" + } +} \ No newline at end of file From d28667ea4ba04eb04e1066df3c67bb1cbadab052 Mon Sep 17 00:00:00 2001 From: weoses Date: Sun, 16 Nov 2025 20:02:25 +0300 Subject: [PATCH 03/10] storage service: - update golang version - query examples - exceptions - specs --- apispec/meme-storage/api.yml | 67 +-- apispec/meme-storage/server/api.gen.go | 65 +-- common/go.mod | 2 +- storage-service/config.yaml | 4 +- storage-service/request_example/example.md | 31 + .../request.storage.create.test-image.json | 3 + storage-service/src/entity/entity.go | 13 +- storage-service/src/helper/helper.go | 24 +- storage-service/src/main.go | 5 +- .../src/service/ApiHandlerService.go | 302 +++++++--- .../ElasticMetadataStorageServiceImpl.go | 544 ++++++++++-------- .../src/service/ImageStorageService.go | 22 - .../src/service/MetadataStorageService.go | 33 -- storage-service/src/service/OcrService.go | 61 +- .../src/service/S3ImageStorageService.go | 45 +- testenv/docker-compose.yml | 15 +- 16 files changed, 671 insertions(+), 565 deletions(-) create mode 100644 storage-service/request_example/example.md create mode 100644 storage-service/request_example/request.storage.create.test-image.json delete mode 100644 storage-service/src/service/ImageStorageService.go delete mode 100644 storage-service/src/service/MetadataStorageService.go diff --git a/apispec/meme-storage/api.yml b/apispec/meme-storage/api.yml index e8e85dc..6eef84c 100644 --- a/apispec/meme-storage/api.yml +++ b/apispec/meme-storage/api.yml @@ -3,7 +3,7 @@ info: description: '' version: "1.0.0" title: 'Meme-server' - + paths: /api/v1/accounts/{AccountId}/check-duplicates: post: @@ -36,7 +36,7 @@ paths: get: parameters: - $ref: "#/components/parameters/AccountId" - - $ref: "#/components/parameters/MemeQuery" + - $ref: "#/components/parameters/Query" - $ref: "#/components/parameters/SearchAfterId" - $ref: "#/components/parameters/PageSize" operationId: "SearchMeme" @@ -48,7 +48,7 @@ paths: schema: type: array items: - $ref: "#/components/schemas/SearchMemeDto" + $ref: "#/components/schemas/SearchMemeResponseItemDto" post: operationId: "CreateMeme" parameters: @@ -57,7 +57,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/ImageDto" + $ref: "#/components/schemas/CreateImageRequestDto" responses: 200: description: ok @@ -82,7 +82,7 @@ paths: $ref: "#/components/schemas/ImageUrlDto" /api/v1/accounts/{AccountId}/meme/{MemeId}: - get: + delete: parameters: - $ref: "#/components/parameters/AccountId" - $ref: "#/components/parameters/MemeId" @@ -104,12 +104,12 @@ paths: application/json: schema: $ref: "#/components/schemas/ImageUrlDto" -components: +components: parameters: - MemeQuery: + Query: in: query required: true - name: MemeQuery + name: Query schema: type: string SearchAfterId: @@ -125,7 +125,6 @@ components: name: PageSize schema: type: integer - MemeId: in: path required: true @@ -142,24 +141,8 @@ components: type: string format: uuid - schemas: - ImageUrlDto: - type: object - properties: - Url: - type: string - - SearchMemeThumb: - type: object - properties: - ThumbUrl: - type: string - ThumbWidth: - type: integer - ThumbHeight: - type: integer - - SearchMemeDto: + schemas: + SearchMemeResponseItemDto: type: object properties: Id: @@ -170,14 +153,10 @@ components: format: int64 OcrResult: type: string - OcrResultHighlight: - type: array - items: - type: string - ImageUrl: - type: string + Image: + $ref: "#/components/schemas/ImageUrlDto" Thumbnail: - $ref: "#/components/schemas/SearchMemeThumb" + $ref: "#/components/schemas/ImageUrlDto" Hash: type: string @@ -193,15 +172,27 @@ components: type: string DuplicateStatus: $ref: "#/components/schemas/DuplicateStatus" - - ImageDto: + + CreateImageRequestDto: type: object + required: + - ImageBase64 properties: - MimeType: - type: string ImageBase64: type: string + ImageUrlDto: + type: object + required: + - Url + properties: + Url: + type: string + Width: + type: integer + Height: + type: integer + DuplicateStatus: type: string enum: diff --git a/apispec/meme-storage/server/api.gen.go b/apispec/meme-storage/server/api.gen.go index d56ac65..af3eaf5 100644 --- a/apispec/meme-storage/server/api.gen.go +++ b/apispec/meme-storage/server/api.gen.go @@ -1,6 +1,6 @@ // Package server provides primitives to interact with the openapi HTTP API. // -// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.4.1 DO NOT EDIT. +// Code generated by github.com/deepmap/oapi-codegen/v2 version v2.2.0 DO NOT EDIT. package server import ( @@ -22,6 +22,11 @@ const ( New DuplicateStatus = "new" ) +// CreateImageRequestDto defines model for CreateImageRequestDto. +type CreateImageRequestDto struct { + ImageBase64 string `json:"ImageBase64"` +} + // CreateMemeResponseDto defines model for CreateMemeResponseDto. type CreateMemeResponseDto struct { DuplicateStatus *DuplicateStatus `json:"DuplicateStatus,omitempty"` @@ -33,33 +38,21 @@ type CreateMemeResponseDto struct { // DuplicateStatus defines model for DuplicateStatus. type DuplicateStatus string -// ImageDto defines model for ImageDto. -type ImageDto struct { - ImageBase64 *string `json:"ImageBase64,omitempty"` - MimeType *string `json:"MimeType,omitempty"` -} - // ImageUrlDto defines model for ImageUrlDto. type ImageUrlDto struct { - Url *string `json:"Url,omitempty"` + Height *int `json:"Height,omitempty"` + Url string `json:"Url"` + Width *int `json:"Width,omitempty"` } -// SearchMemeDto defines model for SearchMemeDto. -type SearchMemeDto struct { - Hash *string `json:"Hash,omitempty"` - Id *openapi_types.UUID `json:"Id,omitempty"` - ImageUrl *string `json:"ImageUrl,omitempty"` - OcrResult *string `json:"OcrResult,omitempty"` - OcrResultHighlight *[]string `json:"OcrResultHighlight,omitempty"` - SortId *int64 `json:"SortId,omitempty"` - Thumbnail *SearchMemeThumb `json:"Thumbnail,omitempty"` -} - -// SearchMemeThumb defines model for SearchMemeThumb. -type SearchMemeThumb struct { - ThumbHeight *int `json:"ThumbHeight,omitempty"` - ThumbUrl *string `json:"ThumbUrl,omitempty"` - ThumbWidth *int `json:"ThumbWidth,omitempty"` +// SearchMemeResponseItemDto defines model for SearchMemeResponseItemDto. +type SearchMemeResponseItemDto struct { + Hash *string `json:"Hash,omitempty"` + Id *openapi_types.UUID `json:"Id,omitempty"` + Image *ImageUrlDto `json:"Image,omitempty"` + OcrResult *string `json:"OcrResult,omitempty"` + SortId *int64 `json:"SortId,omitempty"` + Thumbnail *ImageUrlDto `json:"Thumbnail,omitempty"` } // AccountId defines model for AccountId. @@ -68,24 +61,24 @@ type AccountId = openapi_types.UUID // MemeId defines model for MemeId. type MemeId = openapi_types.UUID -// MemeQuery defines model for MemeQuery. -type MemeQuery = string - // PageSize defines model for PageSize. type PageSize = int +// Query defines model for Query. +type Query = string + // SearchAfterId defines model for SearchAfterId. type SearchAfterId = int64 // SearchMemeParams defines parameters for SearchMeme. type SearchMemeParams struct { - MemeQuery MemeQuery `form:"MemeQuery" json:"MemeQuery"` + Query Query `form:"Query" json:"Query"` SearchAfterSortId *SearchAfterId `form:"SearchAfterSortId,omitempty" json:"SearchAfterSortId,omitempty"` PageSize *PageSize `form:"PageSize,omitempty" json:"PageSize,omitempty"` } // CreateMemeJSONRequestBody defines body for CreateMeme for application/json ContentType. -type CreateMemeJSONRequestBody = ImageDto +type CreateMemeJSONRequestBody = CreateImageRequestDto // ServerInterface represents all server handlers. type ServerInterface interface { @@ -99,7 +92,7 @@ type ServerInterface interface { // (POST /api/v1/accounts/{AccountId}/meme) CreateMeme(ctx echo.Context, accountId AccountId) error - // (GET /api/v1/accounts/{AccountId}/meme/{MemeId}) + // (DELETE /api/v1/accounts/{AccountId}/meme/{MemeId}) DeleteMeme(ctx echo.Context, accountId AccountId, memeId MemeId) error // (GET /api/v1/accounts/{AccountId}/meme/{MemeId}/image/thumb/url) @@ -149,11 +142,11 @@ func (w *ServerInterfaceWrapper) SearchMeme(ctx echo.Context) error { // Parameter object where we will unmarshal all parameters from the context var params SearchMemeParams - // ------------- Required query parameter "MemeQuery" ------------- + // ------------- Required query parameter "Query" ------------- - err = runtime.BindQueryParameter("form", true, true, "MemeQuery", ctx.QueryParams(), ¶ms.MemeQuery) + err = runtime.BindQueryParameter("form", true, true, "Query", ctx.QueryParams(), ¶ms.Query) if err != nil { - return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter MemeQuery: %s", err)) + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter Query: %s", err)) } // ------------- Optional query parameter "SearchAfterSortId" ------------- @@ -334,7 +327,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL router.POST(baseURL+"/api/v1/accounts/:AccountId/check-duplicates", wrapper.CheckDuplicates) router.GET(baseURL+"/api/v1/accounts/:AccountId/meme", wrapper.SearchMeme) router.POST(baseURL+"/api/v1/accounts/:AccountId/meme", wrapper.CreateMeme) - router.GET(baseURL+"/api/v1/accounts/:AccountId/meme/:MemeId", wrapper.DeleteMeme) + router.DELETE(baseURL+"/api/v1/accounts/:AccountId/meme/:MemeId", wrapper.DeleteMeme) router.GET(baseURL+"/api/v1/accounts/:AccountId/meme/:MemeId/image/thumb/url", wrapper.GetMemeImageThumbUrl) router.GET(baseURL+"/api/v1/accounts/:AccountId/meme/:MemeId/image/url", wrapper.GetMemeImageUrl) router.POST(baseURL+"/api/v1/accounts/:AccountId/update-ocr", wrapper.UpdateOcr) @@ -367,7 +360,7 @@ type SearchMemeResponseObject interface { VisitSearchMemeResponse(w http.ResponseWriter) error } -type SearchMeme200JSONResponse []SearchMemeDto +type SearchMeme200JSONResponse []SearchMemeResponseItemDto func (response SearchMeme200JSONResponse) VisitSearchMemeResponse(w http.ResponseWriter) error { w.Header().Set("Content-Type", "application/json") @@ -492,7 +485,7 @@ type StrictServerInterface interface { // (POST /api/v1/accounts/{AccountId}/meme) CreateMeme(ctx context.Context, request CreateMemeRequestObject) (CreateMemeResponseObject, error) - // (GET /api/v1/accounts/{AccountId}/meme/{MemeId}) + // (DELETE /api/v1/accounts/{AccountId}/meme/{MemeId}) DeleteMeme(ctx context.Context, request DeleteMemeRequestObject) (DeleteMemeResponseObject, error) // (GET /api/v1/accounts/{AccountId}/meme/{MemeId}/image/thumb/url) diff --git a/common/go.mod b/common/go.mod index 111ffbf..63ef617 100644 --- a/common/go.mod +++ b/common/go.mod @@ -1,6 +1,6 @@ module mine.local/ocr-gallery/common -go 1.23.2 +go 1.24.10 require ( github.com/labstack/echo/v4 v4.13.3 diff --git a/storage-service/config.yaml b/storage-service/config.yaml index 8eab0b6..d555707 100644 --- a/storage-service/config.yaml +++ b/storage-service/config.yaml @@ -7,8 +7,8 @@ server: image-storage: S3: Endpoint: localhost:9000 - AccessKey: - SecretKey: + AccessKey: minio123 + SecretKey: minio123 Bucket: images diff --git a/storage-service/request_example/example.md b/storage-service/request_example/example.md new file mode 100644 index 0000000..95b01bf --- /dev/null +++ b/storage-service/request_example/example.md @@ -0,0 +1,31 @@ +Account id for all queries = `50c7503d-8301-4697-8f61-1cc31f1e9cac` + +Search all images +```bash +curl http://localhost:7001/api/v1/accounts/50c7503d-8301-4697-8f61-1cc31f1e9cac/meme?Query= +``` + +Search images by query +```bash +curl http://localhost:7001/api/v1/accounts/50c7503d-8301-4697-8f61-1cc31f1e9cac/meme?Query=lorem +``` + +Search images by id +```bash +curl http://localhost:7001/api/v1/accounts/50c7503d-8301-4697-8f61-1cc31f1e9cac/meme?Query=a7317219-1462-436d-82be-9a051c26ebb7 +``` + +Create image +```bash +curl http://localhost:7001/api/v1/accounts/50c7503d-8301-4697-8f61-1cc31f1e9cac/meme -X POST -H "Content-Type: application/json" -d @request.storage.create.test-image.json +``` + +Delete by id +```bash +curl http://localhost:7001/api/v1/accounts/50c7503d-8301-4697-8f61-1cc31f1e9cac/meme/a7317219-1462-436d-82be-9a051c26ebb7 -X DELETE +``` + +Update ocr data +```bash +curl http://localhost:7001/api/v1/accounts/50c7503d-8301-4697-8f61-1cc31f1e9cac/update-ocr -X POST +``` \ No newline at end of file diff --git a/storage-service/request_example/request.storage.create.test-image.json b/storage-service/request_example/request.storage.create.test-image.json new file mode 100644 index 0000000..2928044 --- /dev/null +++ b/storage-service/request_example/request.storage.create.test-image.json @@ -0,0 +1,3 @@ +{ + "ImageBase64": "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" +} \ No newline at end of file diff --git a/storage-service/src/entity/entity.go b/storage-service/src/entity/entity.go index 25ffbe4..f5238ee 100644 --- a/storage-service/src/entity/entity.go +++ b/storage-service/src/entity/entity.go @@ -14,7 +14,8 @@ type ElasticImageMetaData struct { Hash string Result string ThumbSize *ElasticSizes `validator:required` - Created int64 `validator:required` + ImageSize *ElasticSizes + Created int64 `validator:required` Updated int64 EmbeddingV1 *ElasticEmbeddingV1 `validator:required` } @@ -24,12 +25,8 @@ type ElasticEmbeddingV1 struct { Model string `validator:required` } -type ElasticMatchedContent struct { - Metadata *ElasticImageMetaData `validator:required` - ResultMatched *[]string `validator:required` -} - type Image struct { - ImageBase64 *string `validator:required` - MimeType string + ImageBase64 string `validator:required` + Width int + Height int } diff --git a/storage-service/src/helper/helper.go b/storage-service/src/helper/helper.go index d5a7c85..b02a048 100644 --- a/storage-service/src/helper/helper.go +++ b/storage-service/src/helper/helper.go @@ -9,9 +9,9 @@ import ( "mine.local/ocr-gallery/storage-service/entity" ) -func CalcHash(base64Image *string) string { +func CalcHash(base64Image string) string { hasher := md5.New() - hasher.Write([]byte(*base64Image)) + hasher.Write([]byte(base64Image)) byteHash := hasher.Sum(nil) return hex.EncodeToString(byteHash) } @@ -27,26 +27,16 @@ func ElasticToCreateResponse( dto.DuplicateStatus = &duplicate } -func ElasticToSearchMemeDto(elasticEntity *entity.ElasticMatchedContent, dto *server.SearchMemeDto) { - dto.OcrResult = &elasticEntity.Metadata.Result - dto.Hash = &elasticEntity.Metadata.Hash - dto.Id = &elasticEntity.Metadata.ImageId - dto.SortId = &elasticEntity.Metadata.Created - - highlightText := *elasticEntity.ResultMatched - dto.OcrResultHighlight = &highlightText -} - -func ImageToEntity(image *client.ImageDto) *entity.Image { +func OcrImageToEntity(image *client.ImageWithSizeDto) *entity.Image { return &entity.Image{ - ImageBase64: image.ImageBase64, - MimeType: *image.MimeType, + ImageBase64: image.Image.ImageBase64, + Width: image.Width, + Height: image.Height, } } -func ImageToEntity2(image *server.ImageDto) *entity.Image { +func ApiImageToEntity(image *server.CreateImageRequestDto) *entity.Image { return &entity.Image{ ImageBase64: image.ImageBase64, - MimeType: *image.MimeType, } } diff --git a/storage-service/src/main.go b/storage-service/src/main.go index 6abd813..e0866a6 100644 --- a/storage-service/src/main.go +++ b/storage-service/src/main.go @@ -22,6 +22,7 @@ func main() { fx.Provide(conf.NewOcrConfig), fx.Provide(conf.NewMetadataStorageConfig), fx.Provide(conf.NewImageStorageConfig), + fx.Provide(commonmiddleware.NewLoggingMiddleware), fx.Provide(service.NewMetadataStorageService), fx.Provide(service.NewImageStorageService), fx.Provide(service.NewOcrService), @@ -33,14 +34,16 @@ func main() { func Startup( storage server.StrictServerInterface, conf *commonconfig.ServerConfig, + middleware commonmiddleware.LoggingMiddlewareFunc, ) { srv := echo.New() + srv.Debug = true server.RegisterHandlers(srv, server.NewStrictHandler( storage, []oapiEcho.StrictEchoMiddlewareFunc{ - commonmiddleware.NewLoggingMiddleware(), + oapiEcho.StrictEchoMiddlewareFunc(middleware), }), ) diff --git a/storage-service/src/service/ApiHandlerService.go b/storage-service/src/service/ApiHandlerService.go index aacae29..da24043 100644 --- a/storage-service/src/service/ApiHandlerService.go +++ b/storage-service/src/service/ApiHandlerService.go @@ -4,16 +4,16 @@ import ( "context" "errors" "fmt" - "github.com/adrg/strutil/metrics" "log/slog" "strings" "time" + "github.com/adrg/strutil/metrics" + "mine.local/ocr-gallery/common/commonhelper" + "github.com/adrg/strutil" - "github.com/gdexlab/go-render/render" "github.com/go-playground/validator/v10" "github.com/google/uuid" - "github.com/labstack/echo/v4" "mine.local/ocr-gallery/apispec/meme-storage/server" "mine.local/ocr-gallery/common/commonconst" "mine.local/ocr-gallery/storage-service/entity" @@ -33,6 +33,10 @@ func (a *ApiHandler) DeleteMeme(ctx context.Context, request server.DeleteMemeRe return nil, err } + if item == nil { + return server.DeleteMeme200Response{}, nil + } + err = a.metaStorage.DeleteById(ctx, item.AccountId, item.ImageId) if err != nil { return nil, err @@ -51,38 +55,39 @@ func (a *ApiHandler) CreateMeme( request server.CreateMemeRequestObject, ) (server.CreateMemeResponseObject, error) { image := request.Body + accountId := request.AccountId slog.Info("CreateMeme", - commonconst.ACCOUNTID_LOG, request.AccountId) + commonconst.ACCOUNTID_LOG, accountId) idUuid, _ := uuid.NewRandom() - if len(*image.ImageBase64) == 0 { + if len(image.ImageBase64) == 0 { return nil, errors.New("image is empty") } hash := helper.CalcHash(request.Body.ImageBase64) - hashDuplicate, err := a.findHashDuplicates(ctx, hash) + hashDuplicate, err := a.findHashDuplicates(ctx, accountId, hash) if err != nil { return nil, fmt.Errorf("failed to find hash duplicates : %w", err) } - if hashDuplicate != nil { - return a.HandleDuplicate(ctx, server.DuplicateHash, hashDuplicate, request) + if hashDuplicate != nil && len(hashDuplicate) > 0 { + return a.HandleDuplicate(ctx, server.DuplicateHash, hashDuplicate[0], request) } - reqImage := helper.ImageToEntity2(request.Body) - ocrResult, err := a.ocr.DoOcr(ctx, idUuid, reqImage) + reqImage := helper.ApiImageToEntity(request.Body) + ocrResult, err := a.ocr.DoOcr(ctx, reqImage) if err != nil { return nil, fmt.Errorf("failed to do ocr : %w", err) } ocrTextResult := ocrResult.OcrText slog.Info("CreateMeme: ocr result", - commonconst.ACCOUNTID_LOG, request.AccountId, + commonconst.ACCOUNTID_LOG, accountId, "id", idUuid, "ocrText", ocrTextResult) - contentDuplicate, err := a.findContentDuplicates(ctx, ocrResult) + contentDuplicate, err := a.findContentDuplicates(ctx, accountId, ocrResult) if err != nil { return nil, err } @@ -96,7 +101,7 @@ func (a *ApiHandler) CreateMeme( similarity := strutil.Similarity(ocrTextResult, contentDuplicateTextResult, metrics.NewLevenshtein()) slog.Info("CreateMeme: found content-duplicate by embedding search", - commonconst.ACCOUNTID_LOG, request.AccountId, + commonconst.ACCOUNTID_LOG, accountId, "id", idUuid, "dupId", contentDuplicate.ImageId, "ocrText", ocrTextResult, @@ -108,14 +113,14 @@ func (a *ApiHandler) CreateMeme( } } - err = a.imageStorage.Save(ctx, idUuid, ocrResult.Image, ocrResult.Thumbnail.Image) + err = a.imageStorage.Save(ctx, idUuid, ocrResult.Image.ImageBase64, ocrResult.Thumbnail.ImageBase64) if err != nil { return nil, fmt.Errorf("failed to save image metadata : %w", err) } elasticMetaData := OcrResultToElastic( idUuid, - request.AccountId, + accountId, hash, time.Now().UnixMicro(), ocrResult, @@ -140,19 +145,15 @@ func (a *ApiHandler) CreateMeme( // SearchMeme implements server.StrictServerInterface. func (a *ApiHandler) SearchMeme(ctx context.Context, request server.SearchMemeRequestObject) (server.SearchMemeResponseObject, error) { - query := request.Params.MemeQuery + query := request.Params.Query + accountId := request.AccountId + searchAfter := request.Params.SearchAfterSortId + pageSize := request.Params.PageSize slog.Info("SearchMeme", "query", query) - - matchedMetadata, err := a.metaStorage.Search( - ctx, - request.AccountId, - query, - request.Params.SearchAfterSortId, - request.Params.PageSize, - ) + matchedMetadata, err := a.searchMeme(ctx, accountId, query, searchAfter, pageSize) if err != nil { - return nil, fmt.Errorf("failed to search memes : %w", err) + return nil, fmt.Errorf("searchMeme failed: %w", err) } slog.Info("SearchMeme results", @@ -163,42 +164,123 @@ func (a *ApiHandler) SearchMeme(ctx context.Context, request server.SearchMemeRe response := make(server.SearchMeme200JSONResponse, len(matchedMetadata)) for index, metadataItem := range matchedMetadata { slog.Debug("Search meme result item", - commonconst.ACCOUNTID_LOG, metadataItem.Metadata.AccountId, - "id", metadataItem.Metadata.ImageId, - "s3id", metadataItem.Metadata.S3Id, - "index", index, - "matched", render.Render(metadataItem.ResultMatched)) + commonconst.ACCOUNTID_LOG, metadataItem.AccountId, + "id", metadataItem.ImageId, + "s3id", metadataItem.S3Id, + "index", index) - imageThumbUrl, err := a.imageStorage.GetUrlThumb(ctx, metadataItem.Metadata.S3Id) + imageThumbUrl, err := a.imageStorage.GetUrlThumb(ctx, metadataItem.S3Id) if err != nil { - return nil, fmt.Errorf("failed to obtain thumb url for image id=%s : %w", metadataItem.Metadata.ImageId, err) + return nil, fmt.Errorf("failed to obtain thumb url for image id=%s : %w", metadataItem.ImageId, err) } - imageUrl, err := a.imageStorage.GetUrl(ctx, metadataItem.Metadata.S3Id) + imageUrl, err := a.imageStorage.GetUrl(ctx, metadataItem.S3Id) if err != nil { - return nil, fmt.Errorf("failed to obtain image url for image id=%s : %w", metadataItem.Metadata.ImageId, err) + return nil, fmt.Errorf("failed to obtain image url for image id=%s : %w", metadataItem.ImageId, err) } - dto := server.SearchMemeDto{} - helper.ElasticToSearchMemeDto(metadataItem, &dto) - dto.ImageUrl = &imageUrl - dto.Thumbnail = new(server.SearchMemeThumb) - dto.Thumbnail.ThumbUrl = &imageThumbUrl - dto.Thumbnail.ThumbHeight = &metadataItem.Metadata.ThumbSize.Height - dto.Thumbnail.ThumbWidth = &metadataItem.Metadata.ThumbSize.Width + dto := server.SearchMemeResponseItemDto{ + Hash: &metadataItem.Hash, + Id: &metadataItem.ImageId, + Image: &server.ImageUrlDto{ + Url: imageUrl, + Height: &metadataItem.ImageSize.Height, + Width: &metadataItem.ImageSize.Width, + }, + Thumbnail: &server.ImageUrlDto{ + Url: imageThumbUrl, + Height: &metadataItem.ThumbSize.Height, + Width: &metadataItem.ThumbSize.Width, + }, + OcrResult: &metadataItem.Result, + SortId: &metadataItem.Created, + } response[index] = dto } return response, nil } +func (a *ApiHandler) searchMeme( + ctx context.Context, + accountId uuid.UUID, + query string, + searchAfter *int64, + pageSize *int, +) ([]*entity.ElasticImageMetaData, error) { + if query == "" { + slog.Info("SearchMeme method=ALL") + matchedMetadataAll, err := a.metaStorage.SearchAll( + ctx, + accountId, + searchAfter, + pageSize, + ) + + if err != nil { + return nil, fmt.Errorf("failed to search memes[ALL] : %w", err) + } + return matchedMetadataAll, nil + } + + asId, err := uuid.Parse(query) + if err == nil { + slog.Info("SearchMeme method=ID") + matchedById, err := a.metaStorage.GetById(ctx, accountId, asId) + if err != nil { + return nil, fmt.Errorf("failed to search memes[ID] : %w", err) + } + + if matchedById != nil { + return []*entity.ElasticImageMetaData{ + matchedById, + }, nil + } + } + + slog.Info("SearchMeme method=SIMPLE") + matchedMetadataSimple, err := a.metaStorage.SearchSimple( + ctx, + accountId, + query, + searchAfter, + pageSize, + ) + if err != nil { + return nil, fmt.Errorf("failed to search memes[SIMPLE] : %w", err) + } + + if len(matchedMetadataSimple) > 0 || searchAfter != nil { + return matchedMetadataSimple, nil + } + + slog.Info("SearchMeme method=FUZZY") + matchedMetadataFuzzy, err := a.metaStorage.SearchFuzzy( + ctx, + accountId, + query, + pageSize, + ) + if err != nil { + return nil, fmt.Errorf("failed to search memes[Fuzzy] : %w", err) + } + + return matchedMetadataFuzzy, nil +} + // CheckDuplicates implements server.StrictServerInterface. func (a *ApiHandler) CheckDuplicates(ctx context.Context, request server.CheckDuplicatesRequestObject) (server.CheckDuplicatesResponseObject, error) { return server.CheckDuplicates200Response{}, a.iterateDocuments( ctx, request.AccountId, - func(ctx2 context.Context, emc *entity.ElasticMatchedContent) error { - a.internalCheckDuplicate(ctx2, emc.Metadata) + func(ctx2 context.Context, emc *entity.ElasticImageMetaData) error { + err := a.internalCheckDuplicate(ctx2, emc) + if err != nil { + slog.Error("internalCheckDuplicate failed", + "ImageId", emc.ImageId, + commonconst.ERR_LOG, err) + } + return nil }) @@ -210,8 +292,13 @@ func (a *ApiHandler) UpdateOcr(ctx context.Context, request server.UpdateOcrRequ a.iterateDocuments( ctx, request.AccountId, - func(ctx context.Context, emc *entity.ElasticMatchedContent) error { - a.internalUpdateOcr(ctx, emc.Metadata) + func(ctx context.Context, emc *entity.ElasticImageMetaData) error { + err := a.internalUpdateOcr(ctx, emc) + if err != nil { + slog.Error("internalUpdateOcr failed", + "ImageId", emc.ImageId, + commonconst.ERR_LOG, err) + } return nil }) } @@ -220,15 +307,15 @@ func (a *ApiHandler) UpdateOcr(ctx context.Context, request server.UpdateOcrRequ func (a *ApiHandler) GetMemeImageThumbUrl(ctx context.Context, request server.GetMemeImageThumbUrlRequestObject) (server.GetMemeImageThumbUrlResponseObject, error) { memeMetadata, err := a.metaStorage.GetById(ctx, request.AccountId, request.MemeId) if err != nil { - return nil, err + return nil, fmt.Errorf("storage GetById failed: %w", err) } if memeMetadata == nil { - return nil, echo.ErrNotFound + return nil, fmt.Errorf("image for accountId=%s and MemeId=%s not found", request.AccountId, request.MemeId) } if memeMetadata.AccountId != request.AccountId { - return nil, echo.ErrNotFound + return nil, fmt.Errorf("image for accountId=%s and MemeId=%s not found", request.AccountId, request.MemeId) } url, err := a.imageStorage.GetUrlThumb(ctx, memeMetadata.S3Id) @@ -236,8 +323,11 @@ func (a *ApiHandler) GetMemeImageThumbUrl(ctx context.Context, request server.Ge return nil, err } - resp := server.GetMemeImageThumbUrl200JSONResponse{} - resp.Url = &url + resp := &server.GetMemeImageThumbUrl200JSONResponse{ + Url: url, + Height: &memeMetadata.ThumbSize.Height, + Width: &memeMetadata.ThumbSize.Width, + } return resp, nil } @@ -245,11 +335,15 @@ func (a *ApiHandler) GetMemeImageThumbUrl(ctx context.Context, request server.Ge func (a *ApiHandler) GetMemeImageUrl(ctx context.Context, request server.GetMemeImageUrlRequestObject) (server.GetMemeImageUrlResponseObject, error) { memeMetadata, err := a.metaStorage.GetById(ctx, request.AccountId, request.MemeId) if err != nil { - return nil, err + return nil, fmt.Errorf("storage GetById failed: %w", err) } if memeMetadata == nil { - return nil, echo.ErrNotFound + return nil, fmt.Errorf("image for accountId=%s and MemeId=%s not found", request.AccountId, request.MemeId) + } + + if memeMetadata.AccountId != request.AccountId { + return nil, fmt.Errorf("image for accountId=%s and MemeId=%s not found", request.AccountId, request.MemeId) } url, err := a.imageStorage.GetUrl(ctx, memeMetadata.S3Id) @@ -257,8 +351,11 @@ func (a *ApiHandler) GetMemeImageUrl(ctx context.Context, request server.GetMeme return nil, err } - resp := server.GetMemeImageUrl200JSONResponse{} - resp.Url = &url + resp := &server.GetMemeImageUrl200JSONResponse{ + Url: url, + Height: &memeMetadata.ImageSize.Height, + Width: &memeMetadata.ImageSize.Width, + } return resp, nil } @@ -266,36 +363,38 @@ func (a *ApiHandler) GetMemeImageUrl(ctx context.Context, request server.GetMeme func (a *ApiHandler) UpdateOcrOne(ctx context.Context, request server.UpdateOcrOneRequestObject) (server.UpdateOcrOneResponseObject, error) { memeMetadata, err := a.metaStorage.GetById(ctx, request.AccountId, request.MemeId) if err != nil { - return nil, err + return nil, fmt.Errorf("storage GetById failed: %w", err) } if memeMetadata == nil { - return nil, echo.ErrNotFound + return nil, fmt.Errorf("image for accountId=%s and MemeId=%s not found", request.AccountId, request.MemeId) + } + + if memeMetadata.AccountId != request.AccountId { + return nil, fmt.Errorf("image for accountId=%s and MemeId=%s not found", request.AccountId, request.MemeId) + } + + err = a.internalUpdateOcr(ctx, memeMetadata) + if err != nil { + return nil, fmt.Errorf("internalUpdateOcr failed: %w", err) } - a.internalUpdateOcr(ctx, memeMetadata) return server.UpdateOcrOne200Response{}, nil } -func (a *ApiHandler) internalCheckDuplicate(ctx context.Context, emc *entity.ElasticImageMetaData) { +func (a *ApiHandler) internalCheckDuplicate(ctx context.Context, emc *entity.ElasticImageMetaData) error { id := emc.ImageId embedding := emc.EmbeddingV1 slog.Info("Check-duplicate", "id", id.String()) if embedding == nil { - slog.Info("Check-duplicate: NO EMBEDDING:", - "id", id.String()) - return + return fmt.Errorf("embedding is nil. id=%s", id) } - embeddingFoundImage, err := a.metaStorage.GetByEmbeddingV1All(ctx, embedding, 10) + embeddingFoundImage, err := a.metaStorage.GetByEmbeddingV1(ctx, emc.AccountId, embedding, 10) if err != nil { - slog.Error("Check-duplicate: failed to search image embedding duplicates ", - "id", id.String(), - commonconst.ERR_LOG, err) - - return + return fmt.Errorf("GetByEmbeddingV1All failed: %w", err) } for i, item := range embeddingFoundImage { @@ -310,10 +409,11 @@ func (a *ApiHandler) internalCheckDuplicate(ctx context.Context, emc *entity.Ela "id", item.ImageId) } } -} -func (a *ApiHandler) internalUpdateOcr(ctx context.Context, emc *entity.ElasticImageMetaData) { + return nil +} +func (a *ApiHandler) internalUpdateOcr(ctx context.Context, emc *entity.ElasticImageMetaData) error { id := emc.ImageId accountId := emc.AccountId hash := emc.Hash @@ -323,66 +423,78 @@ func (a *ApiHandler) internalUpdateOcr(ctx context.Context, emc *entity.ElasticI slog.Info("UpdateOcr: checking image", "id", id) - img, err := a.imageStorage.GetImage(ctx, s3id) + base64ImgData, err := a.imageStorage.GetImage(ctx, s3id) if err != nil { - slog.Info("Failed to read image from storage", - "id", id, - commonconst.ERR_LOG, err) + return fmt.Errorf("storage GetImage failed: %w", err) + } - return + item := &entity.Image{ + ImageBase64: *base64ImgData, + Width: emc.ImageSize.Width, + Height: emc.ImageSize.Height, } - ocrResult, err := a.ocr.DoOcr(ctx, id, img) + ocrResult, err := a.ocr.DoOcr(ctx, item) if err != nil { - slog.Info("Failed to ocr image", - "id", id, - commonconst.ERR_LOG, err) - return + return fmt.Errorf("doOcr failed: %w", err) } elasticObject := OcrResultToElastic(id, accountId, hash, created, ocrResult) err = a.metaStorage.Save(ctx, elasticObject) if err != nil { - slog.Info("Failed to save new image metadata", - "id", id, - commonconst.ERR_LOG, err) - return + return fmt.Errorf("doOcr failed: %w", err) } + + return nil } -func (a *ApiHandler) iterateDocuments(ctx context.Context, accountId uuid.UUID, callback func(context.Context, *entity.ElasticMatchedContent) error) error { - items, err := a.metaStorage.Search(ctx, accountId, "", nil, addr(1000)) - for err == nil && len(items) > 0 { +func (a *ApiHandler) iterateDocuments( + ctx context.Context, + accountId uuid.UUID, + callback func(context.Context, *entity.ElasticImageMetaData) error, +) error { + items, err := a.metaStorage.SearchAll(ctx, accountId, nil, commonhelper.Addr(1000)) + if err != nil { + return fmt.Errorf("search failed: %w", err) + } + + for len(items) > 0 { for _, item := range items { err = callback(ctx, item) + if err != nil { + return fmt.Errorf("iterateDocuments callback failed: %w", err) + } } + if len(items) > 0 { - items, err = a.metaStorage.Search(ctx, accountId, "", &items[len(items)-1].Metadata.Created, addr(1000)) + items, err = a.metaStorage.SearchAll(ctx, accountId, &items[len(items)-1].Created, commonhelper.Addr(1000)) + if err != nil { + return fmt.Errorf("search failed: %w", err) + } } } - if err != nil { - return err - } return nil } func (a *ApiHandler) findHashDuplicates( ctx context.Context, + accountId uuid.UUID, hash string, -) (*entity.ElasticImageMetaData, error) { - return a.metaStorage.GetByHashAll(ctx, hash) +) ([]*entity.ElasticImageMetaData, error) { + return a.metaStorage.GetByHash(ctx, accountId, hash, nil) } func (a *ApiHandler) findContentDuplicates( ctx context.Context, + accountId uuid.UUID, ocrResult *OcrProcessedResult, ) (*entity.ElasticImageMetaData, error) { embedding := &entity.ElasticEmbeddingV1{ Data: &ocrResult.Embedding.Data, Model: ocrResult.Embedding.Model, } - results, err := a.metaStorage.GetByEmbeddingV1All(ctx, embedding, 1) + results, err := a.metaStorage.GetByEmbeddingV1(ctx, accountId, embedding, 1) if err != nil { return nil, err } @@ -423,6 +535,10 @@ func OcrResultToElastic(idUuid uuid.UUID, accountId uuid.UUID, hash string, crea ImageId: idUuid, S3Id: idUuid, AccountId: accountId, + ImageSize: &entity.ElasticSizes{ + Height: ocrResult.Image.Height, + Width: ocrResult.Image.Width, + }, ThumbSize: &entity.ElasticSizes{ Height: ocrResult.Thumbnail.Height, Width: ocrResult.Thumbnail.Width, diff --git a/storage-service/src/service/ElasticMetadataStorageServiceImpl.go b/storage-service/src/service/ElasticMetadataStorageServiceImpl.go index 4c11bb8..3c04f97 100644 --- a/storage-service/src/service/ElasticMetadataStorageServiceImpl.go +++ b/storage-service/src/service/ElasticMetadataStorageServiceImpl.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "encoding/json" - "errors" "fmt" "log/slog" "time" @@ -17,12 +16,42 @@ import ( "github.com/go-playground/validator/v10" "github.com/google/uuid" "mine.local/ocr-gallery/common/commonconst" + "mine.local/ocr-gallery/common/commonhelper" "mine.local/ocr-gallery/storage-service/conf" "mine.local/ocr-gallery/storage-service/entity" ) -const INDEX_NAME = "image-metadata" -const MAX_FUZZY = 10 +const IndexName = "image-metadata" +const MaxFuzzy = 10 + +type MetadataStorageService interface { + Save(ctx context.Context, file *entity.ElasticImageMetaData) error + + SearchAll(ctx context.Context, + accountId uuid.UUID, + sortIdAfter *int64, + pageSize *int, + ) ([]*entity.ElasticImageMetaData, error) + + SearchSimple(ctx context.Context, + accountId uuid.UUID, + query string, + sortIdAfter *int64, + pageSize *int, + ) ([]*entity.ElasticImageMetaData, error) + + SearchFuzzy(ctx context.Context, + accountId uuid.UUID, + query string, + pageSize *int, + ) ([]*entity.ElasticImageMetaData, error) + + GetById(ctx context.Context, accountId uuid.UUID, id uuid.UUID) (*entity.ElasticImageMetaData, error) + GetByHash(ctx context.Context, accountId uuid.UUID, hash string, count *int) ([]*entity.ElasticImageMetaData, error) + GetByEmbeddingV1(ctx context.Context, accountId uuid.UUID, img *entity.ElasticEmbeddingV1, count int) ([]*entity.ElasticImageMetaData, error) + + DeleteById(ctx context.Context, accountId uuid.UUID, id uuid.UUID) error +} type ElasticMetadataStorageServiceImpl struct { client *elasticsearch8.TypedClient @@ -30,7 +59,57 @@ type ElasticMetadataStorageServiceImpl struct { validate *validator.Validate } +func (e *ElasticMetadataStorageServiceImpl) SearchAll( + ctx context.Context, + accountId uuid.UUID, + sortIdAfter *int64, + pageSize *int, +) ([]*entity.ElasticImageMetaData, error) { + result, err := e.searchAll(ctx, accountId, sortIdAfter, pageSize) + if err != nil { + return nil, fmt.Errorf("search all failed: accountId=%s sortIdAfter=%v: %w", accountId.String(), sortIdAfter, err) + } + + results, err := e.unmarshalResults(result) + if err != nil { + return nil, fmt.Errorf("result unmarshall failed: accountId=%s sortIdAfter=%v: %w", accountId.String(), sortIdAfter, err) + } + + return results, nil +} + +func (e *ElasticMetadataStorageServiceImpl) SearchSimple(ctx context.Context, accountId uuid.UUID, query string, sortIdAfter *int64, pageSize *int) ([]*entity.ElasticImageMetaData, error) { + result, err := e.searchSimple(ctx, accountId, query, sortIdAfter, pageSize) + if err != nil { + return nil, fmt.Errorf("search all failed: %w", err) + } + + results, err := e.unmarshalResults(result) + if err != nil { + return nil, fmt.Errorf("result unmarshall failed: %w", err) + } + + return results, nil +} + +func (e *ElasticMetadataStorageServiceImpl) SearchFuzzy(ctx context.Context, accountId uuid.UUID, query string, pageSize *int) ([]*entity.ElasticImageMetaData, error) { + result, err := e.searchFuzzy(ctx, accountId, query, pageSize) + if err != nil { + return nil, fmt.Errorf("search all failed: %w", err) + } + + results, err := e.unmarshalResults(result) + if err != nil { + return nil, fmt.Errorf("result unmarshall failed: %w", err) + } + + return results, nil +} + func (e *ElasticMetadataStorageServiceImpl) DeleteById(ctx context.Context, accountId uuid.UUID, id uuid.UUID) error { + slog.Info("DeleteById: delete request", + commonconst.ACCOUNTID_LOG, accountId, + "id", id) query := types.NewQuery() query.Bool = types.NewBoolQuery() @@ -39,18 +118,156 @@ func (e *ElasticMetadataStorageServiceImpl) DeleteById(ctx context.Context, acco *e.accountIdQuery(accountId), } - result, err := e.client.DeleteByQuery(INDEX_NAME). + result, err := e.client.DeleteByQuery(IndexName). Query(query). Do(ctx) if err != nil { - return fmt.Errorf("DeleteById: accountId=%s id=%s : %w", accountId, id, err) + return fmt.Errorf("DeleteById query falied: %w", err) } - slog.Debug("DeleteById: delete response", "accountId", accountId, "id", id, "result", result) + slog.Info("DeleteById: delete response", "accountId", accountId, "id", id) + slog.Debug("DeleteById: delete response details", "accountId", accountId, "id", id, "result", result) return nil } +func (e *ElasticMetadataStorageServiceImpl) GetById(ctx context.Context, accountId uuid.UUID, id uuid.UUID) (*entity.ElasticImageMetaData, error) { + slog.Info("GetById: call", + "id", id.String(), + "accountId", accountId) + + result, err := e.getByIdInternal(ctx, accountId, id) + + if err != nil { + return nil, err + } + + if len(result.Hits.Hits) == 0 { + return nil, nil + } + + data, err := unmarshalSearchResultToElasticEntity(0, result) + if err != nil { + return nil, fmt.Errorf("GetById result unmarshall failed: id: %s error: %w", id.String(), err) + } + + return data, e.validate.Struct(data) +} + +func (e *ElasticMetadataStorageServiceImpl) GetByHash( + ctx context.Context, + accountId uuid.UUID, + hash string, + count *int, +) ([]*entity.ElasticImageMetaData, error) { + slog.Info("GetByHash: call", + commonconst.ACCOUNTID_LOG, accountId, + "hash", hash) + + query := types.NewQuery() + + query.Bool = types.NewBoolQuery() + query.Bool.Must = []types.Query{ + *e.accountIdQuery(accountId), + *e.hashQuery(hash), + } + + result, err := e.runSearchQuery(ctx, query, nil, count) + + if err != nil { + return nil, fmt.Errorf("runSearchQuery falied: %w", err) + } + + resultsSize := len(result.Hits.Hits) + if resultsSize == 0 { + return []*entity.ElasticImageMetaData{}, nil + } + + data := make([]*entity.ElasticImageMetaData, resultsSize) + for i := range resultsSize { + item, err := unmarshalSearchResultToElasticEntity(i, result) + if err != nil { + return nil, fmt.Errorf("GetByHash result unmarshall failed: id: %s error: %w", hash, err) + } + data[i] = item + } + + return data, e.validate.Struct(data) +} + +func (e *ElasticMetadataStorageServiceImpl) GetByEmbeddingV1( + ctx context.Context, + accountId uuid.UUID, + img *entity.ElasticEmbeddingV1, + count int, +) ([]*entity.ElasticImageMetaData, error) { + slog.Info("GetByEmbeddingV1: call", + commonconst.ACCOUNTID_LOG, accountId) + + accountIdQuery := e.accountIdQuery(accountId) + knnQuery := e.embeddingV1KnnAllQuery(img, count) + result, err := e.processKnn(ctx, *knnQuery, accountIdQuery) + if err != nil { + return nil, fmt.Errorf("knn search failed: %w", err) + } + + resultsSize := len(result.Hits.Hits) + if resultsSize == 0 { + return []*entity.ElasticImageMetaData{}, nil + } + + resultsEntity := make([]*entity.ElasticImageMetaData, 0) + for index := range resultsSize { + if float64(*(result.Hits.Hits[index].Score_)) < e.embeddingMatchTreshold { + continue + } + + item, err := unmarshalSearchResultToElasticEntity(index, result) + if err != nil { + return nil, fmt.Errorf("GetByEmbeddingV1 result unmarshall failed: error: %w", err) + } + + err = e.validate.Struct(item) + if err != nil { + return nil, fmt.Errorf("GetByEmbeddingV1 result vaildation failed: error: %w", err) + } + + resultsEntity = append(resultsEntity, item) + } + return resultsEntity, nil +} + +func (e *ElasticMetadataStorageServiceImpl) Save(ctx context.Context, file *entity.ElasticImageMetaData) error { + + file.Updated = time.Now().UnixMicro() + + buff := bytes.NewBuffer(nil) + jsonEncoder := json.NewEncoder(buff) + err := jsonEncoder.Encode(file) + if err != nil { + return fmt.Errorf("json encode failed: %w", err) + } + + response, err := e.client. + Index(IndexName). + Document(file). + Id(file.ImageId.String()). + Do(ctx) + + if err != nil { + return fmt.Errorf("save metadata document error: id=%s : %w", file.ImageId, err) + } + + slog.Info("Save metadata document", + "id", file.ImageId) + + slog.Debug("Save metadata document details", + "id", file.ImageId, + "response", render.Render(response)) + + return err +} + func (e *ElasticMetadataStorageServiceImpl) embeddingV1KnnAllQuery( img *entity.ElasticEmbeddingV1, count int, @@ -59,8 +276,8 @@ func (e *ElasticMetadataStorageServiceImpl) embeddingV1KnnAllQuery( query := types.NewKnnSearch() query.Field = "EmbeddingV1.Data" query.QueryVector = *img.Data - query.NumCandidates = addr(1000) - query.K = addr(count) + query.NumCandidates = commonhelper.Addr(1000) + query.K = commonhelper.Addr(count) return query } @@ -93,6 +310,14 @@ func (e *ElasticMetadataStorageServiceImpl) idQuery( q1.Ids.Values = []string{id.String()} return q1 } +func (e *ElasticMetadataStorageServiceImpl) hashQuery( + hash string, +) *types.Query { + query := types.NewQuery() + query.QueryString = types.NewQueryStringQuery() + query.QueryString.Query = fmt.Sprintf("Hash: \"%s\"", hash) + return query +} func (e *ElasticMetadataStorageServiceImpl) stringAndAccountQuery( accountId uuid.UUID, @@ -139,19 +364,21 @@ func (e *ElasticMetadataStorageServiceImpl) fuzzyStringAndAccountQuery( // Search implements MetadataStorageService. func (e *ElasticMetadataStorageServiceImpl) processKnn( ctx context.Context, - query types.KnnSearch, + knnQuery types.KnnSearch, + query *types.Query, ) (*search.Response, error) { sortId := types.NewSortOptions() sortId.SortOptions["Created"] = *types.NewFieldSort() - search := e.client.Search(). - Index(INDEX_NAME). + searchRequest := e.client.Search(). + Index(IndexName). Sort(sortId). - Knn(query). + Knn(knnQuery). + Query(query). TrackScores(true) - knn, err := search.Do(ctx) + knn, err := searchRequest.Do(ctx) if err != nil { return nil, fmt.Errorf("elastic: failed to knn-search: response=%s : %w", render.Render(knn), err) } @@ -164,7 +391,7 @@ func (e *ElasticMetadataStorageServiceImpl) runSearchQuery( ctx context.Context, query *types.Query, sortIdAfter *int64, - pageSize *int, + size *int, ) (*search.Response, error) { highlight := types.NewHighlight() highlight.PreTags = []string{""} @@ -179,22 +406,22 @@ func (e *ElasticMetadataStorageServiceImpl) runSearchQuery( sortId := types.NewSortOptions() sortId.SortOptions["Created"] = *types.NewFieldSort() - search := e.client.Search(). - Index(INDEX_NAME). + searchRequest := e.client.Search(). + Index(IndexName). Query(query). Fields(*resultField). Highlight(highlight). Sort(sortId) if sortIdAfter != nil { - search = search.SearchAfter(*sortIdAfter) + searchRequest = searchRequest.SearchAfter(*sortIdAfter) } - if pageSize != nil { - search = search.Size(*pageSize) + if size != nil { + searchRequest = searchRequest.Size(*size) } - resp, err := search.Do(ctx) + resp, err := searchRequest.Do(ctx) if err != nil { return nil, fmt.Errorf("elastic: failed to search: response=%s : %w", render.Render(resp), err) } @@ -202,114 +429,61 @@ func (e *ElasticMetadataStorageServiceImpl) runSearchQuery( return resp, nil } -func (e *ElasticMetadataStorageServiceImpl) searchQueryInternal( - ctx context.Context, - accountId uuid.UUID, - queryString string, - sortIdAfter *int64, - pageSize *int, -) (*search.Response, error) { - if pageSize != nil && *pageSize <= 0 { - return nil, errors.New("page size is zero") - } +func (e *ElasticMetadataStorageServiceImpl) searchFuzzy(ctx context.Context, accountId uuid.UUID, queryString string, pageSize *int) (*search.Response, error) { + slog.Info("Search FUZZY", + commonconst.ACCOUNTID_LOG, accountId, + commonconst.QUERY_LOG, queryString, + "pageSize", pageSize, + ) - if queryString == "" { - slog.Info("Search ALL (no query string)", - commonconst.ACCOUNTID_LOG, accountId, - commonconst.OFFSET_LOG, sortIdAfter, - "pageSize", pageSize, - ) + queryFuzzy := e.fuzzyStringAndAccountQuery(accountId, queryString) + resultFuzzy, err := e.runSearchQuery(ctx, queryFuzzy, nil, pageSize) + if err != nil { + return nil, fmt.Errorf("failed to search FUZZY query : %w", err) + } - q := e.allInAccountQuery(accountId) - result, err := e.runSearchQuery(ctx, q, sortIdAfter, pageSize) - if err != nil { - return nil, fmt.Errorf("failed to search all query : %w", err) - } + slog.Info("Search FUZZY result", "count", len(resultFuzzy.Hits.Hits)) - slog.Info("Search ALL result", "count", len(result.Hits.Hits)) - return result, nil - } + return resultFuzzy, nil +} +func (e *ElasticMetadataStorageServiceImpl) searchSimple(ctx context.Context, accountId uuid.UUID, queryString string, sortIdAfter *int64, pageSize *int) (*search.Response, error) { slog.Info("Search SIMPLE", commonconst.ACCOUNTID_LOG, accountId, commonconst.OFFSET_LOG, sortIdAfter, commonconst.QUERY_LOG, queryString, "pageSize", pageSize, ) - q := e.stringAndAccountQuery(accountId, queryString) - result, err := e.runSearchQuery(ctx, q, sortIdAfter, pageSize) + + querySimple := e.stringAndAccountQuery(accountId, queryString) + resultSimple, err := e.runSearchQuery(ctx, querySimple, sortIdAfter, pageSize) if err != nil { return nil, fmt.Errorf("failed to search SIMPLE query : %w", err) } - slog.Info("Search SIMPLE result", "count", len(result.Hits.Hits)) + slog.Info("Search SIMPLE result", "count", len(resultSimple.Hits.Hits)) - resultsSize := len(result.Hits.Hits) - if resultsSize > 0 || sortIdAfter != nil { - return result, nil - } + return resultSimple, nil +} - slog.Info("Search FUZZY", +func (e *ElasticMetadataStorageServiceImpl) searchAll(ctx context.Context, accountId uuid.UUID, sortIdAfter *int64, pageSize *int) (*search.Response, error) { + slog.Info("Search ALL (no query string)", commonconst.ACCOUNTID_LOG, accountId, commonconst.OFFSET_LOG, sortIdAfter, - commonconst.QUERY_LOG, queryString, - "maxCount", MAX_FUZZY, + "pageSize", pageSize, ) - q = e.fuzzyStringAndAccountQuery(accountId, queryString) - result, err = e.runSearchQuery(ctx, q, sortIdAfter, addr(MAX_FUZZY)) + q := e.allInAccountQuery(accountId) + result, err := e.runSearchQuery(ctx, q, sortIdAfter, pageSize) if err != nil { - return nil, fmt.Errorf("failed to search FUZZY query : %w", err) + return nil, fmt.Errorf("failed to search all query : %w", err) } + slog.Info("Search ALL result", "count", len(result.Hits.Hits)) return result, nil } -// Search implements MetadataStorageService. -func (e *ElasticMetadataStorageServiceImpl) Search( - ctx context.Context, - accountId uuid.UUID, - queryString string, - sortIdAfter *int64, - pageSize *int, -) ([]*entity.ElasticMatchedContent, error) { - - result, err := e.searchQueryInternal(ctx, accountId, queryString, sortIdAfter, pageSize) - if err != nil { - return nil, - fmt.Errorf( - "search failed: accountId: %s queryString: %s sortIdAfter: %v error: %w", - accountId.String(), queryString, sortIdAfter, err) - } - - resultsSize := len(result.Hits.Hits) - results := make([]*entity.ElasticMatchedContent, resultsSize) - - for index := range resultsSize { - item, err := unmarhalSearchResultToMatchedContent(index, result) - if err != nil { - return nil, - fmt.Errorf( - "search result unmarshall failed: accountId: %s queryString: %s sortIdAfter: %v error: %w", - accountId.String(), queryString, sortIdAfter, err) - } - err = e.validate.Struct(item) - if err != nil { - return nil, - fmt.Errorf( - "search result vaildation failed: accountId: %s queryString: %s sortIdAfter: %v error: %w", - accountId.String(), queryString, sortIdAfter, err) - } - results[index] = item - } - return results, nil -} - -func (e *ElasticMetadataStorageServiceImpl) GetById(ctx context.Context, accountId uuid.UUID, id uuid.UUID) (*entity.ElasticImageMetaData, error) { - slog.Info("GetById: call", - "id", id.String(), - "accountId", accountId) - +func (e *ElasticMetadataStorageServiceImpl) getByIdInternal(ctx context.Context, accountId uuid.UUID, id uuid.UUID) (*search.Response, error) { query := types.NewQuery() query.Bool = types.NewBoolQuery() @@ -319,169 +493,31 @@ func (e *ElasticMetadataStorageServiceImpl) GetById(ctx context.Context, account } result, err := e.client.Search(). - Index(INDEX_NAME). + Index(IndexName). Query(query). Do(ctx) - - if err != nil { - return nil, err - } - - data, err := unmarhalSearchResultToElasticEntity(0, result) - if err != nil { - return nil, - fmt.Errorf( - "GetById result unmarshall failed: id: %s error: %w", - id.String(), err) - } - - return data, e.validate.Struct(data) -} - -func (e *ElasticMetadataStorageServiceImpl) GetByHashAll( - ctx context.Context, - hash string, -) (*entity.ElasticImageMetaData, error) { - slog.Info("GetByHashAll: call", - "hash", hash) - - query := types.NewQuery() - query.QueryString = types.NewQueryStringQuery() - query.QueryString.Query = fmt.Sprintf("Hash: \"%s\"", hash) - - result, err := e.runSearchQuery(ctx, query, nil, nil) - - if err != nil { - return nil, err - } - - data, err := unmarhalSearchResultToElasticEntity(0, result) - if err != nil { - return nil, - fmt.Errorf( - "GetByHashAll result unmarshall failed: id: %s error: %w", - hash, err) - } - - if data == nil { - return nil, nil - } - - return data, e.validate.Struct(data) + return result, err } -func (e *ElasticMetadataStorageServiceImpl) GetByEmbeddingV1All( - ctx context.Context, - img *entity.ElasticEmbeddingV1, - count int, -) ([]*entity.ElasticImageMetaData, error) { - slog.Info("GetByEmbeddingV1All: call") - - query := e.embeddingV1KnnAllQuery(img, count) - result, err := e.processKnn(ctx, *query) - if err != nil { - return nil, err - } - +func (e *ElasticMetadataStorageServiceImpl) unmarshalResults(result *search.Response) ([]*entity.ElasticImageMetaData, error) { resultsSize := len(result.Hits.Hits) - resultsEntity := make([]*entity.ElasticImageMetaData, 0) + results := make([]*entity.ElasticImageMetaData, resultsSize) for index := range resultsSize { - if float64(*(result.Hits.Hits[index].Score_)) < e.embeddingMatchTreshold { - continue - } - - item, err := unmarhalSearchResultToElasticEntity(index, result) + item, err := unmarshalSearchResultToElasticEntity(index, result) if err != nil { - return nil, fmt.Errorf("GetByEmbeddingV1All result unmarshall failed: error: %w", err) + return nil, fmt.Errorf("unmarshall failed: %w", err) } - err = e.validate.Struct(item) if err != nil { - return nil, fmt.Errorf("GetByEmbeddingV1All result vaildation failed: error: %w", err) + return nil, fmt.Errorf("validation failed: %w", err) } - - resultsEntity = append(resultsEntity, item) - } - return resultsEntity, nil -} - -func (e *ElasticMetadataStorageServiceImpl) GetByHash( - ctx context.Context, - accountId uuid.UUID, - hash string) (*entity.ElasticImageMetaData, error) { - - query := types.NewQuery() - query.QueryString = types.NewQueryStringQuery() - query.QueryString.Query = fmt.Sprintf( - "Hash: \"%s\" AND AccountId: \"%s\"", - hash, accountId.String()) - - result, err := e.client.Search(). - Index(INDEX_NAME). - Query(query). - Do(ctx) - - if err != nil { - return nil, err - } - - data, err := unmarhalSearchResultToElasticEntity(0, result) - if err != nil { - return nil, err - } - - return data, e.validate.Struct(data) -} - -func (e *ElasticMetadataStorageServiceImpl) Save(ctx context.Context, file *entity.ElasticImageMetaData) error { - - file.Updated = time.Now().UnixMicro() - - buff := bytes.NewBuffer(nil) - jsonEncoder := json.NewEncoder(buff) - jsonEncoder.Encode(file) - response, err := e.client. - Index(INDEX_NAME). - Document(file). - Id(file.ImageId.String()). - Do(ctx) - - if err != nil { - return fmt.Errorf("Save metadata document error: id=%s : %w", file.ImageId, err) - } - - slog.Info("Save metadata document", - "id", file.ImageId) - - slog.Debug("Save metadata document details", - "id", file.ImageId, - "response", render.Render(response)) - - return err -} - -func unmarhalSearchResultToMatchedContent(i int, result *search.Response) (*entity.ElasticMatchedContent, error) { - hits := result.Hits.Hits - if len(hits) == 0 { - return nil, nil - } - - hit := hits[i] - - document, err := unmarhalSourceDocument(hit.Source_) - if err != nil { - return nil, err + results[index] = item } - highlights := hit.Highlight["Result"] - - matchedContent := new(entity.ElasticMatchedContent) - matchedContent.Metadata = document - matchedContent.ResultMatched = &highlights - return matchedContent, nil + return results, nil } -func unmarhalSearchResultToElasticEntity(i int, result *search.Response) (*entity.ElasticImageMetaData, error) { +func unmarshalSearchResultToElasticEntity(i int, result *search.Response) (*entity.ElasticImageMetaData, error) { hits := result.Hits.Hits if len(hits) == 0 { return nil, nil @@ -522,8 +558,8 @@ func NewElasticMetadataStorage( indexTypeMapping.Properties["ImageId"] = types.NewKeywordProperty() denseProp := types.NewDenseVectorProperty() - denseProp.Index = addr(true) - denseProp.Dims = addr(config.EmbeddingV1Dimensions) + denseProp.Index = commonhelper.Addr(true) + denseProp.Dims = commonhelper.Addr(config.EmbeddingV1Dimensions) indexTypeMapping.Properties["EmbeddingV1.Data"] = denseProp responseMapping, err := es8.Indices.PutMapping(config.Index). @@ -540,3 +576,7 @@ func NewElasticMetadataStorage( validate: validate, } } + +func NewMetadataStorageService(config *conf.MetadataStorageConfig, validate *validator.Validate) MetadataStorageService { + return NewElasticMetadataStorage(config, validate) +} diff --git a/storage-service/src/service/ImageStorageService.go b/storage-service/src/service/ImageStorageService.go deleted file mode 100644 index 0c4391c..0000000 --- a/storage-service/src/service/ImageStorageService.go +++ /dev/null @@ -1,22 +0,0 @@ -package service - -import ( - "context" - - "github.com/google/uuid" - "mine.local/ocr-gallery/storage-service/conf" - "mine.local/ocr-gallery/storage-service/entity" -) - -type ImageStorageService interface { - Save(ctx context.Context, id uuid.UUID, image *entity.Image, thumb *entity.Image) error - GetImage(ctx context.Context, id uuid.UUID) (*entity.Image, error) - - GetUrl(ctx context.Context, id uuid.UUID) (string, error) - GetUrlThumb(ctx context.Context, id uuid.UUID) (string, error) - DeleteImage(ctx context.Context, id uuid.UUID) error -} - -func NewImageStorageService(config *conf.ImageStorageConfig) (ImageStorageService, error) { - return NewMinioFileStorageServiceImpl(config) -} diff --git a/storage-service/src/service/MetadataStorageService.go b/storage-service/src/service/MetadataStorageService.go deleted file mode 100644 index c61d458..0000000 --- a/storage-service/src/service/MetadataStorageService.go +++ /dev/null @@ -1,33 +0,0 @@ -package service - -import ( - "context" - - "github.com/go-playground/validator/v10" - "github.com/google/uuid" - "mine.local/ocr-gallery/storage-service/conf" - "mine.local/ocr-gallery/storage-service/entity" -) - -type MetadataStorageService interface { - GetByHashAll(ctx context.Context, hash string) (*entity.ElasticImageMetaData, error) - GetByEmbeddingV1All(ctx context.Context, img *entity.ElasticEmbeddingV1, count int) ([]*entity.ElasticImageMetaData, error) - - Save(ctx context.Context, file *entity.ElasticImageMetaData) error - - Search(ctx context.Context, - accountId uuid.UUID, - query string, - sortIdAfter *int64, - pageSize *int, - ) ([]*entity.ElasticMatchedContent, error) - - GetByHash(ctx context.Context, accountId uuid.UUID, hash string) (*entity.ElasticImageMetaData, error) - GetById(ctx context.Context, accountId uuid.UUID, id uuid.UUID) (*entity.ElasticImageMetaData, error) - - DeleteById(ctx context.Context, accountId uuid.UUID, id uuid.UUID) error -} - -func NewMetadataStorageService(config *conf.MetadataStorageConfig, validate *validator.Validate) MetadataStorageService { - return NewElasticMetadataStorage(config, validate) -} diff --git a/storage-service/src/service/OcrService.go b/storage-service/src/service/OcrService.go index c223705..699518c 100644 --- a/storage-service/src/service/OcrService.go +++ b/storage-service/src/service/OcrService.go @@ -2,12 +2,11 @@ package service import ( "context" - "errors" + "fmt" "log/slog" "strings" "github.com/go-playground/validator/v10" - "github.com/google/uuid" "mine.local/ocr-gallery/apispec/ocr-server/client" "mine.local/ocr-gallery/storage-service/conf" "mine.local/ocr-gallery/storage-service/entity" @@ -15,10 +14,7 @@ import ( ) type OcrSerivce interface { - DoOcr(ctx context.Context, - id uuid.UUID, - incomingImage *entity.Image, - ) (*OcrProcessedResult, error) + DoOcr(ctx context.Context, incomingImage *entity.Image) (*OcrProcessedResult, error) } type OcrServiceImpl struct { @@ -28,14 +24,9 @@ type OcrServiceImpl struct { type OcrProcessedResult struct { OcrText string - Thumbnail *OcrThumbnail `validator:required` + Thumbnail *entity.Image `validator:required` Image *entity.Image `validator:required` - Embedding *OcrEmbedding -} -type OcrThumbnail struct { - Image *entity.Image `validator:required` - Width int `validator:required` - Height int `validator:required` + Embedding *OcrEmbedding `validator:required` } type OcrEmbedding struct { @@ -45,54 +36,42 @@ type OcrEmbedding struct { func (ocr *OcrServiceImpl) DoOcr( ctx context.Context, - id uuid.UUID, incomingImage *entity.Image, ) (*OcrProcessedResult, error) { - - idStr := id.String() - request := client.OcrRequestDto{ - ImageId: &idStr, Image: &client.ImageDto{ ImageBase64: incomingImage.ImageBase64, - MimeType: &incomingImage.MimeType, }, } response, err := ocr.ocrclient.PostApiV1OcrProcessWithResponse(ctx, request) if err != nil { - return nil, err + return nil, fmt.Errorf("ocr request failed: %w", err) + } + if response.StatusCode() == 500 { + return nil, fmt.Errorf("ocr request failed status=%s message=%v", response.Status(), response.JSON500.Error) } if response.StatusCode() != 200 { - return nil, errors.New("status code fault") + return nil, fmt.Errorf("ocr request failed status=%s", response.Status()) } responseJson := response.JSON200 textVariants := responseJson.ImageText - - image := responseJson.Image - - retval := new(OcrProcessedResult) - retval.OcrText = textVariantsToString(textVariants) - retval.Image = helper.ImageToEntity(image) - - if responseJson.ImageThumb != nil { - thumbnail := responseJson.ImageThumb - retval.Thumbnail = new(OcrThumbnail) - retval.Thumbnail.Image = helper.ImageToEntity(thumbnail.Image) - retval.Thumbnail.Width = *thumbnail.Width - retval.Thumbnail.Height = *thumbnail.Height - } - - if responseJson.Embedding != nil { - retval.Embedding = new(OcrEmbedding) - retval.Embedding.Data = *responseJson.Embedding.Data - retval.Embedding.Model = *responseJson.Embedding.ModelName + sourceImage := responseJson.ImageSource + thumbImage := responseJson.ImageThumb + + retval := &OcrProcessedResult{ + OcrText: textVariantsToString(textVariants), + Image: helper.OcrImageToEntity(sourceImage), + Thumbnail: helper.OcrImageToEntity(thumbImage), + Embedding: &OcrEmbedding{ + Data: *responseJson.Embedding.Data, + Model: *responseJson.Embedding.ModelName, + }, } - return retval, ocr.validate.Struct(retval) } diff --git a/storage-service/src/service/S3ImageStorageService.go b/storage-service/src/service/S3ImageStorageService.go index 643d778..697aa4d 100644 --- a/storage-service/src/service/S3ImageStorageService.go +++ b/storage-service/src/service/S3ImageStorageService.go @@ -5,6 +5,7 @@ import ( "context" "encoding/base64" "errors" + "fmt" "io" "net/url" "strings" @@ -14,9 +15,17 @@ import ( "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" "mine.local/ocr-gallery/storage-service/conf" - "mine.local/ocr-gallery/storage-service/entity" ) +type ImageStorageService interface { + Save(ctx context.Context, id uuid.UUID, imageBase64 string, thumbBase64 string) error + GetImage(ctx context.Context, id uuid.UUID) (*string, error) + + GetUrl(ctx context.Context, id uuid.UUID) (string, error) + GetUrlThumb(ctx context.Context, id uuid.UUID) (string, error) + DeleteImage(ctx context.Context, id uuid.UUID) error +} + type MinioFileStorageServiceImpl struct { client minio.Client bucketName string @@ -30,7 +39,7 @@ func (m *MinioFileStorageServiceImpl) DeleteImage(ctx context.Context, id uuid.U } // GetImage implements ImageStorageService. -func (m *MinioFileStorageServiceImpl) GetImage(ctx context.Context, id uuid.UUID) (*entity.Image, error) { +func (m *MinioFileStorageServiceImpl) GetImage(ctx context.Context, id uuid.UUID) (*string, error) { obj, err := m.client.GetObject( ctx, m.bucketName, @@ -51,18 +60,9 @@ func (m *MinioFileStorageServiceImpl) GetImage(ctx context.Context, id uuid.UUID return nil, err } - stat, err := obj.Stat() - if err != nil { - return nil, err - } - dataBase64 := buf.String() - contentType := stat.ContentType - return &entity.Image{ - ImageBase64: &dataBase64, - MimeType: contentType, - }, nil + return &dataBase64, nil } // GetUrl implements ImageStorageService. @@ -99,32 +99,37 @@ func (m *MinioFileStorageServiceImpl) GetUrlThumb(ctx context.Context, id uuid.U } // Save implements ImageStorageService. -func (m *MinioFileStorageServiceImpl) Save(ctx context.Context, id uuid.UUID, image *entity.Image, thumb *entity.Image) error { +func (m *MinioFileStorageServiceImpl) Save(ctx context.Context, id uuid.UUID, image string, thumb string) error { _, err := m.client.PutObject( ctx, m.bucketName, getObjectNameV1(id, false), - base64.NewDecoder(base64.RawStdEncoding, strings.NewReader(*image.ImageBase64)), + base64.NewDecoder(base64.RawStdEncoding, strings.NewReader(image)), -1, minio.PutObjectOptions{ - ContentType: image.MimeType, + ContentType: "image/jpeg", }, ) if err != nil { - return err + return fmt.Errorf("PutObject failed for source doc: %w", err) } _, err = m.client.PutObject( ctx, m.bucketName, getObjectNameV1(id, true), - base64.NewDecoder(base64.RawStdEncoding, strings.NewReader(*thumb.ImageBase64)), + base64.NewDecoder(base64.RawStdEncoding, strings.NewReader(thumb)), -1, minio.PutObjectOptions{ - ContentType: thumb.MimeType, + ContentType: "image/jpeg", }, ) + + if err != nil { + return fmt.Errorf("PutObject failed for thumb doc: %w", err) + } + return err } @@ -159,3 +164,7 @@ func getObjectNameV1(id uuid.UUID, thumb bool) string { return id.String() + "/" + imgName } + +func NewImageStorageService(config *conf.ImageStorageConfig) (ImageStorageService, error) { + return NewMinioFileStorageServiceImpl(config) +} diff --git a/testenv/docker-compose.yml b/testenv/docker-compose.yml index 24810d6..10b1852 100644 --- a/testenv/docker-compose.yml +++ b/testenv/docker-compose.yml @@ -2,7 +2,16 @@ version: '3' services: elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:8.16.2 - environment: ['ES_JAVA_OPTS=-Xms2g -Xmx2g','bootstrap.memory_lock=true','discovery.type=single-node','xpack.security.enabled=false', 'xpack.security.enrollment.enabled=false'] + environment: [ + 'ES_JAVA_OPTS=-Xms2g -Xmx2g', + 'bootstrap.memory_lock=true', + 'discovery.type=single-node', + 'xpack.security.enabled=false', + 'xpack.security.enrollment.enabled=false', + 'cluster.routing.allocation.disk.watermark.low=600mb', + 'cluster.routing.allocation.disk.watermark.high=500mb', + 'cluster.routing.allocation.disk.watermark.flood_stage=400mb' + ] ports: - 9200:9200 networks: @@ -30,7 +39,7 @@ services: image: minio/minio:latest environment: MINIO_ACCESS_KEY: minio123 - MINIO_SECRET_KEY: 9f97d6bcfe2d2130 + MINIO_SECRET_KEY: minio123 ports: - 9000:9000 command: server /data @@ -42,7 +51,7 @@ services: entrypoint: > /bin/sh -c " sleep 3; - /usr/bin/mc alias set myminio http://minio:9000 minio123 9f97d6bcfe2d2130; + /usr/bin/mc alias set myminio http://minio:9000 minio123 minio123; /usr/bin/mc mb myminio/images; exit 0; " From ada0fba8f8a8e04a6f7ed31cd142aec3a48f63a0 Mon Sep 17 00:00:00 2001 From: weoses Date: Sun, 16 Nov 2025 20:02:25 +0300 Subject: [PATCH 04/10] telegram and storage service - error passtrought, new apis --- apispec/meme-storage/api.yml | 62 ++++++++ apispec/meme-storage/client/api.gen.go | 145 +++++++++++++----- apispec/meme-storage/server/api.gen.go | 82 +++++++++- common/commonhelper/util.go | 7 + .../src/service/ApiHandlerService.go | 23 ++- storage-service/src/utils/AlphabetFix.go | 32 ---- .../src/service/InlineHandlerService.go | 7 +- .../src/service/StorageConnector.go | 43 +++--- 8 files changed, 298 insertions(+), 103 deletions(-) delete mode 100644 storage-service/src/utils/AlphabetFix.go diff --git a/apispec/meme-storage/api.yml b/apispec/meme-storage/api.yml index 6eef84c..8b8f4e2 100644 --- a/apispec/meme-storage/api.yml +++ b/apispec/meme-storage/api.yml @@ -13,6 +13,12 @@ paths: responses: 200: description: ok + 500: + description: error + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponseDto" /api/v1/accounts/{AccountId}/update-ocr: post: parameters: @@ -21,6 +27,12 @@ paths: responses: 200: description: ok + 500: + description: error + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponseDto" /api/v1/accounts/{AccountId}/update-ocr/{MemeId}: post: @@ -31,6 +43,12 @@ paths: responses: 200: description: ok + 500: + description: error + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponseDto" /api/v1/accounts/{AccountId}/meme: get: @@ -49,6 +67,12 @@ paths: type: array items: $ref: "#/components/schemas/SearchMemeResponseItemDto" + 500: + description: error + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponseDto" post: operationId: "CreateMeme" parameters: @@ -65,6 +89,12 @@ paths: application/json: schema: $ref: "#/components/schemas/CreateMemeResponseDto" + 500: + description: error + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponseDto" /api/v1/accounts/{AccountId}/meme/{MemeId}/image/url: @@ -80,6 +110,12 @@ paths: application/json: schema: $ref: "#/components/schemas/ImageUrlDto" + 500: + description: error + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponseDto" /api/v1/accounts/{AccountId}/meme/{MemeId}: delete: @@ -90,6 +126,12 @@ paths: responses: 200: description: ok + 500: + description: error + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponseDto" /api/v1/accounts/{AccountId}/meme/{MemeId}/image/thumb/url: get: @@ -104,6 +146,12 @@ paths: application/json: schema: $ref: "#/components/schemas/ImageUrlDto" + 500: + description: error + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponseDto" components: parameters: Query: @@ -162,6 +210,11 @@ components: CreateMemeResponseDto: type: object + required: + - Id + - OcrResult + - Hash + - DuplicateStatus properties: Id: type: string @@ -185,6 +238,8 @@ components: type: object required: - Url + - Width + - Height properties: Url: type: string @@ -200,3 +255,10 @@ components: - duplicate_hash - new + ErrorResponseDto: + type: object + properties: + message: + type: string + error: + type: string \ No newline at end of file diff --git a/apispec/meme-storage/client/api.gen.go b/apispec/meme-storage/client/api.gen.go index 138d7c2..157c3ce 100644 --- a/apispec/meme-storage/client/api.gen.go +++ b/apispec/meme-storage/client/api.gen.go @@ -1,6 +1,6 @@ // Package client provides primitives to interact with the openapi HTTP API. // -// Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.4.1 DO NOT EDIT. +// Code generated by github.com/deepmap/oapi-codegen/v2 version v2.2.0 DO NOT EDIT. package client import ( @@ -24,44 +24,43 @@ const ( New DuplicateStatus = "new" ) +// CreateImageRequestDto defines model for CreateImageRequestDto. +type CreateImageRequestDto struct { + ImageBase64 string `json:"ImageBase64"` +} + // CreateMemeResponseDto defines model for CreateMemeResponseDto. type CreateMemeResponseDto struct { - DuplicateStatus *DuplicateStatus `json:"DuplicateStatus,omitempty"` - Hash *string `json:"Hash,omitempty"` - Id *openapi_types.UUID `json:"Id,omitempty"` - OcrResult *string `json:"OcrResult,omitempty"` + DuplicateStatus DuplicateStatus `json:"DuplicateStatus"` + Hash string `json:"Hash"` + Id openapi_types.UUID `json:"Id"` + OcrResult string `json:"OcrResult"` } // DuplicateStatus defines model for DuplicateStatus. type DuplicateStatus string -// ImageDto defines model for ImageDto. -type ImageDto struct { - ImageBase64 *string `json:"ImageBase64,omitempty"` - MimeType *string `json:"MimeType,omitempty"` +// ErrorResponseDto defines model for ErrorResponseDto. +type ErrorResponseDto struct { + Error *string `json:"error,omitempty"` + Message *string `json:"message,omitempty"` } // ImageUrlDto defines model for ImageUrlDto. type ImageUrlDto struct { - Url *string `json:"Url,omitempty"` -} - -// SearchMemeDto defines model for SearchMemeDto. -type SearchMemeDto struct { - Hash *string `json:"Hash,omitempty"` - Id *openapi_types.UUID `json:"Id,omitempty"` - ImageUrl *string `json:"ImageUrl,omitempty"` - OcrResult *string `json:"OcrResult,omitempty"` - OcrResultHighlight *[]string `json:"OcrResultHighlight,omitempty"` - SortId *int64 `json:"SortId,omitempty"` - Thumbnail *SearchMemeThumb `json:"Thumbnail,omitempty"` + Height int `json:"Height"` + Url string `json:"Url"` + Width int `json:"Width"` } -// SearchMemeThumb defines model for SearchMemeThumb. -type SearchMemeThumb struct { - ThumbHeight *int `json:"ThumbHeight,omitempty"` - ThumbUrl *string `json:"ThumbUrl,omitempty"` - ThumbWidth *int `json:"ThumbWidth,omitempty"` +// SearchMemeResponseItemDto defines model for SearchMemeResponseItemDto. +type SearchMemeResponseItemDto struct { + Hash *string `json:"Hash,omitempty"` + Id *openapi_types.UUID `json:"Id,omitempty"` + Image *ImageUrlDto `json:"Image,omitempty"` + OcrResult *string `json:"OcrResult,omitempty"` + SortId *int64 `json:"SortId,omitempty"` + Thumbnail *ImageUrlDto `json:"Thumbnail,omitempty"` } // AccountId defines model for AccountId. @@ -70,24 +69,24 @@ type AccountId = openapi_types.UUID // MemeId defines model for MemeId. type MemeId = openapi_types.UUID -// MemeQuery defines model for MemeQuery. -type MemeQuery = string - // PageSize defines model for PageSize. type PageSize = int +// Query defines model for Query. +type Query = string + // SearchAfterId defines model for SearchAfterId. type SearchAfterId = int64 // SearchMemeParams defines parameters for SearchMeme. type SearchMemeParams struct { - MemeQuery MemeQuery `form:"MemeQuery" json:"MemeQuery"` + Query Query `form:"Query" json:"Query"` SearchAfterSortId *SearchAfterId `form:"SearchAfterSortId,omitempty" json:"SearchAfterSortId,omitempty"` PageSize *PageSize `form:"PageSize,omitempty" json:"PageSize,omitempty"` } // CreateMemeJSONRequestBody defines body for CreateMeme for application/json ContentType. -type CreateMemeJSONRequestBody = ImageDto +type CreateMemeJSONRequestBody = CreateImageRequestDto // RequestEditorFn is the function signature for the RequestEditor callback function type RequestEditorFn func(ctx context.Context, req *http.Request) error @@ -360,7 +359,7 @@ func NewSearchMemeRequest(server string, accountId AccountId, params *SearchMeme if params != nil { queryValues := queryURL.Query() - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "MemeQuery", runtime.ParamLocationQuery, params.MemeQuery); err != nil { + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "Query", runtime.ParamLocationQuery, params.Query); err != nil { return nil, err } else if parsed, err := url.ParseQuery(queryFrag); err != nil { return nil, err @@ -495,7 +494,7 @@ func NewDeleteMemeRequest(server string, accountId AccountId, memeId MemeId) (*h return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest("DELETE", queryURL.String(), nil) if err != nil { return nil, err } @@ -733,6 +732,7 @@ type ClientWithResponsesInterface interface { type CheckDuplicatesResponse struct { Body []byte HTTPResponse *http.Response + JSON500 *ErrorResponseDto } // Status returns HTTPResponse.Status @@ -754,7 +754,8 @@ func (r CheckDuplicatesResponse) StatusCode() int { type SearchMemeResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *[]SearchMemeDto + JSON200 *[]SearchMemeResponseItemDto + JSON500 *ErrorResponseDto } // Status returns HTTPResponse.Status @@ -777,6 +778,7 @@ type CreateMemeResponse struct { Body []byte HTTPResponse *http.Response JSON200 *CreateMemeResponseDto + JSON500 *ErrorResponseDto } // Status returns HTTPResponse.Status @@ -798,6 +800,7 @@ func (r CreateMemeResponse) StatusCode() int { type DeleteMemeResponse struct { Body []byte HTTPResponse *http.Response + JSON500 *ErrorResponseDto } // Status returns HTTPResponse.Status @@ -820,6 +823,7 @@ type GetMemeImageThumbUrlResponse struct { Body []byte HTTPResponse *http.Response JSON200 *ImageUrlDto + JSON500 *ErrorResponseDto } // Status returns HTTPResponse.Status @@ -842,6 +846,7 @@ type GetMemeImageUrlResponse struct { Body []byte HTTPResponse *http.Response JSON200 *ImageUrlDto + JSON500 *ErrorResponseDto } // Status returns HTTPResponse.Status @@ -863,6 +868,7 @@ func (r GetMemeImageUrlResponse) StatusCode() int { type UpdateOcrResponse struct { Body []byte HTTPResponse *http.Response + JSON500 *ErrorResponseDto } // Status returns HTTPResponse.Status @@ -884,6 +890,7 @@ func (r UpdateOcrResponse) StatusCode() int { type UpdateOcrOneResponse struct { Body []byte HTTPResponse *http.Response + JSON500 *ErrorResponseDto } // Status returns HTTPResponse.Status @@ -995,6 +1002,16 @@ func ParseCheckDuplicatesResponse(rsp *http.Response) (*CheckDuplicatesResponse, HTTPResponse: rsp, } + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest ErrorResponseDto + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + return response, nil } @@ -1013,12 +1030,19 @@ func ParseSearchMemeResponse(rsp *http.Response) (*SearchMemeResponse, error) { switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest []SearchMemeDto + var dest []SearchMemeResponseItemDto if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } response.JSON200 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest ErrorResponseDto + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + } return response, nil @@ -1045,6 +1069,13 @@ func ParseCreateMemeResponse(rsp *http.Response) (*CreateMemeResponse, error) { } response.JSON200 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest ErrorResponseDto + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + } return response, nil @@ -1063,6 +1094,16 @@ func ParseDeleteMemeResponse(rsp *http.Response) (*DeleteMemeResponse, error) { HTTPResponse: rsp, } + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest ErrorResponseDto + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + return response, nil } @@ -1087,6 +1128,13 @@ func ParseGetMemeImageThumbUrlResponse(rsp *http.Response) (*GetMemeImageThumbUr } response.JSON200 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest ErrorResponseDto + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + } return response, nil @@ -1113,6 +1161,13 @@ func ParseGetMemeImageUrlResponse(rsp *http.Response) (*GetMemeImageUrlResponse, } response.JSON200 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest ErrorResponseDto + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + } return response, nil @@ -1131,6 +1186,16 @@ func ParseUpdateOcrResponse(rsp *http.Response) (*UpdateOcrResponse, error) { HTTPResponse: rsp, } + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest ErrorResponseDto + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + return response, nil } @@ -1147,5 +1212,15 @@ func ParseUpdateOcrOneResponse(rsp *http.Response) (*UpdateOcrOneResponse, error HTTPResponse: rsp, } + switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 500: + var dest ErrorResponseDto + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON500 = &dest + + } + return response, nil } diff --git a/apispec/meme-storage/server/api.gen.go b/apispec/meme-storage/server/api.gen.go index af3eaf5..deba1a1 100644 --- a/apispec/meme-storage/server/api.gen.go +++ b/apispec/meme-storage/server/api.gen.go @@ -38,11 +38,17 @@ type CreateMemeResponseDto struct { // DuplicateStatus defines model for DuplicateStatus. type DuplicateStatus string +// ErrorResponseDto defines model for ErrorResponseDto. +type ErrorResponseDto struct { + Error *string `json:"error,omitempty"` + Message *string `json:"message,omitempty"` +} + // ImageUrlDto defines model for ImageUrlDto. type ImageUrlDto struct { - Height *int `json:"Height,omitempty"` + Height int `json:"Height"` Url string `json:"Url"` - Width *int `json:"Width,omitempty"` + Width int `json:"Width"` } // SearchMemeResponseItemDto defines model for SearchMemeResponseItemDto. @@ -351,6 +357,15 @@ func (response CheckDuplicates200Response) VisitCheckDuplicatesResponse(w http.R return nil } +type CheckDuplicates500JSONResponse ErrorResponseDto + +func (response CheckDuplicates500JSONResponse) VisitCheckDuplicatesResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(500) + + return json.NewEncoder(w).Encode(response) +} + type SearchMemeRequestObject struct { AccountId AccountId `json:"AccountId"` Params SearchMemeParams @@ -369,6 +384,15 @@ func (response SearchMeme200JSONResponse) VisitSearchMemeResponse(w http.Respons return json.NewEncoder(w).Encode(response) } +type SearchMeme500JSONResponse ErrorResponseDto + +func (response SearchMeme500JSONResponse) VisitSearchMemeResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(500) + + return json.NewEncoder(w).Encode(response) +} + type CreateMemeRequestObject struct { AccountId AccountId `json:"AccountId"` Body *CreateMemeJSONRequestBody @@ -387,6 +411,15 @@ func (response CreateMeme200JSONResponse) VisitCreateMemeResponse(w http.Respons return json.NewEncoder(w).Encode(response) } +type CreateMeme500JSONResponse ErrorResponseDto + +func (response CreateMeme500JSONResponse) VisitCreateMemeResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(500) + + return json.NewEncoder(w).Encode(response) +} + type DeleteMemeRequestObject struct { AccountId AccountId `json:"AccountId"` MemeId MemeId `json:"MemeId"` @@ -404,6 +437,15 @@ func (response DeleteMeme200Response) VisitDeleteMemeResponse(w http.ResponseWri return nil } +type DeleteMeme500JSONResponse ErrorResponseDto + +func (response DeleteMeme500JSONResponse) VisitDeleteMemeResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(500) + + return json.NewEncoder(w).Encode(response) +} + type GetMemeImageThumbUrlRequestObject struct { AccountId AccountId `json:"AccountId"` MemeId MemeId `json:"MemeId"` @@ -422,6 +464,15 @@ func (response GetMemeImageThumbUrl200JSONResponse) VisitGetMemeImageThumbUrlRes return json.NewEncoder(w).Encode(response) } +type GetMemeImageThumbUrl500JSONResponse ErrorResponseDto + +func (response GetMemeImageThumbUrl500JSONResponse) VisitGetMemeImageThumbUrlResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(500) + + return json.NewEncoder(w).Encode(response) +} + type GetMemeImageUrlRequestObject struct { AccountId AccountId `json:"AccountId"` MemeId MemeId `json:"MemeId"` @@ -440,6 +491,15 @@ func (response GetMemeImageUrl200JSONResponse) VisitGetMemeImageUrlResponse(w ht return json.NewEncoder(w).Encode(response) } +type GetMemeImageUrl500JSONResponse ErrorResponseDto + +func (response GetMemeImageUrl500JSONResponse) VisitGetMemeImageUrlResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(500) + + return json.NewEncoder(w).Encode(response) +} + type UpdateOcrRequestObject struct { AccountId AccountId `json:"AccountId"` } @@ -456,6 +516,15 @@ func (response UpdateOcr200Response) VisitUpdateOcrResponse(w http.ResponseWrite return nil } +type UpdateOcr500JSONResponse ErrorResponseDto + +func (response UpdateOcr500JSONResponse) VisitUpdateOcrResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(500) + + return json.NewEncoder(w).Encode(response) +} + type UpdateOcrOneRequestObject struct { AccountId AccountId `json:"AccountId"` MemeId MemeId `json:"MemeId"` @@ -473,6 +542,15 @@ func (response UpdateOcrOne200Response) VisitUpdateOcrOneResponse(w http.Respons return nil } +type UpdateOcrOne500JSONResponse ErrorResponseDto + +func (response UpdateOcrOne500JSONResponse) VisitUpdateOcrOneResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(500) + + return json.NewEncoder(w).Encode(response) +} + // StrictServerInterface represents all server handlers. type StrictServerInterface interface { diff --git a/common/commonhelper/util.go b/common/commonhelper/util.go index dd05f48..cea9f1b 100644 --- a/common/commonhelper/util.go +++ b/common/commonhelper/util.go @@ -1,3 +1,10 @@ package commonhelper func Addr[T any](v T) *T { return &v } + +func DefaultString(item *string) string { + if item == nil { + return "" + } + return *item +} diff --git a/storage-service/src/service/ApiHandlerService.go b/storage-service/src/service/ApiHandlerService.go index da24043..b344793 100644 --- a/storage-service/src/service/ApiHandlerService.go +++ b/storage-service/src/service/ApiHandlerService.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "log/slog" - "strings" "time" "github.com/adrg/strutil/metrics" @@ -92,9 +91,9 @@ func (a *ApiHandler) CreateMeme( return nil, err } - if strings.TrimSpace(ocrTextResult) == "" { - return nil, errors.New("no text on image") - } + //if strings.TrimSpace(ocrTextResult) == "" { + // return nil, errors.New("no text on image") + //} if contentDuplicate != nil { contentDuplicateTextResult := contentDuplicate.Result @@ -183,13 +182,13 @@ func (a *ApiHandler) SearchMeme(ctx context.Context, request server.SearchMemeRe Id: &metadataItem.ImageId, Image: &server.ImageUrlDto{ Url: imageUrl, - Height: &metadataItem.ImageSize.Height, - Width: &metadataItem.ImageSize.Width, + Height: metadataItem.ImageSize.Height, + Width: metadataItem.ImageSize.Width, }, Thumbnail: &server.ImageUrlDto{ Url: imageThumbUrl, - Height: &metadataItem.ThumbSize.Height, - Width: &metadataItem.ThumbSize.Width, + Height: metadataItem.ThumbSize.Height, + Width: metadataItem.ThumbSize.Width, }, OcrResult: &metadataItem.Result, SortId: &metadataItem.Created, @@ -325,8 +324,8 @@ func (a *ApiHandler) GetMemeImageThumbUrl(ctx context.Context, request server.Ge resp := &server.GetMemeImageThumbUrl200JSONResponse{ Url: url, - Height: &memeMetadata.ThumbSize.Height, - Width: &memeMetadata.ThumbSize.Width, + Height: memeMetadata.ThumbSize.Height, + Width: memeMetadata.ThumbSize.Width, } return resp, nil } @@ -353,8 +352,8 @@ func (a *ApiHandler) GetMemeImageUrl(ctx context.Context, request server.GetMeme resp := &server.GetMemeImageUrl200JSONResponse{ Url: url, - Height: &memeMetadata.ImageSize.Height, - Width: &memeMetadata.ImageSize.Width, + Height: memeMetadata.ImageSize.Height, + Width: memeMetadata.ImageSize.Width, } return resp, nil } diff --git a/storage-service/src/utils/AlphabetFix.go b/storage-service/src/utils/AlphabetFix.go deleted file mode 100644 index b608089..0000000 --- a/storage-service/src/utils/AlphabetFix.go +++ /dev/null @@ -1,32 +0,0 @@ -package utils - -import "strings" - -var duplicates = map[rune]rune{ - 'а': 'a', - 'в': 'b', - 'е': 'e', - 'к': 'k', - 'м': 'm', - 'о': 'o', - 'р': 'p', - 'с': 'c', - 'т': 't', - 'у': 'y', - 'х': 'x', -} - -func AlphabetFix(incoming string) string { - lowerCased := strings.ToLower(incoming) - builder := strings.Builder{} - - for _, char := range lowerCased { - charReplacement, ok := duplicates[char] - if ok { - builder.WriteRune(charReplacement) - } else { - builder.WriteRune(char) - } - } - return builder.String() -} diff --git a/telegram-service/src/service/InlineHandlerService.go b/telegram-service/src/service/InlineHandlerService.go index 94254ab..3532198 100644 --- a/telegram-service/src/service/InlineHandlerService.go +++ b/telegram-service/src/service/InlineHandlerService.go @@ -3,12 +3,13 @@ package service import ( "context" "fmt" - "github.com/google/uuid" "log/slog" - "mine.local/ocr-gallery/common/commonconst" "strconv" "strings" + "github.com/google/uuid" + "mine.local/ocr-gallery/common/commonconst" + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" "mine.local/ocr-gallery/telegram-service/conf" ) @@ -105,7 +106,7 @@ func (i *InineHandlerServiceImpl) ProcessQuery( searchAfter, ) if err != nil { - return nil, err + return nil, fmt.Errorf("ProcessSearchQuery failed: %w", err) } slog.Info("Search query result", diff --git a/telegram-service/src/service/StorageConnector.go b/telegram-service/src/service/StorageConnector.go index c0b1a48..5cf1fac 100644 --- a/telegram-service/src/service/StorageConnector.go +++ b/telegram-service/src/service/StorageConnector.go @@ -4,11 +4,11 @@ import ( "bytes" "context" "encoding/base64" - "errors" "fmt" "github.com/google/uuid" "mine.local/ocr-gallery/apispec/meme-storage/client" + "mine.local/ocr-gallery/common/commonhelper" "mine.local/ocr-gallery/telegram-service/conf" "mine.local/ocr-gallery/telegram-service/entity" ) @@ -56,7 +56,7 @@ func (s *StorageConnectorImpl) ProcessSearchQuery( ctx, accountId, &client.SearchMemeParams{ - MemeQuery: query, + Query: query, PageSize: &pageSize, SearchAfterSortId: searchAfterSortId, }) @@ -65,18 +65,23 @@ func (s *StorageConnectorImpl) ProcessSearchQuery( return nil, fmt.Errorf("storageService: search meme query failed query: %s : %w", query, err) } + if response.HTTPResponse.StatusCode == 500 { + errorMessage := response.JSON500.Error + return nil, fmt.Errorf("storageService: failed to request storage service: %v", errorMessage) + } + if response.HTTPResponse.StatusCode >= 400 { - return nil, fmt.Errorf("storageService: failed to request storage service: %s", string(response.Body)) + return nil, fmt.Errorf("storageService: failed to request storage service") } entityResult := make([]*entity.MemeSearchResult, len(*response.JSON200)) for i, dto := range *response.JSON200 { entityResult[i] = &entity.MemeSearchResult{ Id: *dto.Id, - ImageUrl: *dto.ImageUrl, - ThumbUrl: *dto.Thumbnail.ThumbUrl, - ThumbWidth: *dto.Thumbnail.ThumbWidth, - ThumbHeight: *dto.Thumbnail.ThumbHeight, + ImageUrl: dto.Image.Url, + ThumbUrl: dto.Thumbnail.Url, + ThumbWidth: dto.Thumbnail.Width, + ThumbHeight: dto.Thumbnail.Height, SortId: *dto.SortId, } } @@ -92,31 +97,31 @@ func (u *StorageConnectorImpl) CreateMeme(ctx context.Context, file []byte, mime data := strbuf.String() reqBody := client.CreateMemeJSONRequestBody{} - reqBody.ImageBase64 = &data - reqBody.MimeType = &mime + reqBody.ImageBase64 = data - resp, err := u.cl.CreateMemeWithResponse( + response, err := u.cl.CreateMemeWithResponse( ctx, accountId, reqBody, ) if err != nil { - return nil, fmt.Errorf("storageService: create meme failed : %w", err) + return nil, fmt.Errorf("storageService: create meme failed: %w", err) } - if resp.StatusCode() != 200 { - return nil, errors.New("storageService: create meme failed : storage service status code non 2xx ") + if response.HTTPResponse.StatusCode == 500 { + errorMessage := response.JSON500.Error + return nil, fmt.Errorf("storageService: failed to request storage service: %s", commonhelper.DefaultString(errorMessage)) } - creationResult := &entity.MemeCreateResult{ - Id: *resp.JSON200.Id, - Text: *resp.JSON200.OcrResult, + if response.HTTPResponse.StatusCode >= 400 { + return nil, fmt.Errorf("storageService: failed to request storage service") } - - if resp.JSON200.DuplicateStatus != nil { - creationResult.DuplicateStatus = string(*resp.JSON200.DuplicateStatus) + creationResult := &entity.MemeCreateResult{ + Id: response.JSON200.Id, + Text: response.JSON200.OcrResult, } + creationResult.DuplicateStatus = string(response.JSON200.DuplicateStatus) return creationResult, nil } From 9a15f1dde249f2f9a8d0ef14ff386869b23df7ed Mon Sep 17 00:00:00 2001 From: weoses Date: Sun, 16 Nov 2025 20:02:25 +0300 Subject: [PATCH 05/10] idea run configurations --- .idea/runConfigurations/OCR.xml | 11 +++++++++++ .idea/runConfigurations/STORAGE.xml | 11 +++++++++++ .idea/runConfigurations/TELEGRAM.xml | 11 +++++++++++ 3 files changed, 33 insertions(+) create mode 100644 .idea/runConfigurations/OCR.xml create mode 100644 .idea/runConfigurations/STORAGE.xml create mode 100644 .idea/runConfigurations/TELEGRAM.xml diff --git a/.idea/runConfigurations/OCR.xml b/.idea/runConfigurations/OCR.xml new file mode 100644 index 0000000..a0bdc2c --- /dev/null +++ b/.idea/runConfigurations/OCR.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/STORAGE.xml b/.idea/runConfigurations/STORAGE.xml new file mode 100644 index 0000000..3fad47f --- /dev/null +++ b/.idea/runConfigurations/STORAGE.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/TELEGRAM.xml b/.idea/runConfigurations/TELEGRAM.xml new file mode 100644 index 0000000..a812249 --- /dev/null +++ b/.idea/runConfigurations/TELEGRAM.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file From ecb12306819f1e6b8841e010ba4c26107d3646e1 Mon Sep 17 00:00:00 2001 From: weoses Date: Sun, 16 Nov 2025 20:02:25 +0300 Subject: [PATCH 06/10] gitignore --- .gitignore | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 97fb1de..3098b1e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,8 @@ config.yml -.vscode \ No newline at end of file +.vscode +.idea/* +!.idea/runConfigurations + +ocr-service/src/config.yml +storage-service-service/src/config.yml +telegram-service-service-service/src/config.yml \ No newline at end of file From fdc2216960b73bd225e1c5f7ad1bd3bc3c38eef4 Mon Sep 17 00:00:00 2001 From: weoses Date: Sun, 16 Nov 2025 20:02:25 +0300 Subject: [PATCH 07/10] package rename --- apispec/go.mod | 2 +- common/go.mod | 2 +- ocr-service/src/api/ApiHandler.go | 4 ++-- ocr-service/src/go.mod | 2 +- ocr-service/src/main.go | 12 ++++++------ ocr-service/src/service/ImageConvertor.go | 4 ++-- ocr-service/src/service/ImageEmbedder.go | 4 ++-- ocr-service/src/service/ImageService.go | 6 +++--- ocr-service/src/service/OcrProcessor.go | 2 +- storage-service/src/go.mod | 2 +- storage-service/src/helper/helper.go | 6 +++--- storage-service/src/main.go | 10 +++++----- storage-service/src/service/ApiHandlerService.go | 10 +++++----- .../src/service/ElasticMetadataStorageServiceImpl.go | 8 ++++---- storage-service/src/service/OcrService.go | 8 ++++---- storage-service/src/service/S3ImageStorageService.go | 2 +- storage-service/src/tools/go.mod | 2 +- telegram-service/src/go.mod | 2 +- telegram-service/src/main.go | 6 +++--- telegram-service/src/service/InlineHandlerService.go | 4 ++-- .../src/service/MessageHandlerService.go | 2 +- telegram-service/src/service/StorageConnector.go | 8 ++++---- telegram-service/src/service/Telegram.go | 4 ++-- telegram-service/src/service/UserAccountService.go | 4 ++-- 24 files changed, 58 insertions(+), 58 deletions(-) diff --git a/apispec/go.mod b/apispec/go.mod index 7c4cbba..e17fa4e 100644 --- a/apispec/go.mod +++ b/apispec/go.mod @@ -1,4 +1,4 @@ -module mine.local/ocr-gallery/apispec +module github.com/weoses/memelo/apispec go 1.24.10 diff --git a/common/go.mod b/common/go.mod index 63ef617..f79d88d 100644 --- a/common/go.mod +++ b/common/go.mod @@ -1,4 +1,4 @@ -module mine.local/ocr-gallery/common +module github.com/weoses/memelo/common go 1.24.10 diff --git a/ocr-service/src/api/ApiHandler.go b/ocr-service/src/api/ApiHandler.go index e6dfd40..0e9119f 100644 --- a/ocr-service/src/api/ApiHandler.go +++ b/ocr-service/src/api/ApiHandler.go @@ -3,8 +3,8 @@ package api import ( "context" - "mine.local/ocr-gallery/apispec/ocr-server/server" - "mine.local/ocr-gallery/ocr-server/service" + "github.com/weoses/memelo/apispec/ocr-server/server" + "github.com/weoses/memelo/ocr-server/service" ) type Handler struct { diff --git a/ocr-service/src/go.mod b/ocr-service/src/go.mod index 5e20231..f1d4b2b 100644 --- a/ocr-service/src/go.mod +++ b/ocr-service/src/go.mod @@ -1,4 +1,4 @@ -module mine.local/ocr-gallery/ocr-server +module github.com/weoses/memelo/ocr-server go 1.23.2 diff --git a/ocr-service/src/main.go b/ocr-service/src/main.go index d157a4a..67c46b6 100644 --- a/ocr-service/src/main.go +++ b/ocr-service/src/main.go @@ -3,13 +3,13 @@ package main import ( "github.com/labstack/echo/v4" oapiEcho "github.com/oapi-codegen/runtime/strictmiddleware/echo" + "github.com/weoses/memelo/apispec/ocr-server/server" + "github.com/weoses/memelo/common/commonconfig" + "github.com/weoses/memelo/common/commonmiddleware" + "github.com/weoses/memelo/ocr-server/api" + "github.com/weoses/memelo/ocr-server/conf" + "github.com/weoses/memelo/ocr-server/service" "go.uber.org/fx" - "mine.local/ocr-gallery/apispec/ocr-server/server" - "mine.local/ocr-gallery/common/commonconfig" - "mine.local/ocr-gallery/common/commonmiddleware" - "mine.local/ocr-gallery/ocr-server/api" - "mine.local/ocr-gallery/ocr-server/conf" - "mine.local/ocr-gallery/ocr-server/service" ) func main() { diff --git a/ocr-service/src/service/ImageConvertor.go b/ocr-service/src/service/ImageConvertor.go index 520ac03..a6ca253 100644 --- a/ocr-service/src/service/ImageConvertor.go +++ b/ocr-service/src/service/ImageConvertor.go @@ -5,8 +5,8 @@ import ( "github.com/h2non/bimg" "github.com/pkg/errors" - "mine.local/ocr-gallery/ocr-server/conf" - "mine.local/ocr-gallery/ocr-server/entity" + "github.com/weoses/memelo/ocr-server/conf" + "github.com/weoses/memelo/ocr-server/entity" ) type ImageConveter interface { diff --git a/ocr-service/src/service/ImageEmbedder.go b/ocr-service/src/service/ImageEmbedder.go index 3116f06..66fb86c 100644 --- a/ocr-service/src/service/ImageEmbedder.go +++ b/ocr-service/src/service/ImageEmbedder.go @@ -9,11 +9,11 @@ import ( aiplatform "cloud.google.com/go/aiplatform/apiv1beta1" aiplatformpb "cloud.google.com/go/aiplatform/apiv1beta1/aiplatformpb" + "github.com/weoses/memelo/ocr-server/conf" + "github.com/weoses/memelo/ocr-server/entity" "google.golang.org/api/option" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/types/known/structpb" - "mine.local/ocr-gallery/ocr-server/conf" - "mine.local/ocr-gallery/ocr-server/entity" ) type ImageEmbeddingExtractor interface { diff --git a/ocr-service/src/service/ImageService.go b/ocr-service/src/service/ImageService.go index 0940a62..a515e78 100644 --- a/ocr-service/src/service/ImageService.go +++ b/ocr-service/src/service/ImageService.go @@ -9,9 +9,9 @@ import ( "strings" "github.com/pkg/errors" - "mine.local/ocr-gallery/apispec/ocr-server/server" - "mine.local/ocr-gallery/common/commonerror" - "mine.local/ocr-gallery/ocr-server/entity" + "github.com/weoses/memelo/apispec/ocr-server/server" + "github.com/weoses/memelo/common/commonerror" + "github.com/weoses/memelo/ocr-server/entity" ) type ImageService interface { diff --git a/ocr-service/src/service/OcrProcessor.go b/ocr-service/src/service/OcrProcessor.go index fd4fa17..9a4bd64 100644 --- a/ocr-service/src/service/OcrProcessor.go +++ b/ocr-service/src/service/OcrProcessor.go @@ -5,7 +5,7 @@ import ( "context" vision "cloud.google.com/go/vision/apiv1" - "mine.local/ocr-gallery/ocr-server/entity" + "github.com/weoses/memelo/ocr-server/entity" ) type OcrProcessor interface { diff --git a/storage-service/src/go.mod b/storage-service/src/go.mod index 705ed13..06ed9a7 100644 --- a/storage-service/src/go.mod +++ b/storage-service/src/go.mod @@ -1,4 +1,4 @@ -module mine.local/ocr-gallery/storage-service +module github.com/weoses/memelo/storage-service go 1.23.2 diff --git a/storage-service/src/helper/helper.go b/storage-service/src/helper/helper.go index b02a048..3117f73 100644 --- a/storage-service/src/helper/helper.go +++ b/storage-service/src/helper/helper.go @@ -4,9 +4,9 @@ import ( "crypto/md5" "encoding/hex" - "mine.local/ocr-gallery/apispec/meme-storage/server" - "mine.local/ocr-gallery/apispec/ocr-server/client" - "mine.local/ocr-gallery/storage-service/entity" + "github.com/weoses/memelo/apispec/meme-storage/server" + "github.com/weoses/memelo/apispec/ocr-server/client" + "github.com/weoses/memelo/storage-service/entity" ) func CalcHash(base64Image string) string { diff --git a/storage-service/src/main.go b/storage-service/src/main.go index e0866a6..eb2724e 100644 --- a/storage-service/src/main.go +++ b/storage-service/src/main.go @@ -4,12 +4,12 @@ import ( "github.com/go-playground/validator/v10" "github.com/labstack/echo/v4" oapiEcho "github.com/oapi-codegen/runtime/strictmiddleware/echo" + "github.com/weoses/memelo/apispec/meme-storage/server" + "github.com/weoses/memelo/common/commonconfig" + "github.com/weoses/memelo/common/commonmiddleware" + "github.com/weoses/memelo/storage-service/conf" + "github.com/weoses/memelo/storage-service/service" "go.uber.org/fx" - "mine.local/ocr-gallery/apispec/meme-storage/server" - "mine.local/ocr-gallery/common/commonconfig" - "mine.local/ocr-gallery/common/commonmiddleware" - "mine.local/ocr-gallery/storage-service/conf" - "mine.local/ocr-gallery/storage-service/service" ) func main() { diff --git a/storage-service/src/service/ApiHandlerService.go b/storage-service/src/service/ApiHandlerService.go index b344793..c661de4 100644 --- a/storage-service/src/service/ApiHandlerService.go +++ b/storage-service/src/service/ApiHandlerService.go @@ -8,15 +8,15 @@ import ( "time" "github.com/adrg/strutil/metrics" - "mine.local/ocr-gallery/common/commonhelper" + "github.com/weoses/memelo/common/commonhelper" "github.com/adrg/strutil" "github.com/go-playground/validator/v10" "github.com/google/uuid" - "mine.local/ocr-gallery/apispec/meme-storage/server" - "mine.local/ocr-gallery/common/commonconst" - "mine.local/ocr-gallery/storage-service/entity" - "mine.local/ocr-gallery/storage-service/helper" + "github.com/weoses/memelo/apispec/meme-storage/server" + "github.com/weoses/memelo/common/commonconst" + "github.com/weoses/memelo/storage-service/entity" + "github.com/weoses/memelo/storage-service/helper" ) type ApiHandler struct { diff --git a/storage-service/src/service/ElasticMetadataStorageServiceImpl.go b/storage-service/src/service/ElasticMetadataStorageServiceImpl.go index 3c04f97..d115441 100644 --- a/storage-service/src/service/ElasticMetadataStorageServiceImpl.go +++ b/storage-service/src/service/ElasticMetadataStorageServiceImpl.go @@ -15,10 +15,10 @@ import ( "github.com/gdexlab/go-render/render" "github.com/go-playground/validator/v10" "github.com/google/uuid" - "mine.local/ocr-gallery/common/commonconst" - "mine.local/ocr-gallery/common/commonhelper" - "mine.local/ocr-gallery/storage-service/conf" - "mine.local/ocr-gallery/storage-service/entity" + "github.com/weoses/memelo/common/commonconst" + "github.com/weoses/memelo/common/commonhelper" + "github.com/weoses/memelo/storage-service/conf" + "github.com/weoses/memelo/storage-service/entity" ) const IndexName = "image-metadata" diff --git a/storage-service/src/service/OcrService.go b/storage-service/src/service/OcrService.go index 699518c..32d78c2 100644 --- a/storage-service/src/service/OcrService.go +++ b/storage-service/src/service/OcrService.go @@ -7,10 +7,10 @@ import ( "strings" "github.com/go-playground/validator/v10" - "mine.local/ocr-gallery/apispec/ocr-server/client" - "mine.local/ocr-gallery/storage-service/conf" - "mine.local/ocr-gallery/storage-service/entity" - "mine.local/ocr-gallery/storage-service/helper" + "github.com/weoses/memelo/apispec/ocr-server/client" + "github.com/weoses/memelo/storage-service/conf" + "github.com/weoses/memelo/storage-service/entity" + "github.com/weoses/memelo/storage-service/helper" ) type OcrSerivce interface { diff --git a/storage-service/src/service/S3ImageStorageService.go b/storage-service/src/service/S3ImageStorageService.go index 697aa4d..ce25008 100644 --- a/storage-service/src/service/S3ImageStorageService.go +++ b/storage-service/src/service/S3ImageStorageService.go @@ -14,7 +14,7 @@ import ( "github.com/google/uuid" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" - "mine.local/ocr-gallery/storage-service/conf" + "github.com/weoses/memelo/storage-service/conf" ) type ImageStorageService interface { diff --git a/storage-service/src/tools/go.mod b/storage-service/src/tools/go.mod index 41c0cc2..116148b 100644 --- a/storage-service/src/tools/go.mod +++ b/storage-service/src/tools/go.mod @@ -1,4 +1,4 @@ -module mine.local/ocr-gallery/ocr-server/tools +module github.com/weoses/memelo/ocr-server/tools go 1.22 diff --git a/telegram-service/src/go.mod b/telegram-service/src/go.mod index 8727c88..4dd1c62 100644 --- a/telegram-service/src/go.mod +++ b/telegram-service/src/go.mod @@ -1,4 +1,4 @@ -module mine.local/ocr-gallery/telegram-service +module github.com/weoses/memelo/telegram-service go 1.23.2 diff --git a/telegram-service/src/main.go b/telegram-service/src/main.go index 0165c96..1f22ab1 100644 --- a/telegram-service/src/main.go +++ b/telegram-service/src/main.go @@ -2,10 +2,10 @@ package main import ( tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" + "github.com/weoses/memelo/common/commonconfig" + "github.com/weoses/memelo/telegram-service/conf" + "github.com/weoses/memelo/telegram-service/service" "go.uber.org/fx" - "mine.local/ocr-gallery/common/commonconfig" - "mine.local/ocr-gallery/telegram-service/conf" - "mine.local/ocr-gallery/telegram-service/service" ) func Statup(serv service.TelegramBotService) { diff --git a/telegram-service/src/service/InlineHandlerService.go b/telegram-service/src/service/InlineHandlerService.go index 3532198..5c8c707 100644 --- a/telegram-service/src/service/InlineHandlerService.go +++ b/telegram-service/src/service/InlineHandlerService.go @@ -8,10 +8,10 @@ import ( "strings" "github.com/google/uuid" - "mine.local/ocr-gallery/common/commonconst" + "github.com/weoses/memelo/common/commonconst" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" - "mine.local/ocr-gallery/telegram-service/conf" + "github.com/weoses/memelo/telegram-service/conf" ) const inlineDeletePrefix = "!del" diff --git a/telegram-service/src/service/MessageHandlerService.go b/telegram-service/src/service/MessageHandlerService.go index be57ab0..f01ff10 100644 --- a/telegram-service/src/service/MessageHandlerService.go +++ b/telegram-service/src/service/MessageHandlerService.go @@ -7,7 +7,7 @@ import ( "log/slog" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" - "mine.local/ocr-gallery/common/commonconst" + "github.com/weoses/memelo/common/commonconst" ) type MessageHandlerService interface { diff --git a/telegram-service/src/service/StorageConnector.go b/telegram-service/src/service/StorageConnector.go index 5cf1fac..bb19b7b 100644 --- a/telegram-service/src/service/StorageConnector.go +++ b/telegram-service/src/service/StorageConnector.go @@ -7,10 +7,10 @@ import ( "fmt" "github.com/google/uuid" - "mine.local/ocr-gallery/apispec/meme-storage/client" - "mine.local/ocr-gallery/common/commonhelper" - "mine.local/ocr-gallery/telegram-service/conf" - "mine.local/ocr-gallery/telegram-service/entity" + "github.com/weoses/memelo/apispec/meme-storage/client" + "github.com/weoses/memelo/common/commonhelper" + "github.com/weoses/memelo/telegram-service/conf" + "github.com/weoses/memelo/telegram-service/entity" ) type StorageConnector interface { diff --git a/telegram-service/src/service/Telegram.go b/telegram-service/src/service/Telegram.go index 96c4416..039a629 100644 --- a/telegram-service/src/service/Telegram.go +++ b/telegram-service/src/service/Telegram.go @@ -5,8 +5,8 @@ import ( "log/slog" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" - "mine.local/ocr-gallery/common/commonconst" - "mine.local/ocr-gallery/telegram-service/conf" + "github.com/weoses/memelo/common/commonconst" + "github.com/weoses/memelo/telegram-service/conf" ) type TelegramBotService interface { diff --git a/telegram-service/src/service/UserAccountService.go b/telegram-service/src/service/UserAccountService.go index 960bfd5..7ff2e3c 100644 --- a/telegram-service/src/service/UserAccountService.go +++ b/telegram-service/src/service/UserAccountService.go @@ -4,11 +4,11 @@ import ( "context" "github.com/google/uuid" + "github.com/weoses/memelo/telegram-service/conf" + "github.com/weoses/memelo/telegram-service/entity" "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options" - "mine.local/ocr-gallery/telegram-service/conf" - "mine.local/ocr-gallery/telegram-service/entity" ) type UserAccountService interface { From 35a91276851b5e5221610d95b14a233dcd2c99a9 Mon Sep 17 00:00:00 2001 From: weoses Date: Sun, 16 Nov 2025 20:02:25 +0300 Subject: [PATCH 08/10] idea run configurations --- .idea/runConfigurations/TELEGRAM.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.idea/runConfigurations/TELEGRAM.xml b/.idea/runConfigurations/TELEGRAM.xml index a812249..8cdc02b 100644 --- a/.idea/runConfigurations/TELEGRAM.xml +++ b/.idea/runConfigurations/TELEGRAM.xml @@ -5,7 +5,7 @@ - + \ No newline at end of file From 23fa92f28e84871ef69474b37900b1d16eb49407 Mon Sep 17 00:00:00 2001 From: weoses Date: Sun, 16 Nov 2025 21:05:49 +0300 Subject: [PATCH 09/10] dependencies, ci builds --- Dockerfile-ocr-service | 2 +- Dockerfile-storage-service | 2 +- Dockerfile-telegram-service | 2 +- apispec/go.mod | 5 +- apispec/go.sum | 147 ++++++------------------ common/go.mod | 21 ++-- common/go.sum | 46 ++++---- go.work | 2 + go.work.sum | 59 +++++----- ocr-service/src/go.mod | 61 ++++++---- ocr-service/src/go.sum | 221 +++++++++++++++++------------------- storage-service/src/go.mod | 48 ++++++-- storage-service/src/go.sum | 133 ++++++++++++++++++---- telegram-service/src/go.mod | 41 +++++-- telegram-service/src/go.sum | 147 +++++++++++++++++++++--- 15 files changed, 552 insertions(+), 385 deletions(-) diff --git a/Dockerfile-ocr-service b/Dockerfile-ocr-service index 8c54e63..dc5febb 100644 --- a/Dockerfile-ocr-service +++ b/Dockerfile-ocr-service @@ -1,4 +1,4 @@ -FROM golang:1.23.2-alpine as builder +FROM golang:1.24.10-alpine AS builder WORKDIR /app/src RUN apk add --update --no-cache bash curl \ diff --git a/Dockerfile-storage-service b/Dockerfile-storage-service index 766864c..17b3873 100644 --- a/Dockerfile-storage-service +++ b/Dockerfile-storage-service @@ -1,4 +1,4 @@ -FROM golang:1.23.2-alpine as builder +FROM golang:1.24.10-alpine AS builder WORKDIR /app/src RUN apk add --update --no-cache bash curl \ diff --git a/Dockerfile-telegram-service b/Dockerfile-telegram-service index f8af80e..7228d35 100644 --- a/Dockerfile-telegram-service +++ b/Dockerfile-telegram-service @@ -1,4 +1,4 @@ -FROM golang:1.23.2-alpine as builder +FROM golang:1.24.10-alpine AS builder WORKDIR /app/src RUN apk add --update --no-cache bash curl \ diff --git a/apispec/go.mod b/apispec/go.mod index e17fa4e..448add9 100644 --- a/apispec/go.mod +++ b/apispec/go.mod @@ -13,10 +13,10 @@ require ( github.com/dprotaso/go-yit v0.0.0-20250909171706-0a81c39169bc // indirect github.com/getkin/kin-openapi v0.133.0 // indirect github.com/go-openapi/jsonpointer v0.22.2 // indirect - github.com/go-openapi/swag v0.25.1 // indirect github.com/go-openapi/swag/jsonname v0.25.1 // indirect github.com/google/uuid v1.6.0 // indirect github.com/josharian/intern v1.0.0 // indirect + github.com/kr/pretty v0.3.1 // indirect github.com/labstack/gommon v0.4.2 // indirect github.com/mailru/easyjson v0.9.1 // indirect github.com/mattn/go-colorable v0.1.14 // indirect @@ -27,6 +27,7 @@ require ( github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/speakeasy-api/jsonpath v0.6.2 // indirect github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect @@ -45,4 +46,4 @@ require ( gopkg.in/yaml.v3 v3.0.1 // indirect ) -tool github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen +tool github.com/deepmap/oapi-codegen/v2/cmd/oapi-codegen diff --git a/apispec/go.sum b/apispec/go.sum index 315cefb..d27a03f 100644 --- a/apispec/go.sum +++ b/apispec/go.sum @@ -2,82 +2,59 @@ github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMz github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 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/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936 h1:PRxIJD8XjimM5aTknUK9w6DHLDox2r2M3DI4i2pnd3w= -github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q= github.com/dprotaso/go-yit v0.0.0-20250909171706-0a81c39169bc h1:YxqE1wh+qGVXQFinuRq5lT77h6baDtBnAVh61LlXp1o= github.com/dprotaso/go-yit v0.0.0-20250909171706-0a81c39169bc/go.mod h1:5NQLChvz4dnEIQ8WcHIFbZ1bp0GEUZHiBH+EpTZ4lBc= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/jsonpointer v0.22.2 h1:JDQEe4B9j6K3tQ7HQQTZfjR59IURhjjLxet2FB4KHyg= github.com/go-openapi/jsonpointer v0.22.2/go.mod h1:0lBbqeRsQ5lIanv3LHZBrmRGHLHcQoOXQnf88fHlGWo= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/go-openapi/swag v0.25.1 h1:6uwVsx+/OuvFVPqfQmOOPsqTcm5/GkBhNwLqIR916n8= -github.com/go-openapi/swag v0.25.1/go.mod h1:bzONdGlT0fkStgGPd3bhZf1MnuPkf2YAys6h+jZipOo= github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -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.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -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.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +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/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= 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= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY= -github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/labstack/echo/v4 v4.13.4 h1:oTZZW+T3s9gAu5L8vmzihV7/lkXGZuITzTQkTEhcXEA= 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/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 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/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oapi-codegen/oapi-codegen/v2 v2.5.1 h1:5vHNY1uuPBRBWqB2Dp0G7YB03phxLQZupZTIZaeorjc= github.com/oapi-codegen/oapi-codegen/v2 v2.5.1/go.mod h1:ro0npU1BWkcGpCgGD9QwPp44l5OIZ94tB3eabnT7DjQ= -github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro= -github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= github.com/oapi-codegen/runtime v1.1.2 h1:P2+CubHq8fO4Q6fV1tqDBZHCwpVpvPg7oKiYzQgXIyI= github.com/oapi-codegen/runtime v1.1.2/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= @@ -86,26 +63,24 @@ github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletI github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= +github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= 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/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= -github.com/speakeasy-api/jsonpath v0.6.0 h1:IhtFOV9EbXplhyRqsVhHoBmmYjblIRh5D1/g8DHMXJ8= -github.com/speakeasy-api/jsonpath v0.6.0/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= github.com/speakeasy-api/jsonpath v0.6.2 h1:Mys71yd6u8kuowNCR0gCVPlVAHCmKtoGXYoAtcEbqXQ= github.com/speakeasy-api/jsonpath v0.6.2/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= -github.com/speakeasy-api/openapi-overlay v0.10.2 h1:VOdQ03eGKeiHnpb1boZCGm7x8Haj6gST0P3SGTX95GU= -github.com/speakeasy-api/openapi-overlay v0.10.2/go.mod h1:n0iOU7AqKpNFfEt6tq7qYITC4f0yzVVdFw0S7hukemg= github.com/speakeasy-api/openapi-overlay v0.10.3 h1:70een4vwHyslIp796vM+ox6VISClhtXsCjrQNhxwvWs= github.com/speakeasy-api/openapi-overlay v0.10.3/go.mod h1:RJjV0jbUHqXLS0/Mxv5XE7LAnJHqHw+01RDdpoGqiyY= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= @@ -113,109 +88,51 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= 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/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= -github.com/woodsbury/decimal128 v1.3.0 h1:8pffMNWIlC0O5vbyHWFZAt5yWvWcrHA+3ovIIjVWss0= -github.com/woodsbury/decimal128 v1.3.0/go.mod h1:C5UTmyTjW3JftjUFzOVhC20BEQa2a4ZKOB5I6Zjb+ds= github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= go.yaml.in/yaml/v4 v4.0.0-rc.3 h1:3h1fjsh1CTAPjW7q/EMe+C8shx5d8ctzZTrLcs/j8Go= go.yaml.in/yaml/v4 v4.0.0-rc.3/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -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.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= -golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/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-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.25.1 h1:YeIyhd0M7gStYR9jb2IFXVVT+QJhgXu1ZECOuRwofh4= -golang.org/x/tools v0.25.1/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -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.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= 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.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/common/go.mod b/common/go.mod index f79d88d..ff05d83 100644 --- a/common/go.mod +++ b/common/go.mod @@ -3,37 +3,38 @@ module github.com/weoses/memelo/common go 1.24.10 require ( - github.com/labstack/echo/v4 v4.13.3 - github.com/oapi-codegen/runtime v1.1.1 + github.com/labstack/echo/v4 v4.13.4 + github.com/oapi-codegen/runtime v1.1.2 github.com/spf13/viper v1.19.0 ) require ( - github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/google/go-cmp v0.6.0 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/labstack/gommon v0.4.2 // indirect github.com/magiconair/properties v1.8.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect - github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/testify v1.11.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect go.uber.org/multierr v1.10.0 // indirect - golang.org/x/crypto v0.32.0 // indirect + golang.org/x/crypto v0.44.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/net v0.47.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/text v0.31.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/common/go.sum b/common/go.sum index ab5b1ae..d51b0cc 100644 --- a/common/go.sum +++ b/common/go.sum @@ -4,10 +4,10 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +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/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -17,28 +17,27 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY= -github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g= +github.com/labstack/echo/v4 v4.13.4 h1:oTZZW+T3s9gAu5L8vmzihV7/lkXGZuITzTQkTEhcXEA= +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/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +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.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro= -github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= +github.com/oapi-codegen/runtime v1.1.2 h1:P2+CubHq8fO4Q6fV1tqDBZHCwpVpvPg7oKiYzQgXIyI= +github.com/oapi-codegen/runtime v1.1.2/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= 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/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= @@ -61,8 +60,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= @@ -71,18 +70,17 @@ github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQ github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= +golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/go.work b/go.work index 0899db4..25ef018 100644 --- a/go.work +++ b/go.work @@ -7,3 +7,5 @@ use ( ./storage-service/src ./telegram-service/src ) + +replace github.com/weoses/memelo => ./ \ No newline at end of file diff --git a/go.work.sum b/go.work.sum index 7cbb879..dfa1314 100644 --- a/go.work.sum +++ b/go.work.sum @@ -109,6 +109,8 @@ cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdi cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= cloud.google.com/go/compute v1.23.4/go.mod h1:/EJMj55asU6kAFnuZET8zqgwgJ9FvXWXOkkfQZa4ioI= cloud.google.com/go/compute v1.29.0 h1:Lph6d8oPi38NHkOr6S55Nus/Pbbcp37m/J0ohgKAefs= +cloud.google.com/go/compute v1.31.1 h1:SObuy8Fs6woazArpXp1fsHCw+ZH4iJ/8dGGTxUhHZQA= +cloud.google.com/go/compute v1.31.1/go.mod h1:hyOponWhXviDptJCJSoEh89XO1cfv616wbwbkde1/+8= cloud.google.com/go/compute/metadata v0.5.2 h1:UxK4uu/Tn+I3p2dYWTfiX4wva7aYlKixAHn3fyqngqo= cloud.google.com/go/contactcenterinsights v1.13.0/go.mod h1:ieq5d5EtHsu8vhe2y3amtZ+BE+AQwX5qAy7cpo0POsI= cloud.google.com/go/contactcenterinsights v1.15.1/go.mod h1:cFGxDVm/OwEVAHbU9UO4xQCtQFn0RZSrSUcF/oJ0Bbs= @@ -445,7 +447,6 @@ cloud.google.com/go/videointelligence v1.12.2/go.mod h1:8xKGlq0lNVyT8JgTkkCUCpyN cloud.google.com/go/videointelligence v1.12.3 h1:zNTOUQyatGQtnCJ2dR3faRtpWQOlC8wszJqwG5CtwVM= cloud.google.com/go/videointelligence v1.12.3/go.mod h1:dUA6V+NH7CVgX6TePq0IelVeBMGzvehxKPR4FGf1dtw= cloud.google.com/go/vision/v2 v2.9.2 h1:u4pu3gKps88oUe76WwVPeX9dgWVyyYopZ1s05FwsKEk= -cloud.google.com/go/vision/v2 v2.9.3 h1:dPvfDuPqPH+Yscf0f2f1RprvKkoo+N/j0a+IbLYX7Cs= cloud.google.com/go/vmmigration v1.7.5/go.mod h1:pkvO6huVnVWzkFioxSghZxIGcsstDvYiVCxQ9ZH3eYI= cloud.google.com/go/vmmigration v1.8.2/go.mod h1:FBejrsr8ZHmJb949BSOyr3D+/yCp9z9Hk0WtsTiHc1Q= cloud.google.com/go/vmmigration v1.8.3 h1:dpCQq3pj2HnKdbvGTftdWymm3r4ovF7JW5z8xBcO2x4= @@ -567,8 +568,6 @@ github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/flosch/pongo2/v4 v4.0.2 h1:gv+5Pe3vaSVmiJvh/BZa82b7/00YUGm0PIyVVLop0Hw= github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8= -github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= -github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/getkin/kin-openapi v0.127.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= @@ -581,6 +580,8 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-openapi/swag/cmdutils v0.25.1 h1:nDke3nAFDArAa631aitksFGj2omusks88GF1VwdYqPY= github.com/go-openapi/swag/cmdutils v0.25.1/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= github.com/go-openapi/swag/conv v0.25.1 h1:+9o8YUg6QuqqBM5X6rYL/p1dpWeZRhoIt9x7CCP+he0= @@ -601,13 +602,8 @@ github.com/go-openapi/swag/typeutils v0.25.1 h1:rD/9HsEQieewNt6/k+JBwkxuAHktFtH3 github.com/go-openapi/swag/typeutils v0.25.1/go.mod h1:9McMC/oCdS4BKwk2shEB7x17P6HmMmA6dQRtAkSnNb8= github.com/go-openapi/swag/yamlutils v0.25.1 h1:mry5ez8joJwzvMbaTGLhw8pXUnhDK91oSJLDPF1bmGk= github.com/go-openapi/swag/yamlutils v0.25.1/go.mod h1:cm9ywbzncy3y6uPm/97ysW8+wZ09qsks+9RS8fLWKqg= -github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= -github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= -github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= -github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= -github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= @@ -625,16 +621,16 @@ github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwm github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/glog v1.2.3 h1:oDTdz9f5VGVVNGu/Q7UXKWYsD0873HXLHdJUNBsSEKM= github.com/golang/glog v1.2.3/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 h1:EcQR3gusLHN46TAD+G+EbaaqJArt5vHhNpXAa12PQf4= github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/flatbuffers v23.5.26+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= -github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-pkcs11 v0.2.1-0.20230907215043-c6f79328ddf9/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= github.com/google/go-pkcs11 v0.3.0 h1:PVRnTgtArZ3QQqTGtbtjtnIkzl2iY2kt24yqbrf7td8= github.com/google/go-pkcs11 v0.3.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= @@ -737,6 +733,7 @@ github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2 github.com/lyft/protoc-gen-star/v2 v2.0.3/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= github.com/mailgun/raymond/v2 v2.0.48 h1:5dmlB680ZkFG2RN/0lvTAghrSxIESeu9/2aeDqACtjw= github.com/mailgun/raymond/v2 v2.0.48/go.mod h1:lsgvL50kgt1ylcFJYZiULi5fjPBkkhNfj4KA0W54Z18= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2 h1:JAEbJn3j/FrhdWA9jW8B5ajsLIjeuEHLi8xE4fk997o= github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs= github.com/mediocregopher/radix/v3 v3.8.1 h1:rOkHflVuulFKlwsLY01/M2cM2tWCjDoETcMqKbAWu1M= @@ -767,24 +764,17 @@ github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= -github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oapi-codegen/oapi-codegen/v2 v2.4.1/go.mod h1:N5+lY1tiTDV3V1BeHtOxeWXHoPVeApvsvjJqegfoaz8= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE= github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= 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/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= @@ -797,7 +787,6 @@ github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk github.com/redis/go-redis/v9 v9.1.0 h1:137FnGdk+EQdCbye1FW+qOEcY5S+SpY9T0NiuqvtfMY= github.com/redis/go-redis/v9 v9.1.0/go.mod h1:urWj3He21Dj5k4TK1y59xH8Uj6ATueP8AH1cY3lZl4c= github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/crypt v0.19.0 h1:WMyLTjHBo64UvNcWqpzY3pbZTYgnemZU8FBZigKc42E= @@ -806,7 +795,6 @@ github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQ github.com/sanity-io/litter v1.5.5/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U= github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiyyjYS17cCYRqP13/SHk= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/shirou/gopsutil/v3 v3.23.8 h1:xnATPiybo6GgdRoC4YoGnxXZFRc3dqQTGi73oLvvBrE= github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= @@ -821,8 +809,9 @@ github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRM github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad h1:fiWzISvDn0Csy5H0iwgAuJGQTUpVfEMJJd4nRFXogbc= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subeshb1/wasm-go-image-to-ascii v0.0.0-20200725121413-d828986df340/go.mod h1:A2X7CsJFb8jEdYaWeCbs2HydXC69J4Iaw4DM+bly5iw= github.com/tdewolff/minify/v2 v2.12.9 h1:dvn5MtmuQ/DFMwqf5j8QhEVpPX6fi3WGImhv8RUB4zA= github.com/tdewolff/minify/v2 v2.12.9/go.mod h1:qOqdlDfL+7v0/fyymB+OP497nIxJYSvX4MQWA8OoiXU= @@ -836,8 +825,6 @@ github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+F github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= @@ -862,6 +849,7 @@ github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3Ifn github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= @@ -876,6 +864,8 @@ go.etcd.io/etcd/client/v2 v2.305.12 h1:0m4ovXYo1CHaA/Mp3X/Fak5sRNIWf01wk/X1/G3sG go.etcd.io/etcd/client/v2 v2.305.12/go.mod h1:aQ/yhsxMu+Oht1FOupSr60oBvcS9cKXHrzBpDsPTf9E= go.etcd.io/etcd/client/v3 v3.5.12 h1:v5lCPXn1pf1Uu3M4laUE2hp/geOTc5uPcYYsNe1lDxg= go.etcd.io/etcd/client/v3 v3.5.12/go.mod h1:tSbBCakoWmmddL+BKVAJHa9km+O/E+bumDe9mSbPiqw= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/detectors/gcp v1.28.0/go.mod h1:9BIqH22qyHWAiZxQh0whuJygro59z+nbMVuc7ciiGug= go.opentelemetry.io/contrib/detectors/gcp v1.33.0 h1:FVPoXEoILwgbZUu4X7YSgsESsAmGRgoYcnXkzgQPhP4= go.opentelemetry.io/contrib/detectors/gcp v1.33.0/go.mod h1:ZHrLmr4ikK2AwRj9QL+c9s2SOlgoSRyMpNVzUj2fZqI= @@ -895,11 +885,7 @@ go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8p go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= go.opentelemetry.io/otel/sdk v1.29.0/go.mod h1:pM8Dx5WKnvxLCb+8lG1PRNIDxu9g9b9g59Qr7hfAAok= -go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= -go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= -go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= -go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= go.opentelemetry.io/otel/trace v1.23.0/go.mod h1:GSGTbIClEsuZrGIzoEHqsVfxgn5UkggkflQwDScNUsk= go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= @@ -908,12 +894,11 @@ go.opentelemetry.io/proto/otlp v0.7.0 h1:rwOQPCuKAKmwGKq2aVNnYIibI6wnV7EvzgfTCzc go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= -go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc= golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= @@ -925,6 +910,7 @@ golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDA golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= @@ -932,6 +918,7 @@ golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= @@ -945,11 +932,14 @@ golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCA golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -961,6 +951,7 @@ golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457 h1:zf5N6UOrA487eEFacMePxjXAJctxKmyjKUsjA11Uzuk= @@ -973,13 +964,13 @@ golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= @@ -997,6 +988,8 @@ google.golang.org/api v0.166.0/go.mod h1:4FcBc686KFi7QI/U51/2GKKevfZMpM17sCdibqe google.golang.org/api v0.167.0/go.mod h1:4FcBc686KFi7QI/U51/2GKKevfZMpM17sCdibqe/bSA= google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= google.golang.org/api v0.211.0 h1:IUpLjq09jxBSV1lACO33CGY3jsRcbctfGzhj+ZSE/Bg= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:+Rvu7ElI+aLzyDQhpHMFMMltsD6m7nqpuWDd2CwJw3k= google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro= @@ -1032,11 +1025,11 @@ google.golang.org/grpc v1.67.3 h1:OgPcDAFKHnH8X3O4WcO4XUc8GRDeKsKReqbQtiCj7N8= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI= honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8= moul.io/http2curl/v2 v2.3.0 h1:9r3JfDzWPcbIklMOs2TnIFzDYvfAZvjeavG6EzP7jYs= diff --git a/ocr-service/src/go.mod b/ocr-service/src/go.mod index f1d4b2b..715b82e 100644 --- a/ocr-service/src/go.mod +++ b/ocr-service/src/go.mod @@ -1,46 +1,60 @@ module github.com/weoses/memelo/ocr-server -go 1.23.2 +go 1.24.10 require ( - github.com/labstack/echo/v4 v4.13.3 - github.com/oapi-codegen/runtime v1.1.1 + github.com/labstack/echo/v4 v4.13.4 + github.com/oapi-codegen/runtime v1.1.2 + github.com/pkg/errors v0.9.1 github.com/spf13/viper v1.19.0 + github.com/weoses/memelo/apispec v0.0.0-00010101000000-000000000000 + github.com/weoses/memelo/common v0.0.0-00010101000000-000000000000 go.uber.org/fx v1.23.0 + google.golang.org/api v0.220.0 + google.golang.org/protobuf v1.36.5 ) require ( cloud.google.com/go v0.118.1 // indirect cloud.google.com/go/auth v0.14.1 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect - cloud.google.com/go/compute v1.31.1 // indirect cloud.google.com/go/compute/metadata v0.6.0 // indirect cloud.google.com/go/iam v1.3.1 // indirect cloud.google.com/go/longrunning v0.6.4 // indirect cloud.google.com/go/vision/v2 v2.9.3 // indirect + github.com/dprotaso/go-yit v0.0.0-20250909171706-0a81c39169bc // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/getkin/kin-openapi v0.133.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.4 // indirect + github.com/go-openapi/jsonpointer v0.22.2 // indirect + github.com/go-openapi/swag/jsonname v0.25.1 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect github.com/googleapis/gax-go/v2 v2.14.1 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/magiconair/properties v1.8.7 // indirect + github.com/mailru/easyjson v0.9.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/oapi-codegen/oapi-codegen/v2 v2.5.1 // indirect + github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect + github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/rogpeppe/go-internal v1.13.1 // indirect + github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect + github.com/speakeasy-api/jsonpath v0.6.2 // indirect + github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.6.0 // indirect - go.opencensus.io v0.24.0 // indirect + github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect @@ -50,35 +64,36 @@ require ( go.uber.org/dig v1.18.0 // indirect go.uber.org/multierr v1.10.0 // indirect go.uber.org/zap v1.26.0 // indirect + go.yaml.in/yaml/v4 v4.0.0-rc.3 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect + golang.org/x/mod v0.30.0 // indirect golang.org/x/oauth2 v0.25.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/time v0.9.0 // indirect - google.golang.org/api v0.220.0 // indirect - google.golang.org/appengine v1.6.8 // indirect + golang.org/x/sync v0.18.0 // indirect + golang.org/x/time v0.11.0 // indirect + golang.org/x/tools v0.39.0 // indirect google.golang.org/genproto v0.0.0-20250122153221-138b5a5a4fd4 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250207221924-e9438ea467c6 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 // indirect google.golang.org/grpc v1.70.0 // indirect - google.golang.org/protobuf v1.36.5 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) require ( cloud.google.com/go/aiplatform v1.73.0 - cloud.google.com/go/vertexai v0.13.3 cloud.google.com/go/vision v1.2.0 github.com/h2non/bimg v1.1.9 github.com/labstack/gommon v0.4.2 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect - github.com/vitali-fedulov/images4 v1.3.1 - golang.org/x/crypto v0.32.0 // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/crypto v0.44.0 // indirect + golang.org/x/net v0.47.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/text v0.31.0 // indirect ) + +replace github.com/weoses/memelo/apispec => ../../apispec +replace github.com/weoses/memelo/common => ../../common \ No newline at end of file diff --git a/ocr-service/src/go.sum b/ocr-service/src/go.sum index 7cb9c8b..56a7cdf 100644 --- a/ocr-service/src/go.sum +++ b/ocr-service/src/go.sum @@ -27,10 +27,6 @@ cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= -cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= -cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= -cloud.google.com/go v0.116.0 h1:B3fRrSDkLRt5qSHWe40ERJvhvnQwdZiHu0bJOpldweE= -cloud.google.com/go v0.116.0/go.mod h1:cEPSRWPzZEswwdr9BxE6ChEn01dWlTaF05LiC2Xs70U= cloud.google.com/go v0.118.1 h1:b8RATMcrK9A4BH0rj8yQupPXp+aP+cJ0l6H7V9osV1E= cloud.google.com/go v0.118.1/go.mod h1:CFO4UPEPi8oV21xoezZCrd3d81K4fFkDTEJu4R8K+9M= cloud.google.com/go/aiplatform v1.73.0 h1:IuxpcwpkmexB7zvzwkCDsKok8mwPWOn2kFaHQYi1INA= @@ -47,23 +43,12 @@ cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4g cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= -cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= -cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= -cloud.google.com/go/compute v1.29.0/go.mod h1:HFlsDurE5DpQZClAGf/cYh+gxssMhBxBovZDYkEn/Og= -cloud.google.com/go/compute v1.31.1 h1:SObuy8Fs6woazArpXp1fsHCw+ZH4iJ/8dGGTxUhHZQA= -cloud.google.com/go/compute v1.31.1/go.mod h1:hyOponWhXviDptJCJSoEh89XO1cfv616wbwbkde1/+8= -cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= -cloud.google.com/go/compute/metadata v0.5.2/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k= cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/iam v1.3.1 h1:KFf8SaT71yYq+sQtRISn90Gyhyf4X8RGgeAVC8XGf3E= cloud.google.com/go/iam v1.3.1/go.mod h1:3wMtuyT4NcbnYNPLMBzYRFiEfjKfJlLVLrisE7bwm34= -cloud.google.com/go/longrunning v0.5.5 h1:GOE6pZFdSrTb4KAiKnXsJBtlE6mEyaW44oKyMILWnOg= -cloud.google.com/go/longrunning v0.5.5/go.mod h1:WV2LAxD8/rg5Z1cNW6FJ/ZpX4E4VnDnoTk0yawPBB7s= -cloud.google.com/go/longrunning v0.6.2/go.mod h1:k/vIs83RN4bE3YCswdXC5PFfWVILjm3hpEUlSko4PiI= cloud.google.com/go/longrunning v0.6.4 h1:3tyw9rO3E2XVXzSApn1gyEEnH2K9SynNQjMlBi3uHLg= cloud.google.com/go/longrunning v0.6.4/go.mod h1:ttZpLCe6e7EXvn9OxpBRx7kZEB0efv8yBO6YnVMfhJs= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= @@ -75,13 +60,9 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/vertexai v0.13.3 h1:pbw1KfpdE8ZDrXxBKcIsS/j+EixyQRsyu6gxRkXq8/k= -cloud.google.com/go/vertexai v0.13.3/go.mod h1:AxzUNrd36yhfOZedO+Y1v0ajVgGKOdv1njeQChL8IFY= cloud.google.com/go/vision v1.2.0 h1:/CsSTkbmO9HC8iQpxbK8ATms3OQaX3YQUeTMGCxlaK4= cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= -cloud.google.com/go/vision/v2 v2.8.0 h1:W52z1b6LdGI66MVhE70g/NFty9zCYYcjdKuycqmlhtg= -cloud.google.com/go/vision/v2 v2.8.0/go.mod h1:ocqDiA2j97pvgogdyhoxiQp2ZkDCyr0HWpicywGGRhU= -cloud.google.com/go/vision/v2 v2.9.2/go.mod h1:WuxjVQdAy4j4WZqY5Rr655EdAgi8B707Vdb5T8c90uo= +cloud.google.com/go/vision/v2 v2.9.3 h1:dPvfDuPqPH+Yscf0f2f1RprvKkoo+N/j0a+IbLYX7Cs= cloud.google.com/go/vision/v2 v2.9.3/go.mod h1:weAcT8aNYSgrWWVTC2PuJTc7fcXKvUeAyDq8B6HkLSg= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -107,6 +88,9 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs 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/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= +github.com/dprotaso/go-yit v0.0.0-20250909171706-0a81c39169bc h1:YxqE1wh+qGVXQFinuRq5lT77h6baDtBnAVh61LlXp1o= +github.com/dprotaso/go-yit v0.0.0-20250909171706-0a81c39169bc/go.mod h1:5NQLChvz4dnEIQ8WcHIFbZ1bp0GEUZHiBH+EpTZ4lBc= 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= @@ -119,8 +103,12 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +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.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= +github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -130,12 +118,18 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/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-openapi/jsonpointer v0.22.2 h1:JDQEe4B9j6K3tQ7HQQTZfjR59IURhjjLxet2FB4KHyg= +github.com/go-openapi/jsonpointer v0.22.2/go.mod h1:0lBbqeRsQ5lIanv3LHZBrmRGHLHcQoOXQnf88fHlGWo= +github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= +github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -162,8 +156,7 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +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.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -181,7 +174,8 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +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/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -201,23 +195,17 @@ github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= -github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= -github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA= github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= -github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= +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/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw= github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= -github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= -github.com/googleapis/gax-go/v2 v2.14.0/go.mod h1:lhBCnjdLrWRaPvLWhmc8IS24m9mr07qSYnHncrgo+zk= github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q= github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= @@ -227,34 +215,58 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY= -github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labstack/echo/v4 v4.13.4 h1:oTZZW+T3s9gAu5L8vmzihV7/lkXGZuITzTQkTEhcXEA= +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/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +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.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro= -github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= +github.com/oapi-codegen/oapi-codegen/v2 v2.5.1 h1:5vHNY1uuPBRBWqB2Dp0G7YB03phxLQZupZTIZaeorjc= +github.com/oapi-codegen/oapi-codegen/v2 v2.5.1/go.mod h1:ro0npU1BWkcGpCgGD9QwPp44l5OIZ94tB3eabnT7DjQ= +github.com/oapi-codegen/runtime v1.1.2 h1:P2+CubHq8fO4Q6fV1tqDBZHCwpVpvPg7oKiYzQgXIyI= +github.com/oapi-codegen/runtime v1.1.2/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= +github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= +github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= +github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= +github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= +github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= +github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -263,16 +275,21 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= 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/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/speakeasy-api/jsonpath v0.6.2 h1:Mys71yd6u8kuowNCR0gCVPlVAHCmKtoGXYoAtcEbqXQ= +github.com/speakeasy-api/jsonpath v0.6.2/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= +github.com/speakeasy-api/openapi-overlay v0.10.3 h1:70een4vwHyslIp796vM+ox6VISClhtXsCjrQNhxwvWs= +github.com/speakeasy-api/openapi-overlay v0.10.3/go.mod h1:RJjV0jbUHqXLS0/Mxv5XE7LAnJHqHw+01RDdpoGqiyY= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= @@ -291,25 +308,27 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= 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/vitali-fedulov/images4 v1.3.1 h1:r8q2iDD3Gq63rE1IxRvpa3KsUUtdGNYFg4RoTtkmwYA= -github.com/vitali-fedulov/images4 v1.3.1/go.mod h1:/VAKZBeMLWZfC2rjWgOb0Q6e6gUzArPAR4l0pKubYAk= +github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= +github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -317,34 +336,20 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 h1:PS8wXpbyaDJQ2VDHHncMe9Vct0Zn1fEjpsjrLxGJoSc= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0/go.mod h1:HDBUsEjOuRC0EzKZ1bSaRGZWUBAzo+MhAcUUORSr4D0= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q= -go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= -go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8= go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= -go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= -go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= -go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8= go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= -go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw= -go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= -go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= +go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= @@ -353,18 +358,22 @@ go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg= go.uber.org/fx v1.23.0/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +go.yaml.in/yaml/v4 v4.0.0-rc.3 h1:3h1fjsh1CTAPjW7q/EMe+C8shx5d8ctzZTrLcs/j8Go= +go.yaml.in/yaml/v4 v4.0.0-rc.3/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= 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-20190605123033-f99c8df09eb5/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.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= +golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -402,9 +411,11 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= +golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= 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-20190108225652-1e06a53dbb7e/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= @@ -439,9 +450,8 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -458,9 +468,6 @@ golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= -golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= -golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -474,10 +481,10 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/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-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= @@ -528,12 +535,9 @@ golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -545,16 +549,13 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= -golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= -golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= +golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= 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= @@ -606,7 +607,8 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= +golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -644,9 +646,6 @@ google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3h google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= -google.golang.org/api v0.171.0 h1:w174hnBPqut76FzW5Qaupt7zY8Kql6fiVjgys4f58sU= -google.golang.org/api v0.171.0/go.mod h1:Hnq5AHm4OTMt2BUVjael2CWZFD6vksJdWCWiUAmjC9o= -google.golang.org/api v0.211.0/go.mod h1:XOloB4MXFH4UTlQSGuNUxw0UT74qdENK8d6JNsXKLi0= google.golang.org/api v0.220.0 h1:3oMI4gdBgB72WFVwE1nerDD8W3HUOS4kypK6rRLbGns= google.golang.org/api v0.220.0/go.mod h1:26ZAlY6aN/8WgpCzjPNy18QpYaz7Zgg1h0qe1GkZEmY= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -656,8 +655,6 @@ google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= 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-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -722,19 +719,10 @@ google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= -google.golang.org/genproto v0.0.0-20241118233622-e639e219e697/go.mod h1:JJrvXBWRZaFMxBufik1a4RpFw4HhgVtBBWQeQgUj2cc= google.golang.org/genproto v0.0.0-20250122153221-138b5a5a4fd4 h1:Pw6WnI9W/LIdRxqK7T6XGugGbHIRl5Q7q3BssH6xk4s= google.golang.org/genproto v0.0.0-20250122153221-138b5a5a4fd4/go.mod h1:qbZzneIOXSq+KFAFut9krLfRLZiFLzZL5u2t8SV83EE= -google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 h1:rIo7ocm2roD9DcFIX67Ym8icoGCKSARAiPljFhh5suQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y= -google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697/go.mod h1:+D9ySVjN8nY8YCVjc5O7PZDIdZporIDY3KaGfJunh88= google.golang.org/genproto/googleapis/api v0.0.0-20250207221924-e9438ea467c6 h1:L9JNMl/plZH9wmzQUHleO/ZZDSN+9Gh41wPczNy+5Fk= google.golang.org/genproto/googleapis/api v0.0.0-20250207221924-e9438ea467c6/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c h1:lfpJ/2rWPa/kJgxyyXM8PrNnfCzcmxJ265mADgwmvLI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241206012308-a4fef0638583/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 h1:2duwAxN2+k0xLNpjnHTXoMUgnv6VPSp5fiqTuwSxjmI= google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -764,9 +752,6 @@ google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= -google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= -google.golang.org/grpc v1.67.3/go.mod h1:YGaHCc6Oap+FzBJTZLBzkGSYt/cvGPFTPxkn7QfSU8s= google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= @@ -783,20 +768,26 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= -google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= 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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +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.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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= diff --git a/storage-service/src/go.mod b/storage-service/src/go.mod index 06ed9a7..1fa615d 100644 --- a/storage-service/src/go.mod +++ b/storage-service/src/go.mod @@ -1,50 +1,71 @@ module github.com/weoses/memelo/storage-service -go 1.23.2 +go 1.24.10 require ( + github.com/adrg/strutil v0.3.1 github.com/google/uuid v1.6.0 - github.com/labstack/echo/v4 v4.13.3 - github.com/oapi-codegen/runtime v1.1.1 + github.com/labstack/echo/v4 v4.13.4 + github.com/oapi-codegen/runtime v1.1.2 github.com/spf13/viper v1.19.0 + github.com/weoses/memelo/apispec v0.0.0-00010101000000-000000000000 + github.com/weoses/memelo/common v0.0.0-00010101000000-000000000000 go.uber.org/fx v1.23.0 ) require ( - github.com/adrg/strutil v0.3.1 // indirect + github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect + github.com/dprotaso/go-yit v0.0.0-20250909171706-0a81c39169bc // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/elastic/elastic-transport-go/v8 v8.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.8 // indirect + github.com/getkin/kin-openapi v0.133.0 // indirect github.com/go-ini/ini v1.67.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-openapi/jsonpointer v0.22.2 // indirect + github.com/go-openapi/swag/jsonname v0.25.1 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/goccy/go-json v0.10.4 // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/compress v1.17.11 // indirect github.com/klauspost/cpuid/v2 v2.2.9 // indirect github.com/labstack/gommon v0.4.2 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mailru/easyjson v0.9.1 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/minio/md5-simd v1.1.2 // indirect - github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/oapi-codegen/oapi-codegen/v2 v2.5.1 // indirect + github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect + github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect + github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/rs/xid v1.6.0 // indirect + github.com/speakeasy-api/jsonpath v0.6.2 // indirect + github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect + github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/sdk v1.22.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect go.uber.org/dig v1.18.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/crypto v0.32.0 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + go.yaml.in/yaml/v4 v4.0.0-rc.3 // indirect + golang.org/x/crypto v0.44.0 // indirect + golang.org/x/mod v0.30.0 // indirect + golang.org/x/sync v0.18.0 // indirect + golang.org/x/tools v0.39.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect ) require ( github.com/elastic/go-elasticsearch/v8 v8.16.0 - github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/gdexlab/go-render v1.0.1 github.com/go-playground/validator/v10 v10.24.0 github.com/hashicorp/hcl v1.0.0 // indirect @@ -61,9 +82,12 @@ require ( github.com/subosito/gotenv v1.6.0 // indirect go.uber.org/multierr v1.10.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/net v0.47.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/text v0.31.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) + +replace github.com/weoses/memelo/apispec => ../../apispec +replace github.com/weoses/memelo/common => ../../common diff --git a/storage-service/src/go.sum b/storage-service/src/go.sum index 98f4ab2..8777b1e 100644 --- a/storage-service/src/go.sum +++ b/storage-service/src/go.sum @@ -1,9 +1,16 @@ +github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= github.com/adrg/strutil v0.3.1 h1:OLvSS7CSJO8lBii4YmBt8jiK9QOtB9CzCzwl4Ic/Fz4= github.com/adrg/strutil v0.3.1/go.mod h1:8h90y18QLrs11IBffcGX3NW/GFBXCMcNg4M7H6MspPA= +github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= +github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= +github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= 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/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= +github.com/dprotaso/go-yit v0.0.0-20250909171706-0a81c39169bc h1:YxqE1wh+qGVXQFinuRq5lT77h6baDtBnAVh61LlXp1o= +github.com/dprotaso/go-yit v0.0.0-20250909171706-0a81c39169bc/go.mod h1:5NQLChvz4dnEIQ8WcHIFbZ1bp0GEUZHiBH+EpTZ4lBc= 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/elastic/elastic-transport-go/v8 v8.6.0 h1:Y2S/FBjx1LlCv5m6pWAF2kDJAHoSjSRSJCApolgfthA= @@ -12,12 +19,15 @@ github.com/elastic/go-elasticsearch/v8 v8.16.0 h1:f7bR+iBz8GTAVhwyFO3hm4ixsz2eMa github.com/elastic/go-elasticsearch/v8 v8.16.0/go.mod h1:lGMlgKIbYoRvay3xWBeKahAiJOgmFDsjZC39nmO3H64= 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.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= github.com/gdexlab/go-render v1.0.1 h1:rxqB3vo5s4n1kF0ySmoNeSPRYkEsyHgln4jFIQY7v0U= github.com/gdexlab/go-render v1.0.1/go.mod h1:wRi5nW2qfjiGj4mPukH4UV0IknS1cHD4VgFTmJX5JzM= +github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= +github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -25,44 +35,59 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/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-openapi/jsonpointer v0.22.2 h1:JDQEe4B9j6K3tQ7HQQTZfjR59IURhjjLxet2FB4KHyg= +github.com/go-openapi/jsonpointer v0.22.2/go.mod h1:0lBbqeRsQ5lIanv3LHZBrmRGHLHcQoOXQnf88fHlGWo= +github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= +github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.24.0 h1:KHQckvo8G6hlWnrPX4NJJ+aBfWNAE/HH+qdL2cBpCmg= github.com/go-playground/validator/v10 v10.24.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM= github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +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= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY= -github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g= +github.com/labstack/echo/v4 v4.13.4 h1:oTZZW+T3s9gAu5L8vmzihV7/lkXGZuITzTQkTEhcXEA= +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.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +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.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= @@ -71,23 +96,48 @@ github.com/minio/minio-go/v7 v7.0.84 h1:D1HVmAF8JF8Bpi6IU4V9vIEj+8pc+xU88EWMs2ye github.com/minio/minio-go/v7 v7.0.84/go.mod h1:57YXpvc5l3rjPdhqNrDsvVlY0qPI6UTk1bflAe+9doY= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/oapi-codegen/runtime v1.1.1 h1:EXLHh0DXIJnWhdRPN2w4MXAzFyE4CskzhNLUmtpMYro= -github.com/oapi-codegen/runtime v1.1.1/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= +github.com/oapi-codegen/oapi-codegen/v2 v2.5.1 h1:5vHNY1uuPBRBWqB2Dp0G7YB03phxLQZupZTIZaeorjc= +github.com/oapi-codegen/oapi-codegen/v2 v2.5.1/go.mod h1:ro0npU1BWkcGpCgGD9QwPp44l5OIZ94tB3eabnT7DjQ= +github.com/oapi-codegen/runtime v1.1.2 h1:P2+CubHq8fO4Q6fV1tqDBZHCwpVpvPg7oKiYzQgXIyI= +github.com/oapi-codegen/runtime v1.1.2/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= +github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= +github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= +github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= +github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= +github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= +github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= 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/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= 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/speakeasy-api/jsonpath v0.6.2 h1:Mys71yd6u8kuowNCR0gCVPlVAHCmKtoGXYoAtcEbqXQ= +github.com/speakeasy-api/jsonpath v0.6.2/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= +github.com/speakeasy-api/openapi-overlay v0.10.3 h1:70een4vwHyslIp796vM+ox6VISClhtXsCjrQNhxwvWs= +github.com/speakeasy-api/openapi-overlay v0.10.3/go.mod h1:RJjV0jbUHqXLS0/Mxv5XE7LAnJHqHw+01RDdpoGqiyY= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= @@ -96,22 +146,32 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= +github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= 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/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= +github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= @@ -130,23 +190,46 @@ go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +go.yaml.in/yaml/v4 v4.0.0-rc.3 h1:3h1fjsh1CTAPjW7q/EMe+C8shx5d8ctzZTrLcs/j8Go= +go.yaml.in/yaml/v4 v4.0.0-rc.3/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= +golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= +golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= +golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= +golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +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.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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= diff --git a/telegram-service/src/go.mod b/telegram-service/src/go.mod index 4dd1c62..5e3958b 100644 --- a/telegram-service/src/go.mod +++ b/telegram-service/src/go.mod @@ -1,30 +1,50 @@ module github.com/weoses/memelo/telegram-service -go 1.23.2 +go 1.24.10 require ( github.com/google/uuid v1.6.0 github.com/spf13/viper v1.19.0 + github.com/weoses/memelo/apispec v0.0.0-00010101000000-000000000000 + github.com/weoses/memelo/common v0.0.0-00010101000000-000000000000 ) require ( + github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect + github.com/dprotaso/go-yit v0.0.0-20250909171706-0a81c39169bc // indirect + github.com/getkin/kin-openapi v0.133.0 // indirect + github.com/go-openapi/jsonpointer v0.22.2 // indirect + github.com/go-openapi/swag/jsonname v0.25.1 // indirect github.com/golang/snappy v0.0.4 // indirect + github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/compress v1.17.11 // indirect - github.com/rogpeppe/go-internal v1.12.0 // indirect - github.com/stretchr/testify v1.10.0 // indirect + github.com/mailru/easyjson v0.9.1 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/oapi-codegen/oapi-codegen/v2 v2.5.1 // indirect + github.com/oapi-codegen/runtime v1.1.2 // indirect + github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect + github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect + github.com/perimeterx/marshmallow v1.1.5 // indirect + github.com/speakeasy-api/jsonpath v0.6.2 // indirect + github.com/speakeasy-api/openapi-overlay v0.10.3 // indirect + github.com/vmware-labs/yaml-jsonpath v0.3.2 // indirect + github.com/woodsbury/decimal128 v1.4.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect go.uber.org/dig v1.18.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/crypto v0.32.0 // indirect - golang.org/x/sync v0.10.0 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect + go.yaml.in/yaml/v4 v4.0.0-rc.3 // indirect + golang.org/x/crypto v0.44.0 // indirect + golang.org/x/mod v0.30.0 // indirect + golang.org/x/sync v0.18.0 // indirect + golang.org/x/tools v0.39.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect ) require ( - github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 github.com/hashicorp/hcl v1.0.0 // indirect github.com/magiconair/properties v1.8.7 // indirect @@ -41,8 +61,11 @@ require ( go.uber.org/fx v1.23.0 go.uber.org/multierr v1.10.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/text v0.31.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) + +replace github.com/weoses/memelo/apispec => ../../apispec +replace github.com/weoses/memelo/common => ../../common \ No newline at end of file diff --git a/telegram-service/src/go.sum b/telegram-service/src/go.sum index 39c930b..72feeaf 100644 --- a/telegram-service/src/go.sum +++ b/telegram-service/src/go.sum @@ -1,21 +1,47 @@ +github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= +github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= +github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= +github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= 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/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58= +github.com/dprotaso/go-yit v0.0.0-20250909171706-0a81c39169bc h1:YxqE1wh+qGVXQFinuRq5lT77h6baDtBnAVh61LlXp1o= +github.com/dprotaso/go-yit v0.0.0-20250909171706-0a81c39169bc/go.mod h1:5NQLChvz4dnEIQ8WcHIFbZ1bp0GEUZHiBH+EpTZ4lBc= 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.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/getkin/kin-openapi v0.133.0 h1:pJdmNohVIJ97r4AUFtEXRXwESr8b0bD721u/Tz6k8PQ= +github.com/getkin/kin-openapi v0.133.0/go.mod h1:boAciF6cXk5FhPqe/NQeBTeenbjqU4LhWBf09ILVvWE= +github.com/go-openapi/jsonpointer v0.22.2 h1:JDQEe4B9j6K3tQ7HQQTZfjR59IURhjjLxet2FB4KHyg= +github.com/go-openapi/jsonpointer v0.22.2/go.mod h1:0lBbqeRsQ5lIanv3LHZBrmRGHLHcQoOXQnf88fHlGWo= +github.com/go-openapi/swag/jsonname v0.25.1 h1:Sgx+qbwa4ej6AomWC6pEfXrA6uP2RkaNjA9BR8a1RJU= +github.com/go-openapi/swag/jsonname v0.25.1/go.mod h1:71Tekow6UOLBD3wS7XhdT98g5J5GR13NOTQ9/6Q11Zo= +github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= +github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc= github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +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/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +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= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -24,21 +50,50 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8= +github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= +github.com/oapi-codegen/oapi-codegen/v2 v2.5.1 h1:5vHNY1uuPBRBWqB2Dp0G7YB03phxLQZupZTIZaeorjc= +github.com/oapi-codegen/oapi-codegen/v2 v2.5.1/go.mod h1:ro0npU1BWkcGpCgGD9QwPp44l5OIZ94tB3eabnT7DjQ= +github.com/oapi-codegen/runtime v1.1.2 h1:P2+CubHq8fO4Q6fV1tqDBZHCwpVpvPg7oKiYzQgXIyI= +github.com/oapi-codegen/runtime v1.1.2/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg= +github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= +github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= +github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= +github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= +github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= +github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= 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/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= 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/speakeasy-api/jsonpath v0.6.2 h1:Mys71yd6u8kuowNCR0gCVPlVAHCmKtoGXYoAtcEbqXQ= +github.com/speakeasy-api/jsonpath v0.6.2/go.mod h1:ymb2iSkyOycmzKwbEAYPJV/yi2rSmvBCLZJcyD+VVWw= +github.com/speakeasy-api/openapi-overlay v0.10.3 h1:70een4vwHyslIp796vM+ox6VISClhtXsCjrQNhxwvWs= +github.com/speakeasy-api/openapi-overlay v0.10.3/go.mod h1:RJjV0jbUHqXLS0/Mxv5XE7LAnJHqHw+01RDdpoGqiyY= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= @@ -47,22 +102,37 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= +github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= +github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/vmware-labs/yaml-jsonpath v0.3.2 h1:/5QKeCBGdsInyDCyVNLbXyilb61MXGi9NP674f9Hobk= +github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ= +github.com/woodsbury/decimal128 v1.4.0 h1:xJATj7lLu4f2oObouMt2tgGiElE5gO6mSWUjQsBgUlc= +github.com/woodsbury/decimal128 v1.4.0/go.mod h1:BP46FUrVjVhdTbKT+XuQh2xfQaGki9LMIRJSFuh6THU= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.mongodb.org/mongo-driver/v2 v2.0.0 h1:Jfd7XpdZa9yk3eY774bO7SWVb30noLSirL9nKTpavhI= go.mongodb.org/mongo-driver/v2 v2.0.0/go.mod h1:nSjmNq4JUstE8IRZKTktLgMHM4F1fccL6HGX1yh+8RA= go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= @@ -75,18 +145,67 @@ go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +go.yaml.in/yaml/v4 v4.0.0-rc.3 h1:3h1fjsh1CTAPjW7q/EMe+C8shx5d8ctzZTrLcs/j8Go= +go.yaml.in/yaml/v4 v4.0.0-rc.3/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= +golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= +golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= +golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +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.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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= From 051dfe2957f07dcb67a1b461ef8bc2c56bf3aa64 Mon Sep 17 00:00:00 2001 From: weoses Date: Sun, 16 Nov 2025 21:13:23 +0300 Subject: [PATCH 10/10] fix ci --- apispec/meme-storage/server/api.gen.go | 8 ++++---- storage-service/src/helper/helper.go | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apispec/meme-storage/server/api.gen.go b/apispec/meme-storage/server/api.gen.go index deba1a1..53639f0 100644 --- a/apispec/meme-storage/server/api.gen.go +++ b/apispec/meme-storage/server/api.gen.go @@ -29,10 +29,10 @@ type CreateImageRequestDto struct { // CreateMemeResponseDto defines model for CreateMemeResponseDto. type CreateMemeResponseDto struct { - DuplicateStatus *DuplicateStatus `json:"DuplicateStatus,omitempty"` - Hash *string `json:"Hash,omitempty"` - Id *openapi_types.UUID `json:"Id,omitempty"` - OcrResult *string `json:"OcrResult,omitempty"` + DuplicateStatus DuplicateStatus `json:"DuplicateStatus"` + Hash string `json:"Hash"` + Id openapi_types.UUID `json:"Id"` + OcrResult string `json:"OcrResult"` } // DuplicateStatus defines model for DuplicateStatus. diff --git a/storage-service/src/helper/helper.go b/storage-service/src/helper/helper.go index 3117f73..42a8c88 100644 --- a/storage-service/src/helper/helper.go +++ b/storage-service/src/helper/helper.go @@ -21,10 +21,10 @@ func ElasticToCreateResponse( duplicate server.DuplicateStatus, dto *server.CreateMeme200JSONResponse, ) { - dto.Hash = &elasticEntity.Hash - dto.Id = &elasticEntity.ImageId - dto.OcrResult = &elasticEntity.Result - dto.DuplicateStatus = &duplicate + dto.Hash = elasticEntity.Hash + dto.Id = elasticEntity.ImageId + dto.OcrResult = elasticEntity.Result + dto.DuplicateStatus = duplicate } func OcrImageToEntity(image *client.ImageWithSizeDto) *entity.Image {