diff --git a/.gitignore b/.gitignore index 4830884..9b402d0 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ __debug_bin* .env +fetch-api diff --git a/Makefile b/Makefile index 962b5ac..78c8823 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: clean run build install dep test lint format docker +.PHONY: clean run build install dep test lint format docker gqlgen podman SHELL := /bin/bash PATHINSTBIN = $(abspath ./bin) @@ -20,7 +20,7 @@ VER_CUT := $(shell echo $(VERSION) | cut -c2-) # Dependency versions GOLANGCI_VERSION = latest -PROTOC_VERSION = 28.3 +PROTOC_VERSION = 33.4 PROTOC_GEN_GO_VERSION = $(shell go list -m -f '{{.Version}}' google.golang.org/protobuf) PROTOC_GEN_GO_GRPC_VERSION = v1.5.1 @@ -56,9 +56,26 @@ lint: ## run linter @PATH=$$PATH golangci-lint run --timeout 10m docker: dep ## build docker image - @docker build -f ./Dockerfile . -t dimozone/$(BIN_NAME):$(VER_CUT) + @docker build --build-arg APP_NAME=$(BIN_NAME) -f ./Dockerfile . -t dimozone/$(BIN_NAME):$(VER_CUT) @docker tag dimozone/$(BIN_NAME):$(VER_CUT) dimozone/$(BIN_NAME):latest +# Build multi-arch (amd64 + arm64) and push with a random tag. Does not trigger GitHub workflows. +# Requires: docker buildx, docker login. Run from repo root. +docker-push-multiarch: + $(eval TAG := dev-$(shell openssl rand -hex 6)) + @echo "Building and pushing dimozone/$(BIN_NAME):$(TAG) (linux/amd64, linux/arm64)" + @docker buildx build --build-arg APP_NAME=$(BIN_NAME) --platform linux/amd64,linux/arm64 -f ./Dockerfile --push -t dimozone/$(BIN_NAME):$(TAG) . + @echo "Pushed dimozone/$(BIN_NAME):$(TAG)" + +# Same as docker-push-multiarch but using podman (manifest list + manifest push --all). +podman-push-multiarch: + $(eval TAG := dev-$(shell openssl rand -hex 6)) + $(eval IMAGE := dimozone/$(BIN_NAME):$(TAG)) + @echo "Building and pushing $(IMAGE) (linux/amd64, linux/arm64)" + @podman build --build-arg APP_NAME=$(BIN_NAME) --platform linux/amd64,linux/arm64 --manifest $(IMAGE) -f ./Dockerfile . + @podman manifest push --all $(IMAGE) docker://$(IMAGE) + @echo "Pushed $(IMAGE)" + tools-golangci-lint: ## install golangci-lint @mkdir -p $(PATHINSTBIN) curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | BINARY=golangci-lint bash -s -- ${GOLANGCI_VERSION} @@ -80,7 +97,10 @@ endif make tools: tools-golangci-lint tools-protoc ## install all tools -generate: generate-swagger generate-go generate-grpc ## run all file generation for the project +gqlgen: ## Generate gqlgen code. + @go tool gqlgen generate + +generate: gqlgen generate-swagger generate-go generate-grpc ## run all file generation for the project generate-swagger: ## generate swagger documentation @go tool swag -version diff --git a/charts/fetch-api/values-prod.yaml b/charts/fetch-api/values-prod.yaml index 6473fbd..87ef106 100644 --- a/charts/fetch-api/values-prod.yaml +++ b/charts/fetch-api/values-prod.yaml @@ -11,7 +11,6 @@ env: TOKEN_EXCHANGE_ISSUER_URL: https://auth-roles-rights.dimo.zone CLOUDEVENT_BUCKET: dimo-ingest-cloudevent-prod EPHEMERAL_BUCKET: dimo-ingest-ephemeral-prod - VC_BUCKET: dimo-network-vc-prod VEHICLE_NFT_ADDRESS: '0xbA5738a18d83D41847dfFbDC6101d37C69c9B0cF' CHAIN_ID: 137 ingress: diff --git a/charts/fetch-api/values.yaml b/charts/fetch-api/values.yaml index dfede40..05f1174 100644 --- a/charts/fetch-api/values.yaml +++ b/charts/fetch-api/values.yaml @@ -33,7 +33,6 @@ env: TOKEN_EXCHANGE_ISSUER_URL: https://auth-roles-rights.dev.dimo.zone CLOUDEVENT_BUCKET: dimo-ingest-cloudevent-dev EPHEMERAL_BUCKET: dimo-ingest-ephemeral-dev - VC_BUCKET: dimo-network-vc-dev S3_AWS_REGION: us-east-2 VEHICLE_NFT_ADDRESS: '0x45fbCD3ef7361d156e8b16F5538AE36DEdf61Da8' CHAIN_ID: 80002 diff --git a/docs/docs.go b/docs/docs.go index 724100e..f8b72a2 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -397,6 +397,9 @@ const docTemplate = `{ "type": "integer" } }, + "data_base64": { + "type": "string" + }, "datacontenttype": { "description": "DataContentType is an optional MIME type for the data field. We almost\nalways serialize to JSON and in that case this field is implicitly\n\"application/json\".", "type": "string" @@ -469,6 +472,9 @@ const docTemplate = `{ } ] }, + "data_base64": { + "type": "string" + }, "datacontenttype": { "description": "DataContentType is an optional MIME type for the data field. We almost\nalways serialize to JSON and in that case this field is implicitly\n\"application/json\".", "type": "string" diff --git a/docs/swagger.json b/docs/swagger.json index 0724563..631f115 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -388,6 +388,9 @@ "type": "integer" } }, + "data_base64": { + "type": "string" + }, "datacontenttype": { "description": "DataContentType is an optional MIME type for the data field. We almost\nalways serialize to JSON and in that case this field is implicitly\n\"application/json\".", "type": "string" @@ -460,6 +463,9 @@ } ] }, + "data_base64": { + "type": "string" + }, "datacontenttype": { "description": "DataContentType is an optional MIME type for the data field. We almost\nalways serialize to JSON and in that case this field is implicitly\n\"application/json\".", "type": "string" diff --git a/docs/swagger.yaml b/docs/swagger.yaml index be529b4..2aaa15d 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -6,6 +6,8 @@ definitions: items: type: integer type: array + data_base64: + type: string datacontenttype: description: |- DataContentType is an optional MIME type for the data field. We almost @@ -72,6 +74,8 @@ definitions: allOf: - $ref: '#/definitions/github_com_DIMO-Network_fetch-api_pkg_eventrepo.ObjectInfo' description: Data contains domain-specific information about the event. + data_base64: + type: string datacontenttype: description: |- DataContentType is an optional MIME type for the data field. We almost diff --git a/go.mod b/go.mod index 3372d38..ee4a497 100644 --- a/go.mod +++ b/go.mod @@ -3,18 +3,21 @@ module github.com/DIMO-Network/fetch-api go 1.25 require ( + github.com/99designs/gqlgen v0.17.86 github.com/ClickHouse/clickhouse-go/v2 v2.40.1 github.com/DIMO-Network/clickhouse-infra v0.0.5 - github.com/DIMO-Network/cloudevent v0.1.4 + github.com/DIMO-Network/cloudevent v0.1.6 github.com/DIMO-Network/server-garage v0.0.7 github.com/DIMO-Network/shared v1.0.7 github.com/DIMO-Network/token-exchange-api v0.3.7 + github.com/apache/arrow-go/v18 v18.5.1 github.com/aws/aws-sdk-go-v2 v1.38.3 github.com/aws/aws-sdk-go-v2/credentials v1.18.10 github.com/aws/aws-sdk-go-v2/service/s3 v1.87.3 github.com/ethereum/go-ethereum v1.16.4 github.com/gofiber/fiber/v2 v2.52.9 github.com/gofiber/swagger v1.1.1 + github.com/golang-jwt/jwt/v5 v5.3.0 github.com/google/go-cmp v0.7.0 github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 @@ -22,11 +25,13 @@ require ( github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.11.1 github.com/swaggo/swag v1.16.6 + github.com/tidwall/gjson v1.18.0 + github.com/vektah/gqlparser/v2 v2.5.31 github.com/volatiletech/sqlboiler/v4 v4.19.1 go.uber.org/mock v0.6.0 - golang.org/x/sync v0.17.0 - google.golang.org/grpc v1.75.0 - google.golang.org/protobuf v1.36.10 + golang.org/x/sync v0.19.0 + google.golang.org/grpc v1.78.0 + google.golang.org/protobuf v1.36.11 ) require ( @@ -36,7 +41,9 @@ require ( github.com/KyleBanks/depth v1.2.1 // indirect github.com/MicahParks/keyfunc/v2 v2.1.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/agnivade/levenshtein v1.2.1 // indirect github.com/andybalholm/brotli v1.2.0 // indirect + github.com/apache/thrift v0.22.0 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.1 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.6 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.6 // indirect @@ -74,14 +81,22 @@ require ( github.com/go-openapi/jsonreference v0.20.4 // indirect github.com/go-openapi/spec v0.20.14 // indirect github.com/go-openapi/swag v0.22.9 // indirect + github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/goccy/go-json v0.10.5 // indirect + github.com/goccy/go-yaml v1.19.2 // indirect github.com/gofiber/contrib/jwt v1.1.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang-jwt/jwt/v5 v5.3.0 // indirect + github.com/golang/snappy v1.0.0 // indirect + github.com/google/flatbuffers v25.12.19+incompatible // indirect github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/websocket v1.5.1 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/holiman/uint256 v1.3.2 // indirect github.com/joho/godotenv v1.5.1 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/asmfmt v1.3.2 // indirect + github.com/klauspost/compress v1.18.2 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 // indirect github.com/magiconair/properties v1.8.10 // indirect github.com/mailru/easyjson v0.7.7 // indirect @@ -90,6 +105,8 @@ require ( github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mdelapenya/tlscert v0.2.0 // indirect github.com/mfridman/interpolate v0.0.2 // indirect + github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 // indirect + github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/go-archive v0.1.0 // indirect github.com/moby/patternmatcher v0.6.0 // indirect @@ -102,9 +119,9 @@ require ( github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect github.com/paulmach/orb v0.11.1 // indirect - github.com/pierrec/lz4/v4 v4.1.22 // indirect + github.com/pierrec/lz4/v4 v4.1.23 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect github.com/pressly/goose/v3 v3.24.3 // indirect github.com/prometheus/client_golang v1.23.0 // indirect @@ -118,38 +135,42 @@ require ( github.com/shirou/gopsutil/v4 v4.25.5 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect + github.com/sosodev/duration v1.3.1 // indirect github.com/spf13/cast v1.7.0 // indirect github.com/swaggo/files/v2 v2.0.2 // indirect github.com/testcontainers/testcontainers-go v0.38.0 // indirect github.com/testcontainers/testcontainers-go/modules/clickhouse v0.38.0 // indirect - github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect github.com/tklauser/go-sysconf v0.3.15 // indirect github.com/tklauser/numcpus v0.10.0 // indirect github.com/urfave/cli/v2 v2.27.5 // indirect + github.com/urfave/cli/v3 v3.6.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.65.0 // indirect github.com/volatiletech/inflect v0.0.1 // indirect github.com/volatiletech/strmangle v0.0.7-0.20240503230658-86517898275a // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect + github.com/zeebo/xxh3 v1.0.2 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect - go.opentelemetry.io/otel v1.37.0 // indirect - go.opentelemetry.io/otel/metric v1.37.0 // indirect - go.opentelemetry.io/otel/trace v1.37.0 // indirect + go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/trace v1.38.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.43.0 // indirect - golang.org/x/mod v0.28.0 // indirect - golang.org/x/net v0.45.0 // indirect - golang.org/x/sys v0.37.0 // indirect - golang.org/x/text v0.30.0 // indirect - golang.org/x/tools v0.37.0 // indirect - golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c // indirect + golang.org/x/crypto v0.47.0 // indirect + golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect + golang.org/x/mod v0.32.0 // indirect + golang.org/x/net v0.49.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2 // indirect + golang.org/x/text v0.33.0 // indirect + golang.org/x/tools v0.41.0 // indirect + golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251029180050-ab9386a59fda // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda // indirect google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -157,6 +178,7 @@ require ( ) tool ( + github.com/99designs/gqlgen github.com/swaggo/swag/cmd/swag go.uber.org/mock/mockgen google.golang.org/grpc/cmd/protoc-gen-go-grpc diff --git a/go.sum b/go.sum index a63ec39..01c6190 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/99designs/gqlgen v0.17.86 h1:C8N3UTa5heXX6twl+b0AJyGkTwYL6dNmFrgZNLRcU6w= +github.com/99designs/gqlgen v0.17.86/go.mod h1:KTrPl+vHA1IUzNlh4EYkl7+tcErL3MgKnhHrBcV74Fw= github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk= github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= @@ -14,8 +16,8 @@ github.com/DATA-DOG/go-sqlmock v1.4.1 h1:ThlnYciV1iM/V0OSF/dtkqWb6xo5qITT1TJBG1M github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DIMO-Network/clickhouse-infra v0.0.5 h1:zY1STwb9+vovpYXdjaeakE29pgZPIJLogJA+h3+IrbM= github.com/DIMO-Network/clickhouse-infra v0.0.5/go.mod h1:XS80lhSJNWBWGgZ+m4j7++zFj1wAXfmtV2gJfhGlabQ= -github.com/DIMO-Network/cloudevent v0.1.4 h1:c6Sq4CyHt05V8OtnEXekUCRGfVuR1pFkJevfiKt1sYM= -github.com/DIMO-Network/cloudevent v0.1.4/go.mod h1:Q2QpMEDYJ+VX0lz9SK2EUFxkuddV1XeF4aQ8LfegB68= +github.com/DIMO-Network/cloudevent v0.1.6 h1:qFKrd+vkfx0TwJHelTtvdTYpUCNmIg8G0RbA/hRh+aQ= +github.com/DIMO-Network/cloudevent v0.1.6/go.mod h1:Q2QpMEDYJ+VX0lz9SK2EUFxkuddV1XeF4aQ8LfegB68= github.com/DIMO-Network/server-garage v0.0.7 h1:kOBVyOtIbxa1x9pAf1epABTb9l/U3khf0PwUaHeHiKs= github.com/DIMO-Network/server-garage v0.0.7/go.mod h1:7DFor8MMJ8fLv9EB16Z5LrN+ftW3qeIk+swpkT7F2cU= github.com/DIMO-Network/shared v1.0.7 h1:LfSgsqJ6R7EUyfo2GTfuhrCpoDcweJqe7eVOa4j7Xbo= @@ -28,8 +30,18 @@ github.com/MicahParks/keyfunc/v2 v2.1.0 h1:6ZXKb9Rp6qp1bDbJefnG7cTH8yMN1IC/4nf+G github.com/MicahParks/keyfunc/v2 v2.1.0/go.mod h1:rW42fi+xgLJ2FRRXAfNx9ZA8WpD4OeE/yHVMteCkw9k= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/agnivade/levenshtein v1.2.1 h1:EHBY3UOn1gwdy/VbFwgo4cxecRznFk7fKWN1KOX7eoM= +github.com/agnivade/levenshtein v1.2.1/go.mod h1:QVVI16kDrtSuwcpd0p1+xMC6Z/VfhtCyDIjcwga4/DU= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ= github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY= +github.com/apache/arrow-go/v18 v18.5.1 h1:yaQ6zxMGgf9YCYw4/oaeOU3AULySDlAYDOcnr4LdHdI= +github.com/apache/arrow-go/v18 v18.5.1/go.mod h1:OCCJsmdq8AsRm8FkBSSmYTwL/s4zHW9CqxeBxEytkNE= +github.com/apache/thrift v0.22.0 h1:r7mTJdj51TMDe6RtcmNdQxgn9XcyfGDOzegMDRg47uc= +github.com/apache/thrift v0.22.0/go.mod h1:1e7J/O1Ae6ZQMTYdy9xa3w9k+XHWPfRvdPyJeynQ+/g= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/aws/aws-sdk-go-v2 v1.38.3 h1:B6cV4oxnMs45fql4yRH+/Po/YU+597zgWqvDpYMturk= github.com/aws/aws-sdk-go-v2 v1.38.3/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.1 h1:i8p8P4diljCr60PpJp6qZXNlgX4m2yQFpYk+9ZT+J4E= @@ -89,6 +101,8 @@ github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5il github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +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 v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI= @@ -136,6 +150,12 @@ github.com/go-openapi/spec v0.20.14/go.mod h1:8EOhTpBoFiask8rrgwbLC3zmJfz4zsCUue github.com/go-openapi/swag v0.22.9 h1:XX2DssF+mQKM2DHsbgZK74y/zj4mo9I99+89xUmuZCE= github.com/go-openapi/swag v0.22.9/go.mod h1:3/OXnFfnMAwBD099SwYRk7GD3xOrr1iL7d/XNLXVVwE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= +github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= +github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM= +github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofiber/contrib/jwt v1.1.2 h1:GmWnOqT4A15EkA8IPXwSpvNUXZR4u5SMj+geBmyLAjs= github.com/gofiber/contrib/jwt v1.1.2/go.mod h1:CpIwrkUQ3Q6IP8y9n3f0wP9bOnSKx39EDp2fBVgMFVk= @@ -158,6 +178,10 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/flatbuffers v25.12.19+incompatible h1:haMV2JRRJCe1998HeW/p0X9UaMTK6SDo0ffLn2+DbLs= +github.com/google/flatbuffers v25.12.19+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -165,6 +189,8 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 h1:sGm2vDRFUrQJO/Veii4h4zG2vvqG6uWNkBHSTqXOZk0= @@ -173,6 +199,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92Bcuy github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= 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/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA= github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= @@ -181,9 +209,13 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= 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/asmfmt v1.3.2 h1:4Ri7ox3EwapiOjCki+hw14RyKk201CN4rzyCJRFLpK4= +github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk= +github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -213,6 +245,10 @@ github.com/mdelapenya/tlscert v0.2.0 h1:7H81W6Z/4weDvZBNOfQte5GpIMo0lGYEeWbkGp5L github.com/mdelapenya/tlscert v0.2.0/go.mod h1:O4njj3ELLnJjGdkN7M/vIVCpZ+Cf0L6muqOG4tLSl8o= github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= +github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpspGNG7Z948v4n35fFGB3RR3G/ry4FWs= +github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= +github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 h1:+n/aFZefKZp7spd8DFdX7uMikMLXX4oubIzJF4kv/wI= +github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= 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/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ= @@ -244,13 +280,14 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt github.com/paulmach/orb v0.11.1 h1:3koVegMC4X/WeiXYz9iswopaTwMem53NzTJuTF20JzU= github.com/paulmach/orb v0.11.1/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU= github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY= -github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= -github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.23 h1:oJE7T90aYBGtFNrI8+KbETnPymobAhzRrR8Mu8n1yfU= +github.com/pierrec/lz4/v4 v4.1.23/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= 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/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/pressly/goose/v3 v3.24.3 h1:DSWWNwwggVUsYZ0X2VitiAa9sKuqtBfe+Jr9zFGwWlM= @@ -278,6 +315,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= +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/sethvargo/go-retry v0.3.0 h1:EEt31A35QhrcRZtrYFDTBg91cqZVnFL2navjDrah2SE= github.com/sethvargo/go-retry v0.3.0/go.mod h1:mNX17F0C/HguQMyMyJxcnU471gOZGxCLyYaFyAZraas= github.com/shirou/gopsutil/v4 v4.25.5 h1:rtd9piuSMGeU8g1RMXjZs9y9luK5BwtnG7dZaQUJAsc= @@ -287,6 +326,8 @@ github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+D github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= 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/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -325,10 +366,14 @@ github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfj github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ= 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/urfave/cli/v3 v3.6.1 h1:j8Qq8NyUawj/7rTYdBGrxcH7A/j7/G8Q5LhWEW4G3Mo= +github.com/urfave/cli/v3 v3.6.1/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.65.0 h1:j/u3uzFEGFfRxw79iYzJN+TteTJwbYkru9uDp3d0Yf8= github.com/valyala/fasthttp v1.65.0/go.mod h1:P/93/YkKPMsKSnATEeELUCkG8a7Y+k99uxNHVbKINr4= +github.com/vektah/gqlparser/v2 v2.5.31 h1:YhWGA1mfTjID7qJhd1+Vxhpk5HTgydrGU9IgkWBTJ7k= +github.com/vektah/gqlparser/v2 v2.5.31/go.mod h1:c1I28gSOVNzlfc4WuDlqU7voQnsqI6OG2amkBAFmgts= github.com/volatiletech/inflect v0.0.1 h1:2a6FcMQyhmPZcLa+uet3VJ8gLn/9svWhJxJYwvE8KsU= github.com/volatiletech/inflect v0.0.1/go.mod h1:IBti31tG6phkHitLlr5j7shC5SOo//x0AjDzaJU1PLA= github.com/volatiletech/null/v8 v8.1.2 h1:kiTiX1PpwvuugKwfvUNX/SU/5A2KGZMXfGD0DUHdKEI= @@ -351,25 +396,29 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= +github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4= 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.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc= -go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -386,8 +435,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk 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-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= -golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= +golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= +golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI= golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ= @@ -397,8 +446,8 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl 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.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= -golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= +golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= +golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -408,8 +457,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL 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-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.45.0 h1:RLBg5JKixCy82FtLJpeNlVM0nrSqpCRYzVU1n8kj0tM= -golang.org/x/net v0.45.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -417,8 +466,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ 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.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= -golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -436,17 +485,19 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2 h1:O1cMQHRfwNpDfDJerqRoE2oD+AFlyid87D40L/OkkJo= +golang.org/x/telemetry v0.0.0-20260109210033-bd525da824e2/go.mod h1:b7fPSJ0pKZ3ccUh8gnTONJxhn3c/PS6tyzQvyqw4iA8= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q= -golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss= +golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= +golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -458,14 +509,14 @@ golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtn 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.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= -golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= +golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= +golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= 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= -golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk= -golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -473,23 +524,23 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c h1:AtEkQdl5b6zsybXcbz00j1LwNodDuH6hVifIaNqk7NQ= -google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c/go.mod h1:ea2MjsO70ssTfCjiwHgI0ZFqcw45Ksuk2ckf9G468GA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c h1:qXWI/sQtv5UKboZ/zUk7h+mrf/lXORyI+n9DKDAusdg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c/go.mod h1:gw1tLEfykwDz2ET4a12jcXt4couGAm7IwsVaTy0Sflo= +google.golang.org/genproto/googleapis/api v0.0.0-20251029180050-ab9386a59fda h1:+2XxjfsAu6vqFxwGBRcHiMaDCuZiqXGDUDVWVtrFAnE= +google.golang.org/genproto/googleapis/api v0.0.0-20251029180050-ab9386a59fda/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda h1:i/Q+bfisr7gq6feoJnS/DlpdwEL4ihp41fvRiM3Ork0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= -google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= +google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/gqlgen.yml b/gqlgen.yml new file mode 100644 index 0000000..0afe1f8 --- /dev/null +++ b/gqlgen.yml @@ -0,0 +1,28 @@ + +schema: + - schema/*.graphqls + +exec: + filename: internal/graph/generated.go + package: graph + + +model: + filename: internal/graph/model/models_gen.go + package: model + + +resolver: + layout: follow-schema + dir: internal/graph + package: graph + filename_template: "{name}.resolvers.go" + + +models: + Time: + model: github.com/99designs/gqlgen/graphql.Time + JSON: + model: github.com/DIMO-Network/cloudevent.RawEvent + CloudEventHeader: + model: github.com/DIMO-Network/cloudevent.CloudEventHeader diff --git a/internal/app/app.go b/internal/app/app.go index 18b6b7f..2abe8c2 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -1,23 +1,35 @@ package app import ( + "bytes" + "context" "fmt" "net/http" "strconv" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/99designs/gqlgen/graphql/handler/extension" + "github.com/99designs/gqlgen/graphql/handler/transport" + "github.com/ClickHouse/clickhouse-go/v2" "github.com/DIMO-Network/fetch-api/internal/config" "github.com/DIMO-Network/fetch-api/internal/fetch/httphandler" "github.com/DIMO-Network/fetch-api/internal/fetch/rpc" + "github.com/DIMO-Network/fetch-api/internal/graph" + "github.com/DIMO-Network/fetch-api/pkg/eventrepo" fetchgrpc "github.com/DIMO-Network/fetch-api/pkg/grpc" "github.com/DIMO-Network/server-garage/pkg/fibercommon" "github.com/DIMO-Network/server-garage/pkg/fibercommon/jwtmiddleware" + "github.com/DIMO-Network/server-garage/pkg/gql/errorhandler" + gqlmetrics "github.com/DIMO-Network/server-garage/pkg/gql/metrics" "github.com/DIMO-Network/shared/pkg/middleware/metrics" "github.com/DIMO-Network/token-exchange-api/pkg/tokenclaims" + "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/cors" "github.com/gofiber/fiber/v2/middleware/recover" "github.com/gofiber/fiber/v2/middleware/redirect" "github.com/gofiber/swagger" + "github.com/golang-jwt/jwt/v5" grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" grpc_ctxtags "github.com/grpc-ecosystem/go-grpc-middleware/tags" "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/recovery" @@ -57,18 +69,23 @@ func CreateWebServer(settings *config.Settings) (*fiber.App, error) { })) app.Get("/swagger/*", swagger.HandlerDefault) - // API v1 routes - v1 := app.Group("/v1") - vehicleGroup := v1.Group("/vehicle") - chConn, err := chClientFromSettings(settings) if err != nil { return nil, fmt.Errorf("failed to create ClickHouse connection: %w", err) } - s3Client := s3ClientFromSettings(settings) - vehHandler := httphandler.NewHandler(chConn, s3Client, - []string{settings.CloudEventBucket, settings.EphemeralBucket, settings.VCBucket}, settings.VehicleNFTAddress, chainId) + buckets := []string{settings.CloudEventBucket, settings.EphemeralBucket} + + // GraphQL endpoint + gqlSrv := newGraphQLHandler(settings, chConn, s3Client, buckets, chainId) + app.Post("/query", jwtAuth, graphQLHandler(gqlSrv)) + app.Get("/query", jwtAuth, graphQLHandler(gqlSrv)) + + // API v1 routes + v1 := app.Group("/v1") + vehicleGroup := v1.Group("/vehicle") + + vehHandler := httphandler.NewHandler(chConn, s3Client, buckets, settings.VehicleNFTAddress, chainId) vehicleMiddleware := jwtmiddleware.AllOfPermissions(settings.VehicleNFTAddress, httphandler.TokenIDParam, []string{tokenclaims.PermissionGetRawData}) @@ -90,7 +107,7 @@ func CreateGRPCServer(logger *zerolog.Logger, settings *config.Settings) (*grpc. s3Client := s3ClientFromSettings(settings) - rpcServer := rpc.NewServer(chConn, s3Client, []string{settings.CloudEventBucket, settings.EphemeralBucket, settings.VCBucket}) + rpcServer := rpc.NewServer(chConn, s3Client, []string{settings.CloudEventBucket, settings.EphemeralBucket}) grpcPanic := metrics.GRPCPanicker{Logger: logger} server := grpc.NewServer( @@ -107,6 +124,99 @@ func CreateGRPCServer(logger *zerolog.Logger, settings *config.Settings) (*grpc. return server, nil } +// newGraphQLHandler creates a configured gqlgen handler.Server. +func newGraphQLHandler(settings *config.Settings, chConn clickhouse.Conn, s3Client *s3.Client, buckets []string, chainID uint64) *handler.Server { + eventService := eventrepo.New(chConn, s3Client) + + resolver := &graph.Resolver{ + EventService: eventService, + Buckets: buckets, + VehicleAddr: settings.VehicleNFTAddress, + ChainID: chainID, + } + + cfg := graph.Config{Resolvers: resolver} + srv := handler.New(graph.NewExecutableSchema(cfg)) + srv.AddTransport(transport.Options{}) + srv.AddTransport(transport.GET{}) + srv.AddTransport(transport.POST{}) + srv.Use(extension.Introspection{}) + srv.Use(extension.FixedComplexityLimit(100)) + srv.Use(gqlmetrics.Tracer{}) + srv.SetErrorPresenter(errorhandler.ErrorPresenter) + return srv +} + +// graphQLHandler bridges Fiber to the gqlgen http.Handler and injects token claims into the request context. +func graphQLHandler(gqlHandler *handler.Server) fiber.Handler { + return func(c *fiber.Ctx) error { + var claims *tokenclaims.Token + if jwtToken, ok := c.Locals(jwtmiddleware.TokenClaimsKey).(*jwt.Token); ok { + claims, _ = jwtToken.Claims.(*tokenclaims.Token) + } + ctx := context.WithValue(c.Context(), graph.ClaimsContextKey{}, claims) + body := c.Body() + var req *http.Request + var err error + if len(body) > 0 { + req, err = http.NewRequestWithContext(ctx, c.Method(), c.OriginalURL(), bytes.NewReader(body)) + } else { + req, err = http.NewRequestWithContext(ctx, c.Method(), c.OriginalURL(), nil) + } + if err != nil { + return err + } + for k, v := range c.GetReqHeaders() { + if len(v) > 0 { + req.Header.Set(k, v[0]) + } + } + w := &fiberResponseWriter{c: c} + gqlHandler.ServeHTTP(w, req) + return nil + } +} + +type fiberResponseWriter struct { + c *fiber.Ctx + header http.Header + status int + committed bool +} + +func (w *fiberResponseWriter) Header() http.Header { + if w.header == nil { + w.header = make(http.Header) + } + return w.header +} + +func (w *fiberResponseWriter) commit() { + if w.committed { + return + } + w.committed = true + if w.status == 0 { + w.status = http.StatusOK + } + w.c.Status(w.status) + for k, v := range w.header { + for _, vv := range v { + w.c.Set(k, vv) + } + } +} + +func (w *fiberResponseWriter) Write(b []byte) (int, error) { + w.commit() + return w.c.Write(b) +} + +func (w *fiberResponseWriter) WriteHeader(statusCode int) { + w.status = statusCode + w.commit() +} + // HealthCheck godoc // @Summary Show the status of server. // @Description get the status of server. diff --git a/internal/config/settings.go b/internal/config/settings.go index 03c7c83..934ebcd 100644 --- a/internal/config/settings.go +++ b/internal/config/settings.go @@ -18,7 +18,6 @@ type Settings struct { ChainID string `env:"CHAIN_ID"` CloudEventBucket string `env:"CLOUDEVENT_BUCKET"` EphemeralBucket string `env:"EPHEMERAL_BUCKET"` - VCBucket string `env:"VC_BUCKET"` S3AWSRegion string `env:"S3_AWS_REGION"` S3AWSAccessKeyID string `env:"S3_AWS_ACCESS_KEY_ID"` S3AWSSecretAccessKey string `env:"S3_AWS_SECRET_ACCESS_KEY"` diff --git a/internal/fetch/fetch.go b/internal/fetch/fetch.go index de3100d..2238a8c 100644 --- a/internal/fetch/fetch.go +++ b/internal/fetch/fetch.go @@ -17,7 +17,7 @@ import ( const fetchers = 25 // ListCloudEventsFromIndexes fetches a list of cloud events from the index service by trying to get them from each bucket in the list returning the first successful result. -func ListCloudEventsFromIndexes(ctx context.Context, evtSvc *eventrepo.Service, indexKeys []cloudevent.CloudEvent[eventrepo.ObjectInfo], buckets []string) ([]cloudevent.CloudEvent[json.RawMessage], error) { +func ListCloudEventsFromIndexes(ctx context.Context, evtSvc *eventrepo.Service, indexKeys []cloudevent.CloudEvent[eventrepo.ObjectInfo], buckets []string) ([]cloudevent.RawEvent, error) { objectsByKeys := map[string]json.RawMessage{} // mutex to protect concurrent access to the map var mutex sync.RWMutex @@ -55,18 +55,17 @@ func ListCloudEventsFromIndexes(ctx context.Context, evtSvc *eventrepo.Service, } // create a slice of cloud events - dataObjects := make([]cloudevent.CloudEvent[json.RawMessage], len(indexKeys)) + dataObjects := make([]cloudevent.RawEvent, len(indexKeys)) for i, objectInfo := range indexKeys { - event := cloudevent.CloudEvent[json.RawMessage]{CloudEventHeader: objectInfo.CloudEventHeader, Data: objectsByKeys[objectInfo.Data.Key]} - dataObjects[i] = event + dataObjects[i] = cloudevent.RawEvent{CloudEventHeader: objectInfo.CloudEventHeader, Data: objectsByKeys[objectInfo.Data.Key]} } return dataObjects, nil } -// GetCloudEventFromKey gets an object from the index service by trying to get it from each bucket in the list returning the first successful result. -func GetCloudEventFromIndex(ctx context.Context, evtSvc *eventrepo.Service, indexKeys cloudevent.CloudEvent[eventrepo.ObjectInfo], buckets []string) (cloudevent.CloudEvent[json.RawMessage], error) { - var obj cloudevent.CloudEvent[json.RawMessage] +// GetCloudEventFromIndex gets an object from the index service by trying to get it from each bucket in the list returning the first successful result. +func GetCloudEventFromIndex(ctx context.Context, evtSvc *eventrepo.Service, indexKeys cloudevent.CloudEvent[eventrepo.ObjectInfo], buckets []string) (cloudevent.RawEvent, error) { + var obj cloudevent.RawEvent var err error // Try to get the object from each bucket in the list for _, bucket := range buckets { @@ -76,9 +75,9 @@ func GetCloudEventFromIndex(ctx context.Context, evtSvc *eventrepo.Service, inde if errors.As(err, ¬FoundErr) { continue } - return cloudevent.CloudEvent[json.RawMessage]{}, fmt.Errorf("failed to get object: %w", err) + return cloudevent.RawEvent{}, fmt.Errorf("failed to get object: %w", err) } return obj, nil } - return cloudevent.CloudEvent[json.RawMessage]{}, fmt.Errorf("failed to get object: %w", err) + return cloudevent.RawEvent{}, fmt.Errorf("failed to get object: %w", err) } diff --git a/internal/fetch/httphandler/httphandler.go b/internal/fetch/httphandler/httphandler.go index 3df5a68..3ad7247 100644 --- a/internal/fetch/httphandler/httphandler.go +++ b/internal/fetch/httphandler/httphandler.go @@ -28,7 +28,10 @@ const ( errTimeout = "request exceeded or is estimated to exceed the maximum execution time" ) -type cloudReturn cloudevent.CloudEvent[eventrepo.ObjectInfo] //nolint:unused // Used in OpenAPI docs +// cloudReturn is used by swag for OpenAPI response types (see @Success annotations). +type cloudReturn cloudevent.CloudEvent[eventrepo.ObjectInfo] + +var _ = (*cloudReturn)(nil) // ensure type is used for staticcheck // Handler is the HTTP handler for the fetch service. type Handler struct { @@ -164,7 +167,7 @@ func (h *Handler) GetIndexKeys(fCtx *fiber.Ctx) error { // @Produce json // @Param params query searchParams false "Search parameters" // @Param tokenId path string true "Token ID" -// @Success 200 {object} []cloudevent.CloudEvent[json.RawMessage] "Returns latest object data" +// @Success 200 {object} []cloudevent.RawEvent "Returns latest object data" // @Failure 400 {object} map[string]string "Invalid request" // @Failure 500 {object} map[string]string "Server error" // @Router /v1/vehicle/objects/{tokenId} [get] @@ -203,7 +206,7 @@ func (h *Handler) GetObjects(fCtx *fiber.Ctx) error { // @Produce json // @Param params query searchParams false "Search parameters" // @Param tokenId path string true "Token ID" -// @Success 200 {object} cloudevent.CloudEvent[json.RawMessage] "Returns latest object data" +// @Success 200 {object} cloudevent.RawEvent "Returns latest object data" // @Failure 400 {object} map[string]string "Invalid request" // @Failure 500 {object} map[string]string "Server error" // @Router /v1/vehicle/latest-object/{tokenId} [get] diff --git a/internal/graph/base.resolvers.go b/internal/graph/base.resolvers.go new file mode 100644 index 0000000..0f645a0 --- /dev/null +++ b/internal/graph/base.resolvers.go @@ -0,0 +1,96 @@ +package graph + +// This file will be automatically regenerated based on the schema, any resolver +// implementations +// will be copied through when generating and any unknown code will be moved to the end. +// Code generated by github.com/99designs/gqlgen version v0.17.86 + +import ( + "context" + "database/sql" + "encoding/json" + "errors" + + "github.com/DIMO-Network/cloudevent" + "github.com/DIMO-Network/fetch-api/internal/fetch" + "github.com/DIMO-Network/fetch-api/internal/graph/model" +) + +// LatestIndex is the resolver for the latestIndex field. +func (r *queryResolver) LatestIndex(ctx context.Context, tokenID int, filter *model.CloudEventFilter) (*model.CloudEventIndex, error) { + opts, err := r.requireVehicleOpts(ctx, tokenID, filter) + if err != nil { + return nil, err + } + idx, err := r.EventService.GetLatestIndex(ctx, opts) + if err != nil { + return nil, err + } + return indexToModel(idx), nil +} + +// Indexes is the resolver for the indexes field. +func (r *queryResolver) Indexes(ctx context.Context, tokenID int, limit *int, filter *model.CloudEventFilter) ([]*model.CloudEventIndex, error) { + opts, err := r.requireVehicleOpts(ctx, tokenID, filter) + if err != nil { + return nil, err + } + list, err := r.EventService.ListIndexes(ctx, resolveLimit(limit), opts) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return emptyCloudEventIndexList, nil + } + return nil, err + } + out := make([]*model.CloudEventIndex, len(list)) + for i := range list { + out[i] = indexToModel(list[i]) + } + return out, nil +} + +// LatestCloudEvent is the resolver for the latestCloudEvent field. +func (r *queryResolver) LatestCloudEvent(ctx context.Context, tokenID int, filter *model.CloudEventFilter) (*cloudevent.CloudEvent[json.RawMessage], error) { + opts, err := r.requireVehicleOpts(ctx, tokenID, filter) + if err != nil { + return nil, err + } + idx, err := r.EventService.GetLatestIndex(ctx, opts) + if err != nil { + return nil, err + } + ce, err := fetch.GetCloudEventFromIndex(ctx, r.EventService, idx, r.Buckets) + if err != nil { + return nil, err + } + return &ce, nil +} + +// CloudEvents is the resolver for the cloudEvents field. +func (r *queryResolver) CloudEvents(ctx context.Context, tokenID int, limit *int, filter *model.CloudEventFilter) ([]*cloudevent.CloudEvent[json.RawMessage], error) { + opts, err := r.requireVehicleOpts(ctx, tokenID, filter) + if err != nil { + return nil, err + } + list, err := r.EventService.ListIndexes(ctx, resolveLimit(limit), opts) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return emptyCloudEventList, nil + } + return nil, err + } + events, err := fetch.ListCloudEventsFromIndexes(ctx, r.EventService, list, r.Buckets) + if err != nil { + return nil, err + } + out := make([]*cloudevent.RawEvent, len(events)) + for i := range events { + out[i] = &events[i] + } + return out, nil +} + +// Query returns QueryResolver implementation. +func (r *Resolver) Query() QueryResolver { return &queryResolver{r} } + +type queryResolver struct{ *Resolver } diff --git a/internal/graph/convert.go b/internal/graph/convert.go new file mode 100644 index 0000000..2045cfe --- /dev/null +++ b/internal/graph/convert.go @@ -0,0 +1,75 @@ +package graph + +import ( + "math/big" + + "github.com/DIMO-Network/cloudevent" + "github.com/DIMO-Network/fetch-api/internal/graph/model" + "github.com/DIMO-Network/fetch-api/pkg/eventrepo" + "github.com/DIMO-Network/fetch-api/pkg/grpc" + "github.com/ethereum/go-ethereum/common" + "google.golang.org/protobuf/types/known/timestamppb" + "google.golang.org/protobuf/types/known/wrapperspb" +) + +// filterToSearchOptions converts GraphQL filter and tokenID to grpc.SearchOptions. +func filterToSearchOptions(filter *model.CloudEventFilter, subject cloudevent.ERC721DID) *grpc.SearchOptions { + opts := &grpc.SearchOptions{ + Subject: &wrapperspb.StringValue{Value: subject.String()}, + } + if filter == nil { + return opts + } + if filter.ID != nil { + opts.Id = &wrapperspb.StringValue{Value: *filter.ID} + } + if filter.Type != nil { + opts.Type = &wrapperspb.StringValue{Value: *filter.Type} + } + if filter.Source != nil { + opts.Source = &wrapperspb.StringValue{Value: *filter.Source} + } + if filter.Producer != nil { + opts.Producer = &wrapperspb.StringValue{Value: *filter.Producer} + } + if filter.Before != nil { + opts.Before = timestamppb.New(*filter.Before) + } + if filter.After != nil { + opts.After = timestamppb.New(*filter.After) + } + return opts +} + +const defaultLimit = 10 + +// Preallocated empty slices for list resolvers to avoid allocating on sql.ErrNoRows. +var ( + emptyCloudEventIndexList = []*model.CloudEventIndex{} + emptyCloudEventList = []*cloudevent.RawEvent{} +) + +func resolveLimit(limit *int) int { + if limit != nil && *limit > 0 { + return *limit + } + return defaultLimit +} + +func subjectFromTokenID(vehicleAddr common.Address, chainID uint64, tokenID int) cloudevent.ERC721DID { + return cloudevent.ERC721DID{ + ChainID: chainID, + ContractAddress: vehicleAddr, + TokenID: big.NewInt(int64(tokenID)), + } +} + +// indexToModel converts a CloudEvent index entry to the GraphQL model, +// using the CloudEventHeader from the library directly. +func indexToModel(idx cloudevent.CloudEvent[eventrepo.ObjectInfo]) *model.CloudEventIndex { + return &model.CloudEventIndex{ + Header: &idx.CloudEventHeader, + IndexKey: idx.Data.Key, + } +} + diff --git a/internal/graph/convert_test.go b/internal/graph/convert_test.go new file mode 100644 index 0000000..2717259 --- /dev/null +++ b/internal/graph/convert_test.go @@ -0,0 +1,55 @@ +package graph + +import ( + "testing" + "time" + + "github.com/DIMO-Network/cloudevent" + "github.com/DIMO-Network/fetch-api/pkg/eventrepo" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestIndexToModel(t *testing.T) { + t.Run("header bound directly from library type", func(t *testing.T) { + idx := cloudevent.CloudEvent[eventrepo.ObjectInfo]{ + CloudEventHeader: cloudevent.CloudEventHeader{ + ID: "test-id", + Source: "0xABC", + Producer: "prod", + Subject: "subj", + Time: time.Date(2026, 2, 17, 1, 0, 0, 0, time.UTC), + Type: "dimo.status", + DataContentType: "application/json", + DataVersion: "r/v0/s", + }, + Data: eventrepo.ObjectInfo{Key: "s3://bucket/key"}, + } + out := indexToModel(idx) + + require.NotNil(t, out.Header) + assert.Equal(t, "test-id", out.Header.ID) + assert.Equal(t, "0xABC", out.Header.Source) + assert.Equal(t, "dimo.status", out.Header.Type) + assert.Equal(t, "application/json", out.Header.DataContentType) + assert.Equal(t, "r/v0/s", out.Header.DataVersion) + assert.Equal(t, "s3://bucket/key", out.IndexKey) + }) + + t.Run("empty optional fields remain zero values", func(t *testing.T) { + idx := cloudevent.CloudEvent[eventrepo.ObjectInfo]{ + CloudEventHeader: cloudevent.CloudEventHeader{ + ID: "test-id", + Source: "src", + Subject: "subj", + Type: "dimo.status", + }, + Data: eventrepo.ObjectInfo{Key: "key"}, + } + out := indexToModel(idx) + + assert.Empty(t, out.Header.DataContentType) + assert.Empty(t, out.Header.DataVersion) + assert.Empty(t, out.Header.Signature) + }) +} diff --git a/internal/graph/generated.go b/internal/graph/generated.go new file mode 100644 index 0000000..6cd36f3 --- /dev/null +++ b/internal/graph/generated.go @@ -0,0 +1,4172 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package graph + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "strconv" + "sync" + "sync/atomic" + "time" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/introspection" + "github.com/DIMO-Network/cloudevent" + "github.com/DIMO-Network/fetch-api/internal/graph/model" + gqlparser "github.com/vektah/gqlparser/v2" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. +func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { + return &executableSchema{ + schema: cfg.Schema, + resolvers: cfg.Resolvers, + directives: cfg.Directives, + complexity: cfg.Complexity, + } +} + +type Config struct { + Schema *ast.Schema + Resolvers ResolverRoot + Directives DirectiveRoot + Complexity ComplexityRoot +} + +type ResolverRoot interface { + Query() QueryResolver +} + +type DirectiveRoot struct { +} + +type ComplexityRoot struct { + CloudEventHeader struct { + DataContentType func(childComplexity int) int + DataSchema func(childComplexity int) int + DataVersion func(childComplexity int) int + ID func(childComplexity int) int + Producer func(childComplexity int) int + Signature func(childComplexity int) int + Source func(childComplexity int) int + SpecVersion func(childComplexity int) int + Subject func(childComplexity int) int + Tags func(childComplexity int) int + Time func(childComplexity int) int + Type func(childComplexity int) int + } + + CloudEventIndex struct { + Header func(childComplexity int) int + IndexKey func(childComplexity int) int + } + + Query struct { + CloudEvents func(childComplexity int, tokenID int, limit *int, filter *model.CloudEventFilter) int + Indexes func(childComplexity int, tokenID int, limit *int, filter *model.CloudEventFilter) int + LatestCloudEvent func(childComplexity int, tokenID int, filter *model.CloudEventFilter) int + LatestIndex func(childComplexity int, tokenID int, filter *model.CloudEventFilter) int + } +} + +type QueryResolver interface { + LatestIndex(ctx context.Context, tokenID int, filter *model.CloudEventFilter) (*model.CloudEventIndex, error) + Indexes(ctx context.Context, tokenID int, limit *int, filter *model.CloudEventFilter) ([]*model.CloudEventIndex, error) + LatestCloudEvent(ctx context.Context, tokenID int, filter *model.CloudEventFilter) (*cloudevent.CloudEvent[json.RawMessage], error) + CloudEvents(ctx context.Context, tokenID int, limit *int, filter *model.CloudEventFilter) ([]*cloudevent.CloudEvent[json.RawMessage], error) +} + +type executableSchema struct { + schema *ast.Schema + resolvers ResolverRoot + directives DirectiveRoot + complexity ComplexityRoot +} + +func (e *executableSchema) Schema() *ast.Schema { + if e.schema != nil { + return e.schema + } + return parsedSchema +} + +func (e *executableSchema) Complexity(ctx context.Context, typeName, field string, childComplexity int, rawArgs map[string]any) (int, bool) { + ec := executionContext{nil, e, 0, 0, nil} + _ = ec + switch typeName + "." + field { + + case "CloudEventHeader.datacontenttype": + if e.complexity.CloudEventHeader.DataContentType == nil { + break + } + + return e.complexity.CloudEventHeader.DataContentType(childComplexity), true + case "CloudEventHeader.dataschema": + if e.complexity.CloudEventHeader.DataSchema == nil { + break + } + + return e.complexity.CloudEventHeader.DataSchema(childComplexity), true + case "CloudEventHeader.dataversion": + if e.complexity.CloudEventHeader.DataVersion == nil { + break + } + + return e.complexity.CloudEventHeader.DataVersion(childComplexity), true + case "CloudEventHeader.id": + if e.complexity.CloudEventHeader.ID == nil { + break + } + + return e.complexity.CloudEventHeader.ID(childComplexity), true + case "CloudEventHeader.producer": + if e.complexity.CloudEventHeader.Producer == nil { + break + } + + return e.complexity.CloudEventHeader.Producer(childComplexity), true + case "CloudEventHeader.signature": + if e.complexity.CloudEventHeader.Signature == nil { + break + } + + return e.complexity.CloudEventHeader.Signature(childComplexity), true + case "CloudEventHeader.source": + if e.complexity.CloudEventHeader.Source == nil { + break + } + + return e.complexity.CloudEventHeader.Source(childComplexity), true + case "CloudEventHeader.specversion": + if e.complexity.CloudEventHeader.SpecVersion == nil { + break + } + + return e.complexity.CloudEventHeader.SpecVersion(childComplexity), true + case "CloudEventHeader.subject": + if e.complexity.CloudEventHeader.Subject == nil { + break + } + + return e.complexity.CloudEventHeader.Subject(childComplexity), true + case "CloudEventHeader.tags": + if e.complexity.CloudEventHeader.Tags == nil { + break + } + + return e.complexity.CloudEventHeader.Tags(childComplexity), true + case "CloudEventHeader.time": + if e.complexity.CloudEventHeader.Time == nil { + break + } + + return e.complexity.CloudEventHeader.Time(childComplexity), true + case "CloudEventHeader.type": + if e.complexity.CloudEventHeader.Type == nil { + break + } + + return e.complexity.CloudEventHeader.Type(childComplexity), true + + case "CloudEventIndex.header": + if e.complexity.CloudEventIndex.Header == nil { + break + } + + return e.complexity.CloudEventIndex.Header(childComplexity), true + case "CloudEventIndex.indexKey": + if e.complexity.CloudEventIndex.IndexKey == nil { + break + } + + return e.complexity.CloudEventIndex.IndexKey(childComplexity), true + + case "Query.cloudEvents": + if e.complexity.Query.CloudEvents == nil { + break + } + + args, err := ec.field_Query_cloudEvents_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.CloudEvents(childComplexity, args["tokenId"].(int), args["limit"].(*int), args["filter"].(*model.CloudEventFilter)), true + case "Query.indexes": + if e.complexity.Query.Indexes == nil { + break + } + + args, err := ec.field_Query_indexes_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.Indexes(childComplexity, args["tokenId"].(int), args["limit"].(*int), args["filter"].(*model.CloudEventFilter)), true + case "Query.latestCloudEvent": + if e.complexity.Query.LatestCloudEvent == nil { + break + } + + args, err := ec.field_Query_latestCloudEvent_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.LatestCloudEvent(childComplexity, args["tokenId"].(int), args["filter"].(*model.CloudEventFilter)), true + case "Query.latestIndex": + if e.complexity.Query.LatestIndex == nil { + break + } + + args, err := ec.field_Query_latestIndex_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.LatestIndex(childComplexity, args["tokenId"].(int), args["filter"].(*model.CloudEventFilter)), true + + } + return 0, false +} + +func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { + opCtx := graphql.GetOperationContext(ctx) + ec := executionContext{opCtx, e, 0, 0, make(chan graphql.DeferredResult)} + inputUnmarshalMap := graphql.BuildUnmarshalerMap( + ec.unmarshalInputCloudEventFilter, + ) + first := true + + switch opCtx.Operation.Operation { + case ast.Query: + return func(ctx context.Context) *graphql.Response { + var response graphql.Response + var data graphql.Marshaler + if first { + first = false + ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap) + data = ec._Query(ctx, opCtx.Operation.SelectionSet) + } else { + if atomic.LoadInt32(&ec.pendingDeferred) > 0 { + result := <-ec.deferredResults + atomic.AddInt32(&ec.pendingDeferred, -1) + data = result.Result + response.Path = result.Path + response.Label = result.Label + response.Errors = result.Errors + } else { + return nil + } + } + var buf bytes.Buffer + data.MarshalGQL(&buf) + response.Data = buf.Bytes() + if atomic.LoadInt32(&ec.deferred) > 0 { + hasNext := atomic.LoadInt32(&ec.pendingDeferred) > 0 + response.HasNext = &hasNext + } + + return &response + } + + default: + return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) + } +} + +type executionContext struct { + *graphql.OperationContext + *executableSchema + deferred int32 + pendingDeferred int32 + deferredResults chan graphql.DeferredResult +} + +func (ec *executionContext) processDeferredGroup(dg graphql.DeferredGroup) { + atomic.AddInt32(&ec.pendingDeferred, 1) + go func() { + ctx := graphql.WithFreshResponseContext(dg.Context) + dg.FieldSet.Dispatch(ctx) + ds := graphql.DeferredResult{ + Path: dg.Path, + Label: dg.Label, + Result: dg.FieldSet, + Errors: graphql.GetErrors(ctx), + } + // null fields should bubble up + if dg.FieldSet.Invalids > 0 { + ds.Result = graphql.Null + } + ec.deferredResults <- ds + }() +} + +func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapSchema(ec.Schema()), nil +} + +func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapTypeFromDef(ec.Schema(), ec.Schema().Types[name]), nil +} + +var sources = []*ast.Source{ + {Name: "../../schema/base.graphqls", Input: `""" +A point in time, encoded per RFC-3339. Typically in UTC. +""" +scalar Time + +""" +Arbitrary JSON payload (e.g. cloud event data). +""" +scalar JSON @specifiedBy(url: "https://ibm.github.io/graphql-specs/custom-scalars/json.html") + +""" +The root query type for the Fetch API GraphQL schema. +""" +type Query { + """ + Latest cloud event index matching filters. + """ + latestIndex(tokenId: Int!, filter: CloudEventFilter): CloudEventIndex! + + """ + List cloud event indexes matching filters. + """ + indexes(tokenId: Int!, limit: Int = 10, filter: CloudEventFilter): [CloudEventIndex!]! + + """ + Latest full cloud event as JSON. + """ + latestCloudEvent(tokenId: Int!, filter: CloudEventFilter): JSON! + + """ + List full cloud events as JSON. + """ + cloudEvents(tokenId: Int!, limit: Int = 10, filter: CloudEventFilter): [JSON!]! +} + +""" +CloudEvents header fields per the CloudEvents v1.0 spec. +""" +type CloudEventHeader { + id: String! + source: String! + producer: String! + specversion: String! + subject: String! + time: Time! + type: String! + datacontenttype: String + dataschema: String + dataversion: String + signature: String + tags: [String!] +} + +""" +Cloud event index entry: typed header + storage key. +""" +type CloudEventIndex { + header: CloudEventHeader! + indexKey: String! +} + +input CloudEventFilter { + id: String + type: String + source: String + producer: String + before: Time + after: Time +} +`, BuiltIn: false}, +} +var parsedSchema = gqlparser.MustLoadSchema(sources...) + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "name", ec.unmarshalNString2string) + if err != nil { + return nil, err + } + args["name"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_cloudEvents_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "tokenId", ec.unmarshalNInt2int) + if err != nil { + return nil, err + } + args["tokenId"] = arg0 + arg1, err := graphql.ProcessArgField(ctx, rawArgs, "limit", ec.unmarshalOInt2ᚖint) + if err != nil { + return nil, err + } + args["limit"] = arg1 + arg2, err := graphql.ProcessArgField(ctx, rawArgs, "filter", ec.unmarshalOCloudEventFilter2ᚖgithubᚗcomᚋDIMOᚑNetworkᚋfetchᚑapiᚋinternalᚋgraphᚋmodelᚐCloudEventFilter) + if err != nil { + return nil, err + } + args["filter"] = arg2 + return args, nil +} + +func (ec *executionContext) field_Query_indexes_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "tokenId", ec.unmarshalNInt2int) + if err != nil { + return nil, err + } + args["tokenId"] = arg0 + arg1, err := graphql.ProcessArgField(ctx, rawArgs, "limit", ec.unmarshalOInt2ᚖint) + if err != nil { + return nil, err + } + args["limit"] = arg1 + arg2, err := graphql.ProcessArgField(ctx, rawArgs, "filter", ec.unmarshalOCloudEventFilter2ᚖgithubᚗcomᚋDIMOᚑNetworkᚋfetchᚑapiᚋinternalᚋgraphᚋmodelᚐCloudEventFilter) + if err != nil { + return nil, err + } + args["filter"] = arg2 + return args, nil +} + +func (ec *executionContext) field_Query_latestCloudEvent_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "tokenId", ec.unmarshalNInt2int) + if err != nil { + return nil, err + } + args["tokenId"] = arg0 + arg1, err := graphql.ProcessArgField(ctx, rawArgs, "filter", ec.unmarshalOCloudEventFilter2ᚖgithubᚗcomᚋDIMOᚑNetworkᚋfetchᚑapiᚋinternalᚋgraphᚋmodelᚐCloudEventFilter) + if err != nil { + return nil, err + } + args["filter"] = arg1 + return args, nil +} + +func (ec *executionContext) field_Query_latestIndex_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "tokenId", ec.unmarshalNInt2int) + if err != nil { + return nil, err + } + args["tokenId"] = arg0 + arg1, err := graphql.ProcessArgField(ctx, rawArgs, "filter", ec.unmarshalOCloudEventFilter2ᚖgithubᚗcomᚋDIMOᚑNetworkᚋfetchᚑapiᚋinternalᚋgraphᚋmodelᚐCloudEventFilter) + if err != nil { + return nil, err + } + args["filter"] = arg1 + return args, nil +} + +func (ec *executionContext) field___Directive_args_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "includeDeprecated", ec.unmarshalOBoolean2ᚖbool) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} + +func (ec *executionContext) field___Field_args_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "includeDeprecated", ec.unmarshalOBoolean2ᚖbool) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} + +func (ec *executionContext) field___Type_enumValues_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "includeDeprecated", ec.unmarshalOBoolean2bool) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} + +func (ec *executionContext) field___Type_fields_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "includeDeprecated", ec.unmarshalOBoolean2bool) + if err != nil { + return nil, err + } + args["includeDeprecated"] = arg0 + return args, nil +} + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _CloudEventHeader_id(ctx context.Context, field graphql.CollectedField, obj *cloudevent.CloudEventHeader) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_CloudEventHeader_id, + func(ctx context.Context) (any, error) { + return obj.ID, nil + }, + nil, + ec.marshalNString2string, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_CloudEventHeader_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CloudEventHeader", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CloudEventHeader_source(ctx context.Context, field graphql.CollectedField, obj *cloudevent.CloudEventHeader) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_CloudEventHeader_source, + func(ctx context.Context) (any, error) { + return obj.Source, nil + }, + nil, + ec.marshalNString2string, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_CloudEventHeader_source(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CloudEventHeader", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CloudEventHeader_producer(ctx context.Context, field graphql.CollectedField, obj *cloudevent.CloudEventHeader) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_CloudEventHeader_producer, + func(ctx context.Context) (any, error) { + return obj.Producer, nil + }, + nil, + ec.marshalNString2string, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_CloudEventHeader_producer(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CloudEventHeader", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CloudEventHeader_specversion(ctx context.Context, field graphql.CollectedField, obj *cloudevent.CloudEventHeader) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_CloudEventHeader_specversion, + func(ctx context.Context) (any, error) { + return obj.SpecVersion, nil + }, + nil, + ec.marshalNString2string, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_CloudEventHeader_specversion(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CloudEventHeader", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CloudEventHeader_subject(ctx context.Context, field graphql.CollectedField, obj *cloudevent.CloudEventHeader) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_CloudEventHeader_subject, + func(ctx context.Context) (any, error) { + return obj.Subject, nil + }, + nil, + ec.marshalNString2string, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_CloudEventHeader_subject(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CloudEventHeader", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CloudEventHeader_time(ctx context.Context, field graphql.CollectedField, obj *cloudevent.CloudEventHeader) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_CloudEventHeader_time, + func(ctx context.Context) (any, error) { + return obj.Time, nil + }, + nil, + ec.marshalNTime2timeᚐTime, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_CloudEventHeader_time(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CloudEventHeader", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Time does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CloudEventHeader_type(ctx context.Context, field graphql.CollectedField, obj *cloudevent.CloudEventHeader) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_CloudEventHeader_type, + func(ctx context.Context) (any, error) { + return obj.Type, nil + }, + nil, + ec.marshalNString2string, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_CloudEventHeader_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CloudEventHeader", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CloudEventHeader_datacontenttype(ctx context.Context, field graphql.CollectedField, obj *cloudevent.CloudEventHeader) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_CloudEventHeader_datacontenttype, + func(ctx context.Context) (any, error) { + return obj.DataContentType, nil + }, + nil, + ec.marshalOString2string, + true, + false, + ) +} + +func (ec *executionContext) fieldContext_CloudEventHeader_datacontenttype(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CloudEventHeader", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CloudEventHeader_dataschema(ctx context.Context, field graphql.CollectedField, obj *cloudevent.CloudEventHeader) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_CloudEventHeader_dataschema, + func(ctx context.Context) (any, error) { + return obj.DataSchema, nil + }, + nil, + ec.marshalOString2string, + true, + false, + ) +} + +func (ec *executionContext) fieldContext_CloudEventHeader_dataschema(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CloudEventHeader", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CloudEventHeader_dataversion(ctx context.Context, field graphql.CollectedField, obj *cloudevent.CloudEventHeader) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_CloudEventHeader_dataversion, + func(ctx context.Context) (any, error) { + return obj.DataVersion, nil + }, + nil, + ec.marshalOString2string, + true, + false, + ) +} + +func (ec *executionContext) fieldContext_CloudEventHeader_dataversion(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CloudEventHeader", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CloudEventHeader_signature(ctx context.Context, field graphql.CollectedField, obj *cloudevent.CloudEventHeader) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_CloudEventHeader_signature, + func(ctx context.Context) (any, error) { + return obj.Signature, nil + }, + nil, + ec.marshalOString2string, + true, + false, + ) +} + +func (ec *executionContext) fieldContext_CloudEventHeader_signature(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CloudEventHeader", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CloudEventHeader_tags(ctx context.Context, field graphql.CollectedField, obj *cloudevent.CloudEventHeader) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_CloudEventHeader_tags, + func(ctx context.Context) (any, error) { + return obj.Tags, nil + }, + nil, + ec.marshalOString2ᚕstringᚄ, + true, + false, + ) +} + +func (ec *executionContext) fieldContext_CloudEventHeader_tags(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CloudEventHeader", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CloudEventIndex_header(ctx context.Context, field graphql.CollectedField, obj *model.CloudEventIndex) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_CloudEventIndex_header, + func(ctx context.Context) (any, error) { + return obj.Header, nil + }, + nil, + ec.marshalNCloudEventHeader2ᚖgithubᚗcomᚋDIMOᚑNetworkᚋcloudeventᚐCloudEventHeader, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_CloudEventIndex_header(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CloudEventIndex", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_CloudEventHeader_id(ctx, field) + case "source": + return ec.fieldContext_CloudEventHeader_source(ctx, field) + case "producer": + return ec.fieldContext_CloudEventHeader_producer(ctx, field) + case "specversion": + return ec.fieldContext_CloudEventHeader_specversion(ctx, field) + case "subject": + return ec.fieldContext_CloudEventHeader_subject(ctx, field) + case "time": + return ec.fieldContext_CloudEventHeader_time(ctx, field) + case "type": + return ec.fieldContext_CloudEventHeader_type(ctx, field) + case "datacontenttype": + return ec.fieldContext_CloudEventHeader_datacontenttype(ctx, field) + case "dataschema": + return ec.fieldContext_CloudEventHeader_dataschema(ctx, field) + case "dataversion": + return ec.fieldContext_CloudEventHeader_dataversion(ctx, field) + case "signature": + return ec.fieldContext_CloudEventHeader_signature(ctx, field) + case "tags": + return ec.fieldContext_CloudEventHeader_tags(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type CloudEventHeader", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _CloudEventIndex_indexKey(ctx context.Context, field graphql.CollectedField, obj *model.CloudEventIndex) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_CloudEventIndex_indexKey, + func(ctx context.Context) (any, error) { + return obj.IndexKey, nil + }, + nil, + ec.marshalNString2string, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_CloudEventIndex_indexKey(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CloudEventIndex", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Query_latestIndex(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Query_latestIndex, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.resolvers.Query().LatestIndex(ctx, fc.Args["tokenId"].(int), fc.Args["filter"].(*model.CloudEventFilter)) + }, + nil, + ec.marshalNCloudEventIndex2ᚖgithubᚗcomᚋDIMOᚑNetworkᚋfetchᚑapiᚋinternalᚋgraphᚋmodelᚐCloudEventIndex, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_Query_latestIndex(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "header": + return ec.fieldContext_CloudEventIndex_header(ctx, field) + case "indexKey": + return ec.fieldContext_CloudEventIndex_indexKey(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type CloudEventIndex", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_latestIndex_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_indexes(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Query_indexes, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.resolvers.Query().Indexes(ctx, fc.Args["tokenId"].(int), fc.Args["limit"].(*int), fc.Args["filter"].(*model.CloudEventFilter)) + }, + nil, + ec.marshalNCloudEventIndex2ᚕᚖgithubᚗcomᚋDIMOᚑNetworkᚋfetchᚑapiᚋinternalᚋgraphᚋmodelᚐCloudEventIndexᚄ, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_Query_indexes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "header": + return ec.fieldContext_CloudEventIndex_header(ctx, field) + case "indexKey": + return ec.fieldContext_CloudEventIndex_indexKey(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type CloudEventIndex", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_indexes_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_latestCloudEvent(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Query_latestCloudEvent, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.resolvers.Query().LatestCloudEvent(ctx, fc.Args["tokenId"].(int), fc.Args["filter"].(*model.CloudEventFilter)) + }, + nil, + ec.marshalNJSON2ᚖgithubᚗcomᚋDIMOᚑNetworkᚋcloudeventᚐCloudEvent, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_Query_latestCloudEvent(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type JSON does not have child fields") + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_latestCloudEvent_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_cloudEvents(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Query_cloudEvents, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.resolvers.Query().CloudEvents(ctx, fc.Args["tokenId"].(int), fc.Args["limit"].(*int), fc.Args["filter"].(*model.CloudEventFilter)) + }, + nil, + ec.marshalNJSON2ᚕᚖgithubᚗcomᚋDIMOᚑNetworkᚋcloudeventᚐCloudEventᚄ, + true, + true, + ) +} + +func (ec *executionContext) fieldContext_Query_cloudEvents(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type JSON does not have child fields") + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_cloudEvents_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Query___type, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.introspectType(fc.Args["name"].(string)) + }, + nil, + ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType, + true, + false, + ) +} + +func (ec *executionContext) fieldContext_Query___type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query___type_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext_Query___schema, + func(ctx context.Context) (any, error) { + return ec.introspectSchema() + }, + nil, + ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema, + true, + false, + ) +} + +func (ec *executionContext) fieldContext_Query___schema(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "description": + return ec.fieldContext___Schema_description(ctx, field) + case "types": + return ec.fieldContext___Schema_types(ctx, field) + case "queryType": + return ec.fieldContext___Schema_queryType(ctx, field) + case "mutationType": + return ec.fieldContext___Schema_mutationType(ctx, field) + case "subscriptionType": + return ec.fieldContext___Schema_subscriptionType(ctx, field) + case "directives": + return ec.fieldContext___Schema_directives(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Schema", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Directive_name, + func(ctx context.Context) (any, error) { + return obj.Name, nil + }, + nil, + ec.marshalNString2string, + true, + true, + ) +} + +func (ec *executionContext) fieldContext___Directive_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Directive_description, + func(ctx context.Context) (any, error) { + return obj.Description(), nil + }, + nil, + ec.marshalOString2ᚖstring, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___Directive_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Directive_isRepeatable, + func(ctx context.Context) (any, error) { + return obj.IsRepeatable, nil + }, + nil, + ec.marshalNBoolean2bool, + true, + true, + ) +} + +func (ec *executionContext) fieldContext___Directive_isRepeatable(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Directive_locations, + func(ctx context.Context) (any, error) { + return obj.Locations, nil + }, + nil, + ec.marshalN__DirectiveLocation2ᚕstringᚄ, + true, + true, + ) +} + +func (ec *executionContext) fieldContext___Directive_locations(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __DirectiveLocation does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Directive_args, + func(ctx context.Context) (any, error) { + return obj.Args, nil + }, + nil, + ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ, + true, + true, + ) +} + +func (ec *executionContext) fieldContext___Directive_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field___Directive_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___EnumValue_name, + func(ctx context.Context) (any, error) { + return obj.Name, nil + }, + nil, + ec.marshalNString2string, + true, + true, + ) +} + +func (ec *executionContext) fieldContext___EnumValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___EnumValue_description, + func(ctx context.Context) (any, error) { + return obj.Description(), nil + }, + nil, + ec.marshalOString2ᚖstring, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___EnumValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___EnumValue_isDeprecated, + func(ctx context.Context) (any, error) { + return obj.IsDeprecated(), nil + }, + nil, + ec.marshalNBoolean2bool, + true, + true, + ) +} + +func (ec *executionContext) fieldContext___EnumValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___EnumValue_deprecationReason, + func(ctx context.Context) (any, error) { + return obj.DeprecationReason(), nil + }, + nil, + ec.marshalOString2ᚖstring, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___EnumValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Field_name, + func(ctx context.Context) (any, error) { + return obj.Name, nil + }, + nil, + ec.marshalNString2string, + true, + true, + ) +} + +func (ec *executionContext) fieldContext___Field_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Field_description, + func(ctx context.Context) (any, error) { + return obj.Description(), nil + }, + nil, + ec.marshalOString2ᚖstring, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___Field_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Field_args, + func(ctx context.Context) (any, error) { + return obj.Args, nil + }, + nil, + ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ, + true, + true, + ) +} + +func (ec *executionContext) fieldContext___Field_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field___Field_args_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Field_type, + func(ctx context.Context) (any, error) { + return obj.Type, nil + }, + nil, + ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType, + true, + true, + ) +} + +func (ec *executionContext) fieldContext___Field_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Field_isDeprecated, + func(ctx context.Context) (any, error) { + return obj.IsDeprecated(), nil + }, + nil, + ec.marshalNBoolean2bool, + true, + true, + ) +} + +func (ec *executionContext) fieldContext___Field_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Field_deprecationReason, + func(ctx context.Context) (any, error) { + return obj.DeprecationReason(), nil + }, + nil, + ec.marshalOString2ᚖstring, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___Field_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___InputValue_name, + func(ctx context.Context) (any, error) { + return obj.Name, nil + }, + nil, + ec.marshalNString2string, + true, + true, + ) +} + +func (ec *executionContext) fieldContext___InputValue_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___InputValue_description, + func(ctx context.Context) (any, error) { + return obj.Description(), nil + }, + nil, + ec.marshalOString2ᚖstring, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___InputValue_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___InputValue_type, + func(ctx context.Context) (any, error) { + return obj.Type, nil + }, + nil, + ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType, + true, + true, + ) +} + +func (ec *executionContext) fieldContext___InputValue_type(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___InputValue_defaultValue, + func(ctx context.Context) (any, error) { + return obj.DefaultValue, nil + }, + nil, + ec.marshalOString2ᚖstring, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___InputValue_defaultValue(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___InputValue_isDeprecated, + func(ctx context.Context) (any, error) { + return obj.IsDeprecated(), nil + }, + nil, + ec.marshalNBoolean2bool, + true, + true, + ) +} + +func (ec *executionContext) fieldContext___InputValue_isDeprecated(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___InputValue_deprecationReason, + func(ctx context.Context) (any, error) { + return obj.DeprecationReason(), nil + }, + nil, + ec.marshalOString2ᚖstring, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___InputValue_deprecationReason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Schema_description, + func(ctx context.Context) (any, error) { + return obj.Description(), nil + }, + nil, + ec.marshalOString2ᚖstring, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___Schema_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Schema_types, + func(ctx context.Context) (any, error) { + return obj.Types(), nil + }, + nil, + ec.marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ, + true, + true, + ) +} + +func (ec *executionContext) fieldContext___Schema_types(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Schema_queryType, + func(ctx context.Context) (any, error) { + return obj.QueryType(), nil + }, + nil, + ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType, + true, + true, + ) +} + +func (ec *executionContext) fieldContext___Schema_queryType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Schema_mutationType, + func(ctx context.Context) (any, error) { + return obj.MutationType(), nil + }, + nil, + ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___Schema_mutationType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Schema_subscriptionType, + func(ctx context.Context) (any, error) { + return obj.SubscriptionType(), nil + }, + nil, + ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___Schema_subscriptionType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_directives(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Schema_directives, + func(ctx context.Context) (any, error) { + return obj.Directives(), nil + }, + nil, + ec.marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ, + true, + true, + ) +} + +func (ec *executionContext) fieldContext___Schema_directives(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Directive_name(ctx, field) + case "description": + return ec.fieldContext___Directive_description(ctx, field) + case "isRepeatable": + return ec.fieldContext___Directive_isRepeatable(ctx, field) + case "locations": + return ec.fieldContext___Directive_locations(ctx, field) + case "args": + return ec.fieldContext___Directive_args(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Directive", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Type_kind, + func(ctx context.Context) (any, error) { + return obj.Kind(), nil + }, + nil, + ec.marshalN__TypeKind2string, + true, + true, + ) +} + +func (ec *executionContext) fieldContext___Type_kind(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __TypeKind does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Type_name, + func(ctx context.Context) (any, error) { + return obj.Name(), nil + }, + nil, + ec.marshalOString2ᚖstring, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___Type_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Type_description, + func(ctx context.Context) (any, error) { + return obj.Description(), nil + }, + nil, + ec.marshalOString2ᚖstring, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___Type_description(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Type_specifiedByURL, + func(ctx context.Context) (any, error) { + return obj.SpecifiedByURL(), nil + }, + nil, + ec.marshalOString2ᚖstring, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___Type_specifiedByURL(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Type_fields, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return obj.Fields(fc.Args["includeDeprecated"].(bool)), nil + }, + nil, + ec.marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___Type_fields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Field_name(ctx, field) + case "description": + return ec.fieldContext___Field_description(ctx, field) + case "args": + return ec.fieldContext___Field_args(ctx, field) + case "type": + return ec.fieldContext___Field_type(ctx, field) + case "isDeprecated": + return ec.fieldContext___Field_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___Field_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Field", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field___Type_fields_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Type_interfaces, + func(ctx context.Context) (any, error) { + return obj.Interfaces(), nil + }, + nil, + ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___Type_interfaces(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Type_possibleTypes, + func(ctx context.Context) (any, error) { + return obj.PossibleTypes(), nil + }, + nil, + ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___Type_possibleTypes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Type_enumValues, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return obj.EnumValues(fc.Args["includeDeprecated"].(bool)), nil + }, + nil, + ec.marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___Type_enumValues(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___EnumValue_name(ctx, field) + case "description": + return ec.fieldContext___EnumValue_description(ctx, field) + case "isDeprecated": + return ec.fieldContext___EnumValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___EnumValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __EnumValue", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field___Type_enumValues_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Type_inputFields, + func(ctx context.Context) (any, error) { + return obj.InputFields(), nil + }, + nil, + ec.marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___Type_inputFields(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + case "isDeprecated": + return ec.fieldContext___InputValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___InputValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Type_ofType, + func(ctx context.Context) (any, error) { + return obj.OfType(), nil + }, + nil, + ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___Type_ofType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "isOneOf": + return ec.fieldContext___Type_isOneOf(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_isOneOf(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + ec.fieldContext___Type_isOneOf, + func(ctx context.Context) (any, error) { + return obj.IsOneOf(), nil + }, + nil, + ec.marshalOBoolean2bool, + true, + false, + ) +} + +func (ec *executionContext) fieldContext___Type_isOneOf(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +func (ec *executionContext) unmarshalInputCloudEventFilter(ctx context.Context, obj any) (model.CloudEventFilter, error) { + var it model.CloudEventFilter + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"id", "type", "source", "producer", "before", "after"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "id": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.ID = data + case "type": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("type")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.Type = data + case "source": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("source")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.Source = data + case "producer": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("producer")) + data, err := ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + it.Producer = data + case "before": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("before")) + data, err := ec.unmarshalOTime2ᚖtimeᚐTime(ctx, v) + if err != nil { + return it, err + } + it.Before = data + case "after": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("after")) + data, err := ec.unmarshalOTime2ᚖtimeᚐTime(ctx, v) + if err != nil { + return it, err + } + it.After = data + } + } + + return it, nil +} + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var cloudEventHeaderImplementors = []string{"CloudEventHeader"} + +func (ec *executionContext) _CloudEventHeader(ctx context.Context, sel ast.SelectionSet, obj *cloudevent.CloudEventHeader) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, cloudEventHeaderImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("CloudEventHeader") + case "id": + out.Values[i] = ec._CloudEventHeader_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "source": + out.Values[i] = ec._CloudEventHeader_source(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "producer": + out.Values[i] = ec._CloudEventHeader_producer(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "specversion": + out.Values[i] = ec._CloudEventHeader_specversion(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "subject": + out.Values[i] = ec._CloudEventHeader_subject(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "time": + out.Values[i] = ec._CloudEventHeader_time(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "type": + out.Values[i] = ec._CloudEventHeader_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "datacontenttype": + out.Values[i] = ec._CloudEventHeader_datacontenttype(ctx, field, obj) + case "dataschema": + out.Values[i] = ec._CloudEventHeader_dataschema(ctx, field, obj) + case "dataversion": + out.Values[i] = ec._CloudEventHeader_dataversion(ctx, field, obj) + case "signature": + out.Values[i] = ec._CloudEventHeader_signature(ctx, field, obj) + case "tags": + out.Values[i] = ec._CloudEventHeader_tags(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var cloudEventIndexImplementors = []string{"CloudEventIndex"} + +func (ec *executionContext) _CloudEventIndex(ctx context.Context, sel ast.SelectionSet, obj *model.CloudEventIndex) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, cloudEventIndexImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("CloudEventIndex") + case "header": + out.Values[i] = ec._CloudEventIndex_header(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "indexKey": + out.Values[i] = ec._CloudEventIndex_indexKey(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var queryImplementors = []string{"Query"} + +func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Query", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Query") + case "latestIndex": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_latestIndex(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "indexes": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_indexes(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "latestCloudEvent": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_latestCloudEvent(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "cloudEvents": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_cloudEvents(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "__type": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + }) + case "__schema": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __DirectiveImplementors = []string{"__Directive"} + +func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Directive") + case "name": + out.Values[i] = ec.___Directive_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Directive_description(ctx, field, obj) + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "locations": + out.Values[i] = ec.___Directive_locations(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "args": + out.Values[i] = ec.___Directive_args(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __EnumValueImplementors = []string{"__EnumValue"} + +func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__EnumValue") + case "name": + out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __FieldImplementors = []string{"__Field"} + +func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Field") + case "name": + out.Values[i] = ec.___Field_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Field_description(ctx, field, obj) + case "args": + out.Values[i] = ec.___Field_args(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "type": + out.Values[i] = ec.___Field_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "isDeprecated": + out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __InputValueImplementors = []string{"__InputValue"} + +func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__InputValue") + case "name": + out.Values[i] = ec.___InputValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___InputValue_description(ctx, field, obj) + case "type": + out.Values[i] = ec.___InputValue_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "defaultValue": + out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___InputValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___InputValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __SchemaImplementors = []string{"__Schema"} + +func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Schema") + case "description": + out.Values[i] = ec.___Schema_description(ctx, field, obj) + case "types": + out.Values[i] = ec.___Schema_types(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "queryType": + out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "mutationType": + out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + case "subscriptionType": + out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + case "directives": + out.Values[i] = ec.___Schema_directives(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __TypeImplementors = []string{"__Type"} + +func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Type") + case "kind": + out.Values[i] = ec.___Type_kind(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec.___Type_name(ctx, field, obj) + case "description": + out.Values[i] = ec.___Type_description(ctx, field, obj) + case "specifiedByURL": + out.Values[i] = ec.___Type_specifiedByURL(ctx, field, obj) + case "fields": + out.Values[i] = ec.___Type_fields(ctx, field, obj) + case "interfaces": + out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + case "possibleTypes": + out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + case "enumValues": + out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + case "inputFields": + out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + case "ofType": + out.Values[i] = ec.___Type_ofType(ctx, field, obj) + case "isOneOf": + out.Values[i] = ec.___Type_isOneOf(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context, v any) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + _ = sel + res := graphql.MarshalBoolean(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) marshalNCloudEventHeader2ᚖgithubᚗcomᚋDIMOᚑNetworkᚋcloudeventᚐCloudEventHeader(ctx context.Context, sel ast.SelectionSet, v *cloudevent.CloudEventHeader) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._CloudEventHeader(ctx, sel, v) +} + +func (ec *executionContext) marshalNCloudEventIndex2githubᚗcomᚋDIMOᚑNetworkᚋfetchᚑapiᚋinternalᚋgraphᚋmodelᚐCloudEventIndex(ctx context.Context, sel ast.SelectionSet, v model.CloudEventIndex) graphql.Marshaler { + return ec._CloudEventIndex(ctx, sel, &v) +} + +func (ec *executionContext) marshalNCloudEventIndex2ᚕᚖgithubᚗcomᚋDIMOᚑNetworkᚋfetchᚑapiᚋinternalᚋgraphᚋmodelᚐCloudEventIndexᚄ(ctx context.Context, sel ast.SelectionSet, v []*model.CloudEventIndex) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNCloudEventIndex2ᚖgithubᚗcomᚋDIMOᚑNetworkᚋfetchᚑapiᚋinternalᚋgraphᚋmodelᚐCloudEventIndex(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalNCloudEventIndex2ᚖgithubᚗcomᚋDIMOᚑNetworkᚋfetchᚑapiᚋinternalᚋgraphᚋmodelᚐCloudEventIndex(ctx context.Context, sel ast.SelectionSet, v *model.CloudEventIndex) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._CloudEventIndex(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNInt2int(ctx context.Context, v any) (int, error) { + res, err := graphql.UnmarshalInt(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.SelectionSet, v int) graphql.Marshaler { + _ = sel + res := graphql.MarshalInt(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalInputJSON(ctx context.Context, v any) (cloudevent.RawEvent, error) { + var ev cloudevent.RawEvent + b, err := json.Marshal(v) + if err != nil { + return ev, err + } + err = json.Unmarshal(b, &ev) + return ev, err +} + +func (ec *executionContext) _JSON(ctx context.Context, sel ast.SelectionSet, v *cloudevent.RawEvent) graphql.Marshaler { + if v == nil { + return graphql.Null + } + data, err := json.Marshal(v) + if err != nil { + return graphql.Null + } + return graphql.WriterFunc(func(w io.Writer) { _, _ = w.Write(data) }) +} + +func (ec *executionContext) unmarshalNJSON2githubᚗcomᚋDIMOᚑNetworkᚋcloudeventᚐCloudEvent(ctx context.Context, v any) (cloudevent.CloudEvent[json.RawMessage], error) { + res, err := ec.unmarshalInputJSON(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNJSON2githubᚗcomᚋDIMOᚑNetworkᚋcloudeventᚐCloudEvent(ctx context.Context, sel ast.SelectionSet, v cloudevent.CloudEvent[json.RawMessage]) graphql.Marshaler { + return ec._JSON(ctx, sel, (*cloudevent.RawEvent)(&v)) +} + +func (ec *executionContext) unmarshalNJSON2ᚕᚖgithubᚗcomᚋDIMOᚑNetworkᚋcloudeventᚐCloudEventᚄ(ctx context.Context, v any) ([]*cloudevent.CloudEvent[json.RawMessage], error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]*cloudevent.CloudEvent[json.RawMessage], len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNJSON2ᚖgithubᚗcomᚋDIMOᚑNetworkᚋcloudeventᚐCloudEvent(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalNJSON2ᚕᚖgithubᚗcomᚋDIMOᚑNetworkᚋcloudeventᚐCloudEventᚄ(ctx context.Context, sel ast.SelectionSet, v []*cloudevent.CloudEvent[json.RawMessage]) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNJSON2ᚖgithubᚗcomᚋDIMOᚑNetworkᚋcloudeventᚐCloudEvent(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalNJSON2ᚖgithubᚗcomᚋDIMOᚑNetworkᚋcloudeventᚐCloudEvent(ctx context.Context, v any) (*cloudevent.CloudEvent[json.RawMessage], error) { + res, err := ec.unmarshalInputJSON(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNJSON2ᚖgithubᚗcomᚋDIMOᚑNetworkᚋcloudeventᚐCloudEvent(ctx context.Context, sel ast.SelectionSet, v *cloudevent.CloudEvent[json.RawMessage]) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._JSON(ctx, sel, (*cloudevent.RawEvent)(v)) +} + +func (ec *executionContext) unmarshalNString2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNTime2timeᚐTime(ctx context.Context, v any) (time.Time, error) { + res, err := graphql.UnmarshalTime(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNTime2timeᚐTime(ctx context.Context, sel ast.SelectionSet, v time.Time) graphql.Marshaler { + _ = sel + res := graphql.MarshalTime(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler { + return ec.___Directive(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Directive) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__DirectiveLocation2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN__DirectiveLocation2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__DirectiveLocation2string(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx context.Context, sel ast.SelectionSet, v introspection.EnumValue) graphql.Marshaler { + return ec.___EnumValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx context.Context, sel ast.SelectionSet, v introspection.Field) graphql.Marshaler { + return ec.___Field(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx context.Context, sel ast.SelectionSet, v introspection.InputValue) graphql.Marshaler { + return ec.___InputValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v introspection.Type) graphql.Marshaler { + return ec.___Type(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Type) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v *introspection.Type) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec.___Type(ctx, sel, v) +} + +func (ec *executionContext) unmarshalN__TypeKind2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v any) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + _ = sel + _ = ctx + res := graphql.MarshalBoolean(v) + return res +} + +func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v any) (*bool, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalBoolean(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast.SelectionSet, v *bool) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalBoolean(*v) + return res +} + +func (ec *executionContext) unmarshalOCloudEventFilter2ᚖgithubᚗcomᚋDIMOᚑNetworkᚋfetchᚑapiᚋinternalᚋgraphᚋmodelᚐCloudEventFilter(ctx context.Context, v any) (*model.CloudEventFilter, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputCloudEventFilter(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalOInt2ᚖint(ctx context.Context, v any) (*int, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalInt(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOInt2ᚖint(ctx context.Context, sel ast.SelectionSet, v *int) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalInt(*v) + return res +} + +func (ec *executionContext) unmarshalOString2string(ctx context.Context, v any) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + _ = sel + _ = ctx + res := graphql.MarshalString(v) + return res +} + +func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v any) ([]string, error) { + if v == nil { + return nil, nil + } + var vSlice []any + vSlice = graphql.CoerceList(v) + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNString2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalOString2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNString2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v any) (*string, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalString(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalString(*v) + return res +} + +func (ec *executionContext) unmarshalOTime2ᚖtimeᚐTime(ctx context.Context, v any) (*time.Time, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalTime(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOTime2ᚖtimeᚐTime(ctx context.Context, sel ast.SelectionSet, v *time.Time) graphql.Marshaler { + if v == nil { + return graphql.Null + } + _ = sel + _ = ctx + res := graphql.MarshalTime(*v) + return res +} + +func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Field) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx context.Context, sel ast.SelectionSet, v *introspection.Schema) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.___Schema(ctx, sel, v) +} + +func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Type) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v *introspection.Type) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.___Type(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/internal/graph/model/models_gen.go b/internal/graph/model/models_gen.go new file mode 100644 index 0000000..4a330fb --- /dev/null +++ b/internal/graph/model/models_gen.go @@ -0,0 +1,28 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package model + +import ( + "time" + + "github.com/DIMO-Network/cloudevent" +) + +type CloudEventFilter struct { + ID *string `json:"id,omitempty"` + Type *string `json:"type,omitempty"` + Source *string `json:"source,omitempty"` + Producer *string `json:"producer,omitempty"` + Before *time.Time `json:"before,omitempty"` + After *time.Time `json:"after,omitempty"` +} + +// Cloud event index entry: typed header + storage key. +type CloudEventIndex struct { + Header *cloudevent.CloudEventHeader `json:"header"` + IndexKey string `json:"indexKey"` +} + +// The root query type for the Fetch API GraphQL schema. +type Query struct { +} diff --git a/internal/graph/resolver.go b/internal/graph/resolver.go new file mode 100644 index 0000000..b1502ed --- /dev/null +++ b/internal/graph/resolver.go @@ -0,0 +1,64 @@ +package graph + +import ( + "context" + "fmt" + "math/big" + "slices" + + "github.com/DIMO-Network/cloudevent" + "github.com/DIMO-Network/fetch-api/internal/graph/model" + "github.com/DIMO-Network/fetch-api/pkg/eventrepo" + "github.com/DIMO-Network/fetch-api/pkg/grpc" + "github.com/DIMO-Network/token-exchange-api/pkg/tokenclaims" + "github.com/ethereum/go-ethereum/common" +) + +// This file will not be regenerated automatically. +// +// It serves as dependency injection for your app, add any dependencies you require +// here. + +// ClaimsContextKey is the context key for token claims (set by JWT middleware). +type ClaimsContextKey struct{} + +type Resolver struct { + EventService *eventrepo.Service + Buckets []string + VehicleAddr common.Address + ChainID uint64 +} + +// CheckVehicleRawData returns an error if the context does not have claims or the token +// does not have GetRawData permission for the given vehicle tokenID. +// requireVehicleOpts validates access and converts the filter into search options. +// Placed here (not in resolvers) so gqlgen regeneration doesn't discard it. +func (r *queryResolver) requireVehicleOpts(ctx context.Context, tokenID int, filter *model.CloudEventFilter) (*grpc.SearchOptions, error) { + if err := CheckVehicleRawData(ctx, r.VehicleAddr, tokenID); err != nil { + return nil, err + } + return filterToSearchOptions(filter, subjectFromTokenID(r.VehicleAddr, r.ChainID, tokenID)), nil +} + +// CheckVehicleRawData returns an error if the context does not have claims or the token +// does not have GetRawData permission for the given vehicle tokenID. +func CheckVehicleRawData(ctx context.Context, vehicleAddr common.Address, tokenID int) error { + tok, _ := ctx.Value(ClaimsContextKey{}).(*tokenclaims.Token) + if tok == nil { + return fmt.Errorf("unauthorized: no token claims") + } + assetDID, err := cloudevent.DecodeERC721DID(tok.Asset) + if err != nil { + return fmt.Errorf("unauthorized: invalid asset") + } + if assetDID.ContractAddress != vehicleAddr { + return fmt.Errorf("unauthorized: wrong contract") + } + if assetDID.TokenID.Cmp(big.NewInt(int64(tokenID))) != 0 { + return fmt.Errorf("unauthorized: token ID mismatch") + } + if !slices.Contains(tok.Permissions, tokenclaims.PermissionGetRawData) { + return fmt.Errorf("unauthorized: missing GetRawData privilege") + } + return nil +} diff --git a/pkg/eventrepo/event_repo_test.go b/pkg/eventrepo/event_repo_test.go index 18f16fa..9abf6bc 100644 --- a/pkg/eventrepo/event_repo_test.go +++ b/pkg/eventrepo/event_repo_test.go @@ -164,7 +164,8 @@ func TestGetDataFromIndex(t *testing.T) { ctrl := gomock.NewController(t) mockS3Client := NewMockObjectGetter(ctrl) - content := []byte(`{"vin": "1HGCM82633A123456"}`) + // Stored object is full CloudEvent JSON (cloudevent unmarshaler expects envelope with "data"). + content := []byte(`{"data":{"vin": "1HGCM82633A123456"}}`) mockS3Client.EXPECT().GetObject(gomock.Any(), gomock.Any(), gomock.Any()).Return(&s3.GetObjectOutput{ Body: io.NopCloser(bytes.NewReader(content)), ContentLength: ref(int64(len(content))), @@ -337,11 +338,12 @@ func TestGetData(t *testing.T) { mockS3Client.EXPECT().GetObject(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn(func(ctx context.Context, params *s3.GetObjectInput, optFns ...func(*s3.Options)) (*s3.GetObjectOutput, error) { require.Equal(t, *params.Key, indexKey) quotedKey := `"` + indexKey + `"` - // content := []byte(`{"data":` + quotedKey + `}`) expectedContent = append(expectedContent, []byte(quotedKey)) + // Stored object is full CloudEvent JSON with "data" field. + body := []byte(`{"data":` + quotedKey + `}`) return &s3.GetObjectOutput{ - Body: io.NopCloser(bytes.NewReader([]byte(quotedKey))), - ContentLength: ref(int64(len(quotedKey))), + Body: io.NopCloser(bytes.NewReader(body)), + ContentLength: ref(int64(len(body))), }, nil }) } @@ -418,19 +420,21 @@ func TestGetEventWithAllHeaderFields(t *testing.T) { ctrl := gomock.NewController(t) mockS3Client := NewMockObjectGetter(ctrl) eventData := []byte(`{"status": "online", "lastSeen": "2023-01-01T12:00:00Z"}`) + // Stored object is full CloudEvent JSON (cloudevent unmarshaler expects envelope with "data"). + eventDataEnvelope := []byte(`{"data":` + string(eventData) + `}`) // Create service indexService := eventrepo.New(conn, mockS3Client) // Test retrieving the event - t.Run("retrieve event with full headers", func(t *testing.T) { + t.Run("retrieve event with full headers", func(t *testing.T) { mockS3Client.EXPECT().GetObject(gomock.Any(), gomock.Any(), gomock.Any()).DoAndReturn( func(ctx context.Context, params *s3.GetObjectInput, optFns ...func(*s3.Options)) (*s3.GetObjectOutput, error) { // Verify the correct key was requested require.Equal(t, indexKey, *params.Key) return &s3.GetObjectOutput{ - Body: io.NopCloser(bytes.NewReader(eventData)), - ContentLength: ref(int64(len(eventData))), + Body: io.NopCloser(bytes.NewReader(eventDataEnvelope)), + ContentLength: ref(int64(len(eventDataEnvelope))), }, nil }, ) @@ -472,8 +476,8 @@ func TestGetEventWithAllHeaderFields(t *testing.T) { // Verify the correct key was requested require.Equal(t, indexKey2, *params.Key) return &s3.GetObjectOutput{ - Body: io.NopCloser(bytes.NewReader(eventData)), - ContentLength: ref(int64(len(eventData))), + Body: io.NopCloser(bytes.NewReader(eventDataEnvelope)), + ContentLength: ref(int64(len(eventDataEnvelope))), }, nil }, ) diff --git a/pkg/eventrepo/eventrepo.go b/pkg/eventrepo/eventrepo.go index 3372dca..004737e 100644 --- a/pkg/eventrepo/eventrepo.go +++ b/pkg/eventrepo/eventrepo.go @@ -13,6 +13,7 @@ import ( "github.com/DIMO-Network/cloudevent" chindexer "github.com/DIMO-Network/cloudevent/pkg/clickhouse" "github.com/DIMO-Network/fetch-api/pkg/grpc" + "github.com/DIMO-Network/fetch-api/pkg/parquetreader" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/volatiletech/sqlboiler/v4/drivers" @@ -25,8 +26,11 @@ const tagsColumn = "JSONExtract(extras, 'tags', 'Array(String)')" // Service manages and retrieves data messages from indexed objects in S3. type Service struct { - objGetter ObjectGetter - chConn clickhouse.Conn + objGetter ObjectGetter + chConn clickhouse.Conn + parquetReader *parquetreader.Reader + // parquetBucket is the object storage bucket for Iceberg Parquet files. + parquetBucket string } // ObjectInfo is the information about the object in S3. @@ -40,14 +44,21 @@ type ObjectGetter interface { PutObject(ctx context.Context, params *s3.PutObjectInput, optFns ...func(*s3.Options)) (*s3.PutObjectOutput, error) } -// New creates a new instance of serviceService. +// New creates a new instance of Service. func New(chConn clickhouse.Conn, objGetter ObjectGetter) *Service { return &Service{ - objGetter: objGetter, - chConn: chConn, + objGetter: objGetter, + chConn: chConn, + parquetReader: parquetreader.New(objGetter), } } +// SetParquetBucket configures the bucket used for Iceberg Parquet files. +// If not set, Parquet index_key references will fail. +func (s *Service) SetParquetBucket(bucket string) { + s.parquetBucket = bucket +} + // GetLatestIndex returns the latest cloud event index that matches the given options. func (s *Service) GetLatestIndex(ctx context.Context, opts *grpc.SearchOptions) (cloudevent.CloudEvent[ObjectInfo], error) { advancedOpts := convertSearchOptionsToAdvanced(opts) @@ -136,13 +147,13 @@ func (s *Service) ListIndexesAdvanced(ctx context.Context, limit int, advancedOp } // ListCloudEvents fetches and returns the cloud events that match the given options. -func (s *Service) ListCloudEvents(ctx context.Context, bucketName string, limit int, opts *grpc.SearchOptions) ([]cloudevent.CloudEvent[json.RawMessage], error) { +func (s *Service) ListCloudEvents(ctx context.Context, bucketName string, limit int, opts *grpc.SearchOptions) ([]cloudevent.RawEvent, error) { advancedOpts := convertSearchOptionsToAdvanced(opts) return s.ListCloudEventsAdvanced(ctx, bucketName, limit, advancedOpts) } // ListCloudEventsAdvanced fetches and returns the cloud events that match the given advanced options. -func (s *Service) ListCloudEventsAdvanced(ctx context.Context, bucketName string, limit int, advancedOpts *grpc.AdvancedSearchOptions) ([]cloudevent.CloudEvent[json.RawMessage], error) { +func (s *Service) ListCloudEventsAdvanced(ctx context.Context, bucketName string, limit int, advancedOpts *grpc.AdvancedSearchOptions) ([]cloudevent.RawEvent, error) { events, err := s.ListIndexesAdvanced(ctx, limit, advancedOpts) if err != nil { return nil, err @@ -156,35 +167,35 @@ func (s *Service) ListCloudEventsAdvanced(ctx context.Context, bucketName string } // GetLatestCloudEvent fetches and returns the latest cloud event that matches the given options. -func (s *Service) GetLatestCloudEvent(ctx context.Context, bucketName string, opts *grpc.SearchOptions) (cloudevent.CloudEvent[json.RawMessage], error) { +func (s *Service) GetLatestCloudEvent(ctx context.Context, bucketName string, opts *grpc.SearchOptions) (cloudevent.RawEvent, error) { advancedOpts := convertSearchOptionsToAdvanced(opts) return s.GetLatestCloudEventAdvanced(ctx, bucketName, advancedOpts) } // GetLatestCloudEventAdvanced fetches and returns the latest cloud event that matches the given advanced options. -func (s *Service) GetLatestCloudEventAdvanced(ctx context.Context, bucketName string, advancedOpts *grpc.AdvancedSearchOptions) (cloudevent.CloudEvent[json.RawMessage], error) { +func (s *Service) GetLatestCloudEventAdvanced(ctx context.Context, bucketName string, advancedOpts *grpc.AdvancedSearchOptions) (cloudevent.RawEvent, error) { cloudIdx, err := s.GetLatestIndexAdvanced(ctx, advancedOpts) if err != nil { - return cloudevent.CloudEvent[json.RawMessage]{}, err + return cloudevent.RawEvent{}, err } data, err := s.GetCloudEventFromIndex(ctx, cloudIdx, bucketName) if err != nil { - return cloudevent.CloudEvent[json.RawMessage]{}, err + return cloudevent.RawEvent{}, err } return data, nil } // ListCloudEventsFromIndexes fetches and returns the cloud events for the given index. -func (s *Service) ListCloudEventsFromIndexes(ctx context.Context, indexes []cloudevent.CloudEvent[ObjectInfo], bucketName string) ([]cloudevent.CloudEvent[json.RawMessage], error) { - events := make([]cloudevent.CloudEvent[json.RawMessage], len(indexes)) +func (s *Service) ListCloudEventsFromIndexes(ctx context.Context, indexes []cloudevent.CloudEvent[ObjectInfo], bucketName string) ([]cloudevent.RawEvent, error) { + events := make([]cloudevent.RawEvent, len(indexes)) var err error - objectsByKeys := map[string][]byte{} + objectsByKeys := map[string]json.RawMessage{} for i := range indexes { // Some objects have multiple cloud events so we cache the objects to avoid fetching them multiple times. - if obj, ok := objectsByKeys[indexes[i].Data.Key]; ok { - events[i] = cloudevent.CloudEvent[json.RawMessage]{CloudEventHeader: indexes[i].CloudEventHeader, Data: obj} + if data, ok := objectsByKeys[indexes[i].Data.Key]; ok { + events[i] = cloudevent.RawEvent{CloudEventHeader: indexes[i].CloudEventHeader, Data: data} continue } events[i], err = s.GetCloudEventFromIndex(ctx, indexes[i], bucketName) @@ -197,12 +208,16 @@ func (s *Service) ListCloudEventsFromIndexes(ctx context.Context, indexes []clou } // GetCloudEventFromIndex fetches and returns the cloud event for the given index. -func (s *Service) GetCloudEventFromIndex(ctx context.Context, index cloudevent.CloudEvent[ObjectInfo], bucketName string) (cloudevent.CloudEvent[json.RawMessage], error) { +func (s *Service) GetCloudEventFromIndex(ctx context.Context, index cloudevent.CloudEvent[ObjectInfo], bucketName string) (cloudevent.RawEvent, error) { rawData, err := s.GetObjectFromKey(ctx, index.Data.Key, bucketName) if err != nil { - return cloudevent.CloudEvent[json.RawMessage]{}, err + return cloudevent.RawEvent{}, err + } + ev, err := toCloudEvent(&index.CloudEventHeader, rawData) + if err != nil { + return cloudevent.RawEvent{}, err } - return toCloudEvent(&index.CloudEventHeader, rawData), nil + return ev, nil } // ListObjectsFromKeys fetches and returns the objects for the given keys. @@ -218,8 +233,43 @@ func (s *Service) ListObjectsFromKeys(ctx context.Context, keys []string, bucket return data, nil } -// GetRawObjectFromKey fetches and returns the raw object for the given key without unmarshalling to a cloud event. +// GetObjectFromKey fetches and returns the raw object for the given key. +// Routes based on index_key format: +// - If key contains "#": Parquet reference (new Iceberg path) -- reads the data column +// from the Parquet file at the specified row offset. +// - Otherwise: legacy S3 path -- fetches the entire object as before. func (s *Service) GetObjectFromKey(ctx context.Context, key, bucketName string) ([]byte, error) { + if parquetreader.IsParquetRef(key) { + return s.getObjectFromParquet(ctx, key) + } + return s.getObjectFromS3(ctx, key, bucketName) +} + +// getObjectFromParquet reads the data column from a Parquet file for a specific row. +func (s *Service) getObjectFromParquet(ctx context.Context, key string) ([]byte, error) { + ref, err := parquetreader.ParseIndexKey(key) + if err != nil { + return nil, fmt.Errorf("failed to parse parquet index_key: %w", err) + } + + // Bucket may come from full s3:// URI in index_key (ref.Bucket) or from config. + bucket := s.parquetBucket + if ref.Bucket != "" { + bucket = ref.Bucket + } + if bucket == "" { + return nil, fmt.Errorf("parquet bucket not configured and index_key has no s3:// URI: %s", key) + } + + data, err := s.parquetReader.ReadData(ctx, bucket, ref) + if err != nil { + return nil, fmt.Errorf("failed to read data from parquet: %w", err) + } + return data, nil +} + +// getObjectFromS3 fetches the entire object from S3 (legacy per-file JSON path). +func (s *Service) getObjectFromS3(ctx context.Context, key, bucketName string) ([]byte, error) { obj, err := s.objGetter.GetObject(ctx, &s3.GetObjectInput{ Bucket: aws.String(bucketName), Key: aws.String(key), @@ -258,53 +308,19 @@ func (s *Service) StoreObject(ctx context.Context, bucketName string, cloudHeade return nil } -// toCloudEvent converts the given data to a cloud event with the given header -// if the provided data is already a cloud event we will replace the header with the given one. -func toCloudEvent(dbHdr *cloudevent.CloudEventHeader, data []byte) cloudevent.CloudEvent[json.RawMessage] { - retData := data - event := cloudevent.CloudEvent[json.RawMessage]{} - err := json.Unmarshal(data, &event) - emptyHdr := cloudevent.CloudEventHeader{} - if err == nil && !event.Equals(emptyHdr) { - // if the data is already a cloud event we use the embedded data field - retData = event.Data - } - return cloudevent.CloudEvent[json.RawMessage]{CloudEventHeader: *dbHdr, Data: retData} -} - -func SearchOptionsToQueryMod(opts *grpc.SearchOptions) ([]qm.QueryMod, error) { - if opts == nil { - return nil, nil +// toCloudEvent deserializes the stored CloudEvent JSON using the cloudevent package, +// then overlays the index header. We never decode data_base64 into Data—when present, +// DataBase64 is preserved for round-trip and Data is left nil. +func toCloudEvent(dbHdr *cloudevent.CloudEventHeader, data []byte) (cloudevent.RawEvent, error) { + var ev cloudevent.RawEvent + if err := json.Unmarshal(data, &ev); err != nil { + return cloudevent.RawEvent{}, err } - var mods []qm.QueryMod - if opts.GetId() != nil { - mods = append(mods, qm.Where(chindexer.IDColumn+" = ?", opts.GetId().GetValue())) - } - if opts.GetAfter() != nil { - mods = append(mods, qm.Where(chindexer.TimestampColumn+" > ?", opts.GetAfter().AsTime())) - } - if opts.GetBefore() != nil { - mods = append(mods, qm.Where(chindexer.TimestampColumn+" < ?", opts.GetBefore().AsTime())) - } - if opts.GetType() != nil { - mods = append(mods, qm.Where(chindexer.TypeColumn+" = ?", opts.GetType().GetValue())) - } - if opts.GetDataVersion() != nil { - mods = append(mods, qm.Where(chindexer.DataVersionColumn+" = ?", opts.GetDataVersion().GetValue())) - } - if opts.GetSubject() != nil { - mods = append(mods, qm.Where(chindexer.SubjectColumn+" = ?", opts.GetSubject().GetValue())) - } - if opts.GetSource() != nil { - mods = append(mods, qm.Where(chindexer.SourceColumn+" = ?", opts.GetSource().GetValue())) - } - if opts.GetProducer() != nil { - mods = append(mods, qm.Where(chindexer.ProducerColumn+" = ?", opts.GetProducer().GetValue())) - } - if opts.GetExtras() != nil { - mods = append(mods, qm.Where(chindexer.ExtrasColumn+" = ?", opts.GetExtras().GetValue())) + if ev.DataBase64 != "" { + ev.Data = nil // never expose decoded bytes in Data } - return mods, nil + ev.CloudEventHeader = *dbHdr + return ev, nil } // convertSearchOptionsToAdvanced converts basic SearchOptions to AdvancedSearchOptions diff --git a/pkg/eventrepo/tocloudevent_test.go b/pkg/eventrepo/tocloudevent_test.go new file mode 100644 index 0000000..21566a7 --- /dev/null +++ b/pkg/eventrepo/tocloudevent_test.go @@ -0,0 +1,88 @@ +package eventrepo + +import ( + "encoding/base64" + "encoding/json" + "testing" + "time" + + "github.com/DIMO-Network/cloudevent" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestToCloudEvent_DataBase64(t *testing.T) { + t.Parallel() + // Stored object has data_base64 (no "data"). We never decode into Data; DataBase64 is preserved for round-trip. + b64 := base64.StdEncoding.EncodeToString([]byte("binary\x00payload")) + ceJSON := []byte(`{ + "id": "ev-1", + "source": "test", + "producer": "p", + "specversion": "1.0", + "subject": "sub", + "time": "` + time.Now().UTC().Format(time.RFC3339Nano) + `", + "type": "dimo.status", + "data_base64": "` + b64 + `" + }`) + hdr := &cloudevent.CloudEventHeader{ + ID: "ev-1", Source: "test", Producer: "p", Subject: "sub", + Time: time.Now().UTC(), Type: cloudevent.TypeStatus, + } + got, err := toCloudEvent(hdr, ceJSON) + require.NoError(t, err) + assert.Nil(t, got.Data, "never decode data_base64 into Data") + assert.Equal(t, b64, got.DataBase64, "data_base64 preserved for round-trip") + assert.Equal(t, hdr.ID, got.ID) + + // Round-trip: marshaling must emit data_base64 so it is not lost. + marshaled, err := got.MarshalJSON() + require.NoError(t, err) + var out map[string]json.RawMessage + require.NoError(t, json.Unmarshal(marshaled, &out)) + require.Contains(t, out, "data_base64") + assert.Equal(t, `"`+b64+`"`, string(out["data_base64"]), "data_base64 preserved in serialization") +} + +func TestToCloudEvent_DataOnly(t *testing.T) { + t.Parallel() + ceJSON := []byte(`{"id":"e2","source":"s","producer":"p","subject":"sub","time":"2024-01-01T00:00:00Z","type":"dimo.status","data":{"x":1}}`) + hdr := &cloudevent.CloudEventHeader{ + ID: "e2", Source: "s", Producer: "p", Subject: "sub", + Time: time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC), Type: cloudevent.TypeStatus, + } + got, err := toCloudEvent(hdr, ceJSON) + require.NoError(t, err) + require.NotNil(t, got.Data) + var m map[string]any + require.NoError(t, json.Unmarshal(got.Data, &m)) + assert.Equal(t, float64(1), m["x"]) +} + +// TestToCloudEvent_DataPassthroughNoParse verifies that the "data" payload from S3 +// is not parsed and re-serialized: we extract it with gjson and it is written raw +// in RawCloudEvent.MarshalJSON via sjson.SetRawBytes. So the exact bytes from the +// stored object's "data" field should appear unchanged in the marshaled output. +func TestToCloudEvent_DataPassthroughNoParse(t *testing.T) { + t.Parallel() + // Exact byte sequence that would often change if unmarshaled and re-marshaled + // (e.g. key order, number formatting). We assert it appears verbatim in output. + exactData := []byte(`{"order":"matters","num": 42 , "key":"value"}`) + ceJSON := []byte(`{"id":"e3","source":"s","producer":"p","subject":"sub","time":"2024-01-01T00:00:00Z","type":"dimo.status","data":` + string(exactData) + `}`) + hdr := &cloudevent.CloudEventHeader{ + ID: "e3", Source: "s", Producer: "p", Subject: "sub", + Time: time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC), Type: cloudevent.TypeStatus, + } + raw, err := toCloudEvent(hdr, ceJSON) + require.NoError(t, err) + require.NotNil(t, raw.Data) + assert.Equal(t, exactData, []byte(raw.Data), "data from S3 should be passed through without parse; gjson extracts raw substring") + + // Marshal as we do for GraphQL; the "data" field in output must be exactly exactData. + marshaled, err := raw.MarshalJSON() + require.NoError(t, err) + var out map[string]json.RawMessage + require.NoError(t, json.Unmarshal(marshaled, &out)) + require.Contains(t, out, "data") + assert.Equal(t, exactData, []byte(out["data"]), "MarshalJSON must write data via SetRawBytes, not re-encode") +} diff --git a/pkg/grpc/cloudevent.pb.go b/pkg/grpc/cloudevent.pb.go index d8ce0c9..dbeeb39 100644 --- a/pkg/grpc/cloudevent.pb.go +++ b/pkg/grpc/cloudevent.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 -// protoc v5.28.3 +// protoc-gen-go v1.36.11 +// protoc v6.33.4 // source: pkg/grpc/cloudevent.proto package grpc diff --git a/pkg/grpc/common.go b/pkg/grpc/common.go index 181a0e3..a52cab6 100644 --- a/pkg/grpc/common.go +++ b/pkg/grpc/common.go @@ -7,9 +7,9 @@ import ( "google.golang.org/protobuf/types/known/timestamppb" ) -// AsCloudEvent converts the CloudEvent to a cloudevent.CloudEvent[json.RawMessage]. -func (c *CloudEvent) AsCloudEvent() cloudevent.CloudEvent[json.RawMessage] { - return cloudevent.CloudEvent[json.RawMessage]{ +// AsRawCloudEvent converts the CloudEvent to a cloudevent.RawEvent. +func (c *CloudEvent) AsRawCloudEvent() cloudevent.RawEvent { + return cloudevent.RawEvent{ CloudEventHeader: c.GetHeader().AsCloudEventHeader(), Data: c.GetData(), } @@ -76,8 +76,8 @@ func CloudEventHeaderToProto(event *cloudevent.CloudEventHeader) *CloudEventHead } } -// CloudEventToProto converts a cloudevent.CloudEvent[json.RawMessage] to a grpc.CloudEvent. -func CloudEventToProto(event cloudevent.CloudEvent[json.RawMessage]) *CloudEvent { +// CloudEventToProto converts a cloudevent.RawEvent to a grpc.CloudEvent. +func CloudEventToProto(event cloudevent.RawEvent) *CloudEvent { return &CloudEvent{ Header: CloudEventHeaderToProto(&event.CloudEventHeader), Data: event.Data, diff --git a/pkg/grpc/common_test.go b/pkg/grpc/common_test.go index ad51a72..9d35344 100644 --- a/pkg/grpc/common_test.go +++ b/pkg/grpc/common_test.go @@ -25,21 +25,21 @@ const ( func TestCloudEventProtoRoundTrip(t *testing.T) { t.Parallel() - // Create a random CloudEvent by filling all fields with random data - originalEvent := cloudevent.CloudEvent[json.RawMessage]{ + // Create a random RawCloudEvent by filling all fields with random data + originalEvent := cloudevent.RawEvent{ CloudEventHeader: fillRandomCloudEventHeader(t), Data: json.RawMessage(`{"random": "test data"}`), } - // Convert CloudEvent to Proto + // Convert RawCloudEvent to Proto protoEvent := CloudEventToProto(originalEvent) // Verify Proto was created require.NotNil(t, protoEvent) require.NotNil(t, protoEvent.GetHeader()) - // Convert back from Proto to CloudEvent - convertedEvent := protoEvent.AsCloudEvent() + // Convert back from Proto to RawCloudEvent + convertedEvent := protoEvent.AsRawCloudEvent() // Verify the data is preserved through round-trip conversion using deep equals require.Empty(t, cmp.Diff(originalEvent.CloudEventHeader, convertedEvent.CloudEventHeader)) @@ -70,7 +70,7 @@ func TestCloudEventHeaderProtoRoundTrip(t *testing.T) { func TestCloudEventProtoWithNilHeader(t *testing.T) { t.Parallel() - originalEvent := cloudevent.CloudEvent[json.RawMessage]{ + originalEvent := cloudevent.RawEvent{ CloudEventHeader: cloudevent.CloudEventHeader{}, Data: json.RawMessage(`{"test": "data"}`), } @@ -78,7 +78,7 @@ func TestCloudEventProtoWithNilHeader(t *testing.T) { protoEvent := CloudEventToProto(originalEvent) require.NotNil(t, protoEvent) - convertedEvent := protoEvent.AsCloudEvent() + convertedEvent := protoEvent.AsRawCloudEvent() require.Equal(t, originalEvent.Data, convertedEvent.Data) } diff --git a/pkg/grpc/fetch-api.pb.go b/pkg/grpc/fetch-api.pb.go index ea634d9..470c4df 100644 --- a/pkg/grpc/fetch-api.pb.go +++ b/pkg/grpc/fetch-api.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.10 -// protoc v5.28.3 +// protoc-gen-go v1.36.11 +// protoc v6.33.4 // source: pkg/grpc/fetch-api.proto package grpc diff --git a/pkg/grpc/fetch-api_grpc.pb.go b/pkg/grpc/fetch-api_grpc.pb.go index feca051..75b31bf 100644 --- a/pkg/grpc/fetch-api_grpc.pb.go +++ b/pkg/grpc/fetch-api_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.5.1 -// - protoc v5.28.3 +// - protoc v6.33.4 // source: pkg/grpc/fetch-api.proto package grpc diff --git a/pkg/parquetreader/parquetreader.go b/pkg/parquetreader/parquetreader.go new file mode 100644 index 0000000..1c6a8ba --- /dev/null +++ b/pkg/parquetreader/parquetreader.go @@ -0,0 +1,172 @@ +// Package parquetreader provides utilities for reading individual rows from +// Parquet files stored on S3-compatible object storage. +// +// Index key format (produced by the DPS Benthos output dimo_parquet_writer): +// +// [{full_uri}|]{object_key}#{row_offset} +// +// Full URI form: s3://bucket/prefix/.../file.parquet#row (bucket and key are parsed). +// Relative form: prefix/.../file.parquet#row (caller must supply bucket). +// Use ParseIndexKey to split into bucket (if present), object key, and 0-based row offset. +// Use IsParquetRef to distinguish from legacy JSON object keys (no '#'). +package parquetreader + +import ( + "bytes" + "context" + "fmt" + "io" + "strconv" + "strings" + + "github.com/apache/arrow-go/v18/arrow/memory" + "github.com/apache/arrow-go/v18/parquet/file" + "github.com/apache/arrow-go/v18/parquet/pqarrow" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/s3" +) + +// IndexKeyRef holds the parsed components of a Parquet index_key reference. +type IndexKeyRef struct { + // Bucket is set when index_key is a full s3://bucket/key#row URI; otherwise empty. + Bucket string + // ObjectKey is the S3 object key (path) of the Parquet file, without bucket. + ObjectKey string + // RowOffset is the 0-based row index within the Parquet file. + RowOffset int +} + +// IsParquetRef returns true if the given index_key uses the new Parquet reference +// format (contains #). Legacy keys (individual S3 JSON files) do not contain #. +func IsParquetRef(indexKey string) bool { + return strings.Contains(indexKey, "#") +} + +// ParseIndexKey parses an index_key string into bucket (if s3:// URI), object key, and row offset. +// Supports: "s3://bucket/key.parquet#row" (sets Bucket) or "key.parquet#row" (Bucket empty). +func ParseIndexKey(indexKey string) (IndexKeyRef, error) { + parts := strings.SplitN(indexKey, "#", 2) + if len(parts) != 2 { + return IndexKeyRef{}, fmt.Errorf("invalid parquet index_key format (missing #): %s", indexKey) + } + + rowOffset, err := strconv.Atoi(parts[1]) + if err != nil { + return IndexKeyRef{}, fmt.Errorf("invalid row offset in index_key %q: %w", indexKey, err) + } + + pathPart := parts[0] + ref := IndexKeyRef{RowOffset: rowOffset} + if strings.HasPrefix(pathPart, "s3://") { + // e.g. s3://mybucket/prefix/.../file.parquet -> bucket=mybucket, key=prefix/.../file.parquet + rest := pathPart[5:] // after "s3://" + idx := strings.Index(rest, "/") + if idx < 0 { + return IndexKeyRef{}, fmt.Errorf("invalid s3 URI in index_key (no path): %s", indexKey) + } + ref.Bucket = rest[:idx] + ref.ObjectKey = rest[idx+1:] + } else { + ref.ObjectKey = pathPart + } + return ref, nil +} + +//------------------------------------------------------------------------------ + +// ObjectGetter is an interface for fetching objects from S3-compatible storage. +// *s3.Client implements it; use this for testing or alternate backends. +type ObjectGetter interface { + GetObject(ctx context.Context, params *s3.GetObjectInput, optFns ...func(*s3.Options)) (*s3.GetObjectOutput, error) +} + +// Reader reads individual row payloads from Parquet files on S3-compatible storage. +// Schema is compatible with CloudEvent Parquet files written by dimo_parquet_writer. +type Reader struct { + objGetter ObjectGetter +} + +// New returns a Reader that uses the given ObjectGetter (e.g. *s3.Client). +func New(objGetter ObjectGetter) *Reader { + return &Reader{objGetter: objGetter} +} + +// ReadData reads the "data" column value for the row at ref.RowOffset in the +// Parquet file at ref.ObjectKey. Bucket is used only when ref.Bucket is empty (relative key). +// Returns nil, nil for null data. +func (r *Reader) ReadData(ctx context.Context, bucket string, ref IndexKeyRef) ([]byte, error) { + bucketToUse := ref.Bucket + if bucketToUse == "" { + bucketToUse = bucket + } + if bucketToUse == "" { + return nil, fmt.Errorf("no bucket for parquet ref (index_key has no s3:// URI and parquet bucket not configured)") + } + // Fetch the Parquet file from object storage. + obj, err := r.objGetter.GetObject(ctx, &s3.GetObjectInput{ + Bucket: aws.String(bucketToUse), + Key: aws.String(ref.ObjectKey), + }) + if err != nil { + return nil, fmt.Errorf("failed to get parquet file %s: %w", ref.ObjectKey, err) + } + defer obj.Body.Close() //nolint + + rawData, err := io.ReadAll(obj.Body) + if err != nil { + return nil, fmt.Errorf("failed to read parquet file body: %w", err) + } + + // Open the Parquet file from the in-memory buffer. + // bytes.Reader satisfies parquet.ReaderAtSeeker (io.ReaderAt + io.ReadSeeker). + pqReader, err := file.NewParquetReader(bytes.NewReader(rawData)) + if err != nil { + return nil, fmt.Errorf("failed to open parquet reader: %w", err) + } + defer func() { _ = pqReader.Close() }() + + // Read the entire file as an Arrow table. + tbl, err := pqarrow.ReadTable(ctx, bytes.NewReader(rawData), nil, pqarrow.ArrowReadProperties{}, memory.DefaultAllocator) + if err != nil { + return nil, fmt.Errorf("failed to read arrow table: %w", err) + } + defer tbl.Release() + + // Validate row offset. + if int64(ref.RowOffset) >= tbl.NumRows() { + return nil, fmt.Errorf("row offset %d out of range (table has %d rows)", ref.RowOffset, tbl.NumRows()) + } + + // Find the "data" column. + dataColIdx := -1 + for i, field := range tbl.Schema().Fields() { + if field.Name == "data" { + dataColIdx = i + break + } + } + if dataColIdx < 0 { + return nil, fmt.Errorf("parquet file %s has no 'data' column", ref.ObjectKey) + } + + // Extract the value at the target row offset. + // Arrow tables store data in chunked arrays; navigate to the right chunk and index. + col := tbl.Column(dataColIdx) + remaining := int64(ref.RowOffset) + for _, chunk := range col.Data().Chunks() { + if remaining < int64(chunk.Len()) { + // Target row is in this chunk. + if chunk.IsNull(int(remaining)) { + return nil, nil // null data value + } + // Binary/ByteArray columns store data as []byte via Value(). + rawVal := chunk.ValueStr(int(remaining)) + out := make([]byte, len(rawVal)) + copy(out, rawVal) + return out, nil + } + remaining -= int64(chunk.Len()) + } + + return nil, fmt.Errorf("row offset %d not found in chunked column data", ref.RowOffset) +} diff --git a/pkg/parquetreader/parquetreader_test.go b/pkg/parquetreader/parquetreader_test.go new file mode 100644 index 0000000..0fab4a6 --- /dev/null +++ b/pkg/parquetreader/parquetreader_test.go @@ -0,0 +1,85 @@ +package parquetreader + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestIsParquetRef(t *testing.T) { + assert.True(t, IsParquetRef("cloudevent/valid/year=2025/month=06/day=15/batch-abc.parquet#3")) + assert.True(t, IsParquetRef("path/file.parquet#0")) + assert.False(t, IsParquetRef("a0000891234bA5738a18d83D41847dfFbDC6101d37C69c9B0cF00000042!2025-06-15T10:30:00Z!dimo.status!abc!id123")) + assert.False(t, IsParquetRef("simple/s3/path.json")) + assert.False(t, IsParquetRef("")) +} + +func TestParseIndexKey(t *testing.T) { + tests := []struct { + name string + key string + wantBucket string + wantPath string + wantOffset int + wantErr bool + }{ + { + name: "valid parquet ref (relative)", + key: "cloudevent/valid/year=2025/month=06/day=15/batch-abc.parquet#3", + wantBucket: "", + wantPath: "cloudevent/valid/year=2025/month=06/day=15/batch-abc.parquet", + wantOffset: 3, + }, + { + name: "zero offset", + key: "path/file.parquet#0", + wantBucket: "", + wantPath: "path/file.parquet", + wantOffset: 0, + }, + { + name: "full s3 URI", + key: "s3://dimo-iceberg-dev/warehouse/cloudevent/valid/year=2025/month=06/day=15/batch-uuid.parquet#0", + wantBucket: "dimo-iceberg-dev", + wantPath: "warehouse/cloudevent/valid/year=2025/month=06/day=15/batch-uuid.parquet", + wantOffset: 0, + }, + { + name: "large offset", + key: "cloudevent/partial/year=2025/month=12/day=31/batch-xyz.parquet#9999", + wantBucket: "", + wantPath: "cloudevent/partial/year=2025/month=12/day=31/batch-xyz.parquet", + wantOffset: 9999, + }, + { + name: "no hash separator", + key: "legacy/s3/path.json", + wantErr: true, + }, + { + name: "non-numeric offset", + key: "path/file.parquet#abc", + wantErr: true, + }, + { + name: "s3 URI with no path", + key: "s3://bucketonly#0", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ref, err := ParseIndexKey(tt.key) + if tt.wantErr { + require.Error(t, err) + return + } + require.NoError(t, err) + assert.Equal(t, tt.wantBucket, ref.Bucket) + assert.Equal(t, tt.wantPath, ref.ObjectKey) + assert.Equal(t, tt.wantOffset, ref.RowOffset) + }) + } +} diff --git a/schema/base.graphqls b/schema/base.graphqls new file mode 100644 index 0000000..8fc8f5a --- /dev/null +++ b/schema/base.graphqls @@ -0,0 +1,69 @@ +""" +A point in time, encoded per RFC-3339. Typically in UTC. +""" +scalar Time + +""" +Arbitrary JSON payload (e.g. cloud event data). +""" +scalar JSON @specifiedBy(url: "https://ibm.github.io/graphql-specs/custom-scalars/json.html") + +""" +The root query type for the Fetch API GraphQL schema. +""" +type Query { + """ + Latest cloud event index matching filters. + """ + latestIndex(tokenId: Int!, filter: CloudEventFilter): CloudEventIndex! + + """ + List cloud event indexes matching filters. + """ + indexes(tokenId: Int!, limit: Int = 10, filter: CloudEventFilter): [CloudEventIndex!]! + + """ + Latest full cloud event as JSON. + """ + latestCloudEvent(tokenId: Int!, filter: CloudEventFilter): JSON! + + """ + List full cloud events as JSON. + """ + cloudEvents(tokenId: Int!, limit: Int = 10, filter: CloudEventFilter): [JSON!]! +} + +""" +CloudEvents header fields per the CloudEvents v1.0 spec. +""" +type CloudEventHeader { + id: String! + source: String! + producer: String! + specversion: String! + subject: String! + time: Time! + type: String! + datacontenttype: String + dataschema: String + dataversion: String + signature: String + tags: [String!] +} + +""" +Cloud event index entry: typed header + storage key. +""" +type CloudEventIndex { + header: CloudEventHeader! + indexKey: String! +} + +input CloudEventFilter { + id: String + type: String + source: String + producer: String + before: Time + after: Time +}