From a21c77c718a34fd9d694de8969bfc9cd811eda0f Mon Sep 17 00:00:00 2001 From: Christian Nicola Date: Wed, 23 Jul 2025 17:15:42 +0200 Subject: [PATCH 01/11] feat: (nix) add flake CBR-14 --- .gitignore | 4 +- .mockery.yaml | 6 +- default.nix | 21 +++++++ flake.lock | 85 +++++++++++++++++++++++++ flake.nix | 39 ++++++++++++ go.mod | 51 +-------------- go.sum | 153 -------------------------------------------- gomod2nix.toml | 168 +++++++++++++++++++++++++++++++++++++++++++++++++ shell.nix | 66 +++++++++++++++++++ 9 files changed, 386 insertions(+), 207 deletions(-) create mode 100644 default.nix create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 gomod2nix.toml create mode 100644 shell.nix diff --git a/.gitignore b/.gitignore index 81aafcb..622435b 100644 --- a/.gitignore +++ b/.gitignore @@ -29,4 +29,6 @@ go.work.sum # build artifacts bin -reports \ No newline at end of file +reports +data +result diff --git a/.mockery.yaml b/.mockery.yaml index 3263dbd..114077e 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -1,8 +1,6 @@ -with-expecter: true -dir: testing/mocks/{{ replaceAll .InterfaceDirRelative "internal" "internal_"}} +dir: testing/mocks filename: "{{.InterfaceName}}.go" -mockname: "Mock{{.InterfaceName}}" -outpkg: "{{.PackageName}}" +pkgname: "mocks" all: true recursive: true packages: diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..0f5cdc6 --- /dev/null +++ b/default.nix @@ -0,0 +1,21 @@ +{ pkgs ? ( + let + inherit (builtins) fetchTree fromJSON readFile; + inherit ((fromJSON (readFile ./flake.lock)).nodes) nixpkgs gomod2nix; + in + import (fetchTree nixpkgs.locked) { + overlays = [ + (import "${fetchTree gomod2nix.locked}/overlay.nix") + ]; + } + ) +, buildGoApplication ? pkgs.buildGoApplication +}: + +buildGoApplication { + pname = "growteer-api"; + version = "0.1"; + src = ./.; + subPackages = [ "cmd/growteer-api" ]; + modules = ./gomod2nix.toml; +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..124db50 --- /dev/null +++ b/flake.lock @@ -0,0 +1,85 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "gomod2nix": { + "inputs": { + "flake-utils": [ + "flake-utils" + ], + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1753096219, + "narHash": "sha256-MaaWYgN/nia7xJcOYLBtPk+cFo7X2zEM1d9xIGPQrLU=", + "owner": "nix-community", + "repo": "gomod2nix", + "rev": "be828766411cad04c194c8f714d46aa2b2596362", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "gomod2nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1752950548, + "narHash": "sha256-NS6BLD0lxOrnCiEOcvQCDVPXafX1/ek1dfJHX1nUIzc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "c87b95e25065c028d31a94f06a62927d18763fdf", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "gomod2nix": "gomod2nix", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..ea234eb --- /dev/null +++ b/flake.nix @@ -0,0 +1,39 @@ +{ + description = "Growteer Backend Flake"; + + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + inputs.flake-utils.url = "github:numtide/flake-utils"; + inputs.gomod2nix.url = "github:nix-community/gomod2nix"; + inputs.gomod2nix.inputs.nixpkgs.follows = "nixpkgs"; + inputs.gomod2nix.inputs.flake-utils.follows = "flake-utils"; + + outputs = + { self + , nixpkgs + , flake-utils + , gomod2nix + , + }: + (flake-utils.lib.eachDefaultSystem ( + system: + let + pkgs = import nixpkgs { + config.allowUnfree = true; + inherit system; + }; + + # The current default sdk for macOS fails to compile go projects, so we use a newer one for now. + # This has no effect on other platforms. + callPackage = pkgs.darwin.apple_sdk_11_0.callPackage or pkgs.callPackage; + + in + { + packages.default = callPackage ./. { + inherit (gomod2nix.legacyPackages.${system}) buildGoApplication; + }; + devShells.default = callPackage ./shell.nix { + inherit (gomod2nix.legacyPackages.${system}) mkGoEnv gomod2nix; + }; + } + )); +} diff --git a/go.mod b/go.mod index a7eb1b6..bc0d2d8 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/growteer/api -go 1.23.4 +go 1.24.4 replace gopkg.in/yaml.v2 v2.4.0 => gopkg.in/yaml.v3 v3.0.0 @@ -17,8 +17,6 @@ require ( github.com/mr-tron/base58 v1.2.0 github.com/rs/cors v1.11.1 github.com/stretchr/testify v1.10.0 - github.com/testcontainers/testcontainers-go v0.35.0 - github.com/testcontainers/testcontainers-go/modules/mongodb v0.35.0 github.com/vektah/gqlparser/v2 v2.5.20 github.com/vrischmann/envconfig v1.3.0 go.mongodb.org/mongo-driver v1.17.1 @@ -26,32 +24,14 @@ require ( ) require ( - dario.cat/mergo v1.0.0 // indirect filippo.io/edwards25519 v1.0.0-rc.1 // indirect - github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect - github.com/Microsoft/go-winio v0.6.2 // indirect github.com/agnivade/levenshtein v1.2.0 // indirect github.com/blendle/zapdriver v1.3.1 // indirect - github.com/cenkalti/backoff/v4 v4.2.1 // indirect - github.com/containerd/containerd v1.7.27 // indirect - github.com/containerd/log v0.1.0 // indirect - github.com/containerd/platforms v0.2.1 // indirect - github.com/cpuguy83/dockercfg v0.3.2 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/distribution/reference v0.6.0 // indirect - github.com/docker/docker v27.1.1+incompatible // indirect - github.com/docker/go-connections v0.5.0 // indirect - github.com/docker/go-units v0.5.0 // indirect github.com/fatih/color v1.16.0 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect github.com/gagliardetto/binary v0.8.0 // indirect github.com/gagliardetto/treeout v0.1.4 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-viper/mapstructure/v2 v2.3.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect @@ -60,57 +40,30 @@ require ( github.com/klauspost/compress v1.17.4 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/logrusorgru/aurora v2.0.3+incompatible // indirect - github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect - github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect - github.com/moby/docker-image-spec v1.3.1 // indirect - github.com/moby/patternmatcher v0.6.0 // indirect - github.com/moby/sys/sequential v0.5.0 // indirect - github.com/moby/sys/user v0.3.0 // indirect - github.com/moby/sys/userns v0.1.0 // indirect - github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/montanaflynn/stats v0.7.1 // indirect - github.com/morikuni/aec v1.0.0 // indirect github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/shirou/gopsutil/v3 v3.23.12 // indirect - github.com/shoenig/go-m1cpu v0.1.6 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect github.com/sosodev/duration v1.3.1 // indirect github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/tklauser/go-sysconf v0.3.12 // indirect - github.com/tklauser/numcpus v0.6.1 // indirect - github.com/urfave/cli/v2 v2.27.5 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect - github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect - github.com/yusufpapurcu/wmi v1.2.3 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect - go.opentelemetry.io/otel v1.24.0 // indirect - go.opentelemetry.io/otel/metric v1.24.0 // indirect - go.opentelemetry.io/otel/trace v1.24.0 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/goleak v1.1.12 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.21.0 // indirect golang.org/x/crypto v0.36.0 // indirect - golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.12.0 // indirect golang.org/x/sys v0.31.0 // indirect golang.org/x/term v0.30.0 // indirect golang.org/x/text v0.23.0 // indirect - golang.org/x/tools v0.24.0 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 0234cd4..a4f5f41 100644 --- a/go.sum +++ b/go.sum @@ -1,15 +1,7 @@ -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= github.com/99designs/gqlgen v0.17.60 h1:xxl7kQDCNw79itzWQtCUSXgkovCyq9r+ogSXfZpKPYM= github.com/99designs/gqlgen v0.17.60/go.mod h1:vQJzWXyGya2TYL7cig1G4OaCQzyck031MgYBlUwaI9I= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/PuerkitoBio/goquery v1.9.3 h1:mpJr/ikUA9/GNJB/DBZcGeFDXUtosHRyRrwh7KGdTG0= github.com/PuerkitoBio/goquery v1.9.3/go.mod h1:1ndLHPdTz+DyQPICCWYlYQMPl0oXZj0G6D4LCYA6u4U= github.com/agnivade/levenshtein v1.2.0 h1:U9L4IOT0Y3i0TIlUIDJ7rVUziKi/zPbrJGaFrtYH3SY= @@ -24,38 +16,14 @@ github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLj github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= -github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= -github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/containerd/containerd v1.7.27 h1:yFyEyojddO3MIGVER2xJLWoCIn+Up4GaHFquP7hsFII= -github.com/containerd/containerd v1.7.27/go.mod h1:xZmPnl75Vc+BLGt4MIfu6bp+fy03gdHAn9bz+FreFR0= -github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= -github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= -github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= -github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA= -github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= -github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= -github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= -github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= 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/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54 h1:SG7nF6SRlWhcT7cNTs5R6Hk4V2lcmLz2NsG2VnInyNo= github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= -github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= -github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY= -github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= -github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/gagliardetto/binary v0.8.0 h1:U9ahc45v9HW0d15LoN++vIXSJyqR/pWw8DDlhd7zvxg= github.com/gagliardetto/binary v0.8.0/go.mod h1:2tfj51g5o9dnvsc+fL3Jxr22MuWzYXwx9wEoN0XQ7/c= github.com/gagliardetto/solana-go v1.12.0 h1:rzsbilDPj6p+/DOPXBMLhwMZeBgeRuXjm5zQFCoXgsg= @@ -64,23 +32,12 @@ github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdF github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= github.com/go-chi/chi/v5 v5.2.2 h1:CMwsvRVTbXVytCk1Wd72Zy1LAsAh9GxMmSNWLHCG618= github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= -github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-viper/mapstructure/v2 v2.3.0 h1:27XbWsHIqhbdR5TIC911OfYvgSaW93HM+dX7970Q7jk= github.com/go-viper/mapstructure/v2 v2.3.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -88,16 +45,12 @@ 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.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= 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/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= @@ -111,28 +64,12 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= -github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= -github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= -github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= -github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= -github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= -github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo= -github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= -github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= -github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= -github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= -github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -140,72 +77,39 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 h1:mPMvm6X6tf4w8y7j9YIt6V9jfWhL6QlbEc7CCmeQlWk= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1/go.mod h1:ye2e/VUEtE2BHE+G/QcKkcLQVAEJoYRFj5VUOQatCRE= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= -github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= -github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 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= -github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4= -github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM= -github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= -github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= -github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= -github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sosodev/duration v1.3.1 h1:qtHBDMQ6lvMQsL15g4aopM4HEfOaYuhWBw3NPTtlqq4= github.com/sosodev/duration v1.3.1/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091 h1:RN5mrigyirb8anBEtdjtHFIufXdacyTi6i4KBfeNXeo= github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091/go.mod h1:VlduQ80JcGJSargkRU4Sg9Xo63wZD/l8A5NC/Uo1/uU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 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.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE= github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU= -github.com/testcontainers/testcontainers-go v0.35.0 h1:uADsZpTKFAtp8SLK+hMwSaa+X+JiERHtd4sQAFmXeMo= -github.com/testcontainers/testcontainers-go v0.35.0/go.mod h1:oEVBj5zrfJTrgjwONs1SsRbnBtH9OKl+IGl3UMcr2B4= -github.com/testcontainers/testcontainers-go/modules/mongodb v0.35.0 h1:i1Kh9fmXgHG9z3uzJv5Arz7pDKVaaNpLrqyd+0xhYMA= -github.com/testcontainers/testcontainers-go/modules/mongodb v0.35.0/go.mod h1:SD8nVMK1m7b/K2YJqYjYNzfHmZfqHtqNOlI44nfxjdg= -github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= -github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= -github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= -github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= -github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= -github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= github.com/vektah/gqlparser/v2 v2.5.20 h1:kPaWbhBntxoZPaNdBaIPT1Kh0i1b/onb5kXgEdP5JCo= github.com/vektah/gqlparser/v2 v2.5.20/go.mod h1:xMl+ta8a5M1Yo1A1Iwt/k7gSpscwSnHZdw7tfhEGfTM= github.com/vrischmann/envconfig v1.3.0 h1:4XIvQTXznxmWMnjouj0ST5lFo/WAYf5Exgl3x82crEk= @@ -216,34 +120,12 @@ github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= -github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= -github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= -github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.mongodb.org/mongo-driver v1.17.1 h1:Wic5cJIwJgSpBhe3lx3+/RybR5PiYRMpVFgO7cOHyIM= go.mongodb.org/mongo-driver v1.17.1/go.mod h1:wwWm/+BuOddhcq3n68LKRmgk2wXzmF6s0SFOa0GINL4= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= -go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= -go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= -go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= -go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= -go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= -go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= -go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= -go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= -go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -258,23 +140,16 @@ go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -282,30 +157,20 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -319,30 +184,14 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3 h1:1hfbdAfFbkmpg41000wDVqr7jUpK/Yo+LPnIxxGzmkg= -google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 h1:RFiFrvy37/mpSpdySBDrUdipW/dHwsRwh3J3+A9VgT4= -google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= -google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= -google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= -google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= -google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -356,5 +205,3 @@ gopkg.in/yaml.v3 v3.0.0 h1:hjy8E9ON/egN1tAYqKb61G10WtihqetD4sz2H+8nIeA= gopkg.in/yaml.v3 v3.0.0/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= -gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= -gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= diff --git a/gomod2nix.toml b/gomod2nix.toml new file mode 100644 index 0000000..393c646 --- /dev/null +++ b/gomod2nix.toml @@ -0,0 +1,168 @@ +schema = 3 + +[mod] + [mod."filippo.io/edwards25519"] + version = "v1.0.0-rc.1" + hash = "sha256-3DboBqby2ejRU33FG96Z8JF5AJ8HP2rC/v++VyoQ2LQ=" + [mod."github.com/99designs/gqlgen"] + version = "v0.17.60" + hash = "sha256-F4oS6rz18zjqYu2WEFrWwOauir8QA5F9MhDMbvJVkwM=" + [mod."github.com/agnivade/levenshtein"] + version = "v1.2.0" + hash = "sha256-Fg6SxKFiJL5xqnVsiLsCcp6XasbBiIuxNWljMpNU6W0=" + [mod."github.com/blendle/zapdriver"] + version = "v1.3.1" + hash = "sha256-SSRaX/YcLFRf3BD/TGjpupGQ0HxFdP1SHyrZNw767IQ=" + [mod."github.com/davecgh/go-spew"] + version = "v1.1.1" + hash = "sha256-nhzSUrE1fCkN0+RL04N4h8jWmRFPPPWbCuDc7Ss0akI=" + [mod."github.com/fatih/color"] + version = "v1.16.0" + hash = "sha256-Aq/SM28aPJVzvapllQ64R/DM4aZ5CHPewcm/AUJPyJQ=" + replaced = "github.com/fatih/color" + [mod."github.com/gagliardetto/binary"] + version = "v0.8.0" + hash = "sha256-Szn+6wdBfOHPNxXCHL8roOirkGnhyWntz405HxtLbic=" + [mod."github.com/gagliardetto/solana-go"] + version = "v1.12.0" + hash = "sha256-+Ksz4QU/PLQ9n+DNWKl8w506uTVCgRmulItBZr0wx+0=" + [mod."github.com/gagliardetto/treeout"] + version = "v0.1.4" + hash = "sha256-odFC2amCEPmZvdK4lfuox2njpt6fqIR0Z0eRtWlDxAM=" + [mod."github.com/go-chi/chi/v5"] + version = "v5.2.2" + hash = "sha256-F+KxLJNRQxkjQCDlJ72MT/YS8cybKPsLeWOjo6HqJHU=" + [mod."github.com/go-viper/mapstructure/v2"] + version = "v2.3.0" + hash = "sha256-1aAH3Iqp8ntSFoMT1NrgDBaKJ6UOjw/1/dzePIF2nR4=" + [mod."github.com/golang-jwt/jwt/v5"] + version = "v5.2.2" + hash = "sha256-C0MhDguxWR6dQUrNVQ5xaFUReSV6CVEBAijG3b4wnX4=" + [mod."github.com/golang/snappy"] + version = "v0.0.5-0.20220116011046-fa5810519dcb" + hash = "sha256-4GVLPBwJIXYFJU+Uvoa/sb5VHea7yJhwE7feABa7ucs=" + [mod."github.com/google/uuid"] + version = "v1.6.0" + hash = "sha256-VWl9sqUzdOuhW0KzQlv0gwwUQClYkmZwSydHG2sALYw=" + [mod."github.com/gorilla/websocket"] + version = "v1.5.0" + hash = "sha256-EYVgkSEMo4HaVrsWKqnsYRp8SSS8gNf7t+Elva02Ofc=" + [mod."github.com/hashicorp/golang-lru/v2"] + version = "v2.0.7" + hash = "sha256-t1bcXLgrQNOYUVyYEZ0knxcXpsTk4IuJZDjKvyJX75g=" + [mod."github.com/joho/godotenv"] + version = "v1.5.1" + hash = "sha256-kA0osKfsc6Kp+nuGTRJyXZZlJt1D/kuEazKMWYCWcQ8=" + [mod."github.com/json-iterator/go"] + version = "v1.1.12" + hash = "sha256-To8A0h+lbfZ/6zM+2PpRpY3+L6725OPC66lffq6fUoM=" + [mod."github.com/klauspost/compress"] + version = "v1.17.4" + hash = "sha256-5E7dDtDKfL3jy7zJxHBMV57WlHZrP/OoEX5e6cOPba0=" + [mod."github.com/kr/pretty"] + version = "v0.3.1" + hash = "sha256-DlER7XM+xiaLjvebcIPiB12oVNjyZHuJHoRGITzzpKU=" + [mod."github.com/logrusorgru/aurora"] + version = "v2.0.3+incompatible" + hash = "sha256-7o5Fh4jscdYKgXfnNMbcD68Kjw8Z4LcPgHcr4ZyQYrI=" + [mod."github.com/mattn/go-colorable"] + version = "v0.1.14" + hash = "sha256-JC60PjKj7MvhZmUHTZ9p372FV72I9Mxvli3fivTbxuA=" + replaced = "github.com/mattn/go-colorable" + [mod."github.com/mattn/go-isatty"] + version = "v0.0.20" + hash = "sha256-qhw9hWtU5wnyFyuMbKx+7RB8ckQaFQ8D+8GKPkN3HHQ=" + [mod."github.com/mitchellh/go-testing-interface"] + version = "v1.14.1" + hash = "sha256-TMGi38D13BEVN5cpeKDzKRIgLclm4ErOG+JEyqJrN/c=" + [mod."github.com/modern-go/concurrent"] + version = "v0.0.0-20180306012644-bacd9c7ef1dd" + hash = "sha256-OTySieAgPWR4oJnlohaFTeK1tRaVp/b0d1rYY8xKMzo=" + [mod."github.com/modern-go/reflect2"] + version = "v1.0.2" + hash = "sha256-+W9EIW7okXIXjWEgOaMh58eLvBZ7OshW2EhaIpNLSBU=" + [mod."github.com/montanaflynn/stats"] + version = "v0.7.1" + hash = "sha256-0QXUA/syOtDSBooh3isAffrVAjpSoBmSMMuZfO5maHg=" + [mod."github.com/mostynb/zstdpool-freelist"] + version = "v0.0.0-20201229113212-927304c0c3b1" + hash = "sha256-P9ksvx6IcHo4L44PDcSpt6BWowPwkiIB6P0blB84MZc=" + [mod."github.com/mr-tron/base58"] + version = "v1.2.0" + hash = "sha256-8FzMu3kHUbBX10pUdtGf59Ag7BNupx8ZHeUaodR1/Vk=" + [mod."github.com/pmezard/go-difflib"] + version = "v1.0.0" + hash = "sha256-/FtmHnaGjdvEIKAJtrUfEhV7EVo5A/eYrtdnUkuxLDA=" + [mod."github.com/rs/cors"] + version = "v1.11.1" + hash = "sha256-0z4aFR5VjuVYn+XnANbjui0ADcdG7gU56A9Y/NtrzCQ=" + [mod."github.com/sosodev/duration"] + version = "v1.3.1" + hash = "sha256-4TQS0p7FjTztG7P3VJDEaWLHHEOUADFwgEswuh/obb0=" + [mod."github.com/streamingfast/logging"] + version = "v0.0.0-20230608130331-f22c91403091" + hash = "sha256-ucpmtSeDGcV6HHCvE782XhkaZe4xKieWFdmVaA9PDjA=" + [mod."github.com/stretchr/objx"] + version = "v0.5.2" + hash = "sha256-VKYxrrFb1nkX6Wu3tE5DoP9+fCttwSl9pgLN6567nck=" + [mod."github.com/stretchr/testify"] + version = "v1.10.0" + hash = "sha256-fJ4gnPr0vnrOhjQYQwJ3ARDKPsOtA7d4olQmQWR+wpI=" + [mod."github.com/vektah/gqlparser/v2"] + version = "v2.5.20" + hash = "sha256-jkHpt9vF+QSAdN7kNLoIr6vViMFOvbGxI8feZbuOwF0=" + [mod."github.com/vrischmann/envconfig"] + version = "v1.3.0" + hash = "sha256-OLPild6/eKWBOCrBHUlNY1MS1l+8QBLfsNVC66fD8LY=" + [mod."github.com/xdg-go/pbkdf2"] + version = "v1.0.0" + hash = "sha256-UKK8JrdxEeToqs53sUUMUZNQv8w+lzuhd7bNXryMN9o=" + [mod."github.com/xdg-go/scram"] + version = "v1.1.2" + hash = "sha256-BPlloFojiFA8TiYIaBPW9BFBNkCmYD68JrY5gry1f64=" + [mod."github.com/xdg-go/stringprep"] + version = "v1.0.4" + hash = "sha256-zGNSty2K8PoqMw71AHPvICuUvIzXzUvCW+fCNr3XmLE=" + [mod."github.com/youmark/pkcs8"] + version = "v0.0.0-20240726163527-a2c0da244d78" + hash = "sha256-7ETUt8onE9mdUlvHT5xxzfh8mK0qw15ZSYXQCtah9p4=" + [mod."go.mongodb.org/mongo-driver"] + version = "v1.17.1" + hash = "sha256-/0TG8G5SHfaRPnCH9L2Nc73JnhZZhb64TJ1pz1x2sHk=" + [mod."go.uber.org/atomic"] + version = "v1.7.0" + hash = "sha256-g83RSzO/5k8W3qyiIsrQbVq1F8qJGccdWEXTjkqUOfc=" + [mod."go.uber.org/goleak"] + version = "v1.1.12" + hash = "sha256-7++AVgDu59zNKqxEQHnao2bLmHlU5Pum3nbhXtoaqvE=" + [mod."go.uber.org/multierr"] + version = "v1.6.0" + hash = "sha256-X+l7OPAkMhpw+5VvFWuQ/DfTCSjQH/8VvSoQrb44CEU=" + [mod."go.uber.org/zap"] + version = "v1.21.0" + hash = "sha256-ZqIYkENfis3vlN4Z1Ejdn9Nn0pU89tHtcAYcR+b2Kb0=" + [mod."golang.org/x/crypto"] + version = "v0.36.0" + hash = "sha256-Np+suvZdMOXALDm4m8nDNa+QsvUV0rE0PEINuxCoKGM=" + [mod."golang.org/x/net"] + version = "v0.38.0" + hash = "sha256-iHmyxkZQLw1PsUZaXHMt84GrjbXPvkEc92sLoK3W++c=" + [mod."golang.org/x/sync"] + version = "v0.12.0" + hash = "sha256-lPIbI6aXx+iKtFjPaXKNLEnuNfhHCVl7EQiE7alUvlM=" + [mod."golang.org/x/sys"] + version = "v0.31.0" + hash = "sha256-aulv5obCrhheMlSq7seUgP3C29nfZABwiQ4IBNisgME=" + [mod."golang.org/x/term"] + version = "v0.30.0" + hash = "sha256-bgN4cMED7P2SqFZQZPNRPJL2Px35chNoWaqNhLDEoZM=" + [mod."golang.org/x/text"] + version = "v0.23.0" + hash = "sha256-TiYX1K4DYpP1dEV06whOm43xyOntjrPFi+VAdncoeCY=" + [mod."gopkg.in/check.v1"] + version = "v1.0.0-20201130134442-10cb98267c6c" + hash = "sha256-VlIpM2r/OD+kkyItn6vW35dyc0rtkJufA93rjFyzncs=" + [mod."gopkg.in/yaml.v2"] + version = "v3.0.1" + hash = "sha256-FqL9TKYJ0XkNwJFnq9j0VvJ5ZUU1RvH/52h/f5bkYAU=" + replaced = "gopkg.in/yaml.v3" diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..efc196d --- /dev/null +++ b/shell.nix @@ -0,0 +1,66 @@ +{ pkgs ? ( + let + inherit (builtins) fetchTree fromJSON readFile; + inherit ((fromJSON (readFile ./flake.lock)).nodes) nixpkgs gomod2nix; + in + import (fetchTree nixpkgs.locked) { + overlays = [ + (import "${fetchTree gomod2nix.locked}/overlay.nix") + ]; + } + ) +, mkGoEnv ? pkgs.mkGoEnv +, gomod2nix ? pkgs.gomod2nix +, mongodb ? pkgs.mongodb +, mongosh ? pkgs.mongosh +, gqlgen ? pkgs.gqlgen +, golangci-lint ? pkgs.golangci-lint +, go-mockery ? pkgs.go-mockery +, go-junit-report ? pkgs.go-junit-report +, gopls ? pkgs.gopls +}: + +let + goEnv = mkGoEnv { pwd = ./.; }; +in +pkgs.mkShell { + packages = [ + goEnv + gomod2nix + mongodb + mongosh + gqlgen + golangci-lint + go-mockery + go-junit-report + gopls + ]; + + env = { + MONGODB_URI = "mongodb://localhost:27017/?directConnection=true"; + MONGODB_DATABASE = "growteer"; + JWT_SECRET = "baconkilbasa"; + ALLOWED_ORIGINS = "http://localhost:5173"; + HTTP_PORT = "8080"; + SESSION_TTL_MINUTES = "60"; + }; + + shellHook = '' + # Create necessary directories + mkdir -p ./data/db + mkdir -p ./data/log + + # Start MongoDB as a service + echo "Starting MongoDB..." + mongod --quiet --fork --logpath ./data/log/mongod.log --dbpath ./data/db + + # Cleanup command to stop MongoDB when exiting the shell + trap 'echo "Stopping MongoDB..."; mongod --quiet --shutdown --dbpath ./data/db' EXIT + + echo "Connect to mongodb with:" + echo "Connection URI: $MONGODB_URL" + echo "Database Name: $MONGODB_DATABASE" + echo "" + echo "JWS secret: $JWT_SECRET" + ''; +} From 28dcaaf860d6df4780518e302e87d5d1dee74137 Mon Sep 17 00:00:00 2001 From: Christian Nicola Date: Wed, 23 Jul 2025 17:16:28 +0200 Subject: [PATCH 02/11] chore: (project) add Makefile & editorconfig CBR-14 --- .editorconfig | 17 +++++++++++++++++ Makefile | 16 ++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 .editorconfig create mode 100644 Makefile diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..643483e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +root = true + +# Unix-style newlines with a newline ending every file, UTF-8 charset +[*] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +charset = utf-8 + +# Match Nix files, set indent to spaces with width of two +[*.nix] +indent_style = space +indent_size = 2 + +[*.go] +indent_style = tab +indent_size = 4 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8c62310 --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +.PHONY: lint +lint: + @golangci-lint run + +.PHONY: test +test: + @mkdir -p reports + @go test -v -covermode=atomic -coverprofile=reports/coverage.out ./... | tee reports/test-result.out + @go-junit-report < reports/test-result.out > reports/junit-report.xml + @go tool cover -html=reports/coverage.out -o reports/coverage.html + +.PHONY: gen +gen: + @gqlgen generate + @mockery + @go generate ./... From afb886b918a83214a7814b01ef75189936e88f62 Mon Sep 17 00:00:00 2001 From: Christian Nicola Date: Wed, 23 Jul 2025 17:16:54 +0200 Subject: [PATCH 03/11] chore: (project): improbe sub-command structure CBR-14 --- cmd/{ => growteer-api}/main.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename cmd/{ => growteer-api}/main.go (100%) diff --git a/cmd/main.go b/cmd/growteer-api/main.go similarity index 100% rename from cmd/main.go rename to cmd/growteer-api/main.go From 8822f45084a697fb67532b252f61161f43129c88 Mon Sep 17 00:00:00 2001 From: Christian Nicola Date: Wed, 23 Jul 2025 18:04:36 +0200 Subject: [PATCH 04/11] chore: (api) change mongodb configuration & test setup - it's usually better to just use a predefined uri instead of building your own. this patch removes the mongodb parameters and accepts a uri now instead. - remove testcontainers; no longer necessary, we have a working database right in our development shell. CBR-14 --- internal/api/graphql/authn.resolvers_test.go | 67 ++++++------- .../api/graphql/profile.resolvers_test.go | 51 +++++----- internal/api/server.go | 4 +- .../infrastructure/environment/environment.go | 36 ++++--- internal/infrastructure/mongodb/client.go | 7 +- testing/testcontainer/mongodb.go | 93 ------------------- tools/tools.go | 5 - 7 files changed, 73 insertions(+), 190 deletions(-) delete mode 100644 testing/testcontainer/mongodb.go delete mode 100644 tools/tools.go diff --git a/internal/api/graphql/authn.resolvers_test.go b/internal/api/graphql/authn.resolvers_test.go index f75c5d6..cbc2ede 100644 --- a/internal/api/graphql/authn.resolvers_test.go +++ b/internal/api/graphql/authn.resolvers_test.go @@ -10,11 +10,11 @@ import ( "github.com/growteer/api/internal/api/graphql" "github.com/growteer/api/internal/api/graphql/model" "github.com/growteer/api/internal/app/shared/apperrors" + "github.com/growteer/api/internal/infrastructure/environment" "github.com/growteer/api/internal/infrastructure/mongodb" "github.com/growteer/api/pkg/web3util" "github.com/growteer/api/testing/fixtures" "github.com/growteer/api/testing/mocks/internal_/app/authn" - "github.com/growteer/api/testing/testcontainer" "github.com/mr-tron/base58" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -25,23 +25,22 @@ const ( testRefreshToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJyZWZyZXNoVG9rZW4iLCJpYXQiOjE2MjYwNzQwNzcsImV4cCI6MTYyNjA3NzY3N30.7Q7J9" ) -func Test_Login(t *testing.T) { - mongoEnv, terminateDB := testcontainer.StartMongoAndGetDetails(t) - defer terminateDB() +var config = environment.Load() - db := mongodb.NewDB(mongoEnv) +func Test_Login(t *testing.T) { + db := mongodb.NewDB(config.Mongo) tokenProvider := authn.NewMockTokenProvider(t) resolver := graphql.NewResolver(db, tokenProvider) t.Run("success, user not onboarded", func(t *testing.T) { - //given + // given privKey, pubKeyBase58 := fixtures.GenerateEd25519KeyPair(t) did := web3util.NewDID(web3util.DIDMethodPKH, web3util.NamespaceSolana, pubKeyBase58) tokenProvider.EXPECT().NewSessionToken(did).Return(testSessionToken, nil) tokenProvider.EXPECT().NewRefreshToken(did).Return(testRefreshToken, nil) - //when + // when nonceResult, err := resolver.Mutation().GenerateNonce(context.Background(), pubKeyBase58) require.NoError(t, err) @@ -49,14 +48,14 @@ func Test_Login(t *testing.T) { loginResult, err := resolver.Mutation().Login(context.Background(), loginDetails) require.NoError(t, err) - //then + // then assert.False(t, loginResult.State.IsOnboarded) assert.Equal(t, testRefreshToken, loginResult.RefreshToken) assert.Equal(t, testSessionToken, loginResult.SessionToken) }) t.Run("success, user onboarded", func(t *testing.T) { - //given + // given privKey, pubKeyBase58 := fixtures.GenerateEd25519KeyPair(t) did := web3util.NewDID(web3util.DIDMethodPKH, web3util.NamespaceSolana, pubKeyBase58) @@ -74,7 +73,7 @@ func Test_Login(t *testing.T) { require.NoError(t, err) }() - //when + // when nonceResult, err := resolver.Mutation().GenerateNonce(context.Background(), pubKeyBase58) require.NoError(t, err) @@ -82,58 +81,58 @@ func Test_Login(t *testing.T) { loginResult, err := resolver.Mutation().Login(context.Background(), loginDetails) require.NoError(t, err) - //then + // then assert.True(t, loginResult.State.IsOnboarded) assert.NotEmpty(t, loginResult.RefreshToken) assert.NotEmpty(t, loginResult.SessionToken) }) t.Run("fail, invalid address", func(t *testing.T) { - //given + // given privKey, pubKeyBase58 := fixtures.GenerateEd25519KeyPair(t) did := web3util.NewDID(web3util.DIDMethodPKH, web3util.NamespaceSolana, pubKeyBase58) tokenProvider.EXPECT().NewSessionToken(did).Maybe().Return(testSessionToken, nil) tokenProvider.EXPECT().NewRefreshToken(did).Maybe().Return(testRefreshToken, nil) - //when + // when nonceResult, err := resolver.Mutation().GenerateNonce(context.Background(), pubKeyBase58) require.NoError(t, err) loginDetails := newLoginDetails(privKey, "invalidAddress", nonceResult.Nonce) loginResult, err := resolver.Mutation().Login(context.Background(), loginDetails) - //then + // then require.ErrorAs(t, err, &apperrors.BadInput{}) assert.Nil(t, loginResult) }) t.Run("fail, nonce not found", func(t *testing.T) { - //given + // given privKey, pubKeyBase58 := fixtures.GenerateEd25519KeyPair(t) did := web3util.NewDID(web3util.DIDMethodPKH, web3util.NamespaceSolana, pubKeyBase58) tokenProvider.EXPECT().NewSessionToken(did).Maybe().Return(testSessionToken, nil) tokenProvider.EXPECT().NewRefreshToken(did).Maybe().Return(testRefreshToken, nil) - //when + // when loginDetails := newLoginDetails(privKey, pubKeyBase58, "invalidNonce") loginResult, err := resolver.Mutation().Login(context.Background(), loginDetails) - //then + // then require.ErrorAs(t, err, &apperrors.BadInput{}) assert.Nil(t, loginResult) }) t.Run("fail, invalid signature", func(t *testing.T) { - //given + // given privKey, pubKeyBase58 := fixtures.GenerateEd25519KeyPair(t) did := web3util.NewDID(web3util.DIDMethodPKH, web3util.NamespaceSolana, pubKeyBase58) tokenProvider.EXPECT().NewSessionToken(did).Maybe().Return(testSessionToken, nil) tokenProvider.EXPECT().NewRefreshToken(did).Maybe().Return(testRefreshToken, nil) - //when + // when nonceResult, err := resolver.Mutation().GenerateNonce(context.Background(), pubKeyBase58) require.NoError(t, err) @@ -141,22 +140,19 @@ func Test_Login(t *testing.T) { loginDetails.Signature = "invalidSignature" loginResult, err := resolver.Mutation().Login(context.Background(), loginDetails) - //then + // then require.ErrorAs(t, err, &apperrors.BadInput{}) assert.Nil(t, loginResult) }) } func Test_GenerateNonce(t *testing.T) { - mongoEnv, terminateDB := testcontainer.StartMongoAndGetDetails(t) - defer terminateDB() - - db := mongodb.NewDB(mongoEnv) + db := mongodb.NewDB(config.Mongo) tokenProvider := authn.NewMockTokenProvider(t) resolver := graphql.NewResolver(db, tokenProvider) t.Run("fail, invalid address", func(t *testing.T) { - //given + // given _, pubKeyBase58 := fixtures.GenerateEd25519KeyPair(t) pubKeyRaw, err := base58.Decode(pubKeyBase58) require.NoError(t, err) @@ -166,25 +162,22 @@ func Test_GenerateNonce(t *testing.T) { tokenProvider.EXPECT().NewSessionToken(did).Maybe().Return(testSessionToken, nil) tokenProvider.EXPECT().NewRefreshToken(did).Maybe().Return(testRefreshToken, nil) - //when + // when nonceResult, err := resolver.Mutation().GenerateNonce(context.Background(), string(pubKeyRaw)) - //then + // then require.ErrorAs(t, err, &apperrors.BadInput{}) assert.Nil(t, nonceResult) }) } func Test_Refresh(t *testing.T) { - mongoEnv, terminateDB := testcontainer.StartMongoAndGetDetails(t) - defer terminateDB() - - db := mongodb.NewDB(mongoEnv) + db := mongodb.NewDB(config.Mongo) tokenProvider := authn.NewMockTokenProvider(t) resolver := graphql.NewResolver(db, tokenProvider) t.Run("success", func(t *testing.T) { - //given + // given _, pubKeyBase58 := fixtures.GenerateEd25519KeyPair(t) did := web3util.NewDID(web3util.DIDMethodPKH, web3util.NamespaceSolana, pubKeyBase58) initialRefreshToken := "eyKMlcCI6MTYyNjA3NzY3N30.7Q7J9" @@ -199,31 +192,31 @@ func Test_Refresh(t *testing.T) { tokenProvider.EXPECT().NewRefreshToken(did).Return(testRefreshToken, nil) tokenProvider.EXPECT().ParseRefreshToken(initialRefreshToken).Return(&jwt.RegisteredClaims{Subject: did.String()}, nil) - //when + // when refreshResult, err := resolver.Mutation().RefreshSession(context.Background(), model.RefreshInput{ RefreshToken: initialRefreshToken, }) require.NoError(t, err) - //then + // then assert.Equal(t, testRefreshToken, refreshResult.RefreshToken) assert.Equal(t, testSessionToken, refreshResult.SessionToken) }) t.Run("fail, non-existent refresh token", func(t *testing.T) { - //given + // given _, pubKeyBase58 := fixtures.GenerateEd25519KeyPair(t) did := web3util.NewDID(web3util.DIDMethodPKH, web3util.NamespaceSolana, pubKeyBase58) initialRefreshToken := "eyKMlcCI6MTYyFjA3NzY3N30.7Q7J9" tokenProvider.EXPECT().ParseRefreshToken(initialRefreshToken).Return(&jwt.RegisteredClaims{Subject: did.String()}, nil) - //when + // when refreshResult, err := resolver.Mutation().RefreshSession(context.Background(), model.RefreshInput{ RefreshToken: initialRefreshToken, }) - //then + // then require.ErrorAs(t, err, &apperrors.Unauthenticated{}) assert.Empty(t, refreshResult) }) diff --git a/internal/api/graphql/profile.resolvers_test.go b/internal/api/graphql/profile.resolvers_test.go index 5992975..0885704 100644 --- a/internal/api/graphql/profile.resolvers_test.go +++ b/internal/api/graphql/profile.resolvers_test.go @@ -12,7 +12,6 @@ import ( "github.com/growteer/api/pkg/web3util" "github.com/growteer/api/testing/fixtures" "github.com/growteer/api/testing/mocks/internal_/app/authn" - "github.com/growteer/api/testing/testcontainer" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -65,16 +64,14 @@ const ( ) func Test_Onboard(t *testing.T) { - mongoEnv, terminateDB := testcontainer.StartMongoAndGetDetails(t) - defer terminateDB() - db := mongodb.NewDB(mongoEnv) + db := mongodb.NewDB(config.Mongo) t.Run("success", func(t *testing.T) { - //given + // given did := fixtures.NewDID(t) gqlClient := setupGQLClient(t, did, db) - //when + // when var onboardResult struct{ Onboard model.Profile } err := gqlClient.Post( onboardMutation, @@ -86,18 +83,18 @@ func Test_Onboard(t *testing.T) { client.Var("country", "US"), ) - //then + // then require.NoError(t, err) assert.Equal(t, "John", onboardResult.Onboard.FirstName) assert.Equal(t, "Doe", onboardResult.Onboard.LastName) }) t.Run("fail, invalid input", func(t *testing.T) { - //given + // given did := fixtures.NewDID(t) gqlClient := setupGQLClient(t, did, db) - //when + // when var onboardResult struct{ Onboard model.Profile } err := gqlClient.Post( onboardMutation, @@ -109,7 +106,7 @@ func Test_Onboard(t *testing.T) { client.Var("country", "US"), ) - //then + // then require.Error(t, err) assert.Contains(t, err.Error(), "BAD_INPUT") assert.Empty(t, onboardResult.Onboard) @@ -117,22 +114,20 @@ func Test_Onboard(t *testing.T) { } func Test_Profile(t *testing.T) { - mongoEnv, terminateDB := testcontainer.StartMongoAndGetDetails(t) - defer terminateDB() - db := mongodb.NewDB(mongoEnv) + db := mongodb.NewDB(config.Mongo) t.Run("success", func(t *testing.T) { - //given + // given did := fixtures.NewDID(t) gqlClient := setupGQLClient(t, did, db) _ = onboardTestProfile(t, gqlClient) - //when + // when var profileResult struct{ Profile model.Profile } err := gqlClient.Post(profileQuery, &profileResult, client.Var("userDID", did.String())) require.NoError(t, err) - //then + // then assert.Equal(t, "John", profileResult.Profile.FirstName) assert.Equal(t, "Doe", profileResult.Profile.LastName) assert.Contains(t, profileResult.Profile.DateOfBirth, "1990-01-01") @@ -146,7 +141,7 @@ func Test_Profile(t *testing.T) { }) t.Run("fail, profile doesn't exist", func(t *testing.T) { - //given + // given did := fixtures.NewDID(t) gqlClient := setupGQLClient(t, did, db) _ = onboardTestProfile(t, gqlClient) @@ -154,7 +149,7 @@ func Test_Profile(t *testing.T) { _, altPubKeyBase58 := fixtures.GenerateEd25519KeyPair(t) altDID := web3util.NewDID(web3util.DIDMethodPKH, web3util.NamespaceSolana, altPubKeyBase58) - //when + // when var profileResult struct{ Profile model.Profile } err := gqlClient.Post( profileQuery, @@ -162,7 +157,7 @@ func Test_Profile(t *testing.T) { client.Var("userDID", altDID.String()), ) - //then + // then require.Error(t, err) assert.Contains(t, err.Error(), "NOT_FOUND") assert.Empty(t, profileResult.Profile) @@ -170,17 +165,15 @@ func Test_Profile(t *testing.T) { } func Test_UpdateProfile(t *testing.T) { - mongoEnv, terminateDB := testcontainer.StartMongoAndGetDetails(t) - defer terminateDB() - db := mongodb.NewDB(mongoEnv) + db := mongodb.NewDB(config.Mongo) t.Run("success", func(t *testing.T) { - //given + // given did := fixtures.NewDID(t) gqlClient := setupGQLClient(t, did, db) _ = onboardTestProfile(t, gqlClient) - //when + // when var updateResult struct{ UpdateProfile model.Profile } err := gqlClient.Post( updateProfileMutation, @@ -193,7 +186,7 @@ func Test_UpdateProfile(t *testing.T) { ) require.NoError(t, err) - //then + // then assert.Equal(t, "Jane", updateResult.UpdateProfile.FirstName) assert.Equal(t, "Doe", updateResult.UpdateProfile.LastName) assert.Contains(t, updateResult.UpdateProfile.DateOfBirth, "1990-01-01") @@ -207,12 +200,12 @@ func Test_UpdateProfile(t *testing.T) { }) t.Run("fail, profile doesn't exist", func(t *testing.T) { - //given + // given did := fixtures.NewDID(t) gqlClient := setupGQLClient(t, did, db) _ = onboardTestProfile(t, gqlClient) - //when + // when var updateResult struct{ UpdateProfile model.Profile } err := gqlClient.Post( updateProfileMutation, @@ -224,7 +217,7 @@ func Test_UpdateProfile(t *testing.T) { client.Var("country", "US"), ) - //then + // then require.Error(t, err) assert.Contains(t, err.Error(), "BAD_INPUT") assert.Empty(t, updateResult.UpdateProfile) @@ -235,7 +228,7 @@ func setupGQLClient(t *testing.T, did *web3util.DID, db *mongo.Database) *client tokenProvider := authn.NewMockTokenProvider(t) tokenProvider.EXPECT().ParseSessionToken(mock.Anything).Return(&jwt.RegisteredClaims{Subject: did.String()}, nil) - gqlServer := api.NewServer(environment.ServerEnv{HTTPPort: 8080}, db, tokenProvider) + gqlServer := api.NewServer(environment.Server{HTTPPort: 8080}, db, tokenProvider) return client.New(gqlServer.Router, client.Path("/query"), client.AddHeader("Authorization", "Bearer "+sessionToken)) } diff --git a/internal/api/server.go b/internal/api/server.go index 40788f6..7aa942b 100644 --- a/internal/api/server.go +++ b/internal/api/server.go @@ -37,7 +37,7 @@ func (s *GQLServer) Start() { } } -func NewServer(env environment.ServerEnv, db *mongo.Database, tokenProvider authn.TokenProvider) *GQLServer { +func NewServer(env environment.Server, db *mongo.Database, tokenProvider authn.TokenProvider) *GQLServer { resolver := graphql.NewResolver(db, tokenProvider) server := handler.New(graphql.NewExecutableSchema(graphql.Config{Resolvers: resolver})) @@ -62,7 +62,7 @@ func NewServer(env environment.ServerEnv, db *mongo.Database, tokenProvider auth } } -func newRouter(env environment.ServerEnv, server *handler.Server, tokenProvider authn.TokenProvider) *chi.Mux { +func newRouter(env environment.Server, server *handler.Server, tokenProvider authn.TokenProvider) *chi.Mux { router := chi.NewRouter() router.Use(cors.New(cors.Options{ AllowedHeaders: []string{"Accept", "Authorization", "Content-Type"}, diff --git a/internal/infrastructure/environment/environment.go b/internal/infrastructure/environment/environment.go index 9030d6e..2ac76f2 100644 --- a/internal/infrastructure/environment/environment.go +++ b/internal/infrastructure/environment/environment.go @@ -7,14 +7,14 @@ import ( "github.com/vrischmann/envconfig" ) -func Load() *Environment { +func Load() Environment { if err := godotenv.Load(); err != nil { slog.Debug("no .env file loaded") } - - env := new(Environment) - if err := envconfig.Init(env); err != nil { + env := Environment{} + + if err := envconfig.Init(&env); err != nil { panic(err) } @@ -22,27 +22,23 @@ func Load() *Environment { } type Environment struct { - Mongo MongoEnv - Server ServerEnv - Token TokenEnv + Mongo Mongo + Server Server + Token Token } -type MongoEnv struct { - Host string `envconfig:"MONGO_HOST"` - Port int `envconfig:"MONGO_PORT"` - User string `envconfig:"MONGO_USER"` - Password string `envconfig:"MONGO_PASSWORD"` - DBName string `envconfig:"MONGO_DB_NAME"` - SSL bool `envconfig:"MONGO_SSL,default=true"` +type Mongo struct { + URI string `envconfig:"MONGODB_URI"` + Database string `envconfig:"MONGODB_DATABASE"` } -type ServerEnv struct { +type Server struct { AllowedOrigins []string `envconfig:"ALLOWED_ORIGINS"` - HTTPPort int `envconfig:"HTTP_PORT,default=8080"` + HTTPPort int `envconfig:"HTTP_PORT,default=8080"` } -type TokenEnv struct { - JWTSecret string `envconfig:"JWT_SECRET"` - SessionTTLMinutes int `envconfig:"SESSION_TTL_MINUTES,default=15"` - RefreshTTLMinutes int `envconfig:"REFRESH_TTL_MINUTES,default=10080"` // Default = One Week +type Token struct { + JWTSecret string `envconfig:"JWT_SECRET"` + SessionTTLMinutes int `envconfig:"SESSION_TTL_MINUTES,default=15"` + RefreshTTLMinutes int `envconfig:"REFRESH_TTL_MINUTES,default=10080"` // Default = One Week } diff --git a/internal/infrastructure/mongodb/client.go b/internal/infrastructure/mongodb/client.go index 161f67b..670f977 100644 --- a/internal/infrastructure/mongodb/client.go +++ b/internal/infrastructure/mongodb/client.go @@ -12,9 +12,8 @@ import ( "go.mongodb.org/mongo-driver/mongo/readpref" ) -func NewDB(env environment.MongoEnv) *mongo.Database { - uri := fmt.Sprintf("mongodb://%s:%s@%s:%d/?ssl=%t", env.User, env.Password, env.Host, env.Port, env.SSL) - clientOptions := options.Client().ApplyURI(uri).SetTimeout(5 * time.Second) +func NewDB(env environment.Mongo) *mongo.Database { + clientOptions := options.Client().ApplyURI(env.URI).SetTimeout(5 * time.Second) client, err := mongo.Connect(context.Background(), clientOptions) if err != nil { @@ -30,5 +29,5 @@ func NewDB(env environment.MongoEnv) *mongo.Database { slog.Info("connected to mongodb") - return client.Database(env.DBName) + return client.Database(env.Database) } diff --git a/testing/testcontainer/mongodb.go b/testing/testcontainer/mongodb.go deleted file mode 100644 index 83a726c..0000000 --- a/testing/testcontainer/mongodb.go +++ /dev/null @@ -1,93 +0,0 @@ -package testcontainer - -import ( - "context" - "fmt" - "strconv" - "testing" - "time" - - "github.com/growteer/api/internal/infrastructure/environment" - "github.com/stretchr/testify/require" - "github.com/testcontainers/testcontainers-go" - "github.com/testcontainers/testcontainers-go/modules/mongodb" - "github.com/testcontainers/testcontainers-go/wait" - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" -) - -const ( - dbName = "growteer_test" - containerImage = "mongo:latest" - defaultPort = "27017/tcp" - password = "mongo" - ssl = false - username = "mongo" -) - -func runContainer() (testcontainers.Container, error) { - return mongodb.Run( - context.Background(), - containerImage, - mongodb.WithUsername(username), - mongodb.WithPassword(password), - testcontainers.WithWaitStrategy(wait.ForAll( - wait.ForLog("Waiting for connections"), - wait.ForListeningPort(defaultPort), - ))) -} - -func StartMongoAndGetDetails(t *testing.T) (mongoEnv environment.MongoEnv, shutdown func()) { - container, err := runContainer() - require.NoError(t, err) - - shutdown = func() { - err := container.Terminate(context.Background()) - if err != nil { - t.Fatal() - } - } - - host, err := container.Host(context.Background()) - require.NoError(t, err) - - port, err := container.MappedPort(context.Background(), defaultPort) - if err != nil { - shutdown() - require.Fail(t, err.Error()) - } - - mongoEnv = environment.MongoEnv{ - Host: host, - Port: port.Int(), - User: username, - Password: password, - DBName: dbName, - SSL: ssl, - } - - require.NoError(t, waitForReadiness(mongoEnv)) - - return mongoEnv, shutdown -} - -func waitForReadiness(env environment.MongoEnv) (err error) { - clientOptions := options.Client().ApplyURI(fmt.Sprintf("mongodb://%s:%s@%s:%s", env.User, env.Password, env.Host, strconv.Itoa(env.Port))) - var client *mongo.Client - - for i := 0; i < 30; i++ { - client, err = mongo.Connect(context.Background(), clientOptions) - - if err == nil { - err = client.Ping(context.Background(), nil) - - if err == nil { - break - } - } - - time.Sleep(1 * time.Second) - } - - return -} diff --git a/tools/tools.go b/tools/tools.go deleted file mode 100644 index 4deb32b..0000000 --- a/tools/tools.go +++ /dev/null @@ -1,5 +0,0 @@ -//go:build tools - -package tools - -import _ "github.com/99designs/gqlgen" From fbbfa5d9ab81d08905b019dce5dc9f7a10926ecd Mon Sep 17 00:00:00 2001 From: Christian Nicola Date: Wed, 23 Jul 2025 18:08:50 +0200 Subject: [PATCH 05/11] feat: (docker) build the docker image with flake.nix this patch changes the docker file to use the exact same setup, using the nix flake. this ensures that the build / dependencies are exactly the same. CBR-14 --- Dockerfile | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/Dockerfile b/Dockerfile index c881d3e..c46362b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,26 +1,22 @@ -#################### -# BUILD IMAGE # -#################### -FROM alpine:latest AS builder -WORKDIR /app +FROM nixos/nix:latest AS builder -RUN apk update && \ - apk add --no-cache ca-certificates && \ - mkdir /user && \ - echo 'nobody:x:65534:65534:nobody:/:' > /user/passwd && \ - echo 'nobody:x:65534:' > /user/group +COPY . /tmp/build -#################### -# PRODUCTION IMAGE # -#################### -FROM scratch AS final +WORKDIR /tmp/build -EXPOSE 8080 +RUN nix-env -iA nixpkgs.cacert -USER nobody:nobody +RUN cp /etc/ssl/certs/ca-bundle.crt ca-certificates +RUN nix --extra-experimental-features "nix-command flakes" build +RUN mkdir /tmp/nix-store-closure +RUN cp -R $(nix-store -qR result/) /tmp/nix-store-closure -COPY --from=builder /user/group /user/passwd /etc/ -COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ -COPY ./bin/main . +FROM scratch -ENTRYPOINT ["/main"] \ No newline at end of file +WORKDIR /bin + +COPY --from=builder /tmp/nix-store-closure /nix/store +COPY --from=builder /tmp/build/ca-certificates /etc/ssl/certs/ca-certificates.crt +COPY --from=builder /tmp/build/result/bin/growteer-api . + +CMD ["/bin/growteer-api"] From c1d0aa6317e9326671f364e2000164b2c5ec3f1f Mon Sep 17 00:00:00 2001 From: Christian Nicola Date: Wed, 23 Jul 2025 18:10:23 +0200 Subject: [PATCH 06/11] chore: (project) retire compose & taskfile - the compose stack is no longer needed as we have a working environment right in our nix shell - taskfile has been replaced with a small Makefile CBR-14 --- Taskfile.yaml | 100 -------------------------------------------- docker-compose.yaml | 43 ------------------- 2 files changed, 143 deletions(-) delete mode 100644 Taskfile.yaml delete mode 100644 docker-compose.yaml diff --git a/Taskfile.yaml b/Taskfile.yaml deleted file mode 100644 index 43af2b7..0000000 --- a/Taskfile.yaml +++ /dev/null @@ -1,100 +0,0 @@ -version: "3" - -vars: - BIN: "{{ .TASKFILE_DIR }}/bin" - GOBIN: - sh: echo $GOPATH/bin - REPORTS: "{{ .TASKFILE_DIR }}/reports" - VERSION_DELVE: latest - VERSION_GO_JUNIT_REPORT: v2.1.0 - VERSION_GOCOV: v1.1.0 - VERSION_GOCOV_XML: v1.1.0 - VERSION_GOLANGCI_LINT: v1.63.4 - VERSION_MOCKERY: v2.52.1 - TESTABLE_DIRS: - - ./internal/... - - ./pkg/... - -tasks: - db: - cmd: | - docker run -it -p 27017:27017 \ - -e MONGO_INITDB_ROOT_USERNAME=admin \ - -e MONGO_INITDB_ROOT_PASSWORD=password \ - mongo:latest - - run: - cmds: - - go run ./cmd - env: - ALLOWED_ORIGINS: "http://localhost:5173" - HTTP_PORT: 8080 - MONGO_HOST: localhost - MONGO_PORT: 27017 - MONGO_USER: admin - MONGO_PASSWORD: password - MONGO_DB_NAME: api_service - MONGO_SSL: false - JWT_SECRET: baconkilbasa - SESSION_TTL_MINUTES: 60 - - debug: - cmd: | - go run github.com/go-delve/delve/cmd/dlv@{{ .VERSION_DELVE }} debug \ - ./cmd \ - --headless \ - --listen=:2345 \ - --api-version=2 - - build: - cmds: - - cmd: | - go build \ - -tags release \ - -o {{.BIN}}/main \ - ./cmd; - env: - CGO_ENABLED: 0 - GOOS: linux - GOARCH: amd64 - - gen-api: - cmd: go run github.com/99designs/gqlgen generate - - gen-mocks: - cmds: - - rm -rf ./testing/mocks - - go run github.com/vektra/mockery/v2@{{ .VERSION_MOCKERY }} - - lint: - cmd: | - go run github.com/golangci/golangci-lint/cmd/golangci-lint@{{ .VERSION_GOLANGCI_LINT }} run - - test: - cmd: go test ./... -v - - test-with-reports: - cmds: - - task: test-tools - - mkdir -p {{ .REPORTS }} - - cmd: | - go test {{ join " " .TESTABLE_DIRS }} -v \ - -covermode=atomic \ - -coverprofile={{ .COVERAGE_PROFILE }} \ - -json > {{ .REPORTS }}/test-report.json - - cmd: | - {{ .GOBIN }}/go-junit-report \ - < {{ .REPORTS }}/test-report.json \ - > {{ .REPORTS }}/junit-report.xml - - cmd: | - go tool cover \ - -html={{ .COVERAGE_PROFILE }} \ - -o {{ .REPORTS }}/coverage.html - vars: - COVERAGE_PROFILE: "{{ .REPORTS }}/coverage.out" - - test-tools: - cmds: - - go install github.com/jstemmer/go-junit-report/v2@{{ .VERSION_GO_JUNIT_REPORT }} - - go install github.com/axw/gocov/gocov@{{ .VERSION_GOCOV }} - - go install github.com/AlekSi/gocov-xml@{{ .VERSION_GOCOV_XML }} diff --git a/docker-compose.yaml b/docker-compose.yaml deleted file mode 100644 index 4f0423e..0000000 --- a/docker-compose.yaml +++ /dev/null @@ -1,43 +0,0 @@ -# Only for local testing! -version: "3.9" -services: - mongodb: - image: mongo:latest - container_name: mongodb - ports: - - "27017:27017" - volumes: - - mongodb:/data/db - environment: - MONGO_INITDB_DATABASE: api_service - MONGO_INITDB_ROOT_USERNAME: admin - MONGO_INITDB_ROOT_PASSWORD: password - networks: - growteer_network: - - api: - build: - context: . - dockerfile: Dockerfile - ports: - - "8080:80" - depends_on: - - mongodb - environment: - ALLOWED_ORIGINS: http://localhost:3000 - MONGO_DB_NAME: api_service - MONGO_HOST: mongodb - MONGO_PORT: 27017 - MONGO_USER: admin - MONGO_PASSWORD: password - MONGODB_CONNECTION_STRING: mongodb://admin:password@mongodb:27017/?ssl=false - JWT_SECRET: baconkilbasa - SESSION_TTL_MINUTES: 60 - networks: - growteer_network: - -volumes: - mongodb: - -networks: - growteer_network: From ded130ae62d3e583adf35f78b17e90df831939e5 Mon Sep 17 00:00:00 2001 From: Christian Nicola Date: Wed, 23 Jul 2025 18:20:05 +0200 Subject: [PATCH 07/11] chore: (project) update README add some basic instructions on how to work with nix CBR-14 --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 21437db..88c9ad6 100644 --- a/README.md +++ b/README.md @@ -1 +1,16 @@ [![codecov](https://codecov.io/gh/growteer/api/graph/badge.svg?token=Y6SAD10060)](https://codecov.io/gh/growteer/api) + +# Setup + +- Install Nix, instructions are found here [nixos.org](https://nixos.org/download/) +- Launch a development environment with `nix develop` +- Build the project with `nix build` (output path is `result/bin`) +- Test the project with `nix develop -c make test` (or run `make test` while inside the development shell) +- Lint the project with `nix develop -c make lint` (or run `make lint` while inside the development shell) + +All current dependencies are ready and available inside `nix develop`, so it is encouraged to use it for developing. + +# Upgrade + +If the `go.mod` file changes due to an upgrade, please remember to run `gomod2nix generate` to rehydrate the `gomod2nix.toml` file. This file +tracks the dependencies as separatate nix packages and are thus versioned with the flake. From d36b21e337c47ed42bd68fa81bfe0eb8cd15e9d2 Mon Sep 17 00:00:00 2001 From: Christian Nicola Date: Wed, 23 Jul 2025 18:26:08 +0200 Subject: [PATCH 08/11] feat: (github) use flake for CI this patch enables the github actions to also use the flake, just like your local environment. this ensures a reproducable environment, no matter where the code runs. CBR-14 --- .github/workflows/integration.yaml | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/.github/workflows/integration.yaml b/.github/workflows/integration.yaml index 5a567dc..9a4bbf1 100644 --- a/.github/workflows/integration.yaml +++ b/.github/workflows/integration.yaml @@ -14,10 +14,6 @@ permissions: contents: read pull-requests: write -env: - GOPATH: ${{ github.workspace }}/../go - GO_VERSION: 1.23 - jobs: build: runs-on: ubuntu-latest @@ -26,19 +22,15 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Set up Go - uses: actions/setup-go@v5 + - uses: cachix/install-nix-action@v31 with: - go-version: ${{ env.GO_VERSION }} - - - name: Install Task - uses: arduino/setup-task@v2 + nix_path: nixpkgs=channel:nixos-unstable - name: Lint - run: task lint + run: nix develop -c make lint - name: Test - run: task test-with-reports + run: nix develop -c make test - name: Publish Test Results if: success() || failure() @@ -54,4 +46,4 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} - name: Build - run: task build + run: nix build From ca9b13ef9390b59c1245fea24c71ed235da95702 Mon Sep 17 00:00:00 2001 From: Christian Nicola Date: Thu, 24 Jul 2025 08:47:44 +0200 Subject: [PATCH 09/11] fix: (ci) make dorny/test-reporter work with PRs CBR-14 --- .github/workflows/integration.yaml | 14 ++++++-------- .github/workflows/test-report.yaml | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/test-report.yaml diff --git a/.github/workflows/integration.yaml b/.github/workflows/integration.yaml index 9a4bbf1..e2f27d9 100644 --- a/.github/workflows/integration.yaml +++ b/.github/workflows/integration.yaml @@ -26,24 +26,22 @@ jobs: with: nix_path: nixpkgs=channel:nixos-unstable + - name: Build + run: nix build + - name: Lint run: nix develop -c make lint - name: Test run: nix develop -c make test - - name: Publish Test Results - if: success() || failure() - uses: dorny/test-reporter@v1.9.1 + - uses: actions/upload-artifact@v4 + if: ${{ !cancelled() }} with: - name: Unit & Integration Tests + name: test-results path: reports/junit-report.xml - reporter: java-junit - name: Upload coverage reports to Codecov uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} - - - name: Build - run: nix build diff --git a/.github/workflows/test-report.yaml b/.github/workflows/test-report.yaml new file mode 100644 index 0000000..553e592 --- /dev/null +++ b/.github/workflows/test-report.yaml @@ -0,0 +1,20 @@ +name: 'Test Report' +on: + workflow_run: + workflows: ['Integration Pipeline'] + types: + - completed +permissions: + contents: read + actions: read + checks: write +jobs: + report: + runs-on: ubuntu-latest + steps: + - uses: dorny/test-reporter@v2 + with: + artifact: test-results + name: JEST Tests + path: junit-report.xml + reporter: jest-junit From f8509ea8c0cbbdcd7e38883f2fc95215c280dce7 Mon Sep 17 00:00:00 2001 From: Christian Nicola Date: Thu, 24 Jul 2025 10:07:10 +0200 Subject: [PATCH 10/11] chore: add tests CBR-14 --- cmd/growteer-api/main.go | 11 +++++ go.mod | 1 + gomod2nix.toml | 3 ++ internal/api/server.go | 48 +++++++++++-------- internal/api/server_test.go | 44 +++++++++++++++++ .../infrastructure/mongodb/client_test.go | 33 +++++++++++++ 6 files changed, 120 insertions(+), 20 deletions(-) create mode 100644 internal/api/server_test.go create mode 100644 internal/infrastructure/mongodb/client_test.go diff --git a/cmd/growteer-api/main.go b/cmd/growteer-api/main.go index 47c6809..2f92677 100644 --- a/cmd/growteer-api/main.go +++ b/cmd/growteer-api/main.go @@ -1,6 +1,11 @@ package main import ( + "log/slog" + "os" + "os/signal" + "syscall" + "github.com/growteer/api/internal/api" "github.com/growteer/api/internal/infrastructure/environment" "github.com/growteer/api/internal/infrastructure/mongodb" @@ -9,6 +14,8 @@ import ( func main() { env := environment.Load() + sig := make(chan os.Signal, 1) + signal.Notify(sig, syscall.SIGTERM, os.Interrupt) db := mongodb.NewDB(env.Mongo) tokenProvider := tokens.NewProvider(env.Token.JWTSecret, env.Token.SessionTTLMinutes, env.Token.RefreshTTLMinutes) @@ -16,4 +23,8 @@ func main() { server := api.NewServer(env.Server, db, tokenProvider) server.Start() + + <-sig + + slog.Info("shutting down") } diff --git a/go.mod b/go.mod index bc0d2d8..8fe4e1a 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,7 @@ require ( github.com/mr-tron/base58 v1.2.0 github.com/rs/cors v1.11.1 github.com/stretchr/testify v1.10.0 + github.com/test-go/testify v1.1.4 github.com/vektah/gqlparser/v2 v2.5.20 github.com/vrischmann/envconfig v1.3.0 go.mongodb.org/mongo-driver v1.17.1 diff --git a/gomod2nix.toml b/gomod2nix.toml index 393c646..28a5755 100644 --- a/gomod2nix.toml +++ b/gomod2nix.toml @@ -108,6 +108,9 @@ schema = 3 [mod."github.com/stretchr/testify"] version = "v1.10.0" hash = "sha256-fJ4gnPr0vnrOhjQYQwJ3ARDKPsOtA7d4olQmQWR+wpI=" + [mod."github.com/test-go/testify"] + version = "v1.1.4" + hash = "sha256-8xygO1Rd4eTrmRe/g7zaifpNkeb6EmjNfUvTWbjDtPg=" [mod."github.com/vektah/gqlparser/v2"] version = "v2.5.20" hash = "sha256-jkHpt9vF+QSAdN7kNLoIr6vViMFOvbGxI8feZbuOwF0=" diff --git a/internal/api/server.go b/internal/api/server.go index 7aa942b..8cbeea3 100644 --- a/internal/api/server.go +++ b/internal/api/server.go @@ -1,6 +1,7 @@ package api import ( + "context" "fmt" "log/slog" "net/http" @@ -21,7 +22,7 @@ import ( ) type GQLServer struct { - *handler.Server + server http.Server Router *chi.Mux port int } @@ -29,40 +30,47 @@ type GQLServer struct { func (s *GQLServer) Start() { slog.Info(fmt.Sprintf("connect on port %d for GraphQL playground", s.port)) - err := http.ListenAndServe(fmt.Sprintf(":%d", s.port), s.Router) - if err != nil && err != http.ErrServerClosed { - slog.Error("server unexpectedly shut down", "error", err) - } else { - slog.Info("server shut down gracefully") - } + go func() { + if err := s.server.ListenAndServe(); err != nil && err != http.ErrServerClosed { + slog.Error("server unexpectedly shut down", "error", err) + } else { + slog.Info("server shut down gracefully") + } + }() +} + +func (s *GQLServer) Shutdown(ctx context.Context) error { + return s.server.Shutdown(ctx) } func NewServer(env environment.Server, db *mongo.Database, tokenProvider authn.TokenProvider) *GQLServer { resolver := graphql.NewResolver(db, tokenProvider) - server := handler.New(graphql.NewExecutableSchema(graphql.Config{Resolvers: resolver})) - server.SetErrorPresenter(gqlutil.PresentError) - server.SetRecoverFunc(gqlutil.Recover) + handler := handler.New(graphql.NewExecutableSchema(graphql.Config{Resolvers: resolver})) + handler.SetErrorPresenter(gqlutil.PresentError) + handler.SetRecoverFunc(gqlutil.Recover) - server.AddTransport(transport.Options{}) - server.AddTransport(transport.GET{}) - server.AddTransport(transport.POST{}) + handler.AddTransport(transport.Options{}) + handler.AddTransport(transport.GET{}) + handler.AddTransport(transport.POST{}) - server.SetQueryCache(lru.New[*ast.QueryDocument](1000)) + handler.SetQueryCache(lru.New[*ast.QueryDocument](1000)) - server.Use(extension.Introspection{}) - server.Use(extension.AutomaticPersistedQuery{ + handler.Use(extension.Introspection{}) + handler.Use(extension.AutomaticPersistedQuery{ Cache: lru.New[string](100), }) + router := newRouter(env, handler, tokenProvider) + return &GQLServer{ - Server: server, - Router: newRouter(env, server, tokenProvider), + Router: router, + server: http.Server{Addr: fmt.Sprintf(":%d", env.HTTPPort), Handler: router}, port: env.HTTPPort, } } -func newRouter(env environment.Server, server *handler.Server, tokenProvider authn.TokenProvider) *chi.Mux { +func newRouter(env environment.Server, handler *handler.Server, tokenProvider authn.TokenProvider) *chi.Mux { router := chi.NewRouter() router.Use(cors.New(cors.Options{ AllowedHeaders: []string{"Accept", "Authorization", "Content-Type"}, @@ -73,7 +81,7 @@ func newRouter(env environment.Server, server *handler.Server, tokenProvider aut router.Use(authn.UserSessionMiddleware(tokenProvider)) router.Handle("/", playground.Handler("GraphQL playground", "/query")) - router.Handle("/query", server) + router.Handle("/query", handler) return router } diff --git a/internal/api/server_test.go b/internal/api/server_test.go new file mode 100644 index 0000000..190d871 --- /dev/null +++ b/internal/api/server_test.go @@ -0,0 +1,44 @@ +package api_test + +import ( + "context" + "fmt" + "net/http" + "testing" + + "github.com/growteer/api/internal/api" + "github.com/growteer/api/internal/infrastructure/environment" + "github.com/growteer/api/internal/infrastructure/mongodb" + "github.com/growteer/api/internal/infrastructure/tokens" + "github.com/test-go/testify/assert" +) + +var config = environment.Load() + +func TestNewServer(t *testing.T) { + var server *api.GQLServer + + db := mongodb.NewDB(config.Mongo) + tokenProvider := tokens.NewProvider(config.Token.JWTSecret, config.Token.SessionTTLMinutes, config.Token.RefreshTTLMinutes) + + t.Run("create server", func(t *testing.T) { + server = api.NewServer(config.Server, db, tokenProvider) + + assert.NotNil(t, server) + }) + + t.Run("start server", func(t *testing.T) { + assert.NotPanics(t, func() { server.Start() }) + }) + + t.Run("check that server is online", func(t *testing.T) { + response, err := http.Get(fmt.Sprintf("http://localhost:%d", config.Server.HTTPPort)) + + assert.NoError(t, err) + assert.Equal(t, http.StatusOK, response.StatusCode) + }) + + t.Run("shutdown", func(t *testing.T) { + assert.NoError(t, server.Shutdown(context.Background())) + }) +} diff --git a/internal/infrastructure/mongodb/client_test.go b/internal/infrastructure/mongodb/client_test.go new file mode 100644 index 0000000..3ddb6c2 --- /dev/null +++ b/internal/infrastructure/mongodb/client_test.go @@ -0,0 +1,33 @@ +package mongodb_test + +import ( + "testing" + + "github.com/growteer/api/internal/infrastructure/environment" + "github.com/growteer/api/internal/infrastructure/mongodb" + "github.com/test-go/testify/assert" +) + +var config = environment.Load() + +func TestNewDB(t *testing.T) { + t.Parallel() + + t.Run("successful connection", func(t *testing.T) { + database := mongodb.NewDB(config.Mongo) + + assert.NotNil(t, database) + }) + + t.Run("invalid parameters", func(t *testing.T) { + assert.Panics(t, func() { + mongodb.NewDB(environment.Mongo{URI: "http://localhost:27017"}) + }) + }) + + t.Run("no connection", func(t *testing.T) { + assert.Panics(t, func() { + mongodb.NewDB(environment.Mongo{URI: "mongodb://100.100.2.3:11111"}) + }) + }) +} From 19615a727888164f17901be5f8a125f3b0dbbbcf Mon Sep 17 00:00:00 2001 From: Christian Nicola Date: Thu, 24 Jul 2025 10:46:37 +0200 Subject: [PATCH 11/11] feat: (docker) build container via flake CBR-14 --- Dockerfile | 22 ---------------------- README.md | 1 + container.nix | 14 ++++++++++++++ default.nix | 4 ++++ flake.nix | 5 ++++- 5 files changed, 23 insertions(+), 23 deletions(-) delete mode 100644 Dockerfile create mode 100644 container.nix diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index c46362b..0000000 --- a/Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -FROM nixos/nix:latest AS builder - -COPY . /tmp/build - -WORKDIR /tmp/build - -RUN nix-env -iA nixpkgs.cacert - -RUN cp /etc/ssl/certs/ca-bundle.crt ca-certificates -RUN nix --extra-experimental-features "nix-command flakes" build -RUN mkdir /tmp/nix-store-closure -RUN cp -R $(nix-store -qR result/) /tmp/nix-store-closure - -FROM scratch - -WORKDIR /bin - -COPY --from=builder /tmp/nix-store-closure /nix/store -COPY --from=builder /tmp/build/ca-certificates /etc/ssl/certs/ca-certificates.crt -COPY --from=builder /tmp/build/result/bin/growteer-api . - -CMD ["/bin/growteer-api"] diff --git a/README.md b/README.md index 88c9ad6..c46b395 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ - Build the project with `nix build` (output path is `result/bin`) - Test the project with `nix develop -c make test` (or run `make test` while inside the development shell) - Lint the project with `nix develop -c make lint` (or run `make lint` while inside the development shell) +- Build a docker image with `nix build .#container` and load the image with `docker load < result` All current dependencies are ready and available inside `nix develop`, so it is encouraged to use it for developing. diff --git a/container.nix b/container.nix new file mode 100644 index 0000000..773db3e --- /dev/null +++ b/container.nix @@ -0,0 +1,14 @@ +{ pkgs, package }: + + +pkgs.dockerTools.buildImage { + name = "growteer-api"; + tag = "0.1"; + created = "now"; + copyToRoot = pkgs.buildEnv { + name = "image-root"; + paths = [ package ]; + pathsToLink = [ "/bin" ]; + }; + config.Cmd = [ "${package}/bin/growteer-api" ]; +} diff --git a/default.nix b/default.nix index 0f5cdc6..8f2fead 100644 --- a/default.nix +++ b/default.nix @@ -18,4 +18,8 @@ buildGoApplication { src = ./.; subPackages = [ "cmd/growteer-api" ]; modules = ./gomod2nix.toml; + + CGO_ENABLED = 0; + + ldflags = [ "-s -w" ]; } diff --git a/flake.nix b/flake.nix index ea234eb..d0c0a32 100644 --- a/flake.nix +++ b/flake.nix @@ -27,10 +27,13 @@ callPackage = pkgs.darwin.apple_sdk_11_0.callPackage or pkgs.callPackage; in - { + rec { packages.default = callPackage ./. { inherit (gomod2nix.legacyPackages.${system}) buildGoApplication; }; + packages.container = callPackage ./container.nix { + package = packages.default; + }; devShells.default = callPackage ./shell.nix { inherit (gomod2nix.legacyPackages.${system}) mkGoEnv gomod2nix; };