├── .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 | [](https://github.com/iamelevich/pocketbase-plugin-proxy/actions/workflows/test.yml)
2 | [](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 |
--------------------------------------------------------------------------------