Compare commits

...

73 Commits

Author SHA1 Message Date
argoyle 38b4ab8ee2 Merge pull request 'chore(release): prepare for v0.9.5' (#740) from next-release into main
Release / release (push) Successful in 1m0s
schemas / vulnerabilities (push) Successful in 4m2s
Goreleaser / release (push) Successful in 5m8s
schemas / check-release (push) Successful in 6m38s
schemas / check (push) Successful in 8m59s
schemas / build (push) Successful in 6m0s
schemas / deploy-prod (push) Has been skipped
pre-commit / pre-commit (push) Successful in 8m14s
Reviewed-on: #740
2026-02-25 11:32:35 +00:00
releaser 1fa91ad573 chore(release): prepare for v0.9.5
schemas / vulnerabilities (pull_request) Successful in 2m48s
schemas / check-release (pull_request) Successful in 5m48s
schemas / check (pull_request) Successful in 5m48s
schemas / build (pull_request) Successful in 12m9s
schemas / deploy-prod (pull_request) Has been skipped
pre-commit / pre-commit (pull_request) Successful in 12m36s
2026-02-25 06:27:43 +00:00
releaser 7182ae2a11 chore(release): prepare for v0.9.5 2026-02-25 06:27:39 +00:00
renovate 19b7f0edb6 chore(deps): update node.js to 7fddd9d (#739)
Release / release (push) Successful in 1m36s
schemas / vulnerabilities (push) Successful in 3m25s
schemas / check-release (push) Successful in 5m10s
schemas / check (push) Successful in 6m21s
pre-commit / pre-commit (push) Successful in 11m40s
schemas / build (push) Successful in 6m36s
schemas / deploy-prod (push) Successful in 1m13s
2026-02-25 06:26:07 +00:00
renovate 0b68cadd24 chore(deps): update node.js to v24.14.0 (#735)
Release / release (push) Successful in 1m5s
schemas / vulnerabilities (push) Successful in 2m51s
schemas / check-release (push) Successful in 3m42s
schemas / check (push) Successful in 6m23s
pre-commit / pre-commit (push) Successful in 10m4s
schemas / build (push) Successful in 7m19s
schemas / deploy-prod (push) Successful in 1m11s
2026-02-25 00:28:09 +00:00
renovate 50087adeac chore(deps): update golang:1.26.0 docker digest to 9835fb4 (#736)
schemas / vulnerabilities (push) Successful in 2m38s
schemas / check (push) Successful in 4m25s
schemas / check-release (push) Successful in 4m34s
Release / release (push) Successful in 1m23s
pre-commit / pre-commit (push) Successful in 17m31s
schemas / build (push) Successful in 26m14s
schemas / deploy-prod (push) Successful in 1m16s
2026-02-24 22:44:21 +00:00
argoyle 03c903cf0e Merge pull request 'fix(deps): update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.256' (#733) from renovate/github.com-wundergraph-graphql-go-tools-v2-2.x into main
Release / release (push) Successful in 2m0s
schemas / vulnerabilities (push) Successful in 4m40s
schemas / check-release (push) Successful in 10m7s
schemas / check (push) Successful in 11m58s
schemas / build (push) Successful in 9m21s
schemas / deploy-prod (push) Successful in 2m12s
pre-commit / pre-commit (push) Successful in 24m26s
Reviewed-on: #733
2026-02-23 16:32:56 +00:00
renovate 59d0d40d4d fix(deps): update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.256
schemas / vulnerabilities (pull_request) Successful in 4m44s
schemas / check-release (pull_request) Successful in 10m55s
schemas / check (pull_request) Successful in 12m29s
pre-commit / pre-commit (pull_request) Successful in 20m0s
schemas / build (pull_request) Successful in 10m4s
schemas / deploy-prod (pull_request) Has been skipped
2026-02-23 16:07:55 +00:00
argoyle 3bb0511277 Merge pull request 'chore(release): prepare for v0.9.4' (#732) from next-release into main
Release / release (push) Successful in 1m36s
schemas / vulnerabilities (push) Successful in 2m31s
schemas / check-release (push) Successful in 5m33s
schemas / check (push) Successful in 6m17s
pre-commit / pre-commit (push) Successful in 10m5s
Goreleaser / release (push) Successful in 3m39s
schemas / build (push) Failing after 1m1s
schemas / deploy-prod (push) Has been skipped
Reviewed-on: #732
2026-02-23 13:30:22 +00:00
releaser f0fadb4ab7 chore(release): prepare for v0.9.4
schemas / vulnerabilities (pull_request) Successful in 11m30s
schemas / check (pull_request) Successful in 17m40s
pre-commit / pre-commit (pull_request) Successful in 22m31s
schemas / check-release (pull_request) Successful in 25m51s
schemas / build (pull_request) Successful in 23m52s
schemas / deploy-prod (pull_request) Has been skipped
2026-02-23 12:39:51 +00:00
releaser 59c128fe0c chore(release): prepare for v0.9.4 2026-02-23 12:39:47 +00:00
argoyle 9518403394 Merge pull request 'fix(ci): pin goreleaser to v2.13.3 for Gitea SDK compatibility' (#731) from fix-goreleaser-gitea-sdk-compat into main
schemas / vulnerabilities (push) Successful in 3m20s
schemas / check-release (push) Successful in 4m57s
Release / release (push) Successful in 2m12s
schemas / check (push) Successful in 18m55s
pre-commit / pre-commit (push) Successful in 16m38s
schemas / build (push) Failing after 27m35s
schemas / deploy-prod (push) Has been skipped
Reviewed-on: #731
2026-02-23 12:28:21 +00:00
argoyle 3b4e513653 fix(ci): pin goreleaser to v2.13.3 for Gitea SDK compatibility
schemas / vulnerabilities (pull_request) Successful in 2m19s
schemas / check-release (pull_request) Successful in 6m5s
schemas / check (pull_request) Successful in 6m24s
pre-commit / pre-commit (pull_request) Successful in 12m13s
schemas / build (pull_request) Successful in 7m21s
schemas / deploy-prod (pull_request) Has been skipped
GoReleaser v2.14.0 upgraded the Gitea SDK from v0.22.1 to v0.23.2,
which fails to parse the Gitea server version during homebrew cask
publishing (error: unknown version: daf0483). Pin to v2.13.3 until
the Gitea server is updated to a compatible version.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 13:08:38 +01:00
argoyle fe1de50ded Merge pull request 'chore(release): prepare for v0.9.3' (#730) from next-release into main
Release / release (push) Successful in 56s
schemas / vulnerabilities (push) Successful in 8m44s
schemas / check-release (push) Successful in 16m53s
schemas / check (push) Successful in 21m15s
pre-commit / pre-commit (push) Successful in 29m33s
schemas / build (push) Successful in 11m14s
schemas / deploy-prod (push) Successful in 1m34s
Goreleaser / release (push) Failing after 5m37s
Reviewed-on: #730
2026-02-23 08:14:51 +00:00
releaser 2d243469ed chore(release): prepare for v0.9.3
schemas / vulnerabilities (pull_request) Successful in 9m25s
schemas / check-release (pull_request) Successful in 16m59s
schemas / check (pull_request) Successful in 27m0s
pre-commit / pre-commit (pull_request) Successful in 32m15s
schemas / build (pull_request) Successful in 7m55s
schemas / deploy-prod (pull_request) Has been skipped
2026-02-23 07:39:42 +00:00
releaser a23aa5e5e9 chore(release): prepare for v0.9.3 2026-02-23 07:39:39 +00:00
argoyle 2286e092d9 Merge pull request 'fix: prevent OOM on rapid schema publishing' (#729) from fix-oom-rapid-schema-publishing into main
schemas / vulnerabilities (push) Successful in 5m37s
Release / release (push) Successful in 1m42s
schemas / check-release (push) Successful in 14m32s
schemas / check (push) Successful in 22m34s
schemas / build (push) Successful in 11m37s
schemas / deploy-prod (push) Successful in 2m35s
pre-commit / pre-commit (push) Successful in 37m18s
Reviewed-on: #729
2026-02-23 07:31:08 +00:00
argoyle 28aa32ad8c fix: prevent OOM on rapid schema publishing
schemas / vulnerabilities (pull_request) Successful in 6m43s
schemas / check-release (pull_request) Successful in 11m27s
schemas / check (pull_request) Successful in 14m51s
pre-commit / pre-commit (pull_request) Successful in 19m39s
schemas / build (pull_request) Successful in 8m26s
schemas / deploy-prod (pull_request) Has been skipped
Add concurrency-limited CosmoGenerator (semaphore limit=1, 60s timeout)
to prevent unbounded concurrent wgc process spawning. Add debouncer
(500ms) to coalesce rapid schema updates per org+ref. Fix double
subgraph fetch in Supergraph resolver and goroutine leak in
SchemaUpdates subscription.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 08:05:47 +01:00
renovate a9885f8b65 fix(deps): update module gitlab.com/unboundsoftware/eventsourced/pg to v1.18.4 (#727)
Release / release (push) Successful in 1m48s
schemas / vulnerabilities (push) Successful in 3m31s
schemas / check-release (push) Successful in 19m53s
schemas / check (push) Successful in 28m16s
pre-commit / pre-commit (push) Successful in 41m21s
schemas / build (push) Successful in 15m44s
schemas / deploy-prod (push) Successful in 1m33s
2026-02-22 23:07:02 +00:00
argoyle 2fbe44fea1 Merge pull request 'fix(deps): update module github.com/pressly/goose/v3 to v3.27.0' (#725) from renovate/github.com-pressly-goose-v3-3.x into main
Release / release (push) Successful in 1m41s
schemas / vulnerabilities (push) Successful in 7m40s
schemas / check-release (push) Successful in 12m45s
schemas / check (push) Successful in 25m22s
pre-commit / pre-commit (push) Successful in 43m42s
schemas / build (push) Successful in 21m37s
schemas / deploy-prod (push) Successful in 1m47s
Reviewed-on: #725
2026-02-22 18:55:45 +00:00
renovate 80d08c1ba7 fix(deps): update module github.com/pressly/goose/v3 to v3.27.0
schemas / vulnerabilities (pull_request) Successful in 13m33s
schemas / check-release (pull_request) Successful in 31m22s
schemas / check (pull_request) Successful in 38m33s
pre-commit / pre-commit (pull_request) Successful in 57m7s
schemas / build (pull_request) Successful in 28m17s
schemas / deploy-prod (pull_request) Has been skipped
2026-02-22 17:09:40 +00:00
argoyle d6866b9f72 Merge pull request 'chore(deps): update actions/setup-node action to v6' (#724) from renovate/actions-setup-node-6.x into main
Release / release (push) Failing after 1m50s
schemas / vulnerabilities (push) Successful in 4m33s
schemas / check-release (push) Successful in 7m19s
schemas / check (push) Successful in 8m18s
pre-commit / pre-commit (push) Successful in 16m9s
schemas / build (push) Successful in 10m21s
schemas / deploy-prod (push) Successful in 1m1s
Reviewed-on: #724
2026-02-22 13:22:13 +00:00
renovate 3c1fc68016 chore(deps): update actions/setup-node action to v6
schemas / vulnerabilities (pull_request) Successful in 1m46s
schemas / check-release (pull_request) Successful in 4m33s
schemas / check (pull_request) Successful in 11m3s
pre-commit / pre-commit (pull_request) Successful in 14m11s
schemas / build (pull_request) Successful in 4m31s
schemas / deploy-prod (pull_request) Has been skipped
2026-02-22 11:35:29 +00:00
argoyle 817449afbc Merge pull request 'fix(deps): update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.255' (#721) from renovate/github.com-wundergraph-graphql-go-tools-v2-2.x into main
Release / release (push) Successful in 1m18s
schemas / vulnerabilities (push) Successful in 6m17s
schemas / check-release (push) Successful in 7m2s
schemas / check (push) Successful in 8m8s
schemas / build (push) Successful in 15m11s
schemas / deploy-prod (push) Successful in 1m57s
pre-commit / pre-commit (push) Successful in 25m52s
Reviewed-on: #721
2026-02-22 11:14:35 +00:00
argoyle 856423a221 Merge pull request 'chore(deps): update goreleaser/goreleaser-action action to v7' (#720) from renovate/goreleaser-goreleaser-action-7.x into main
Release / release (push) Successful in 2m17s
schemas / vulnerabilities (push) Successful in 4m32s
schemas / check (push) Successful in 7m22s
schemas / check-release (push) Successful in 8m32s
schemas / build (push) Successful in 7m4s
schemas / deploy-prod (push) Successful in 1m11s
pre-commit / pre-commit (push) Successful in 18m44s
Reviewed-on: #720
2026-02-22 10:48:57 +00:00
renovate 3c43f1bd80 chore(deps): update goreleaser/goreleaser-action action to v7
schemas / vulnerabilities (pull_request) Successful in 2m19s
pre-commit / pre-commit (pull_request) Successful in 11m12s
schemas / check-release (pull_request) Successful in 14m14s
schemas / check (pull_request) Successful in 19m52s
schemas / build (pull_request) Successful in 7m24s
schemas / deploy-prod (pull_request) Has been skipped
2026-02-22 10:03:48 +01:00
renovate 4fd36c1330 fix(deps): update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.255
schemas / vulnerabilities (pull_request) Successful in 4m39s
schemas / check-release (pull_request) Successful in 6m29s
schemas / check (pull_request) Successful in 9m54s
pre-commit / pre-commit (pull_request) Successful in 12m35s
schemas / build (pull_request) Successful in 7m25s
schemas / deploy-prod (pull_request) Has been skipped
2026-02-21 22:06:11 +00:00
renovate 9411a2dd7d fix(deps): update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.254 (#718)
schemas / vulnerabilities (push) Successful in 3m34s
Release / release (push) Successful in 5m28s
schemas / check-release (push) Successful in 5m53s
schemas / check (push) Successful in 10m11s
pre-commit / pre-commit (push) Successful in 19m21s
schemas / build (push) Successful in 9m58s
schemas / deploy-prod (push) Successful in 2m14s
2026-02-20 20:07:54 +00:00
argoyle f1dc71163b Merge pull request 'fix(deps): update module github.com/99designs/gqlgen to v0.17.87' (#713) from renovate/github.com-99designs-gqlgen-0.x into main
schemas / vulnerabilities (push) Successful in 4m50s
Release / release (push) Successful in 5m18s
schemas / check-release (push) Successful in 6m1s
schemas / check (push) Successful in 10m14s
pre-commit / pre-commit (push) Successful in 12m39s
schemas / build (push) Successful in 6m49s
schemas / deploy-prod (push) Successful in 1m44s
Reviewed-on: #713
2026-02-20 14:04:17 +00:00
renovate 08e84ac1dc fix(deps): update module github.com/99designs/gqlgen to v0.17.87
schemas / check-release (pull_request) Successful in 7m11s
schemas / check (pull_request) Successful in 10m16s
pre-commit / pre-commit (pull_request) Successful in 13m23s
schemas / vulnerabilities (pull_request) Successful in 21m6s
schemas / build (pull_request) Successful in 8m44s
schemas / deploy-prod (pull_request) Has been skipped
2026-02-20 14:26:46 +01:00
renovate 3ea1ef520c fix(deps): update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.253 (#716)
Release / release (push) Failing after 1m32s
schemas / vulnerabilities (push) Successful in 2m38s
schemas / check-release (push) Successful in 3m21s
schemas / check (push) Successful in 6m6s
pre-commit / pre-commit (push) Successful in 9m19s
schemas / build (push) Successful in 6m3s
schemas / deploy-prod (push) Failing after 2m59s
2026-02-20 12:24:11 +00:00
renovate e30ab93a47 fix(deps): update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.252 (#714)
schemas / vulnerabilities (push) Successful in 2m4s
Release / release (push) Successful in 2m23s
schemas / check-release (push) Successful in 3m36s
schemas / check (push) Successful in 5m25s
pre-commit / pre-commit (push) Successful in 9m0s
schemas / build (push) Successful in 11m55s
schemas / deploy-prod (push) Successful in 2m19s
2026-02-19 16:30:35 +00:00
argoyle 0eb59235c1 Merge pull request 'fix(deps): update module github.com/vektah/gqlparser/v2 to v2.5.32' (#711) from renovate/github.com-vektah-gqlparser-v2-2.x into main
schemas / vulnerabilities (push) Successful in 4m16s
schemas / check-release (push) Successful in 5m2s
Release / release (push) Successful in 3m50s
schemas / check (push) Successful in 9m44s
pre-commit / pre-commit (push) Successful in 16m21s
schemas / build (push) Successful in 12m51s
schemas / deploy-prod (push) Failing after 4m59s
Reviewed-on: #711
2026-02-19 15:27:00 +00:00
renovate 31022037ff fix(deps): update module github.com/vektah/gqlparser/v2 to v2.5.32
schemas / vulnerabilities (pull_request) Successful in 4m17s
schemas / check-release (pull_request) Successful in 6m2s
schemas / check (pull_request) Successful in 9m14s
pre-commit / pre-commit (pull_request) Successful in 12m3s
schemas / build (pull_request) Successful in 9m27s
schemas / deploy-prod (pull_request) Has been skipped
2026-02-19 13:44:52 +00:00
argoyle 085bf35d92 Merge pull request 'fix(deps): update module gitlab.com/unboundsoftware/eventsourced/pg to v1.18.3' (#708) from renovate/eventsourced into main
Release / release (push) Successful in 1m53s
schemas / vulnerabilities (push) Successful in 4m17s
schemas / check-release (push) Successful in 8m14s
schemas / check (push) Successful in 12m36s
pre-commit / pre-commit (push) Successful in 17m14s
schemas / build (push) Successful in 11m43s
schemas / deploy-prod (push) Successful in 1m32s
Reviewed-on: #708
2026-02-18 12:47:52 +00:00
argoyle 9d655e1a23 Merge pull request 'fix(deps): update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.251' (#707) from renovate/github.com-wundergraph-graphql-go-tools-v2-2.x into main
Release / release (push) Successful in 1m11s
schemas / vulnerabilities (push) Successful in 3m35s
schemas / check-release (push) Successful in 5m23s
schemas / check (push) Successful in 10m11s
schemas / build (push) Successful in 7m50s
schemas / deploy-prod (push) Successful in 2m15s
pre-commit / pre-commit (push) Successful in 20m42s
Reviewed-on: #707
2026-02-18 12:46:17 +00:00
renovate eee1d45d8c fix(deps): update module gitlab.com/unboundsoftware/eventsourced/pg to v1.18.3
schemas / vulnerabilities (pull_request) Successful in 10m29s
schemas / check-release (pull_request) Successful in 25m55s
schemas / check (pull_request) Successful in 43m26s
pre-commit / pre-commit (pull_request) Successful in 55m0s
schemas / build (pull_request) Successful in 29m31s
schemas / deploy-prod (pull_request) Has been skipped
2026-02-18 11:08:55 +00:00
renovate 782185981f fix(deps): update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.251
schemas / vulnerabilities (pull_request) Successful in 10m52s
schemas / check-release (pull_request) Successful in 12m47s
schemas / check (pull_request) Successful in 30m49s
pre-commit / pre-commit (pull_request) Successful in 57m57s
schemas / build (pull_request) Successful in 22m15s
schemas / deploy-prod (pull_request) Has been skipped
2026-02-18 11:08:42 +00:00
renovate e3f156fe9e chore(deps): update pre-commit hook golangci/golangci-lint to v2.10.1 (#706)
Release / release (push) Failing after 1m29s
schemas / check (push) Successful in 3m12s
schemas / vulnerabilities (push) Successful in 5m8s
schemas / check-release (push) Successful in 6m8s
pre-commit / pre-commit (push) Successful in 14m2s
schemas / build (push) Successful in 9m32s
schemas / deploy-prod (push) Successful in 2m4s
2026-02-17 17:55:12 +00:00
renovate 230876b523 fix(deps): update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.250 (#704)
Release / release (push) Failing after 2m21s
schemas / vulnerabilities (push) Successful in 4m47s
schemas / check-release (push) Successful in 10m4s
schemas / check (push) Successful in 12m57s
pre-commit / pre-commit (push) Successful in 15m14s
schemas / build (push) Successful in 9m15s
schemas / deploy-prod (push) Successful in 51s
2026-02-16 17:05:42 +00:00
renovate e64adc96ae fix(deps): update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.249 (#702)
Release / release (push) Successful in 2m53s
schemas / vulnerabilities (push) Successful in 4m10s
schemas / check (push) Successful in 11m2s
schemas / check-release (push) Successful in 11m33s
pre-commit / pre-commit (push) Successful in 16m21s
schemas / build (push) Successful in 6m34s
schemas / deploy-prod (push) Successful in 57s
2026-02-13 21:35:11 +00:00
argoyle f534752e2c Merge pull request 'chore(release): prepare for v0.9.2' (#701) from next-release into main
Release / release (push) Successful in 1m20s
schemas / vulnerabilities (push) Successful in 5m8s
schemas / check (push) Successful in 8m3s
schemas / check-release (push) Successful in 7m12s
Goreleaser / release (push) Successful in 7m12s
pre-commit / pre-commit (push) Successful in 12m36s
schemas / build (push) Successful in 5m40s
schemas / deploy-prod (push) Successful in 54s
Reviewed-on: #701
2026-02-13 09:28:17 +00:00
releaser 42f4c8014d chore(release): prepare for v0.9.2
schemas / vulnerabilities (pull_request) Successful in 3m25s
schemas / check-release (pull_request) Successful in 4m6s
schemas / check (pull_request) Successful in 7m0s
schemas / build (pull_request) Successful in 4m17s
schemas / deploy-prod (pull_request) Has been skipped
pre-commit / pre-commit (pull_request) Successful in 10m25s
2026-02-13 09:14:54 +00:00
releaser e098562e0c chore(release): prepare for v0.9.2 2026-02-13 09:14:50 +00:00
renovate 948ab167c1 chore(deps): update node.js to v24.13.1 (#699)
schemas / vulnerabilities (push) Successful in 3m20s
schemas / check (push) Successful in 4m36s
schemas / check-release (push) Successful in 5m3s
schemas / build (push) Successful in 5m40s
pre-commit / pre-commit (push) Successful in 11m19s
schemas / deploy-prod (push) Successful in 1m19s
Release / release (push) Successful in 1m3s
2026-02-12 18:19:39 +00:00
renovate 404c4106bc fix(deps): update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.248 (#698)
schemas / vulnerabilities (push) Successful in 5m13s
schemas / check-release (push) Successful in 5m36s
Release / release (push) Successful in 4m12s
schemas / check (push) Successful in 12m42s
pre-commit / pre-commit (push) Successful in 16m33s
schemas / build (push) Successful in 15m24s
schemas / deploy-prod (push) Failing after 2m47s
2026-02-11 20:17:37 +00:00
renovate 593874ba52 chore(deps): update golang docker tag to v1.26.0 (#696)
Release / release (push) Successful in 4m12s
schemas / vulnerabilities (push) Successful in 6m10s
schemas / check (push) Successful in 6m44s
pre-commit / pre-commit (push) Successful in 9m35s
schemas / check-release (push) Successful in 16m33s
schemas / build (push) Successful in 1h10m47s
schemas / deploy-prod (push) Successful in 2m41s
2026-02-11 15:30:17 +00:00
renovate bcbdc4458e chore(deps): update pre-commit hook golangci/golangci-lint to v2.9.0 (#697)
Release / release (push) Successful in 1m37s
schemas / vulnerabilities (push) Successful in 3m42s
schemas / check-release (push) Successful in 6m28s
schemas / check (push) Successful in 14m42s
pre-commit / pre-commit (push) Successful in 22m33s
schemas / build (push) Successful in 25m34s
schemas / deploy-prod (push) Successful in 1m9s
2026-02-11 13:51:39 +00:00
renovate 4b6637b027 chore(deps): update golang:1.25.7 docker digest to d2819ff (#695)
schemas / check (push) Failing after 2s
schemas / check-release (push) Failing after 2s
pre-commit / pre-commit (push) Failing after 2s
schemas / vulnerabilities (push) Failing after 3s
schemas / build (push) Has been skipped
Release / release (push) Failing after 2s
schemas / deploy-prod (push) Has been skipped
2026-02-11 00:22:36 +00:00
renovate bc7729b702 fix(deps): update module golang.org/x/crypto to v0.48.0 (#694)
Release / release (push) Failing after 2m0s
schemas / vulnerabilities (push) Successful in 5m6s
schemas / check-release (push) Successful in 6m0s
schemas / check (push) Successful in 13m25s
schemas / build (push) Successful in 4m41s
pre-commit / pre-commit (push) Successful in 17m25s
schemas / deploy-prod (push) Successful in 1m21s
2026-02-09 17:30:20 +00:00
renovate 942508e467 fix(deps): update eventsourced (#693)
Release / release (push) Successful in 1m8s
schemas / vulnerabilities (push) Successful in 1m50s
schemas / check-release (push) Successful in 6m4s
schemas / check (push) Successful in 6m7s
pre-commit / pre-commit (push) Successful in 15m11s
schemas / build (push) Successful in 11m52s
schemas / deploy-prod (push) Successful in 1m28s
2026-02-07 20:32:28 +00:00
renovate 59e8a3c43d fix(deps): update module github.com/alecthomas/kong to v1.14.0 (#692)
schemas / vulnerabilities (push) Successful in 2m1s
Release / release (push) Successful in 2m5s
schemas / check-release (push) Successful in 5m56s
pre-commit / pre-commit (push) Successful in 8m13s
schemas / check (push) Successful in 8m45s
schemas / build (push) Successful in 8m24s
schemas / deploy-prod (push) Successful in 55s
2026-02-07 00:41:14 +00:00
renovate d7358d8053 fix(deps): update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.247 (#691)
Release / release (push) Failing after 1m33s
schemas / vulnerabilities (push) Successful in 3m28s
schemas / check-release (push) Successful in 3m31s
schemas / check (push) Successful in 8m56s
pre-commit / pre-commit (push) Successful in 12m25s
schemas / build (push) Successful in 6m11s
schemas / deploy-prod (push) Successful in 1m1s
2026-02-06 13:17:32 +00:00
argoyle 2350099e7f Merge pull request 'chore(deps): update golang docker tag to v1.25.7' (#690) from renovate/golang-1.x into main
Release / release (push) Successful in 1m16s
schemas / vulnerabilities (push) Successful in 3m35s
schemas / check-release (push) Successful in 4m11s
pre-commit / pre-commit (push) Successful in 8m11s
schemas / check (push) Successful in 9m18s
schemas / build (push) Successful in 5m0s
schemas / deploy-prod (push) Successful in 1m24s
Reviewed-on: #690
2026-02-05 12:00:52 +00:00
renovate ab5a8a9f6a chore(deps): update golang docker tag to v1.25.7
schemas / vulnerabilities (pull_request) Successful in 2m14s
schemas / check (pull_request) Successful in 4m45s
schemas / check-release (pull_request) Successful in 10m57s
schemas / build (pull_request) Successful in 4m32s
schemas / deploy-prod (pull_request) Has been skipped
2026-02-04 18:15:45 +00:00
renovate 369a0b050a chore(deps): update golang:1.25.6 docker digest to ceda080 (#689)
schemas / check (push) Successful in 3m22s
pre-commit / pre-commit (push) Successful in 7m59s
schemas / check-release (push) Failing after 12m25s
schemas / vulnerabilities (push) Failing after 12m25s
schemas / build (push) Has been skipped
Release / release (push) Failing after 22m10s
schemas / deploy-prod (push) Has been skipped
2026-02-03 09:01:58 +00:00
renovate 3bf43210a1 fix(deps): update module go.opentelemetry.io/contrib/bridges/otelslog to v0.15.0 (#688)
Release / release (push) Successful in 55s
schemas / vulnerabilities (push) Successful in 1m31s
schemas / check-release (push) Successful in 4m58s
schemas / check (push) Successful in 5m51s
pre-commit / pre-commit (push) Successful in 7m51s
schemas / build (push) Successful in 8m38s
schemas / deploy-prod (push) Successful in 55s
2026-02-02 20:48:58 +00:00
renovate 148f8befe7 fix(deps): update opentelemetry-go monorepo (#687)
Release / release (push) Failing after 47s
schemas / vulnerabilities (push) Successful in 2m21s
schemas / check (push) Successful in 3m27s
schemas / check-release (push) Successful in 4m42s
schemas / build (push) Successful in 5m9s
schemas / deploy-prod (push) Successful in 1m25s
pre-commit / pre-commit (push) Successful in 15m42s
2026-02-02 19:34:16 +00:00
renovate 90b9e91d20 fix(deps): update module gitlab.com/unboundsoftware/eventsourced/pg to v1.18.1 (#686)
schemas / vulnerabilities (push) Successful in 1m41s
Release / release (push) Successful in 1m24s
schemas / check-release (push) Successful in 3m33s
schemas / check (push) Successful in 7m19s
pre-commit / pre-commit (push) Successful in 13m29s
schemas / build (push) Successful in 9m25s
schemas / deploy-prod (push) Successful in 57s
2026-01-30 07:24:43 +00:00
renovate 985bca2f58 fix(deps): update module gitlab.com/unboundsoftware/eventsourced/pg to v1.18.0 (#685)
schemas / vulnerabilities (push) Successful in 1m31s
Release / release (push) Successful in 1m23s
schemas / check-release (push) Successful in 6m10s
schemas / check (push) Successful in 12m6s
schemas / build (push) Successful in 3m24s
pre-commit / pre-commit (push) Successful in 16m9s
schemas / deploy-prod (push) Successful in 53s
2026-01-29 10:42:16 +00:00
renovate 3fce241596 chore(deps): update node.js to cd6fb7e (#684)
Release / release (push) Successful in 1m49s
schemas / check-release (push) Successful in 4m33s
schemas / vulnerabilities (push) Successful in 4m34s
schemas / check (push) Successful in 5m5s
schemas / build (push) Successful in 5m1s
schemas / deploy-prod (push) Successful in 1m30s
pre-commit / pre-commit (push) Successful in 13m38s
2026-01-28 08:30:07 +00:00
renovate a0baa44320 fix(deps): update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.246 (#683)
Release / release (push) Successful in 1m12s
schemas / vulnerabilities (push) Successful in 3m44s
schemas / check-release (push) Successful in 5m47s
schemas / check (push) Successful in 8m53s
pre-commit / pre-commit (push) Successful in 9m12s
schemas / build (push) Successful in 6m25s
schemas / deploy-prod (push) Successful in 58s
2026-01-27 14:40:50 +00:00
renovate 60939c3159 fix(deps): update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.245 (#682)
Release / release (push) Successful in 2m50s
schemas / vulnerabilities (push) Successful in 4m56s
schemas / check-release (push) Successful in 7m4s
schemas / check (push) Successful in 15m32s
schemas / build (push) Successful in 5m3s
pre-commit / pre-commit (push) Successful in 20m34s
schemas / deploy-prod (push) Successful in 1m47s
2026-01-26 14:25:49 +00:00
renovate 6530408f15 fix(deps): update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.244 (#681)
Release / release (push) Failing after 3m11s
schemas / vulnerabilities (push) Successful in 4m53s
schemas / check-release (push) Successful in 5m38s
schemas / check (push) Successful in 14m0s
pre-commit / pre-commit (push) Successful in 16m56s
schemas / build (push) Successful in 7m22s
schemas / deploy-prod (push) Successful in 1m4s
2026-01-26 10:08:30 +00:00
renovate fd6694614e fix(deps): update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.243 (#680)
Release / release (push) Successful in 2m44s
schemas / vulnerabilities (push) Successful in 5m49s
schemas / check-release (push) Successful in 12m43s
schemas / check (push) Successful in 14m54s
schemas / build (push) Successful in 15m55s
schemas / deploy-prod (push) Failing after 4m4s
pre-commit / pre-commit (push) Successful in 57m25s
2026-01-20 15:13:13 +00:00
argoyle 6143a96c75 Merge pull request 'fix(deps): update module github.com/auth0/go-jwt-middleware/v2 to v3' (#678) from renovate/github.com-auth0-go-jwt-middleware-v2-3.x into main
Release / release (push) Successful in 1m39s
schemas / vulnerabilities (push) Successful in 2m53s
schemas / check (push) Successful in 3m11s
schemas / check-release (push) Successful in 3m51s
pre-commit / pre-commit (push) Successful in 8m5s
schemas / build (push) Successful in 5m33s
schemas / deploy-prod (push) Successful in 1m0s
Reviewed-on: #678
2026-01-19 20:07:08 +00:00
argoyle 817927cb7d fix: migrate to go-jwt-middleware v3 API
schemas / check-release (pull_request) Successful in 1m57s
schemas / vulnerabilities (pull_request) Successful in 2m48s
schemas / check (pull_request) Successful in 8m17s
pre-commit / pre-commit (pull_request) Successful in 11m38s
schemas / build (pull_request) Successful in 5m31s
schemas / deploy-prod (pull_request) Has been skipped
- Use validator and jwks packages for JWT validation
- Replace manual JWKS caching with jwks.NewCachingProvider
- Add CustomClaims struct for https://unbound.se/roles claim
- Rename TokenFromContext to ClaimsFromContext
- Update middleware/auth.go to use new claims structure
- Update tests to use core.SetClaims and validator.ValidatedClaims

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-19 20:31:45 +01:00
renovate e2c1803683 fix(deps): update module github.com/auth0/go-jwt-middleware/v2 to v3 2026-01-19 20:19:58 +01:00
argoyle d79a10e910 Merge pull request 'chore(release): prepare for v0.9.1' (#677) from next-release into main
schemas / vulnerabilities (push) Successful in 1m58s
schemas / check-release (push) Successful in 2m40s
pre-commit / pre-commit (push) Successful in 7m12s
Goreleaser / release (push) Successful in 2m30s
schemas / check (push) Successful in 5m21s
schemas / build (push) Successful in 4m0s
schemas / deploy-prod (push) Has been skipped
Release / release (push) Successful in 1m18s
Reviewed-on: #677
2026-01-18 09:46:25 +00:00
releaser 48f0ec0bbe chore(release): prepare for v0.9.1 2026-01-18 09:43:20 +00:00
releaser b89b124a0e chore(release): prepare for v0.9.1 2026-01-18 09:43:11 +00:00
argoyle d008303068 Merge pull request 'fix(ci): run build job on tags for Docker images' (#676) from fix-build-on-tags into main
schemas / vulnerabilities (push) Successful in 1m21s
Release / release (push) Successful in 1m30s
schemas / check-release (push) Successful in 2m57s
schemas / check (push) Successful in 4m1s
pre-commit / pre-commit (push) Successful in 7m0s
schemas / build (push) Successful in 5m52s
schemas / deploy-prod (push) Successful in 1m6s
Reviewed-on: #676
2026-01-18 09:41:09 +00:00
argoyle e328ef5a64 fix(ci): run build job on tags for Docker images
schemas / vulnerabilities (pull_request) Successful in 1m33s
schemas / check (pull_request) Successful in 2m55s
schemas / check-release (pull_request) Successful in 2m9s
pre-commit / pre-commit (pull_request) Successful in 5m40s
schemas / build (pull_request) Successful in 4m20s
schemas / deploy-prod (pull_request) Has been skipped
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 10:30:24 +01:00
19 changed files with 897 additions and 1035 deletions
+7 -2
View File
@@ -3,6 +3,8 @@ name: schemas
on:
push:
branches: [main]
tags:
- 'v*'
pull_request:
branches: [main]
workflow_dispatch:
@@ -48,16 +50,19 @@ jobs:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/setup-node@v6
with:
node-version: '24'
- uses: actions/setup-go@v6
with:
go-version: 'stable'
- name: Check goreleaser config
uses: goreleaser/goreleaser-action@v6
uses: goreleaser/goreleaser-action@v7
with:
version: '~> v2'
args: check
- name: Test release build
uses: goreleaser/goreleaser-action@v6
uses: goreleaser/goreleaser-action@v7
with:
version: '~> v2'
args: release --snapshot --clean
+5 -2
View File
@@ -15,13 +15,16 @@ jobs:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/setup-node@v6
with:
node-version: '24'
- uses: actions/setup-go@v6
with:
go-version: 'stable'
- name: Install goreleaser
uses: goreleaser/goreleaser-action@v6
uses: goreleaser/goreleaser-action@v7
with:
version: '~> v2'
version: 'v2.13.3'
install-only: true
- name: Release
run: |
+1 -1
View File
@@ -30,7 +30,7 @@ repos:
- id: go-test
- id: gofumpt
- repo: https://github.com/golangci/golangci-lint
rev: v2.8.0
rev: v2.10.1
hooks:
- id: golangci-lint-full
- repo: https://github.com/gitleaks/gitleaks
+1 -1
View File
@@ -1,3 +1,3 @@
{
"version": "v0.9.0"
"version": "v0.9.5"
}
+79 -1
View File
@@ -2,7 +2,85 @@
All notable changes to this project will be documented in this file.
## [0.9.0] - 2026-01-17
## [0.9.5] - 2026-02-25
### 🐛 Bug Fixes
- *(deps)* Update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.256
### ⚙️ Miscellaneous Tasks
- *(deps)* Update golang:1.26.0 docker digest to 9835fb4 (#736)
- *(deps)* Update node.js to v24.14.0 (#735)
- *(deps)* Update node.js to 7fddd9d (#739)
## [0.9.4] - 2026-02-23
### 🐛 Bug Fixes
- *(ci)* Pin goreleaser to v2.13.3 for Gitea SDK compatibility
## [0.9.3] - 2026-02-23
### 🐛 Bug Fixes
- *(deps)* Update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.249 (#702)
- *(deps)* Update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.250 (#704)
- *(deps)* Update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.251
- *(deps)* Update module gitlab.com/unboundsoftware/eventsourced/pg to v1.18.3
- *(deps)* Update module github.com/vektah/gqlparser/v2 to v2.5.32
- *(deps)* Update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.252 (#714)
- *(deps)* Update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.253 (#716)
- *(deps)* Update module github.com/99designs/gqlgen to v0.17.87
- *(deps)* Update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.254 (#718)
- *(deps)* Update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.255
- *(deps)* Update module github.com/pressly/goose/v3 to v3.27.0
- *(deps)* Update module gitlab.com/unboundsoftware/eventsourced/pg to v1.18.4 (#727)
- Prevent OOM on rapid schema publishing
### ⚙️ Miscellaneous Tasks
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.10.1 (#706)
- *(deps)* Update goreleaser/goreleaser-action action to v7
- *(deps)* Update actions/setup-node action to v6
## [0.9.2] - 2026-02-13
### 🐛 Bug Fixes
- *(deps)* Update module github.com/auth0/go-jwt-middleware/v2 to v3
- Migrate to go-jwt-middleware v3 API
- *(deps)* Update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.243 (#680)
- *(deps)* Update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.244 (#681)
- *(deps)* Update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.245 (#682)
- *(deps)* Update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.246 (#683)
- *(deps)* Update module gitlab.com/unboundsoftware/eventsourced/pg to v1.18.0 (#685)
- *(deps)* Update module gitlab.com/unboundsoftware/eventsourced/pg to v1.18.1 (#686)
- *(deps)* Update opentelemetry-go monorepo (#687)
- *(deps)* Update module go.opentelemetry.io/contrib/bridges/otelslog to v0.15.0 (#688)
- *(deps)* Update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.247 (#691)
- *(deps)* Update module github.com/alecthomas/kong to v1.14.0 (#692)
- *(deps)* Update eventsourced (#693)
- *(deps)* Update module golang.org/x/crypto to v0.48.0 (#694)
- *(deps)* Update module github.com/wundergraph/graphql-go-tools/v2 to v2.0.0-rc.248 (#698)
### ⚙️ Miscellaneous Tasks
- *(deps)* Update node.js to cd6fb7e (#684)
- *(deps)* Update golang:1.25.6 docker digest to ceda080 (#689)
- *(deps)* Update golang docker tag to v1.25.7
- *(deps)* Update golang:1.25.7 docker digest to d2819ff (#695)
- *(deps)* Update pre-commit hook golangci/golangci-lint to v2.9.0 (#697)
- *(deps)* Update golang docker tag to v1.26.0 (#696)
- *(deps)* Update node.js to v24.13.1 (#699)
## [0.9.1] - 2026-01-18
### 🐛 Bug Fixes
- *(ci)* Run build job on tags for Docker images
## [0.9.0] - 2026-01-18
### 🚀 Features
+2 -2
View File
@@ -1,4 +1,4 @@
FROM amd64/golang:1.25.6@sha256:9860925875ac68a8fb57416cfc5c1ee267a06226730434af677b9406e8ea6ee6 as modules
FROM amd64/golang:1.26.0@sha256:9835fb4f8aa06038ca460e300ee3cb8079d0802a1979724cdb455f5784448704 as modules
WORKDIR /build
ADD go.* /build
RUN go mod download
@@ -24,7 +24,7 @@ RUN GOOS=linux GOARCH=amd64 go build \
FROM scratch as export
COPY --from=build /build/coverage.txt /
FROM node:24.13.0-alpine@sha256:931d7d57f8c1fd0e2179dbff7cc7da4c9dd100998bc2b32afc85142d8efbc213
FROM node:24.14.0-alpine@sha256:7fddd9ddeae8196abf4a3ef2de34e11f7b1a722119f91f28ddf1e99dcafdf114
ENV TZ Europe/Stockholm
# Install wgc CLI globally for Cosmo Router composition
+7 -5
View File
@@ -201,11 +201,13 @@ func start(closeEvents chan error, logger *slog.Logger, connectToAmqpFunc func(u
defer rootCancel()
resolver := &graph.Resolver{
EventStore: eventStore,
Publisher: eventPublisher,
Logger: logger,
Cache: serviceCache,
PubSub: graph.NewPubSub(),
EventStore: eventStore,
Publisher: eventPublisher,
Logger: logger,
Cache: serviceCache,
PubSub: graph.NewPubSub(),
CosmoGenerator: graph.NewCosmoGenerator(&graph.DefaultCommandExecutor{}, 60*time.Second),
Debouncer: graph.NewDebouncer(500 * time.Millisecond),
}
config := generated.Config{
+50 -39
View File
@@ -1,38 +1,37 @@
module gitea.unbound.se/unboundsoftware/schemas
go 1.25
go 1.25.0
require (
github.com/99designs/gqlgen v0.17.86
github.com/99designs/gqlgen v0.17.87
github.com/DATA-DOG/go-sqlmock v1.5.2
github.com/Khan/genqlient v0.8.1
github.com/alecthomas/kong v1.13.0
github.com/alecthomas/kong v1.14.0
github.com/apex/log v1.9.0
github.com/auth0/go-jwt-middleware/v2 v2.3.1
github.com/golang-jwt/jwt/v5 v5.3.0
github.com/auth0/go-jwt-middleware/v3 v3.0.0
github.com/google/uuid v1.6.0
github.com/jmoiron/sqlx v1.4.0
github.com/pkg/errors v0.9.1
github.com/pressly/goose/v3 v3.26.0
github.com/pressly/goose/v3 v3.27.0
github.com/rs/cors v1.11.1
github.com/sparetimecoders/goamqp v0.3.3
github.com/stretchr/testify v1.11.1
github.com/vektah/gqlparser/v2 v2.5.31
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.242
gitlab.com/unboundsoftware/eventsourced/amqp v1.9.0
gitlab.com/unboundsoftware/eventsourced/eventsourced v1.19.3
gitlab.com/unboundsoftware/eventsourced/pg v1.17.0
go.opentelemetry.io/contrib/bridges/otelslog v0.14.0
go.opentelemetry.io/otel v1.39.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.15.0
go.opentelemetry.io/otel/log v0.15.0
go.opentelemetry.io/otel/sdk v1.39.0
go.opentelemetry.io/otel/sdk/log v0.15.0
go.opentelemetry.io/otel/sdk/metric v1.39.0
go.opentelemetry.io/otel/trace v1.39.0
golang.org/x/crypto v0.47.0
github.com/vektah/gqlparser/v2 v2.5.32
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.256
gitlab.com/unboundsoftware/eventsourced/amqp v1.9.1
gitlab.com/unboundsoftware/eventsourced/eventsourced v1.19.4
gitlab.com/unboundsoftware/eventsourced/pg v1.18.4
go.opentelemetry.io/contrib/bridges/otelslog v0.15.0
go.opentelemetry.io/otel v1.40.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.40.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.16.0
go.opentelemetry.io/otel/log v0.16.0
go.opentelemetry.io/otel/sdk v1.40.0
go.opentelemetry.io/otel/sdk/log v0.16.0
go.opentelemetry.io/otel/sdk/metric v1.40.0
go.opentelemetry.io/otel/trace v1.40.0
golang.org/x/crypto v0.48.0
golang.org/x/sync v0.19.0
gopkg.in/yaml.v3 v3.0.1
)
@@ -42,17 +41,28 @@ require (
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/goccy/go-yaml v1.19.2 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/lestrrat-go/blackmagic v1.0.4 // indirect
github.com/lestrrat-go/dsig v1.0.0 // indirect
github.com/lestrrat-go/dsig-secp256k1 v1.0.0 // indirect
github.com/lestrrat-go/httpcc v1.0.1 // indirect
github.com/lestrrat-go/httprc/v3 v3.0.3 // indirect
github.com/lestrrat-go/jwx/v3 v3.0.12 // indirect
github.com/lestrrat-go/option/v2 v2.0.0 // indirect
github.com/lib/pq v1.11.2 // indirect
github.com/mfridman/interpolate v0.0.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rabbitmq/amqp091-go v1.10.0 // indirect
github.com/segmentio/asm v1.2.1 // indirect
github.com/sethvargo/go-retry v0.3.0 // indirect
github.com/sosodev/duration v1.3.1 // indirect
github.com/stretchr/objx v0.5.2 // indirect
@@ -60,21 +70,22 @@ require (
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/tidwall/sjson v1.2.5 // indirect
github.com/urfave/cli/v3 v3.6.1 // indirect
github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083 // indirect
github.com/urfave/cli/v3 v3.6.2 // indirect
github.com/valyala/fastjson v1.6.7 // indirect
github.com/wundergraph/astjson v1.1.0 // indirect
github.com/wundergraph/go-arena v1.1.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 // indirect
go.opentelemetry.io/otel/metric v1.39.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 // indirect
go.opentelemetry.io/otel/metric v1.40.0 // indirect
go.opentelemetry.io/proto/otlp v1.9.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/mod v0.31.0 // indirect
golang.org/x/net v0.48.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.40.0 // indirect
golang.org/x/text v0.33.0 // indirect
golang.org/x/tools v0.40.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
google.golang.org/grpc v1.77.0 // indirect
golang.org/x/mod v0.33.0 // indirect
golang.org/x/net v0.50.0 // indirect
golang.org/x/sys v0.41.0 // indirect
golang.org/x/text v0.34.0 // indirect
golang.org/x/tools v0.42.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d // indirect
google.golang.org/grpc v1.79.1 // indirect
google.golang.org/protobuf v1.36.11 // indirect
)
+107 -84
View File
@@ -1,7 +1,8 @@
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/99designs/gqlgen v0.17.86 h1:C8N3UTa5heXX6twl+b0AJyGkTwYL6dNmFrgZNLRcU6w=
github.com/99designs/gqlgen v0.17.86/go.mod h1:KTrPl+vHA1IUzNlh4EYkl7+tcErL3MgKnhHrBcV74Fw=
filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo=
filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc=
github.com/99designs/gqlgen v0.17.87 h1:pSnCIMhBQezAE8bc1GNmfdLXFmnWtWl1GRDFEE/nHP8=
github.com/99designs/gqlgen v0.17.87/go.mod h1:fK05f1RqSNfQpd4CfW5qk/810Tqi4/56Wf6Nem0khAg=
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
github.com/Khan/genqlient v0.8.1 h1:wtOCc8N9rNynRLXN3k3CnfzheCUNKBcvXmVv5zt6WCs=
@@ -12,8 +13,8 @@ github.com/agnivade/levenshtein v1.2.1 h1:EHBY3UOn1gwdy/VbFwgo4cxecRznFk7fKWN1KO
github.com/agnivade/levenshtein v1.2.1/go.mod h1:QVVI16kDrtSuwcpd0p1+xMC6Z/VfhtCyDIjcwga4/DU=
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
github.com/alecthomas/kong v1.13.0 h1:5e/7XC3ugvhP1DQBmTS+WuHtCbcv44hsohMgcvVxSrA=
github.com/alecthomas/kong v1.13.0/go.mod h1:wrlbXem1CWqUV5Vbmss5ISYhsVPkBb1Yo7YKJghju2I=
github.com/alecthomas/kong v1.14.0 h1:gFgEUZWu2ZmZ+UhyZ1bDhuutbKN1nTtJTwh19Wsn21s=
github.com/alecthomas/kong v1.14.0/go.mod h1:wrlbXem1CWqUV5Vbmss5ISYhsVPkBb1Yo7YKJghju2I=
github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs=
github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
@@ -27,8 +28,8 @@ github.com/aphistic/golf v0.0.0-20180712155816-02c07f170c5a/go.mod h1:3NqKYiepwy
github.com/aphistic/sweet v0.2.0/go.mod h1:fWDlIh/isSE9n6EPsRmC0det+whmX6dJid3stzu0Xys=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
github.com/auth0/go-jwt-middleware/v2 v2.3.1 h1:lbDyWE9aLydb3zrank+Gufb9qGJN9u//7EbJK07pRrw=
github.com/auth0/go-jwt-middleware/v2 v2.3.1/go.mod h1:mqVr0gdB5zuaFyQFWMJH/c/2hehNjbYUD4i8Dpyf+Hc=
github.com/auth0/go-jwt-middleware/v3 v3.0.0 h1:+rvUPCT+VbAuK4tpS13fWfZrMyqTwLopt3VoY0Y7kvA=
github.com/auth0/go-jwt-middleware/v3 v3.0.0/go.mod h1:iU42jqjRyeKbf9YYSnRnolr836gk6Ty/jnUNuVq2b0o=
github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
@@ -40,6 +41,8 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54 h1:SG7nF6SRlWhcT7cNTs5R6Hk4V2lcmLz2NsG2VnInyNo=
github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
@@ -55,12 +58,12 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo=
github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
@@ -72,8 +75,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3/go.mod h1:zQrxl1YP88HQlA6i9c63DSVPFklWpGX4OWAc9bFuaH4=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 h1:X+2YciYSxvMQK0UZ7sg45ZVabVZBeBuvMkmuI2V3Fak=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7/go.mod h1:lW34nIZuQ8UDPdkon5fmfp2l3+ZkQ2me/+oecHYLOII=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
@@ -94,8 +97,23 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lestrrat-go/blackmagic v1.0.4 h1:IwQibdnf8l2KoO+qC3uT4OaTWsW7tuRQXy9TRN9QanA=
github.com/lestrrat-go/blackmagic v1.0.4/go.mod h1:6AWFyKNNj0zEXQYfTMPfZrAXUWUfTIZ5ECEUEJaijtw=
github.com/lestrrat-go/dsig v1.0.0 h1:OE09s2r9Z81kxzJYRn07TFM9XA4akrUdoMwr0L8xj38=
github.com/lestrrat-go/dsig v1.0.0/go.mod h1:dEgoOYYEJvW6XGbLasr8TFcAxoWrKlbQvmJgCR0qkDo=
github.com/lestrrat-go/dsig-secp256k1 v1.0.0 h1:JpDe4Aybfl0soBvoVwjqDbp+9S1Y2OM7gcrVVMFPOzY=
github.com/lestrrat-go/dsig-secp256k1 v1.0.0/go.mod h1:CxUgAhssb8FToqbL8NjSPoGQlnO4w3LG1P0qPWQm/NU=
github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
github.com/lestrrat-go/httprc/v3 v3.0.3 h1:WjLHWkDkgWXeIUrKi/7lS/sGq2DjkSAwdTbH5RHXAKs=
github.com/lestrrat-go/httprc/v3 v3.0.3/go.mod h1:mSMtkZW92Z98M5YoNNztbRGxbXHql7tSitCvaxvo9l0=
github.com/lestrrat-go/jwx/v3 v3.0.12 h1:p25r68Y4KrbBdYjIsQweYxq794CtGCzcrc5dGzJIRjg=
github.com/lestrrat-go/jwx/v3 v3.0.12/go.mod h1:HiUSaNmMLXgZ08OmGBaPVvoZQgJVOQphSrGr5zMamS8=
github.com/lestrrat-go/option/v2 v2.0.0 h1:XxrcaJESE1fokHy3FpaQ/cXW8ZsIdWcdFzzLOcID3Ss=
github.com/lestrrat-go/option/v2 v2.0.0/go.mod h1:oSySsmzMoR0iRzCDCaUfsCzxQHUEuhOViQObyy7S6Vg=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.11.2 h1:x6gxUeu39V0BHZiugWe8LXZYZ+Utk7hSJGThs8sdzfs=
github.com/lib/pq v1.11.2/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
@@ -107,8 +125,8 @@ github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxU
github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY=
github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -116,8 +134,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pressly/goose/v3 v3.26.0 h1:KJakav68jdH0WDvoAcj8+n61WqOIaPGgH0bJWS6jpmM=
github.com/pressly/goose/v3 v3.26.0/go.mod h1:4hC1KrritdCxtuFsqgs1R4AU5bWtTAf+cnWvfhf2DNY=
github.com/pressly/goose/v3 v3.27.0 h1:/D30gVTuQhu0WsNZYbJi4DMOsx1lNq+6SkLe+Wp59BM=
github.com/pressly/goose/v3 v3.27.0/go.mod h1:3ZBeCXqzkgIRvrEMDkYh1guvtoJTU5oMMuDdkutoM78=
github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw=
github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
@@ -131,6 +149,8 @@ github.com/sanity-io/litter v1.5.8 h1:uM/2lKrWdGbRXDrIq08Lh9XtVYoeGtcQxk9rtQ7+rY
github.com/sanity-io/litter v1.5.8/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U=
github.com/sebdah/goldie/v2 v2.7.1 h1:PkBHymaYdtvEkZV7TmyqKxdmn5/Vcj+8TpATWZjnG5E=
github.com/sebdah/goldie/v2 v2.7.1/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
github.com/segmentio/asm v1.2.1 h1:DTNbBqs57ioxAD4PrArqftgypG4/qNpXoJx8TVXxPR0=
github.com/segmentio/asm v1.2.1/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
@@ -148,6 +168,7 @@ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
@@ -167,48 +188,52 @@ github.com/tj/go-buffer v1.1.0/go.mod h1:iyiJpfFcR2B9sXu7KvjbT9fpM4mOelRSDTbntVj
github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0=
github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao=
github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4=
github.com/urfave/cli/v3 v3.6.1 h1:j8Qq8NyUawj/7rTYdBGrxcH7A/j7/G8Q5LhWEW4G3Mo=
github.com/urfave/cli/v3 v3.6.1/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso=
github.com/vektah/gqlparser/v2 v2.5.31 h1:YhWGA1mfTjID7qJhd1+Vxhpk5HTgydrGU9IgkWBTJ7k=
github.com/vektah/gqlparser/v2 v2.5.31/go.mod h1:c1I28gSOVNzlfc4WuDlqU7voQnsqI6OG2amkBAFmgts=
github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083 h1:8/D7f8gKxTBjW+SZK4mhxTTBVpxcqeBgWF1Rfmltbfk=
github.com/wundergraph/astjson v0.0.0-20250106123708-be463c97e083/go.mod h1:eOTL6acwctsN4F3b7YE+eE2t8zcJ/doLm9sZzsxxxrE=
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.242 h1:0ieQmRxYz0nbJEbaaA4Cx2RPcxlomhQ8KI31uuevWx0=
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.242/go.mod h1:mX25ASEQiKamxaFSK6NZihh0oDCigIuzro30up4mFH4=
gitlab.com/unboundsoftware/eventsourced/amqp v1.9.0 h1:TdBJnrnrxJrPhC4i6KTFUElZa3k/fFXiGwg0sds5aAo=
gitlab.com/unboundsoftware/eventsourced/amqp v1.9.0/go.mod h1:VauAph7uCvEakYNdHkkSAoOOGKvEuUA/uhsR376ThbI=
gitlab.com/unboundsoftware/eventsourced/eventsourced v1.19.3 h1:0HbDHF4sHfoyDrbPLMFWvsQLbTl2ITrpI9PjDIZsV1Y=
gitlab.com/unboundsoftware/eventsourced/eventsourced v1.19.3/go.mod h1:LrA7I7etRmhIC1PjO8c26BHm+gWsy2rC3eSMe5+XUWE=
gitlab.com/unboundsoftware/eventsourced/pg v1.17.0 h1:pUJzMpNPX0GVsffRZXlpKR1d7Ws96KTxJwbLFPpASSc=
gitlab.com/unboundsoftware/eventsourced/pg v1.17.0/go.mod h1:WgPrZhyCbsZ3TG2tPUbh2MUjOEaANJjsWi/0hlIwRVU=
github.com/urfave/cli/v3 v3.6.2 h1:lQuqiPrZ1cIz8hz+HcrG0TNZFxU70dPZ3Yl+pSrH9A8=
github.com/urfave/cli/v3 v3.6.2/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso=
github.com/valyala/fastjson v1.6.7 h1:ZE4tRy0CIkh+qDc5McjatheGX2czdn8slQjomexVpBM=
github.com/valyala/fastjson v1.6.7/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
github.com/vektah/gqlparser/v2 v2.5.32 h1:k9QPJd4sEDTL+qB4ncPLflqTJ3MmjB9SrVzJrawpFSc=
github.com/vektah/gqlparser/v2 v2.5.32/go.mod h1:c1I28gSOVNzlfc4WuDlqU7voQnsqI6OG2amkBAFmgts=
github.com/wundergraph/astjson v1.1.0 h1:xORDosrZ87zQFJwNGe/HIHXqzpdHOFmqWgykCLVL040=
github.com/wundergraph/astjson v1.1.0/go.mod h1:h12D/dxxnedtLzsKyBLK7/Oe4TAoGpRVC9nDpDrZSWw=
github.com/wundergraph/go-arena v1.1.0 h1:9+wSRkJAkA2vbYHp6s8tEGhPViRGQNGXqPHT0QzhdIc=
github.com/wundergraph/go-arena v1.1.0/go.mod h1:ROOysEHWJjLQ8FSfNxZCziagb7Qw2nXY3/vgKRh7eWw=
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.256 h1:IlLfd3qL4THUkxSXsVRwcDNCAPNXqDrflMI0Hbvlb/Q=
github.com/wundergraph/graphql-go-tools/v2 v2.0.0-rc.256/go.mod h1:gfmmrPd2khZONmwYE8RIfnGjwIG+RqL52jYiBzcUST8=
gitlab.com/unboundsoftware/eventsourced/amqp v1.9.1 h1:X6269JoAzHIKCVmtgMHZH3m7xOpACSp37ca3eODe9iU=
gitlab.com/unboundsoftware/eventsourced/amqp v1.9.1/go.mod h1:EAs0d6Eh0aDiQkUJlSWErHqgHFQdxx0e8I7aG/2FarY=
gitlab.com/unboundsoftware/eventsourced/eventsourced v1.19.4 h1:+yZkhi9/sTyBEN5vJTfvycyXgGrm07QKGSh3jiWiQdM=
gitlab.com/unboundsoftware/eventsourced/eventsourced v1.19.4/go.mod h1:LrA7I7etRmhIC1PjO8c26BHm+gWsy2rC3eSMe5+XUWE=
gitlab.com/unboundsoftware/eventsourced/pg v1.18.4 h1:ei0xdaACXw6/54w5hPscGUlJUzHJm6MQoeUP7hPqbJA=
gitlab.com/unboundsoftware/eventsourced/pg v1.18.4/go.mod h1:IryGlvRa02/IAASbGqoMHTC2Q4WHXr2QY7fLUVN3mL0=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/contrib/bridges/otelslog v0.14.0 h1:eypSOd+0txRKCXPNyqLPsbSfA0jULgJcGmSAdFAnrCM=
go.opentelemetry.io/contrib/bridges/otelslog v0.14.0/go.mod h1:CRGvIBL/aAxpQU34ZxyQVFlovVcp67s4cAmQu8Jh9mc=
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0 h1:nKP4Z2ejtHn3yShBb+2KawiXgpn8In5cT7aO2wXuOTE=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.39.0/go.mod h1:NwjeBbNigsO4Aj9WgM0C+cKIrxsZUaRmZUO7A8I7u8o=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0 h1:f0cb2XPmrqn4XMy9PNliTgRKJgS5WcL/u0/WRYGz4t0=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.39.0/go.mod h1:vnakAaFckOMiMtOIhFI2MNH4FYrZzXCYxmb1LlhoGz8=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0 h1:Ckwye2FpXkYgiHX7fyVrN1uA/UYd9ounqqTuSNAv0k4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.39.0/go.mod h1:teIFJh5pW2y+AN7riv6IBPX2DuesS3HgP39mwOspKwU=
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.15.0 h1:0BSddrtQqLEylcErkeFrJBmwFzcqfQq9+/uxfTZq+HE=
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.15.0/go.mod h1:87sjYuAPzaRCtdd09GU5gM1U9wQLrrcYrm77mh5EBoc=
go.opentelemetry.io/otel/log v0.15.0 h1:0VqVnc3MgyYd7QqNVIldC3dsLFKgazR6P3P3+ypkyDY=
go.opentelemetry.io/otel/log v0.15.0/go.mod h1:9c/G1zbyZfgu1HmQD7Qj84QMmwTp2QCQsZH1aeoWDE4=
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
go.opentelemetry.io/otel/sdk/log v0.15.0 h1:WgMEHOUt5gjJE93yqfqJOkRflApNif84kxoHWS9VVHE=
go.opentelemetry.io/otel/sdk/log v0.15.0/go.mod h1:qDC/FlKQCXfH5hokGsNg9aUBGMJQsrUyeOiW5u+dKBQ=
go.opentelemetry.io/otel/sdk/log/logtest v0.14.0 h1:Ijbtz+JKXl8T2MngiwqBlPaHqc4YCaP/i13Qrow6gAM=
go.opentelemetry.io/otel/sdk/log/logtest v0.14.0/go.mod h1:dCU8aEL6q+L9cYTqcVOk8rM9Tp8WdnHOPLiBgp0SGOA=
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
go.opentelemetry.io/contrib/bridges/otelslog v0.15.0 h1:yOYhGNPZseueTTvWp5iBD3/CthrmvayUXYEX862dDi4=
go.opentelemetry.io/contrib/bridges/otelslog v0.15.0/go.mod h1:CvaNVqIfcybc+7xqZNubbE+26K6P7AKZF/l0lE2kdCk=
go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms=
go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.40.0 h1:9y5sHvAxWzft1WQ4BwqcvA+IFVUJ1Ya75mSAUnFEVwE=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.40.0/go.mod h1:eQqT90eR3X5Dbs1g9YSM30RavwLF725Ris5/XSXWvqE=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 h1:QKdN8ly8zEMrByybbQgv8cWBcdAarwmIPZ6FThrWXJs=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0/go.mod h1:bTdK1nhqF76qiPoCCdyFIV+N/sRHYXYCTQc+3VCi3MI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0 h1:wVZXIWjQSeSmMoxF74LzAnpVQOAFDo3pPji9Y4SOFKc=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0/go.mod h1:khvBS2IggMFNwZK/6lEeHg/W57h/IX6J4URh57fuI40=
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.16.0 h1:ivlbaajBWJqhcCPniDqDJmRwj4lc6sRT+dCAVKNmxlQ=
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.16.0/go.mod h1:u/G56dEKDDwXNCVLsbSrllB2o8pbtFLUC4HpR66r2dc=
go.opentelemetry.io/otel/log v0.16.0 h1:DeuBPqCi6pQwtCK0pO4fvMB5eBq6sNxEnuTs88pjsN4=
go.opentelemetry.io/otel/log v0.16.0/go.mod h1:rWsmqNVTLIA8UnwYVOItjyEZDbKIkMxdQunsIhpUMes=
go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g=
go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc=
go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8=
go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE=
go.opentelemetry.io/otel/sdk/log v0.16.0 h1:e/b4bdlQwC5fnGtG3dlXUrNOnP7c8YLVSpSfEBIkTnI=
go.opentelemetry.io/otel/sdk/log v0.16.0/go.mod h1:JKfP3T6ycy7QEuv3Hj8oKDy7KItrEkus8XJE6EoSzw4=
go.opentelemetry.io/otel/sdk/log/logtest v0.16.0 h1:/XVkpZ41rVRTP4DfMgYv1nEtNmf65XPPyAdqV90TMy4=
go.opentelemetry.io/otel/sdk/log/logtest v0.16.0/go.mod h1:iOOPgQr5MY9oac/F5W86mXdeyWZGleIx3uXO98X2R6Y=
go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw=
go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg=
go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw=
go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA=
go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A=
go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
@@ -217,17 +242,17 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o=
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0=
golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA=
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
@@ -235,23 +260,23 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls=
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww=
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM=
google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig=
google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 h1:merA0rdPeUV3YIIfHHcH4qBkiQAc1nfCKSI7lB4cV2M=
google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409/go.mod h1:fl8J1IvUjCilwZzQowmw2b7HQB2eAuYBabMXzWurF+I=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d h1:t/LOSXPJ9R0B6fnZNyALBRfZBH0Uy0gT+uR+SJ6syqQ=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY=
google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -259,8 +284,6 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/go-jose/go-jose.v2 v2.6.3 h1:nt80fvSDlhKWQgSWyHyy5CfmlQr+asih51R8PTWNKKs=
gopkg.in/go-jose/go-jose.v2 v2.6.3/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -268,11 +291,11 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
modernc.org/libc v1.66.3 h1:cfCbjTUcdsKyyZZfEUKfoHcP3S0Wkvz3jgSzByEWVCQ=
modernc.org/libc v1.66.3/go.mod h1:XD9zO8kt59cANKvHPXpx7yS2ELPheAey0vjIuZOhOU8=
modernc.org/libc v1.68.0 h1:PJ5ikFOV5pwpW+VqCK1hKJuEWsonkIJhhIXyuF/91pQ=
modernc.org/libc v1.68.0/go.mod h1:NnKCYeoYgsEqnY3PgvNgAeaJnso968ygU8Z0DxjoEc0=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/sqlite v1.38.2 h1:Aclu7+tgjgcQVShZqim41Bbw9Cho0y/7WzYptXqkEek=
modernc.org/sqlite v1.38.2/go.mod h1:cPTJYSlgg3Sfg046yBShXENNtPrWrDX8bsbAQBzgQ5E=
modernc.org/sqlite v1.46.1 h1:eFJ2ShBLIEnUWlLy12raN0Z1plqmFX9Qe3rjQTKt6sU=
modernc.org/sqlite v1.46.1/go.mod h1:CzbrU2lSB1DKUusvwGz7rqEKIq+NUd8GWuBBZDs9/nA=
+36
View File
@@ -1,11 +1,14 @@
package graph
import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
"time"
"golang.org/x/sync/semaphore"
"gopkg.in/yaml.v3"
"gitea.unbound.se/unboundsoftware/schemas/graph/model"
@@ -123,3 +126,36 @@ func GenerateCosmoRouterConfigWithExecutor(subGraphs []*model.SubGraph, executor
return string(configJSON), nil
}
// CosmoGenerator wraps config generation with a concurrency limit and timeout
// to prevent unbounded wgc process spawning under rapid schema updates.
type CosmoGenerator struct {
sem *semaphore.Weighted
executor CommandExecutor
timeout time.Duration
}
// NewCosmoGenerator creates a CosmoGenerator that allows at most one concurrent
// wgc process and applies the given timeout to each generation attempt.
func NewCosmoGenerator(executor CommandExecutor, timeout time.Duration) *CosmoGenerator {
return &CosmoGenerator{
sem: semaphore.NewWeighted(1),
executor: executor,
timeout: timeout,
}
}
// Generate produces a Cosmo Router config, blocking if another generation is
// already in progress. The provided context (plus the configured timeout)
// controls cancellation.
func (g *CosmoGenerator) Generate(ctx context.Context, subGraphs []*model.SubGraph) (string, error) {
ctx, cancel := context.WithTimeout(ctx, g.timeout)
defer cancel()
if err := g.sem.Acquire(ctx, 1); err != nil {
return "", fmt.Errorf("acquire cosmo generator: %w", err)
}
defer g.sem.Release(1)
return GenerateCosmoRouterConfigWithExecutor(subGraphs, g.executor)
}
+112
View File
@@ -1,11 +1,15 @@
package graph
import (
"context"
"encoding/json"
"fmt"
"os"
"strings"
"sync"
"sync/atomic"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -459,6 +463,114 @@ func TestGenerateCosmoRouterConfig_MockError(t *testing.T) {
assert.Equal(t, 1, mockExecutor.CallCount, "Should have attempted to call executor")
}
// SlowMockExecutor simulates a slow wgc command for concurrency testing.
type SlowMockExecutor struct {
MockCommandExecutor
delay time.Duration
mu sync.Mutex
concurrent atomic.Int32
maxSeen atomic.Int32
}
func (m *SlowMockExecutor) Execute(name string, args ...string) ([]byte, error) {
cur := m.concurrent.Add(1)
// Track the maximum concurrent executions observed.
for {
old := m.maxSeen.Load()
if cur <= old || m.maxSeen.CompareAndSwap(old, cur) {
break
}
}
defer m.concurrent.Add(-1)
time.Sleep(m.delay)
m.mu.Lock()
defer m.mu.Unlock()
return m.MockCommandExecutor.Execute(name, args...)
}
func TestCosmoGenerator_ConcurrencyLimit(t *testing.T) {
executor := &SlowMockExecutor{delay: 100 * time.Millisecond}
gen := NewCosmoGenerator(executor, 5*time.Second)
subGraphs := []*model.SubGraph{
{
Service: "svc",
URL: stringPtr("http://localhost:4001/query"),
Sdl: "type Query { hello: String }",
},
}
var wg sync.WaitGroup
for range 5 {
wg.Add(1)
go func() {
defer wg.Done()
_, _ = gen.Generate(context.Background(), subGraphs)
}()
}
wg.Wait()
assert.Equal(t, int32(1), executor.maxSeen.Load(),
"at most 1 wgc process should run concurrently")
}
func TestCosmoGenerator_Timeout(t *testing.T) {
// Executor that takes longer than the timeout.
executor := &SlowMockExecutor{delay: 500 * time.Millisecond}
gen := NewCosmoGenerator(executor, 50*time.Millisecond)
subGraphs := []*model.SubGraph{
{
Service: "svc",
URL: stringPtr("http://localhost:4001/query"),
Sdl: "type Query { hello: String }",
},
}
// First call: occupies the semaphore for 500ms.
go func() {
_, _ = gen.Generate(context.Background(), subGraphs)
}()
// Give the first goroutine time to acquire the semaphore.
time.Sleep(20 * time.Millisecond)
// Second call: should timeout waiting for the semaphore.
_, err := gen.Generate(context.Background(), subGraphs)
require.Error(t, err)
assert.Contains(t, err.Error(), "acquire cosmo generator")
}
func TestCosmoGenerator_ContextCancellation(t *testing.T) {
executor := &SlowMockExecutor{delay: 500 * time.Millisecond}
gen := NewCosmoGenerator(executor, 5*time.Second)
subGraphs := []*model.SubGraph{
{
Service: "svc",
URL: stringPtr("http://localhost:4001/query"),
Sdl: "type Query { hello: String }",
},
}
// First call: occupies the semaphore.
go func() {
_, _ = gen.Generate(context.Background(), subGraphs)
}()
time.Sleep(20 * time.Millisecond)
// Second call with an already-cancelled context.
ctx, cancel := context.WithCancel(context.Background())
cancel()
_, err := gen.Generate(ctx, subGraphs)
require.Error(t, err)
assert.Contains(t, err.Error(), "acquire cosmo generator")
}
// Helper function for tests
func stringPtr(s string) *string {
return &s
+42
View File
@@ -0,0 +1,42 @@
package graph
import (
"sync"
"time"
)
// Debouncer coalesces rapid calls with the same key, executing only the last
// one after a configurable delay. This prevents redundant work when multiple
// updates arrive in quick succession (e.g., rapid schema publishing).
type Debouncer struct {
mu sync.Mutex
delay time.Duration
timers map[string]*time.Timer
}
// NewDebouncer creates a Debouncer with the given delay window.
func NewDebouncer(delay time.Duration) *Debouncer {
return &Debouncer{
delay: delay,
timers: make(map[string]*time.Timer),
}
}
// Debounce resets the timer for key. When the timer fires (after delay with no
// new calls for the same key), fn is executed in a new goroutine.
func (d *Debouncer) Debounce(key string, fn func()) {
d.mu.Lock()
defer d.mu.Unlock()
if t, ok := d.timers[key]; ok {
t.Stop()
}
d.timers[key] = time.AfterFunc(d.delay, func() {
d.mu.Lock()
delete(d.timers, key)
d.mu.Unlock()
fn()
})
}
+57
View File
@@ -0,0 +1,57 @@
package graph
import (
"sync/atomic"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestDebouncer_Coalesces(t *testing.T) {
d := NewDebouncer(50 * time.Millisecond)
var calls atomic.Int32
// Fire 10 rapid calls for the same key — only the last should execute.
for range 10 {
d.Debounce("key1", func() {
calls.Add(1)
})
}
// Wait for the debounce delay plus some margin.
time.Sleep(150 * time.Millisecond)
assert.Equal(t, int32(1), calls.Load(), "rapid calls should coalesce into a single execution")
}
func TestDebouncer_DifferentKeys(t *testing.T) {
d := NewDebouncer(50 * time.Millisecond)
var calls atomic.Int32
d.Debounce("key-a", func() { calls.Add(1) })
d.Debounce("key-b", func() { calls.Add(1) })
d.Debounce("key-c", func() { calls.Add(1) })
time.Sleep(150 * time.Millisecond)
assert.Equal(t, int32(3), calls.Load(), "different keys should fire independently")
}
func TestDebouncer_TimerReset(t *testing.T) {
d := NewDebouncer(100 * time.Millisecond)
var value atomic.Int32
// First call sets value to 1.
d.Debounce("key", func() { value.Store(1) })
// Wait 60ms (less than the 100ms delay), then replace with value 2.
time.Sleep(60 * time.Millisecond)
d.Debounce("key", func() { value.Store(2) })
// At 60ms the first timer hasn't fired yet. Wait for the second timer.
time.Sleep(150 * time.Millisecond)
require.Equal(t, int32(2), value.Load(), "later call should replace the earlier one")
}
File diff suppressed because it is too large Load Diff
+7 -5
View File
@@ -24,11 +24,13 @@ type Publisher interface {
}
type Resolver struct {
EventStore eventsourced.EventStore
Publisher Publisher
Logger *slog.Logger
Cache *cache.Cache
PubSub *PubSub
EventStore eventsourced.EventStore
Publisher Publisher
Logger *slog.Logger
Cache *cache.Cache
PubSub *PubSub
CosmoGenerator *CosmoGenerator
Debouncer *Debouncer
}
func (r *Resolver) apiKeyCanAccessRef(ctx context.Context, ref string, publish bool) (string, error) {
+21 -49
View File
@@ -174,8 +174,9 @@ func (r *mutationResolver) UpdateSubGraph(ctx context.Context, input model.Input
return nil, err
}
// Publish schema update to subscribers
go func() {
// Debounce schema update publishing so rapid successive updates for the
// same org+ref only trigger one config generation.
r.Debouncer.Debounce(orgId+":"+input.Ref, func() {
services, lastUpdate := r.Cache.Services(orgId, input.Ref, "")
r.Logger.Info("Publishing schema update after subgraph change",
"ref", input.Ref,
@@ -191,19 +192,11 @@ func (r *mutationResolver) UpdateSubGraph(ctx context.Context, input model.Input
r.Logger.Error("fetch subgraph for update notification", "error", err)
continue
}
subGraphs[i] = &model.SubGraph{
ID: sg.ID.String(),
Service: sg.Service,
URL: sg.Url,
WsURL: sg.WSUrl,
Sdl: sg.Sdl,
ChangedBy: sg.ChangedBy,
ChangedAt: sg.ChangedAt,
}
subGraphs[i] = r.toGqlSubGraph(sg)
}
// Generate Cosmo router config
cosmoConfig, err := GenerateCosmoRouterConfig(subGraphs)
// Generate Cosmo router config (concurrency-limited)
cosmoConfig, err := r.CosmoGenerator.Generate(context.Background(), subGraphs)
if err != nil {
r.Logger.Error("generate cosmo config for update", "error", err)
cosmoConfig = "" // Send empty if generation fails
@@ -225,7 +218,7 @@ func (r *mutationResolver) UpdateSubGraph(ctx context.Context, input model.Input
)
r.PubSub.Publish(input.Ref, update)
}()
})
return r.toGqlSubGraph(subGraph), nil
}
@@ -292,30 +285,16 @@ func (r *queryResolver) Supergraph(ctx context.Context, ref string, isAfter *str
}, nil
}
subGraphs := make([]*model.SubGraph, len(services))
serviceSDLs := make([]string, len(services))
for i, id := range services {
sg, err := r.fetchSubGraph(ctx, id)
if err != nil {
return nil, err
}
subGraphs[i] = &model.SubGraph{
ID: sg.ID.String(),
Service: sg.Service,
URL: sg.Url,
WsURL: sg.WSUrl,
Sdl: sg.Sdl,
ChangedBy: sg.ChangedBy,
ChangedAt: sg.ChangedAt,
}
subGraphs[i] = r.toGqlSubGraph(sg)
serviceSDLs[i] = sg.Sdl
}
var serviceSDLs []string
for _, id := range services {
sg, err := r.fetchSubGraph(ctx, id)
if err != nil {
return nil, err
}
serviceSDLs = append(serviceSDLs, sg.Sdl)
}
sdl, err := sdlmerge.MergeSDLs(serviceSDLs...)
if err != nil {
return nil, err
@@ -388,8 +367,8 @@ func (r *queryResolver) LatestSchema(ctx context.Context, ref string) (*model.Sc
}
}
// Generate Cosmo router config
cosmoConfig, err := GenerateCosmoRouterConfig(subGraphs)
// Generate Cosmo router config (concurrency-limited)
cosmoConfig, err := r.CosmoGenerator.Generate(ctx, subGraphs)
if err != nil {
r.Logger.Error("generate cosmo config", "error", err)
cosmoConfig = "" // Return empty if generation fails
@@ -432,9 +411,6 @@ func (r *subscriptionResolver) SchemaUpdates(ctx context.Context, ref string) (<
// Send initial state immediately
go func() {
// Use background context for async operation
bgCtx := context.Background()
services, lastUpdate := r.Cache.Services(orgId, ref, "")
r.Logger.Info("Preparing initial schema update",
"ref", ref,
@@ -445,24 +421,16 @@ func (r *subscriptionResolver) SchemaUpdates(ctx context.Context, ref string) (<
subGraphs := make([]*model.SubGraph, len(services))
for i, id := range services {
sg, err := r.fetchSubGraph(bgCtx, id)
sg, err := r.fetchSubGraph(ctx, id)
if err != nil {
r.Logger.Error("fetch subgraph for initial update", "error", err, "id", id)
continue
}
subGraphs[i] = &model.SubGraph{
ID: sg.ID.String(),
Service: sg.Service,
URL: sg.Url,
WsURL: sg.WSUrl,
Sdl: sg.Sdl,
ChangedBy: sg.ChangedBy,
ChangedAt: sg.ChangedAt,
}
subGraphs[i] = r.toGqlSubGraph(sg)
}
// Generate Cosmo router config
cosmoConfig, err := GenerateCosmoRouterConfig(subGraphs)
// Generate Cosmo router config (concurrency-limited)
cosmoConfig, err := r.CosmoGenerator.Generate(ctx, subGraphs)
if err != nil {
r.Logger.Error("generate cosmo config", "error", err)
cosmoConfig = "" // Send empty if generation fails
@@ -483,7 +451,11 @@ func (r *subscriptionResolver) SchemaUpdates(ctx context.Context, ref string) (<
"cosmoConfigLength", len(cosmoConfig),
)
ch <- update
select {
case ch <- update:
case <-ctx.Done():
return
}
}()
// Clean up subscription when context is done
+9 -26
View File
@@ -6,7 +6,6 @@ import (
"net/http"
"github.com/99designs/gqlgen/graphql"
"github.com/golang-jwt/jwt/v5"
"gitea.unbound.se/unboundsoftware/schemas/domain"
)
@@ -33,14 +32,9 @@ type AuthMiddleware struct {
func (m *AuthMiddleware) Handler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
token, err := TokenFromContext(r.Context())
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte("Invalid JWT token format"))
return
}
if token != nil {
ctx = context.WithValue(ctx, UserKey, token.Claims.(jwt.MapClaims)["sub"])
claims := ClaimsFromContext(r.Context())
if claims != nil {
ctx = context.WithValue(ctx, UserKey, claims.RegisteredClaims.Subject)
}
apiKey, err := ApiKeyFromContext(r.Context())
if err != nil {
@@ -68,29 +62,18 @@ func UserFromContext(ctx context.Context) string {
}
func UserHasRole(ctx context.Context, role string) bool {
token, err := TokenFromContext(ctx)
if err != nil || token == nil {
claims := ClaimsFromContext(ctx)
if claims == nil {
return false
}
claims, ok := token.Claims.(jwt.MapClaims)
if !ok {
customClaims, ok := claims.CustomClaims.(*CustomClaims)
if !ok || customClaims == nil {
return false
}
// Check the custom roles claim
rolesInterface, ok := claims["https://unbound.se/roles"]
if !ok {
return false
}
roles, ok := rolesInterface.([]interface{})
if !ok {
return false
}
for _, r := range roles {
if roleStr, ok := r.(string); ok && roleStr == role {
for _, r := range customClaims.Roles {
if r == role {
return true
}
}
+50 -141
View File
@@ -2,39 +2,34 @@ package middleware
import (
"context"
"crypto/tls"
"encoding/json"
"fmt"
"net/http"
"strings"
"sync"
"time"
"log"
"net/url"
mw "github.com/auth0/go-jwt-middleware/v2"
"github.com/golang-jwt/jwt/v5"
"github.com/pkg/errors"
jwtmiddleware "github.com/auth0/go-jwt-middleware/v3"
"github.com/auth0/go-jwt-middleware/v3/jwks"
"github.com/auth0/go-jwt-middleware/v3/validator"
)
// CustomClaims contains custom claims from the JWT token.
type CustomClaims struct {
Roles []string `json:"https://unbound.se/roles"`
}
// Validate implements the validator.CustomClaims interface.
func (c CustomClaims) Validate(_ context.Context) error {
return nil
}
type Auth0 struct {
domain string
audience string
client *http.Client
cache JwksCache
}
func NewAuth0(audience, domain string, strictSsl bool) *Auth0 {
customTransport := http.DefaultTransport.(*http.Transport).Clone()
customTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: !strictSsl}
client := &http.Client{Transport: customTransport}
func NewAuth0(audience, domain string, _ bool) *Auth0 {
return &Auth0{
domain: domain,
audience: audience,
client: client,
cache: JwksCache{
RWMutex: &sync.RWMutex{},
cache: make(map[string]cacheItem),
},
}
}
@@ -42,133 +37,47 @@ type Response struct {
Message string `json:"message"`
}
type Jwks struct {
Keys []JSONWebKeys `json:"keys"`
}
type JSONWebKeys struct {
Kty string `json:"kty"`
Kid string `json:"kid"`
Use string `json:"use"`
N string `json:"n"`
E string `json:"e"`
X5c []string `json:"x5c"`
}
func (a *Auth0) ValidationKeyGetter() func(token *jwt.Token) (interface{}, error) {
return func(token *jwt.Token) (interface{}, error) {
// Verify 'aud' claim
cert, err := a.getPemCert(token)
if err != nil {
panic(err.Error())
}
result, _ := jwt.ParseRSAPublicKeyFromPEM([]byte(cert))
return result, nil
}
}
func (a *Auth0) Middleware() *mw.JWTMiddleware {
func (a *Auth0) Middleware() *jwtmiddleware.JWTMiddleware {
issuer := fmt.Sprintf("https://%s/", a.domain)
jwtMiddleware := mw.New(func(ctx context.Context, token string) (interface{}, error) {
jwtToken, err := jwt.Parse(token, a.ValidationKeyGetter(), jwt.WithAudience(a.audience), jwt.WithIssuer(issuer))
if err != nil {
return nil, err
}
if _, ok := jwtToken.Method.(*jwt.SigningMethodRSA); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", jwtToken.Header["alg"])
}
return jwtToken, nil
},
mw.WithTokenExtractor(func(r *http.Request) (string, error) {
token := r.Header.Get("Authorization")
if strings.HasPrefix(token, "Bearer ") {
return token[7:], nil
}
return "", nil
issuerURL, err := url.Parse(issuer)
if err != nil {
log.Fatalf("failed to parse issuer URL: %v", err)
}
provider, err := jwks.NewCachingProvider(jwks.WithIssuerURL(issuerURL))
if err != nil {
log.Fatalf("failed to create JWKS provider: %v", err)
}
jwtValidator, err := validator.New(
validator.WithKeyFunc(provider.KeyFunc),
validator.WithAlgorithm(validator.RS256),
validator.WithIssuer(issuer),
validator.WithAudience(a.audience),
validator.WithCustomClaims(func() validator.CustomClaims {
return &CustomClaims{}
}),
mw.WithCredentialsOptional(true),
)
if err != nil {
log.Fatalf("failed to create JWT validator: %v", err)
}
jwtMiddleware, err := jwtmiddleware.New(
jwtmiddleware.WithValidator(jwtValidator),
jwtmiddleware.WithCredentialsOptional(true),
)
if err != nil {
log.Fatalf("failed to create JWT middleware: %v", err)
}
return jwtMiddleware
}
func TokenFromContext(ctx context.Context) (*jwt.Token, error) {
if value := ctx.Value(mw.ContextKey{}); value != nil {
if u, ok := value.(*jwt.Token); ok {
return u, nil
}
return nil, fmt.Errorf("token is in wrong format")
}
return nil, nil
}
func (a *Auth0) cacheGetWellknown(url string) (*Jwks, error) {
if value := a.cache.get(url); value != nil {
return value, nil
}
jwks := &Jwks{}
resp, err := a.client.Get(url)
func ClaimsFromContext(ctx context.Context) *validator.ValidatedClaims {
claims, err := jwtmiddleware.GetClaims[*validator.ValidatedClaims](ctx)
if err != nil {
return jwks, err
}
defer func() {
_ = resp.Body.Close()
}()
err = json.NewDecoder(resp.Body).Decode(jwks)
if err == nil && jwks != nil {
a.cache.put(url, jwks)
}
return jwks, err
}
func (a *Auth0) getPemCert(token *jwt.Token) (string, error) {
jwks, err := a.cacheGetWellknown(fmt.Sprintf("https://%s/.well-known/jwks.json", a.domain))
if err != nil {
return "", err
}
var cert string
for k := range jwks.Keys {
if token.Header["kid"] == jwks.Keys[k].Kid {
cert = "-----BEGIN CERTIFICATE-----\n" + jwks.Keys[k].X5c[0] + "\n-----END CERTIFICATE-----"
}
}
if cert == "" {
err := errors.New("Unable to find appropriate key.")
return cert, err
}
return cert, nil
}
type JwksCache struct {
*sync.RWMutex
cache map[string]cacheItem
}
type cacheItem struct {
data *Jwks
expiration time.Time
}
func (c *JwksCache) get(url string) *Jwks {
c.RLock()
defer c.RUnlock()
if value, ok := c.cache[url]; ok {
if time.Now().After(value.expiration) {
return nil
}
return value.data
}
return nil
}
func (c *JwksCache) put(url string, jwks *Jwks) {
c.Lock()
defer c.Unlock()
c.cache[url] = cacheItem{
data: jwks,
expiration: time.Now().Add(time.Minute * 60),
return nil
}
return claims
}
+73 -71
View File
@@ -6,8 +6,8 @@ import (
"net/http/httptest"
"testing"
mw "github.com/auth0/go-jwt-middleware/v2"
"github.com/golang-jwt/jwt/v5"
"github.com/auth0/go-jwt-middleware/v3/core"
"github.com/auth0/go-jwt-middleware/v3/validator"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
@@ -155,9 +155,11 @@ func TestAuthMiddleware_Handler_WithValidJWT(t *testing.T) {
mockCache.On("OrganizationByAPIKey", "").Return(nil)
userID := "user-123"
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"sub": userID,
})
claims := &validator.ValidatedClaims{
RegisteredClaims: validator.RegisteredClaims{
Subject: userID,
},
}
// Create a test handler that checks the context
var capturedUser string
@@ -170,9 +172,9 @@ func TestAuthMiddleware_Handler_WithValidJWT(t *testing.T) {
w.WriteHeader(http.StatusOK)
})
// Create request with JWT token in context
// Create request with JWT claims in context
req := httptest.NewRequest(http.MethodGet, "/test", nil)
ctx := context.WithValue(req.Context(), mw.ContextKey{}, token)
ctx := core.SetClaims(req.Context(), claims)
req = req.WithContext(ctx)
rec := httptest.NewRecorder()
@@ -209,28 +211,35 @@ func TestAuthMiddleware_Handler_APIKeyErrorHandling(t *testing.T) {
assert.Contains(t, rec.Body.String(), "Invalid API Key format")
}
func TestAuthMiddleware_Handler_JWTErrorHandling(t *testing.T) {
func TestAuthMiddleware_Handler_JWTMissingClaims(t *testing.T) {
// Setup
mockCache := new(MockCache)
authMiddleware := NewAuth(mockCache)
// The middleware passes the plaintext API key (cache handles hashing)
mockCache.On("OrganizationByAPIKey", "").Return(nil)
// Create a test handler that checks the context
var capturedUser string
testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if user := r.Context().Value(UserKey); user != nil {
if u, ok := user.(string); ok {
capturedUser = u
}
}
w.WriteHeader(http.StatusOK)
})
// Create request with invalid JWT token type in context
// Create request without JWT claims - user should not be set
req := httptest.NewRequest(http.MethodGet, "/test", nil)
ctx := context.WithValue(req.Context(), mw.ContextKey{}, "not-a-token") // Invalid type
req = req.WithContext(ctx)
rec := httptest.NewRecorder()
// Execute
authMiddleware.Handler(testHandler).ServeHTTP(rec, req)
// Assert
assert.Equal(t, http.StatusInternalServerError, rec.Code)
assert.Contains(t, rec.Body.String(), "Invalid JWT token format")
assert.Equal(t, http.StatusOK, rec.Code)
assert.Empty(t, capturedUser, "User should not be set when no claims in context")
}
func TestAuthMiddleware_Handler_BothJWTAndAPIKey(t *testing.T) {
@@ -249,9 +258,11 @@ func TestAuthMiddleware_Handler_BothJWTAndAPIKey(t *testing.T) {
userID := "user-123"
apiKey := "test-api-key-123"
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"sub": userID,
})
claims := &validator.ValidatedClaims{
RegisteredClaims: validator.RegisteredClaims{
Subject: userID,
},
}
// Mock expects plaintext key (cache handles hashing internally)
mockCache.On("OrganizationByAPIKey", apiKey).Return(expectedOrg)
@@ -273,9 +284,9 @@ func TestAuthMiddleware_Handler_BothJWTAndAPIKey(t *testing.T) {
w.WriteHeader(http.StatusOK)
})
// Create request with both JWT and API key in context
// Create request with both JWT claims and API key in context
req := httptest.NewRequest(http.MethodGet, "/test", nil)
ctx := context.WithValue(req.Context(), mw.ContextKey{}, token)
ctx := core.SetClaims(req.Context(), claims)
ctx = context.WithValue(ctx, ApiKey, apiKey)
req = req.WithContext(ctx)
@@ -475,13 +486,17 @@ func TestAuthMiddleware_Directive_NoRequirements(t *testing.T) {
}
func TestUserHasRole_WithValidRole(t *testing.T) {
// Create token with roles claim
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"sub": "user-123",
"https://unbound.se/roles": []interface{}{"admin", "user"},
})
// Create claims with roles
claims := &validator.ValidatedClaims{
RegisteredClaims: validator.RegisteredClaims{
Subject: "user-123",
},
CustomClaims: &CustomClaims{
Roles: []string{"admin", "user"},
},
}
ctx := context.WithValue(context.Background(), mw.ContextKey{}, token)
ctx := core.SetClaims(context.Background(), claims)
// Test for existing role
hasRole := UserHasRole(ctx, "admin")
@@ -492,13 +507,17 @@ func TestUserHasRole_WithValidRole(t *testing.T) {
}
func TestUserHasRole_WithoutRole(t *testing.T) {
// Create token with roles claim
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"sub": "user-123",
"https://unbound.se/roles": []interface{}{"user"},
})
// Create claims with roles
claims := &validator.ValidatedClaims{
RegisteredClaims: validator.RegisteredClaims{
Subject: "user-123",
},
CustomClaims: &CustomClaims{
Roles: []string{"user"},
},
}
ctx := context.WithValue(context.Background(), mw.ContextKey{}, token)
ctx := core.SetClaims(context.Background(), claims)
// Test for non-existing role
hasRole := UserHasRole(ctx, "admin")
@@ -506,59 +525,42 @@ func TestUserHasRole_WithoutRole(t *testing.T) {
}
func TestUserHasRole_WithoutRolesClaim(t *testing.T) {
// Create token without roles claim
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"sub": "user-123",
})
// Create claims without custom claims
claims := &validator.ValidatedClaims{
RegisteredClaims: validator.RegisteredClaims{
Subject: "user-123",
},
}
ctx := context.WithValue(context.Background(), mw.ContextKey{}, token)
ctx := core.SetClaims(context.Background(), claims)
// Test should return false when roles claim is missing
// Test should return false when custom claims is missing
hasRole := UserHasRole(ctx, "admin")
assert.False(t, hasRole)
}
func TestUserHasRole_WithoutToken(t *testing.T) {
func TestUserHasRole_WithoutClaims(t *testing.T) {
ctx := context.Background()
// Test should return false when no token in context
// Test should return false when no claims in context
hasRole := UserHasRole(ctx, "admin")
assert.False(t, hasRole)
}
func TestUserHasRole_WithInvalidTokenType(t *testing.T) {
// Put invalid token type in context
ctx := context.WithValue(context.Background(), mw.ContextKey{}, "not-a-token")
func TestUserHasRole_WithEmptyRoles(t *testing.T) {
// Create claims with empty roles
claims := &validator.ValidatedClaims{
RegisteredClaims: validator.RegisteredClaims{
Subject: "user-123",
},
CustomClaims: &CustomClaims{
Roles: []string{},
},
}
// Test should return false when token type is invalid
hasRole := UserHasRole(ctx, "admin")
assert.False(t, hasRole)
}
func TestUserHasRole_WithInvalidRolesType(t *testing.T) {
// Create token with invalid roles type
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"sub": "user-123",
"https://unbound.se/roles": "not-an-array",
})
ctx := context.WithValue(context.Background(), mw.ContextKey{}, token)
// Test should return false when roles type is invalid
hasRole := UserHasRole(ctx, "admin")
assert.False(t, hasRole)
}
func TestUserHasRole_WithInvalidRoleElementType(t *testing.T) {
// Create token with invalid role element types
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"sub": "user-123",
"https://unbound.se/roles": []interface{}{123, 456}, // Numbers instead of strings
})
ctx := context.WithValue(context.Background(), mw.ContextKey{}, token)
// Test should return false when role elements are not strings
ctx := core.SetClaims(context.Background(), claims)
// Test should return false when roles array is empty
hasRole := UserHasRole(ctx, "admin")
assert.False(t, hasRole)
}