├── .commitlintrc.yaml ├── .envrc ├── .github └── workflows │ ├── commitlint.yml │ ├── release-please.yml │ └── test.yml ├── .gitignore ├── .mergify.yml ├── .pre-commit-config.yaml ├── .tool-versions ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── Taskfile.yml ├── examples └── base │ ├── .gitignore │ └── main.go ├── go.mod ├── go.sum ├── golangci.yml ├── plugin.go ├── plugin_test.go └── renovate.json /.commitlintrc.yaml: -------------------------------------------------------------------------------- 1 | extends: 2 | - '@commitlint/config-conventional' 3 | -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | use asdf -------------------------------------------------------------------------------- /.github/workflows/commitlint.yml: -------------------------------------------------------------------------------- 1 | name: Lint Commit Messages 2 | on: [pull_request] 3 | 4 | jobs: 5 | commitlint: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - uses: actions/checkout@v4 9 | with: 10 | fetch-depth: 0 11 | - uses: wagoid/commitlint-github-action@v6 12 | with: 13 | config_file: .commitlintrc.yaml -------------------------------------------------------------------------------- /.github/workflows/release-please.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - master 5 | 6 | permissions: 7 | contents: write 8 | pull-requests: write 9 | 10 | name: release-please 11 | 12 | jobs: 13 | release-please: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: google-github-actions/release-please-action@v4 17 | with: 18 | release-type: go -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | 9 | jobs: 10 | test: 11 | runs-on: ubuntu-latest 12 | name: Test 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@v4 16 | with: 17 | ref: ${{ github.head_ref }} 18 | fetch-depth: 0 19 | 20 | - name: Setup Golang with cache 21 | uses: magnetikonline/action-golang-cache@v5 22 | with: 23 | go-version-file: go.mod 24 | 25 | - name: Run Test 26 | run: | 27 | go test -v `go list ./... | grep -v -e './examples' -e './test'` -covermode=atomic -coverprofile=coverage.out 28 | 29 | - name: Upload coverage reports to Codecov 30 | uses: codecov/codecov-action@v5 31 | env: 32 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | coverage.out 2 | .idea -------------------------------------------------------------------------------- /.mergify.yml: -------------------------------------------------------------------------------- 1 | pull_request_rules: 2 | - name: Automatically merge Renovate PRs 3 | conditions: 4 | - author = renovate[bot] 5 | actions: 6 | merge: 7 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # See https://pre-commit.com for more information 2 | # See https://pre-commit.com/hooks.html for more hooks 3 | repos: 4 | - repo: local 5 | hooks: 6 | - id: golangci-lint 7 | name: golangci-lint 8 | entry: task lint:staged 9 | language: system 10 | types: [go] 11 | pass_filenames: false 12 | - repo: https://github.com/pre-commit/pre-commit-hooks 13 | rev: v4.4.0 14 | hooks: 15 | - id: trailing-whitespace 16 | - id: check-yaml 17 | - id: check-added-large-files 18 | - repo: https://github.com/tekwizely/pre-commit-golang 19 | rev: v1.0.0-rc.1 20 | hooks: 21 | - id: go-fmt 22 | - id: go-mod-tidy 23 | - repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook 24 | rev: v9.4.0 25 | hooks: 26 | - id: commitlint 27 | stages: [commit-msg] 28 | additional_dependencies: 29 | - '@commitlint/config-conventional' 30 | -------------------------------------------------------------------------------- /.tool-versions: -------------------------------------------------------------------------------- 1 | golang 1.24.4 2 | golangci-lint 2.1.6 3 | pre-commit 4.2.0 4 | task 3.38.0 -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [0.16.0](https://github.com/iamelevich/pocketbase-plugin-proxy/compare/v0.15.7...v0.16.0) (2024-08-22) 4 | 5 | 6 | ### Features 7 | 8 | * fix repo tests and other updates ([904da71](https://github.com/iamelevich/pocketbase-plugin-proxy/commit/904da713a99dd988d3d0a97b26a9b709e369efa0)) 9 | 10 | 11 | ### Bug Fixes 12 | 13 | * **deps:** update github.com/labstack/echo/v5 digest to d20a625 ([5a135b5](https://github.com/iamelevich/pocketbase-plugin-proxy/commit/5a135b511c39a75e7e4937e1194c4e1ff77b26de)) 14 | * **deps:** update module github.com/fatih/color to v1.17.0 ([561fdbb](https://github.com/iamelevich/pocketbase-plugin-proxy/commit/561fdbb310320dd8236d27a82dbcff54d544a789)) 15 | * **deps:** update module github.com/pocketbase/pocketbase to v0.22.18 ([e0e9d52](https://github.com/iamelevich/pocketbase-plugin-proxy/commit/e0e9d526d3bfc72a924e8d7f1a9f6d1e8f34355c)) 16 | * **deps:** update module github.com/pocketbase/pocketbase to v0.22.19 ([1012bb5](https://github.com/iamelevich/pocketbase-plugin-proxy/commit/1012bb50d341630236cbdf2c0d9627cb94dc7b4c)) 17 | 18 | ## [0.15.7](https://github.com/iamelevich/pocketbase-plugin-proxy/compare/v0.15.6...v0.15.7) (2023-07-18) 19 | 20 | 21 | ### Bug Fixes 22 | 23 | * **deps:** update module github.com/pocketbase/pocketbase to v0.16.10 ([6affa9b](https://github.com/iamelevich/pocketbase-plugin-proxy/commit/6affa9bdca68fb670b6fa07f689d0fa41ce17d66)) 24 | 25 | ## [0.15.6](https://github.com/iamelevich/pocketbase-plugin-proxy/compare/v0.15.5...v0.15.6) (2023-06-23) 26 | 27 | 28 | ### Bug Fixes 29 | 30 | * **deps:** update module github.com/pocketbase/pocketbase to v0.16.5 ([7ceb1f0](https://github.com/iamelevich/pocketbase-plugin-proxy/commit/7ceb1f00946ba80af461020ad873c0a8c29528a8)) 31 | 32 | ## [0.15.5](https://github.com/iamelevich/pocketbase-plugin-proxy/compare/v0.15.4...v0.15.5) (2023-05-01) 33 | 34 | 35 | ### Bug Fixes 36 | 37 | * **deps:** update module github.com/pocketbase/pocketbase to v0.15.2 ([6b18174](https://github.com/iamelevich/pocketbase-plugin-proxy/commit/6b181749acd8d7cc58f4d195bc5a75b6f2bb80f1)) 38 | 39 | ## [0.15.4](https://github.com/iamelevich/pocketbase-plugin-proxy/compare/v0.15.3...v0.15.4) (2023-04-19) 40 | 41 | 42 | ### Bug Fixes 43 | 44 | * **deps:** update module github.com/pocketbase/pocketbase to v0.15.0 ([c4361ba](https://github.com/iamelevich/pocketbase-plugin-proxy/commit/c4361ba0db836ecb582ee305f56e4b94de82b7b4)) 45 | 46 | ## [0.15.3](https://github.com/iamelevich/pocketbase-plugin-proxy/compare/v0.15.2...v0.15.3) (2023-04-18) 47 | 48 | 49 | ### Bug Fixes 50 | 51 | * **deps:** update module github.com/pocketbase/pocketbase to v0.14.5 ([da22b72](https://github.com/iamelevich/pocketbase-plugin-proxy/commit/da22b7249a18d4fecf4107bfbaebab356298b675)) 52 | 53 | ## [0.15.2](https://github.com/iamelevich/pocketbase-plugin-proxy/compare/v0.15.1...v0.15.2) (2023-04-13) 54 | 55 | 56 | ### Bug Fixes 57 | 58 | * **deps:** update module github.com/pocketbase/pocketbase to v0.14.2 ([0a9c6a0](https://github.com/iamelevich/pocketbase-plugin-proxy/commit/0a9c6a02c74c092dd1103ead71368527f61200bb)) 59 | * **deps:** update module github.com/pocketbase/pocketbase to v0.14.4 ([a8b3ada](https://github.com/iamelevich/pocketbase-plugin-proxy/commit/a8b3adaa7980d8df6507a6a86e3082a25209ede3)) 60 | 61 | ## [0.15.1](https://github.com/iamelevich/pocketbase-plugin-proxy/compare/v0.15.0...v0.15.1) (2023-04-01) 62 | 63 | 64 | ### Bug Fixes 65 | 66 | * fix wrong package name ([bfc2e3b](https://github.com/iamelevich/pocketbase-plugin-proxy/commit/bfc2e3b73a41d6dea807b3c4e43e74e74b970917)) 67 | 68 | ## [0.15.0](https://github.com/iamelevich/pocketbase-plugin-proxy/compare/v0.14.0...v0.15.0) (2023-04-01) 69 | 70 | 71 | ### Features 72 | 73 | * add `SetSkipper` method to `Plugin`, that let change skipper in proxy middleware ([4921998](https://github.com/iamelevich/pocketbase-plugin-proxy/commit/49219982b20909d9d6e49b82d54dd3034b8f956a)) 74 | 75 | 76 | ### Bug Fixes 77 | 78 | * **deps:** update module github.com/pocketbase/pocketbase to v0.14.1 ([48ff88f](https://github.com/iamelevich/pocketbase-plugin-proxy/commit/48ff88f584aedafd627864a2d25539f3686f70ba)) 79 | * not return error from `enableProxy` ([cbc265e](https://github.com/iamelevich/pocketbase-plugin-proxy/commit/cbc265e10b30555a57fb8974558900e07cde2bc8)) 80 | 81 | ## [0.14.0](https://github.com/iamelevich/pocketbase-plugin-proxy/compare/v0.13.4...v0.14.0) (2023-04-01) 82 | 83 | 84 | ### Bug Fixes 85 | 86 | * **deps:** update module github.com/pocketbase/pocketbase to v0.14.0 ([0d0202c](https://github.com/iamelevich/pocketbase-plugin-proxy/commit/0d0202c7618d34837257cd5fa6ee0314064afb58)) 87 | 88 | 89 | ### Miscellaneous Chores 90 | 91 | * release 0.14.0 ([53dbff2](https://github.com/iamelevich/pocketbase-plugin-proxy/commit/53dbff2e3b6bfd92861eb179f35063d9af51baff)) 92 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2023 - present, Ilya Amelevich 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software 5 | and associated documentation files (the "Software"), to deal in the Software without restriction, 6 | including without limitation the rights to use, copy, modify, merge, publish, distribute, 7 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software 8 | is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all copies or 11 | substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 14 | BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 15 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 16 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Test](https://github.com/iamelevich/pocketbase-plugin-proxy/actions/workflows/test.yml/badge.svg)](https://github.com/iamelevich/pocketbase-plugin-proxy/actions/workflows/test.yml) 2 | [![codecov](https://codecov.io/github/iamelevich/pocketbase-plugin-proxy/graph/badge.svg?token=MAXWWCGHWD)](https://codecov.io/github/iamelevich/pocketbase-plugin-proxy) 3 | 4 | 5 | * [Overview](#overview) 6 | * [Requirements](#requirements) 7 | * [Installation](#installation) 8 | * [Example](#example) 9 | * [pocketbase\_plugin\_proxy](#pocketbasepluginproxy) 10 | * [Index](#index) 11 | * [func DefaultSkipper](#func-defaultskipper) 12 | * [type Options](#type-options) 13 | * [type Plugin](#type-plugin) 14 | * [func MustRegister](#func-mustregister) 15 | * [func Register](#func-register) 16 | * [func \(\*Plugin\) SetSkipper](#func-plugin-setskipper) 17 | * [func \(\*Plugin\) Validate](#func-plugin-validate) 18 | * [Contributing](#contributing) 19 | * [Process](#process) 20 | * [Development setup](#development-setup) 21 | * [Testing](#testing) 22 | * [Linting](#linting) 23 | * [Docs update in README](#docs-update-in-readme) 24 | 25 | 26 | # Overview 27 | 28 | This plugin allow proxify requests to other host. It can be useful if you want to use separate server as frontend but use one address for both frontend and backend. 29 | 30 | ## Requirements 31 | 32 | - [Pocketbase](https://github.com/pocketbase/pocketbase) 33 | 34 | ## Installation 35 | 36 | ```bash 37 | go get github.com/iamelevich/pocketbase-plugin-proxy 38 | ``` 39 | 40 | ## Example 41 | 42 | You can check examples in [examples folder](/examples) 43 | 44 | ```go 45 | package main 46 | 47 | import ( 48 | "log" 49 | 50 | proxyPlugin "github.com/iamelevich/pocketbase-plugin-proxy" 51 | "github.com/pocketbase/pocketbase" 52 | ) 53 | 54 | func main() { 55 | app := pocketbase.New() 56 | 57 | // Setup proxy plugin 58 | proxyPlugin.MustRegister(app, &proxyPlugin.Options{ 59 | Enabled: true, 60 | Url: "http://localhost:3000", 61 | }) 62 | 63 | if err := app.Start(); err != nil { 64 | log.Fatal(err) 65 | } 66 | } 67 | ``` 68 | 69 | 70 | 71 | 72 | 73 | # pocketbase\_plugin\_proxy 74 | 75 | ```go 76 | import "github.com/iamelevich/pocketbase-plugin-proxy" 77 | ``` 78 | 79 | ## Index 80 | 81 | - [func DefaultSkipper\(c echo.Context\) bool](<#DefaultSkipper>) 82 | - [type Options](<#Options>) 83 | - [type Plugin](<#Plugin>) 84 | - [func MustRegister\(app core.App, options \*Options\) \*Plugin](<#MustRegister>) 85 | - [func Register\(app core.App, options \*Options\) \(\*Plugin, error\)](<#Register>) 86 | - [func \(p \*Plugin\) SetSkipper\(skipper middleware.Skipper\)](<#Plugin.SetSkipper>) 87 | - [func \(p \*Plugin\) Validate\(\) error](<#Plugin.Validate>) 88 | 89 | 90 | 91 | ## func [DefaultSkipper]() 92 | 93 | ```go 94 | func DefaultSkipper(c echo.Context) bool 95 | ``` 96 | 97 | DefaultSkipper skip proxy middleware for requests, where path starts with /\_/ or /api/. 98 | 99 | 100 | ## type [Options]() 101 | 102 | Options defines optional struct to customize the default plugin behavior. 103 | 104 | ```go 105 | type Options struct { 106 | // Enabled defines if proxy should be enabled. 107 | Enabled bool 108 | 109 | //Url to the target. 110 | // 111 | //Only http and https links are supported. 112 | Url string 113 | 114 | // Are proxy logs enabled? 115 | ProxyLogsEnabled bool 116 | } 117 | ``` 118 | 119 | 120 | ## type [Plugin]() 121 | 122 | 123 | 124 | ```go 125 | type Plugin struct { 126 | // contains filtered or unexported fields 127 | } 128 | ``` 129 | 130 | 131 | ### func [MustRegister]() 132 | 133 | ```go 134 | func MustRegister(app core.App, options *Options) *Plugin 135 | ``` 136 | 137 | MustRegister is a helper function that registers plugin and panics if error occurred. 138 | 139 | 140 | ### func [Register]() 141 | 142 | ```go 143 | func Register(app core.App, options *Options) (*Plugin, error) 144 | ``` 145 | 146 | Register registers plugin. 147 | 148 | 149 | ### func \(\*Plugin\) [SetSkipper]() 150 | 151 | ```go 152 | func (p *Plugin) SetSkipper(skipper middleware.Skipper) 153 | ``` 154 | 155 | SetSkipper set skipper function that should return true if that route shouldn't be proxied. 156 | 157 | If not set, the DefaultSkipper is used: 158 | 159 | If set \- you should also control the middleware behavior for /\_/ and /api/ routes. 160 | 161 | Example: 162 | 163 | ``` 164 | plugin := proxyPlugin.MustRegister(app, &proxyPlugin.Options{ 165 | Enabled: true, 166 | Url: "http://localhost:3000", 167 | }) 168 | plugin.SetSkipper(func(c echo.Context) bool { 169 | return c.Request().URL.Path == "/my-super-secret-route" 170 | }) 171 | ``` 172 | 173 | 174 | ### func \(\*Plugin\) [Validate]() 175 | 176 | ```go 177 | func (p *Plugin) Validate() error 178 | ``` 179 | 180 | Validate plugin options. Return error if some option is invalid. 181 | 182 | Generated by [gomarkdoc]() 183 | 184 | 185 | 186 | 187 | # Contributing 188 | 189 | This pocketbase plugin is free and open source project licensed under the [MIT License](LICENSE.md). 190 | You are free to do whatever you want with it, even offering it as a paid service. 191 | 192 | ## Process 193 | 194 | - Fork the repo 195 | - Create a new branch 196 | - Make your changes 197 | - Create a pull request 198 | - Wait for review 199 | - Make changes if needed 200 | - Merge 201 | - Celebrate :) 202 | 203 | ## Development setup 204 | 205 | - Install [asdf](https://asdf-vm.com/#/core-manage-asdf-vm) and plugins for tools listed in [.tool-versions](.tool-versions) file. 206 | - This repo also uses [asdf-direnv](https://github.com/asdf-community/asdf-direnv). Install it and run `direnv allow` in the repo root. 207 | - Setup `pre-commit` hooks with `pre-commit install -t commit-msg -t pre-commit` 208 | 209 | ## Testing 210 | 211 | - Run `task test` to run tests 212 | - Run `task test:report` to run tests and get coverage report in `./coverage.html` 213 | 214 | ## Linting 215 | 216 | - Run `task lint` to run linters 217 | 218 | ## Docs update in README 219 | 220 | - Run `task docs` to update docs in README (it will also install [gomarkdoc](https://github.com/princjef/gomarkdoc)) 221 | -------------------------------------------------------------------------------- /Taskfile.yml: -------------------------------------------------------------------------------- 1 | version: 3 2 | 3 | tasks: 4 | lint: 5 | cmds: 6 | - golangci-lint run ./... 7 | 8 | lint:staged: 9 | cmds: 10 | - git diff --cached > /tmp/stage.patch 11 | - defer: rm /tmp/stage.patch 12 | - golangci-lint run --new-from-patch=/tmp/stage.patch 13 | 14 | test: 15 | cmds: 16 | - go test -v `go list ./... | grep -v -e './examples' -e './test'` --cover 17 | test:report: 18 | cmds: 19 | - go test -v `go list ./... | grep -v -e './examples' -e './test'` --coverprofile=coverage.out 20 | - go tool cover -html=coverage.out -o coverage.html 21 | 22 | run:example:base: 23 | cmds: 24 | - go run main.go serve 25 | dir: examples/base 26 | 27 | # Generate docs 28 | # Require gomarkdoc (https://github.com/princjef/gomarkdoc) 29 | docs: 30 | cmds: 31 | - go install github.com/princjef/gomarkdoc/cmd/gomarkdoc@latest 32 | - gomarkdoc -o README.md -e . -------------------------------------------------------------------------------- /examples/base/.gitignore: -------------------------------------------------------------------------------- 1 | # ignore everything 2 | /* 3 | 4 | # exclude from the ignore filter 5 | !.gitignore 6 | !main.go 7 | -------------------------------------------------------------------------------- /examples/base/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | 6 | proxyPlugin "github.com/iamelevich/pocketbase-plugin-proxy" 7 | "github.com/pocketbase/pocketbase" 8 | ) 9 | 10 | func main() { 11 | app := pocketbase.New() 12 | 13 | // Setup ngrok 14 | proxyPlugin.MustRegister(app, &proxyPlugin.Options{ 15 | Enabled: true, 16 | Url: "http://localhost:3000", 17 | }) 18 | 19 | if err := app.Start(); err != nil { 20 | log.Fatal(err) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/iamelevich/pocketbase-plugin-proxy 2 | 3 | go 1.23 4 | 5 | toolchain go1.24.4 6 | 7 | require ( 8 | github.com/fatih/color v1.18.0 9 | github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61 10 | github.com/pocketbase/pocketbase v0.22.27 11 | ) 12 | 13 | require ( 14 | github.com/AlecAivazis/survey/v2 v2.3.7 // indirect 15 | github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect 16 | github.com/aws/aws-sdk-go-v2 v1.32.2 // indirect 17 | github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4 // indirect 18 | github.com/aws/aws-sdk-go-v2/config v1.27.31 // indirect 19 | github.com/aws/aws-sdk-go-v2/credentials v1.17.30 // indirect 20 | github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 // indirect 21 | github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.15 // indirect 22 | github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 // indirect 23 | github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 // indirect 24 | github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect 25 | github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.16 // indirect 26 | github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 // indirect 27 | github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.18 // indirect 28 | github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 // indirect 29 | github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.16 // indirect 30 | github.com/aws/aws-sdk-go-v2/service/s3 v1.60.1 // indirect 31 | github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 // indirect 32 | github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 // indirect 33 | github.com/aws/aws-sdk-go-v2/service/sts v1.30.5 // indirect 34 | github.com/aws/smithy-go v1.22.0 // indirect 35 | github.com/disintegration/imaging v1.6.2 // indirect 36 | github.com/domodwyer/mailyak/v3 v3.6.2 // indirect 37 | github.com/dustin/go-humanize v1.0.1 // indirect 38 | github.com/gabriel-vasile/mimetype v1.4.5 // indirect 39 | github.com/ganigeorgiev/fexpr v0.4.1 // indirect 40 | github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect 41 | github.com/goccy/go-json v0.10.3 // indirect 42 | github.com/golang-jwt/jwt/v4 v4.5.0 // indirect 43 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect 44 | github.com/google/uuid v1.6.0 // indirect 45 | github.com/googleapis/gax-go/v2 v2.13.0 // indirect 46 | github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect 47 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 48 | github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect 49 | github.com/mattn/go-colorable v0.1.13 // indirect 50 | github.com/mattn/go-isatty v0.0.20 // indirect 51 | github.com/mattn/go-sqlite3 v1.14.22 // indirect 52 | github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect 53 | github.com/ncruces/go-strftime v0.1.9 // indirect 54 | github.com/pocketbase/dbx v1.10.1 // indirect 55 | github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect 56 | github.com/spf13/cast v1.7.0 // indirect 57 | github.com/spf13/cobra v1.8.1 // indirect 58 | github.com/spf13/pflag v1.0.5 // indirect 59 | github.com/valyala/bytebufferpool v1.0.0 // indirect 60 | github.com/valyala/fasttemplate v1.2.2 // indirect 61 | go.opencensus.io v0.24.0 // indirect 62 | gocloud.dev v0.39.0 // indirect 63 | golang.org/x/crypto v0.28.0 // indirect 64 | golang.org/x/image v0.19.0 // indirect 65 | golang.org/x/net v0.30.0 // indirect 66 | golang.org/x/oauth2 v0.22.0 // indirect 67 | golang.org/x/sync v0.8.0 // indirect 68 | golang.org/x/sys v0.26.0 // indirect 69 | golang.org/x/term v0.25.0 // indirect 70 | golang.org/x/text v0.19.0 // indirect 71 | golang.org/x/time v0.6.0 // indirect 72 | golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect 73 | google.golang.org/api v0.194.0 // indirect 74 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed // indirect 75 | google.golang.org/grpc v1.65.0 // indirect 76 | google.golang.org/protobuf v1.34.2 // indirect 77 | modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a // indirect 78 | modernc.org/libc v1.55.3 // indirect 79 | modernc.org/mathutil v1.6.0 // indirect 80 | modernc.org/memory v1.8.0 // indirect 81 | modernc.org/sqlite v1.32.0 // indirect 82 | modernc.org/strutil v1.2.0 // indirect 83 | modernc.org/token v1.1.0 // indirect 84 | ) 85 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14= 3 | cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU= 4 | cloud.google.com/go/auth v0.7.2 h1:uiha352VrCDMXg+yoBtaD0tUF4Kv9vrtrWPYXwutnDE= 5 | cloud.google.com/go/auth v0.7.2/go.mod h1:VEc4p5NNxycWQTMQEDQF0bd6aTMb6VgYDXEwiJJQAbs= 6 | cloud.google.com/go/auth/oauth2adapt v0.2.3 h1:MlxF+Pd3OmSudg/b1yZ5lJwoXCEaeedAguodky1PcKI= 7 | cloud.google.com/go/auth/oauth2adapt v0.2.3/go.mod h1:tMQXOfZzFuNuUxOypHlQEXgdfX5cuhwU+ffUuXRJE8I= 8 | cloud.google.com/go/compute v1.25.0 h1:H1/4SqSUhjPFE7L5ddzHOfY2bCAvjwNRZPNl6Ni5oYU= 9 | cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= 10 | cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= 11 | cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= 12 | cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= 13 | cloud.google.com/go/storage v1.39.1 h1:MvraqHKhogCOTXTlct/9C3K3+Uy2jBmFYb3/Sp6dVtY= 14 | cloud.google.com/go/storage v1.39.1/go.mod h1:xK6xZmxZmo+fyP7+DEF6FhNc24/JAe95OLyOHCXFH1o= 15 | filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= 16 | filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= 17 | github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= 18 | github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= 19 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 20 | github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= 21 | github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= 22 | github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= 23 | github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= 24 | github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= 25 | github.com/aws/aws-sdk-go v1.51.11 h1:El5VypsMIz7sFwAAj/j06JX9UGs4KAbAIEaZ57bNY4s= 26 | github.com/aws/aws-sdk-go v1.51.11/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= 27 | github.com/aws/aws-sdk-go-v2 v1.30.3 h1:jUeBtG0Ih+ZIFH0F4UkmL9w3cSpaMv9tYYDbzILP8dY= 28 | github.com/aws/aws-sdk-go-v2 v1.30.3/go.mod h1:nIQjQVp5sfpQcTc9mPSr1B0PaWK5ByX9MOoDadSN4lc= 29 | github.com/aws/aws-sdk-go-v2 v1.30.4 h1:frhcagrVNrzmT95RJImMHgabt99vkXGslubDaDagTk8= 30 | github.com/aws/aws-sdk-go-v2 v1.30.4/go.mod h1:CT+ZPWXbYrci8chcARI3OmI/qgd+f6WtuLOoaIA8PR0= 31 | github.com/aws/aws-sdk-go-v2 v1.32.2 h1:AkNLZEyYMLnx/Q/mSKkcMqwNFXMAvFto9bNsHqcTduI= 32 | github.com/aws/aws-sdk-go-v2 v1.32.2/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo= 33 | github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3 h1:tW1/Rkad38LA15X4UQtjXZXNKsCgkshC3EbmcUmghTg= 34 | github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.3/go.mod h1:UbnqO+zjqk3uIt9yCACHJ9IVNhyhOCnYk8yA19SAWrM= 35 | github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4 h1:70PVAiL15/aBMh5LThwgXdSQorVr91L127ttckI9QQU= 36 | github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.4/go.mod h1:/MQxMqci8tlqDH+pjmoLu1i0tbWCUP1hhyMRuFxpQCw= 37 | github.com/aws/aws-sdk-go-v2/config v1.27.27 h1:HdqgGt1OAP0HkEDDShEl0oSYa9ZZBSOmKpdpsDMdO90= 38 | github.com/aws/aws-sdk-go-v2/config v1.27.27/go.mod h1:MVYamCg76dFNINkZFu4n4RjDixhVr51HLj4ErWzrVwg= 39 | github.com/aws/aws-sdk-go-v2/config v1.27.31 h1:kxBoRsjhT3pq0cKthgj6RU6bXTm/2SgdoUMyrVw0rAI= 40 | github.com/aws/aws-sdk-go-v2/config v1.27.31/go.mod h1:z04nZdSWFPaDwK3DdJOG2r+scLQzMYuJeW0CujEm9FM= 41 | github.com/aws/aws-sdk-go-v2/credentials v1.17.27 h1:2raNba6gr2IfA0eqqiP2XiQ0UVOpGPgDSi0I9iAP+UI= 42 | github.com/aws/aws-sdk-go-v2/credentials v1.17.27/go.mod h1:gniiwbGahQByxan6YjQUMcW4Aov6bLC3m+evgcoN4r4= 43 | github.com/aws/aws-sdk-go-v2/credentials v1.17.30 h1:aau/oYFtibVovr2rDt8FHlU17BTicFEMAi29V1U+L5Q= 44 | github.com/aws/aws-sdk-go-v2/credentials v1.17.30/go.mod h1:BPJ/yXV92ZVq6G8uYvbU0gSl8q94UB63nMT5ctNO38g= 45 | github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11 h1:KreluoV8FZDEtI6Co2xuNk/UqI9iwMrOx/87PBNIKqw= 46 | github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.11/go.mod h1:SeSUYBLsMYFoRvHE0Tjvn7kbxaUhl75CJi1sbfhMxkU= 47 | github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12 h1:yjwoSyDZF8Jth+mUk5lSPJCkMC0lMy6FaCD51jm6ayE= 48 | github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.12/go.mod h1:fuR57fAgMk7ot3WcNQfb6rSEn+SUffl7ri+aa8uKysI= 49 | github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.8 h1:u1KOU1S15ufyZqmH/rA3POkiRH6EcDANHj2xHRzq+zc= 50 | github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.8/go.mod h1:WPv2FRnkIOoDv/8j2gSUsI4qDc7392w5anFB/I89GZ8= 51 | github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.15 h1:ijB7hr56MngOiELJe0C5aQRaBQ11LveNgWFyG02AUto= 52 | github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.15/go.mod h1:0QEmQSSWMVfiAk93l1/ayR9DQ9+jwni7gHS2NARZXB0= 53 | github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15 h1:SoNJ4RlFEQEbtDcCEt+QG56MY4fm4W8rYirAmq+/DdU= 54 | github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.15/go.mod h1:U9ke74k1n2bf+RIgoX1SXFed1HLs51OgUSs+Ph0KJP8= 55 | github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16 h1:TNyt/+X43KJ9IJJMjKfa3bNTiZbUP7DeCxfbTROESwY= 56 | github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.16/go.mod h1:2DwJF39FlNAUiX5pAc0UNeiz16lK2t7IaFcm0LFHEgc= 57 | github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15 h1:C6WHdGnTDIYETAm5iErQUiVNsclNx9qbJVPIt03B6bI= 58 | github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.15/go.mod h1:ZQLZqhcu+JhSrA9/NXRm8SkDvsycE+JkV3WGY41e+IM= 59 | github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16 h1:jYfy8UPmd+6kJW5YhY0L1/KftReOGxI/4NtVSTh9O/I= 60 | github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.16/go.mod h1:7ZfEPZxkW42Afq4uQB8H2E2e6ebh6mXTueEpYzjCzcs= 61 | github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= 62 | github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= 63 | github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= 64 | github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= 65 | github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.15 h1:Z5r7SycxmSllHYmaAZPpmN8GviDrSGhMS6bldqtXZPw= 66 | github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.15/go.mod h1:CetW7bDE00QoGEmPUoZuRog07SGVAUVW6LFpNP0YfIg= 67 | github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.16 h1:mimdLQkIX1zr8GIPY1ZtALdBQGxcASiBd2MOp8m/dMc= 68 | github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.16/go.mod h1:YHk6owoSwrIsok+cAH9PENCOGoH5PU2EllX4vLtSrsY= 69 | github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 h1:dT3MqvGhSoaIhRseqw2I0yH81l7wiR2vjs57O51EAm8= 70 | github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3/go.mod h1:GlAeCkHwugxdHaueRr4nhPuY+WW+gR8UjlcqzPr1SPI= 71 | github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4 h1:KypMCbLPPHEmf9DgMGw51jMj77VfGPAN2Kv4cfhlfgI= 72 | github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.4/go.mod h1:Vz1JQXliGcQktFTN/LN6uGppAIRoLBR2bMvIMP0gOjc= 73 | github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.17 h1:YPYe6ZmvUfDDDELqEKtAd6bo8zxhkm+XEFEzQisqUIE= 74 | github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.17/go.mod h1:oBtcnYua/CgzCWYN7NZ5j7PotFDaFSUjCYVTtfyn7vw= 75 | github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.18 h1:GckUnpm4EJOAio1c8o25a+b3lVfwVzC9gnSBqiiNmZM= 76 | github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.18/go.mod h1:Br6+bxfG33Dk3ynmkhsW2Z/t9D4+lRqdLDNCKi85w0U= 77 | github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17 h1:HGErhhrxZlQ044RiM+WdoZxp0p+EGM62y3L6pwA4olE= 78 | github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.17/go.mod h1:RkZEx4l0EHYDJpWppMJ3nD9wZJAa8/0lq9aVC+r2UII= 79 | github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18 h1:tJ5RnkHCiSH0jyd6gROjlJtNwov0eGYNz8s8nFcR0jQ= 80 | github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.18/go.mod h1:++NHzT+nAF7ZPrHPsA+ENvsXkOO8wEu+C6RXltAG4/c= 81 | github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.15 h1:246A4lSTXWJw/rmlQI+TT2OcqeDMKBdyjEQrafMaQdA= 82 | github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.15/go.mod h1:haVfg3761/WF7YPuJOER2MP0k4UAXyHaLclKXB6usDg= 83 | github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.16 h1:jg16PhLPUiHIj8zYIW6bqzeQSuHVEiWnGA0Brz5Xv2I= 84 | github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.16/go.mod h1:Uyk1zE1VVdsHSU7096h/rwnXDzOzYQVl+FNPhPw7ShY= 85 | github.com/aws/aws-sdk-go-v2/service/s3 v1.58.2 h1:sZXIzO38GZOU+O0C+INqbH7C2yALwfMWpd64tONS/NE= 86 | github.com/aws/aws-sdk-go-v2/service/s3 v1.58.2/go.mod h1:Lcxzg5rojyVPU/0eFwLtcyTaek/6Mtic5B1gJo7e/zE= 87 | github.com/aws/aws-sdk-go-v2/service/s3 v1.60.1 h1:mx2ucgtv+MWzJesJY9Ig/8AFHgoE5FwLXwUVgW/FGdI= 88 | github.com/aws/aws-sdk-go-v2/service/s3 v1.60.1/go.mod h1:BSPI0EfnYUuNHPS0uqIo5VrRwzie+Fp+YhQOUs16sKI= 89 | github.com/aws/aws-sdk-go-v2/service/sso v1.22.4 h1:BXx0ZIxvrJdSgSvKTZ+yRBeSqqgPM89VPlulEcl37tM= 90 | github.com/aws/aws-sdk-go-v2/service/sso v1.22.4/go.mod h1:ooyCOXjvJEsUw7x+ZDHeISPMhtwI3ZCB7ggFMcFfWLU= 91 | github.com/aws/aws-sdk-go-v2/service/sso v1.22.5 h1:zCsFCKvbj25i7p1u94imVoO447I/sFv8qq+lGJhRN0c= 92 | github.com/aws/aws-sdk-go-v2/service/sso v1.22.5/go.mod h1:ZeDX1SnKsVlejeuz41GiajjZpRSWR7/42q/EyA/QEiM= 93 | github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 h1:yiwVzJW2ZxZTurVbYWA7QOrAaCYQR72t0wrSBfoesUE= 94 | github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4/go.mod h1:0oxfLkpz3rQ/CHlx5hB7H69YUpFiI1tql6Q6Ne+1bCw= 95 | github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5 h1:SKvPgvdvmiTWoi0GAJ7AsJfOz3ngVkD/ERbs5pUnHNI= 96 | github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.5/go.mod h1:20sz31hv/WsPa3HhU3hfrIet2kxM4Pe0r20eBZ20Tac= 97 | github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 h1:ZsDKRLXGWHk8WdtyYMoGNO7bTudrvuKpDKgMVRlepGE= 98 | github.com/aws/aws-sdk-go-v2/service/sts v1.30.3/go.mod h1:zwySh8fpFyXp9yOr/KVzxOl8SRqgf/IDw5aUt9UKFcQ= 99 | github.com/aws/aws-sdk-go-v2/service/sts v1.30.5 h1:OMsEmCyz2i89XwRwPouAJvhj81wINh+4UK+k/0Yo/q8= 100 | github.com/aws/aws-sdk-go-v2/service/sts v1.30.5/go.mod h1:vmSqFK+BVIwVpDAGZB3CoCXHzurt4qBE8lf+I/kRTh0= 101 | github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE= 102 | github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= 103 | github.com/aws/smithy-go v1.20.4 h1:2HK1zBdPgRbjFOHlfeQZfpC4r72MOb9bZkiFwggKO+4= 104 | github.com/aws/smithy-go v1.20.4/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= 105 | github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM= 106 | github.com/aws/smithy-go v1.22.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= 107 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 108 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 109 | github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= 110 | github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 111 | github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI= 112 | github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= 113 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 114 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 115 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 116 | github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= 117 | github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= 118 | github.com/domodwyer/mailyak/v3 v3.6.2 h1:x3tGMsyFhTCaxp6ycgR0FE/bu5QiNp+hetUuCOBXMn8= 119 | github.com/domodwyer/mailyak/v3 v3.6.2/go.mod h1:lOm/u9CyCVWHeaAmHIdF4RiKVxKUT/H5XX10lIKAL6c= 120 | github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= 121 | github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= 122 | github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 123 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 124 | github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= 125 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= 126 | github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= 127 | github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= 128 | github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= 129 | github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= 130 | github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= 131 | github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= 132 | github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= 133 | github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= 134 | github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= 135 | github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= 136 | github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4= 137 | github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4= 138 | github.com/ganigeorgiev/fexpr v0.4.1 h1:hpUgbUEEWIZhSDBtf4M9aUNfQQ0BZkGRaMePy7Gcx5k= 139 | github.com/ganigeorgiev/fexpr v0.4.1/go.mod h1:RyGiGqmeXhEQ6+mlGdnUleLHgtzzu/VGO2WtJkF5drE= 140 | github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= 141 | github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 142 | github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= 143 | github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= 144 | github.com/go-ozzo/ozzo-validation/v4 v4.3.0 h1:byhDUpfEwjsVQb1vBunvIjh2BHQ9ead57VkAEY4V+Es= 145 | github.com/go-ozzo/ozzo-validation/v4 v4.3.0/go.mod h1:2NKgrcHl3z6cJs+3Oo940FPRiTzuqKbvfrL2RxCj6Ew= 146 | github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= 147 | github.com/go-sql-driver/mysql v1.8.0 h1:UtktXaU2Nb64z/pLiGIxY4431SJ4/dR5cjMmlVHgnT4= 148 | github.com/go-sql-driver/mysql v1.8.0/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= 149 | github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= 150 | github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= 151 | github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= 152 | github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= 153 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 154 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 155 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= 156 | github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 157 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 158 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 159 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 160 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 161 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 162 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 163 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 164 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 165 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 166 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= 167 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 168 | github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= 169 | github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 170 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 171 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 172 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 173 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 174 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 175 | github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 176 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 177 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 178 | github.com/google/pprof v0.0.0-20240625030939-27f56978b8b0 h1:e+8XbKB6IMn8A4OAyZccO4pYfB3s7bt6azNIPE7AnPg= 179 | github.com/google/pprof v0.0.0-20240625030939-27f56978b8b0/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= 180 | github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= 181 | github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= 182 | github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 183 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 184 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 185 | github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI= 186 | github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA= 187 | github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= 188 | github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= 189 | github.com/googleapis/gax-go/v2 v2.13.0 h1:yitjD5f7jQHhyDsnhKEBU52NdvvdSeGzlAnDPT0hH1s= 190 | github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A= 191 | github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= 192 | github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= 193 | github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= 194 | github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= 195 | github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= 196 | github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= 197 | github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= 198 | github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= 199 | github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= 200 | github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= 201 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 202 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 203 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 204 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 205 | github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61 h1:FwuzbVh87iLiUQj1+uQUsuw9x5t9m5n5g7rG7o4svW4= 206 | github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61/go.mod h1:paQfF1YtHe+GrGg5fOgjsjoCX/UKDr9bc1DoWpZfns8= 207 | github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 208 | github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 209 | github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 210 | github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 211 | github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 212 | github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 213 | github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 214 | github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= 215 | github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= 216 | github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= 217 | github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= 218 | github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= 219 | github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= 220 | github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= 221 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 222 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 223 | github.com/pocketbase/dbx v1.10.1 h1:cw+vsyfCJD8YObOVeqb93YErnlxwYMkNZ4rwN0G0AaA= 224 | github.com/pocketbase/dbx v1.10.1/go.mod h1:xXRCIAKTHMgUCyCKZm55pUOdvFziJjQfXaWKhu2vhMs= 225 | github.com/pocketbase/pocketbase v0.22.19 h1:Hu9J2nsRQIaw8MiDLzE65xUPyMPjf4DcS2f+QmH1G+c= 226 | github.com/pocketbase/pocketbase v0.22.19/go.mod h1:0QFvDOOW7ANId78ChZSagyHbmP6CgMxDQrQFXzeaDpA= 227 | github.com/pocketbase/pocketbase v0.22.20 h1:yUkhO5bTPWlzD4ZK6EQlS4R3AcHKDlBD+DxxU2BR83I= 228 | github.com/pocketbase/pocketbase v0.22.20/go.mod h1:Cw5E4uoGhKItBIE2lJL3NfmiUr9Syk2xaNJ2G7Dssow= 229 | github.com/pocketbase/pocketbase v0.22.21 h1:DGPCxn6co8VuTV0mton4NFO/ON49XiFMszRr+Mysy48= 230 | github.com/pocketbase/pocketbase v0.22.21/go.mod h1:Cw5E4uoGhKItBIE2lJL3NfmiUr9Syk2xaNJ2G7Dssow= 231 | github.com/pocketbase/pocketbase v0.22.23 h1:cnjSiBcMf7VIhXmoBmZCAV8qKYkOubHCOQQPZMKFBAk= 232 | github.com/pocketbase/pocketbase v0.22.23/go.mod h1:h2ojT2pqBWH9LLl1aiawkwXiICKtzZA/kjM/8VhydR4= 233 | github.com/pocketbase/pocketbase v0.22.24 h1:IxjVN5Yd3k4k59CZuD8tBFL6qjmDVb/uqK3xU8JSSsE= 234 | github.com/pocketbase/pocketbase v0.22.24/go.mod h1:h2ojT2pqBWH9LLl1aiawkwXiICKtzZA/kjM/8VhydR4= 235 | github.com/pocketbase/pocketbase v0.22.25 h1:ewn97JQu0izpge+a57YZYPhOOqdTmHao8kUOtpxj7AQ= 236 | github.com/pocketbase/pocketbase v0.22.25/go.mod h1:h2ojT2pqBWH9LLl1aiawkwXiICKtzZA/kjM/8VhydR4= 237 | github.com/pocketbase/pocketbase v0.22.26 h1:8hoD9xCEOaZfDpP23FkFH6A51QDfM0gK+vnxlTCyNXw= 238 | github.com/pocketbase/pocketbase v0.22.26/go.mod h1:h2ojT2pqBWH9LLl1aiawkwXiICKtzZA/kjM/8VhydR4= 239 | github.com/pocketbase/pocketbase v0.22.27 h1:uhA8W4x0dQP9G3m9Azs3kruaKcN7icFWyIbBwZ+mZ7I= 240 | github.com/pocketbase/pocketbase v0.22.27/go.mod h1:h2ojT2pqBWH9LLl1aiawkwXiICKtzZA/kjM/8VhydR4= 241 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 242 | github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= 243 | github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= 244 | github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= 245 | github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= 246 | github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 247 | github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= 248 | github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= 249 | github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= 250 | github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= 251 | github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= 252 | github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= 253 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= 254 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 255 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 256 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 257 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 258 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 259 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 260 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 261 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 262 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 263 | github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= 264 | github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 265 | github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= 266 | github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= 267 | github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= 268 | github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= 269 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 270 | go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= 271 | go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= 272 | go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= 273 | go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= 274 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= 275 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= 276 | go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= 277 | go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= 278 | go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= 279 | go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= 280 | go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= 281 | go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= 282 | gocloud.dev v0.37.0 h1:XF1rN6R0qZI/9DYjN16Uy0durAmSlf58DHOcb28GPro= 283 | gocloud.dev v0.37.0/go.mod h1:7/O4kqdInCNsc6LqgmuFnS0GRew4XNNYWpA44yQnwco= 284 | gocloud.dev v0.39.0 h1:EYABYGhAalPUaMrbSKOr5lejxoxvXj99nE8XFtsDgds= 285 | gocloud.dev v0.39.0/go.mod h1:drz+VyYNBvrMTW0KZiBAYEdl8lbNZx+OQ7oQvdrFmSQ= 286 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 287 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 288 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 289 | golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= 290 | golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= 291 | golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= 292 | golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= 293 | golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= 294 | golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= 295 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 296 | golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 297 | golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ= 298 | golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E= 299 | golang.org/x/image v0.19.0 h1:D9FX4QWkLfkeqaC62SonffIIuYdOk/UE2XKUBgRIBIQ= 300 | golang.org/x/image v0.19.0/go.mod h1:y0zrRqlQRWQ5PXaYCOMLTW2fpsxZ8Qh9I/ohnInJEys= 301 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 302 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 303 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 304 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 305 | golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= 306 | golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 307 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 308 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 309 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 310 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 311 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 312 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 313 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 314 | golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 315 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 316 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 317 | golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= 318 | golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= 319 | golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= 320 | golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= 321 | golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= 322 | golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= 323 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 324 | golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= 325 | golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= 326 | golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= 327 | golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= 328 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 329 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 330 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 331 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 332 | golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= 333 | golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 334 | golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= 335 | golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 336 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 337 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 338 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 339 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 340 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 341 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 342 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 343 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 344 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 345 | golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 346 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 347 | golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= 348 | golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 349 | golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= 350 | golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 351 | golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= 352 | golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 353 | golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= 354 | golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 355 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 356 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 357 | golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= 358 | golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= 359 | golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= 360 | golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= 361 | golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= 362 | golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= 363 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 364 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 365 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 366 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 367 | golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 368 | golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= 369 | golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= 370 | golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= 371 | golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= 372 | golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= 373 | golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= 374 | golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= 375 | golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= 376 | golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= 377 | golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= 378 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 379 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 380 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 381 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 382 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 383 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 384 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 385 | golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= 386 | golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= 387 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 388 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 389 | golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk= 390 | golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= 391 | google.golang.org/api v0.189.0 h1:equMo30LypAkdkLMBqfeIqtyAnlyig1JSZArl4XPwdI= 392 | google.golang.org/api v0.189.0/go.mod h1:FLWGJKb0hb+pU2j+rJqwbnsF+ym+fQs73rbJ+KAUgy8= 393 | google.golang.org/api v0.194.0 h1:dztZKG9HgtIpbI35FhfuSNR/zmaMVdxNlntHj1sIS4s= 394 | google.golang.org/api v0.194.0/go.mod h1:AgvUFdojGANh3vI+P7EVnxj3AISHllxGCJSFmggmnd0= 395 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 396 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 397 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 398 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 399 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 400 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= 401 | google.golang.org/genproto v0.0.0-20240722135656-d784300faade h1:lKFsS7wpngDgSCeFn7MoLy+wBDQZ1UQIJD4UNM1Qvkg= 402 | google.golang.org/genproto v0.0.0-20240722135656-d784300faade/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= 403 | google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY= 404 | google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0= 405 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240723171418-e6d459c13d2a h1:hqK4+jJZXCU4pW7jsAdGOVFIfLHQeV7LaizZKnZ84HI= 406 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240723171418-e6d459c13d2a/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= 407 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed h1:J6izYgfBXAI3xTKLgxzTmUltdYaLsuBxFCgDHWJ/eXg= 408 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= 409 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 410 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 411 | google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= 412 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 413 | google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= 414 | google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= 415 | google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= 416 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 417 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 418 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 419 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 420 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 421 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 422 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 423 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 424 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 425 | google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= 426 | google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= 427 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 428 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 429 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 430 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 431 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 432 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 433 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 434 | modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ= 435 | modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= 436 | modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y= 437 | modernc.org/ccgo/v4 v4.19.2/go.mod h1:ysS3mxiMV38XGRTTcgo0DQTeTmAO4oCmJl1nX9VFI3s= 438 | modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= 439 | modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= 440 | modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw= 441 | modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= 442 | modernc.org/gc/v3 v3.0.0-20240722195230-4a140ff9c08e h1:WPC4v0rNIFb2PY+nBBEEKyugPPRHPzUgyN3xZPpGK58= 443 | modernc.org/gc/v3 v3.0.0-20240722195230-4a140ff9c08e/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= 444 | modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a h1:CfbpOLEo2IwNzJdMvE8aiRbPMxoTpgAJeyePh0SmO8M= 445 | modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= 446 | modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= 447 | modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w= 448 | modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= 449 | modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= 450 | modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= 451 | modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= 452 | modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= 453 | modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= 454 | modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= 455 | modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= 456 | modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= 457 | modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= 458 | modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= 459 | modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= 460 | modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= 461 | modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= 462 | modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= 463 | modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= 464 | -------------------------------------------------------------------------------- /golangci.yml: -------------------------------------------------------------------------------- 1 | run: 2 | go: 1.23 3 | concurrency: 4 4 | timeout: 10m 5 | 6 | issues: 7 | exclude-dirs: 8 | - examples 9 | 10 | linters: 11 | enable: 12 | - asciicheck 13 | - exportloopref 14 | - gofmt 15 | - goimports 16 | - gomodguard 17 | - goprintffuncname 18 | - gosimple 19 | - govet 20 | - ineffassign 21 | - misspell 22 | - nakedret 23 | - nolintlint 24 | - prealloc 25 | - staticcheck 26 | - typecheck 27 | - unconvert 28 | - unused 29 | - whitespace 30 | -------------------------------------------------------------------------------- /plugin.go: -------------------------------------------------------------------------------- 1 | package pocketbase_plugin_proxy 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "net/url" 7 | "strings" 8 | 9 | "github.com/fatih/color" 10 | "github.com/labstack/echo/v5" 11 | "github.com/labstack/echo/v5/middleware" 12 | "github.com/pocketbase/pocketbase/core" 13 | ) 14 | 15 | // DefaultSkipper skip proxy middleware for requests, where path starts with /_/ or /api/. 16 | func DefaultSkipper(c echo.Context) bool { 17 | return strings.HasPrefix(c.Request().URL.Path, "/_/") || strings.HasPrefix(c.Request().URL.Path, "/api/") 18 | } 19 | 20 | // Options defines optional struct to customize the default plugin behavior. 21 | type Options struct { 22 | // Enabled defines if proxy should be enabled. 23 | Enabled bool 24 | 25 | //Url to the target. 26 | // 27 | //Only http and https links are supported. 28 | Url string 29 | 30 | // Are proxy logs enabled? 31 | ProxyLogsEnabled bool 32 | } 33 | 34 | type Plugin struct { 35 | // app is a Pocketbase application instance. 36 | app core.App 37 | 38 | // options is a plugin options. 39 | options *Options 40 | 41 | // parsedUrl from options.Url 42 | parsedUrl *url.URL 43 | 44 | // Skipper function for proxy middleware 45 | skipper middleware.Skipper 46 | } 47 | 48 | // Validate plugin options. Return error if some option is invalid. 49 | func (p *Plugin) Validate() error { 50 | if p.options == nil { 51 | return fmt.Errorf("options is required") 52 | } 53 | 54 | if p.app == nil { 55 | return fmt.Errorf("app is required") 56 | } 57 | 58 | if p.options.Enabled { 59 | if p.options.Url == "" { 60 | return fmt.Errorf("url is required when proxy is enabled") 61 | } 62 | 63 | // Check is url valid 64 | if parsedUrl, err := url.Parse(p.options.Url); err != nil { 65 | return fmt.Errorf("url is invalid") 66 | } else { 67 | if parsedUrl.Scheme != "http" && parsedUrl.Scheme != "https" { 68 | return fmt.Errorf("url schema is invalid, only http and https are supported") 69 | } 70 | // Fill plugin parsedUrl 71 | p.parsedUrl = parsedUrl 72 | } 73 | } 74 | 75 | return nil 76 | } 77 | 78 | /* 79 | SetSkipper set skipper function that should return true if that route shouldn't be proxied. 80 | 81 | If not set, the DefaultSkipper is used: 82 | 83 | If set - you should also control the middleware behavior for /_/ and /api/ routes. 84 | 85 | Example: 86 | 87 | plugin := proxyPlugin.MustRegister(app, &proxyPlugin.Options{ 88 | Enabled: true, 89 | Url: "http://localhost:3000", 90 | }) 91 | plugin.SetSkipper(func(c echo.Context) bool { 92 | return c.Request().URL.Path == "/my-super-secret-route" 93 | }) 94 | */ 95 | func (p *Plugin) SetSkipper(skipper middleware.Skipper) { 96 | p.skipper = skipper 97 | } 98 | 99 | func (p *Plugin) enableProxy(e *core.ServeEvent) { 100 | if p.options.Enabled { 101 | if p.options.ProxyLogsEnabled { 102 | e.Router.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{ 103 | Skipper: p.skipper, 104 | })) 105 | } else { 106 | log.Println("Proxy logs are disabled") 107 | } 108 | e.Router.Use(middleware.ProxyWithConfig(middleware.ProxyConfig{ 109 | Skipper: p.skipper, 110 | Balancer: middleware.NewRoundRobinBalancer([]*middleware.ProxyTarget{ 111 | { 112 | URL: p.parsedUrl, 113 | }, 114 | }), 115 | })) 116 | 117 | date := new(strings.Builder) 118 | log.New(date, "", log.LstdFlags).Print() 119 | 120 | bold := color.New(color.Bold).Add(color.FgGreen) 121 | bold.Printf( 122 | "%s Proxy will forward requests to %s\n", 123 | strings.TrimSpace(date.String()), 124 | color.CyanString("%s", p.parsedUrl.String()), 125 | ) 126 | } 127 | } 128 | 129 | // MustRegister is a helper function that registers plugin and panics if error occurred. 130 | func MustRegister(app core.App, options *Options) *Plugin { 131 | if p, err := Register(app, options); err != nil { 132 | panic(err) 133 | } else { 134 | return p 135 | } 136 | } 137 | 138 | // Register registers plugin. 139 | func Register(app core.App, options *Options) (*Plugin, error) { 140 | p := &Plugin{ 141 | app: app, 142 | skipper: DefaultSkipper, 143 | } 144 | 145 | // Set default options 146 | if options != nil { 147 | p.options = options 148 | } else { 149 | p.options = &Options{} 150 | } 151 | 152 | // Validate options 153 | if err := p.Validate(); err != nil { 154 | return p, err 155 | } 156 | 157 | app.OnBeforeServe().Add(func(e *core.ServeEvent) error { 158 | p.enableProxy(e) 159 | return nil 160 | }) 161 | 162 | return p, nil 163 | } 164 | -------------------------------------------------------------------------------- /plugin_test.go: -------------------------------------------------------------------------------- 1 | package pocketbase_plugin_proxy 2 | 3 | import ( 4 | "net/http" 5 | "testing" 6 | 7 | "github.com/labstack/echo/v5" 8 | "github.com/pocketbase/pocketbase" 9 | "github.com/pocketbase/pocketbase/core" 10 | "github.com/pocketbase/pocketbase/tests" 11 | ) 12 | 13 | func TestPlugin_Validate(t *testing.T) { 14 | type fields struct { 15 | app core.App 16 | options *Options 17 | } 18 | tests := []struct { 19 | name string 20 | fields fields 21 | wantErr bool 22 | }{ 23 | { 24 | name: "options is nil", 25 | fields: fields{ 26 | app: pocketbase.New(), 27 | options: nil, 28 | }, 29 | wantErr: true, 30 | }, 31 | { 32 | name: "App is nil", 33 | fields: fields{ 34 | app: nil, 35 | options: &Options{}, 36 | }, 37 | wantErr: true, 38 | }, 39 | { 40 | name: "Empty url, but disabled", 41 | fields: fields{ 42 | app: pocketbase.New(), 43 | options: &Options{ 44 | Enabled: false, 45 | }, 46 | }, 47 | wantErr: false, 48 | }, 49 | { 50 | name: "Enabled, but empty url", 51 | fields: fields{ 52 | app: pocketbase.New(), 53 | options: &Options{ 54 | Enabled: true, 55 | Url: "", 56 | }, 57 | }, 58 | wantErr: true, 59 | }, 60 | { 61 | name: "Enabled, but invalid url", 62 | fields: fields{ 63 | app: pocketbase.New(), 64 | options: &Options{ 65 | Enabled: true, 66 | Url: "!@#$%^&*()_+", 67 | }, 68 | }, 69 | wantErr: true, 70 | }, 71 | { 72 | name: "Enabled, but valid url with wrong scheme", 73 | fields: fields{ 74 | app: pocketbase.New(), 75 | options: &Options{ 76 | Enabled: true, 77 | Url: "redis://localhost:6379", 78 | }, 79 | }, 80 | wantErr: true, 81 | }, 82 | { 83 | name: "Enabled and valid options with http url", 84 | fields: fields{ 85 | app: pocketbase.New(), 86 | options: &Options{ 87 | Enabled: true, 88 | Url: "http://localhost:300", 89 | }, 90 | }, 91 | wantErr: false, 92 | }, 93 | { 94 | name: "Enabled and valid options with https url", 95 | fields: fields{ 96 | app: pocketbase.New(), 97 | options: &Options{ 98 | Enabled: true, 99 | Url: "https://localhost:300", 100 | }, 101 | }, 102 | wantErr: false, 103 | }, 104 | } 105 | for _, tt := range tests { 106 | t.Run(tt.name, func(t *testing.T) { 107 | p := &Plugin{ 108 | app: tt.fields.app, 109 | options: tt.fields.options, 110 | } 111 | if err := p.Validate(); (err != nil) != tt.wantErr { 112 | t.Errorf("Validate() error = %v, wantErr %v", err, tt.wantErr) 113 | } 114 | }) 115 | } 116 | } 117 | 118 | func TestPlugin_Register(t *testing.T) { 119 | _, err := Register(nil, nil) 120 | if err == nil { 121 | t.Errorf("Register() should fail when app is nil") 122 | } 123 | } 124 | 125 | func TestPlugin_MustRegister(t *testing.T) { 126 | // setup the test ApiScenario app instance 127 | setupTestApp := func(options *Options) func(t *testing.T) *tests.TestApp { 128 | return func(t *testing.T) *tests.TestApp { 129 | testApp, err := tests.NewTestApp() 130 | if err != nil { 131 | t.Fatal("Cannot initialize test app", err) 132 | } 133 | 134 | MustRegister(testApp, options) 135 | 136 | return testApp 137 | } 138 | } 139 | 140 | proxyDestinationServer := &http.Server{ 141 | Addr: "localhost:1234", 142 | Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 143 | w.WriteHeader(http.StatusOK) 144 | w.Write([]byte("OK from " + r.URL.Path)) 145 | }), 146 | } 147 | defer proxyDestinationServer.Close() 148 | go proxyDestinationServer.ListenAndServe() 149 | 150 | scenarios := []tests.ApiScenario{ 151 | { 152 | Name: "/ request should be proxied when enabled", 153 | Method: http.MethodPost, 154 | Url: "/", 155 | ExpectedStatus: 200, 156 | ExpectedContent: []string{`OK from /`}, 157 | TestAppFactory: setupTestApp(&Options{ 158 | Enabled: true, 159 | Url: "http://localhost:1234", 160 | }), 161 | }, 162 | { 163 | Name: "/ request should be proxied when enabled and ProxyLogsEnabled", 164 | Method: http.MethodPost, 165 | Url: "/", 166 | ExpectedStatus: 200, 167 | ExpectedContent: []string{`OK from /`}, 168 | TestAppFactory: setupTestApp(&Options{ 169 | Enabled: true, 170 | Url: "http://localhost:1234", 171 | ProxyLogsEnabled: true, 172 | }), 173 | }, 174 | { 175 | Name: "/ shouldn be proxied when options nil", 176 | Method: http.MethodPost, 177 | Url: "/", 178 | ExpectedStatus: 404, 179 | ExpectedContent: []string{`"data":{}`}, 180 | TestAppFactory: setupTestApp(nil), 181 | }, 182 | { 183 | Name: "/ shouldn be proxied when disabled", 184 | Method: http.MethodPost, 185 | Url: "/", 186 | ExpectedStatus: 404, 187 | ExpectedContent: []string{`"data":{}`}, 188 | TestAppFactory: setupTestApp(&Options{ 189 | Enabled: false, 190 | Url: "http://localhost:1234", 191 | }), 192 | }, 193 | { 194 | Name: "/api/test request should not be proxied when enabled", 195 | Method: http.MethodPost, 196 | Url: "/api/test", 197 | ExpectedStatus: 404, 198 | ExpectedContent: []string{`"data":{}`}, 199 | TestAppFactory: setupTestApp(&Options{ 200 | Enabled: true, 201 | Url: "http://localhost:1234", 202 | }), 203 | }, 204 | { 205 | Name: "/_/test request should not be proxied when enabled", 206 | Method: http.MethodPost, 207 | Url: "/_/test", 208 | ExpectedStatus: 405, 209 | ExpectedContent: []string{`"data":{}`}, 210 | TestAppFactory: setupTestApp(&Options{ 211 | Enabled: true, 212 | Url: "http://localhost:1234", 213 | }), 214 | }, 215 | { 216 | Name: "/my-super-api-path request should not be proxied when enabled with custom skipper", 217 | Method: http.MethodPost, 218 | Url: "/my-super-api-path", 219 | ExpectedStatus: 404, 220 | ExpectedContent: []string{`"data":{}`}, 221 | TestAppFactory: func(t *testing.T) *tests.TestApp { 222 | testApp, err := tests.NewTestApp() 223 | if err != nil { 224 | t.Fatal("Cannot initialize test app", err) 225 | } 226 | 227 | p := MustRegister(testApp, &Options{ 228 | Enabled: true, 229 | Url: "http://localhost:1234", 230 | }) 231 | 232 | p.SetSkipper(func(c echo.Context) bool { 233 | return c.Request().URL.Path == "/my-super-api-path" 234 | }) 235 | 236 | return testApp 237 | }, 238 | }, 239 | } 240 | 241 | for _, scenario := range scenarios { 242 | scenario.Test(t) 243 | } 244 | } 245 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:base" 5 | ] 6 | } 7 | --------------------------------------------------------------------------------