From aaaa9d9a10e1aaab5e59b8da52a4541e70887e0a Mon Sep 17 00:00:00 2001 From: AndrewSisley Date: Fri, 28 Jun 2024 15:55:06 -0400 Subject: [PATCH 01/41] fix: Support one-many self joins without primary directive (#2799) ## Relevant issue(s) Resolves #2620 ## Description Support one-many self joins without primary directive. --- internal/request/graphql/schema/collection.go | 14 ++- tests/integration/schema/one_many_test.go | 90 +++++++++++++++++++ 2 files changed, 96 insertions(+), 8 deletions(-) diff --git a/internal/request/graphql/schema/collection.go b/internal/request/graphql/schema/collection.go index c4180be0f4..d6ae0854d0 100644 --- a/internal/request/graphql/schema/collection.go +++ b/internal/request/graphql/schema/collection.go @@ -667,15 +667,13 @@ func finalizeRelations( continue } - var otherColFieldDescription immutable.Option[client.CollectionFieldDescription] - for _, otherField := range otherColDefinition.Value().Description.Fields { - if otherField.RelationName.Value() == field.RelationName.Value() { - otherColFieldDescription = immutable.Some(otherField) - break - } - } + otherColFieldDescription, hasOtherColFieldDescription := otherColDefinition.Value().Description.GetFieldByRelation( + field.RelationName.Value(), + definition.GetName(), + field.Name, + ) - if !otherColFieldDescription.HasValue() || otherColFieldDescription.Value().Kind.Value().IsArray() { + if !hasOtherColFieldDescription || otherColFieldDescription.Kind.Value().IsArray() { if _, exists := definition.Schema.GetFieldByName(field.Name); !exists { // Relations only defined on one side of the object are possible, and so if this is one of them // or if the other side is an array, we need to add the field to the schema (is primary side) diff --git a/tests/integration/schema/one_many_test.go b/tests/integration/schema/one_many_test.go index bab84b3d40..6783a17e7b 100644 --- a/tests/integration/schema/one_many_test.go +++ b/tests/integration/schema/one_many_test.go @@ -83,3 +83,93 @@ func TestSchemaOneMany_Primary(t *testing.T) { testUtils.ExecuteTestCase(t, test) } + +func TestSchemaOneMany_SelfReferenceOneFieldLexographicallyFirst(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + a: User + b: [User] + } + `, + ExpectedResults: []client.CollectionDescription{ + { + Name: immutable.Some("User"), + Fields: []client.CollectionFieldDescription{ + { + Name: "_docID", + }, + { + Name: "a", + ID: 1, + Kind: immutable.Some[client.FieldKind](client.ObjectKind("User")), + RelationName: immutable.Some("user_user"), + }, + { + Name: "a_id", + ID: 2, + Kind: immutable.Some[client.FieldKind](client.ScalarKind(client.FieldKind_DocID)), + RelationName: immutable.Some("user_user"), + }, + { + Name: "b", + ID: 3, + Kind: immutable.Some[client.FieldKind](client.ObjectArrayKind("User")), + RelationName: immutable.Some("user_user"), + }, + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestSchemaOneMany_SelfReferenceManyFieldLexographicallyFirst(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + b: User + a: [User] + } + `, + ExpectedResults: []client.CollectionDescription{ + { + Name: immutable.Some("User"), + Fields: []client.CollectionFieldDescription{ + { + Name: "_docID", + }, + { + Name: "a", + ID: 1, + Kind: immutable.Some[client.FieldKind](client.ObjectArrayKind("User")), + RelationName: immutable.Some("user_user"), + }, + { + Name: "b", + ID: 2, + Kind: immutable.Some[client.FieldKind](client.ObjectKind("User")), + RelationName: immutable.Some("user_user"), + }, + { + Name: "b_id", + ID: 3, + Kind: immutable.Some[client.FieldKind](client.ScalarKind(client.FieldKind_DocID)), + RelationName: immutable.Some("user_user"), + }, + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} From e2b205d03fcda697a2c8108a37a4cadc5ae231c3 Mon Sep 17 00:00:00 2001 From: Shahzad Lone Date: Sat, 29 Jun 2024 13:54:57 -0400 Subject: [PATCH 02/41] chore(i): Bump & fix the breaking change of libp2p dep (#2791) ## Description - Fix some broken deps ## How has this been tested? ci Specify the platform(s) on which this was tested: - WSL2 --- go.mod | 74 ++++++++++++-------- go.sum | 216 ++++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 198 insertions(+), 92 deletions(-) diff --git a/go.mod b/go.mod index 7ffa87cf4c..fc3c6166e8 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/go-errors/errors v1.5.1 github.com/gofrs/uuid/v5 v5.2.0 github.com/iancoleman/strcase v0.3.0 - github.com/ipfs/boxo v0.19.0 + github.com/ipfs/boxo v0.21.0 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-datastore v0.6.0 @@ -28,10 +28,10 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/lens-vm/lens/host-go v0.0.0-20231127204031-8d858ed2926c github.com/lestrrat-go/jwx/v2 v2.1.0 - github.com/libp2p/go-libp2p v0.33.2 + github.com/libp2p/go-libp2p v0.35.1 github.com/libp2p/go-libp2p-gostream v0.6.0 github.com/libp2p/go-libp2p-kad-dht v0.25.2 - github.com/libp2p/go-libp2p-pubsub v0.10.1 + github.com/libp2p/go-libp2p-pubsub v0.11.0 github.com/libp2p/go-libp2p-record v0.2.0 github.com/multiformats/go-multiaddr v0.12.4 github.com/multiformats/go-multibase v0.2.0 @@ -54,10 +54,10 @@ require ( go.opentelemetry.io/otel/metric v1.27.0 go.opentelemetry.io/otel/sdk/metric v1.27.0 go.uber.org/zap v1.27.0 - golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 + golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/term v0.21.0 google.golang.org/grpc v1.64.0 - google.golang.org/protobuf v1.34.1 + google.golang.org/protobuf v1.34.2 ) require ( @@ -97,20 +97,20 @@ require ( github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/elastic/gosigar v0.14.2 // indirect + github.com/elastic/gosigar v0.14.3 // indirect github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gabriel-vasile/mimetype v1.4.4 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect github.com/go-openapi/swag v0.22.8 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.15.1 // indirect - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/goccy/go-json v0.10.3 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -122,17 +122,17 @@ require ( github.com/google/flatbuffers v2.0.6+incompatible // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 // indirect + github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/gorilla/websocket v1.5.1 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect + github.com/gorilla/websocket v1.5.3 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-metrics v0.5.3 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-uuid v1.0.2 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect - github.com/hashicorp/golang-lru/arc/v2 v2.0.5 // indirect + github.com/hashicorp/golang-lru/arc/v2 v2.0.7 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/huin/goupnp v1.3.0 // indirect @@ -156,8 +156,8 @@ require ( github.com/jorrizza/ed2curve25519 v0.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 // indirect - github.com/klauspost/compress v1.17.7 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -185,7 +185,7 @@ require ( github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/miekg/dns v1.1.58 // indirect + github.com/miekg/dns v1.1.61 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.1 // indirect @@ -199,25 +199,41 @@ require ( github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect - github.com/onsi/ginkgo/v2 v2.15.0 // indirect + github.com/onsi/ginkgo/v2 v2.19.0 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 // indirect + github.com/pion/datachannel v1.5.6 // indirect + github.com/pion/dtls/v2 v2.2.11 // indirect + github.com/pion/ice/v2 v2.3.25 // indirect + github.com/pion/interceptor v0.1.29 // indirect + github.com/pion/logging v0.2.2 // indirect + github.com/pion/mdns v0.0.12 // indirect + github.com/pion/randutil v0.1.0 // indirect + github.com/pion/rtcp v1.2.14 // indirect + github.com/pion/rtp v1.8.6 // indirect + github.com/pion/sctp v1.8.16 // indirect + github.com/pion/sdp/v3 v3.0.9 // indirect + github.com/pion/srtp/v2 v2.0.18 // indirect + github.com/pion/stun v0.6.1 // indirect + github.com/pion/transport/v2 v2.2.5 // indirect + github.com/pion/turn/v2 v2.1.6 // indirect + github.com/pion/webrtc/v3 v3.2.42 // indirect github.com/piprate/json-gold v0.5.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/pquerna/cachecontrol v0.1.0 // indirect - github.com/prometheus/client_golang v1.19.0 // indirect + github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.52.2 // indirect - github.com/prometheus/procfs v0.13.0 // indirect + github.com/prometheus/common v0.54.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/quic-go v0.42.0 // indirect - github.com/quic-go/webtransport-go v0.6.0 // indirect + github.com/quic-go/quic-go v0.45.0 // indirect + github.com/quic-go/webtransport-go v0.8.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/zerolog v1.32.0 // indirect @@ -247,19 +263,19 @@ require ( go.opentelemetry.io/otel/sdk v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.20.1 // indirect + go.uber.org/fx v1.22.0 // indirect go.uber.org/mock v0.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/crypto v0.24.0 // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/net v0.25.0 // indirect + golang.org/x/mod v0.18.0 // indirect + golang.org/x/net v0.26.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.21.0 // indirect golang.org/x/text v0.16.0 // indirect - golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect - gonum.org/v1/gonum v0.14.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240415141817-7cd4c1c1f9ec // indirect + golang.org/x/tools v0.22.0 // indirect + gonum.org/v1/gonum v0.15.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.3.0 // indirect diff --git a/go.sum b/go.sum index b457ef68e9..34845f2e94 100644 --- a/go.sum +++ b/go.sum @@ -147,8 +147,8 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= -github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= -github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/elastic/gosigar v0.14.3 h1:xwkKwPia+hSfg9GqrCUKYdId102m9qTJIIr7egmK/uo= +github.com/elastic/gosigar v0.14.3/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/emicklei/dot v1.6.1 h1:ujpDlBkkwgWUY+qPId5IwapRW/xEoligRSYjioR6DFI= github.com/emicklei/dot v1.6.1/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -171,8 +171,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA= github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= +github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= github.com/getkin/kin-openapi v0.125.0 h1:jyQCyf2qXS1qvs2U00xQzkGCqYPhEhZDmSmVt65fXno= github.com/getkin/kin-openapi v0.125.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= @@ -191,8 +191,8 @@ github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= @@ -209,8 +209,8 @@ github.com/go-playground/validator/v10 v10.15.1 h1:BSe8uhN+xQ4r5guV/ywQI4gO59C2r github.com/go-playground/validator/v10 v10.15.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= @@ -276,10 +276,11 @@ github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo= -github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8 h1:ASJ/LAqdCHOyMYI+dwNxn7Rd8FscNkMyTr1KZU1JI/M= +github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= @@ -287,12 +288,12 @@ github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE0 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f h1:KMlcu9X58lhTA/KrfX8Bi1LQSO4pzoVjTiL3h4Jk+Zk= github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -311,8 +312,8 @@ github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru/arc/v2 v2.0.5 h1:l2zaLDubNhW4XO3LnliVj0GXO3+/CGNJAg1dcN2Fpfw= -github.com/hashicorp/golang-lru/arc/v2 v2.0.5/go.mod h1:ny6zBSQZi2JxIeYcv7kt2sH2PXJtirBN7RDhRpxPkxU= +github.com/hashicorp/golang-lru/arc/v2 v2.0.7 h1:QxkVTxwColcduO+LP7eJO56r2hFiG8zEbfAAzRv52KQ= +github.com/hashicorp/golang-lru/arc/v2 v2.0.7/go.mod h1:Pe7gBlGdc8clY5LJ0LpJXMt5AmgmWNH1g+oFFVUHOEc= 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/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -343,8 +344,8 @@ github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY= github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.19.0 h1:UbX9FBJQF19ACLqRZOgdEla6jR/sC4H1O+iGE0NToXA= -github.com/ipfs/boxo v0.19.0/go.mod h1:V5gJzbIMwKEXrg3IdvAxIdF7UPgU4RsXmNGS8MQ/0D4= +github.com/ipfs/boxo v0.21.0 h1:XpGXb+TQQ0IUdYaeAxGzWjSs6ow/Lce148A/2IbRDVE= +github.com/ipfs/boxo v0.21.0/go.mod h1:NmweAYeY1USOaJJxouy7DLr/Y5M8UBSsCI2KRivO+TY= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= @@ -415,10 +416,10 @@ github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69/go.mod h1:tlkavy github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= -github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= @@ -454,8 +455,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.33.2 h1:vCdwnFxoGOXMKmaGHlDSnL4bM3fQeW8pgIa9DECnb40= -github.com/libp2p/go-libp2p v0.33.2/go.mod h1:zTeppLuCvUIkT118pFVzA8xzP/p2dJYOMApCkFh0Yww= +github.com/libp2p/go-libp2p v0.35.1 h1:Hm7Ub2BF+GCb14ojcsEK6WAy5it5smPDK02iXSZLl50= +github.com/libp2p/go-libp2p v0.35.1/go.mod h1:Dnkgba5hsfSv5dvvXC8nfqk44hH0gIKKno+HOMU0fdc= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qkCnjyaZUPYU= @@ -464,8 +465,8 @@ github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0Trt github.com/libp2p/go-libp2p-kad-dht v0.25.2/go.mod h1:6za56ncRHYXX4Nc2vn8z7CZK0P4QiMcrn77acKLM2Oo= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= -github.com/libp2p/go-libp2p-pubsub v0.10.1 h1:/RqOZpEtAolsr8/9CC8KqROJSOZeu7lK7fPftn4MwNg= -github.com/libp2p/go-libp2p-pubsub v0.10.1/go.mod h1:1OxbaT/pFRO5h+Dpze8hdHQ63R0ke55XTs6b6NwLLkw= +github.com/libp2p/go-libp2p-pubsub v0.11.0 h1:+JvS8Kty0OiyUiN0i8H5JbaCgjnJTRnTHe4rU88dLFc= +github.com/libp2p/go-libp2p-pubsub v0.11.0/go.mod h1:QEb+hEV9WL9wCiUAnpY29FZR6W3zK8qYlaml8R4q6gQ= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= github.com/libp2p/go-libp2p-routing-helpers v0.7.3 h1:u1LGzAMVRK9Nqq5aYDVOiq/HaB93U9WWczBzGyAC5ZY= @@ -506,8 +507,8 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= -github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= +github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= +github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -559,8 +560,9 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a h1:dlRvE5fWabOchtH7znfiFCcOvmIYgOeAS5ifBXBlh9Q= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -570,15 +572,15 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= -github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= +github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= +github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= -github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -598,6 +600,50 @@ github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 h1:jik8PHtAIsPlCR github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pion/datachannel v1.5.6 h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGeg= +github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNIVb/NfGW4= +github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= +github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks= +github.com/pion/dtls/v2 v2.2.11/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= +github.com/pion/ice/v2 v2.3.25 h1:M5rJA07dqhi3nobJIg+uPtcVjFECTrhcR3n0ns8kDZs= +github.com/pion/ice/v2 v2.3.25/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw= +github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= +github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8= +github.com/pion/mdns v0.0.12/go.mod h1:VExJjv8to/6Wqm1FXK+Ii/Z9tsVk/F5sD/N70cnYFbk= +github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= +github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= +github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= +github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= +github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= +github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/rtp v1.8.6 h1:MTmn/b0aWWsAzux2AmP8WGllusBVw4NPYPVFFd7jUPw= +github.com/pion/rtp v1.8.6/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/sctp v1.8.13/go.mod h1:YKSgO/bO/6aOMP9LCie1DuD7m+GamiK2yIiPM6vH+GA= +github.com/pion/sctp v1.8.16 h1:PKrMs+o9EMLRvFfXq59WFsC+V8mN1wnKzqrv+3D/gYY= +github.com/pion/sctp v1.8.16/go.mod h1:P6PbDVA++OJMrVNg2AL3XtYHV4uD6dvfyOovCgMs0PE= +github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= +github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= +github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo= +github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= +github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= +github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= +github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= +github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc= +github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v2 v2.2.5 h1:iyi25i/21gQck4hfRhomF6SktmUQjRsRW4WJdhfc3Kc= +github.com/pion/transport/v2 v2.2.5/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= +github.com/pion/transport/v3 v3.0.2 h1:r+40RJR25S9w3jbA6/5uEPTzcdn7ncyU44RWCbHkLg4= +github.com/pion/transport/v3 v3.0.2/go.mod h1:nIToODoOlb5If2jF9y2Igfx3PFYWfuXi37m0IlWa/D0= +github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= +github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= +github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= +github.com/pion/webrtc/v3 v3.2.42 h1:WN/ZuMjtpQOoGRCZUg/zFG+JHEvYLVyDKOxU6H1qWlE= +github.com/pion/webrtc/v3 v3.2.42/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY= github.com/piprate/json-gold v0.5.0 h1:RmGh1PYboCFcchVFuh2pbSWAZy4XJaqTMU4KQYsApbM= github.com/piprate/json-gold v0.5.0/go.mod h1:WZ501QQMbZZ+3pXFPhQKzNwS1+jls0oqov3uQ2WasLs= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -616,8 +662,8 @@ github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= -github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -627,20 +673,20 @@ github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQy github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.52.2 h1:LW8Vk7BccEdONfrJBDffQGRtpSzi5CQaRZGtboOO2ck= -github.com/prometheus/common v0.52.2/go.mod h1:lrWtQx+iDfn2mbH5GUzlH9TSHyfZpHkSiG1W7y3sF2Q= +github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8= +github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o= -github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM= -github.com/quic-go/quic-go v0.42.0/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M= -github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= -github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= +github.com/quic-go/quic-go v0.45.0 h1:OHmkQGM37luZITyTSu6ff03HP/2IrwDX1ZFiNEhSFUE= +github.com/quic-go/quic-go v0.45.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= +github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= +github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -746,6 +792,7 @@ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1F github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= @@ -792,6 +839,7 @@ github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcY github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8= github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= @@ -809,12 +857,10 @@ go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5 go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= -go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= -go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= +go.uber.org/fx v1.22.0 h1:pApUK7yL0OUHMd8vkunWSlLxZVFFk70jR2nKde8X2NM= +go.uber.org/fx v1.22.0/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= @@ -842,11 +888,18 @@ golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8= -golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -858,8 +911,10 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -883,8 +938,17 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -898,6 +962,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.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -933,15 +999,32 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -949,6 +1032,11 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -973,15 +1061,17 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= 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-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= -gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= +gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ= +gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= @@ -996,10 +1086,10 @@ google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be h1:Zz7rLWqp0ApfsR/l7+zSHhY3PMiH2xqgxlfYfAfNpoU= -google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be/go.mod h1:dvdCTIoAGbkWbcIKBniID56/7XHTt6WfxXNMxuziJ+w= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240415141817-7cd4c1c1f9ec h1:C3cpGJVV1aqtO+b3L4LV6wQsB7sYplbahYZxrjkZd3A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240415141817-7cd4c1c1f9ec/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 h1:MuYw1wJzT+ZkybKfaOXKp5hJiZDn2iHaXRw0mRYdHSc= +google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4/go.mod h1:px9SlOOZBg1wM1zdnr8jEL4CNGUBZ+ZKYtNPApNQc4c= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 h1:Di6ANFilr+S60a4S61ZM00vLdw0IrQOSMS2/6mrnOU0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1022,8 +1112,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 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= From 204c8efc3a4ac691e9b6d7487cb6595cd55ccd45 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 29 Jun 2024 14:16:58 -0400 Subject: [PATCH 03/41] bot: Bump github.com/cometbft/cometbft from 0.38.7 to 0.38.8 (#2794) Bumps [github.com/cometbft/cometbft](https://github.com/cometbft/cometbft) from 0.38.7 to 0.38.8.
Release notes

Sourced from github.com/cometbft/cometbft's releases.

v0.38.8

See the CHANGELOG for this release.

Changelog

Sourced from github.com/cometbft/cometbft's changelog.

v0.38.8

June 27, 2024

This release contains a few bug fixes and performance improvements.

BREAKING CHANGES

  • [mempool] Add to the Mempool interface a new method PreUpdate(). This method should be called before acquiring the mempool lock, to signal that a new update is coming. Also add to ErrMempoolIsFull a new field RecheckFull. (#3314)

BUG FIXES

  • [mempool] Fix data race when rechecking with async ABCI client (#1827)
  • [consensus] Fix a race condition in the consensus timeout ticker. Race is caused by two timeouts being scheduled at the same time. (#3092)
  • [types] Do not batch verify a commit if the validator set keys have different types. (#3195

IMPROVEMENTS

  • [blockstore] Added peer banning in blockstore (#ABC-0013)
  • [blockstore] Send correct error message when vote extensions do not align with received packet (#ABC-0014)
  • [config] Added recheck_timeout mempool parameter to set how much time to wait for recheck responses from the app (only applies to non-local ABCI clients). (#1827)
  • [rpc] Add a configurable maximum batch size for RPC requests. (#2867).
  • [event-bus] Remove the debug logs in PublishEventTx, which were noticed production slowdowns. (#2911)
  • [state/execution] Cache the block hash computation inside of the Block Type, so we only compute it once. (#2924)
  • [consensus/state] Remove a redundant VerifyBlock call in FinalizeCommit (#2928)
  • [p2p/channel] Speedup ProtoIO writer creation time, and thereby speedup channel writing by 5%. (#2949)
  • [p2p/conn] Minor speedup (3%) to connection.WritePacketMsgTo, by removing MinInt calls. (#2952)
  • [internal/bits] 10x speedup creating initialized bitArrays, which speedsup extendedCommit.BitArray(). This is used in consensus vote gossip. (#2959).
  • [blockstore] Remove a redundant Header.ValidateBasic call in LoadBlockMeta, 75% reducing this time. (#2964)
  • [p2p/conn] Speedup connection.WritePacketMsgTo, by reusing internal buffers rather than re-allocating. (#2986)
  • [blockstore] Use LRU caches in blockstore, significiantly improving consensus gossip routine performance

... (truncated)

Commits
  • 6959205 Release/v0.38.8 (#3350)
  • 8ba2e4f Merge pull request from GHSA-hg58-rf2h-6rr7
  • 0a89ec1 Update blocksync/pool_test.go
  • 065810c Readded good peer to test
  • 007efd7 Removed defers from test
  • 4199f27 Remove one thread to make test more compact
  • 8a473ca Update blocksync/pool_test.go
  • 872210c Update blocksync/pool_test.go
  • 4cb0df8 Update blocksync/pool_test.go
  • 26bda8b Test assertions have more detail
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/cometbft/cometbft&package-manager=go_modules&previous-version=0.38.7&new-version=0.38.8)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/sourcenetwork/defradb/network/alerts).
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index fc3c6166e8..6efc0e1590 100644 --- a/go.mod +++ b/go.mod @@ -83,7 +83,7 @@ require ( github.com/cockroachdb/pebble v1.1.0 // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/cometbft/cometbft v0.38.7 // indirect + github.com/cometbft/cometbft v0.38.8 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cosmos/cosmos-db v1.0.2 // indirect diff --git a/go.sum b/go.sum index 34845f2e94..3f8aaf0ce5 100644 --- a/go.sum +++ b/go.sum @@ -91,8 +91,8 @@ github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwP github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= -github.com/cometbft/cometbft v0.38.7 h1:ULhIOJ9+LgSy6nLekhq9ae3juX3NnQUMMPyVdhZV6Hk= -github.com/cometbft/cometbft v0.38.7/go.mod h1:HIyf811dFMI73IE0F7RrnY/Fr+d1+HuJAgtkEpQjCMY= +github.com/cometbft/cometbft v0.38.8 h1:XyJ9Cu3xqap6xtNxiemrO8roXZ+KS2Zlu7qQ0w1trvU= +github.com/cometbft/cometbft v0.38.8/go.mod h1:xOoGZrtUT+A5izWfHSJgl0gYZUE7lu7Z2XIS1vWG/QQ= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= From ea77dc2bb942ca455df43ce149a0adbfa5bfac82 Mon Sep 17 00:00:00 2001 From: Fred Carle Date: Mon, 1 Jul 2024 19:15:51 -0400 Subject: [PATCH 04/41] refactor: Decouple client.DB from net (#2768) ## Relevant issue(s) Resolves #2767 ## Description This PR make the `net` package no longer dependent on `client.DB`. Instead, on creation, the peer takes in a rootstore, a blockstore and an event bus. The p2p collections and replicators have been moved to `db`. Most of the code is reused but it now makes use of the event bus to update the peer's related state (pubsub topics and peer connections). --- client/db.go | 11 +- client/errors.go | 1 + client/mocks/db.go | 391 ++++++- client/p2p.go | 2 - datastore/blockstore.go | 2 +- datastore/mocks/root_store.go | 178 ++-- datastore/mocks/txn.go | 74 +- datastore/mocks/utils.go | 6 +- datastore/multi.go | 6 +- datastore/store.go | 14 +- event/event.go | 32 + go.mod | 2 +- http/client.go | 4 +- http/client_tx.go | 2 +- internal/db/db.go | 22 +- internal/db/errors.go | 28 + internal/db/fetcher/versioned.go | 12 +- internal/db/index_test.go | 26 +- internal/db/merge.go | 50 +- internal/db/merge_test.go | 6 +- internal/db/messages.go | 84 ++ internal/db/p2p_replicator.go | 346 +++++++ internal/db/p2p_replicator_test.go | 320 ++++++ .../db/p2p_schema_root.go | 140 +-- internal/db/p2p_schema_root_test.go | 307 ++++++ internal/merkle/clock/clock.go | 18 +- internal/merkle/clock/clock_test.go | 6 +- internal/merkle/crdt/composite.go | 2 +- internal/merkle/crdt/counter.go | 2 +- internal/merkle/crdt/lwwreg.go | 2 +- internal/merkle/crdt/merklecrdt.go | 2 +- internal/merkle/crdt/merklecrdt_test.go | 2 +- internal/planner/commit.go | 2 +- net/client_test.go | 50 +- net/dialer_test.go | 42 +- net/errors.go | 33 +- net/node.go | 282 ----- net/node_test.go | 204 ---- net/peer.go | 429 ++++---- net/peer_replicator.go | 230 ----- net/peer_test.go | 965 +++++------------- net/server.go | 110 +- net/server_test.go | 163 +-- node/node.go | 28 +- node/store.go | 2 +- tests/bench/bench_util.go | 2 +- tests/bench/query/planner/utils.go | 2 +- tests/bench/storage/utils.go | 4 +- tests/clients/cli/wrapper.go | 32 +- tests/clients/cli/wrapper_tx.go | 4 +- tests/clients/clients.go | 2 +- tests/clients/http/wrapper.go | 32 +- tests/clients/http/wrapper_tx.go | 4 +- tests/integration/client.go | 33 +- tests/integration/db.go | 6 +- tests/integration/p2p.go | 36 +- tests/integration/utils2.go | 75 +- 57 files changed, 2643 insertions(+), 2229 deletions(-) create mode 100644 internal/db/messages.go create mode 100644 internal/db/p2p_replicator.go create mode 100644 internal/db/p2p_replicator_test.go rename net/peer_collection.go => internal/db/p2p_schema_root.go (59%) create mode 100644 internal/db/p2p_schema_root_test.go delete mode 100644 net/node.go delete mode 100644 net/node_test.go delete mode 100644 net/peer_replicator.go diff --git a/client/db.go b/client/db.go index e52dfed60a..ad2229cdb0 100644 --- a/client/db.go +++ b/client/db.go @@ -42,13 +42,13 @@ type DB interface { // can safely operate on it concurrently. NewConcurrentTxn(context.Context, bool) (datastore.Txn, error) - // Root returns the underlying root store, within which all data managed by DefraDB is held. - Root() datastore.RootStore + // Rootstore returns the underlying root store, within which all data managed by DefraDB is held. + Rootstore() datastore.Rootstore // Blockstore returns the blockstore, within which all blocks (commits) managed by DefraDB are held. // // It sits within the rootstore returned by [Root]. - Blockstore() datastore.DAGStore + Blockstore() datastore.Blockstore // Peerstore returns the peerstore where known host information is stored. // @@ -106,6 +106,11 @@ type Store interface { // Backup holds the backup related methods that must be implemented by the database. Backup + // P2P contains functions related to the P2P system. + // + // These functions are only useful if there is a configured network peer. + P2P + // AddSchema takes the provided GQL schema in SDL format, and applies it to the [Store], // creating the necessary collections, request types, etc. // diff --git a/client/errors.go b/client/errors.go index 460392a030..dac8ebcc87 100644 --- a/client/errors.go +++ b/client/errors.go @@ -56,6 +56,7 @@ var ( ErrCanNotNormalizeValue = errors.New(errCanNotNormalizeValue) ErrCanNotTurnNormalValueIntoArray = errors.New(errCanNotTurnNormalValueIntoArray) ErrCanNotMakeNormalNilFromFieldKind = errors.New(errCanNotMakeNormalNilFromFieldKind) + ErrCollectionNotFound = errors.New(errCollectionNotFound) ) // NewErrFieldNotExist returns an error indicating that the given field does not exist. diff --git a/client/mocks/db.go b/client/mocks/db.go index 396bc5397c..089e41c159 100644 --- a/client/mocks/db.go +++ b/client/mocks/db.go @@ -18,6 +18,8 @@ import ( mock "github.com/stretchr/testify/mock" model "github.com/lens-vm/lens/host-go/config/model" + + peer "github.com/libp2p/go-libp2p/core/peer" ) // DB is an autogenerated mock type for the DB type @@ -33,6 +35,53 @@ func (_m *DB) EXPECT() *DB_Expecter { return &DB_Expecter{mock: &_m.Mock} } +// AddP2PCollections provides a mock function with given fields: ctx, collectionIDs +func (_m *DB) AddP2PCollections(ctx context.Context, collectionIDs []string) error { + ret := _m.Called(ctx, collectionIDs) + + if len(ret) == 0 { + panic("no return value specified for AddP2PCollections") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, []string) error); ok { + r0 = rf(ctx, collectionIDs) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DB_AddP2PCollections_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddP2PCollections' +type DB_AddP2PCollections_Call struct { + *mock.Call +} + +// AddP2PCollections is a helper method to define mock.On call +// - ctx context.Context +// - collectionIDs []string +func (_e *DB_Expecter) AddP2PCollections(ctx interface{}, collectionIDs interface{}) *DB_AddP2PCollections_Call { + return &DB_AddP2PCollections_Call{Call: _e.mock.On("AddP2PCollections", ctx, collectionIDs)} +} + +func (_c *DB_AddP2PCollections_Call) Run(run func(ctx context.Context, collectionIDs []string)) *DB_AddP2PCollections_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]string)) + }) + return _c +} + +func (_c *DB_AddP2PCollections_Call) Return(_a0 error) *DB_AddP2PCollections_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *DB_AddP2PCollections_Call) RunAndReturn(run func(context.Context, []string) error) *DB_AddP2PCollections_Call { + _c.Call.Return(run) + return _c +} + // AddPolicy provides a mock function with given fields: ctx, policy func (_m *DB) AddPolicy(ctx context.Context, policy string) (client.AddPolicyResult, error) { ret := _m.Called(ctx, policy) @@ -305,19 +354,19 @@ func (_c *DB_BasicImport_Call) RunAndReturn(run func(context.Context, string) er } // Blockstore provides a mock function with given fields: -func (_m *DB) Blockstore() datastore.DAGStore { +func (_m *DB) Blockstore() datastore.Blockstore { ret := _m.Called() if len(ret) == 0 { panic("no return value specified for Blockstore") } - var r0 datastore.DAGStore - if rf, ok := ret.Get(0).(func() datastore.DAGStore); ok { + var r0 datastore.Blockstore + if rf, ok := ret.Get(0).(func() datastore.Blockstore); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(datastore.DAGStore) + r0 = ret.Get(0).(datastore.Blockstore) } } @@ -341,12 +390,12 @@ func (_c *DB_Blockstore_Call) Run(run func()) *DB_Blockstore_Call { return _c } -func (_c *DB_Blockstore_Call) Return(_a0 datastore.DAGStore) *DB_Blockstore_Call { +func (_c *DB_Blockstore_Call) Return(_a0 datastore.Blockstore) *DB_Blockstore_Call { _c.Call.Return(_a0) return _c } -func (_c *DB_Blockstore_Call) RunAndReturn(run func() datastore.DAGStore) *DB_Blockstore_Call { +func (_c *DB_Blockstore_Call) RunAndReturn(run func() datastore.Blockstore) *DB_Blockstore_Call { _c.Call.Return(run) return _c } @@ -383,6 +432,53 @@ func (_c *DB_Close_Call) RunAndReturn(run func()) *DB_Close_Call { return _c } +// DeleteReplicator provides a mock function with given fields: ctx, rep +func (_m *DB) DeleteReplicator(ctx context.Context, rep client.Replicator) error { + ret := _m.Called(ctx, rep) + + if len(ret) == 0 { + panic("no return value specified for DeleteReplicator") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, client.Replicator) error); ok { + r0 = rf(ctx, rep) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DB_DeleteReplicator_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteReplicator' +type DB_DeleteReplicator_Call struct { + *mock.Call +} + +// DeleteReplicator is a helper method to define mock.On call +// - ctx context.Context +// - rep client.Replicator +func (_e *DB_Expecter) DeleteReplicator(ctx interface{}, rep interface{}) *DB_DeleteReplicator_Call { + return &DB_DeleteReplicator_Call{Call: _e.mock.On("DeleteReplicator", ctx, rep)} +} + +func (_c *DB_DeleteReplicator_Call) Run(run func(ctx context.Context, rep client.Replicator)) *DB_DeleteReplicator_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(client.Replicator)) + }) + return _c +} + +func (_c *DB_DeleteReplicator_Call) Return(_a0 error) *DB_DeleteReplicator_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *DB_DeleteReplicator_Call) RunAndReturn(run func(context.Context, client.Replicator) error) *DB_DeleteReplicator_Call { + _c.Call.Return(run) + return _c +} + // Events provides a mock function with given fields: func (_m *DB) Events() *event.Bus { ret := _m.Called() @@ -537,6 +633,122 @@ func (_c *DB_GetAllIndexes_Call) RunAndReturn(run func(context.Context) (map[str return _c } +// GetAllP2PCollections provides a mock function with given fields: ctx +func (_m *DB) GetAllP2PCollections(ctx context.Context) ([]string, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetAllP2PCollections") + } + + var r0 []string + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]string, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []string); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]string) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DB_GetAllP2PCollections_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAllP2PCollections' +type DB_GetAllP2PCollections_Call struct { + *mock.Call +} + +// GetAllP2PCollections is a helper method to define mock.On call +// - ctx context.Context +func (_e *DB_Expecter) GetAllP2PCollections(ctx interface{}) *DB_GetAllP2PCollections_Call { + return &DB_GetAllP2PCollections_Call{Call: _e.mock.On("GetAllP2PCollections", ctx)} +} + +func (_c *DB_GetAllP2PCollections_Call) Run(run func(ctx context.Context)) *DB_GetAllP2PCollections_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *DB_GetAllP2PCollections_Call) Return(_a0 []string, _a1 error) *DB_GetAllP2PCollections_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *DB_GetAllP2PCollections_Call) RunAndReturn(run func(context.Context) ([]string, error)) *DB_GetAllP2PCollections_Call { + _c.Call.Return(run) + return _c +} + +// GetAllReplicators provides a mock function with given fields: ctx +func (_m *DB) GetAllReplicators(ctx context.Context) ([]client.Replicator, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetAllReplicators") + } + + var r0 []client.Replicator + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]client.Replicator, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []client.Replicator); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]client.Replicator) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DB_GetAllReplicators_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAllReplicators' +type DB_GetAllReplicators_Call struct { + *mock.Call +} + +// GetAllReplicators is a helper method to define mock.On call +// - ctx context.Context +func (_e *DB_Expecter) GetAllReplicators(ctx interface{}) *DB_GetAllReplicators_Call { + return &DB_GetAllReplicators_Call{Call: _e.mock.On("GetAllReplicators", ctx)} +} + +func (_c *DB_GetAllReplicators_Call) Run(run func(ctx context.Context)) *DB_GetAllReplicators_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context)) + }) + return _c +} + +func (_c *DB_GetAllReplicators_Call) Return(_a0 []client.Replicator, _a1 error) *DB_GetAllReplicators_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *DB_GetAllReplicators_Call) RunAndReturn(run func(context.Context) ([]client.Replicator, error)) *DB_GetAllReplicators_Call { + _c.Call.Return(run) + return _c +} + // GetCollectionByName provides a mock function with given fields: _a0, _a1 func (_m *DB) GetCollectionByName(_a0 context.Context, _a1 string) (client.Collection, error) { ret := _m.Called(_a0, _a1) @@ -1124,6 +1336,51 @@ func (_c *DB_PatchSchema_Call) RunAndReturn(run func(context.Context, string, im return _c } +// PeerInfo provides a mock function with given fields: +func (_m *DB) PeerInfo() peer.AddrInfo { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for PeerInfo") + } + + var r0 peer.AddrInfo + if rf, ok := ret.Get(0).(func() peer.AddrInfo); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(peer.AddrInfo) + } + + return r0 +} + +// DB_PeerInfo_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PeerInfo' +type DB_PeerInfo_Call struct { + *mock.Call +} + +// PeerInfo is a helper method to define mock.On call +func (_e *DB_Expecter) PeerInfo() *DB_PeerInfo_Call { + return &DB_PeerInfo_Call{Call: _e.mock.On("PeerInfo")} +} + +func (_c *DB_PeerInfo_Call) Run(run func()) *DB_PeerInfo_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *DB_PeerInfo_Call) Return(_a0 peer.AddrInfo) *DB_PeerInfo_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *DB_PeerInfo_Call) RunAndReturn(run func() peer.AddrInfo) *DB_PeerInfo_Call { + _c.Call.Return(run) + return _c +} + // Peerstore provides a mock function with given fields: func (_m *DB) Peerstore() datastore.DSBatching { ret := _m.Called() @@ -1217,49 +1474,96 @@ func (_c *DB_PrintDump_Call) RunAndReturn(run func(context.Context) error) *DB_P return _c } -// Root provides a mock function with given fields: -func (_m *DB) Root() datastore.RootStore { +// RemoveP2PCollections provides a mock function with given fields: ctx, collectionIDs +func (_m *DB) RemoveP2PCollections(ctx context.Context, collectionIDs []string) error { + ret := _m.Called(ctx, collectionIDs) + + if len(ret) == 0 { + panic("no return value specified for RemoveP2PCollections") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, []string) error); ok { + r0 = rf(ctx, collectionIDs) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DB_RemoveP2PCollections_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveP2PCollections' +type DB_RemoveP2PCollections_Call struct { + *mock.Call +} + +// RemoveP2PCollections is a helper method to define mock.On call +// - ctx context.Context +// - collectionIDs []string +func (_e *DB_Expecter) RemoveP2PCollections(ctx interface{}, collectionIDs interface{}) *DB_RemoveP2PCollections_Call { + return &DB_RemoveP2PCollections_Call{Call: _e.mock.On("RemoveP2PCollections", ctx, collectionIDs)} +} + +func (_c *DB_RemoveP2PCollections_Call) Run(run func(ctx context.Context, collectionIDs []string)) *DB_RemoveP2PCollections_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]string)) + }) + return _c +} + +func (_c *DB_RemoveP2PCollections_Call) Return(_a0 error) *DB_RemoveP2PCollections_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *DB_RemoveP2PCollections_Call) RunAndReturn(run func(context.Context, []string) error) *DB_RemoveP2PCollections_Call { + _c.Call.Return(run) + return _c +} + +// Rootstore provides a mock function with given fields: +func (_m *DB) Rootstore() datastore.Rootstore { ret := _m.Called() if len(ret) == 0 { - panic("no return value specified for Root") + panic("no return value specified for Rootstore") } - var r0 datastore.RootStore - if rf, ok := ret.Get(0).(func() datastore.RootStore); ok { + var r0 datastore.Rootstore + if rf, ok := ret.Get(0).(func() datastore.Rootstore); ok { r0 = rf() } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(datastore.RootStore) + r0 = ret.Get(0).(datastore.Rootstore) } } return r0 } -// DB_Root_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Root' -type DB_Root_Call struct { +// DB_Rootstore_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Rootstore' +type DB_Rootstore_Call struct { *mock.Call } -// Root is a helper method to define mock.On call -func (_e *DB_Expecter) Root() *DB_Root_Call { - return &DB_Root_Call{Call: _e.mock.On("Root")} +// Rootstore is a helper method to define mock.On call +func (_e *DB_Expecter) Rootstore() *DB_Rootstore_Call { + return &DB_Rootstore_Call{Call: _e.mock.On("Rootstore")} } -func (_c *DB_Root_Call) Run(run func()) *DB_Root_Call { +func (_c *DB_Rootstore_Call) Run(run func()) *DB_Rootstore_Call { _c.Call.Run(func(args mock.Arguments) { run() }) return _c } -func (_c *DB_Root_Call) Return(_a0 datastore.RootStore) *DB_Root_Call { +func (_c *DB_Rootstore_Call) Return(_a0 datastore.Rootstore) *DB_Rootstore_Call { _c.Call.Return(_a0) return _c } -func (_c *DB_Root_Call) RunAndReturn(run func() datastore.RootStore) *DB_Root_Call { +func (_c *DB_Rootstore_Call) RunAndReturn(run func() datastore.Rootstore) *DB_Rootstore_Call { _c.Call.Return(run) return _c } @@ -1358,6 +1662,53 @@ func (_c *DB_SetMigration_Call) RunAndReturn(run func(context.Context, client.Le return _c } +// SetReplicator provides a mock function with given fields: ctx, rep +func (_m *DB) SetReplicator(ctx context.Context, rep client.Replicator) error { + ret := _m.Called(ctx, rep) + + if len(ret) == 0 { + panic("no return value specified for SetReplicator") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, client.Replicator) error); ok { + r0 = rf(ctx, rep) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DB_SetReplicator_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetReplicator' +type DB_SetReplicator_Call struct { + *mock.Call +} + +// SetReplicator is a helper method to define mock.On call +// - ctx context.Context +// - rep client.Replicator +func (_e *DB_Expecter) SetReplicator(ctx interface{}, rep interface{}) *DB_SetReplicator_Call { + return &DB_SetReplicator_Call{Call: _e.mock.On("SetReplicator", ctx, rep)} +} + +func (_c *DB_SetReplicator_Call) Run(run func(ctx context.Context, rep client.Replicator)) *DB_SetReplicator_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(client.Replicator)) + }) + return _c +} + +func (_c *DB_SetReplicator_Call) Return(_a0 error) *DB_SetReplicator_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *DB_SetReplicator_Call) RunAndReturn(run func(context.Context, client.Replicator) error) *DB_SetReplicator_Call { + _c.Call.Return(run) + return _c +} + // NewDB creates a new instance of DB. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewDB(t interface { diff --git a/client/p2p.go b/client/p2p.go index 12be6ebf8d..d3d3c699b3 100644 --- a/client/p2p.go +++ b/client/p2p.go @@ -18,8 +18,6 @@ import ( // P2P is a peer connected database implementation. type P2P interface { - DB - // PeerInfo returns the p2p host id and listening addresses. PeerInfo() peer.AddrInfo diff --git a/datastore/blockstore.go b/datastore/blockstore.go index f9f92198cd..408e209eff 100644 --- a/datastore/blockstore.go +++ b/datastore/blockstore.go @@ -62,7 +62,7 @@ type bstore struct { } var _ blockstore.Blockstore = (*bstore)(nil) -var _ DAGStore = (*bstore)(nil) +var _ Blockstore = (*bstore)(nil) // AsIPLDStorage returns an IPLDStorage instance. // diff --git a/datastore/mocks/root_store.go b/datastore/mocks/root_store.go index 94d2694721..1cd09f9e7c 100644 --- a/datastore/mocks/root_store.go +++ b/datastore/mocks/root_store.go @@ -12,21 +12,21 @@ import ( query "github.com/ipfs/go-datastore/query" ) -// RootStore is an autogenerated mock type for the RootStore type -type RootStore struct { +// Rootstore is an autogenerated mock type for the Rootstore type +type Rootstore struct { mock.Mock } -type RootStore_Expecter struct { +type Rootstore_Expecter struct { mock *mock.Mock } -func (_m *RootStore) EXPECT() *RootStore_Expecter { - return &RootStore_Expecter{mock: &_m.Mock} +func (_m *Rootstore) EXPECT() *Rootstore_Expecter { + return &Rootstore_Expecter{mock: &_m.Mock} } // Batch provides a mock function with given fields: ctx -func (_m *RootStore) Batch(ctx context.Context) (datastore.Batch, error) { +func (_m *Rootstore) Batch(ctx context.Context) (datastore.Batch, error) { ret := _m.Called(ctx) if len(ret) == 0 { @@ -55,36 +55,36 @@ func (_m *RootStore) Batch(ctx context.Context) (datastore.Batch, error) { return r0, r1 } -// RootStore_Batch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Batch' -type RootStore_Batch_Call struct { +// Rootstore_Batch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Batch' +type Rootstore_Batch_Call struct { *mock.Call } // Batch is a helper method to define mock.On call // - ctx context.Context -func (_e *RootStore_Expecter) Batch(ctx interface{}) *RootStore_Batch_Call { - return &RootStore_Batch_Call{Call: _e.mock.On("Batch", ctx)} +func (_e *Rootstore_Expecter) Batch(ctx interface{}) *Rootstore_Batch_Call { + return &Rootstore_Batch_Call{Call: _e.mock.On("Batch", ctx)} } -func (_c *RootStore_Batch_Call) Run(run func(ctx context.Context)) *RootStore_Batch_Call { +func (_c *Rootstore_Batch_Call) Run(run func(ctx context.Context)) *Rootstore_Batch_Call { _c.Call.Run(func(args mock.Arguments) { run(args[0].(context.Context)) }) return _c } -func (_c *RootStore_Batch_Call) Return(_a0 datastore.Batch, _a1 error) *RootStore_Batch_Call { +func (_c *Rootstore_Batch_Call) Return(_a0 datastore.Batch, _a1 error) *Rootstore_Batch_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *RootStore_Batch_Call) RunAndReturn(run func(context.Context) (datastore.Batch, error)) *RootStore_Batch_Call { +func (_c *Rootstore_Batch_Call) RunAndReturn(run func(context.Context) (datastore.Batch, error)) *Rootstore_Batch_Call { _c.Call.Return(run) return _c } // Close provides a mock function with given fields: -func (_m *RootStore) Close() error { +func (_m *Rootstore) Close() error { ret := _m.Called() if len(ret) == 0 { @@ -101,35 +101,35 @@ func (_m *RootStore) Close() error { return r0 } -// RootStore_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' -type RootStore_Close_Call struct { +// Rootstore_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close' +type Rootstore_Close_Call struct { *mock.Call } // Close is a helper method to define mock.On call -func (_e *RootStore_Expecter) Close() *RootStore_Close_Call { - return &RootStore_Close_Call{Call: _e.mock.On("Close")} +func (_e *Rootstore_Expecter) Close() *Rootstore_Close_Call { + return &Rootstore_Close_Call{Call: _e.mock.On("Close")} } -func (_c *RootStore_Close_Call) Run(run func()) *RootStore_Close_Call { +func (_c *Rootstore_Close_Call) Run(run func()) *Rootstore_Close_Call { _c.Call.Run(func(args mock.Arguments) { run() }) return _c } -func (_c *RootStore_Close_Call) Return(_a0 error) *RootStore_Close_Call { +func (_c *Rootstore_Close_Call) Return(_a0 error) *Rootstore_Close_Call { _c.Call.Return(_a0) return _c } -func (_c *RootStore_Close_Call) RunAndReturn(run func() error) *RootStore_Close_Call { +func (_c *Rootstore_Close_Call) RunAndReturn(run func() error) *Rootstore_Close_Call { _c.Call.Return(run) return _c } // Delete provides a mock function with given fields: ctx, key -func (_m *RootStore) Delete(ctx context.Context, key datastore.Key) error { +func (_m *Rootstore) Delete(ctx context.Context, key datastore.Key) error { ret := _m.Called(ctx, key) if len(ret) == 0 { @@ -146,37 +146,37 @@ func (_m *RootStore) Delete(ctx context.Context, key datastore.Key) error { return r0 } -// RootStore_Delete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Delete' -type RootStore_Delete_Call struct { +// Rootstore_Delete_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Delete' +type Rootstore_Delete_Call struct { *mock.Call } // Delete is a helper method to define mock.On call // - ctx context.Context // - key datastore.Key -func (_e *RootStore_Expecter) Delete(ctx interface{}, key interface{}) *RootStore_Delete_Call { - return &RootStore_Delete_Call{Call: _e.mock.On("Delete", ctx, key)} +func (_e *Rootstore_Expecter) Delete(ctx interface{}, key interface{}) *Rootstore_Delete_Call { + return &Rootstore_Delete_Call{Call: _e.mock.On("Delete", ctx, key)} } -func (_c *RootStore_Delete_Call) Run(run func(ctx context.Context, key datastore.Key)) *RootStore_Delete_Call { +func (_c *Rootstore_Delete_Call) Run(run func(ctx context.Context, key datastore.Key)) *Rootstore_Delete_Call { _c.Call.Run(func(args mock.Arguments) { run(args[0].(context.Context), args[1].(datastore.Key)) }) return _c } -func (_c *RootStore_Delete_Call) Return(_a0 error) *RootStore_Delete_Call { +func (_c *Rootstore_Delete_Call) Return(_a0 error) *Rootstore_Delete_Call { _c.Call.Return(_a0) return _c } -func (_c *RootStore_Delete_Call) RunAndReturn(run func(context.Context, datastore.Key) error) *RootStore_Delete_Call { +func (_c *Rootstore_Delete_Call) RunAndReturn(run func(context.Context, datastore.Key) error) *Rootstore_Delete_Call { _c.Call.Return(run) return _c } // Get provides a mock function with given fields: ctx, key -func (_m *RootStore) Get(ctx context.Context, key datastore.Key) ([]byte, error) { +func (_m *Rootstore) Get(ctx context.Context, key datastore.Key) ([]byte, error) { ret := _m.Called(ctx, key) if len(ret) == 0 { @@ -205,37 +205,37 @@ func (_m *RootStore) Get(ctx context.Context, key datastore.Key) ([]byte, error) return r0, r1 } -// RootStore_Get_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Get' -type RootStore_Get_Call struct { +// Rootstore_Get_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Get' +type Rootstore_Get_Call struct { *mock.Call } // Get is a helper method to define mock.On call // - ctx context.Context // - key datastore.Key -func (_e *RootStore_Expecter) Get(ctx interface{}, key interface{}) *RootStore_Get_Call { - return &RootStore_Get_Call{Call: _e.mock.On("Get", ctx, key)} +func (_e *Rootstore_Expecter) Get(ctx interface{}, key interface{}) *Rootstore_Get_Call { + return &Rootstore_Get_Call{Call: _e.mock.On("Get", ctx, key)} } -func (_c *RootStore_Get_Call) Run(run func(ctx context.Context, key datastore.Key)) *RootStore_Get_Call { +func (_c *Rootstore_Get_Call) Run(run func(ctx context.Context, key datastore.Key)) *Rootstore_Get_Call { _c.Call.Run(func(args mock.Arguments) { run(args[0].(context.Context), args[1].(datastore.Key)) }) return _c } -func (_c *RootStore_Get_Call) Return(value []byte, err error) *RootStore_Get_Call { +func (_c *Rootstore_Get_Call) Return(value []byte, err error) *Rootstore_Get_Call { _c.Call.Return(value, err) return _c } -func (_c *RootStore_Get_Call) RunAndReturn(run func(context.Context, datastore.Key) ([]byte, error)) *RootStore_Get_Call { +func (_c *Rootstore_Get_Call) RunAndReturn(run func(context.Context, datastore.Key) ([]byte, error)) *Rootstore_Get_Call { _c.Call.Return(run) return _c } // GetSize provides a mock function with given fields: ctx, key -func (_m *RootStore) GetSize(ctx context.Context, key datastore.Key) (int, error) { +func (_m *Rootstore) GetSize(ctx context.Context, key datastore.Key) (int, error) { ret := _m.Called(ctx, key) if len(ret) == 0 { @@ -262,37 +262,37 @@ func (_m *RootStore) GetSize(ctx context.Context, key datastore.Key) (int, error return r0, r1 } -// RootStore_GetSize_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSize' -type RootStore_GetSize_Call struct { +// Rootstore_GetSize_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetSize' +type Rootstore_GetSize_Call struct { *mock.Call } // GetSize is a helper method to define mock.On call // - ctx context.Context // - key datastore.Key -func (_e *RootStore_Expecter) GetSize(ctx interface{}, key interface{}) *RootStore_GetSize_Call { - return &RootStore_GetSize_Call{Call: _e.mock.On("GetSize", ctx, key)} +func (_e *Rootstore_Expecter) GetSize(ctx interface{}, key interface{}) *Rootstore_GetSize_Call { + return &Rootstore_GetSize_Call{Call: _e.mock.On("GetSize", ctx, key)} } -func (_c *RootStore_GetSize_Call) Run(run func(ctx context.Context, key datastore.Key)) *RootStore_GetSize_Call { +func (_c *Rootstore_GetSize_Call) Run(run func(ctx context.Context, key datastore.Key)) *Rootstore_GetSize_Call { _c.Call.Run(func(args mock.Arguments) { run(args[0].(context.Context), args[1].(datastore.Key)) }) return _c } -func (_c *RootStore_GetSize_Call) Return(size int, err error) *RootStore_GetSize_Call { +func (_c *Rootstore_GetSize_Call) Return(size int, err error) *Rootstore_GetSize_Call { _c.Call.Return(size, err) return _c } -func (_c *RootStore_GetSize_Call) RunAndReturn(run func(context.Context, datastore.Key) (int, error)) *RootStore_GetSize_Call { +func (_c *Rootstore_GetSize_Call) RunAndReturn(run func(context.Context, datastore.Key) (int, error)) *Rootstore_GetSize_Call { _c.Call.Return(run) return _c } // Has provides a mock function with given fields: ctx, key -func (_m *RootStore) Has(ctx context.Context, key datastore.Key) (bool, error) { +func (_m *Rootstore) Has(ctx context.Context, key datastore.Key) (bool, error) { ret := _m.Called(ctx, key) if len(ret) == 0 { @@ -319,37 +319,37 @@ func (_m *RootStore) Has(ctx context.Context, key datastore.Key) (bool, error) { return r0, r1 } -// RootStore_Has_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Has' -type RootStore_Has_Call struct { +// Rootstore_Has_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Has' +type Rootstore_Has_Call struct { *mock.Call } // Has is a helper method to define mock.On call // - ctx context.Context // - key datastore.Key -func (_e *RootStore_Expecter) Has(ctx interface{}, key interface{}) *RootStore_Has_Call { - return &RootStore_Has_Call{Call: _e.mock.On("Has", ctx, key)} +func (_e *Rootstore_Expecter) Has(ctx interface{}, key interface{}) *Rootstore_Has_Call { + return &Rootstore_Has_Call{Call: _e.mock.On("Has", ctx, key)} } -func (_c *RootStore_Has_Call) Run(run func(ctx context.Context, key datastore.Key)) *RootStore_Has_Call { +func (_c *Rootstore_Has_Call) Run(run func(ctx context.Context, key datastore.Key)) *Rootstore_Has_Call { _c.Call.Run(func(args mock.Arguments) { run(args[0].(context.Context), args[1].(datastore.Key)) }) return _c } -func (_c *RootStore_Has_Call) Return(exists bool, err error) *RootStore_Has_Call { +func (_c *Rootstore_Has_Call) Return(exists bool, err error) *Rootstore_Has_Call { _c.Call.Return(exists, err) return _c } -func (_c *RootStore_Has_Call) RunAndReturn(run func(context.Context, datastore.Key) (bool, error)) *RootStore_Has_Call { +func (_c *Rootstore_Has_Call) RunAndReturn(run func(context.Context, datastore.Key) (bool, error)) *Rootstore_Has_Call { _c.Call.Return(run) return _c } // NewTransaction provides a mock function with given fields: ctx, readOnly -func (_m *RootStore) NewTransaction(ctx context.Context, readOnly bool) (datastore.Txn, error) { +func (_m *Rootstore) NewTransaction(ctx context.Context, readOnly bool) (datastore.Txn, error) { ret := _m.Called(ctx, readOnly) if len(ret) == 0 { @@ -378,37 +378,37 @@ func (_m *RootStore) NewTransaction(ctx context.Context, readOnly bool) (datasto return r0, r1 } -// RootStore_NewTransaction_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NewTransaction' -type RootStore_NewTransaction_Call struct { +// Rootstore_NewTransaction_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NewTransaction' +type Rootstore_NewTransaction_Call struct { *mock.Call } // NewTransaction is a helper method to define mock.On call // - ctx context.Context // - readOnly bool -func (_e *RootStore_Expecter) NewTransaction(ctx interface{}, readOnly interface{}) *RootStore_NewTransaction_Call { - return &RootStore_NewTransaction_Call{Call: _e.mock.On("NewTransaction", ctx, readOnly)} +func (_e *Rootstore_Expecter) NewTransaction(ctx interface{}, readOnly interface{}) *Rootstore_NewTransaction_Call { + return &Rootstore_NewTransaction_Call{Call: _e.mock.On("NewTransaction", ctx, readOnly)} } -func (_c *RootStore_NewTransaction_Call) Run(run func(ctx context.Context, readOnly bool)) *RootStore_NewTransaction_Call { +func (_c *Rootstore_NewTransaction_Call) Run(run func(ctx context.Context, readOnly bool)) *Rootstore_NewTransaction_Call { _c.Call.Run(func(args mock.Arguments) { run(args[0].(context.Context), args[1].(bool)) }) return _c } -func (_c *RootStore_NewTransaction_Call) Return(_a0 datastore.Txn, _a1 error) *RootStore_NewTransaction_Call { +func (_c *Rootstore_NewTransaction_Call) Return(_a0 datastore.Txn, _a1 error) *Rootstore_NewTransaction_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *RootStore_NewTransaction_Call) RunAndReturn(run func(context.Context, bool) (datastore.Txn, error)) *RootStore_NewTransaction_Call { +func (_c *Rootstore_NewTransaction_Call) RunAndReturn(run func(context.Context, bool) (datastore.Txn, error)) *Rootstore_NewTransaction_Call { _c.Call.Return(run) return _c } // Put provides a mock function with given fields: ctx, key, value -func (_m *RootStore) Put(ctx context.Context, key datastore.Key, value []byte) error { +func (_m *Rootstore) Put(ctx context.Context, key datastore.Key, value []byte) error { ret := _m.Called(ctx, key, value) if len(ret) == 0 { @@ -425,8 +425,8 @@ func (_m *RootStore) Put(ctx context.Context, key datastore.Key, value []byte) e return r0 } -// RootStore_Put_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Put' -type RootStore_Put_Call struct { +// Rootstore_Put_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Put' +type Rootstore_Put_Call struct { *mock.Call } @@ -434,29 +434,29 @@ type RootStore_Put_Call struct { // - ctx context.Context // - key datastore.Key // - value []byte -func (_e *RootStore_Expecter) Put(ctx interface{}, key interface{}, value interface{}) *RootStore_Put_Call { - return &RootStore_Put_Call{Call: _e.mock.On("Put", ctx, key, value)} +func (_e *Rootstore_Expecter) Put(ctx interface{}, key interface{}, value interface{}) *Rootstore_Put_Call { + return &Rootstore_Put_Call{Call: _e.mock.On("Put", ctx, key, value)} } -func (_c *RootStore_Put_Call) Run(run func(ctx context.Context, key datastore.Key, value []byte)) *RootStore_Put_Call { +func (_c *Rootstore_Put_Call) Run(run func(ctx context.Context, key datastore.Key, value []byte)) *Rootstore_Put_Call { _c.Call.Run(func(args mock.Arguments) { run(args[0].(context.Context), args[1].(datastore.Key), args[2].([]byte)) }) return _c } -func (_c *RootStore_Put_Call) Return(_a0 error) *RootStore_Put_Call { +func (_c *Rootstore_Put_Call) Return(_a0 error) *Rootstore_Put_Call { _c.Call.Return(_a0) return _c } -func (_c *RootStore_Put_Call) RunAndReturn(run func(context.Context, datastore.Key, []byte) error) *RootStore_Put_Call { +func (_c *Rootstore_Put_Call) RunAndReturn(run func(context.Context, datastore.Key, []byte) error) *Rootstore_Put_Call { _c.Call.Return(run) return _c } // Query provides a mock function with given fields: ctx, q -func (_m *RootStore) Query(ctx context.Context, q query.Query) (query.Results, error) { +func (_m *Rootstore) Query(ctx context.Context, q query.Query) (query.Results, error) { ret := _m.Called(ctx, q) if len(ret) == 0 { @@ -485,37 +485,37 @@ func (_m *RootStore) Query(ctx context.Context, q query.Query) (query.Results, e return r0, r1 } -// RootStore_Query_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Query' -type RootStore_Query_Call struct { +// Rootstore_Query_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Query' +type Rootstore_Query_Call struct { *mock.Call } // Query is a helper method to define mock.On call // - ctx context.Context // - q query.Query -func (_e *RootStore_Expecter) Query(ctx interface{}, q interface{}) *RootStore_Query_Call { - return &RootStore_Query_Call{Call: _e.mock.On("Query", ctx, q)} +func (_e *Rootstore_Expecter) Query(ctx interface{}, q interface{}) *Rootstore_Query_Call { + return &Rootstore_Query_Call{Call: _e.mock.On("Query", ctx, q)} } -func (_c *RootStore_Query_Call) Run(run func(ctx context.Context, q query.Query)) *RootStore_Query_Call { +func (_c *Rootstore_Query_Call) Run(run func(ctx context.Context, q query.Query)) *Rootstore_Query_Call { _c.Call.Run(func(args mock.Arguments) { run(args[0].(context.Context), args[1].(query.Query)) }) return _c } -func (_c *RootStore_Query_Call) Return(_a0 query.Results, _a1 error) *RootStore_Query_Call { +func (_c *Rootstore_Query_Call) Return(_a0 query.Results, _a1 error) *Rootstore_Query_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *RootStore_Query_Call) RunAndReturn(run func(context.Context, query.Query) (query.Results, error)) *RootStore_Query_Call { +func (_c *Rootstore_Query_Call) RunAndReturn(run func(context.Context, query.Query) (query.Results, error)) *Rootstore_Query_Call { _c.Call.Return(run) return _c } // Sync provides a mock function with given fields: ctx, prefix -func (_m *RootStore) Sync(ctx context.Context, prefix datastore.Key) error { +func (_m *Rootstore) Sync(ctx context.Context, prefix datastore.Key) error { ret := _m.Called(ctx, prefix) if len(ret) == 0 { @@ -532,42 +532,42 @@ func (_m *RootStore) Sync(ctx context.Context, prefix datastore.Key) error { return r0 } -// RootStore_Sync_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Sync' -type RootStore_Sync_Call struct { +// Rootstore_Sync_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Sync' +type Rootstore_Sync_Call struct { *mock.Call } // Sync is a helper method to define mock.On call // - ctx context.Context // - prefix datastore.Key -func (_e *RootStore_Expecter) Sync(ctx interface{}, prefix interface{}) *RootStore_Sync_Call { - return &RootStore_Sync_Call{Call: _e.mock.On("Sync", ctx, prefix)} +func (_e *Rootstore_Expecter) Sync(ctx interface{}, prefix interface{}) *Rootstore_Sync_Call { + return &Rootstore_Sync_Call{Call: _e.mock.On("Sync", ctx, prefix)} } -func (_c *RootStore_Sync_Call) Run(run func(ctx context.Context, prefix datastore.Key)) *RootStore_Sync_Call { +func (_c *Rootstore_Sync_Call) Run(run func(ctx context.Context, prefix datastore.Key)) *Rootstore_Sync_Call { _c.Call.Run(func(args mock.Arguments) { run(args[0].(context.Context), args[1].(datastore.Key)) }) return _c } -func (_c *RootStore_Sync_Call) Return(_a0 error) *RootStore_Sync_Call { +func (_c *Rootstore_Sync_Call) Return(_a0 error) *Rootstore_Sync_Call { _c.Call.Return(_a0) return _c } -func (_c *RootStore_Sync_Call) RunAndReturn(run func(context.Context, datastore.Key) error) *RootStore_Sync_Call { +func (_c *Rootstore_Sync_Call) RunAndReturn(run func(context.Context, datastore.Key) error) *Rootstore_Sync_Call { _c.Call.Return(run) return _c } -// NewRootStore creates a new instance of RootStore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// NewRootstore creates a new instance of Rootstore. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. -func NewRootStore(t interface { +func NewRootstore(t interface { mock.TestingT Cleanup(func()) -}) *RootStore { - mock := &RootStore{} +}) *Rootstore { + mock := &Rootstore{} mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) diff --git a/datastore/mocks/txn.go b/datastore/mocks/txn.go index 7c9872dfb2..f29c045dcd 100644 --- a/datastore/mocks/txn.go +++ b/datastore/mocks/txn.go @@ -22,95 +22,95 @@ func (_m *Txn) EXPECT() *Txn_Expecter { return &Txn_Expecter{mock: &_m.Mock} } -// Commit provides a mock function with given fields: ctx -func (_m *Txn) Commit(ctx context.Context) error { - ret := _m.Called(ctx) +// Blockstore provides a mock function with given fields: +func (_m *Txn) Blockstore() datastore.Blockstore { + ret := _m.Called() if len(ret) == 0 { - panic("no return value specified for Commit") + panic("no return value specified for Blockstore") } - var r0 error - if rf, ok := ret.Get(0).(func(context.Context) error); ok { - r0 = rf(ctx) + var r0 datastore.Blockstore + if rf, ok := ret.Get(0).(func() datastore.Blockstore); ok { + r0 = rf() } else { - r0 = ret.Error(0) + if ret.Get(0) != nil { + r0 = ret.Get(0).(datastore.Blockstore) + } } return r0 } -// Txn_Commit_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Commit' -type Txn_Commit_Call struct { +// Txn_Blockstore_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Blockstore' +type Txn_Blockstore_Call struct { *mock.Call } -// Commit is a helper method to define mock.On call -// - ctx context.Context -func (_e *Txn_Expecter) Commit(ctx interface{}) *Txn_Commit_Call { - return &Txn_Commit_Call{Call: _e.mock.On("Commit", ctx)} +// Blockstore is a helper method to define mock.On call +func (_e *Txn_Expecter) Blockstore() *Txn_Blockstore_Call { + return &Txn_Blockstore_Call{Call: _e.mock.On("Blockstore")} } -func (_c *Txn_Commit_Call) Run(run func(ctx context.Context)) *Txn_Commit_Call { +func (_c *Txn_Blockstore_Call) Run(run func()) *Txn_Blockstore_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context)) + run() }) return _c } -func (_c *Txn_Commit_Call) Return(_a0 error) *Txn_Commit_Call { +func (_c *Txn_Blockstore_Call) Return(_a0 datastore.Blockstore) *Txn_Blockstore_Call { _c.Call.Return(_a0) return _c } -func (_c *Txn_Commit_Call) RunAndReturn(run func(context.Context) error) *Txn_Commit_Call { +func (_c *Txn_Blockstore_Call) RunAndReturn(run func() datastore.Blockstore) *Txn_Blockstore_Call { _c.Call.Return(run) return _c } -// DAGstore provides a mock function with given fields: -func (_m *Txn) DAGstore() datastore.DAGStore { - ret := _m.Called() +// Commit provides a mock function with given fields: ctx +func (_m *Txn) Commit(ctx context.Context) error { + ret := _m.Called(ctx) if len(ret) == 0 { - panic("no return value specified for DAGstore") + panic("no return value specified for Commit") } - var r0 datastore.DAGStore - if rf, ok := ret.Get(0).(func() datastore.DAGStore); ok { - r0 = rf() + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(ctx) } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(datastore.DAGStore) - } + r0 = ret.Error(0) } return r0 } -// Txn_DAGstore_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DAGstore' -type Txn_DAGstore_Call struct { +// Txn_Commit_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Commit' +type Txn_Commit_Call struct { *mock.Call } -// DAGstore is a helper method to define mock.On call -func (_e *Txn_Expecter) DAGstore() *Txn_DAGstore_Call { - return &Txn_DAGstore_Call{Call: _e.mock.On("DAGstore")} +// Commit is a helper method to define mock.On call +// - ctx context.Context +func (_e *Txn_Expecter) Commit(ctx interface{}) *Txn_Commit_Call { + return &Txn_Commit_Call{Call: _e.mock.On("Commit", ctx)} } -func (_c *Txn_DAGstore_Call) Run(run func()) *Txn_DAGstore_Call { +func (_c *Txn_Commit_Call) Run(run func(ctx context.Context)) *Txn_Commit_Call { _c.Call.Run(func(args mock.Arguments) { - run() + run(args[0].(context.Context)) }) return _c } -func (_c *Txn_DAGstore_Call) Return(_a0 datastore.DAGStore) *Txn_DAGstore_Call { +func (_c *Txn_Commit_Call) Return(_a0 error) *Txn_Commit_Call { _c.Call.Return(_a0) return _c } -func (_c *Txn_DAGstore_Call) RunAndReturn(run func() datastore.DAGStore) *Txn_DAGstore_Call { +func (_c *Txn_Commit_Call) RunAndReturn(run func(context.Context) error) *Txn_Commit_Call { _c.Call.Return(run) return _c } diff --git a/datastore/mocks/utils.go b/datastore/mocks/utils.go index 50131a8538..af3c49fd0c 100644 --- a/datastore/mocks/utils.go +++ b/datastore/mocks/utils.go @@ -36,7 +36,7 @@ func prepareDataStore(t *testing.T) *DSReaderWriter { return dataStore } -func prepareRootStore(t *testing.T) *DSReaderWriter { +func prepareRootstore(t *testing.T) *DSReaderWriter { return NewDSReaderWriter(t) } @@ -73,7 +73,7 @@ func NewTxnWithMultistore(t *testing.T) *MultiStoreTxn { result := &MultiStoreTxn{ Txn: txn, t: t, - MockRootstore: prepareRootStore(t), + MockRootstore: prepareRootstore(t), MockDatastore: prepareDataStore(t), MockHeadstore: prepareHeadStore(t), MockDAGstore: prepareDAGStore(t), @@ -83,7 +83,7 @@ func NewTxnWithMultistore(t *testing.T) *MultiStoreTxn { txn.EXPECT().Rootstore().Return(result.MockRootstore).Maybe() txn.EXPECT().Datastore().Return(result.MockDatastore).Maybe() txn.EXPECT().Headstore().Return(result.MockHeadstore).Maybe() - txn.EXPECT().DAGstore().Return(result.MockDAGstore).Maybe() + txn.EXPECT().Blockstore().Return(result.MockDAGstore).Maybe() txn.EXPECT().Systemstore().Return(result.MockSystemstore).Maybe() return result diff --git a/datastore/multi.go b/datastore/multi.go index bbd333ba19..a70a24a60d 100644 --- a/datastore/multi.go +++ b/datastore/multi.go @@ -32,7 +32,7 @@ type multistore struct { peer DSBatching system DSReaderWriter // block DSReaderWriter - dag DAGStore + dag Blockstore } var _ MultiStore = (*multistore)(nil) @@ -67,8 +67,8 @@ func (ms multistore) Peerstore() DSBatching { return ms.peer } -// DAGstore implements MultiStore. -func (ms multistore) DAGstore() DAGStore { +// Blockstore implements MultiStore. +func (ms multistore) Blockstore() Blockstore { return ms.dag } diff --git a/datastore/store.go b/datastore/store.go index 7954eb5014..66501270d1 100644 --- a/datastore/store.go +++ b/datastore/store.go @@ -24,8 +24,8 @@ var ( log = corelog.NewLogger("store") ) -// RootStore wraps Batching and TxnDatastore requiring datastore to support both batching and transactions. -type RootStore interface { +// Rootstore wraps Batching and TxnDatastore requiring datastore to support both batching and transactions. +type Rootstore interface { ds.Batching ds.TxnDatastore } @@ -47,10 +47,10 @@ type MultiStore interface { // under the /peers namespace Peerstore() DSBatching - // DAGstore is a wrapped root DSReaderWriter - // as a Blockstore, embedded into a DAGStore + // Blockstore is a wrapped root DSReaderWriter + // as a Blockstore, embedded into a Blockstore // under the /blocks namespace - DAGstore() DAGStore + Blockstore() Blockstore // Headstore is a wrapped root DSReaderWriter // under the /system namespace @@ -70,8 +70,8 @@ type DSReaderWriter interface { iterable.Iterable } -// DAGStore proxies the ipld.DAGService under the /core namespace for future-proofing -type DAGStore interface { +// Blockstore proxies the ipld.DAGService under the /core namespace for future-proofing +type Blockstore interface { blockstore.Blockstore AsIPLDStorage() IPLDStorage } diff --git a/event/event.go b/event/event.go index e9afdf1a57..fa557cc03c 100644 --- a/event/event.go +++ b/event/event.go @@ -32,6 +32,16 @@ const ( PubSubName = Name("pubsub") // PeerName is the name of the network connect event. PeerName = Name("peer") + // P2PTopicName is the name of the network p2p topic update event. + P2PTopicName = Name("p2p-topic") + // PeerInfoName is the name of the network peer info event. + PeerInfoName = Name("peer-info") + // ReplicatorName is the name of the replicator event. + ReplicatorName = Name("replicator") + // P2PTopicCompletedName is the name of the network p2p topic update completed event. + P2PTopicCompletedName = Name("p2p-topic-completed") + // ReplicatorCompletedName is the name of the replicator completed event. + ReplicatorCompletedName = Name("replicator-completed") ) // Peer is an event that is published when @@ -110,3 +120,25 @@ type Subscription struct { func (s *Subscription) Message() <-chan Message { return s.value } + +// P2PTopic is an event that is published when a peer has updated the topics it is subscribed to. +type P2PTopic struct { + ToAdd []string + ToRemove []string +} + +// PeerInfo is an event that is published when the node has updated its peer info. +type PeerInfo struct { + Info peer.AddrInfo +} + +// Replicator is an event that is published when a replicator is added or updated. +type Replicator struct { + // The peer info for the replicator instance. + Info peer.AddrInfo + // The map of schema roots that the replicator will receive updates for. + Schemas map[string]struct{} + // Docs will receive Updates if new collections have been added to the replicator + // and those collections have documents to be replicated. + Docs <-chan Update +} diff --git a/go.mod b/go.mod index 6efc0e1590..350e183739 100644 --- a/go.mod +++ b/go.mod @@ -33,6 +33,7 @@ require ( github.com/libp2p/go-libp2p-kad-dht v0.25.2 github.com/libp2p/go-libp2p-pubsub v0.11.0 github.com/libp2p/go-libp2p-record v0.2.0 + github.com/mr-tron/base58 v1.2.0 github.com/multiformats/go-multiaddr v0.12.4 github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multicodec v0.9.0 @@ -191,7 +192,6 @@ require ( github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect diff --git a/http/client.go b/http/client.go index 2843ee4f2d..2082604599 100644 --- a/http/client.go +++ b/http/client.go @@ -435,11 +435,11 @@ func (c *Client) Close() { // do nothing } -func (c *Client) Root() datastore.RootStore { +func (c *Client) Rootstore() datastore.Rootstore { panic("client side database") } -func (c *Client) Blockstore() datastore.DAGStore { +func (c *Client) Blockstore() datastore.Blockstore { panic("client side database") } diff --git a/http/client_tx.go b/http/client_tx.go index 19e5814b51..a804b934f1 100644 --- a/http/client_tx.go +++ b/http/client_tx.go @@ -99,7 +99,7 @@ func (c *Transaction) Peerstore() datastore.DSBatching { panic("client side transaction") } -func (c *Transaction) DAGstore() datastore.DAGStore { +func (c *Transaction) Blockstore() datastore.Blockstore { panic("client side transaction") } diff --git a/internal/db/db.go b/internal/db/db.go index a6fb37f643..197ab493d5 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -55,7 +55,7 @@ const ( type db struct { glock sync.RWMutex - rootstore datastore.RootStore + rootstore datastore.Rootstore multistore datastore.MultiStore events *event.Bus @@ -75,12 +75,16 @@ type db struct { // Contains ACP if it exists acp immutable.Option[acp.ACP] + + // The peer ID and network address information for the current node + // if network is enabled. The `atomic.Value` should hold a `peer.AddrInfo` struct. + peerInfo atomic.Value } // NewDB creates a new instance of the DB using the given options. func NewDB( ctx context.Context, - rootstore datastore.RootStore, + rootstore datastore.Rootstore, acp immutable.Option[acp.ACP], lens client.LensRegistry, options ...Option, @@ -90,7 +94,7 @@ func NewDB( func newDB( ctx context.Context, - rootstore datastore.RootStore, + rootstore datastore.Rootstore, acp immutable.Option[acp.ACP], lens client.LensRegistry, options ...Option, @@ -126,11 +130,11 @@ func newDB( return nil, err } - sub, err := db.events.Subscribe(event.MergeName) + sub, err := db.events.Subscribe(event.MergeName, event.PeerInfoName) if err != nil { return nil, err } - go db.handleMerges(ctx, sub) + go db.handleMessages(ctx, sub) return db, nil } @@ -147,14 +151,14 @@ func (db *db) NewConcurrentTxn(ctx context.Context, readonly bool) (datastore.Tx return datastore.NewConcurrentTxnFrom(ctx, db.rootstore, txnId, readonly) } -// Root returns the root datastore. -func (db *db) Root() datastore.RootStore { +// Rootstore returns the root datastore. +func (db *db) Rootstore() datastore.Rootstore { return db.rootstore } // Blockstore returns the internal DAG store which contains IPLD blocks. -func (db *db) Blockstore() datastore.DAGStore { - return db.multistore.DAGstore() +func (db *db) Blockstore() datastore.Blockstore { + return db.multistore.Blockstore() } // Peerstore returns the internal DAG store which contains IPLD blocks. diff --git a/internal/db/errors.go b/internal/db/errors.go index 7a81824efe..603cee8130 100644 --- a/internal/db/errors.go +++ b/internal/db/errors.go @@ -11,6 +11,8 @@ package db import ( + "github.com/libp2p/go-libp2p/core/peer" + "github.com/sourcenetwork/defradb/client" "github.com/sourcenetwork/defradb/errors" ) @@ -94,6 +96,10 @@ const ( errSecondaryFieldOnSchema string = "secondary relation fields cannot be defined on the schema" errRelationMissingField string = "relation missing field" errNoTransactionInContext string = "no transaction in context" + errReplicatorExists string = "replicator already exists for %s with peerID %s" + errReplicatorDocID string = "failed to get docID for replicator" + errReplicatorCollections string = "failed to get collections for replicator" + errReplicatorNotFound string = "replicator not found" ) var ( @@ -127,7 +133,13 @@ var ( ErrSecondaryFieldOnSchema = errors.New(errSecondaryFieldOnSchema) ErrRelationMissingField = errors.New(errRelationMissingField) ErrMultipleRelationPrimaries = errors.New("relation can only have a single field set as primary") + ErrP2PColHasPolicy = errors.New("p2p collection specified has a policy on it") ErrNoTransactionInContext = errors.New(errNoTransactionInContext) + ErrReplicatorColHasPolicy = errors.New("replicator collection specified has a policy on it") + ErrReplicatorSomeColsHavePolicy = errors.New("replicator can not use all collections, as some have policy") + ErrSelfTargetForReplicator = errors.New("can't target ourselves as a replicator") + ErrReplicatorCollections = errors.New(errReplicatorCollections) + ErrReplicatorNotFound = errors.New(errReplicatorNotFound) ) // NewErrFailedToGetHeads returns a new error indicating that the heads of a document @@ -617,3 +629,19 @@ func NewErrRelationMissingField(objectName, relationName string) error { errors.NewKV("RelationName", relationName), ) } + +func NewErrReplicatorExists(collection string, peerID peer.ID) error { + return errors.New( + errReplicatorExists, + errors.NewKV("Collection", collection), + errors.NewKV("PeerID", peerID.String()), + ) +} + +func NewErrReplicatorDocID(inner error, kv ...errors.KV) error { + return errors.Wrap(errReplicatorDocID, inner, kv...) +} + +func NewErrReplicatorCollections(inner error, kv ...errors.KV) error { + return errors.Wrap(errReplicatorCollections, inner, kv...) +} diff --git a/internal/db/fetcher/versioned.go b/internal/db/fetcher/versioned.go index 6ce8f94ebc..892b84e329 100644 --- a/internal/db/fetcher/versioned.go +++ b/internal/db/fetcher/versioned.go @@ -86,7 +86,7 @@ type VersionedFetcher struct { ctx context.Context // Transient version store - root datastore.RootStore + root datastore.Rootstore store datastore.Txn dsKey core.DataStoreKey @@ -281,7 +281,7 @@ func (vf *VersionedFetcher) seekNext(c cid.Cid, topParent bool) error { // @body: We could possibly append the DocID to the CID either as a // child key, or an instance on the CID key. - hasLocalBlock, err := vf.store.DAGstore().Has(vf.ctx, c) + hasLocalBlock, err := vf.store.Blockstore().Has(vf.ctx, c) if err != nil { return NewErrVFetcherFailedToFindBlock(err) } @@ -290,13 +290,13 @@ func (vf *VersionedFetcher) seekNext(c cid.Cid, topParent bool) error { return nil } - blk, err := vf.txn.DAGstore().Get(vf.ctx, c) + blk, err := vf.txn.Blockstore().Get(vf.ctx, c) if err != nil { return NewErrVFetcherFailedToGetBlock(err) } // store the block in the local (transient store) - if err := vf.store.DAGstore().Put(vf.ctx, blk); err != nil { + if err := vf.store.Blockstore().Put(vf.ctx, blk); err != nil { return NewErrVFetcherFailedToWriteBlock(err) } @@ -336,7 +336,7 @@ func (vf *VersionedFetcher) seekNext(c cid.Cid, topParent bool) error { } // merge in the state of the IPLD Block identified by CID c into the VersionedFetcher state. -// Requires the CID to already exist in the DAGStore. +// Requires the CID to already exist in the Blockstore. // This function only works for merging Composite MerkleCRDT objects. // // First it checks for the existence of the block, @@ -421,7 +421,7 @@ func (vf *VersionedFetcher) processBlock( func (vf *VersionedFetcher) getDAGBlock(c cid.Cid) (*coreblock.Block, error) { // get Block - blk, err := vf.store.DAGstore().Get(vf.ctx, c) + blk, err := vf.store.Blockstore().Get(vf.ctx, c) if err != nil { return nil, NewErrFailedToGetDagNode(err) } diff --git a/internal/db/index_test.go b/internal/db/index_test.go index b7f4bbfb96..9226f92efd 100644 --- a/internal/db/index_test.go +++ b/internal/db/index_test.go @@ -473,11 +473,11 @@ func TestCreateIndex_IfFailsToCreateTxn_ReturnError(t *testing.T) { testErr := errors.New("test error") - mockedRootStore := mocks.NewRootStore(t) - mockedRootStore.On("Close").Return(nil) + mockedRootstore := mocks.NewRootstore(t) + mockedRootstore.On("Close").Return(nil) - mockedRootStore.EXPECT().NewTransaction(mock.Anything, mock.Anything).Return(nil, testErr) - f.db.rootstore = mockedRootStore + mockedRootstore.EXPECT().NewTransaction(mock.Anything, mock.Anything).Return(nil, testErr) + f.db.rootstore = mockedRootstore _, err := f.users.CreateIndex(f.ctx, getUsersIndexDescOnName()) require.ErrorIs(t, err, testErr) @@ -859,15 +859,15 @@ func TestCollectionGetIndexes_IfFailsToCreateTxn_ShouldNotCache(t *testing.T) { testErr := errors.New("test error") - workingRootStore := f.db.rootstore - mockedRootStore := mocks.NewRootStore(t) - f.db.rootstore = mockedRootStore - mockedRootStore.EXPECT().NewTransaction(mock.Anything, mock.Anything).Return(nil, testErr) + workingRootstore := f.db.rootstore + mockedRootstore := mocks.NewRootstore(t) + f.db.rootstore = mockedRootstore + mockedRootstore.EXPECT().NewTransaction(mock.Anything, mock.Anything).Return(nil, testErr) _, err := f.users.GetIndexes(f.ctx) require.ErrorIs(t, err, testErr) - f.db.rootstore = workingRootStore + f.db.rootstore = workingRootstore indexes, err := f.users.GetIndexes(f.ctx) require.NoError(t, err) @@ -1075,11 +1075,11 @@ func TestDropIndex_IfFailsToCreateTxn_ReturnError(t *testing.T) { testErr := errors.New("test error") - mockedRootStore := mocks.NewRootStore(t) - mockedRootStore.On("Close").Return(nil) + mockedRootstore := mocks.NewRootstore(t) + mockedRootstore.On("Close").Return(nil) - mockedRootStore.EXPECT().NewTransaction(mock.Anything, mock.Anything).Return(nil, testErr) - f.db.rootstore = mockedRootStore + mockedRootstore.EXPECT().NewTransaction(mock.Anything, mock.Anything).Return(nil, testErr) + f.db.rootstore = mockedRootstore err := f.users.DropIndex(f.ctx, testUsersColIndexName) require.ErrorIs(t, err, testErr) diff --git a/internal/db/merge.go b/internal/db/merge.go index e7d4c8252c..bbfedd98d8 100644 --- a/internal/db/merge.go +++ b/internal/db/merge.go @@ -19,12 +19,10 @@ import ( "github.com/ipld/go-ipld-prime/linking" cidlink "github.com/ipld/go-ipld-prime/linking/cid" - "github.com/sourcenetwork/corelog" "github.com/sourcenetwork/immutable" "github.com/sourcenetwork/defradb/client" "github.com/sourcenetwork/defradb/datastore" - "github.com/sourcenetwork/defradb/datastore/badger/v4" "github.com/sourcenetwork/defradb/errors" "github.com/sourcenetwork/defradb/event" "github.com/sourcenetwork/defradb/internal/core" @@ -34,50 +32,6 @@ import ( merklecrdt "github.com/sourcenetwork/defradb/internal/merkle/crdt" ) -func (db *db) handleMerges(ctx context.Context, sub *event.Subscription) { - queue := newMergeQueue() - for { - select { - case <-ctx.Done(): - return - case msg, ok := <-sub.Message(): - if !ok { - return - } - merge, ok := msg.Data.(event.Merge) - if !ok { - continue - } - go func() { - // ensure only one merge per docID - queue.add(merge.DocID) - defer queue.done(merge.DocID) - - // retry the merge process if a conflict occurs - // - // conficts occur when a user updates a document - // while a merge is in progress. - var err error - for i := 0; i < db.MaxTxnRetries(); i++ { - err = db.executeMerge(ctx, merge) - if errors.Is(err, badger.ErrTxnConflict) { - continue // retry merge - } - break // merge success or error - } - - if err != nil { - log.ErrorContextE( - ctx, - "Failed to execute merge", - err, - corelog.Any("Event", merge)) - } - }() - } - } -} - func (db *db) executeMerge(ctx context.Context, dagMerge event.Merge) error { ctx, txn, err := ensureContextTxn(ctx, db, false) if err != nil { @@ -91,7 +45,7 @@ func (db *db) executeMerge(ctx context.Context, dagMerge event.Merge) error { } ls := cidlink.DefaultLinkSystem() - ls.SetReadStorage(txn.DAGstore().AsIPLDStorage()) + ls.SetReadStorage(txn.Blockstore().AsIPLDStorage()) docID, err := client.NewDocIDFromString(dagMerge.DocID) if err != nil { @@ -409,7 +363,7 @@ func getHeadsAsMergeTarget(ctx context.Context, txn datastore.Txn, dsKey core.Da mt := newMergeTarget() for _, cid := range cids { - b, err := txn.DAGstore().Get(ctx, cid) + b, err := txn.Blockstore().Get(ctx, cid) if err != nil { return mergeTarget{}, err } diff --git a/internal/db/merge_test.go b/internal/db/merge_test.go index f620003bbe..a78fd59983 100644 --- a/internal/db/merge_test.go +++ b/internal/db/merge_test.go @@ -48,7 +48,7 @@ func TestMerge_SingleBranch_NoError(t *testing.T) { require.NoError(t, err) lsys := cidlink.DefaultLinkSystem() - lsys.SetWriteStorage(db.multistore.DAGstore().AsIPLDStorage()) + lsys.SetWriteStorage(db.multistore.Blockstore().AsIPLDStorage()) initialDocState := map[string]any{ "name": "John", @@ -93,7 +93,7 @@ func TestMerge_DualBranch_NoError(t *testing.T) { require.NoError(t, err) lsys := cidlink.DefaultLinkSystem() - lsys.SetWriteStorage(db.multistore.DAGstore().AsIPLDStorage()) + lsys.SetWriteStorage(db.multistore.Blockstore().AsIPLDStorage()) initialDocState := map[string]any{ "name": "John", @@ -151,7 +151,7 @@ func TestMerge_DualBranchWithOneIncomplete_CouldNotFindCID(t *testing.T) { require.NoError(t, err) lsys := cidlink.DefaultLinkSystem() - lsys.SetWriteStorage(db.multistore.DAGstore().AsIPLDStorage()) + lsys.SetWriteStorage(db.multistore.Blockstore().AsIPLDStorage()) initialDocState := map[string]any{ "name": "John", diff --git a/internal/db/messages.go b/internal/db/messages.go new file mode 100644 index 0000000000..1967c0e238 --- /dev/null +++ b/internal/db/messages.go @@ -0,0 +1,84 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package db + +import ( + "context" + "sync" + + "github.com/sourcenetwork/corelog" + + "github.com/sourcenetwork/defradb/datastore/badger/v4" + "github.com/sourcenetwork/defradb/errors" + "github.com/sourcenetwork/defradb/event" +) + +func (db *db) handleMessages(ctx context.Context, sub *event.Subscription) { + queue := newMergeQueue() + // This is used to ensure we only trigger loadAndPublishP2PCollections and loadAndPublishReplicators + // once per db instanciation. + loadOnce := sync.Once{} + for { + select { + case <-ctx.Done(): + return + case msg, ok := <-sub.Message(): + if !ok { + return + } + switch evt := msg.Data.(type) { + case event.Merge: + go func() { + // ensure only one merge per docID + queue.add(evt.DocID) + defer queue.done(evt.DocID) + + // retry the merge process if a conflict occurs + // + // conficts occur when a user updates a document + // while a merge is in progress. + var err error + for i := 0; i < db.MaxTxnRetries(); i++ { + err = db.executeMerge(ctx, evt) + if errors.Is(err, badger.ErrTxnConflict) { + continue // retry merge + } + break // merge success or error + } + + if err != nil { + log.ErrorContextE( + ctx, + "Failed to execute merge", + err, + corelog.Any("Event", evt)) + } + }() + case event.PeerInfo: + db.peerInfo.Store(evt.Info) + // Load and publish P2P collections and replicators once per db instance start. + // A Go routine is used to ensure the message handler is not blocked by these potentially + // long running operations. + go loadOnce.Do(func() { + err := db.loadAndPublishP2PCollections(ctx) + if err != nil { + log.ErrorContextE(ctx, "Failed to load P2P collections", err) + } + + err = db.loadAndPublishReplicators(ctx) + if err != nil { + log.ErrorContextE(ctx, "Failed to load replicators", err) + } + }) + } + } + } +} diff --git a/internal/db/p2p_replicator.go b/internal/db/p2p_replicator.go new file mode 100644 index 0000000000..9f2fd84215 --- /dev/null +++ b/internal/db/p2p_replicator.go @@ -0,0 +1,346 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package db + +import ( + "context" + "encoding/json" + + dsq "github.com/ipfs/go-datastore/query" + "github.com/libp2p/go-libp2p/core/peer" + + "github.com/sourcenetwork/corelog" + + "github.com/sourcenetwork/defradb/client" + "github.com/sourcenetwork/defradb/errors" + "github.com/sourcenetwork/defradb/event" + "github.com/sourcenetwork/defradb/internal/core" + "github.com/sourcenetwork/defradb/internal/merkle/clock" +) + +func (db *db) SetReplicator(ctx context.Context, rep client.Replicator) error { + txn, err := db.NewTxn(ctx, false) + if err != nil { + return err + } + defer txn.Discard(ctx) + + if err := rep.Info.ID.Validate(); err != nil { + return err + } + + peerInfo := peer.AddrInfo{} + if info := db.peerInfo.Load(); info != nil { + peerInfo = info.(peer.AddrInfo) + } + if rep.Info.ID == peerInfo.ID { + return ErrSelfTargetForReplicator + } + + // TODO-ACP: Support ACP <> P2P - https://github.com/sourcenetwork/defradb/issues/2366 + // ctx = db.SetContextIdentity(ctx, identity) + ctx = SetContextTxn(ctx, txn) + + storedRep := client.Replicator{} + storedSchemas := make(map[string]struct{}) + repKey := core.NewReplicatorKey(rep.Info.ID.String()) + hasOldRep, err := txn.Systemstore().Has(ctx, repKey.ToDS()) + if err != nil { + return err + } + if hasOldRep { + repBytes, err := txn.Systemstore().Get(ctx, repKey.ToDS()) + if err != nil { + return err + } + err = json.Unmarshal(repBytes, &storedRep) + if err != nil { + return err + } + for _, schema := range storedRep.Schemas { + storedSchemas[schema] = struct{}{} + } + } else { + storedRep.Info = rep.Info + } + + var collections []client.Collection + switch { + case len(rep.Schemas) > 0: + // if specific collections are chosen get them by name + for _, name := range rep.Schemas { + col, err := db.GetCollectionByName(ctx, name) + if err != nil { + return NewErrReplicatorCollections(err) + } + + if col.Description().Policy.HasValue() { + return ErrReplicatorColHasPolicy + } + + collections = append(collections, col) + } + + default: + // default to all collections (unless a collection contains a policy). + // TODO-ACP: default to all collections after resolving https://github.com/sourcenetwork/defradb/issues/2366 + allCollections, err := db.GetCollections(ctx, client.CollectionFetchOptions{}) + if err != nil { + return NewErrReplicatorCollections(err) + } + + for _, col := range allCollections { + // Can not default to all collections if any collection has a policy. + // TODO-ACP: remove this check/loop after https://github.com/sourcenetwork/defradb/issues/2366 + if col.Description().Policy.HasValue() { + return ErrReplicatorSomeColsHavePolicy + } + } + collections = allCollections + } + + addedCols := []client.Collection{} + for _, col := range collections { + if _, ok := storedSchemas[col.SchemaRoot()]; !ok { + storedSchemas[col.SchemaRoot()] = struct{}{} + addedCols = append(addedCols, col) + storedRep.Schemas = append(storedRep.Schemas, col.SchemaRoot()) + } + } + + // persist replicator to the datastore + newRepBytes, err := json.Marshal(storedRep) + if err != nil { + return err + } + + err = txn.Systemstore().Put(ctx, repKey.ToDS(), newRepBytes) + if err != nil { + return err + } + + txn.OnSuccess(func() { + db.events.Publish(event.NewMessage(event.ReplicatorName, event.Replicator{ + Info: rep.Info, + Schemas: storedSchemas, + Docs: db.getDocsHeads(context.Background(), addedCols), + })) + }) + + return txn.Commit(ctx) +} + +func (db *db) getDocsHeads( + ctx context.Context, + cols []client.Collection, +) <-chan event.Update { + updateChan := make(chan event.Update) + go func() { + defer close(updateChan) + txn, err := db.NewTxn(ctx, true) + if err != nil { + log.ErrorContextE(ctx, "Failed to get transaction", err) + return + } + defer txn.Discard(ctx) + ctx = SetContextTxn(ctx, txn) + for _, col := range cols { + keysCh, err := col.GetAllDocIDs(ctx) + if err != nil { + log.ErrorContextE( + ctx, + "Failed to get all docIDs", + NewErrReplicatorDocID(err, errors.NewKV("Collection", col.Name().Value())), + ) + continue + } + for docIDResult := range keysCh { + if docIDResult.Err != nil { + log.ErrorContextE(ctx, "Key channel error", docIDResult.Err) + continue + } + docID := core.DataStoreKeyFromDocID(docIDResult.ID) + headset := clock.NewHeadSet( + txn.Headstore(), + docID.WithFieldId(core.COMPOSITE_NAMESPACE).ToHeadStoreKey(), + ) + cids, _, err := headset.List(ctx) + if err != nil { + log.ErrorContextE( + ctx, + "Failed to get heads", + err, + corelog.String("DocID", docIDResult.ID.String()), + corelog.Any("Collection", col.Name())) + continue + } + // loop over heads, get block, make the required logs, and send + for _, c := range cids { + blk, err := txn.Blockstore().Get(ctx, c) + if err != nil { + log.ErrorContextE(ctx, "Failed to get block", err, + corelog.Any("CID", c), + corelog.Any("Collection", col.Name())) + continue + } + + updateChan <- event.Update{ + DocID: docIDResult.ID.String(), + Cid: c, + SchemaRoot: col.SchemaRoot(), + Block: blk.RawData(), + } + } + } + } + }() + + return updateChan +} + +func (db *db) DeleteReplicator(ctx context.Context, rep client.Replicator) error { + txn, err := db.NewTxn(ctx, false) + if err != nil { + return err + } + defer txn.Discard(ctx) + + if err := rep.Info.ID.Validate(); err != nil { + return err + } + + // set transaction for all operations + ctx = SetContextTxn(ctx, txn) + + storedRep := client.Replicator{} + storedSchemas := make(map[string]struct{}) + repKey := core.NewReplicatorKey(rep.Info.ID.String()) + hasOldRep, err := txn.Systemstore().Has(ctx, repKey.ToDS()) + if err != nil { + return err + } + if !hasOldRep { + return ErrReplicatorNotFound + } + repBytes, err := txn.Systemstore().Get(ctx, repKey.ToDS()) + if err != nil { + return err + } + err = json.Unmarshal(repBytes, &storedRep) + if err != nil { + return err + } + for _, schema := range storedRep.Schemas { + storedSchemas[schema] = struct{}{} + } + + var collections []client.Collection + if len(rep.Schemas) > 0 { + // if specific collections are chosen get them by name + for _, name := range rep.Schemas { + col, err := db.GetCollectionByName(ctx, name) + if err != nil { + return NewErrReplicatorCollections(err) + } + collections = append(collections, col) + } + // make sure the replicator exists in the datastore + key := core.NewReplicatorKey(rep.Info.ID.String()) + _, err = txn.Systemstore().Get(ctx, key.ToDS()) + if err != nil { + return err + } + } else { + storedSchemas = make(map[string]struct{}) + } + + for _, col := range collections { + delete(storedSchemas, col.SchemaRoot()) + } + // Update the list of schemas for this replicator prior to persisting. + storedRep.Schemas = []string{} + for schema := range storedSchemas { + storedRep.Schemas = append(storedRep.Schemas, schema) + } + + // Persist the replicator to the store, deleting it if no schemas remain + key := core.NewReplicatorKey(rep.Info.ID.String()) + if len(rep.Schemas) == 0 { + err := txn.Systemstore().Delete(ctx, key.ToDS()) + if err != nil { + return err + } + } else { + repBytes, err := json.Marshal(rep) + if err != nil { + return err + } + err = txn.Systemstore().Put(ctx, key.ToDS(), repBytes) + if err != nil { + return err + } + } + + txn.OnSuccess(func() { + db.events.Publish(event.NewMessage(event.ReplicatorName, event.Replicator{ + Info: rep.Info, + Schemas: storedSchemas, + })) + }) + + return txn.Commit(ctx) +} + +func (db *db) GetAllReplicators(ctx context.Context) ([]client.Replicator, error) { + txn, err := db.NewTxn(ctx, true) + if err != nil { + return nil, err + } + defer txn.Discard(ctx) + + // create collection system prefix query + query := dsq.Query{ + Prefix: core.NewReplicatorKey("").ToString(), + } + results, err := txn.Systemstore().Query(ctx, query) + if err != nil { + return nil, err + } + + var reps []client.Replicator + for result := range results.Next() { + var rep client.Replicator + if err = json.Unmarshal(result.Value, &rep); err != nil { + return nil, err + } + reps = append(reps, rep) + } + return reps, nil +} + +func (db *db) loadAndPublishReplicators(ctx context.Context) error { + replicators, err := db.GetAllReplicators(ctx) + if err != nil { + return err + } + + for _, rep := range replicators { + schemaMap := make(map[string]struct{}) + for _, schema := range rep.Schemas { + schemaMap[schema] = struct{}{} + } + db.events.Publish(event.NewMessage(event.ReplicatorName, event.Replicator{ + Info: rep.Info, + Schemas: schemaMap, + })) + } + return nil +} diff --git a/internal/db/p2p_replicator_test.go b/internal/db/p2p_replicator_test.go new file mode 100644 index 0000000000..b287101a54 --- /dev/null +++ b/internal/db/p2p_replicator_test.go @@ -0,0 +1,320 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package db + +import ( + "context" + "testing" + "time" + + "github.com/libp2p/go-libp2p/core/peer" + b58 "github.com/mr-tron/base58/base58" + "github.com/stretchr/testify/require" + + "github.com/sourcenetwork/defradb/client" + "github.com/sourcenetwork/defradb/event" +) + +func waitForPeerInfo(db *db, sub *event.Subscription) { + for msg := range sub.Message() { + if msg.Name == event.PeerInfoName { + hasPeerInfo := false + if db.peerInfo.Load() != nil { + hasPeerInfo = true + } + if !hasPeerInfo { + time.Sleep(1 * time.Millisecond) + } + break + } + } +} + +func TestSetReplicator_WithEmptyPeerInfo_ShouldError(t *testing.T) { + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + err = db.SetReplicator(ctx, client.Replicator{}) + require.ErrorContains(t, err, "empty peer ID") +} + +func TestSetReplicator_WithSelfTarget_ShouldError(t *testing.T) { + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + sub, err := db.events.Subscribe(event.PeerInfoName) + require.NoError(t, err) + db.events.Publish(event.NewMessage(event.PeerInfoName, event.PeerInfo{Info: peer.AddrInfo{ID: "self"}})) + waitForPeerInfo(db, sub) + err = db.SetReplicator(ctx, client.Replicator{Info: peer.AddrInfo{ID: "self"}}) + require.ErrorIs(t, err, ErrSelfTargetForReplicator) +} + +func TestSetReplicator_WithInvalidCollection_ShouldError(t *testing.T) { + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + sub, err := db.events.Subscribe(event.PeerInfoName) + require.NoError(t, err) + db.events.Publish(event.NewMessage(event.PeerInfoName, event.PeerInfo{Info: peer.AddrInfo{ID: "self"}})) + waitForPeerInfo(db, sub) + err = db.SetReplicator(ctx, client.Replicator{ + Info: peer.AddrInfo{ID: "other"}, + Schemas: []string{"invalidCollection"}, + }) + require.ErrorIs(t, err, ErrReplicatorCollections) +} + +func TestSetReplicator_WithValidCollection_ShouldSucceed(t *testing.T) { + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + sub, err := db.events.Subscribe(event.ReplicatorName) + require.NoError(t, err) + cols, err := db.AddSchema(ctx, `type User { name: String }`) + require.NoError(t, err) + schema, err := db.GetSchemaByVersionID(ctx, cols[0].SchemaVersionID) + require.NoError(t, err) + err = db.SetReplicator(ctx, client.Replicator{ + Info: peer.AddrInfo{ID: "other"}, + Schemas: []string{"User"}, + }) + require.NoError(t, err) + msg := <-sub.Message() + replicator := msg.Data.(event.Replicator) + require.Equal(t, peer.ID("other"), replicator.Info.ID) + require.Equal(t, map[string]struct{}{schema.Root: {}}, replicator.Schemas) +} + +func TestSetReplicator_WithValidCollectionsOnSeparateSet_ShouldSucceed(t *testing.T) { + b, err := b58.Decode("12D3KooWB8Na2fKhdGtej5GjoVhmBBYFvqXiqFCSkR7fJFWHUbNr") + require.NoError(t, err) + peerID, err := peer.IDFromBytes(b) + require.NoError(t, err) + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + sub, err := db.events.Subscribe(event.ReplicatorName) + require.NoError(t, err) + cols1, err := db.AddSchema(ctx, `type User { name: String }`) + require.NoError(t, err) + schema1, err := db.GetSchemaByVersionID(ctx, cols1[0].SchemaVersionID) + require.NoError(t, err) + err = db.SetReplicator(ctx, client.Replicator{ + Info: peer.AddrInfo{ID: peerID}, + Schemas: []string{"User"}, + }) + require.NoError(t, err) + msg := <-sub.Message() + replicator := msg.Data.(event.Replicator) + require.Equal(t, peerID, replicator.Info.ID) + require.Equal(t, map[string]struct{}{schema1.Root: {}}, replicator.Schemas) + + cols2, err := db.AddSchema(ctx, `type Book { name: String }`) + require.NoError(t, err) + schema2, err := db.GetSchemaByVersionID(ctx, cols2[0].SchemaVersionID) + require.NoError(t, err) + err = db.SetReplicator(ctx, client.Replicator{ + Info: peer.AddrInfo{ID: peerID}, + Schemas: []string{"Book"}, + }) + require.NoError(t, err) + msg = <-sub.Message() + replicator = msg.Data.(event.Replicator) + require.Equal(t, peerID, replicator.Info.ID) + require.Equal(t, map[string]struct{}{schema1.Root: {}, schema2.Root: {}}, replicator.Schemas) +} + +func TestSetReplicator_WithValidCollectionWithDoc_ShouldSucceed(t *testing.T) { + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + sub, err := db.events.Subscribe(event.ReplicatorName) + require.NoError(t, err) + cols, err := db.AddSchema(ctx, `type User { name: String }`) + require.NoError(t, err) + col, err := db.GetCollectionByName(ctx, cols[0].Name.Value()) + require.NoError(t, err) + doc, err := client.NewDocFromMap(map[string]any{"name": "Alice"}, col.Definition()) + require.NoError(t, err) + err = col.Create(ctx, doc) + require.NoError(t, err) + + err = db.SetReplicator(ctx, client.Replicator{ + Info: peer.AddrInfo{ID: "other"}, + Schemas: []string{"User"}, + }) + require.NoError(t, err) + msg := <-sub.Message() + replicator := msg.Data.(event.Replicator) + require.Equal(t, peer.ID("other"), replicator.Info.ID) + require.Equal(t, map[string]struct{}{col.SchemaRoot(): {}}, replicator.Schemas) + for docEvt := range replicator.Docs { + require.Equal(t, doc.ID().String(), docEvt.DocID) + } +} + +func TestDeleteReplicator_WithEmptyPeerInfo_ShouldError(t *testing.T) { + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + err = db.DeleteReplicator(ctx, client.Replicator{}) + require.ErrorContains(t, err, "empty peer ID") +} + +func TestDeleteReplicator_WithNonExistantReplicator_ShouldError(t *testing.T) { + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + err = db.DeleteReplicator(ctx, client.Replicator{Info: peer.AddrInfo{ID: "other"}}) + require.ErrorIs(t, err, ErrReplicatorNotFound) +} + +func TestDeleteReplicator_WithValidCollection_ShouldSucceed(t *testing.T) { + b, err := b58.Decode("12D3KooWB8Na2fKhdGtej5GjoVhmBBYFvqXiqFCSkR7fJFWHUbNr") + require.NoError(t, err) + peerID, err := peer.IDFromBytes(b) + require.NoError(t, err) + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + sub, err := db.events.Subscribe(event.ReplicatorName) + require.NoError(t, err) + cols, err := db.AddSchema(ctx, `type User { name: String }`) + require.NoError(t, err) + schema, err := db.GetSchemaByVersionID(ctx, cols[0].SchemaVersionID) + require.NoError(t, err) + err = db.SetReplicator(ctx, client.Replicator{ + Info: peer.AddrInfo{ID: peerID}, + Schemas: []string{"User"}, + }) + require.NoError(t, err) + msg := <-sub.Message() + replicator := msg.Data.(event.Replicator) + require.Equal(t, peerID, replicator.Info.ID) + require.Equal(t, map[string]struct{}{schema.Root: {}}, replicator.Schemas) + err = db.DeleteReplicator(ctx, client.Replicator{Info: peer.AddrInfo{ID: peerID}}) + require.NoError(t, err) + msg = <-sub.Message() + replicator = msg.Data.(event.Replicator) + require.Equal(t, peerID, replicator.Info.ID) + require.Equal(t, map[string]struct{}{}, replicator.Schemas) +} + +func TestDeleteReplicator_PartialWithValidCollections_ShouldSucceed(t *testing.T) { + b, err := b58.Decode("12D3KooWB8Na2fKhdGtej5GjoVhmBBYFvqXiqFCSkR7fJFWHUbNr") + require.NoError(t, err) + peerID, err := peer.IDFromBytes(b) + require.NoError(t, err) + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + sub, err := db.events.Subscribe(event.ReplicatorName) + require.NoError(t, err) + cols1, err := db.AddSchema(ctx, `type User { name: String }`) + require.NoError(t, err) + schema1, err := db.GetSchemaByVersionID(ctx, cols1[0].SchemaVersionID) + require.NoError(t, err) + cols2, err := db.AddSchema(ctx, `type Book { name: String }`) + require.NoError(t, err) + schema2, err := db.GetSchemaByVersionID(ctx, cols2[0].SchemaVersionID) + require.NoError(t, err) + err = db.SetReplicator(ctx, client.Replicator{ + Info: peer.AddrInfo{ID: peerID}, + Schemas: []string{"User", "Book"}, + }) + require.NoError(t, err) + msg := <-sub.Message() + replicator := msg.Data.(event.Replicator) + require.Equal(t, peerID, replicator.Info.ID) + require.Equal(t, map[string]struct{}{schema1.Root: {}, schema2.Root: {}}, replicator.Schemas) + + err = db.DeleteReplicator(ctx, client.Replicator{Info: peer.AddrInfo{ID: peerID}, Schemas: []string{"User"}}) + require.NoError(t, err) + msg = <-sub.Message() + replicator = msg.Data.(event.Replicator) + require.Equal(t, peerID, replicator.Info.ID) + require.Equal(t, map[string]struct{}{schema2.Root: {}}, replicator.Schemas) +} + +func TestGetAllReplicators_WithValidCollection_ShouldSucceed(t *testing.T) { + b, err := b58.Decode("12D3KooWB8Na2fKhdGtej5GjoVhmBBYFvqXiqFCSkR7fJFWHUbNr") + require.NoError(t, err) + peerID, err := peer.IDFromBytes(b) + require.NoError(t, err) + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + sub, err := db.events.Subscribe(event.ReplicatorName) + require.NoError(t, err) + cols, err := db.AddSchema(ctx, `type User { name: String }`) + require.NoError(t, err) + schema, err := db.GetSchemaByVersionID(ctx, cols[0].SchemaVersionID) + require.NoError(t, err) + err = db.SetReplicator(ctx, client.Replicator{ + Info: peer.AddrInfo{ID: peerID}, + Schemas: []string{"User"}, + }) + require.NoError(t, err) + msg := <-sub.Message() + replicator := msg.Data.(event.Replicator) + require.Equal(t, peerID, replicator.Info.ID) + require.Equal(t, map[string]struct{}{schema.Root: {}}, replicator.Schemas) + + reps, err := db.GetAllReplicators(ctx) + require.NoError(t, err) + require.Equal(t, peerID, reps[0].Info.ID) + require.Equal(t, []string{schema.Root}, reps[0].Schemas) +} + +func TestLoadReplicators_WithValidCollection_ShouldSucceed(t *testing.T) { + b, err := b58.Decode("12D3KooWB8Na2fKhdGtej5GjoVhmBBYFvqXiqFCSkR7fJFWHUbNr") + require.NoError(t, err) + peerID, err := peer.IDFromBytes(b) + require.NoError(t, err) + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + sub, err := db.events.Subscribe(event.ReplicatorName) + require.NoError(t, err) + cols, err := db.AddSchema(ctx, `type User { name: String }`) + require.NoError(t, err) + schema, err := db.GetSchemaByVersionID(ctx, cols[0].SchemaVersionID) + require.NoError(t, err) + err = db.SetReplicator(ctx, client.Replicator{ + Info: peer.AddrInfo{ID: peerID}, + Schemas: []string{"User"}, + }) + require.NoError(t, err) + msg := <-sub.Message() + replicator := msg.Data.(event.Replicator) + require.Equal(t, peerID, replicator.Info.ID) + require.Equal(t, map[string]struct{}{schema.Root: {}}, replicator.Schemas) + + err = db.loadAndPublishReplicators(ctx) + require.NoError(t, err) + msg = <-sub.Message() + replicator = msg.Data.(event.Replicator) + require.Equal(t, peerID, replicator.Info.ID) + require.Equal(t, map[string]struct{}{schema.Root: {}}, replicator.Schemas) +} diff --git a/net/peer_collection.go b/internal/db/p2p_schema_root.go similarity index 59% rename from net/peer_collection.go rename to internal/db/p2p_schema_root.go index 1676a7be43..b16af0ff4e 100644 --- a/net/peer_collection.go +++ b/internal/db/p2p_schema_root.go @@ -1,4 +1,4 @@ -// Copyright 2023 Democratized Data Foundation +// Copyright 2024 Democratized Data Foundation // // Use of this software is governed by the Business Source License // included in the file licenses/BSL.txt. @@ -8,23 +8,24 @@ // by the Apache License, Version 2.0, included in the file // licenses/APL.txt. -package net +package db import ( "context" dsq "github.com/ipfs/go-datastore/query" + "github.com/libp2p/go-libp2p/core/peer" "github.com/sourcenetwork/immutable" "github.com/sourcenetwork/defradb/client" + "github.com/sourcenetwork/defradb/event" "github.com/sourcenetwork/defradb/internal/core" - "github.com/sourcenetwork/defradb/internal/db" ) const marker = byte(0xff) -func (p *Peer) AddP2PCollections(ctx context.Context, collectionIDs []string) error { - txn, err := p.db.NewTxn(ctx, false) +func (db *db) AddP2PCollections(ctx context.Context, collectionIDs []string) error { + txn, err := db.NewTxn(ctx, false) if err != nil { return err } @@ -32,12 +33,12 @@ func (p *Peer) AddP2PCollections(ctx context.Context, collectionIDs []string) er // TODO-ACP: Support ACP <> P2P - https://github.com/sourcenetwork/defradb/issues/2366 // ctx = db.SetContextIdentity(ctx, identity) - ctx = db.SetContextTxn(ctx, txn) + ctx = SetContextTxn(ctx, txn) // first let's make sure the collections actually exists storeCollections := []client.Collection{} for _, col := range collectionIDs { - storeCol, err := p.db.GetCollections( + storeCol, err := db.GetCollections( ctx, client.CollectionFetchOptions{ SchemaRoot: immutable.Some(col), @@ -60,6 +61,8 @@ func (p *Peer) AddP2PCollections(ctx context.Context, collectionIDs []string) er } } + evt := event.P2PTopic{} + // Ensure we can add all the collections to the store on the transaction // before adding to topics. for _, col := range storeCollections { @@ -68,45 +71,28 @@ func (p *Peer) AddP2PCollections(ctx context.Context, collectionIDs []string) er if err != nil { return err } + evt.ToAdd = append(evt.ToAdd, col.SchemaRoot()) } - // Add pubsub topics and remove them if we get an error. - addedTopics := []string{} - for _, col := range collectionIDs { - err = p.server.addPubSubTopic(col, true) - if err != nil { - return p.rollbackAddPubSubTopics(addedTopics, err) - } - addedTopics = append(addedTopics, col) - } - - // After adding the collection topics, we remove the collections' documents - // from the pubsub topics to avoid receiving duplicate events. - removedTopics := []string{} for _, col := range storeCollections { keyChan, err := col.GetAllDocIDs(ctx) if err != nil { return err } for key := range keyChan { - err := p.server.removePubSubTopic(key.ID.String()) - if err != nil { - return p.rollbackRemovePubSubTopics(removedTopics, err) - } - removedTopics = append(removedTopics, key.ID.String()) + evt.ToRemove = append(evt.ToRemove, key.ID.String()) } } - if err = txn.Commit(ctx); err != nil { - err = p.rollbackRemovePubSubTopics(removedTopics, err) - return p.rollbackAddPubSubTopics(addedTopics, err) - } + txn.OnSuccess(func() { + db.events.Publish(event.NewMessage(event.P2PTopicName, evt)) + }) - return nil + return txn.Commit(ctx) } -func (p *Peer) RemoveP2PCollections(ctx context.Context, collectionIDs []string) error { - txn, err := p.db.NewTxn(ctx, false) +func (db *db) RemoveP2PCollections(ctx context.Context, collectionIDs []string) error { + txn, err := db.NewTxn(ctx, false) if err != nil { return err } @@ -114,12 +100,12 @@ func (p *Peer) RemoveP2PCollections(ctx context.Context, collectionIDs []string) // TODO-ACP: Support ACP <> P2P - https://github.com/sourcenetwork/defradb/issues/2366 // ctx = db.SetContextIdentity(ctx, identity) - ctx = db.SetContextTxn(ctx, txn) + ctx = SetContextTxn(ctx, txn) // first let's make sure the collections actually exists storeCollections := []client.Collection{} for _, col := range collectionIDs { - storeCol, err := p.db.GetCollections( + storeCol, err := db.GetCollections( ctx, client.CollectionFetchOptions{ SchemaRoot: immutable.Some(col), @@ -134,6 +120,8 @@ func (p *Peer) RemoveP2PCollections(ctx context.Context, collectionIDs []string) storeCollections = append(storeCollections, storeCol...) } + evt := event.P2PTopic{} + // Ensure we can remove all the collections to the store on the transaction // before adding to topics. for _, col := range storeCollections { @@ -142,49 +130,32 @@ func (p *Peer) RemoveP2PCollections(ctx context.Context, collectionIDs []string) if err != nil { return err } + evt.ToRemove = append(evt.ToRemove, col.SchemaRoot()) } - // Remove pubsub topics and add them back if we get an error. - removedTopics := []string{} - for _, col := range collectionIDs { - err = p.server.removePubSubTopic(col) - if err != nil { - return p.rollbackRemovePubSubTopics(removedTopics, err) - } - removedTopics = append(removedTopics, col) - } - - // After removing the collection topics, we add back the collections' documents - // to the pubsub topics. - addedTopics := []string{} for _, col := range storeCollections { keyChan, err := col.GetAllDocIDs(ctx) if err != nil { return err } for key := range keyChan { - err := p.server.addPubSubTopic(key.ID.String(), true) - if err != nil { - return p.rollbackAddPubSubTopics(addedTopics, err) - } - addedTopics = append(addedTopics, key.ID.String()) + evt.ToAdd = append(evt.ToAdd, key.ID.String()) } } - if err = txn.Commit(ctx); err != nil { - err = p.rollbackAddPubSubTopics(addedTopics, err) - return p.rollbackRemovePubSubTopics(removedTopics, err) - } + txn.OnSuccess(func() { + db.events.Publish(event.NewMessage(event.P2PTopicName, evt)) + }) - return nil + return txn.Commit(ctx) } -func (p *Peer) GetAllP2PCollections(ctx context.Context) ([]string, error) { - txn, err := p.db.NewTxn(p.ctx, true) +func (db *db) GetAllP2PCollections(ctx context.Context) ([]string, error) { + txn, err := db.NewTxn(ctx, true) if err != nil { return nil, err } - defer txn.Discard(p.ctx) + defer txn.Discard(ctx) query := dsq.Query{ Prefix: core.NewP2PCollectionKey("").ToString(), @@ -205,3 +176,52 @@ func (p *Peer) GetAllP2PCollections(ctx context.Context) ([]string, error) { return collectionIDs, nil } + +func (db *db) PeerInfo() peer.AddrInfo { + peerInfo := db.peerInfo.Load() + if peerInfo != nil { + return peerInfo.(peer.AddrInfo) + } + return peer.AddrInfo{} +} + +func (db *db) loadAndPublishP2PCollections(ctx context.Context) error { + schemaRoots, err := db.GetAllP2PCollections(ctx) + if err != nil { + return err + } + db.events.Publish(event.NewMessage(event.P2PTopicName, event.P2PTopic{ + ToAdd: schemaRoots, + })) + + // Get all DocIDs across all collections in the DB + cols, err := db.GetCollections(ctx, client.CollectionFetchOptions{}) + if err != nil { + return err + } + + // Index the schema roots for faster lookup. + colMap := make(map[string]struct{}) + for _, schemaRoot := range schemaRoots { + colMap[schemaRoot] = struct{}{} + } + + for _, col := range cols { + // If we subscribed to the collection, we skip subscribing to the collection's docIDs. + if _, ok := colMap[col.SchemaRoot()]; ok { + continue + } + // TODO-ACP: Support ACP <> P2P - https://github.com/sourcenetwork/defradb/issues/2366 + docIDChan, err := col.GetAllDocIDs(ctx) + if err != nil { + return err + } + + for docID := range docIDChan { + db.events.Publish(event.NewMessage(event.P2PTopicName, event.P2PTopic{ + ToAdd: []string{docID.ID.String()}, + })) + } + } + return nil +} diff --git a/internal/db/p2p_schema_root_test.go b/internal/db/p2p_schema_root_test.go new file mode 100644 index 0000000000..8039f815b0 --- /dev/null +++ b/internal/db/p2p_schema_root_test.go @@ -0,0 +1,307 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package db + +import ( + "context" + "encoding/hex" + "fmt" + "testing" + + "github.com/decred/dcrd/dcrec/secp256k1/v4" + "github.com/stretchr/testify/require" + + "github.com/sourcenetwork/immutable" + + "github.com/sourcenetwork/defradb/acp" + acpIdentity "github.com/sourcenetwork/defradb/acp/identity" + "github.com/sourcenetwork/defradb/client" + "github.com/sourcenetwork/defradb/datastore/memory" + "github.com/sourcenetwork/defradb/event" +) + +func TestAddP2PCollection_WithInvalidCollection_ShouldError(t *testing.T) { + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + err = db.AddP2PCollections(ctx, []string{"invalidCollection"}) + require.ErrorIs(t, err, client.ErrCollectionNotFound) +} + +func TestAddP2PCollection_WithValidCollection_ShouldSucceed(t *testing.T) { + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + sub, err := db.events.Subscribe(event.P2PTopicName) + require.NoError(t, err) + cols, err := db.AddSchema(ctx, `type User { name: String }`) + require.NoError(t, err) + schema, err := db.GetSchemaByVersionID(ctx, cols[0].SchemaVersionID) + require.NoError(t, err) + err = db.AddP2PCollections(ctx, []string{schema.Root}) + require.NoError(t, err) + // Check that the event was published + for msg := range sub.Message() { + p2pTopic := msg.Data.(event.P2PTopic) + require.Equal(t, []string{schema.Root}, p2pTopic.ToAdd) + break + } +} + +func TestAddP2PCollection_WithValidCollectionAndDoc_ShouldSucceed(t *testing.T) { + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + sub, err := db.events.Subscribe(event.P2PTopicName) + require.NoError(t, err) + cols, err := db.AddSchema(ctx, `type User { name: String }`) + require.NoError(t, err) + col, err := db.GetCollectionByName(ctx, cols[0].Name.Value()) + require.NoError(t, err) + doc, err := client.NewDocFromMap(map[string]any{"name": "Alice"}, col.Definition()) + require.NoError(t, err) + err = col.Create(ctx, doc) + require.NoError(t, err) + + err = db.AddP2PCollections(ctx, []string{col.SchemaRoot()}) + require.NoError(t, err) + // Check that the event was published + for msg := range sub.Message() { + p2pTopic := msg.Data.(event.P2PTopic) + require.Equal(t, []string{col.SchemaRoot()}, p2pTopic.ToAdd) + require.Equal(t, []string{doc.ID().String()}, p2pTopic.ToRemove) + break + } +} + +func TestAddP2PCollection_WithMultipleValidCollections_ShouldSucceed(t *testing.T) { + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + sub, err := db.events.Subscribe(event.P2PTopicName) + require.NoError(t, err) + cols1, err := db.AddSchema(ctx, `type User { name: String }`) + require.NoError(t, err) + schema1, err := db.GetSchemaByVersionID(ctx, cols1[0].SchemaVersionID) + require.NoError(t, err) + cols2, err := db.AddSchema(ctx, `type Books { name: String }`) + require.NoError(t, err) + schema2, err := db.GetSchemaByVersionID(ctx, cols2[0].SchemaVersionID) + require.NoError(t, err) + err = db.AddP2PCollections(ctx, []string{schema1.Root, schema2.Root}) + require.NoError(t, err) + // Check that the event was published + for msg := range sub.Message() { + p2pTopic := msg.Data.(event.P2PTopic) + require.Equal(t, []string{schema1.Root, schema2.Root}, p2pTopic.ToAdd) + break + } +} + +func TestRemoveP2PCollection_WithInvalidCollection_ShouldError(t *testing.T) { + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + err = db.RemoveP2PCollections(ctx, []string{"invalidCollection"}) + require.ErrorIs(t, err, client.ErrCollectionNotFound) +} + +func TestRemoveP2PCollection_WithValidCollection_ShouldSucceed(t *testing.T) { + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + sub, err := db.events.Subscribe(event.P2PTopicName) + require.NoError(t, err) + cols, err := db.AddSchema(ctx, `type User { name: String }`) + require.NoError(t, err) + schema, err := db.GetSchemaByVersionID(ctx, cols[0].SchemaVersionID) + require.NoError(t, err) + err = db.AddP2PCollections(ctx, []string{schema.Root}) + require.NoError(t, err) + // Check that the event was published + for msg := range sub.Message() { + p2pTopic := msg.Data.(event.P2PTopic) + require.Equal(t, []string{schema.Root}, p2pTopic.ToAdd) + break + } + err = db.RemoveP2PCollections(ctx, []string{schema.Root}) + require.NoError(t, err) + // Check that the event was published + for msg := range sub.Message() { + p2pTopic := msg.Data.(event.P2PTopic) + require.Equal(t, []string{schema.Root}, p2pTopic.ToRemove) + break + } +} + +func TestRemoveP2PCollection_WithValidCollectionAndDoc_ShouldSucceed(t *testing.T) { + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + sub, err := db.events.Subscribe(event.P2PTopicName) + require.NoError(t, err) + cols, err := db.AddSchema(ctx, `type User { name: String }`) + require.NoError(t, err) + col, err := db.GetCollectionByName(ctx, cols[0].Name.Value()) + require.NoError(t, err) + doc, err := client.NewDocFromMap(map[string]any{"name": "Alice"}, col.Definition()) + require.NoError(t, err) + err = col.Create(ctx, doc) + require.NoError(t, err) + + err = db.AddP2PCollections(ctx, []string{col.SchemaRoot()}) + require.NoError(t, err) + // Check that the event was published + for msg := range sub.Message() { + p2pTopic := msg.Data.(event.P2PTopic) + require.Equal(t, []string{col.SchemaRoot()}, p2pTopic.ToAdd) + require.Equal(t, []string{doc.ID().String()}, p2pTopic.ToRemove) + break + } + err = db.RemoveP2PCollections(ctx, []string{col.SchemaRoot()}) + require.NoError(t, err) + // Check that the event was published + for msg := range sub.Message() { + p2pTopic := msg.Data.(event.P2PTopic) + require.Equal(t, []string{col.SchemaRoot()}, p2pTopic.ToRemove) + require.Equal(t, []string{doc.ID().String()}, p2pTopic.ToAdd) + break + } +} + +func TestLoadP2PCollection_WithValidCollectionsAndDocs_ShouldSucceed(t *testing.T) { + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + sub, err := db.events.Subscribe(event.P2PTopicName) + require.NoError(t, err) + cols1, err := db.AddSchema(ctx, `type User { name: String }`) + require.NoError(t, err) + col1, err := db.GetCollectionByName(ctx, cols1[0].Name.Value()) + require.NoError(t, err) + doc1, err := client.NewDocFromMap(map[string]any{"name": "Alice"}, col1.Definition()) + require.NoError(t, err) + err = col1.Create(ctx, doc1) + require.NoError(t, err) + + cols2, err := db.AddSchema(ctx, `type Book { name: String }`) + require.NoError(t, err) + col2, err := db.GetCollectionByName(ctx, cols2[0].Name.Value()) + require.NoError(t, err) + doc2, err := client.NewDocFromMap(map[string]any{"name": "Some book"}, col2.Definition()) + require.NoError(t, err) + err = col2.Create(ctx, doc2) + require.NoError(t, err) + + err = db.AddP2PCollections(ctx, []string{col1.SchemaRoot()}) + require.NoError(t, err) + // Check that the event was published + for msg := range sub.Message() { + p2pTopic := msg.Data.(event.P2PTopic) + require.Equal(t, []string{col1.SchemaRoot()}, p2pTopic.ToAdd) + require.Equal(t, []string{doc1.ID().String()}, p2pTopic.ToRemove) + break + } + err = db.loadAndPublishP2PCollections(ctx) + require.NoError(t, err) + // Check that the event was published + msg := <-sub.Message() + p2pTopic := msg.Data.(event.P2PTopic) + require.Equal(t, []string{col1.SchemaRoot()}, p2pTopic.ToAdd) + msg = <-sub.Message() + p2pTopic = msg.Data.(event.P2PTopic) + require.Equal(t, []string{doc2.ID().String()}, p2pTopic.ToAdd) +} + +func TestGetAllP2PCollections_WithMultipleValidCollections_ShouldSucceed(t *testing.T) { + ctx := context.Background() + db, err := newDefraMemoryDB(ctx) + require.NoError(t, err) + defer db.Close() + cols1, err := db.AddSchema(ctx, `type User { name: String }`) + require.NoError(t, err) + schema1, err := db.GetSchemaByVersionID(ctx, cols1[0].SchemaVersionID) + require.NoError(t, err) + cols2, err := db.AddSchema(ctx, `type Books { name: String }`) + require.NoError(t, err) + schema2, err := db.GetSchemaByVersionID(ctx, cols2[0].SchemaVersionID) + require.NoError(t, err) + err = db.AddP2PCollections(ctx, []string{schema1.Root, schema2.Root}) + require.NoError(t, err) + cols, err := db.GetAllP2PCollections(ctx) + require.NoError(t, err) + require.Equal(t, []string{schema2.Root, schema1.Root}, cols) +} + +// This test documents that we don't allow adding p2p collections that have a policy +// until the following is implemented: +// TODO-ACP: ACP <> P2P https://github.com/sourcenetwork/defradb/issues/2366 +func TestAddP2PCollectionsWithPermissionedCollection_Error(t *testing.T) { + ctx := context.Background() + rootstore := memory.NewDatastore(ctx) + db, err := newDB(ctx, rootstore, immutable.Some[acp.ACP](acp.NewLocalACP()), nil) + require.NoError(t, err) + + policy := ` + name: test + description: a policy + actor: + name: actor + resources: + user: + permissions: + read: + expr: owner + write: + expr: owner + relations: + owner: + types: + - actor + ` + + privKeyBytes, err := hex.DecodeString("028d53f37a19afb9a0dbc5b4be30c65731479ee8cfa0c9bc8f8bf198cc3c075f") + require.NoError(t, err) + privKey := secp256k1.PrivKeyFromBytes(privKeyBytes) + identity, err := acpIdentity.FromPrivateKey(privKey) + require.NoError(t, err) + + ctx = SetContextIdentity(ctx, identity) + policyResult, err := db.AddPolicy(ctx, policy) + policyID := policyResult.PolicyID + require.NoError(t, err) + require.Equal(t, "7b5ed30570e8d9206027ef6d5469879a6c1ea4595625c6ca33a19063a6ed6214", policyID) + + schema := fmt.Sprintf(` + type User @policy(id: "%s", resource: "user") { + name: String + age: Int + } + `, policyID, + ) + _, err = db.AddSchema(ctx, schema) + require.NoError(t, err) + + col, err := db.GetCollectionByName(ctx, "User") + require.NoError(t, err) + + err = db.AddP2PCollections(ctx, []string{col.SchemaRoot()}) + require.Error(t, err) + require.ErrorIs(t, err, ErrP2PColHasPolicy) +} diff --git a/internal/merkle/clock/clock.go b/internal/merkle/clock/clock.go index 06cccb6467..d16d1d6a5b 100644 --- a/internal/merkle/clock/clock.go +++ b/internal/merkle/clock/clock.go @@ -32,8 +32,8 @@ var ( // MerkleClock is a MerkleCRDT clock that can be used to read/write events (deltas) to the clock. type MerkleClock struct { - headstore datastore.DSReaderWriter - dagstore datastore.DAGStore + headstore datastore.DSReaderWriter + blockstore datastore.Blockstore // dagSyncer headset *heads crdt core.ReplicatedData @@ -42,15 +42,15 @@ type MerkleClock struct { // NewMerkleClock returns a new MerkleClock. func NewMerkleClock( headstore datastore.DSReaderWriter, - dagstore datastore.DAGStore, + blockstore datastore.Blockstore, namespace core.HeadStoreKey, crdt core.ReplicatedData, ) *MerkleClock { return &MerkleClock{ - headstore: headstore, - dagstore: dagstore, - headset: NewHeadSet(headstore, namespace), - crdt: crdt, + headstore: headstore, + blockstore: blockstore, + headset: NewHeadSet(headstore, namespace), + crdt: crdt, } } @@ -60,7 +60,7 @@ func (mc *MerkleClock) putBlock( ) (cidlink.Link, error) { nd := block.GenerateNode() lsys := cidlink.DefaultLinkSystem() - lsys.SetWriteStorage(mc.dagstore.AsIPLDStorage()) + lsys.SetWriteStorage(mc.blockstore.AsIPLDStorage()) link, err := lsys.Store(linking.LinkContext{Ctx: ctx}, coreblock.GetLinkPrototype(), nd) if err != nil { return cidlink.Link{}, NewErrWritingBlock(err) @@ -155,7 +155,7 @@ func (mc *MerkleClock) ProcessBlock( continue } - known, err := mc.dagstore.Has(ctx, linkCid) + known, err := mc.blockstore.Has(ctx, linkCid) if err != nil { return NewErrCouldNotFindBlock(linkCid, err) } diff --git a/internal/merkle/clock/clock_test.go b/internal/merkle/clock/clock_test.go index c9a51a7a1e..7effc02fef 100644 --- a/internal/merkle/clock/clock_test.go +++ b/internal/merkle/clock/clock_test.go @@ -36,7 +36,7 @@ func newTestMerkleClock() *MerkleClock { reg := crdt.NewLWWRegister(multistore.Rootstore(), core.CollectionSchemaVersionKey{}, core.DataStoreKey{}, "") return NewMerkleClock( multistore.Headstore(), - multistore.DAGstore(), + multistore.Blockstore(), core.HeadStoreKey{DocID: request.DocIDArgName, FieldId: "1"}, reg, ) @@ -46,7 +46,7 @@ func TestNewMerkleClock(t *testing.T) { s := newDS() multistore := datastore.MultiStoreFrom(s) reg := crdt.NewLWWRegister(multistore.Rootstore(), core.CollectionSchemaVersionKey{}, core.DataStoreKey{}, "") - clk := NewMerkleClock(multistore.Headstore(), multistore.DAGstore(), core.HeadStoreKey{}, reg) + clk := NewMerkleClock(multistore.Headstore(), multistore.Blockstore(), core.HeadStoreKey{}, reg) if clk.headstore != multistore.Headstore() { t.Error("MerkleClock store not correctly set") @@ -146,7 +146,7 @@ func TestMerkleClockAddDeltaWithHeads(t *testing.T) { } numBlocks := 0 - cids, err := clk.dagstore.AllKeysChan(ctx) + cids, err := clk.blockstore.AllKeysChan(ctx) if err != nil { t.Error("Failed to get blockstore content for merkle clock:", err) return diff --git a/internal/merkle/crdt/composite.go b/internal/merkle/crdt/composite.go index 33d6ab2d3c..26ab4134e5 100644 --- a/internal/merkle/crdt/composite.go +++ b/internal/merkle/crdt/composite.go @@ -44,7 +44,7 @@ func NewMerkleCompositeDAG( fieldName, ) - clock := clock.NewMerkleClock(store.Headstore(), store.DAGstore(), key.ToHeadStoreKey(), compositeDag) + clock := clock.NewMerkleClock(store.Headstore(), store.Blockstore(), key.ToHeadStoreKey(), compositeDag) base := &baseMerkleCRDT{clock: clock, crdt: compositeDag} return &MerkleCompositeDAG{ diff --git a/internal/merkle/crdt/counter.go b/internal/merkle/crdt/counter.go index c5d3a7e8dd..2553dcfd2f 100644 --- a/internal/merkle/crdt/counter.go +++ b/internal/merkle/crdt/counter.go @@ -39,7 +39,7 @@ func NewMerkleCounter( kind client.ScalarKind, ) *MerkleCounter { register := crdt.NewCounter(store.Datastore(), schemaVersionKey, key, fieldName, allowDecrement, kind) - clk := clock.NewMerkleClock(store.Headstore(), store.DAGstore(), key.ToHeadStoreKey(), register) + clk := clock.NewMerkleClock(store.Headstore(), store.Blockstore(), key.ToHeadStoreKey(), register) base := &baseMerkleCRDT{clock: clk, crdt: register} return &MerkleCounter{ baseMerkleCRDT: base, diff --git a/internal/merkle/crdt/lwwreg.go b/internal/merkle/crdt/lwwreg.go index 6755eac639..b8132ccad5 100644 --- a/internal/merkle/crdt/lwwreg.go +++ b/internal/merkle/crdt/lwwreg.go @@ -37,7 +37,7 @@ func NewMerkleLWWRegister( fieldName string, ) *MerkleLWWRegister { register := corecrdt.NewLWWRegister(store.Datastore(), schemaVersionKey, key, fieldName) - clk := clock.NewMerkleClock(store.Headstore(), store.DAGstore(), key.ToHeadStoreKey(), register) + clk := clock.NewMerkleClock(store.Headstore(), store.Blockstore(), key.ToHeadStoreKey(), register) base := &baseMerkleCRDT{clock: clk, crdt: register} return &MerkleLWWRegister{ baseMerkleCRDT: base, diff --git a/internal/merkle/crdt/merklecrdt.go b/internal/merkle/crdt/merklecrdt.go index abc0ffeb51..fc3019b05c 100644 --- a/internal/merkle/crdt/merklecrdt.go +++ b/internal/merkle/crdt/merklecrdt.go @@ -26,7 +26,7 @@ import ( type Stores interface { Datastore() datastore.DSReaderWriter - DAGstore() datastore.DAGStore + Blockstore() datastore.Blockstore Headstore() datastore.DSReaderWriter } diff --git a/internal/merkle/crdt/merklecrdt_test.go b/internal/merkle/crdt/merklecrdt_test.go index bd42223509..29482b28bf 100644 --- a/internal/merkle/crdt/merklecrdt_test.go +++ b/internal/merkle/crdt/merklecrdt_test.go @@ -32,7 +32,7 @@ func newTestBaseMerkleCRDT() (*baseMerkleCRDT, datastore.DSReaderWriter) { multistore := datastore.MultiStoreFrom(s) reg := crdt.NewLWWRegister(multistore.Datastore(), core.CollectionSchemaVersionKey{}, core.DataStoreKey{}, "") - clk := clock.NewMerkleClock(multistore.Headstore(), multistore.DAGstore(), core.HeadStoreKey{}, reg) + clk := clock.NewMerkleClock(multistore.Headstore(), multistore.Blockstore(), core.HeadStoreKey{}, reg) return &baseMerkleCRDT{clock: clk, crdt: reg}, multistore.Rootstore() } diff --git a/internal/planner/commit.go b/internal/planner/commit.go index 2f9de44bac..3a5bec39f9 100644 --- a/internal/planner/commit.go +++ b/internal/planner/commit.go @@ -184,7 +184,7 @@ func (n *dagScanNode) Next() (bool, error) { n.execInfo.iterations++ var currentCid *cid.Cid - store := n.planner.txn.DAGstore() + store := n.planner.txn.Blockstore() if len(n.queuedCids) > 0 { currentCid = n.queuedCids[0] diff --git a/net/client_test.go b/net/client_test.go index 6a43805ae8..43c4ec1e01 100644 --- a/net/client_test.go +++ b/net/client_test.go @@ -45,8 +45,9 @@ var def = client.CollectionDefinition{ func TestPushlogWithDialFailure(t *testing.T) { ctx := context.Background() - _, n := newTestNode(ctx, t) - defer n.Close() + db, p := newTestPeer(ctx, t) + defer db.Close() + defer p.Close() doc, err := client.NewDocFromJSON([]byte(`{"test": "test"}`), def) require.NoError(t, err) @@ -56,13 +57,13 @@ func TestPushlogWithDialFailure(t *testing.T) { cid, err := createCID(doc) require.NoError(t, err) - n.server.opts = append( - n.server.opts, + p.server.opts = append( + p.server.opts, grpc.WithTransportCredentials(nil), grpc.WithCredentialsBundle(nil), ) - err = n.server.pushLog(ctx, event.Update{ + err = p.server.pushLog(ctx, event.Update{ DocID: id.String(), Cid: cid, SchemaRoot: "test", @@ -73,8 +74,9 @@ func TestPushlogWithDialFailure(t *testing.T) { func TestPushlogWithInvalidPeerID(t *testing.T) { ctx := context.Background() - _, n := newTestNode(ctx, t) - defer n.Close() + db, p := newTestPeer(ctx, t) + defer db.Close() + defer p.Close() doc, err := client.NewDocFromJSON([]byte(`{"test": "test"}`), def) require.NoError(t, err) @@ -84,7 +86,7 @@ func TestPushlogWithInvalidPeerID(t *testing.T) { cid, err := createCID(doc) require.NoError(t, err) - err = n.server.pushLog(ctx, event.Update{ + err = p.server.pushLog(ctx, event.Update{ DocID: id.String(), Cid: cid, SchemaRoot: "test", @@ -95,27 +97,29 @@ func TestPushlogWithInvalidPeerID(t *testing.T) { func TestPushlogW_WithValidPeerID_NoError(t *testing.T) { ctx := context.Background() - _, n1 := newTestNode(ctx, t) - defer n1.Close() - n1.Start() - _, n2 := newTestNode(ctx, t) - defer n2.Close() - n2.Start() + db1, p1 := newTestPeer(ctx, t) + defer db1.Close() + defer p1.Close() + p1.Start() + db2, p2 := newTestPeer(ctx, t) + defer p2.Close() + defer db2.Close() + p2.Start() - err := n1.host.Connect(ctx, n2.PeerInfo()) + err := p1.host.Connect(ctx, p2.PeerInfo()) require.NoError(t, err) - _, err = n1.db.AddSchema(ctx, `type User { + _, err = db1.AddSchema(ctx, `type User { name: String }`) require.NoError(t, err) - _, err = n2.db.AddSchema(ctx, `type User { + _, err = db2.AddSchema(ctx, `type User { name: String }`) require.NoError(t, err) - col, err := n1.db.GetCollectionByName(ctx, "User") + col, err := db1.GetCollectionByName(ctx, "User") require.NoError(t, err) doc, err := client.NewDocFromJSON([]byte(`{"name": "test"}`), col.Definition()) @@ -124,22 +128,22 @@ func TestPushlogW_WithValidPeerID_NoError(t *testing.T) { err = col.Save(ctx, doc) require.NoError(t, err) - col, err = n2.db.GetCollectionByName(ctx, "User") + col, err = db2.GetCollectionByName(ctx, "User") require.NoError(t, err) err = col.Save(ctx, doc) require.NoError(t, err) - headCID, err := getHead(ctx, n1.db, doc.ID()) + headCID, err := getHead(ctx, db1, doc.ID()) require.NoError(t, err) - b, err := n1.db.Blockstore().AsIPLDStorage().Get(ctx, headCID.KeyString()) + b, err := db1.Blockstore().AsIPLDStorage().Get(ctx, headCID.KeyString()) require.NoError(t, err) - err = n1.server.pushLog(ctx, event.Update{ + err = p1.server.pushLog(ctx, event.Update{ DocID: doc.ID().String(), Cid: headCID, SchemaRoot: col.SchemaRoot(), Block: b, - }, n2.PeerInfo().ID) + }, p2.PeerInfo().ID) require.NoError(t, err) } diff --git a/net/dialer_test.go b/net/dialer_test.go index 7f37611ec3..479d4d7e63 100644 --- a/net/dialer_test.go +++ b/net/dialer_test.go @@ -23,17 +23,23 @@ import ( func TestDial_WithConnectedPeer_NoError(t *testing.T) { db1 := FixtureNewMemoryDBWithBroadcaster(t) db2 := FixtureNewMemoryDBWithBroadcaster(t) + defer db1.Close() + defer db2.Close() ctx := context.Background() - n1, err := NewNode( + n1, err := NewPeer( ctx, - db1, + db1.Rootstore(), + db1.Blockstore(), + db1.Events(), WithListenAddresses("/ip4/0.0.0.0/tcp/0"), ) assert.NoError(t, err) defer n1.Close() - n2, err := NewNode( + n2, err := NewPeer( ctx, - db2, + db2.Rootstore(), + db2.Blockstore(), + db2.Events(), WithListenAddresses("/ip4/0.0.0.0/tcp/0"), ) assert.NoError(t, err) @@ -50,17 +56,23 @@ func TestDial_WithConnectedPeer_NoError(t *testing.T) { func TestDial_WithConnectedPeerAndSecondConnection_NoError(t *testing.T) { db1 := FixtureNewMemoryDBWithBroadcaster(t) db2 := FixtureNewMemoryDBWithBroadcaster(t) + defer db1.Close() + defer db2.Close() ctx := context.Background() - n1, err := NewNode( + n1, err := NewPeer( ctx, - db1, + db1.Rootstore(), + db1.Blockstore(), + db1.Events(), WithListenAddresses("/ip4/0.0.0.0/tcp/0"), ) assert.NoError(t, err) defer n1.Close() - n2, err := NewNode( + n2, err := NewPeer( ctx, - db2, + db2.Rootstore(), + db2.Blockstore(), + db2.Events(), WithListenAddresses("/ip4/0.0.0.0/tcp/0"), ) assert.NoError(t, err) @@ -80,17 +92,23 @@ func TestDial_WithConnectedPeerAndSecondConnection_NoError(t *testing.T) { func TestDial_WithConnectedPeerAndSecondConnectionWithConnectionShutdown_ClosingConnectionError(t *testing.T) { db1 := FixtureNewMemoryDBWithBroadcaster(t) db2 := FixtureNewMemoryDBWithBroadcaster(t) + defer db1.Close() + defer db2.Close() ctx := context.Background() - n1, err := NewNode( + n1, err := NewPeer( ctx, - db1, + db1.Rootstore(), + db1.Blockstore(), + db1.Events(), WithListenAddresses("/ip4/0.0.0.0/tcp/0"), ) assert.NoError(t, err) defer n1.Close() - n2, err := NewNode( + n2, err := NewPeer( ctx, - db2, + db2.Rootstore(), + db2.Blockstore(), + db2.Events(), WithListenAddresses("/ip4/0.0.0.0/tcp/0"), ) assert.NoError(t, err) diff --git a/net/errors.go b/net/errors.go index eb53a8e2a5..615f1088ef 100644 --- a/net/errors.go +++ b/net/errors.go @@ -13,8 +13,6 @@ package net import ( "fmt" - "github.com/libp2p/go-libp2p/core/peer" - "github.com/sourcenetwork/defradb/errors" ) @@ -23,23 +21,16 @@ const ( errFailedToGetDocID = "failed to get DocID from broadcast message" errPublishingToDocIDTopic = "can't publish log %s for docID %s" errPublishingToSchemaTopic = "can't publish log %s for schema %s" - errReplicatorExists = "replicator already exists for %s with peerID %s" - errReplicatorDocID = "failed to get docID for replicator %s with peerID %s" - errReplicatorCollections = "failed to get collections for replicator" errCheckingForExistingBlock = "failed to check for existing block" ) var ( - ErrP2PColHasPolicy = errors.New("p2p collection specified has a policy on it") - ErrReplicatorColHasPolicy = errors.New("replicator collection specified has a policy on it") - ErrReplicatorSomeColsHavePolicy = errors.New("replicator can not use all collections, as some have policy") - ErrPeerConnectionWaitTimout = errors.New("waiting for peer connection timed out") - ErrPubSubWaitTimeout = errors.New("waiting for pubsub timed out") - ErrPushLogWaitTimeout = errors.New("waiting for pushlog timed out") - ErrNilDB = errors.New("database object can't be nil") - ErrNilUpdateChannel = errors.New("tried to subscribe to update channel, but update channel is nil") - ErrSelfTargetForReplicator = errors.New("can't target ourselves as a replicator") - ErrCheckingForExistingBlock = errors.New(errCheckingForExistingBlock) + ErrPeerConnectionWaitTimout = errors.New("waiting for peer connection timed out") + ErrPubSubWaitTimeout = errors.New("waiting for pubsub timed out") + ErrPushLogWaitTimeout = errors.New("waiting for pushlog timed out") + ErrNilDB = errors.New("database object can't be nil") + ErrNilUpdateChannel = errors.New("tried to subscribe to update channel, but update channel is nil") + ErrCheckingForExistingBlock = errors.New(errCheckingForExistingBlock) ) func NewErrPushLog(inner error, kv ...errors.KV) error { @@ -58,18 +49,6 @@ func NewErrPublishingToSchemaTopic(inner error, cid, docID string, kv ...errors. return errors.Wrap(fmt.Sprintf(errPublishingToSchemaTopic, cid, docID), inner, kv...) } -func NewErrReplicatorExists(collection string, peerID peer.ID, kv ...errors.KV) error { - return errors.New(fmt.Sprintf(errReplicatorExists, collection, peerID), kv...) -} - -func NewErrReplicatorDocID(inner error, collection string, peerID peer.ID, kv ...errors.KV) error { - return errors.Wrap(fmt.Sprintf(errReplicatorDocID, collection, peerID), inner, kv...) -} - -func NewErrReplicatorCollections(inner error, kv ...errors.KV) error { - return errors.Wrap(errReplicatorCollections, inner, kv...) -} - func NewErrCheckingForExistingBlock(inner error, cid string) error { return errors.Wrap(errCheckingForExistingBlock, inner, errors.NewKV("cid", cid)) } diff --git a/net/node.go b/net/node.go deleted file mode 100644 index 3338ac0f04..0000000000 --- a/net/node.go +++ /dev/null @@ -1,282 +0,0 @@ -// Copyright 2023 Democratized Data Foundation -// -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. - -/* -Package node is responsible for interfacing a given DefraDB instance with a networked peer instance -and GRPC server. - -Basically it combines db/DB, net/Peer, and net/Server into a single Node object. -*/ -package net - -import ( - "context" - "fmt" - "sync" - "sync/atomic" - "time" - - "github.com/ipfs/boxo/ipns" - ds "github.com/ipfs/go-datastore" - libp2p "github.com/libp2p/go-libp2p" - dht "github.com/libp2p/go-libp2p-kad-dht" - dualdht "github.com/libp2p/go-libp2p-kad-dht/dual" - pubsub "github.com/libp2p/go-libp2p-pubsub" - record "github.com/libp2p/go-libp2p-record" - libp2pCrypto "github.com/libp2p/go-libp2p/core/crypto" - libp2pEvent "github.com/libp2p/go-libp2p/core/event" - "github.com/libp2p/go-libp2p/core/host" - "github.com/libp2p/go-libp2p/core/peer" - "github.com/libp2p/go-libp2p/core/routing" - "github.com/multiformats/go-multiaddr" - - "github.com/sourcenetwork/corelog" - "github.com/sourcenetwork/go-libp2p-pubsub-rpc/finalizer" - - // @TODO: https://github.com/sourcenetwork/defradb/issues/1902 - //nolint:staticcheck - "github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoreds" - "github.com/libp2p/go-libp2p/p2p/net/connmgr" - - "github.com/sourcenetwork/defradb/client" - "github.com/sourcenetwork/defradb/crypto" - "github.com/sourcenetwork/defradb/event" -) - -var _ client.P2P = (*Node)(nil) - -// Node is a networked peer instance of DefraDB. -type Node struct { - // embed the DB interface into the node - client.DB - - *Peer - - ctx context.Context - cancel context.CancelFunc - dhtClose func() error -} - -// NewNode creates a new network node instance of DefraDB, wired into libp2p. -func NewNode( - ctx context.Context, - db client.DB, - opts ...NodeOpt, -) (node *Node, err error) { - options := DefaultOptions() - for _, opt := range opts { - opt(options) - } - - connManager, err := connmgr.NewConnManager(100, 400, connmgr.WithGracePeriod(time.Second*20)) - if err != nil { - return nil, err - } - - var listenAddresses []multiaddr.Multiaddr - for _, addr := range options.ListenAddresses { - listenAddress, err := multiaddr.NewMultiaddr(addr) - if err != nil { - return nil, err - } - listenAddresses = append(listenAddresses, listenAddress) - } - - fin := finalizer.NewFinalizer() - - ctx, cancel := context.WithCancel(ctx) - defer func() { - if node == nil { - cancel() - } - }() - - peerstore, err := pstoreds.NewPeerstore(ctx, db.Peerstore(), pstoreds.DefaultOpts()) - if err != nil { - return nil, fin.Cleanup(err) - } - fin.Add(peerstore) - - if options.PrivateKey == nil { - // generate an ephemeral private key - key, err := crypto.GenerateEd25519() - if err != nil { - return nil, fin.Cleanup(err) - } - options.PrivateKey = key - } - - // unmarshal the private key bytes - privateKey, err := libp2pCrypto.UnmarshalEd25519PrivateKey(options.PrivateKey) - if err != nil { - return nil, fin.Cleanup(err) - } - - var ddht *dualdht.DHT - - libp2pOpts := []libp2p.Option{ - libp2p.ConnectionManager(connManager), - libp2p.DefaultTransports, - libp2p.Identity(privateKey), - libp2p.ListenAddrs(listenAddresses...), - libp2p.Peerstore(peerstore), - libp2p.Routing(func(h host.Host) (routing.PeerRouting, error) { - // Delete this line and uncomment the next 6 lines once we remove batchable datastore support. - // var store ds.Batching - // // If `rootstore` doesn't implement `Batching`, `nil` will be passed - // // to newDHT which will cause the DHT to be stored in memory. - // if dsb, isBatching := rootstore.(ds.Batching); isBatching { - // store = dsb - // } - store := db.Root() // Delete this line once we remove batchable datastore support. - ddht, err = newDHT(ctx, h, store) - return ddht, err - }), - } - if !options.EnableRelay { - libp2pOpts = append(libp2pOpts, libp2p.DisableRelay()) - } - - h, err := libp2p.New(libp2pOpts...) - if err != nil { - return nil, fin.Cleanup(err) - } - log.InfoContext( - ctx, - "Created LibP2P host", - corelog.Any("PeerId", h.ID()), - corelog.Any("Address", options.ListenAddresses), - ) - - var ps *pubsub.PubSub - if options.EnablePubSub { - ps, err = pubsub.NewGossipSub( - ctx, - h, - pubsub.WithPeerExchange(true), - pubsub.WithFloodPublish(true), - ) - if err != nil { - return nil, fin.Cleanup(err) - } - } - - peer, err := NewPeer( - ctx, - db, - h, - ddht, - ps, - options.GRPCServerOptions, - options.GRPCDialOptions, - ) - if err != nil { - return nil, fin.Cleanup(err) - } - - sub, err := h.EventBus().Subscribe(&libp2pEvent.EvtPeerConnectednessChanged{}) - if err != nil { - return nil, fin.Cleanup(err) - } - // publish subscribed events to the event bus - go func() { - for val := range sub.Out() { - db.Events().Publish(event.NewMessage(event.PeerName, val)) - } - }() - - node = &Node{ - Peer: peer, - DB: db, - ctx: ctx, - cancel: cancel, - dhtClose: ddht.Close, - } - - return -} - -// Bootstrap connects to the given peers. -func (n *Node) Bootstrap(addrs []peer.AddrInfo) { - var connected uint64 - - var wg sync.WaitGroup - for _, pinfo := range addrs { - wg.Add(1) - go func(pinfo peer.AddrInfo) { - defer wg.Done() - err := n.host.Connect(n.ctx, pinfo) - if err != nil { - log.ErrorContextE(n.ctx, "Cannot connect to peer", err) - return - } - log.InfoContext(n.ctx, "Connected", corelog.Any("PeerID", pinfo.ID)) - atomic.AddUint64(&connected, 1) - }(pinfo) - } - - wg.Wait() - - if nPeers := len(addrs); int(connected) < nPeers/2 { - log.InfoContext(n.ctx, fmt.Sprintf("Only connected to %d bootstrap peers out of %d", connected, nPeers)) - } - - err := n.dht.Bootstrap(n.ctx) - if err != nil { - log.ErrorContextE(n.ctx, "Problem bootstraping using DHT", err) - return - } -} - -func (n *Node) PeerID() peer.ID { - return n.host.ID() -} - -func (n *Node) ListenAddrs() []multiaddr.Multiaddr { - return n.host.Network().ListenAddresses() -} - -func (n *Node) PeerInfo() peer.AddrInfo { - return peer.AddrInfo{ - ID: n.host.ID(), - Addrs: n.host.Network().ListenAddresses(), - } -} - -func newDHT(ctx context.Context, h host.Host, dsb ds.Batching) (*dualdht.DHT, error) { - dhtOpts := []dualdht.Option{ - dualdht.DHTOption(dht.NamespacedValidator("pk", record.PublicKeyValidator{})), - dualdht.DHTOption(dht.NamespacedValidator("ipns", ipns.Validator{KeyBook: h.Peerstore()})), - dualdht.DHTOption(dht.Concurrency(10)), - dualdht.DHTOption(dht.Mode(dht.ModeAuto)), - } - if dsb != nil { - dhtOpts = append(dhtOpts, dualdht.DHTOption(dht.Datastore(dsb))) - } - - return dualdht.New(ctx, h, dhtOpts...) -} - -// Close closes the node and all its services. -func (n Node) Close() { - if n.cancel != nil { - n.cancel() - } - if n.Peer != nil { - n.Peer.Close() - } - if n.dhtClose != nil { - err := n.dhtClose() - if err != nil { - log.ErrorContextE(n.ctx, "Failed to close DHT", err) - } - } - n.DB.Close() -} diff --git a/net/node_test.go b/net/node_test.go deleted file mode 100644 index f04e7c6bac..0000000000 --- a/net/node_test.go +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright 2023 Democratized Data Foundation -// -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. - -package net - -import ( - "context" - "testing" - - "github.com/libp2p/go-libp2p/core/peer" - badger "github.com/sourcenetwork/badger/v4" - "github.com/stretchr/testify/require" - - "github.com/sourcenetwork/defradb/acp" - "github.com/sourcenetwork/defradb/client" - badgerds "github.com/sourcenetwork/defradb/datastore/badger/v4" - "github.com/sourcenetwork/defradb/datastore/memory" - "github.com/sourcenetwork/defradb/internal/db" - netutils "github.com/sourcenetwork/defradb/net/utils" -) - -// Node.Boostrap is not tested because the underlying, *ipfslite.Peer.Bootstrap is a best-effort function. - -func FixtureNewMemoryDBWithBroadcaster(t *testing.T) client.DB { - var database client.DB - ctx := context.Background() - opts := badgerds.Options{Options: badger.DefaultOptions("").WithInMemory(true)} - rootstore, err := badgerds.NewDatastore("", &opts) - require.NoError(t, err) - database, err = db.NewDB(ctx, rootstore, acp.NoACP, nil) - require.NoError(t, err) - return database -} - -func TestNewNode_WithEnableRelay_NoError(t *testing.T) { - ctx := context.Background() - store := memory.NewDatastore(ctx) - db, err := db.NewDB(ctx, store, acp.NoACP, nil) - require.NoError(t, err) - n, err := NewNode( - context.Background(), - db, - WithEnableRelay(true), - ) - require.NoError(t, err) - defer n.Close() -} - -func TestNewNode_WithDBClosed_NoError(t *testing.T) { - ctx := context.Background() - store := memory.NewDatastore(ctx) - - db, err := db.NewDB(ctx, store, acp.NoACP, nil) - require.NoError(t, err) - db.Close() - - _, err = NewNode( - context.Background(), - db, - ) - require.ErrorContains(t, err, "datastore closed") -} - -func TestNewNode_NoPubSub_NoError(t *testing.T) { - ctx := context.Background() - store := memory.NewDatastore(ctx) - db, err := db.NewDB(ctx, store, acp.NoACP, nil) - require.NoError(t, err) - n, err := NewNode( - context.Background(), - db, - WithEnablePubSub(false), - ) - require.NoError(t, err) - defer n.Close() - require.Nil(t, n.ps) -} - -func TestNewNode_WithEnablePubSub_NoError(t *testing.T) { - ctx := context.Background() - store := memory.NewDatastore(ctx) - db, err := db.NewDB(ctx, store, acp.NoACP, nil) - require.NoError(t, err) - - n, err := NewNode( - ctx, - db, - WithEnablePubSub(true), - ) - - require.NoError(t, err) - defer n.Close() - // overly simple check of validity of pubsub, avoiding the process of creating a PubSub - require.NotNil(t, n.ps) -} - -func TestNodeClose_NoError(t *testing.T) { - ctx := context.Background() - store := memory.NewDatastore(ctx) - db, err := db.NewDB(ctx, store, acp.NoACP, nil) - require.NoError(t, err) - n, err := NewNode( - context.Background(), - db, - ) - require.NoError(t, err) - n.Close() -} - -func TestNewNode_BootstrapWithNoPeer_NoError(t *testing.T) { - ctx := context.Background() - store := memory.NewDatastore(ctx) - db, err := db.NewDB(ctx, store, acp.NoACP, nil) - require.NoError(t, err) - - n1, err := NewNode( - ctx, - db, - WithListenAddresses("/ip4/0.0.0.0/tcp/0"), - ) - require.NoError(t, err) - defer n1.Close() - n1.Bootstrap([]peer.AddrInfo{}) -} - -func TestNewNode_BootstrapWithOnePeer_NoError(t *testing.T) { - ctx := context.Background() - store := memory.NewDatastore(ctx) - db, err := db.NewDB(ctx, store, acp.NoACP, nil) - require.NoError(t, err) - - n1, err := NewNode( - ctx, - db, - WithListenAddresses("/ip4/0.0.0.0/tcp/0"), - ) - require.NoError(t, err) - defer n1.Close() - n2, err := NewNode( - ctx, - db, - WithListenAddresses("/ip4/0.0.0.0/tcp/0"), - ) - require.NoError(t, err) - defer n2.Close() - addrs, err := netutils.ParsePeers([]string{n1.host.Addrs()[0].String() + "/p2p/" + n1.PeerID().String()}) - if err != nil { - t.Fatal(err) - } - n2.Bootstrap(addrs) -} - -func TestNewNode_BootstrapWithOneValidPeerAndManyInvalidPeers_NoError(t *testing.T) { - ctx := context.Background() - store := memory.NewDatastore(ctx) - db, err := db.NewDB(ctx, store, acp.NoACP, nil) - require.NoError(t, err) - - n1, err := NewNode( - ctx, - db, - WithListenAddresses("/ip4/0.0.0.0/tcp/0"), - ) - require.NoError(t, err) - defer n1.Close() - n2, err := NewNode( - ctx, - db, - WithListenAddresses("/ip4/0.0.0.0/tcp/0"), - ) - require.NoError(t, err) - defer n2.Close() - addrs, err := netutils.ParsePeers([]string{ - n1.host.Addrs()[0].String() + "/p2p/" + n1.PeerID().String(), - "/ip4/0.0.0.0/tcp/1234/p2p/" + "12D3KooWC8YY6Tx3uAeHsdBmoy7PJPwqXAHE4HkCZ5veankKWci6", - "/ip4/0.0.0.0/tcp/1235/p2p/" + "12D3KooWC8YY6Tx3uAeHsdBmoy7PJPwqXAHE4HkCZ5veankKWci5", - "/ip4/0.0.0.0/tcp/1236/p2p/" + "12D3KooWC8YY6Tx3uAeHsdBmoy7PJPwqXAHE4HkCZ5veankKWci4", - }) - require.NoError(t, err) - n2.Bootstrap(addrs) -} - -func TestListenAddrs_WithListenAddresses_NoError(t *testing.T) { - ctx := context.Background() - store := memory.NewDatastore(ctx) - db, err := db.NewDB(ctx, store, acp.NoACP, nil) - require.NoError(t, err) - n, err := NewNode( - context.Background(), - db, - WithListenAddresses("/ip4/0.0.0.0/tcp/0"), - ) - require.NoError(t, err) - defer n.Close() - - require.Contains(t, n.ListenAddrs()[0].String(), "/tcp/") -} diff --git a/net/peer.go b/net/peer.go index adb749de70..00ea8653a0 100644 --- a/net/peer.go +++ b/net/peer.go @@ -14,40 +14,53 @@ package net import ( "context" + "fmt" "sync" + "sync/atomic" "time" "github.com/ipfs/boxo/bitswap" "github.com/ipfs/boxo/bitswap/network" "github.com/ipfs/boxo/blockservice" exchange "github.com/ipfs/boxo/exchange" + "github.com/ipfs/boxo/ipns" "github.com/ipfs/go-cid" ds "github.com/ipfs/go-datastore" + libp2p "github.com/libp2p/go-libp2p" gostream "github.com/libp2p/go-libp2p-gostream" + dht "github.com/libp2p/go-libp2p-kad-dht" + dualdht "github.com/libp2p/go-libp2p-kad-dht/dual" pubsub "github.com/libp2p/go-libp2p-pubsub" + record "github.com/libp2p/go-libp2p-record" + libp2pCrypto "github.com/libp2p/go-libp2p/core/crypto" + libp2pEvent "github.com/libp2p/go-libp2p/core/event" "github.com/libp2p/go-libp2p/core/host" "github.com/libp2p/go-libp2p/core/peer" - peerstore "github.com/libp2p/go-libp2p/core/peerstore" "github.com/libp2p/go-libp2p/core/routing" + + // @TODO: https://github.com/sourcenetwork/defradb/issues/1902 + //nolint:staticcheck + "github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoreds" + "github.com/libp2p/go-libp2p/p2p/net/connmgr" + "github.com/multiformats/go-multiaddr" "github.com/sourcenetwork/corelog" "google.golang.org/grpc" "github.com/sourcenetwork/defradb/client" + "github.com/sourcenetwork/defradb/crypto" "github.com/sourcenetwork/defradb/datastore" "github.com/sourcenetwork/defradb/errors" "github.com/sourcenetwork/defradb/event" - "github.com/sourcenetwork/defradb/internal/core" corenet "github.com/sourcenetwork/defradb/internal/core/net" - "github.com/sourcenetwork/defradb/internal/merkle/clock" pb "github.com/sourcenetwork/defradb/net/pb" ) // Peer is a DefraDB Peer node which exposes all the LibP2P host/peer functionality // to the underlying DefraDB instance. type Peer struct { - //config?? + blockstore datastore.Blockstore - db client.DB + bus *event.Bus updateSub *event.Subscription host host.Host @@ -57,50 +70,156 @@ type Peer struct { server *server p2pRPC *grpc.Server // rpc server over the P2P network - // replicators is a map from collectionName => peerId - replicators map[string]map[peer.ID]struct{} - mu sync.Mutex - // peer DAG service exch exchange.Interface bserv blockservice.BlockService - ctx context.Context - cancel context.CancelFunc + ctx context.Context + cancel context.CancelFunc + dhtClose func() error } // NewPeer creates a new instance of the DefraDB server as a peer-to-peer node. func NewPeer( ctx context.Context, - db client.DB, - h host.Host, - dht routing.Routing, - ps *pubsub.PubSub, - serverOptions []grpc.ServerOption, - dialOptions []grpc.DialOption, -) (*Peer, error) { - if db == nil { + rootstore datastore.Rootstore, + blockstore datastore.Blockstore, + bus *event.Bus, + opts ...NodeOpt, +) (p *Peer, err error) { + if rootstore == nil || blockstore == nil { return nil, ErrNilDB } + options := DefaultOptions() + for _, opt := range opts { + opt(options) + } + + connManager, err := connmgr.NewConnManager(100, 400, connmgr.WithGracePeriod(time.Second*20)) + if err != nil { + return nil, err + } + + var listenAddresses []multiaddr.Multiaddr + for _, addr := range options.ListenAddresses { + listenAddress, err := multiaddr.NewMultiaddr(addr) + if err != nil { + return nil, err + } + listenAddresses = append(listenAddresses, listenAddress) + } + ctx, cancel := context.WithCancel(ctx) - p := &Peer{ - host: h, - dht: dht, - ps: ps, - db: db, - p2pRPC: grpc.NewServer(serverOptions...), - ctx: ctx, - cancel: cancel, - replicators: make(map[string]map[peer.ID]struct{}), - } - var err error - p.server, err = newServer(p, dialOptions...) + defer func() { + if p == nil { + cancel() + } + }() + + peerstore, err := pstoreds.NewPeerstore(ctx, rootstore, pstoreds.DefaultOpts()) if err != nil { return nil, err } - err = p.loadReplicators(p.ctx) + if options.PrivateKey == nil { + // generate an ephemeral private key + key, err := crypto.GenerateEd25519() + if err != nil { + return nil, err + } + options.PrivateKey = key + } + + // unmarshal the private key bytes + privateKey, err := libp2pCrypto.UnmarshalEd25519PrivateKey(options.PrivateKey) + if err != nil { + return nil, err + } + + var ddht *dualdht.DHT + + libp2pOpts := []libp2p.Option{ + libp2p.ConnectionManager(connManager), + libp2p.DefaultTransports, + libp2p.Identity(privateKey), + libp2p.ListenAddrs(listenAddresses...), + libp2p.Peerstore(peerstore), + libp2p.Routing(func(h host.Host) (routing.PeerRouting, error) { + // Delete this line and uncomment the next 6 lines once we remove batchable datastore support. + // var store ds.Batching + // // If `rootstore` doesn't implement `Batching`, `nil` will be passed + // // to newDHT which will cause the DHT to be stored in memory. + // if dsb, isBatching := rootstore.(ds.Batching); isBatching { + // store = dsb + // } + ddht, err = newDHT(ctx, h, rootstore) + return ddht, err + }), + } + if !options.EnableRelay { + libp2pOpts = append(libp2pOpts, libp2p.DisableRelay()) + } + + h, err := libp2p.New(libp2pOpts...) + if err != nil { + return nil, err + } + log.InfoContext( + ctx, + "Created LibP2P host", + corelog.Any("PeerId", h.ID()), + corelog.Any("Address", options.ListenAddresses), + ) + + var ps *pubsub.PubSub + if options.EnablePubSub { + ps, err = pubsub.NewGossipSub( + ctx, + h, + pubsub.WithPeerExchange(true), + pubsub.WithFloodPublish(true), + ) + if err != nil { + return nil, err + } + } + + if err != nil { + return nil, err + } + + sub, err := h.EventBus().Subscribe(&libp2pEvent.EvtPeerConnectednessChanged{}) + if err != nil { + return nil, err + } + // publish subscribed events to the event bus + go func() { + for { + select { + case <-ctx.Done(): + return + case val, isOpen := <-sub.Out(): + if !isOpen { + return + } + bus.Publish(event.NewMessage(event.PeerName, val)) + } + } + }() + + p = &Peer{ + host: h, + dht: ddht, + ps: ps, + blockstore: blockstore, + bus: bus, + p2pRPC: grpc.NewServer(options.GRPCServerOptions...), + ctx: ctx, + cancel: cancel, + } + + p.server, err = newServer(p, options.GRPCDialOptions...) if err != nil { return nil, err } @@ -112,9 +231,6 @@ func NewPeer( // Start all the internal workers/goroutines/loops that manage the P2P state. func (p *Peer) Start() error { - p.mu.Lock() - defer p.mu.Unlock() - // reconnect to known peers var wg sync.WaitGroup for _, id := range p.host.Peerstore().PeersWithAddrs() { @@ -142,13 +258,13 @@ func (p *Peer) Start() error { } if p.ps != nil { - sub, err := p.db.Events().Subscribe(event.UpdateName) + sub, err := p.bus.Subscribe(event.UpdateName, event.P2PTopicName, event.ReplicatorName) if err != nil { return err } p.updateSub = sub log.InfoContext(p.ctx, "Starting internal broadcaster for pubsub network") - go p.handleBroadcastLoop() + go p.handleMessageLoop() } log.InfoContext( @@ -164,6 +280,8 @@ func (p *Peer) Start() error { } }() + p.bus.Publish(event.NewMessage(event.PeerInfoName, event.PeerInfo{Info: p.PeerInfo()})) + return nil } @@ -180,10 +298,9 @@ func (p *Peer) Close() { log.ErrorContextE(p.ctx, "Failed closing server RPC connections", err) } } - stopGRPCServer(p.ctx, p.p2pRPC) if p.updateSub != nil { - p.db.Events().Unsubscribe(p.updateSub) + p.bus.Unsubscribe(p.updateSub) } if err := p.bserv.Close(); err != nil { @@ -194,31 +311,50 @@ func (p *Peer) Close() { log.ErrorContextE(p.ctx, "Error closing host", err) } - p.cancel() + if p.dhtClose != nil { + err := p.dhtClose() + if err != nil { + log.ErrorContextE(p.ctx, "Failed to close DHT", err) + } + } + + stopGRPCServer(p.ctx, p.p2pRPC) + + if p.cancel != nil { + p.cancel() + } } -// handleBroadcast loop manages the transition of messages +// handleMessage loop manages the transition of messages // from the internal broadcaster to the external pubsub network -func (p *Peer) handleBroadcastLoop() { +func (p *Peer) handleMessageLoop() { for { msg, isOpen := <-p.updateSub.Message() if !isOpen { return } - update, ok := msg.Data.(event.Update) - if !ok { - continue // ignore invalid value - } - var err error - if update.IsCreate { - err = p.handleDocCreateLog(update) - } else { - err = p.handleDocUpdateLog(update) - } + switch evt := msg.Data.(type) { + case event.Update: + var err error + if evt.IsCreate { + err = p.handleDocCreateLog(evt) + } else { + err = p.handleDocUpdateLog(evt) + } - if err != nil { - log.ErrorContextE(p.ctx, "Error while handling broadcast log", err) + if err != nil { + log.ErrorContextE(p.ctx, "Error while handling broadcast log", err) + } + + case event.P2PTopic: + p.server.updatePubSubTopics(evt) + + case event.Replicator: + p.server.updateReplicators(evt) + default: + // ignore other events + continue } } } @@ -258,112 +394,6 @@ func (p *Peer) RegisterNewDocument( return p.server.publishLog(p.ctx, schemaRoot, req) } -func (p *Peer) pushToReplicator( - ctx context.Context, - txn datastore.Txn, - collection client.Collection, - docIDsCh <-chan client.DocIDResult, - pid peer.ID, -) { - for docIDResult := range docIDsCh { - if docIDResult.Err != nil { - log.ErrorContextE(ctx, "Key channel error", docIDResult.Err) - continue - } - docID := core.DataStoreKeyFromDocID(docIDResult.ID) - headset := clock.NewHeadSet( - txn.Headstore(), - docID.WithFieldId(core.COMPOSITE_NAMESPACE).ToHeadStoreKey(), - ) - cids, _, err := headset.List(ctx) - if err != nil { - log.ErrorContextE( - ctx, - "Failed to get heads", - err, - corelog.String("DocID", docIDResult.ID.String()), - corelog.Any("PeerID", pid), - corelog.Any("Collection", collection.Name())) - continue - } - // loop over heads, get block, make the required logs, and send - for _, c := range cids { - blk, err := txn.DAGstore().Get(ctx, c) - if err != nil { - log.ErrorContextE(ctx, "Failed to get block", err, - corelog.Any("CID", c), - corelog.Any("PeerID", pid), - corelog.Any("Collection", collection.Name())) - continue - } - - evt := event.Update{ - DocID: docIDResult.ID.String(), - Cid: c, - SchemaRoot: collection.SchemaRoot(), - Block: blk.RawData(), - } - if err := p.server.pushLog(ctx, evt, pid); err != nil { - log.ErrorContextE( - ctx, - "Failed to replicate log", - err, - corelog.Any("CID", c), - corelog.Any("PeerID", pid), - ) - } - } - } -} - -func (p *Peer) loadReplicators(ctx context.Context) error { - reps, err := p.GetAllReplicators(ctx) - if err != nil { - return errors.Wrap("failed to get replicators", err) - } - p.mu.Lock() - defer p.mu.Unlock() - for _, rep := range reps { - for _, schema := range rep.Schemas { - if pReps, exists := p.replicators[schema]; exists { - if _, exists := pReps[rep.Info.ID]; exists { - continue - } - } else { - p.replicators[schema] = make(map[peer.ID]struct{}) - } - - // add to replicators list - p.replicators[schema][rep.Info.ID] = struct{}{} - } - - // Add the destination's peer multiaddress in the peerstore. - // This will be used during connection and stream creation by libp2p. - p.host.Peerstore().AddAddrs(rep.Info.ID, rep.Info.Addrs, peerstore.PermanentAddrTTL) - - log.InfoContext(ctx, "loaded replicators from datastore", corelog.Any("Replicator", rep)) - } - - return nil -} - -func (p *Peer) loadP2PCollections(ctx context.Context) (map[string]struct{}, error) { - collections, err := p.GetAllP2PCollections(ctx) - if err != nil && !errors.Is(err, ds.ErrNotFound) { - return nil, err - } - colMap := make(map[string]struct{}) - for _, col := range collections { - err := p.server.addPubSubTopic(col, true) - if err != nil { - return nil, err - } - colMap[col] = struct{}{} - } - - return colMap, nil -} - func (p *Peer) handleDocCreateLog(evt event.Update) error { docID, err := client.NewDocIDFromString(evt.DocID) if err != nil { @@ -425,9 +455,9 @@ func (p *Peer) pushLogToReplicators(lg event.Update) { peers[peer.String()] = struct{}{} } - p.mu.Lock() - reps, exists := p.replicators[lg.SchemaRoot] - p.mu.Unlock() + p.server.mu.Lock() + reps, exists := p.server.replicators[lg.SchemaRoot] + p.server.mu.Unlock() if exists { for pid := range reps { @@ -453,8 +483,8 @@ func (p *Peer) pushLogToReplicators(lg event.Update) { func (p *Peer) setupBlockService() { bswapnet := network.NewFromIpfsHost(p.host, p.dht) - bswap := bitswap.New(p.ctx, bswapnet, p.db.Blockstore()) - p.bserv = blockservice.New(p.db.Blockstore(), bswap) + bswap := bitswap.New(p.ctx, bswapnet, p.blockstore) + p.bserv = blockservice.New(p.blockstore, bswap) p.exch = bswap } @@ -474,22 +504,63 @@ func stopGRPCServer(ctx context.Context, server *grpc.Server) { } } -// rollbackAddPubSubTopics removes the given topics from the pubsub system. -func (p *Peer) rollbackAddPubSubTopics(topics []string, cause error) error { - for _, topic := range topics { - if err := p.server.removePubSubTopic(topic); err != nil { - return errors.WithStack(err, errors.NewKV("Cause", cause)) - } +// Bootstrap connects to the given peers. +func (p *Peer) Bootstrap(addrs []peer.AddrInfo) { + var connected uint64 + + var wg sync.WaitGroup + for _, pinfo := range addrs { + wg.Add(1) + go func(pinfo peer.AddrInfo) { + defer wg.Done() + err := p.host.Connect(p.ctx, pinfo) + if err != nil { + log.InfoContext(p.ctx, "Cannot connect to peer", corelog.Any("Error", err)) + return + } + log.InfoContext(p.ctx, "Connected", corelog.Any("PeerID", pinfo.ID)) + atomic.AddUint64(&connected, 1) + }(pinfo) + } + + wg.Wait() + + if nPeers := len(addrs); int(connected) < nPeers/2 { + log.InfoContext(p.ctx, fmt.Sprintf("Only connected to %d bootstrap peers out of %d", connected, nPeers)) + } + + err := p.dht.Bootstrap(p.ctx) + if err != nil { + log.ErrorContextE(p.ctx, "Problem bootstraping using DHT", err) + return } - return cause } -// rollbackRemovePubSubTopics adds back the given topics from the pubsub system. -func (p *Peer) rollbackRemovePubSubTopics(topics []string, cause error) error { - for _, topic := range topics { - if err := p.server.addPubSubTopic(topic, true); err != nil { - return errors.WithStack(err, errors.NewKV("Cause", cause)) - } +func (p *Peer) PeerID() peer.ID { + return p.host.ID() +} + +func (p *Peer) ListenAddrs() []multiaddr.Multiaddr { + return p.host.Network().ListenAddresses() +} + +func (p *Peer) PeerInfo() peer.AddrInfo { + return peer.AddrInfo{ + ID: p.host.ID(), + Addrs: p.host.Network().ListenAddresses(), + } +} + +func newDHT(ctx context.Context, h host.Host, dsb ds.Batching) (*dualdht.DHT, error) { + dhtOpts := []dualdht.Option{ + dualdht.DHTOption(dht.NamespacedValidator("pk", record.PublicKeyValidator{})), + dualdht.DHTOption(dht.NamespacedValidator("ipns", ipns.Validator{KeyBook: h.Peerstore()})), + dualdht.DHTOption(dht.Concurrency(10)), + dualdht.DHTOption(dht.Mode(dht.ModeAuto)), } - return cause + if dsb != nil { + dhtOpts = append(dhtOpts, dualdht.DHTOption(dht.Datastore(dsb))) + } + + return dualdht.New(ctx, h, dhtOpts...) } diff --git a/net/peer_replicator.go b/net/peer_replicator.go deleted file mode 100644 index 19accb17c4..0000000000 --- a/net/peer_replicator.go +++ /dev/null @@ -1,230 +0,0 @@ -// Copyright 2023 Democratized Data Foundation -// -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. - -package net - -import ( - "context" - "encoding/json" - - dsq "github.com/ipfs/go-datastore/query" - "github.com/libp2p/go-libp2p/core/peer" - "github.com/libp2p/go-libp2p/core/peerstore" - - "github.com/sourcenetwork/defradb/client" - "github.com/sourcenetwork/defradb/internal/core" - "github.com/sourcenetwork/defradb/internal/db" -) - -func (p *Peer) SetReplicator(ctx context.Context, rep client.Replicator) error { - p.mu.Lock() - defer p.mu.Unlock() - - txn, err := p.db.NewTxn(ctx, false) - if err != nil { - return err - } - defer txn.Discard(ctx) - - if rep.Info.ID == p.host.ID() { - return ErrSelfTargetForReplicator - } - if err := rep.Info.ID.Validate(); err != nil { - return err - } - - // TODO-ACP: Support ACP <> P2P - https://github.com/sourcenetwork/defradb/issues/2366 - // ctx = db.SetContextIdentity(ctx, identity) - ctx = db.SetContextTxn(ctx, txn) - - var collections []client.Collection - switch { - case len(rep.Schemas) > 0: - // if specific collections are chosen get them by name - for _, name := range rep.Schemas { - col, err := p.db.GetCollectionByName(ctx, name) - if err != nil { - return NewErrReplicatorCollections(err) - } - - if col.Description().Policy.HasValue() { - return ErrReplicatorColHasPolicy - } - - collections = append(collections, col) - } - - default: - // default to all collections (unless a collection contains a policy). - // TODO-ACP: default to all collections after resolving https://github.com/sourcenetwork/defradb/issues/2366 - allCollections, err := p.db.GetCollections(ctx, client.CollectionFetchOptions{}) - if err != nil { - return NewErrReplicatorCollections(err) - } - - for _, col := range allCollections { - // Can not default to all collections if any collection has a policy. - // TODO-ACP: remove this check/loop after https://github.com/sourcenetwork/defradb/issues/2366 - if col.Description().Policy.HasValue() { - return ErrReplicatorSomeColsHavePolicy - } - } - collections = allCollections - } - rep.Schemas = nil - - // Add the destination's peer multiaddress in the peerstore. - // This will be used during connection and stream creation by libp2p. - p.host.Peerstore().AddAddrs(rep.Info.ID, rep.Info.Addrs, peerstore.PermanentAddrTTL) - - var added []client.Collection - for _, col := range collections { - reps, exists := p.replicators[col.SchemaRoot()] - if !exists { - p.replicators[col.SchemaRoot()] = make(map[peer.ID]struct{}) - } - if _, exists := reps[rep.Info.ID]; !exists { - // keep track of newly added collections so we don't - // push logs to a replicator peer multiple times. - p.replicators[col.SchemaRoot()][rep.Info.ID] = struct{}{} - added = append(added, col) - } - rep.Schemas = append(rep.Schemas, col.SchemaRoot()) - } - - // persist replicator to the datastore - repBytes, err := json.Marshal(rep) - if err != nil { - return err - } - key := core.NewReplicatorKey(rep.Info.ID.String()) - err = txn.Systemstore().Put(ctx, key.ToDS(), repBytes) - if err != nil { - return err - } - - // push all collection documents to the replicator peer - for _, col := range added { - keysCh, err := col.GetAllDocIDs(ctx) - if err != nil { - return NewErrReplicatorDocID(err, col.Name().Value(), rep.Info.ID) - } - p.pushToReplicator(ctx, txn, col, keysCh, rep.Info.ID) - } - - return txn.Commit(ctx) -} - -func (p *Peer) DeleteReplicator(ctx context.Context, rep client.Replicator) error { - p.mu.Lock() - defer p.mu.Unlock() - - txn, err := p.db.NewTxn(ctx, false) - if err != nil { - return err - } - defer txn.Discard(ctx) - - if rep.Info.ID == p.host.ID() { - return ErrSelfTargetForReplicator - } - if err := rep.Info.ID.Validate(); err != nil { - return err - } - - // set transaction for all operations - ctx = db.SetContextTxn(ctx, txn) - - var collections []client.Collection - switch { - case len(rep.Schemas) > 0: - // if specific collections are chosen get them by name - for _, name := range rep.Schemas { - col, err := p.db.GetCollectionByName(ctx, name) - if err != nil { - return NewErrReplicatorCollections(err) - } - collections = append(collections, col) - } - // make sure the replicator exists in the datastore - key := core.NewReplicatorKey(rep.Info.ID.String()) - _, err = txn.Systemstore().Get(ctx, key.ToDS()) - if err != nil { - return err - } - - default: - // default to all collections - collections, err = p.db.GetCollections(ctx, client.CollectionFetchOptions{}) - if err != nil { - return NewErrReplicatorCollections(err) - } - } - rep.Schemas = nil - - schemaMap := make(map[string]struct{}) - for _, col := range collections { - schemaMap[col.SchemaRoot()] = struct{}{} - } - - // update replicators and add remaining schemas to rep - for key, val := range p.replicators { - if _, exists := val[rep.Info.ID]; exists { - if _, toDelete := schemaMap[key]; toDelete { - delete(p.replicators[key], rep.Info.ID) - } else { - rep.Schemas = append(rep.Schemas, key) - } - } - } - - if len(rep.Schemas) == 0 { - // Remove the destination's peer multiaddress in the peerstore. - p.host.Peerstore().ClearAddrs(rep.Info.ID) - } - - // persist the replicator to the store, deleting it if no schemas remain - key := core.NewReplicatorKey(rep.Info.ID.String()) - if len(rep.Schemas) == 0 { - return txn.Systemstore().Delete(ctx, key.ToDS()) - } - repBytes, err := json.Marshal(rep) - if err != nil { - return err - } - return txn.Systemstore().Put(ctx, key.ToDS(), repBytes) -} - -func (p *Peer) GetAllReplicators(ctx context.Context) ([]client.Replicator, error) { - txn, err := p.db.NewTxn(ctx, true) - if err != nil { - return nil, err - } - defer txn.Discard(ctx) - - // create collection system prefix query - query := dsq.Query{ - Prefix: core.NewReplicatorKey("").ToString(), - } - results, err := txn.Systemstore().Query(ctx, query) - if err != nil { - return nil, err - } - - var reps []client.Replicator - for result := range results.Next() { - var rep client.Replicator - if err = json.Unmarshal(result.Value, &rep); err != nil { - return nil, err - } - reps = append(reps, rep) - } - return reps, nil -} diff --git a/net/peer_test.go b/net/peer_test.go index 6f6fda67ad..cb8c8eab44 100644 --- a/net/peer_test.go +++ b/net/peer_test.go @@ -12,25 +12,20 @@ package net import ( "context" - "encoding/hex" - "fmt" "testing" "time" - "github.com/decred/dcrd/dcrec/secp256k1/v4" "github.com/ipfs/go-cid" - ds "github.com/ipfs/go-datastore" - libp2p "github.com/libp2p/go-libp2p" - pubsub "github.com/libp2p/go-libp2p-pubsub" "github.com/libp2p/go-libp2p/core/peer" mh "github.com/multiformats/go-multihash" + badger "github.com/sourcenetwork/badger/v4" rpc "github.com/sourcenetwork/go-libp2p-pubsub-rpc" "github.com/sourcenetwork/immutable" "github.com/stretchr/testify/require" "github.com/sourcenetwork/defradb/acp" - acpIdentity "github.com/sourcenetwork/defradb/acp/identity" "github.com/sourcenetwork/defradb/client" + badgerds "github.com/sourcenetwork/defradb/datastore/badger/v4" "github.com/sourcenetwork/defradb/datastore/memory" "github.com/sourcenetwork/defradb/event" coreblock "github.com/sourcenetwork/defradb/internal/core/block" @@ -71,16 +66,18 @@ func createCID(doc *client.Document) (cid.Cid, error) { const randomMultiaddr = "/ip4/127.0.0.1/tcp/0" -func newTestNode(ctx context.Context, t *testing.T) (client.DB, *Node) { +func newTestPeer(ctx context.Context, t *testing.T) (client.DB, *Peer) { store := memory.NewDatastore(ctx) acpLocal := acp.NewLocalACP() acpLocal.Init(context.Background(), "") db, err := db.NewDB(ctx, store, immutable.Some[acp.ACP](acpLocal), nil) require.NoError(t, err) - n, err := NewNode( + n, err := NewPeer( ctx, - db, + db.Rootstore(), + db.Blockstore(), + db.Events(), WithListenAddresses(randomMultiaddr), ) require.NoError(t, err) @@ -93,72 +90,26 @@ func TestNewPeer_NoError(t *testing.T) { store := memory.NewDatastore(ctx) db, err := db.NewDB(ctx, store, acp.NoACP, nil) require.NoError(t, err) - - h, err := libp2p.New() - require.NoError(t, err) - - _, err = NewPeer(ctx, db, h, nil, nil, nil, nil) + defer db.Close() + p, err := NewPeer(ctx, db.Rootstore(), db.Blockstore(), db.Events()) require.NoError(t, err) + p.Close() } func TestNewPeer_NoDB_NilDBError(t *testing.T) { ctx := context.Background() - - h, err := libp2p.New() - require.NoError(t, err) - - _, err = NewPeer(ctx, nil, h, nil, nil, nil, nil) + _, err := NewPeer(ctx, nil, nil, nil) require.ErrorIs(t, err, ErrNilDB) } -func TestNewPeer_WithExistingTopic_TopicAlreadyExistsError(t *testing.T) { - ctx := context.Background() - store := memory.NewDatastore(ctx) - db, err := db.NewDB(ctx, store, acp.NoACP, nil) - require.NoError(t, err) - - _, err = db.AddSchema(ctx, `type User { - name: String - age: Int - }`) - require.NoError(t, err) - - col, err := db.GetCollectionByName(ctx, "User") - require.NoError(t, err) - - doc, err := client.NewDocFromJSON([]byte(`{"name": "John", "age": 30}`), col.Definition()) - require.NoError(t, err) - - err = col.Create(ctx, doc) - require.NoError(t, err) - - h, err := libp2p.New() - require.NoError(t, err) - - ps, err := pubsub.NewGossipSub( - ctx, - h, - pubsub.WithPeerExchange(true), - pubsub.WithFloodPublish(true), - ) - require.NoError(t, err) - - _, err = rpc.NewTopic(ctx, ps, h.ID(), doc.ID().String(), true) - require.NoError(t, err) - - _, err = NewPeer(ctx, db, h, nil, ps, nil, nil) - require.ErrorContains(t, err, "topic already exists") -} - func TestStartAndClose_NoError(t *testing.T) { ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() + db, p := newTestPeer(ctx, t) + defer db.Close() + defer p.Close() - err := n.Start() + err := p.Start() require.NoError(t, err) - - db.Close() } func TestStart_WithKnownPeer_NoError(t *testing.T) { @@ -166,23 +117,31 @@ func TestStart_WithKnownPeer_NoError(t *testing.T) { store := memory.NewDatastore(ctx) db1, err := db.NewDB(ctx, store, acp.NoACP, nil) require.NoError(t, err) + defer db1.Close() store2 := memory.NewDatastore(ctx) db2, err := db.NewDB(ctx, store2, acp.NoACP, nil) require.NoError(t, err) + defer db2.Close() - n1, err := NewNode( + n1, err := NewPeer( ctx, - db1, + db1.Rootstore(), + db1.Blockstore(), + db1.Events(), WithListenAddresses("/ip4/0.0.0.0/tcp/0"), ) require.NoError(t, err) - n2, err := NewNode( + defer n1.Close() + n2, err := NewPeer( ctx, - db2, + db2.Rootstore(), + db2.Blockstore(), + db2.Events(), WithListenAddresses("/ip4/0.0.0.0/tcp/0"), ) require.NoError(t, err) + defer n2.Close() addrs, err := netutils.ParsePeers([]string{n1.host.Addrs()[0].String() + "/p2p/" + n1.PeerID().String()}) if err != nil { @@ -192,9 +151,6 @@ func TestStart_WithKnownPeer_NoError(t *testing.T) { err = n2.Start() require.NoError(t, err) - - db1.Close() - db2.Close() } func TestStart_WithOfflineKnownPeer_NoError(t *testing.T) { @@ -202,23 +158,31 @@ func TestStart_WithOfflineKnownPeer_NoError(t *testing.T) { store := memory.NewDatastore(ctx) db1, err := db.NewDB(ctx, store, acp.NoACP, nil) require.NoError(t, err) + defer db1.Close() store2 := memory.NewDatastore(ctx) db2, err := db.NewDB(ctx, store2, acp.NoACP, nil) require.NoError(t, err) + defer db2.Close() - n1, err := NewNode( + n1, err := NewPeer( ctx, - db1, + db1.Rootstore(), + db1.Blockstore(), + db1.Events(), WithListenAddresses("/ip4/0.0.0.0/tcp/0"), ) require.NoError(t, err) - n2, err := NewNode( + defer n1.Close() + n2, err := NewPeer( ctx, - db2, + db2.Rootstore(), + db2.Blockstore(), + db2.Events(), WithListenAddresses("/ip4/0.0.0.0/tcp/0"), ) require.NoError(t, err) + defer n2.Close() addrs, err := netutils.ParsePeers([]string{n1.host.Addrs()[0].String() + "/p2p/" + n1.PeerID().String()}) if err != nil { @@ -232,15 +196,13 @@ func TestStart_WithOfflineKnownPeer_NoError(t *testing.T) { err = n2.Start() require.NoError(t, err) - - db1.Close() - db2.Close() } func TestRegisterNewDocument_NoError(t *testing.T) { ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() + db, p := newTestPeer(ctx, t) + defer db.Close() + defer p.Close() _, err := db.AddSchema(ctx, `type User { name: String @@ -257,14 +219,15 @@ func TestRegisterNewDocument_NoError(t *testing.T) { cid, err := createCID(doc) require.NoError(t, err) - err = n.RegisterNewDocument(ctx, doc.ID(), cid, emptyBlock(), col.SchemaRoot()) + err = p.RegisterNewDocument(ctx, doc.ID(), cid, emptyBlock(), col.SchemaRoot()) require.NoError(t, err) } func TestRegisterNewDocument_RPCTopicAlreadyRegisteredError(t *testing.T) { ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() + db, p := newTestPeer(ctx, t) + defer db.Close() + defer p.Close() _, err := db.AddSchema(ctx, `type User { name: String @@ -278,228 +241,22 @@ func TestRegisterNewDocument_RPCTopicAlreadyRegisteredError(t *testing.T) { doc, err := client.NewDocFromJSON([]byte(`{"name": "John", "age": 30}`), col.Definition()) require.NoError(t, err) - _, err = rpc.NewTopic(ctx, n.Peer.ps, n.Peer.host.ID(), doc.ID().String(), true) + _, err = rpc.NewTopic(ctx, p.ps, p.host.ID(), doc.ID().String(), true) require.NoError(t, err) cid, err := createCID(doc) require.NoError(t, err) - err = n.RegisterNewDocument(ctx, doc.ID(), cid, emptyBlock(), col.SchemaRoot()) + err = p.RegisterNewDocument(ctx, doc.ID(), cid, emptyBlock(), col.SchemaRoot()) require.Equal(t, err.Error(), "creating topic: joining topic: topic already exists") } -func TestSetReplicator_NoError(t *testing.T) { - ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() - - _, err := db.AddSchema(ctx, `type User { - name: String - age: Int - }`) - require.NoError(t, err) - - info, err := peer.AddrInfoFromString("/ip4/0.0.0.0/tcp/0/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N") - require.NoError(t, err) - - err = n.Peer.SetReplicator(ctx, client.Replicator{ - Info: *info, - Schemas: []string{"User"}, - }) - require.NoError(t, err) -} - -// This test documents that we don't allow setting replicator with a collection that has a policy -// until the following is implemented: -// TODO-ACP: ACP <> P2P https://github.com/sourcenetwork/defradb/issues/2366 -func TestSetReplicatorWithACollectionSpecifiedThatHasPolicy_ReturnError(t *testing.T) { - ctx := context.Background() - d, n := newTestNode(ctx, t) - defer n.Close() - - policy := ` - name: test - description: a policy - actor: - name: actor - resources: - user: - permissions: - read: - expr: owner - write: - expr: owner - relations: - owner: - types: - - actor - ` - - privKeyBytes, err := hex.DecodeString("028d53f37a19afb9a0dbc5b4be30c65731479ee8cfa0c9bc8f8bf198cc3c075f") - require.NoError(t, err) - privKey := secp256k1.PrivKeyFromBytes(privKeyBytes) - identity, err := acpIdentity.FromPrivateKey(privKey) - require.NoError(t, err) - - ctx = db.SetContextIdentity(ctx, identity) - policyResult, err := d.AddPolicy(ctx, policy) - policyID := policyResult.PolicyID - require.NoError(t, err) - require.Equal(t, "7b5ed30570e8d9206027ef6d5469879a6c1ea4595625c6ca33a19063a6ed6214", policyID) - - schema := fmt.Sprintf(` - type User @policy(id: "%s", resource: "user") { - name: String - age: Int - } - `, policyID, - ) - _, err = d.AddSchema(ctx, schema) - require.NoError(t, err) - - info, err := peer.AddrInfoFromString("/ip4/0.0.0.0/tcp/0/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N") - require.NoError(t, err) - - err = n.Peer.SetReplicator(ctx, client.Replicator{ - Info: *info, - Schemas: []string{"User"}, - }) - require.Error(t, err) - require.ErrorIs(t, err, ErrReplicatorColHasPolicy) -} - -// This test documents that we don't allow setting replicator using default option when any collection has a policy -// until the following is implemented: -// TODO-ACP: ACP <> P2P https://github.com/sourcenetwork/defradb/issues/2366 -func TestSetReplicatorWithSomeCollectionThatHasPolicyUsingAllCollectionsByDefault_ReturnError(t *testing.T) { - ctx := context.Background() - d, n := newTestNode(ctx, t) - defer n.Close() - - policy := ` - name: test - description: a policy - actor: - name: actor - resources: - user: - permissions: - read: - expr: owner - write: - expr: owner - relations: - owner: - types: - - actor - ` - - privKeyBytes, err := hex.DecodeString("028d53f37a19afb9a0dbc5b4be30c65731479ee8cfa0c9bc8f8bf198cc3c075f") - require.NoError(t, err) - privKey := secp256k1.PrivKeyFromBytes(privKeyBytes) - identity, err := acpIdentity.FromPrivateKey(privKey) - require.NoError(t, err) - - ctx = db.SetContextIdentity(ctx, identity) - policyResult, err := d.AddPolicy(ctx, policy) - policyID := policyResult.PolicyID - require.NoError(t, err) - require.Equal(t, "7b5ed30570e8d9206027ef6d5469879a6c1ea4595625c6ca33a19063a6ed6214", policyID) - - schema := fmt.Sprintf(` - type User @policy(id: "%s", resource: "user") { - name: String - age: Int - } - `, policyID, - ) - _, err = d.AddSchema(ctx, schema) - require.NoError(t, err) - - info, err := peer.AddrInfoFromString("/ip4/0.0.0.0/tcp/0/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N") - require.NoError(t, err) - - err = n.Peer.SetReplicator(ctx, client.Replicator{ - Info: *info, - // Note: The missing explicit input of schemas here - }) - require.ErrorIs(t, err, ErrReplicatorSomeColsHavePolicy) -} - -func TestSetReplicator_WithInvalidAddress_EmptyPeerIDError(t *testing.T) { - ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() - - _, err := db.AddSchema(ctx, `type User { - name: String - age: Int - }`) - require.NoError(t, err) - - err = n.Peer.SetReplicator(ctx, client.Replicator{ - Info: peer.AddrInfo{}, - Schemas: []string{"User"}, - }) - require.ErrorContains(t, err, "empty peer ID") -} - -func TestSetReplicator_WithDBClosed_DatastoreClosedError(t *testing.T) { - ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() - - db.Close() - - info, err := peer.AddrInfoFromString("/ip4/0.0.0.0/tcp/0/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N") - require.NoError(t, err) - - err = n.Peer.SetReplicator(ctx, client.Replicator{ - Info: *info, - Schemas: []string{"User"}, - }) - require.ErrorContains(t, err, "datastore closed") -} - -func TestSetReplicator_WithUndefinedCollection_KeyNotFoundError(t *testing.T) { - ctx := context.Background() - _, n := newTestNode(ctx, t) - defer n.Close() - - info, err := peer.AddrInfoFromString("/ip4/0.0.0.0/tcp/0/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N") - require.NoError(t, err) - - err = n.Peer.SetReplicator(ctx, client.Replicator{ - Info: *info, - Schemas: []string{"User"}, - }) - require.ErrorContains(t, err, "failed to get collections for replicator: datastore: key not found") -} - -func TestSetReplicator_ForAllCollections_NoError(t *testing.T) { +func TestHandleDocCreateLog_NoError(t *testing.T) { ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() - - _, err := db.AddSchema(ctx, `type User { - name: String - age: Int - }`) - require.NoError(t, err) - - info, err := peer.AddrInfoFromString("/ip4/0.0.0.0/tcp/0/p2p/QmYyQSo1c1Ym7orWxLYvCrM2EmxFTANf8wXmmE7DWjhx5N") - require.NoError(t, err) - - err = n.Peer.SetReplicator(ctx, client.Replicator{ - Info: *info, - }) - require.NoError(t, err) -} + db, p := newTestPeer(ctx, t) + defer db.Close() + defer p.Close() -func TestPushToReplicator_SingleDocumentNoPeer_FailedToReplicateLogError(t *testing.T) { - ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() _, err := db.AddSchema(ctx, `type User { name: String age: Int @@ -515,313 +272,38 @@ func TestPushToReplicator_SingleDocumentNoPeer_FailedToReplicateLogError(t *test err = col.Create(ctx, doc) require.NoError(t, err) - keysCh, err := col.GetAllDocIDs(ctx) - require.NoError(t, err) - - txn, err := db.NewTxn(ctx, true) - require.NoError(t, err) - - n.pushToReplicator(ctx, txn, col, keysCh, n.PeerID()) -} - -func TestDeleteReplicator_WithDBClosed_DataStoreClosedError(t *testing.T) { - ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() - - info := peer.AddrInfo{ - ID: n.PeerID(), - Addrs: n.ListenAddrs(), - } - - db.Close() - - err := n.Peer.DeleteReplicator(ctx, client.Replicator{ - Info: info, - Schemas: []string{"User"}, - }) - require.ErrorContains(t, err, "datastore closed") -} - -func TestDeleteReplicator_WithTargetSelf_SelfTargetForReplicatorError(t *testing.T) { - ctx := context.Background() - _, n := newTestNode(ctx, t) - defer n.Close() - - err := n.Peer.DeleteReplicator(ctx, client.Replicator{ - Info: n.PeerInfo(), - Schemas: []string{"User"}, - }) - require.ErrorIs(t, err, ErrSelfTargetForReplicator) -} - -func TestDeleteReplicator_WithInvalidCollection_KeyNotFoundError(t *testing.T) { - ctx := context.Background() - _, n := newTestNode(ctx, t) - defer n.Close() - - _, n2 := newTestNode(ctx, t) - defer n2.Close() - - err := n.Peer.DeleteReplicator(ctx, client.Replicator{ - Info: n2.PeerInfo(), - Schemas: []string{"User"}, - }) - require.ErrorContains(t, err, "failed to get collections for replicator: datastore: key not found") -} - -func TestDeleteReplicator_WithCollectionAndPreviouslySetReplicator_NoError(t *testing.T) { - ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() - - _, err := db.AddSchema(ctx, `type User { - name: String - age: Int - }`) - require.NoError(t, err) - - _, n2 := newTestNode(ctx, t) - defer n2.Close() - - err = n.Peer.SetReplicator(ctx, client.Replicator{ - Info: n2.PeerInfo(), - }) - require.NoError(t, err) - - err = n.Peer.DeleteReplicator(ctx, client.Replicator{ - Info: n2.PeerInfo(), - }) - require.NoError(t, err) -} - -func TestDeleteReplicator_WithNoCollection_NoError(t *testing.T) { - ctx := context.Background() - _, n := newTestNode(ctx, t) - defer n.Close() - - _, n2 := newTestNode(ctx, t) - defer n2.Close() - - err := n.Peer.DeleteReplicator(ctx, client.Replicator{ - Info: n2.PeerInfo(), - }) - require.NoError(t, err) -} - -func TestDeleteReplicator_WithNotSetReplicator_KeyNotFoundError(t *testing.T) { - ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() - - _, err := db.AddSchema(ctx, `type User { - name: String - age: Int - }`) - require.NoError(t, err) - - _, n2 := newTestNode(ctx, t) - defer n2.Close() - - err = n.Peer.DeleteReplicator(ctx, client.Replicator{ - Info: n2.PeerInfo(), - Schemas: []string{"User"}, - }) - require.ErrorContains(t, err, "datastore: key not found") -} - -func TestGetAllReplicator_WithReplicator_NoError(t *testing.T) { - ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() - - _, err := db.AddSchema(ctx, `type User { - name: String - age: Int - }`) - require.NoError(t, err) - - _, n2 := newTestNode(ctx, t) - defer n2.Close() - - err = n.Peer.SetReplicator(ctx, client.Replicator{ - Info: n2.PeerInfo(), - }) - require.NoError(t, err) - - reps, err := n.Peer.GetAllReplicators(ctx) + headCID, err := getHead(ctx, db, doc.ID()) require.NoError(t, err) - require.Len(t, reps, 1) - require.Equal(t, n2.PeerInfo().ID, reps[0].Info.ID) -} - -func TestGetAllReplicator_WithDBClosed_DatastoreClosedError(t *testing.T) { - ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() - - db.Close() - - _, err := n.Peer.GetAllReplicators(ctx) - require.ErrorContains(t, err, "datastore closed") -} - -func TestLoadReplicators_WithDBClosed_DatastoreClosedError(t *testing.T) { - ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() - - db.Close() - - err := n.Peer.loadReplicators(ctx) - require.ErrorContains(t, err, "datastore closed") -} - -func TestLoadReplicator_WithReplicator_NoError(t *testing.T) { - ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() - - _, err := db.AddSchema(ctx, `type User { - name: String - age: Int - }`) + b, err := db.Blockstore().AsIPLDStorage().Get(ctx, headCID.KeyString()) require.NoError(t, err) - _, n2 := newTestNode(ctx, t) - defer n2.Close() - - err = n.Peer.SetReplicator(ctx, client.Replicator{ - Info: n2.PeerInfo(), + err = p.handleDocCreateLog(event.Update{ + DocID: doc.ID().String(), + Cid: headCID, + SchemaRoot: col.SchemaRoot(), + Block: b, }) require.NoError(t, err) - - err = n.Peer.loadReplicators(ctx) - require.NoError(t, err) } -func TestLoadReplicator_WithReplicatorAndEmptyReplicatorMap_NoError(t *testing.T) { +func TestHandleDocCreateLog_WithInvalidDocID_NoError(t *testing.T) { ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() + db, p := newTestPeer(ctx, t) + defer db.Close() + defer p.Close() - _, err := db.AddSchema(ctx, `type User { - name: String - age: Int - }`) - require.NoError(t, err) - - _, n2 := newTestNode(ctx, t) - defer n2.Close() - - err = n.Peer.SetReplicator(ctx, client.Replicator{ - Info: n2.PeerInfo(), + err := p.handleDocCreateLog(event.Update{ + DocID: "some-invalid-key", }) - require.NoError(t, err) - - n.replicators = make(map[string]map[peer.ID]struct{}) - - err = n.Peer.loadReplicators(ctx) - require.NoError(t, err) -} - -func TestAddP2PCollections_WithInvalidCollectionID_NotFoundError(t *testing.T) { - ctx := context.Background() - _, n := newTestNode(ctx, t) - defer n.Close() - - err := n.Peer.AddP2PCollections(ctx, []string{"invalid_collection"}) - require.Error(t, err, ds.ErrNotFound) -} - -// This test documents that we don't allow adding p2p collections that have a policy -// until the following is implemented: -// TODO-ACP: ACP <> P2P https://github.com/sourcenetwork/defradb/issues/2366 -func TestAddP2PCollectionsWithPermissionedCollection_Error(t *testing.T) { - ctx := context.Background() - d, n := newTestNode(ctx, t) - defer n.Close() - - policy := ` - name: test - description: a policy - actor: - name: actor - resources: - user: - permissions: - read: - expr: owner - write: - expr: owner - relations: - owner: - types: - - actor - ` - - privKeyBytes, err := hex.DecodeString("028d53f37a19afb9a0dbc5b4be30c65731479ee8cfa0c9bc8f8bf198cc3c075f") - require.NoError(t, err) - privKey := secp256k1.PrivKeyFromBytes(privKeyBytes) - identity, err := acpIdentity.FromPrivateKey(privKey) - require.NoError(t, err) - - ctx = db.SetContextIdentity(ctx, identity) - policyResult, err := d.AddPolicy(ctx, policy) - policyID := policyResult.PolicyID - require.NoError(t, err) - require.Equal(t, "7b5ed30570e8d9206027ef6d5469879a6c1ea4595625c6ca33a19063a6ed6214", policyID) - - schema := fmt.Sprintf(` - type User @policy(id: "%s", resource: "user") { - name: String - age: Int - } - `, policyID, - ) - _, err = d.AddSchema(ctx, schema) - require.NoError(t, err) - - col, err := d.GetCollectionByName(ctx, "User") - require.NoError(t, err) - - err = n.Peer.AddP2PCollections(ctx, []string{col.SchemaRoot()}) - require.Error(t, err) - require.ErrorIs(t, err, ErrP2PColHasPolicy) -} - -func TestAddP2PCollections_NoError(t *testing.T) { - ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() - - _, err := db.AddSchema(ctx, `type User { - name: String - age: Int - }`) - require.NoError(t, err) - - col, err := db.GetCollectionByName(ctx, "User") - require.NoError(t, err) - - err = n.Peer.AddP2PCollections(ctx, []string{col.SchemaRoot()}) - require.NoError(t, err) -} - -func TestRemoveP2PCollectionsWithInvalidCollectionID(t *testing.T) { - ctx := context.Background() - _, n := newTestNode(ctx, t) - defer n.Close() - - err := n.Peer.RemoveP2PCollections(ctx, []string{"invalid_collection"}) - require.Error(t, err, ds.ErrNotFound) + require.ErrorContains(t, err, "failed to get DocID from broadcast message: selected encoding not supported") } -func TestRemoveP2PCollections(t *testing.T) { +func TestHandleDocCreateLog_WithExistingTopic_TopicExistsError(t *testing.T) { ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() + db, p := newTestPeer(ctx, t) + defer db.Close() + defer p.Close() _, err := db.AddSchema(ctx, `type User { name: String @@ -832,46 +314,27 @@ func TestRemoveP2PCollections(t *testing.T) { col, err := db.GetCollectionByName(ctx, "User") require.NoError(t, err) - err = n.Peer.RemoveP2PCollections(ctx, []string{col.SchemaRoot()}) - require.NoError(t, err) -} - -func TestGetAllP2PCollectionsWithNoCollections(t *testing.T) { - ctx := context.Background() - _, n := newTestNode(ctx, t) - defer n.Close() - - cols, err := n.Peer.GetAllP2PCollections(ctx) - require.NoError(t, err) - require.Len(t, cols, 0) -} - -func TestGetAllP2PCollections(t *testing.T) { - ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() - - _, err := db.AddSchema(ctx, `type User { - name: String - age: Int - }`) + doc, err := client.NewDocFromJSON([]byte(`{"name": "John", "age": 30}`), col.Definition()) require.NoError(t, err) - col, err := db.GetCollectionByName(ctx, "User") + err = col.Create(ctx, doc) require.NoError(t, err) - err = n.Peer.AddP2PCollections(ctx, []string{col.SchemaRoot()}) + _, err = rpc.NewTopic(ctx, p.ps, p.host.ID(), doc.ID().String(), true) require.NoError(t, err) - cols, err := n.Peer.GetAllP2PCollections(ctx) - require.NoError(t, err) - require.ElementsMatch(t, []string{col.SchemaRoot()}, cols) + err = p.handleDocCreateLog(event.Update{ + DocID: doc.ID().String(), + SchemaRoot: col.SchemaRoot(), + }) + require.ErrorContains(t, err, "topic already exists") } -func TestHandleDocCreateLog_NoError(t *testing.T) { +func TestHandleDocUpdateLog_NoError(t *testing.T) { ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() + db, p := newTestPeer(ctx, t) + defer db.Close() + defer p.Close() _, err := db.AddSchema(ctx, `type User { name: String @@ -894,7 +357,7 @@ func TestHandleDocCreateLog_NoError(t *testing.T) { b, err := db.Blockstore().AsIPLDStorage().Get(ctx, headCID.KeyString()) require.NoError(t, err) - err = n.handleDocCreateLog(event.Update{ + err = p.handleDocUpdateLog(event.Update{ DocID: doc.ID().String(), Cid: headCID, SchemaRoot: col.SchemaRoot(), @@ -903,21 +366,23 @@ func TestHandleDocCreateLog_NoError(t *testing.T) { require.NoError(t, err) } -func TestHandleDocCreateLog_WithInvalidDocID_NoError(t *testing.T) { +func TestHandleDoUpdateLog_WithInvalidDocID_NoError(t *testing.T) { ctx := context.Background() - _, n := newTestNode(ctx, t) - defer n.Close() + db, p := newTestPeer(ctx, t) + defer db.Close() + defer p.Close() - err := n.handleDocCreateLog(event.Update{ + err := p.handleDocUpdateLog(event.Update{ DocID: "some-invalid-key", }) require.ErrorContains(t, err, "failed to get DocID from broadcast message: selected encoding not supported") } -func TestHandleDocCreateLog_WithExistingTopic_TopicExistsError(t *testing.T) { +func TestHandleDocUpdateLog_WithExistingDocIDTopic_TopicExistsError(t *testing.T) { ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() + db, p := newTestPeer(ctx, t) + defer db.Close() + defer p.Close() _, err := db.AddSchema(ctx, `type User { name: String @@ -934,20 +399,29 @@ func TestHandleDocCreateLog_WithExistingTopic_TopicExistsError(t *testing.T) { err = col.Create(ctx, doc) require.NoError(t, err) - _, err = rpc.NewTopic(ctx, n.ps, n.host.ID(), doc.ID().String(), true) + headCID, err := getHead(ctx, db, doc.ID()) + require.NoError(t, err) + + b, err := db.Blockstore().AsIPLDStorage().Get(ctx, headCID.KeyString()) + require.NoError(t, err) + + _, err = rpc.NewTopic(ctx, p.ps, p.host.ID(), doc.ID().String(), true) require.NoError(t, err) - err = n.handleDocCreateLog(event.Update{ + err = p.handleDocUpdateLog(event.Update{ DocID: doc.ID().String(), + Cid: headCID, SchemaRoot: col.SchemaRoot(), + Block: b, }) require.ErrorContains(t, err, "topic already exists") } -func TestHandleDocUpdateLog_NoError(t *testing.T) { +func TestHandleDocUpdateLog_WithExistingSchemaTopic_TopicExistsError(t *testing.T) { ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() + db, p := newTestPeer(ctx, t) + defer db.Close() + defer p.Close() _, err := db.AddSchema(ctx, `type User { name: String @@ -970,98 +444,219 @@ func TestHandleDocUpdateLog_NoError(t *testing.T) { b, err := db.Blockstore().AsIPLDStorage().Get(ctx, headCID.KeyString()) require.NoError(t, err) - err = n.handleDocUpdateLog(event.Update{ + _, err = rpc.NewTopic(ctx, p.ps, p.host.ID(), col.SchemaRoot(), true) + require.NoError(t, err) + + err = p.handleDocUpdateLog(event.Update{ DocID: doc.ID().String(), Cid: headCID, SchemaRoot: col.SchemaRoot(), Block: b, }) - require.NoError(t, err) + require.ErrorContains(t, err, "topic already exists") } -func TestHandleDoUpdateLog_WithInvalidDocID_NoError(t *testing.T) { +func FixtureNewMemoryDBWithBroadcaster(t *testing.T) client.DB { + var database client.DB ctx := context.Background() - _, n := newTestNode(ctx, t) - defer n.Close() + opts := badgerds.Options{Options: badger.DefaultOptions("").WithInMemory(true)} + rootstore, err := badgerds.NewDatastore("", &opts) + require.NoError(t, err) + database, err = db.NewDB(ctx, rootstore, acp.NoACP, nil) + require.NoError(t, err) + return database +} - err := n.handleDocUpdateLog(event.Update{ - DocID: "some-invalid-key", - }) - require.ErrorContains(t, err, "failed to get DocID from broadcast message: selected encoding not supported") +func TestNewPeer_WithEnableRelay_NoError(t *testing.T) { + ctx := context.Background() + store := memory.NewDatastore(ctx) + db, err := db.NewDB(ctx, store, acp.NoACP, nil) + require.NoError(t, err) + defer db.Close() + n, err := NewPeer( + context.Background(), + db.Rootstore(), + db.Blockstore(), + db.Events(), + WithEnableRelay(true), + ) + require.NoError(t, err) + n.Close() } -func TestHandleDocUpdateLog_WithExistingDocIDTopic_TopicExistsError(t *testing.T) { +func TestNewPeer_WithDBClosed_NoError(t *testing.T) { ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() + store := memory.NewDatastore(ctx) - _, err := db.AddSchema(ctx, `type User { - name: String - age: Int - }`) + db, err := db.NewDB(ctx, store, acp.NoACP, nil) require.NoError(t, err) + db.Close() - col, err := db.GetCollectionByName(ctx, "User") - require.NoError(t, err) + _, err = NewPeer( + context.Background(), + db.Rootstore(), + db.Blockstore(), + db.Events(), + ) + require.ErrorContains(t, err, "datastore closed") +} - doc, err := client.NewDocFromJSON([]byte(`{"name": "John", "age": 30}`), col.Definition()) +func TestNewPeer_NoPubSub_NoError(t *testing.T) { + ctx := context.Background() + store := memory.NewDatastore(ctx) + db, err := db.NewDB(ctx, store, acp.NoACP, nil) require.NoError(t, err) + defer db.Close() - err = col.Create(ctx, doc) + n, err := NewPeer( + context.Background(), + db.Rootstore(), + db.Blockstore(), + db.Events(), + WithEnablePubSub(false), + ) require.NoError(t, err) + require.Nil(t, n.ps) + n.Close() +} - headCID, err := getHead(ctx, db, doc.ID()) +func TestNewPeer_WithEnablePubSub_NoError(t *testing.T) { + ctx := context.Background() + store := memory.NewDatastore(ctx) + db, err := db.NewDB(ctx, store, acp.NoACP, nil) require.NoError(t, err) + defer db.Close() - b, err := db.Blockstore().AsIPLDStorage().Get(ctx, headCID.KeyString()) - require.NoError(t, err) + n, err := NewPeer( + ctx, + db.Rootstore(), + db.Blockstore(), + db.Events(), + WithEnablePubSub(true), + ) - _, err = rpc.NewTopic(ctx, n.ps, n.host.ID(), doc.ID().String(), true) require.NoError(t, err) - - err = n.handleDocUpdateLog(event.Update{ - DocID: doc.ID().String(), - Cid: headCID, - SchemaRoot: col.SchemaRoot(), - Block: b, - }) - require.ErrorContains(t, err, "topic already exists") + // overly simple check of validity of pubsub, avoiding the process of creating a PubSub + require.NotNil(t, n.ps) + n.Close() } -func TestHandleDocUpdateLog_WithExistingSchemaTopic_TopicExistsError(t *testing.T) { +func TestNodeClose_NoError(t *testing.T) { ctx := context.Background() - db, n := newTestNode(ctx, t) - defer n.Close() - - _, err := db.AddSchema(ctx, `type User { - name: String - age: Int - }`) + store := memory.NewDatastore(ctx) + db, err := db.NewDB(ctx, store, acp.NoACP, nil) require.NoError(t, err) + defer db.Close() + n, err := NewPeer( + context.Background(), + db.Rootstore(), + db.Blockstore(), + db.Events(), + ) + require.NoError(t, err) + n.Close() +} - col, err := db.GetCollectionByName(ctx, "User") +func TestNewPeer_BootstrapWithNoPeer_NoError(t *testing.T) { + ctx := context.Background() + store := memory.NewDatastore(ctx) + db, err := db.NewDB(ctx, store, acp.NoACP, nil) require.NoError(t, err) + defer db.Close() - doc, err := client.NewDocFromJSON([]byte(`{"name": "John", "age": 30}`), col.Definition()) + n1, err := NewPeer( + ctx, + db.Rootstore(), + db.Blockstore(), + db.Events(), + WithListenAddresses("/ip4/0.0.0.0/tcp/0"), + ) require.NoError(t, err) + n1.Bootstrap([]peer.AddrInfo{}) + n1.Close() +} - err = col.Create(ctx, doc) +func TestNewPeer_BootstrapWithOnePeer_NoError(t *testing.T) { + ctx := context.Background() + store := memory.NewDatastore(ctx) + db, err := db.NewDB(ctx, store, acp.NoACP, nil) + require.NoError(t, err) + defer db.Close() + n1, err := NewPeer( + ctx, + db.Rootstore(), + db.Blockstore(), + db.Events(), + WithListenAddresses("/ip4/0.0.0.0/tcp/0"), + ) require.NoError(t, err) + defer n1.Close() + n2, err := NewPeer( + ctx, + db.Rootstore(), + db.Blockstore(), + db.Events(), + WithListenAddresses("/ip4/0.0.0.0/tcp/0"), + ) + require.NoError(t, err) + defer n2.Close() + addrs, err := netutils.ParsePeers([]string{n1.host.Addrs()[0].String() + "/p2p/" + n1.PeerID().String()}) + if err != nil { + t.Fatal(err) + } + n2.Bootstrap(addrs) +} - headCID, err := getHead(ctx, db, doc.ID()) +func TestNewPeer_BootstrapWithOneValidPeerAndManyInvalidPeers_NoError(t *testing.T) { + ctx := context.Background() + store := memory.NewDatastore(ctx) + db, err := db.NewDB(ctx, store, acp.NoACP, nil) require.NoError(t, err) + defer db.Close() - b, err := db.Blockstore().AsIPLDStorage().Get(ctx, headCID.KeyString()) + n1, err := NewPeer( + ctx, + db.Rootstore(), + db.Blockstore(), + db.Events(), + WithListenAddresses("/ip4/0.0.0.0/tcp/0"), + ) + require.NoError(t, err) + defer n1.Close() + n2, err := NewPeer( + ctx, + db.Rootstore(), + db.Blockstore(), + db.Events(), + WithListenAddresses("/ip4/0.0.0.0/tcp/0"), + ) require.NoError(t, err) + defer n2.Close() + addrs, err := netutils.ParsePeers([]string{ + n1.host.Addrs()[0].String() + "/p2p/" + n1.PeerID().String(), + "/ip4/0.0.0.0/tcp/1234/p2p/" + "12D3KooWC8YY6Tx3uAeHsdBmoy7PJPwqXAHE4HkCZ5veankKWci6", + "/ip4/0.0.0.0/tcp/1235/p2p/" + "12D3KooWC8YY6Tx3uAeHsdBmoy7PJPwqXAHE4HkCZ5veankKWci5", + "/ip4/0.0.0.0/tcp/1236/p2p/" + "12D3KooWC8YY6Tx3uAeHsdBmoy7PJPwqXAHE4HkCZ5veankKWci4", + }) + require.NoError(t, err) + n2.Bootstrap(addrs) +} - _, err = rpc.NewTopic(ctx, n.ps, n.host.ID(), col.SchemaRoot(), true) +func TestListenAddrs_WithListenAddresses_NoError(t *testing.T) { + ctx := context.Background() + store := memory.NewDatastore(ctx) + db, err := db.NewDB(ctx, store, acp.NoACP, nil) require.NoError(t, err) + defer db.Close() - err = n.handleDocUpdateLog(event.Update{ - DocID: doc.ID().String(), - Cid: headCID, - SchemaRoot: col.SchemaRoot(), - Block: b, - }) - require.ErrorContains(t, err, "topic already exists") + n, err := NewPeer( + context.Background(), + db.Rootstore(), + db.Blockstore(), + db.Events(), + WithListenAddresses("/ip4/0.0.0.0/tcp/0"), + ) + require.NoError(t, err) + require.Contains(t, n.ListenAddrs()[0].String(), "/tcp/") + n.Close() } diff --git a/net/server.go b/net/server.go index 413f391064..3b4922fe5e 100644 --- a/net/server.go +++ b/net/server.go @@ -18,7 +18,9 @@ import ( "sync" cid "github.com/ipfs/go-cid" + "github.com/libp2p/go-libp2p/core/peer" libpeer "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" "github.com/sourcenetwork/corelog" rpc "github.com/sourcenetwork/go-libp2p-pubsub-rpc" "google.golang.org/grpc" @@ -43,7 +45,9 @@ type server struct { opts []grpc.DialOption topics map[string]pubsubTopic - mu sync.Mutex + // replicators is a map from collectionName => peerId + replicators map[string]map[peer.ID]struct{} + mu sync.Mutex conns map[libpeer.ID]*grpc.ClientConn @@ -61,9 +65,10 @@ type pubsubTopic struct { // underlying DB instance. func newServer(p *Peer, opts ...grpc.DialOption) (*server, error) { s := &server{ - peer: p, - conns: make(map[libpeer.ID]*grpc.ClientConn), - topics: make(map[string]pubsubTopic), + peer: p, + conns: make(map[libpeer.ID]*grpc.ClientConn), + topics: make(map[string]pubsubTopic), + replicators: make(map[string]map[peer.ID]struct{}), } cred := insecure.NewCredentials() @@ -73,38 +78,6 @@ func newServer(p *Peer, opts ...grpc.DialOption) (*server, error) { } s.opts = append(defaultOpts, opts...) - if s.peer.ps != nil { - colMap, err := p.loadP2PCollections(p.ctx) - if err != nil { - return nil, err - } - - // Get all DocIDs across all collections in the DB - cols, err := s.peer.db.GetCollections(s.peer.ctx, client.CollectionFetchOptions{}) - if err != nil { - return nil, err - } - - i := 0 - for _, col := range cols { - // If we subscribed to the collection, we skip subscribing to the collection's docIDs. - if _, ok := colMap[col.SchemaRoot()]; ok { - continue - } - // TODO-ACP: Support ACP <> P2P - https://github.com/sourcenetwork/defradb/issues/2366 - docIDChan, err := col.GetAllDocIDs(p.ctx) - if err != nil { - return nil, err - } - - for docID := range docIDChan { - if err := s.addPubSubTopic(docID.ID.String(), true); err != nil { - return nil, err - } - i++ - } - } - } return s, nil } @@ -157,7 +130,7 @@ func (s *server) PushLog(ctx context.Context, req *pb.PushLogRequest) (*pb.PushL return nil, err } - s.peer.db.Events().Publish(event.NewMessage(event.MergeName, event.Merge{ + s.peer.bus.Publish(event.NewMessage(event.MergeName, event.Merge{ DocID: docID.String(), ByPeer: byPeer, FromPeer: pid, @@ -313,7 +286,7 @@ func (s *server) pubSubEventHandler(from libpeer.ID, topic string, msg []byte) { evt := event.NewMessage(event.PubSubName, event.PubSub{ Peer: from, }) - s.peer.db.Events().Publish(evt) + s.peer.bus.Publish(evt) } // addr implements net.Addr and holds a libp2p peer ID. @@ -337,3 +310,64 @@ func peerIDFromContext(ctx context.Context) (libpeer.ID, error) { } return pid, nil } + +func (s *server) updatePubSubTopics(evt event.P2PTopic) { + for _, topic := range evt.ToAdd { + err := s.addPubSubTopic(topic, true) + if err != nil { + log.ErrorContextE(s.peer.ctx, "Failed to add pubsub topic.", err) + } + } + + for _, topic := range evt.ToRemove { + err := s.removePubSubTopic(topic) + if err != nil { + log.ErrorContextE(s.peer.ctx, "Failed to remove pubsub topic.", err) + } + } + s.peer.bus.Publish(event.NewMessage(event.P2PTopicCompletedName, nil)) +} + +func (s *server) updateReplicators(evt event.Replicator) { + isDeleteRep := len(evt.Schemas) == 0 + // update the cached replicators + s.mu.Lock() + for schema, peers := range s.replicators { + if _, hasSchema := evt.Schemas[schema]; hasSchema { + s.replicators[schema][evt.Info.ID] = struct{}{} + delete(evt.Schemas, schema) + } else { + if _, exists := peers[evt.Info.ID]; exists { + delete(s.replicators[schema], evt.Info.ID) + } + } + } + for schema := range evt.Schemas { + if _, exists := s.replicators[schema]; !exists { + s.replicators[schema] = make(map[peer.ID]struct{}) + } + s.replicators[schema][evt.Info.ID] = struct{}{} + } + s.mu.Unlock() + + if isDeleteRep { + s.peer.host.Peerstore().ClearAddrs(evt.Info.ID) + } else { + s.peer.host.Peerstore().AddAddrs(evt.Info.ID, evt.Info.Addrs, peerstore.PermanentAddrTTL) + } + + if evt.Docs != nil { + for update := range evt.Docs { + if err := s.pushLog(s.peer.ctx, update, evt.Info.ID); err != nil { + log.ErrorContextE( + s.peer.ctx, + "Failed to replicate log", + err, + corelog.Any("CID", update.Cid), + corelog.Any("PeerID", evt.Info.ID), + ) + } + } + } + s.peer.bus.Publish(event.NewMessage(event.ReplicatorCompletedName, nil)) +} diff --git a/net/server_test.go b/net/server_test.go index d17705b404..1ac178a2d1 100644 --- a/net/server_test.go +++ b/net/server_test.go @@ -18,12 +18,10 @@ import ( "github.com/ipfs/go-datastore/query" "github.com/libp2p/go-libp2p/core/event" "github.com/libp2p/go-libp2p/core/host" - rpc "github.com/sourcenetwork/go-libp2p-pubsub-rpc" "github.com/stretchr/testify/require" grpcpeer "google.golang.org/grpc/peer" "github.com/sourcenetwork/defradb/client" - "github.com/sourcenetwork/defradb/datastore/memory" "github.com/sourcenetwork/defradb/errors" "github.com/sourcenetwork/defradb/internal/core" net_pb "github.com/sourcenetwork/defradb/net/pb" @@ -31,124 +29,15 @@ import ( func TestNewServerSimple(t *testing.T) { ctx := context.Background() - _, n := newTestNode(ctx, t) - _, err := newServer(n.Peer) + db, p := newTestPeer(ctx, t) + defer db.Close() + defer p.Close() + _, err := newServer(p) require.NoError(t, err) } -func TestNewServerWithDBClosed(t *testing.T) { - ctx := context.Background() - db, n := newTestNode(ctx, t) - db.Close() - - _, err := newServer(n.Peer) - require.ErrorIs(t, err, memory.ErrClosed) -} - var mockError = errors.New("mock error") -type mockDBColError struct { - client.DB -} - -func (mDB *mockDBColError) GetCollections(context.Context, client.CollectionFetchOptions) ([]client.Collection, error) { - return nil, mockError -} - -func TestNewServerWithGetAllCollectionError(t *testing.T) { - ctx := context.Background() - db, n := newTestNode(ctx, t) - mDB := mockDBColError{db} - n.Peer.db = &mDB - _, err := newServer(n.Peer) - require.ErrorIs(t, err, mockError) -} - -func TestNewServerWithCollectionSubscribed(t *testing.T) { - ctx := context.Background() - db, n := newTestNode(ctx, t) - - _, err := db.AddSchema(ctx, `type User { - name: String - age: Int - }`) - require.NoError(t, err) - - col, err := db.GetCollectionByName(ctx, "User") - require.NoError(t, err) - - err = n.AddP2PCollections(ctx, []string{col.SchemaRoot()}) - require.NoError(t, err) - - _, err = newServer(n.Peer) - require.NoError(t, err) -} - -type mockDBDocIDsError struct { - client.DB -} - -func (mDB *mockDBDocIDsError) GetCollections(context.Context, client.CollectionFetchOptions) ([]client.Collection, error) { - return []client.Collection{ - &mockCollection{}, - }, nil -} - -type mockCollection struct { - client.Collection -} - -func (mCol *mockCollection) SchemaRoot() string { - return "mockColID" -} -func (mCol *mockCollection) GetAllDocIDs( - ctx context.Context, -) (<-chan client.DocIDResult, error) { - return nil, mockError -} - -func TestNewServerWithGetAllDocIDsError(t *testing.T) { - ctx := context.Background() - db, n := newTestNode(ctx, t) - - _, err := db.AddSchema(ctx, `type User { - name: String - age: Int - }`) - require.NoError(t, err) - - mDB := mockDBDocIDsError{db} - n.Peer.db = &mDB - _, err = newServer(n.Peer) - require.ErrorIs(t, err, mockError) -} - -func TestNewServerWithAddTopicError(t *testing.T) { - ctx := context.Background() - db, n := newTestNode(ctx, t) - - _, err := db.AddSchema(ctx, `type User { - name: String - age: Int - }`) - require.NoError(t, err) - - col, err := db.GetCollectionByName(ctx, "User") - require.NoError(t, err) - - doc, err := client.NewDocFromJSON([]byte(`{"name": "John", "age": 30}`), col.Definition()) - require.NoError(t, err) - - err = col.Create(ctx, doc) - require.NoError(t, err) - - _, err = rpc.NewTopic(ctx, n.Peer.ps, n.Peer.host.ID(), doc.ID().String(), true) - require.NoError(t, err) - - _, err = newServer(n.Peer) - require.ErrorContains(t, err, "topic already exists") -} - type mockHost struct { host.Host } @@ -171,7 +60,9 @@ func (mB *mockBus) Subscribe(eventType any, opts ...event.SubscriptionOpt) (even func TestNewServerWithEmitterError(t *testing.T) { ctx := context.Background() - db, n := newTestNode(ctx, t) + db, p := newTestPeer(ctx, t) + defer db.Close() + defer p.Close() _, err := db.AddSchema(ctx, `type User { name: String @@ -188,40 +79,48 @@ func TestNewServerWithEmitterError(t *testing.T) { err = col.Create(ctx, doc) require.NoError(t, err) - n.Peer.host = &mockHost{n.Peer.host} + p.host = &mockHost{p.host} - _, err = newServer(n.Peer) + _, err = newServer(p) require.NoError(t, err) } func TestGetDocGraph(t *testing.T) { ctx := context.Background() - _, n := newTestNode(ctx, t) - r, err := n.server.GetDocGraph(ctx, &net_pb.GetDocGraphRequest{}) + db, p := newTestPeer(ctx, t) + defer db.Close() + defer p.Close() + r, err := p.server.GetDocGraph(ctx, &net_pb.GetDocGraphRequest{}) require.Nil(t, r) require.Nil(t, err) } func TestPushDocGraph(t *testing.T) { ctx := context.Background() - _, n := newTestNode(ctx, t) - r, err := n.server.PushDocGraph(ctx, &net_pb.PushDocGraphRequest{}) + db, p := newTestPeer(ctx, t) + defer db.Close() + defer p.Close() + r, err := p.server.PushDocGraph(ctx, &net_pb.PushDocGraphRequest{}) require.Nil(t, r) require.Nil(t, err) } func TestGetLog(t *testing.T) { ctx := context.Background() - _, n := newTestNode(ctx, t) - r, err := n.server.GetLog(ctx, &net_pb.GetLogRequest{}) + db, p := newTestPeer(ctx, t) + defer db.Close() + defer p.Close() + r, err := p.server.GetLog(ctx, &net_pb.GetLogRequest{}) require.Nil(t, r) require.Nil(t, err) } func TestGetHeadLog(t *testing.T) { ctx := context.Background() - _, n := newTestNode(ctx, t) - r, err := n.server.GetHeadLog(ctx, &net_pb.GetHeadLogRequest{}) + db, p := newTestPeer(ctx, t) + defer db.Close() + defer p.Close() + r, err := p.server.GetHeadLog(ctx, &net_pb.GetHeadLogRequest{}) require.Nil(t, r) require.Nil(t, err) } @@ -249,8 +148,10 @@ func getHead(ctx context.Context, db client.DB, docID client.DocID) (cid.Cid, er func TestPushLog(t *testing.T) { ctx := context.Background() - db, n := newTestNode(ctx, t) - err := n.Start() + db, p := newTestPeer(ctx, t) + defer db.Close() + defer p.Close() + err := p.Start() require.NoError(t, err) _, err = db.AddSchema(ctx, `type User { @@ -266,7 +167,7 @@ func TestPushLog(t *testing.T) { require.NoError(t, err) ctx = grpcpeer.NewContext(ctx, &grpcpeer.Peer{ - Addr: addr{n.PeerID()}, + Addr: addr{p.PeerID()}, }) err = col.Create(ctx, doc) @@ -278,12 +179,12 @@ func TestPushLog(t *testing.T) { b, err := db.Blockstore().AsIPLDStorage().Get(ctx, headCID.KeyString()) require.NoError(t, err) - _, err = n.server.PushLog(ctx, &net_pb.PushLogRequest{ + _, err = p.server.PushLog(ctx, &net_pb.PushLogRequest{ Body: &net_pb.PushLogRequest_Body{ DocID: []byte(doc.ID().String()), Cid: headCID.Bytes(), SchemaRoot: []byte(col.SchemaRoot()), - Creator: n.PeerID().String(), + Creator: p.PeerID().String(), Log: &net_pb.Document_Log{ Block: b, }, diff --git a/node/node.go b/node/node.go index 215cf05fc7..6dad35f593 100644 --- a/node/node.go +++ b/node/node.go @@ -77,7 +77,7 @@ func WithPeers(peers ...peer.AddrInfo) NodeOpt { // Node is a DefraDB instance with optional sub-systems. type Node struct { DB client.DB - Node *net.Node + Peer *net.Peer Server *http.Server } @@ -138,27 +138,22 @@ func NewNode(ctx context.Context, opts ...Option) (*Node, error) { return nil, err } - var node *net.Node + var peer *net.Peer if !options.disableP2P { // setup net node - node, err = net.NewNode(ctx, db, netOpts...) + peer, err = net.NewPeer(ctx, db.Rootstore(), db.Blockstore(), db.Events(), netOpts...) if err != nil { return nil, err } if len(options.peers) > 0 { - node.Bootstrap(options.peers) + peer.Bootstrap(options.peers) } } var server *http.Server if !options.disableAPI { // setup http server - var handler *http.Handler - if node != nil { - handler, err = http.NewHandler(node) - } else { - handler, err = http.NewHandler(db) - } + handler, err := http.NewHandler(db) if err != nil { return nil, err } @@ -170,15 +165,15 @@ func NewNode(ctx context.Context, opts ...Option) (*Node, error) { return &Node{ DB: db, - Node: node, + Peer: peer, Server: server, }, nil } // Start starts the node sub-systems. func (n *Node) Start(ctx context.Context) error { - if n.Node != nil { - if err := n.Node.Start(); err != nil { + if n.Peer != nil { + if err := n.Peer.Start(); err != nil { return err } } @@ -203,9 +198,10 @@ func (n *Node) Close(ctx context.Context) error { if n.Server != nil { err = n.Server.Shutdown(ctx) } - if n.Node != nil { - n.Node.Close() - } else { + if n.Peer != nil { + n.Peer.Close() + } + if n.DB != nil { n.DB.Close() } return err diff --git a/node/store.go b/node/store.go index 8354c0f7df..1a5b46f8e0 100644 --- a/node/store.go +++ b/node/store.go @@ -77,7 +77,7 @@ func WithEncryptionKey(encryptionKey []byte) StoreOpt { } // NewStore returns a new store with the given options. -func NewStore(ctx context.Context, opts ...StoreOpt) (datastore.RootStore, error) { +func NewStore(ctx context.Context, opts ...StoreOpt) (datastore.Rootstore, error) { options := DefaultStoreOptions() for _, opt := range opts { opt(options) diff --git a/tests/bench/bench_util.go b/tests/bench/bench_util.go index 5993ee50f8..a574088148 100644 --- a/tests/bench/bench_util.go +++ b/tests/bench/bench_util.go @@ -216,7 +216,7 @@ func NewTestDB(ctx context.Context, t testing.TB) (client.DB, error) { func NewTestStorage(ctx context.Context, t testing.TB) (ds.Batching, error) { dbi, err := newBenchStoreInfo(ctx, t) - return dbi.Root(), err + return dbi.Rootstore(), err } func newBenchStoreInfo(ctx context.Context, t testing.TB) (client.DB, error) { diff --git a/tests/bench/query/planner/utils.go b/tests/bench/query/planner/utils.go index b91b0aa2a3..5a842222f5 100644 --- a/tests/bench/query/planner/utils.go +++ b/tests/bench/query/planner/utils.go @@ -136,7 +136,7 @@ func (*dummyTxn) Rootstore() datastore.DSReaderWriter { return nil } func (*dummyTxn) Datastore() datastore.DSReaderWriter { return nil } func (*dummyTxn) Headstore() datastore.DSReaderWriter { return nil } func (*dummyTxn) Peerstore() datastore.DSBatching { return nil } -func (*dummyTxn) DAGstore() datastore.DAGStore { return nil } +func (*dummyTxn) Blockstore() datastore.Blockstore { return nil } func (*dummyTxn) Systemstore() datastore.DSReaderWriter { return nil } func (*dummyTxn) Commit(ctx context.Context) error { return nil } func (*dummyTxn) Discard(ctx context.Context) {} diff --git a/tests/bench/storage/utils.go b/tests/bench/storage/utils.go index 5c550f25db..c413f0bd42 100644 --- a/tests/bench/storage/utils.go +++ b/tests/bench/storage/utils.go @@ -69,7 +69,7 @@ func runStorageBenchTxnGet( if err != nil { return err } - defer db.Root().Close() //nolint:errcheck + defer db.Rootstore().Close() //nolint:errcheck keys, err := backfillBenchmarkTxn(ctx, db, objCount, valueSize) if err != nil { @@ -109,7 +109,7 @@ func runStorageBenchTxnIterator( if err != nil { return err } - defer db.Root().Close() //nolint:errcheck + defer db.Rootstore().Close() //nolint:errcheck keys, err := backfillBenchmarkTxn(ctx, db, objCount, valueSize) if err != nil { diff --git a/tests/clients/cli/wrapper.go b/tests/clients/cli/wrapper.go index 18e306c0f4..a6f3feef4c 100644 --- a/tests/clients/cli/wrapper.go +++ b/tests/clients/cli/wrapper.go @@ -31,20 +31,20 @@ import ( "github.com/sourcenetwork/defradb/datastore" "github.com/sourcenetwork/defradb/event" "github.com/sourcenetwork/defradb/http" - "github.com/sourcenetwork/defradb/net" + "github.com/sourcenetwork/defradb/node" ) -var _ client.P2P = (*Wrapper)(nil) +var _ client.DB = (*Wrapper)(nil) type Wrapper struct { - node *net.Node + node *node.Node cmd *cliWrapper handler *http.Handler httpServer *httptest.Server } -func NewWrapper(node *net.Node) (*Wrapper, error) { - handler, err := http.NewHandler(node) +func NewWrapper(node *node.Node) (*Wrapper, error) { + handler, err := http.NewHandler(node.DB) if err != nil { return nil, err } @@ -503,40 +503,40 @@ func (w *Wrapper) NewConcurrentTxn(ctx context.Context, readOnly bool) (datastor return &Transaction{tx, w.cmd}, nil } -func (w *Wrapper) Root() datastore.RootStore { - return w.node.Root() +func (w *Wrapper) Rootstore() datastore.Rootstore { + return w.node.DB.Rootstore() } -func (w *Wrapper) Blockstore() datastore.DAGStore { - return w.node.Blockstore() +func (w *Wrapper) Blockstore() datastore.Blockstore { + return w.node.DB.Blockstore() } func (w *Wrapper) Headstore() ds.Read { - return w.node.Headstore() + return w.node.DB.Headstore() } func (w *Wrapper) Peerstore() datastore.DSBatching { - return w.node.Peerstore() + return w.node.DB.Peerstore() } func (w *Wrapper) Close() { w.httpServer.CloseClientConnections() w.httpServer.Close() - w.node.Close() + _ = w.node.Close(context.Background()) } func (w *Wrapper) Events() *event.Bus { - return w.node.Events() + return w.node.DB.Events() } func (w *Wrapper) MaxTxnRetries() int { - return w.node.MaxTxnRetries() + return w.node.DB.MaxTxnRetries() } func (w *Wrapper) PrintDump(ctx context.Context) error { - return w.node.PrintDump(ctx) + return w.node.DB.PrintDump(ctx) } func (w *Wrapper) Bootstrap(addrs []peer.AddrInfo) { - w.node.Bootstrap(addrs) + w.node.Peer.Bootstrap(addrs) } diff --git a/tests/clients/cli/wrapper_tx.go b/tests/clients/cli/wrapper_tx.go index 5b5b2c3ea7..0330b8d47e 100644 --- a/tests/clients/cli/wrapper_tx.go +++ b/tests/clients/cli/wrapper_tx.go @@ -83,8 +83,8 @@ func (w *Transaction) Peerstore() datastore.DSBatching { return w.tx.Peerstore() } -func (w *Transaction) DAGstore() datastore.DAGStore { - return w.tx.DAGstore() +func (w *Transaction) Blockstore() datastore.Blockstore { + return w.tx.Blockstore() } func (w *Transaction) Systemstore() datastore.DSReaderWriter { diff --git a/tests/clients/clients.go b/tests/clients/clients.go index 249b1e767f..f5d822ab39 100644 --- a/tests/clients/clients.go +++ b/tests/clients/clients.go @@ -19,6 +19,6 @@ import ( // Client implements the P2P interface along with a few other methods // required for testing. type Client interface { - client.P2P + client.DB Bootstrap([]peer.AddrInfo) } diff --git a/tests/clients/http/wrapper.go b/tests/clients/http/wrapper.go index 89b5bce5e7..f183a4671a 100644 --- a/tests/clients/http/wrapper.go +++ b/tests/clients/http/wrapper.go @@ -24,22 +24,22 @@ import ( "github.com/sourcenetwork/defradb/datastore" "github.com/sourcenetwork/defradb/event" "github.com/sourcenetwork/defradb/http" - "github.com/sourcenetwork/defradb/net" + "github.com/sourcenetwork/defradb/node" ) -var _ client.P2P = (*Wrapper)(nil) +var _ client.DB = (*Wrapper)(nil) // Wrapper combines an HTTP client and server into a // single struct that implements the client.DB interface. type Wrapper struct { - node *net.Node + node *node.Node handler *http.Handler client *http.Client httpServer *httptest.Server } -func NewWrapper(node *net.Node) (*Wrapper, error) { - handler, err := http.NewHandler(node) +func NewWrapper(node *node.Node) (*Wrapper, error) { + handler, err := http.NewHandler(node.DB) if err != nil { return nil, err } @@ -199,40 +199,40 @@ func (w *Wrapper) NewConcurrentTxn(ctx context.Context, readOnly bool) (datastor return &TxWrapper{server, client}, nil } -func (w *Wrapper) Root() datastore.RootStore { - return w.node.Root() +func (w *Wrapper) Rootstore() datastore.Rootstore { + return w.node.DB.Rootstore() } -func (w *Wrapper) Blockstore() datastore.DAGStore { - return w.node.Blockstore() +func (w *Wrapper) Blockstore() datastore.Blockstore { + return w.node.DB.Blockstore() } func (w *Wrapper) Headstore() ds.Read { - return w.node.Headstore() + return w.node.DB.Headstore() } func (w *Wrapper) Peerstore() datastore.DSBatching { - return w.node.Peerstore() + return w.node.DB.Peerstore() } func (w *Wrapper) Close() { w.httpServer.CloseClientConnections() w.httpServer.Close() - w.node.Close() + _ = w.node.Close(context.Background()) } func (w *Wrapper) Events() *event.Bus { - return w.node.Events() + return w.node.DB.Events() } func (w *Wrapper) MaxTxnRetries() int { - return w.node.MaxTxnRetries() + return w.node.DB.MaxTxnRetries() } func (w *Wrapper) PrintDump(ctx context.Context) error { - return w.node.PrintDump(ctx) + return w.node.DB.PrintDump(ctx) } func (w *Wrapper) Bootstrap(addrs []peer.AddrInfo) { - w.node.Bootstrap(addrs) + w.node.Peer.Bootstrap(addrs) } diff --git a/tests/clients/http/wrapper_tx.go b/tests/clients/http/wrapper_tx.go index d53d967b3b..133d3bc1d3 100644 --- a/tests/clients/http/wrapper_tx.go +++ b/tests/clients/http/wrapper_tx.go @@ -77,8 +77,8 @@ func (w *TxWrapper) Peerstore() datastore.DSBatching { return w.server.Peerstore() } -func (w *TxWrapper) DAGstore() datastore.DAGStore { - return w.server.DAGstore() +func (w *TxWrapper) Blockstore() datastore.Blockstore { + return w.server.Blockstore() } func (w *TxWrapper) Systemstore() datastore.DSReaderWriter { diff --git a/tests/integration/client.go b/tests/integration/client.go index 1d06bfc744..dee5a3f0c9 100644 --- a/tests/integration/client.go +++ b/tests/integration/client.go @@ -15,7 +15,11 @@ import ( "os" "strconv" + "github.com/libp2p/go-libp2p/core/peer" + + "github.com/sourcenetwork/defradb/client" "github.com/sourcenetwork/defradb/net" + "github.com/sourcenetwork/defradb/node" "github.com/sourcenetwork/defradb/tests/clients" "github.com/sourcenetwork/defradb/tests/clients/cli" "github.com/sourcenetwork/defradb/tests/clients/http" @@ -63,7 +67,7 @@ func init() { // setupClient returns the client implementation for the current // testing state. The client type on the test state is used to // select the client implementation to use. -func setupClient(s *state, node *net.Node) (impl clients.Client, err error) { +func setupClient(s *state, node *node.Node) (impl clients.Client, err error) { switch s.clientType { case HTTPClientType: impl, err = http.NewWrapper(node) @@ -72,7 +76,7 @@ func setupClient(s *state, node *net.Node) (impl clients.Client, err error) { impl, err = cli.NewWrapper(node) case GoClientType: - impl = node + impl = newGoClientWrapper(node) default: err = fmt.Errorf("invalid client type: %v", s.dbt) @@ -83,3 +87,28 @@ func setupClient(s *state, node *net.Node) (impl clients.Client, err error) { } return } + +type goClientWrapper struct { + client.DB + peer *net.Peer +} + +func newGoClientWrapper(n *node.Node) *goClientWrapper { + return &goClientWrapper{ + DB: n.DB, + peer: n.Peer, + } +} + +func (w *goClientWrapper) Bootstrap(addrs []peer.AddrInfo) { + if w.peer != nil { + w.peer.Bootstrap(addrs) + } +} + +func (w *goClientWrapper) Close() { + if w.peer != nil { + w.peer.Close() + } + w.DB.Close() +} diff --git a/tests/integration/db.go b/tests/integration/db.go index ab15e2d5fc..dbbbed7ffb 100644 --- a/tests/integration/db.go +++ b/tests/integration/db.go @@ -97,10 +97,10 @@ func NewBadgerFileDB(ctx context.Context, t testing.TB) (client.DB, error) { return node.DB, err } -// setupDatabase returns the database implementation for the current +// setupNode returns the database implementation for the current // testing state. The database type on the test state is used to // select the datastore implementation to use. -func setupDatabase(s *state) (client.DB, string, error) { +func setupNode(s *state) (*node.Node, string, error) { opts := []node.Option{ node.WithLensPoolSize(lensPoolSize), // The test framework sets this up elsewhere when required so that it may be wrapped @@ -158,5 +158,5 @@ func setupDatabase(s *state) (client.DB, string, error) { return nil, "", err } - return node.DB, path, nil + return node, path, nil } diff --git a/tests/integration/p2p.go b/tests/integration/p2p.go index d990a3d322..4a57ac7a1a 100644 --- a/tests/integration/p2p.go +++ b/tests/integration/p2p.go @@ -288,9 +288,15 @@ func configureReplicator( sourceNode := s.nodes[cfg.SourceNodeID] targetNode := s.nodes[cfg.TargetNodeID] - err := sourceNode.SetReplicator(s.ctx, client.Replicator{ + sub, err := sourceNode.Events().Subscribe(event.ReplicatorCompletedName) + require.NoError(s.t, err) + err = sourceNode.SetReplicator(s.ctx, client.Replicator{ Info: targetNode.PeerInfo(), }) + if err == nil { + // wait for the replicator setup to complete + <-sub.Message() + } expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, cfg.ExpectedError) assertExpectedErrorRaised(s.t, s.testCase.Description, cfg.ExpectedError, expectedErrorRaised) @@ -306,9 +312,15 @@ func deleteReplicator( sourceNode := s.nodes[cfg.SourceNodeID] targetNode := s.nodes[cfg.TargetNodeID] - err := sourceNode.DeleteReplicator(s.ctx, client.Replicator{ + sub, err := sourceNode.Events().Subscribe(event.ReplicatorCompletedName) + require.NoError(s.t, err) + err = sourceNode.DeleteReplicator(s.ctx, client.Replicator{ Info: targetNode.PeerInfo(), }) + if err == nil { + // wait for the replicator setup to complete + <-sub.Message() + } require.NoError(s.t, err) } @@ -390,7 +402,15 @@ func subscribeToCollection( schemaRoots = append(schemaRoots, col.SchemaRoot()) } - err := n.AddP2PCollections(s.ctx, schemaRoots) + sub, err := n.Events().Subscribe(event.P2PTopicCompletedName) + require.NoError(s.t, err) + + err = n.AddP2PCollections(s.ctx, schemaRoots) + if err == nil { + // wait for the p2p collection setup to complete + <-sub.Message() + } + expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) @@ -420,7 +440,15 @@ func unsubscribeToCollection( schemaRoots = append(schemaRoots, col.SchemaRoot()) } - err := n.RemoveP2PCollections(s.ctx, schemaRoots) + sub, err := n.Events().Subscribe(event.P2PTopicCompletedName) + require.NoError(s.t, err) + + err = n.RemoveP2PCollections(s.ctx, schemaRoots) + if err == nil { + // wait for the p2p collection setup to complete + <-sub.Message() + } + expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) diff --git a/tests/integration/utils2.go b/tests/integration/utils2.go index 42ab28c04c..fab8cc5ed9 100644 --- a/tests/integration/utils2.go +++ b/tests/integration/utils2.go @@ -649,10 +649,10 @@ func setStartingNodes( // If nodes have not been explicitly configured via actions, setup a default one. if !hasExplicitNode { - db, path, err := setupDatabase(s) + node, path, err := setupNode(s) require.Nil(s.t, err) - c, err := setupClient(s, &net.Node{DB: db}) + c, err := setupClient(s, node) require.Nil(s.t, err) s.nodes = append(s.nodes, c) @@ -673,19 +673,35 @@ func restartNodes( for i := len(s.nodes) - 1; i >= 0; i-- { originalPath := databaseDir databaseDir = s.dbPaths[i] - db, _, err := setupDatabase(s) + node, _, err := setupNode(s) require.Nil(s.t, err) databaseDir = originalPath if len(s.nodeConfigs) == 0 { // If there are no explicit node configuration actions the node will be // basic (i.e. no P2P stuff) and can be yielded now. - c, err := setupClient(s, &net.Node{DB: db}) + c, err := setupClient(s, node) require.NoError(s.t, err) s.nodes[i] = c continue } + // We need to ensure that on restart, the node pubsub is configured before + // we continue with the test. Otherwise, we may miss update events. + readySub, err := node.DB.Events().Subscribe(event.P2PTopicCompletedName, event.ReplicatorCompletedName) + require.NoError(s.t, err) + waitLen := 0 + cols, err := node.DB.GetAllP2PCollections(s.ctx) + require.NoError(s.t, err) + if len(cols) > 0 { + // there is only one message for loading of P2P collections + waitLen++ + } + reps, err := node.DB.GetAllReplicators(s.ctx) + require.NoError(s.t, err) + // there is one message per replicator + waitLen += len(reps) + // We need to make sure the node is configured with its old address, otherwise // a new one may be selected and reconnnection to it will fail. var addresses []string @@ -696,16 +712,16 @@ func restartNodes( nodeOpts := s.nodeConfigs[i] nodeOpts = append(nodeOpts, net.WithListenAddresses(addresses...)) - var n *net.Node - n, err = net.NewNode(s.ctx, db, nodeOpts...) + p, err := net.NewPeer(s.ctx, node.DB.Rootstore(), node.DB.Blockstore(), node.DB.Events(), nodeOpts...) require.NoError(s.t, err) - if err := n.Start(); err != nil { - n.Close() + if err := p.Start(); err != nil { + p.Close() require.NoError(s.t, err) } + node.Peer = p - c, err := setupClient(s, n) + c, err := setupClient(s, node) require.NoError(s.t, err) s.nodes[i] = c @@ -713,6 +729,14 @@ func restartNodes( sub, err := c.Events().Subscribe(event.MergeCompleteName) require.NoError(s.t, err) s.eventSubs[i] = sub + for waitLen > 0 { + select { + case <-readySub.Message(): + waitLen-- + case <-time.After(10 * time.Second): + s.t.Fatalf("timeout waiting for node to be ready") + } + } } // The index of the action after the last wait action before the current restart action. @@ -787,7 +811,7 @@ func configureNode( return } - db, path, err := setupDatabase(s) //disable change dector, or allow it? + node, path, err := setupNode(s) //disable change dector, or allow it? require.NoError(s.t, err) privateKey, err := crypto.GenerateEd25519() @@ -796,20 +820,21 @@ func configureNode( nodeOpts := action() nodeOpts = append(nodeOpts, net.WithPrivateKey(privateKey)) - var n *net.Node - n, err = net.NewNode(s.ctx, db, nodeOpts...) + p, err := net.NewPeer(s.ctx, node.DB.Rootstore(), node.DB.Blockstore(), node.DB.Events(), nodeOpts...) require.NoError(s.t, err) - log.InfoContext(s.ctx, "Starting P2P node", corelog.Any("P2P address", n.PeerInfo())) - if err := n.Start(); err != nil { - n.Close() + log.InfoContext(s.ctx, "Starting P2P node", corelog.Any("P2P address", p.PeerInfo())) + if err := p.Start(); err != nil { + p.Close() require.NoError(s.t, err) } - s.nodeAddresses = append(s.nodeAddresses, n.PeerInfo()) + s.nodeAddresses = append(s.nodeAddresses, p.PeerInfo()) s.nodeConfigs = append(s.nodeConfigs, nodeOpts) - c, err := setupClient(s, n) + node.Peer = p + + c, err := setupClient(s, node) require.NoError(s.t, err) s.nodes = append(s.nodes, c) @@ -1144,7 +1169,7 @@ func createDoc( substituteRelations(s, action) } - var mutation func(*state, CreateDoc, client.P2P, []client.Collection) (*client.Document, error) + var mutation func(*state, CreateDoc, client.DB, []client.Collection) (*client.Document, error) switch mutationType { case CollectionSaveMutationType: @@ -1185,7 +1210,7 @@ func createDoc( func createDocViaColSave( s *state, action CreateDoc, - node client.P2P, + node client.DB, collections []client.Collection, ) (*client.Document, error) { var err error @@ -1210,7 +1235,7 @@ func createDocViaColSave( func createDocViaColCreate( s *state, action CreateDoc, - node client.P2P, + node client.DB, collections []client.Collection, ) (*client.Document, error) { var err error @@ -1235,7 +1260,7 @@ func createDocViaColCreate( func createDocViaGQL( s *state, action CreateDoc, - node client.P2P, + node client.DB, collections []client.Collection, ) (*client.Document, error) { collection := collections[action.CollectionID] @@ -1337,7 +1362,7 @@ func updateDoc( s *state, action UpdateDoc, ) { - var mutation func(*state, UpdateDoc, client.P2P, []client.Collection) error + var mutation func(*state, UpdateDoc, client.DB, []client.Collection) error switch mutationType { case CollectionSaveMutationType: @@ -1367,7 +1392,7 @@ func updateDoc( func updateDocViaColSave( s *state, action UpdateDoc, - node client.P2P, + node client.DB, collections []client.Collection, ) error { cachedDoc := s.documents[action.CollectionID][action.DocID] @@ -1394,7 +1419,7 @@ func updateDocViaColSave( func updateDocViaColUpdate( s *state, action UpdateDoc, - node client.P2P, + node client.DB, collections []client.Collection, ) error { cachedDoc := s.documents[action.CollectionID][action.DocID] @@ -1418,7 +1443,7 @@ func updateDocViaColUpdate( func updateDocViaGQL( s *state, action UpdateDoc, - node client.P2P, + node client.DB, collections []client.Collection, ) error { doc := s.documents[action.CollectionID][action.DocID] From 24fa14f895644621915e4bf65d41469c7dc52979 Mon Sep 17 00:00:00 2001 From: Islam Aliev Date: Thu, 4 Jul 2024 19:10:15 +0200 Subject: [PATCH 05/41] feat: Doc encryption with symmetric key (#2731) ## Relevant issue(s) Resolves #2711 #2808 ## Description This change introduces doc encryption. Upon creation of a document the user can pass the encryption flag which will signal to db to create a new symmetric key using AES-GCM and will store it locally. With the encryption flag all doc fields (deltas) being stored in the DAG encrypted. The datastore will still store data as plain text, as for it's encryption we can use encryption-at-rest. Decryption is not used at the moment, as it is relevant only p2p environment and we don't have yet key exchange mechanism. All peers sync encrypted data. This PR also adds 2 new parameters to GraphQL `create_` mutation: 1. `inputs`: a list of documents to be created 2. `encrypt`: flag that indicates if document(s) need to be encrypted. --- cli/collection_create.go | 18 +- cli/utils.go | 15 + client/document.go | 2 +- client/document_test.go | 63 ++++ client/request/consts.go | 3 + client/request/mutation.go | 9 + datastore/mocks/txn.go | 47 +++ datastore/multi.go | 8 + datastore/store.go | 20 +- .../cli/defradb_client_collection_create.md | 12 +- http/client.go | 4 + http/client_collection.go | 14 + http/client_tx.go | 4 + http/handler_collection.go | 12 +- internal/core/block/block.go | 20 +- internal/core/crdt/ipld_union.go | 59 ++- internal/core/crdt/lwwreg_test.go | 6 +- internal/core/key.go | 59 ++- internal/core/key_test.go | 2 +- internal/db/collection.go | 6 +- internal/db/context.go | 5 +- internal/db/fetcher/fetcher.go | 6 +- internal/db/fetcher/versioned.go | 2 +- internal/db/merge.go | 12 +- internal/encryption/aes.go | 79 ++++ internal/encryption/config.go | 16 + internal/encryption/context.go | 73 ++++ internal/encryption/encryptor.go | 127 +++++++ internal/encryption/encryptor_test.go | 175 +++++++++ internal/encryption/errors.go | 23 ++ internal/encryption/nonce.go | 53 +++ internal/merkle/clock/clock.go | 88 ++++- internal/merkle/crdt/counter.go | 4 +- internal/merkle/crdt/errors.go | 2 +- internal/merkle/crdt/field.go | 22 ++ internal/merkle/crdt/lwwreg.go | 5 +- internal/merkle/crdt/merklecrdt.go | 5 +- internal/planner/commit.go | 2 +- internal/planner/create.go | 114 +++--- internal/planner/explain.go | 2 +- internal/planner/mapper/mapper.go | 8 +- internal/planner/mapper/mutation.go | 14 +- internal/planner/multi.go | 2 +- internal/planner/planner.go | 4 +- internal/request/graphql/parser/mutation.go | 14 + .../request/graphql/schema/descriptions.go | 5 + internal/request/graphql/schema/generate.go | 35 +- tests/bench/query/planner/utils.go | 1 + tests/clients/cli/wrapper_collection.go | 25 +- tests/clients/cli/wrapper_tx.go | 4 + tests/clients/http/wrapper_tx.go | 4 + tests/integration/encryption/commit_test.go | 356 ++++++++++++++++++ tests/integration/encryption/peer_test.go | 147 ++++++++ tests/integration/encryption/query_test.go | 110 ++++++ tests/integration/encryption/utils.go | 31 ++ .../events/simple/with_update_test.go | 9 +- .../explain/default/create_test.go | 8 +- .../explain/execute/create_test.go | 4 +- tests/integration/gql.go | 37 +- .../create/simple_create_many_test.go | 70 ++++ tests/integration/test_case.go | 3 + tests/integration/utils2.go | 122 ++++-- 62 files changed, 1984 insertions(+), 227 deletions(-) create mode 100644 internal/encryption/aes.go create mode 100644 internal/encryption/config.go create mode 100644 internal/encryption/context.go create mode 100644 internal/encryption/encryptor.go create mode 100644 internal/encryption/encryptor_test.go create mode 100644 internal/encryption/errors.go create mode 100644 internal/encryption/nonce.go create mode 100644 internal/merkle/crdt/field.go create mode 100644 tests/integration/encryption/commit_test.go create mode 100644 tests/integration/encryption/peer_test.go create mode 100644 tests/integration/encryption/query_test.go create mode 100644 tests/integration/encryption/utils.go create mode 100644 tests/integration/mutation/create/simple_create_many_test.go diff --git a/cli/collection_create.go b/cli/collection_create.go index 994911a14c..f4c36fbd53 100644 --- a/cli/collection_create.go +++ b/cli/collection_create.go @@ -17,14 +17,25 @@ import ( "github.com/spf13/cobra" "github.com/sourcenetwork/defradb/client" + "github.com/sourcenetwork/defradb/internal/db" ) func MakeCollectionCreateCommand() *cobra.Command { var file string + var shouldEncrypt bool var cmd = &cobra.Command{ - Use: "create [-i --identity] ", + Use: "create [-i --identity] [-e --encrypt] ", Short: "Create a new document.", Long: `Create a new document. + +Options: + -i, --identity + Marks the document as private and set the identity as the owner. The access to the document + and permissions are controlled by ACP (Access Control Policy). + + -e, --encrypt + Encrypt flag specified if the document needs to be encrypted. If set, DefraDB will generate a + symmetric key for encryption using AES-GCM. Example: create from string: defradb client collection create --name User '{ "name": "Bob" }' @@ -69,6 +80,9 @@ Example: create from stdin: return cmd.Usage() } + txn, _ := db.TryGetContextTxn(cmd.Context()) + setContextDocEncryption(cmd, shouldEncrypt, txn) + if client.IsJSONArray(docData) { docs, err := client.NewDocsFromJSON(docData, col.Definition()) if err != nil { @@ -84,6 +98,8 @@ Example: create from stdin: return col.Create(cmd.Context(), doc) }, } + cmd.PersistentFlags().BoolVarP(&shouldEncrypt, "encrypt", "e", false, + "Flag to enable encryption of the document") cmd.Flags().StringVarP(&file, "file", "f", "", "File containing document(s)") return cmd } diff --git a/cli/utils.go b/cli/utils.go index d1ee09962b..b2d4c076bc 100644 --- a/cli/utils.go +++ b/cli/utils.go @@ -25,8 +25,10 @@ import ( acpIdentity "github.com/sourcenetwork/defradb/acp/identity" "github.com/sourcenetwork/defradb/client" + "github.com/sourcenetwork/defradb/datastore" "github.com/sourcenetwork/defradb/http" "github.com/sourcenetwork/defradb/internal/db" + "github.com/sourcenetwork/defradb/internal/encryption" "github.com/sourcenetwork/defradb/keyring" ) @@ -160,6 +162,19 @@ func setContextIdentity(cmd *cobra.Command, privateKeyHex string) error { return nil } +// setContextDocEncryption sets doc encryption for the current command context. +func setContextDocEncryption(cmd *cobra.Command, shouldEncrypt bool, txn datastore.Txn) { + if !shouldEncrypt { + return + } + ctx := cmd.Context() + if txn != nil { + ctx = encryption.ContextWithStore(ctx, txn) + } + ctx = encryption.SetContextConfig(ctx, encryption.DocEncConfig{IsEncrypted: true}) + cmd.SetContext(ctx) +} + // setContextRootDir sets the rootdir for the current command context. func setContextRootDir(cmd *cobra.Command) error { rootdir, err := cmd.Root().PersistentFlags().GetString("rootdir") diff --git a/client/document.go b/client/document.go index ada47cc8f9..f8d427c349 100644 --- a/client/document.go +++ b/client/document.go @@ -118,7 +118,7 @@ func NewDocFromMap(data map[string]any, collectionDefinition CollectionDefinitio return doc, nil } -var jsonArrayPattern = regexp.MustCompile(`^\s*\[.*\]\s*$`) +var jsonArrayPattern = regexp.MustCompile(`(?s)^\s*\[.*\]\s*$`) // IsJSONArray returns true if the given byte array is a JSON Array. func IsJSONArray(obj []byte) bool { diff --git a/client/document_test.go b/client/document_test.go index b15c7b019a..a11a6a67c8 100644 --- a/client/document_test.go +++ b/client/document_test.go @@ -206,3 +206,66 @@ func TestNewFromJSON_WithInvalidJSONFieldValueSimpleString_Error(t *testing.T) { _, err := NewDocFromJSON(objWithJSONField, def) require.ErrorContains(t, err, "invalid JSON payload. Payload: blah") } + +func TestIsJSONArray(t *testing.T) { + tests := []struct { + name string + input []byte + expected bool + }{ + { + name: "Valid JSON Array", + input: []byte(`[{"name":"John","age":21},{"name":"Islam","age":33}]`), + expected: true, + }, + { + name: "Valid Empty JSON Array", + input: []byte(`[]`), + expected: true, + }, + { + name: "Valid JSON Object", + input: []byte(`{"name":"John","age":21}`), + expected: false, + }, + { + name: "Invalid JSON String", + input: []byte(`{"name":"John","age":21`), + expected: false, + }, + { + name: "Non-JSON String", + input: []byte(`Hello, World!`), + expected: false, + }, + { + name: "Array of Primitives", + input: []byte(`[1, 2, 3, 4]`), + expected: true, + }, + { + name: "Nested JSON Array", + input: []byte(`[[1, 2], [3, 4]]`), + expected: true, + }, + { + name: "Valid JSON Array with Whitespace", + input: []byte(` + [ + { "name": "John", "age": 21 }, + { "name": "Islam", "age": 33 } + ] + `), + expected: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actual := IsJSONArray(tt.input) + if actual != tt.expected { + t.Errorf("IsJSONArray(%s) = %v; expected %v", tt.input, actual, tt.expected) + } + }) + } +} diff --git a/client/request/consts.go b/client/request/consts.go index 1a1d653a25..cba609b788 100644 --- a/client/request/consts.go +++ b/client/request/consts.go @@ -21,10 +21,13 @@ const ( Cid = "cid" Input = "input" + Inputs = "inputs" FieldName = "field" FieldIDName = "fieldId" ShowDeleted = "showDeleted" + EncryptArgName = "encrypt" + FilterClause = "filter" GroupByClause = "groupBy" LimitClause = "limit" diff --git a/client/request/mutation.go b/client/request/mutation.go index 81fcc823c9..70d0bed1d9 100644 --- a/client/request/mutation.go +++ b/client/request/mutation.go @@ -41,6 +41,15 @@ type ObjectMutation struct { // // This is ignored for [DeleteObjects] mutations. Input map[string]any + + // Inputs is the array of json representations of the fieldName-value pairs of document + // properties to mutate. + // + // This is ignored for [DeleteObjects] mutations. + Inputs []map[string]any + + // Encrypt is a boolean flag that indicates whether the input data should be encrypted. + Encrypt bool } // ToSelect returns a basic Select object, with the same Name, Alias, and Fields as diff --git a/datastore/mocks/txn.go b/datastore/mocks/txn.go index f29c045dcd..41606260ea 100644 --- a/datastore/mocks/txn.go +++ b/datastore/mocks/txn.go @@ -195,6 +195,53 @@ func (_c *Txn_Discard_Call) RunAndReturn(run func(context.Context)) *Txn_Discard return _c } +// Encstore provides a mock function with given fields: +func (_m *Txn) Encstore() datastore.DSReaderWriter { + ret := _m.Called() + + if len(ret) == 0 { + panic("no return value specified for Encstore") + } + + var r0 datastore.DSReaderWriter + if rf, ok := ret.Get(0).(func() datastore.DSReaderWriter); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(datastore.DSReaderWriter) + } + } + + return r0 +} + +// Txn_Encstore_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Encstore' +type Txn_Encstore_Call struct { + *mock.Call +} + +// Encstore is a helper method to define mock.On call +func (_e *Txn_Expecter) Encstore() *Txn_Encstore_Call { + return &Txn_Encstore_Call{Call: _e.mock.On("Encstore")} +} + +func (_c *Txn_Encstore_Call) Run(run func()) *Txn_Encstore_Call { + _c.Call.Run(func(args mock.Arguments) { + run() + }) + return _c +} + +func (_c *Txn_Encstore_Call) Return(_a0 datastore.DSReaderWriter) *Txn_Encstore_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *Txn_Encstore_Call) RunAndReturn(run func() datastore.DSReaderWriter) *Txn_Encstore_Call { + _c.Call.Return(run) + return _c +} + // Headstore provides a mock function with given fields: func (_m *Txn) Headstore() datastore.DSReaderWriter { ret := _m.Called() diff --git a/datastore/multi.go b/datastore/multi.go index a70a24a60d..f863924d5d 100644 --- a/datastore/multi.go +++ b/datastore/multi.go @@ -23,11 +23,13 @@ var ( headStoreKey = rootStoreKey.ChildString("heads") blockStoreKey = rootStoreKey.ChildString("blocks") peerStoreKey = rootStoreKey.ChildString("ps") + encStoreKey = rootStoreKey.ChildString("enc") ) type multistore struct { root DSReaderWriter data DSReaderWriter + enc DSReaderWriter head DSReaderWriter peer DSBatching system DSReaderWriter @@ -43,6 +45,7 @@ func MultiStoreFrom(rootstore ds.Datastore) MultiStore { ms := &multistore{ root: rootRW, data: prefix(rootRW, dataStoreKey), + enc: prefix(rootRW, encStoreKey), head: prefix(rootRW, headStoreKey), peer: namespace.Wrap(rootstore, peerStoreKey), system: prefix(rootRW, systemStoreKey), @@ -57,6 +60,11 @@ func (ms multistore) Datastore() DSReaderWriter { return ms.data } +// Encstore implements MultiStore. +func (ms multistore) Encstore() DSReaderWriter { + return ms.enc +} + // Headstore implements MultiStore. func (ms multistore) Headstore() DSReaderWriter { return ms.head diff --git a/datastore/store.go b/datastore/store.go index 66501270d1..516bfe0b65 100644 --- a/datastore/store.go +++ b/datastore/store.go @@ -34,26 +34,26 @@ type Rootstore interface { type MultiStore interface { Rootstore() DSReaderWriter - // Datastore is a wrapped root DSReaderWriter - // under the /data namespace + // Datastore is a wrapped root DSReaderWriter under the /data namespace Datastore() DSReaderWriter - // Headstore is a wrapped root DSReaderWriter - // under the /head namespace + // Encstore is a wrapped root DSReaderWriter under the /enc namespace + // This store is used for storing symmetric encryption keys for doc encryption. + // The store keys are comprised of docID + field name. + Encstore() DSReaderWriter + + // Headstore is a wrapped root DSReaderWriter under the /head namespace Headstore() DSReaderWriter - // Peerstore is a wrapped root DSReaderWriter - // as a ds.Batching, embedded into a DSBatching + // Peerstore is a wrapped root DSReaderWriter as a ds.Batching, embedded into a DSBatching // under the /peers namespace Peerstore() DSBatching - // Blockstore is a wrapped root DSReaderWriter - // as a Blockstore, embedded into a Blockstore + // Blockstore is a wrapped root DSReaderWriter as a Blockstore, embedded into a Blockstore // under the /blocks namespace Blockstore() Blockstore - // Headstore is a wrapped root DSReaderWriter - // under the /system namespace + // Headstore is a wrapped root DSReaderWriter under the /system namespace Systemstore() DSReaderWriter } diff --git a/docs/website/references/cli/defradb_client_collection_create.md b/docs/website/references/cli/defradb_client_collection_create.md index 425be82753..5425e3f860 100644 --- a/docs/website/references/cli/defradb_client_collection_create.md +++ b/docs/website/references/cli/defradb_client_collection_create.md @@ -5,6 +5,15 @@ Create a new document. ### Synopsis Create a new document. + +Options: + -i, --identity + Marks the document as private and set the identity as the owner. The access to the document + and permissions are controlled by ACP (Access Control Policy). + + -e, --encrypt + Encrypt flag specified if the document needs to be encrypted. If set, DefraDB will generate a + symmetric key for encryption using AES-GCM. Example: create from string: defradb client collection create --name User '{ "name": "Bob" }' @@ -24,12 +33,13 @@ Example: create from stdin: ``` -defradb client collection create [-i --identity] [flags] +defradb client collection create [-i --identity] [-e --encrypt] [flags] ``` ### Options ``` + -e, --encrypt Flag to enable encryption of the document -f, --file string File containing document(s) -h, --help help for create ``` diff --git a/http/client.go b/http/client.go index 2082604599..6e5cc21276 100644 --- a/http/client.go +++ b/http/client.go @@ -349,12 +349,16 @@ func (c *Client) ExecRequest( result.GQL.Errors = []error{err} return result } + req, err := http.NewRequestWithContext(ctx, http.MethodPost, methodURL.String(), bytes.NewBuffer(body)) if err != nil { result.GQL.Errors = []error{err} return result } err = c.http.setDefaultHeaders(req) + + setDocEncryptionFlagIfNeeded(ctx, req) + if err != nil { result.GQL.Errors = []error{err} return result diff --git a/http/client_collection.go b/http/client_collection.go index ee614c1dba..8df094f5fc 100644 --- a/http/client_collection.go +++ b/http/client_collection.go @@ -24,6 +24,7 @@ import ( sse "github.com/vito/go-sse/sse" "github.com/sourcenetwork/defradb/client" + "github.com/sourcenetwork/defradb/internal/encryption" ) var _ client.Collection = (*Collection)(nil) @@ -78,6 +79,8 @@ func (c *Collection) Create( return err } + setDocEncryptionFlagIfNeeded(ctx, req) + _, err = c.http.request(req) if err != nil { return err @@ -114,6 +117,8 @@ func (c *Collection) CreateMany( return err } + setDocEncryptionFlagIfNeeded(ctx, req) + _, err = c.http.request(req) if err != nil { return err @@ -125,6 +130,15 @@ func (c *Collection) CreateMany( return nil } +func setDocEncryptionFlagIfNeeded(ctx context.Context, req *http.Request) { + encConf := encryption.GetContextConfig(ctx) + if encConf.HasValue() && encConf.Value().IsEncrypted { + q := req.URL.Query() + q.Set(docEncryptParam, "true") + req.URL.RawQuery = q.Encode() + } +} + func (c *Collection) Update( ctx context.Context, doc *client.Document, diff --git a/http/client_tx.go b/http/client_tx.go index a804b934f1..5b99f5aaad 100644 --- a/http/client_tx.go +++ b/http/client_tx.go @@ -91,6 +91,10 @@ func (c *Transaction) Datastore() datastore.DSReaderWriter { panic("client side transaction") } +func (c *Transaction) Encstore() datastore.DSReaderWriter { + panic("client side transaction") +} + func (c *Transaction) Headstore() datastore.DSReaderWriter { panic("client side transaction") } diff --git a/http/handler_collection.go b/http/handler_collection.go index 60c18b3442..412f486602 100644 --- a/http/handler_collection.go +++ b/http/handler_collection.go @@ -21,8 +21,11 @@ import ( "github.com/go-chi/chi/v5" "github.com/sourcenetwork/defradb/client" + "github.com/sourcenetwork/defradb/internal/encryption" ) +const docEncryptParam = "encrypt" + type collectionHandler struct{} type CollectionDeleteRequest struct { @@ -43,6 +46,11 @@ func (s *collectionHandler) Create(rw http.ResponseWriter, req *http.Request) { return } + ctx := req.Context() + if req.URL.Query().Get(docEncryptParam) == "true" { + ctx = encryption.SetContextConfig(ctx, encryption.DocEncConfig{IsEncrypted: true}) + } + switch { case client.IsJSONArray(data): docList, err := client.NewDocsFromJSON(data, col.Definition()) @@ -51,7 +59,7 @@ func (s *collectionHandler) Create(rw http.ResponseWriter, req *http.Request) { return } - if err := col.CreateMany(req.Context(), docList); err != nil { + if err := col.CreateMany(ctx, docList); err != nil { responseJSON(rw, http.StatusBadRequest, errorResponse{err}) return } @@ -62,7 +70,7 @@ func (s *collectionHandler) Create(rw http.ResponseWriter, req *http.Request) { responseJSON(rw, http.StatusBadRequest, errorResponse{err}) return } - if err := col.Create(req.Context(), doc); err != nil { + if err := col.Create(ctx, doc); err != nil { responseJSON(rw, http.StatusBadRequest, errorResponse{err}) return } diff --git a/internal/core/block/block.go b/internal/core/block/block.go index 8482a23d91..d2caa610f7 100644 --- a/internal/core/block/block.go +++ b/internal/core/block/block.go @@ -103,6 +103,9 @@ type Block struct { Delta crdt.CRDT // Links are the links to other blocks in the DAG. Links []DAGLink + // IsEncrypted is a flag that indicates if the block's delta is encrypted. + // It needs to be a pointer so that it can be translated from and to `optional Bool` in the IPLD schema. + IsEncrypted *bool } // IPLDSchemaBytes returns the IPLD schema representation for the block. @@ -111,8 +114,9 @@ type Block struct { func (b Block) IPLDSchemaBytes() []byte { return []byte(` type Block struct { - delta CRDT - links [ DAGLink ] + delta CRDT + links [ DAGLink ] + isEncrypted optional Bool }`) } @@ -143,19 +147,9 @@ func New(delta core.Delta, links []DAGLink, heads ...cid.Cid) *Block { blockLinks = append(blockLinks, links...) - var crdtDelta crdt.CRDT - switch delta := delta.(type) { - case *crdt.LWWRegDelta: - crdtDelta = crdt.CRDT{LWWRegDelta: delta} - case *crdt.CompositeDAGDelta: - crdtDelta = crdt.CRDT{CompositeDAGDelta: delta} - case *crdt.CounterDelta: - crdtDelta = crdt.CRDT{CounterDelta: delta} - } - return &Block{ Links: blockLinks, - Delta: crdtDelta, + Delta: crdt.NewCRDT(delta), } } diff --git a/internal/core/crdt/ipld_union.go b/internal/core/crdt/ipld_union.go index 361a41b150..95023f28b2 100644 --- a/internal/core/crdt/ipld_union.go +++ b/internal/core/crdt/ipld_union.go @@ -19,6 +19,19 @@ type CRDT struct { CounterDelta *CounterDelta } +// NewCRDT returns a new CRDT. +func NewCRDT(delta core.Delta) CRDT { + switch d := delta.(type) { + case *LWWRegDelta: + return CRDT{LWWRegDelta: d} + case *CompositeDAGDelta: + return CRDT{CompositeDAGDelta: d} + case *CounterDelta: + return CRDT{CounterDelta: d} + } + return CRDT{} +} + // IPLDSchemaBytes returns the IPLD schema representation for the CRDT. // // This needs to match the [CRDT] struct or [mustSetSchema] will panic on init. @@ -96,6 +109,39 @@ func (c CRDT) GetSchemaVersionID() string { return "" } +// Clone returns a clone of the CRDT. +func (c CRDT) Clone() CRDT { + var cloned CRDT + switch { + case c.LWWRegDelta != nil: + cloned.LWWRegDelta = &LWWRegDelta{ + DocID: c.LWWRegDelta.DocID, + FieldName: c.LWWRegDelta.FieldName, + Priority: c.LWWRegDelta.Priority, + SchemaVersionID: c.LWWRegDelta.SchemaVersionID, + Data: c.LWWRegDelta.Data, + } + case c.CompositeDAGDelta != nil: + cloned.CompositeDAGDelta = &CompositeDAGDelta{ + DocID: c.CompositeDAGDelta.DocID, + FieldName: c.CompositeDAGDelta.FieldName, + Priority: c.CompositeDAGDelta.Priority, + SchemaVersionID: c.CompositeDAGDelta.SchemaVersionID, + Status: c.CompositeDAGDelta.Status, + } + case c.CounterDelta != nil: + cloned.CounterDelta = &CounterDelta{ + DocID: c.CounterDelta.DocID, + FieldName: c.CounterDelta.FieldName, + Priority: c.CounterDelta.Priority, + SchemaVersionID: c.CounterDelta.SchemaVersionID, + Nonce: c.CounterDelta.Nonce, + Data: c.CounterDelta.Data, + } + } + return cloned +} + // GetStatus returns the status of the delta. // // Currently only implemented for CompositeDAGDelta. @@ -107,15 +153,24 @@ func (c CRDT) GetStatus() uint8 { } // GetData returns the data of the delta. -// -// Currently only implemented for LWWRegDelta. func (c CRDT) GetData() []byte { if c.LWWRegDelta != nil { return c.LWWRegDelta.Data + } else if c.CounterDelta != nil { + return c.CounterDelta.Data } return nil } +// SetData sets the data of the delta. +func (c CRDT) SetData(data []byte) { + if c.LWWRegDelta != nil { + c.LWWRegDelta.Data = data + } else if c.CounterDelta != nil { + c.CounterDelta.Data = data + } +} + // IsComposite returns true if the CRDT is a composite CRDT. func (c CRDT) IsComposite() bool { return c.CompositeDAGDelta != nil diff --git a/internal/core/crdt/lwwreg_test.go b/internal/core/crdt/lwwreg_test.go index 2083a5b800..136d5cd09d 100644 --- a/internal/core/crdt/lwwreg_test.go +++ b/internal/core/crdt/lwwreg_test.go @@ -31,7 +31,7 @@ func setupLWWRegister() LWWRegister { return NewLWWRegister(store, core.CollectionSchemaVersionKey{}, key, "") } -func setupLoadedLWWRegster(ctx context.Context) LWWRegister { +func setupLoadedLWWRegister(ctx context.Context) LWWRegister { lww := setupLWWRegister() addDelta := lww.Set([]byte("test")) addDelta.SetPriority(1) @@ -73,7 +73,7 @@ func TestLWWRegisterInitialMerge(t *testing.T) { func TestLWWReisterFollowupMerge(t *testing.T) { ctx := context.Background() - lww := setupLoadedLWWRegster(ctx) + lww := setupLoadedLWWRegister(ctx) addDelta := lww.Set([]byte("test2")) addDelta.SetPriority(2) lww.Merge(ctx, addDelta) @@ -90,7 +90,7 @@ func TestLWWReisterFollowupMerge(t *testing.T) { func TestLWWRegisterOldMerge(t *testing.T) { ctx := context.Background() - lww := setupLoadedLWWRegster(ctx) + lww := setupLoadedLWWRegister(ctx) addDelta := lww.Set([]byte("test-1")) addDelta.SetPriority(0) lww.Merge(ctx, addDelta) diff --git a/internal/core/key.go b/internal/core/key.go index d087c43af8..efc2d73017 100644 --- a/internal/core/key.go +++ b/internal/core/key.go @@ -71,7 +71,7 @@ type DataStoreKey struct { CollectionRootID uint32 InstanceType InstanceType DocID string - FieldId string + FieldID string } var _ Key = (*DataStoreKey)(nil) @@ -238,7 +238,7 @@ func NewDataStoreKey(key string) (DataStoreKey, error) { dataStoreKey.InstanceType = InstanceType(elements[1]) dataStoreKey.DocID = elements[2] if numberOfElements == 4 { - dataStoreKey.FieldId = elements[3] + dataStoreKey.FieldID = elements[3] } return dataStoreKey, nil @@ -429,21 +429,21 @@ func (k DataStoreKey) WithDocID(docID string) DataStoreKey { func (k DataStoreKey) WithInstanceInfo(key DataStoreKey) DataStoreKey { newKey := k newKey.DocID = key.DocID - newKey.FieldId = key.FieldId + newKey.FieldID = key.FieldID newKey.InstanceType = key.InstanceType return newKey } func (k DataStoreKey) WithFieldId(fieldId string) DataStoreKey { newKey := k - newKey.FieldId = fieldId + newKey.FieldID = fieldId return newKey } func (k DataStoreKey) ToHeadStoreKey() HeadStoreKey { return HeadStoreKey{ DocID: k.DocID, - FieldId: k.FieldId, + FieldId: k.FieldID, } } @@ -477,8 +477,8 @@ func (k DataStoreKey) ToString() string { if k.DocID != "" { result = result + "/" + k.DocID } - if k.FieldId != "" { - result = result + "/" + k.FieldId + if k.FieldID != "" { + result = result + "/" + k.FieldID } return result @@ -495,7 +495,7 @@ func (k DataStoreKey) ToDS() ds.Key { func (k DataStoreKey) Equal(other DataStoreKey) bool { return k.CollectionRootID == other.CollectionRootID && k.DocID == other.DocID && - k.FieldId == other.FieldId && + k.FieldID == other.FieldID && k.InstanceType == other.InstanceType } @@ -769,8 +769,8 @@ func (k HeadStoreKey) ToDS() ds.Key { func (k DataStoreKey) PrefixEnd() DataStoreKey { newKey := k - if k.FieldId != "" { - newKey.FieldId = string(bytesPrefixEnd([]byte(k.FieldId))) + if k.FieldID != "" { + newKey.FieldID = string(bytesPrefixEnd([]byte(k.FieldID))) return newKey } if k.DocID != "" { @@ -789,12 +789,12 @@ func (k DataStoreKey) PrefixEnd() DataStoreKey { return newKey } -// FieldID extracts the Field Identifier from the Key. -// In a Primary index, the last key path is the FieldID. +// FieldIDAsUint extracts the Field Identifier from the Key. +// In a Primary index, the last key path is the FieldIDAsUint. // This may be different in Secondary Indexes. // An error is returned if it can't correct convert the field to a uint32. -func (k DataStoreKey) FieldID() (uint32, error) { - fieldID, err := strconv.Atoi(k.FieldId) +func (k DataStoreKey) FieldIDAsUint() (uint32, error) { + fieldID, err := strconv.Atoi(k.FieldID) if err != nil { return 0, NewErrFailedToGetFieldIdOfKey(err) } @@ -814,3 +814,34 @@ func bytesPrefixEnd(b []byte) []byte { // maximal byte string (i.e. already \xff...). return b } + +// EncStoreDocKey is a key for the encryption store. +type EncStoreDocKey struct { + DocID string + FieldID uint32 +} + +var _ Key = (*EncStoreDocKey)(nil) + +// NewEncStoreDocKey creates a new EncStoreDocKey from a docID and fieldID. +func NewEncStoreDocKey(docID string, fieldID uint32) EncStoreDocKey { + return EncStoreDocKey{ + DocID: docID, + FieldID: fieldID, + } +} + +func (k EncStoreDocKey) ToString() string { + if k.FieldID == 0 { + return k.DocID + } + return fmt.Sprintf("%s/%d", k.DocID, k.FieldID) +} + +func (k EncStoreDocKey) Bytes() []byte { + return []byte(k.ToString()) +} + +func (k EncStoreDocKey) ToDS() ds.Key { + return ds.NewKey(k.ToString()) +} diff --git a/internal/core/key_test.go b/internal/core/key_test.go index c5e34073a3..90bd122d6f 100644 --- a/internal/core/key_test.go +++ b/internal/core/key_test.go @@ -54,7 +54,7 @@ func TestNewDataStoreKey_ReturnsCollectionIdAndIndexIdAndDocIDAndFieldIdAndInsta DataStoreKey{ CollectionRootID: collectionRootID, DocID: docID, - FieldId: fieldID, + FieldID: fieldID, InstanceType: InstanceType(instanceType)}, result) assert.Equal(t, fmt.Sprintf("/%v/%s/%s/%s", collectionRootID, instanceType, docID, fieldID), resultString) diff --git a/internal/db/collection.go b/internal/db/collection.go index 7e20f0da8f..64f90960cc 100644 --- a/internal/db/collection.go +++ b/internal/db/collection.go @@ -657,7 +657,7 @@ func (c *collection) save( return cid.Undef, err } - link, _, err := merkleCRDT.Save(ctx, val) + link, _, err := merkleCRDT.Save(ctx, &merklecrdt.DocField{DocID: primaryKey.DocID, FieldValue: val}) if err != nil { return cid.Undef, err } @@ -905,7 +905,7 @@ func (c *collection) getDataStoreKeyFromDocID(docID client.DocID) core.DataStore } func (c *collection) tryGetFieldKey(primaryKey core.PrimaryDataStoreKey, fieldName string) (core.DataStoreKey, bool) { - fieldId, hasField := c.tryGetFieldID(fieldName) + fieldID, hasField := c.tryGetFieldID(fieldName) if !hasField { return core.DataStoreKey{}, false } @@ -913,7 +913,7 @@ func (c *collection) tryGetFieldKey(primaryKey core.PrimaryDataStoreKey, fieldNa return core.DataStoreKey{ CollectionRootID: c.Description().RootID, DocID: primaryKey.DocID, - FieldId: strconv.FormatUint(uint64(fieldId), 10), + FieldID: strconv.FormatUint(uint64(fieldID), 10), }, true } diff --git a/internal/db/context.go b/internal/db/context.go index 88019af323..8ad51c86ce 100644 --- a/internal/db/context.go +++ b/internal/db/context.go @@ -17,6 +17,7 @@ import ( acpIdentity "github.com/sourcenetwork/defradb/acp/identity" "github.com/sourcenetwork/defradb/datastore" + "github.com/sourcenetwork/defradb/internal/encryption" ) // txnContextKey is the key type for transaction context values. @@ -62,6 +63,7 @@ func ensureContextTxn(ctx context.Context, db transactionDB, readOnly bool) (con if err != nil { return nil, txn, err } + ctx = encryption.ContextWithStore(ctx, txn) return SetContextTxn(ctx, txn), txn, nil } @@ -87,9 +89,6 @@ func SetContextTxn(ctx context.Context, txn datastore.Txn) context.Context { return context.WithValue(ctx, txnContextKey{}, txn) } -// TryGetContextTxn returns an identity and a bool indicating if the -// identity was retrieved from the given context. - // GetContextIdentity returns the identity from the given context. // // If an identity does not exist `NoIdentity` is returned. diff --git a/internal/db/fetcher/fetcher.go b/internal/db/fetcher/fetcher.go index bfaed9d871..06e3255e8c 100644 --- a/internal/db/fetcher/fetcher.go +++ b/internal/db/fetcher/fetcher.go @@ -351,7 +351,7 @@ func (df *DocumentFetcher) nextKey(ctx context.Context, seekNext bool) (spanDone if seekNext { curKey := df.kv.Key - curKey.FieldId = "" // clear field so prefixEnd applies to docID + curKey.FieldID = "" // clear field so prefixEnd applies to docID seekKey := curKey.PrefixEnd().ToString() spanDone, df.kv, err = df.seekKV(seekKey) // handle any internal errors @@ -504,7 +504,7 @@ func (df *DocumentFetcher) processKV(kv *keyValue) error { } } - if kv.Key.FieldId == core.DATASTORE_DOC_VERSION_FIELD_ID { + if kv.Key.FieldID == core.DATASTORE_DOC_VERSION_FIELD_ID { df.doc.schemaVersionID = string(kv.Value) return nil } @@ -515,7 +515,7 @@ func (df *DocumentFetcher) processKV(kv *keyValue) error { } // extract the FieldID and update the encoded doc properties map - fieldID, err := kv.Key.FieldID() + fieldID, err := kv.Key.FieldIDAsUint() if err != nil { return err } diff --git a/internal/db/fetcher/versioned.go b/internal/db/fetcher/versioned.go index 892b84e329..0ff58c4eeb 100644 --- a/internal/db/fetcher/versioned.go +++ b/internal/db/fetcher/versioned.go @@ -415,7 +415,7 @@ func (vf *VersionedFetcher) processBlock( vf.mCRDTs[crdtIndex] = mcrdt } - err = mcrdt.Clock().ProcessBlock(vf.ctx, block, blockLink) + err = mcrdt.Clock().ProcessBlock(vf.ctx, block, blockLink, false) return err } diff --git a/internal/db/merge.go b/internal/db/merge.go index bbfedd98d8..e588cb60a4 100644 --- a/internal/db/merge.go +++ b/internal/db/merge.go @@ -227,11 +227,15 @@ func (mp *mergeProcessor) loadComposites( func (mp *mergeProcessor) mergeComposites(ctx context.Context) error { for e := mp.composites.Front(); e != nil; e = e.Next() { block := e.Value.(*coreblock.Block) + var onlyHeads bool + if block.IsEncrypted != nil && *block.IsEncrypted { + onlyHeads = true + } link, err := block.GenerateLink() if err != nil { return err } - err = mp.processBlock(ctx, block, link) + err = mp.processBlock(ctx, block, link, onlyHeads) if err != nil { return err } @@ -240,10 +244,12 @@ func (mp *mergeProcessor) mergeComposites(ctx context.Context) error { } // processBlock merges the block and its children to the datastore and sets the head accordingly. +// If onlyHeads is true, it will skip merging and update only the heads. func (mp *mergeProcessor) processBlock( ctx context.Context, block *coreblock.Block, blockLink cidlink.Link, + onlyHeads bool, ) error { crdt, err := mp.initCRDTForType(block.Delta.GetFieldName()) if err != nil { @@ -256,7 +262,7 @@ func (mp *mergeProcessor) processBlock( return nil } - err = crdt.Clock().ProcessBlock(ctx, block, blockLink) + err = crdt.Clock().ProcessBlock(ctx, block, blockLink, onlyHeads) if err != nil { return err } @@ -276,7 +282,7 @@ func (mp *mergeProcessor) processBlock( return err } - if err := mp.processBlock(ctx, childBlock, link.Link); err != nil { + if err := mp.processBlock(ctx, childBlock, link.Link, onlyHeads); err != nil { return err } } diff --git a/internal/encryption/aes.go b/internal/encryption/aes.go new file mode 100644 index 0000000000..e3a7feb563 --- /dev/null +++ b/internal/encryption/aes.go @@ -0,0 +1,79 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package encryption + +import ( + "crypto/aes" + "crypto/cipher" + "encoding/base64" + "fmt" +) + +// EncryptAES encrypts data using AES-GCM with a provided key. +func EncryptAES(plainText, key []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + + nonce, err := generateNonceFunc() + if err != nil { + return nil, err + } + + aesGCM, err := cipher.NewGCM(block) + if err != nil { + return nil, err + } + + cipherText := aesGCM.Seal(nonce, nonce, plainText, nil) + + buf := make([]byte, base64.StdEncoding.EncodedLen(len(cipherText))) + base64.StdEncoding.Encode(buf, cipherText) + + return buf, nil +} + +// DecryptAES decrypts AES-GCM encrypted data with a provided key. +func DecryptAES(cipherTextBase64, key []byte) ([]byte, error) { + cipherText := make([]byte, base64.StdEncoding.DecodedLen(len(cipherTextBase64))) + n, err := base64.StdEncoding.Decode(cipherText, []byte(cipherTextBase64)) + + if err != nil { + return nil, err + } + + cipherText = cipherText[:n] + + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + + if len(cipherText) < nonceLength { + return nil, fmt.Errorf("cipherText too short") + } + + nonce := cipherText[:nonceLength] + cipherText = cipherText[nonceLength:] + + aesGCM, err := cipher.NewGCM(block) + if err != nil { + return nil, err + } + + plainText, err := aesGCM.Open(nil, nonce, cipherText, nil) + if err != nil { + return nil, err + } + + return plainText, nil +} diff --git a/internal/encryption/config.go b/internal/encryption/config.go new file mode 100644 index 0000000000..ddb4a3815a --- /dev/null +++ b/internal/encryption/config.go @@ -0,0 +1,16 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package encryption + +// DocEncConfig is the configuration for document encryption. +type DocEncConfig struct { + IsEncrypted bool +} diff --git a/internal/encryption/context.go b/internal/encryption/context.go new file mode 100644 index 0000000000..10a03c89c1 --- /dev/null +++ b/internal/encryption/context.go @@ -0,0 +1,73 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package encryption + +import ( + "context" + + "github.com/sourcenetwork/immutable" + + "github.com/sourcenetwork/defradb/datastore" +) + +// docEncContextKey is the key type for document encryption context values. +type docEncContextKey struct{} + +// configContextKey is the key type for encryption context values. +type configContextKey struct{} + +// TryGetContextDocEnc returns a document encryption and a bool indicating if +// it was retrieved from the given context. +func TryGetContextEncryptor(ctx context.Context) (*DocEncryptor, bool) { + enc, ok := ctx.Value(docEncContextKey{}).(*DocEncryptor) + if ok { + checkKeyGenerationFlag(ctx, enc) + } + return enc, ok +} + +func checkKeyGenerationFlag(ctx context.Context, enc *DocEncryptor) { + encConfig := GetContextConfig(ctx) + if encConfig.HasValue() && encConfig.Value().IsEncrypted { + enc.EnableKeyGeneration() + } +} + +func ensureContextWithDocEnc(ctx context.Context) (context.Context, *DocEncryptor) { + enc, ok := TryGetContextEncryptor(ctx) + if !ok { + enc = newDocEncryptor(ctx) + ctx = context.WithValue(ctx, docEncContextKey{}, enc) + } + return ctx, enc +} + +// ContextWithStore sets the store on the doc encryptor in the context. +// If the doc encryptor is not present, it will be created. +func ContextWithStore(ctx context.Context, txn datastore.Txn) context.Context { + ctx, encryptor := ensureContextWithDocEnc(ctx) + encryptor.SetStore(txn.Encstore()) + return ctx +} + +// GetContextConfig returns the doc encryption config from the given context. +func GetContextConfig(ctx context.Context) immutable.Option[DocEncConfig] { + encConfig, ok := ctx.Value(configContextKey{}).(DocEncConfig) + if ok { + return immutable.Some(encConfig) + } + return immutable.None[DocEncConfig]() +} + +// SetContextConfig returns a new context with the doc encryption config set. +func SetContextConfig(ctx context.Context, encConfig DocEncConfig) context.Context { + return context.WithValue(ctx, configContextKey{}, encConfig) +} diff --git a/internal/encryption/encryptor.go b/internal/encryption/encryptor.go new file mode 100644 index 0000000000..596e9f9903 --- /dev/null +++ b/internal/encryption/encryptor.go @@ -0,0 +1,127 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package encryption + +import ( + "context" + "crypto/rand" + "errors" + "io" + + ds "github.com/ipfs/go-datastore" + + "github.com/sourcenetwork/defradb/datastore" + "github.com/sourcenetwork/defradb/internal/core" +) + +var generateEncryptionKeyFunc = generateEncryptionKey + +const keyLength = 32 // 32 bytes for AES-256 + +const testEncryptionKey = "examplekey1234567890examplekey12" + +// generateEncryptionKey generates a random AES key. +func generateEncryptionKey() ([]byte, error) { + key := make([]byte, keyLength) + if _, err := io.ReadFull(rand.Reader, key); err != nil { + return nil, err + } + return key, nil +} + +// generateTestEncryptionKey generates a deterministic encryption key for testing. +func generateTestEncryptionKey() ([]byte, error) { + return []byte(testEncryptionKey), nil +} + +type DocEncryptor struct { + shouldGenerateKey bool + ctx context.Context + store datastore.DSReaderWriter +} + +func newDocEncryptor(ctx context.Context) *DocEncryptor { + return &DocEncryptor{ctx: ctx} +} + +func (d *DocEncryptor) EnableKeyGeneration() { + d.shouldGenerateKey = true +} + +func (d *DocEncryptor) SetStore(store datastore.DSReaderWriter) { + d.store = store +} + +func (d *DocEncryptor) Encrypt(docID string, fieldID uint32, plainText []byte) ([]byte, error) { + encryptionKey, storeKey, err := d.fetchEncryptionKey(docID, fieldID) + if err != nil { + return nil, err + } + + if len(encryptionKey) == 0 { + if !d.shouldGenerateKey { + return plainText, nil + } + + encryptionKey, err = generateEncryptionKeyFunc() + if err != nil { + return nil, err + } + + err = d.store.Put(d.ctx, storeKey.ToDS(), encryptionKey) + if err != nil { + return nil, err + } + } + return EncryptAES(plainText, encryptionKey) +} + +func (d *DocEncryptor) Decrypt(docID string, fieldID uint32, cipherText []byte) ([]byte, error) { + encKey, _, err := d.fetchEncryptionKey(docID, fieldID) + if err != nil { + return nil, err + } + if len(encKey) == 0 { + return nil, nil + } + return DecryptAES(cipherText, encKey) +} + +// fetchEncryptionKey fetches the encryption key for the given docID and fieldID. +// If the key is not found, it returns an empty key. +func (d *DocEncryptor) fetchEncryptionKey(docID string, fieldID uint32) ([]byte, core.EncStoreDocKey, error) { + storeKey := core.NewEncStoreDocKey(docID, fieldID) + if d.store == nil { + return nil, core.EncStoreDocKey{}, ErrNoStorageProvided + } + encryptionKey, err := d.store.Get(d.ctx, storeKey.ToDS()) + isNotFound := errors.Is(err, ds.ErrNotFound) + if err != nil && !isNotFound { + return nil, core.EncStoreDocKey{}, err + } + return encryptionKey, storeKey, nil +} + +func EncryptDoc(ctx context.Context, docID string, fieldID uint32, plainText []byte) ([]byte, error) { + enc, ok := TryGetContextEncryptor(ctx) + if !ok { + return nil, nil + } + return enc.Encrypt(docID, fieldID, plainText) +} + +func DecryptDoc(ctx context.Context, docID string, fieldID uint32, cipherText []byte) ([]byte, error) { + enc, ok := TryGetContextEncryptor(ctx) + if !ok { + return nil, nil + } + return enc.Decrypt(docID, fieldID, cipherText) +} diff --git a/internal/encryption/encryptor_test.go b/internal/encryption/encryptor_test.go new file mode 100644 index 0000000000..10abd1f062 --- /dev/null +++ b/internal/encryption/encryptor_test.go @@ -0,0 +1,175 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package encryption + +import ( + "context" + "errors" + "testing" + + ds "github.com/ipfs/go-datastore" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + "github.com/sourcenetwork/defradb/datastore/mocks" + "github.com/sourcenetwork/defradb/internal/core" +) + +var testErr = errors.New("test error") + +var docID = "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3" + +func getPlainText() []byte { + return []byte("test") +} + +func getCipherText(t *testing.T) []byte { + cipherText, err := EncryptAES(getPlainText(), []byte(testEncryptionKey)) + assert.NoError(t, err) + return cipherText +} + +func TestEncryptorEncrypt_IfStorageReturnsError_Error(t *testing.T) { + enc := newDocEncryptor(context.Background()) + st := mocks.NewDSReaderWriter(t) + enc.SetStore(st) + + st.EXPECT().Get(mock.Anything, mock.Anything).Return(nil, testErr) + + _, err := enc.Encrypt(docID, 0, []byte("test")) + + assert.ErrorIs(t, err, testErr) +} + +func TestEncryptorEncrypt_IfNoKeyFoundInStorage_ShouldGenerateKeyStoreItAndReturnCipherText(t *testing.T) { + enc := newDocEncryptor(context.Background()) + st := mocks.NewDSReaderWriter(t) + enc.EnableKeyGeneration() + enc.SetStore(st) + + st.EXPECT().Get(mock.Anything, mock.Anything).Return(nil, ds.ErrNotFound) + + storeKey := core.NewEncStoreDocKey(docID, 0) + + st.EXPECT().Put(mock.Anything, storeKey.ToDS(), []byte(testEncryptionKey)).Return(nil) + + cipherText, err := enc.Encrypt(docID, 0, getPlainText()) + + assert.NoError(t, err) + assert.Equal(t, getCipherText(t), cipherText) +} + +func TestEncryptorEncrypt_IfKeyFoundInStorage_ShouldUseItToReturnCipherText(t *testing.T) { + enc := newDocEncryptor(context.Background()) + st := mocks.NewDSReaderWriter(t) + enc.EnableKeyGeneration() + enc.SetStore(st) + + st.EXPECT().Get(mock.Anything, mock.Anything).Return([]byte(testEncryptionKey), nil) + + cipherText, err := enc.Encrypt(docID, 0, getPlainText()) + + assert.NoError(t, err) + assert.Equal(t, getCipherText(t), cipherText) +} + +func TestEncryptorEncrypt_IfStorageFailsToStoreEncryptionKey_ReturnError(t *testing.T) { + enc := newDocEncryptor(context.Background()) + st := mocks.NewDSReaderWriter(t) + enc.EnableKeyGeneration() + enc.SetStore(st) + + st.EXPECT().Get(mock.Anything, mock.Anything).Return(nil, ds.ErrNotFound) + + st.EXPECT().Put(mock.Anything, mock.Anything, mock.Anything).Return(testErr) + + _, err := enc.Encrypt(docID, 0, getPlainText()) + + assert.ErrorIs(t, err, testErr) +} + +func TestEncryptorEncrypt_IfKeyGenerationIsNotEnabled_ShouldReturnPlainText(t *testing.T) { + enc := newDocEncryptor(context.Background()) + st := mocks.NewDSReaderWriter(t) + // we don call enc.EnableKeyGeneration() + enc.SetStore(st) + + st.EXPECT().Get(mock.Anything, mock.Anything).Return(nil, ds.ErrNotFound) + + cipherText, err := enc.Encrypt(docID, 0, getPlainText()) + + assert.NoError(t, err) + assert.Equal(t, getPlainText(), cipherText) +} + +func TestEncryptorEncrypt_IfNoStorageProvided_Error(t *testing.T) { + enc := newDocEncryptor(context.Background()) + enc.EnableKeyGeneration() + // we don call enc.SetStore(st) + + _, err := enc.Encrypt(docID, 0, getPlainText()) + + assert.ErrorIs(t, err, ErrNoStorageProvided) +} + +func TestEncryptorDecrypt_IfNoStorageProvided_Error(t *testing.T) { + enc := newDocEncryptor(context.Background()) + enc.EnableKeyGeneration() + // we don call enc.SetStore(st) + + _, err := enc.Decrypt(docID, 0, getPlainText()) + + assert.ErrorIs(t, err, ErrNoStorageProvided) +} + +func TestEncryptorDecrypt_IfStorageReturnsError_Error(t *testing.T) { + enc := newDocEncryptor(context.Background()) + st := mocks.NewDSReaderWriter(t) + enc.SetStore(st) + + st.EXPECT().Get(mock.Anything, mock.Anything).Return(nil, testErr) + + _, err := enc.Decrypt(docID, 0, []byte("test")) + + assert.ErrorIs(t, err, testErr) +} + +func TestEncryptorDecrypt_IfKeyFoundInStorage_ShouldUseItToReturnPlainText(t *testing.T) { + enc := newDocEncryptor(context.Background()) + st := mocks.NewDSReaderWriter(t) + enc.EnableKeyGeneration() + enc.SetStore(st) + + st.EXPECT().Get(mock.Anything, mock.Anything).Return([]byte(testEncryptionKey), nil) + + plainText, err := enc.Decrypt(docID, 0, getCipherText(t)) + + assert.NoError(t, err) + assert.Equal(t, getPlainText(), plainText) +} + +func TestEncryptorDecrypt_IfNoKeyFoundInStorage_ShouldGenerateKeyStoreItAndReturnCipherText(t *testing.T) { + enc := newDocEncryptor(context.Background()) + st := mocks.NewDSReaderWriter(t) + enc.EnableKeyGeneration() + enc.SetStore(st) + + st.EXPECT().Get(mock.Anything, mock.Anything).Return(nil, ds.ErrNotFound) + + storeKey := core.NewEncStoreDocKey(docID, 0) + + st.EXPECT().Put(mock.Anything, storeKey.ToDS(), []byte(testEncryptionKey)).Return(nil) + + cipherText, err := enc.Encrypt(docID, 0, getPlainText()) + + assert.NoError(t, err) + assert.Equal(t, getCipherText(t), cipherText) +} diff --git a/internal/encryption/errors.go b/internal/encryption/errors.go new file mode 100644 index 0000000000..6a443ad834 --- /dev/null +++ b/internal/encryption/errors.go @@ -0,0 +1,23 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package encryption + +import ( + "github.com/sourcenetwork/defradb/errors" +) + +const ( + errNoStorageProvided string = "no storage provided" +) + +var ( + ErrNoStorageProvided = errors.New(errNoStorageProvided) +) diff --git a/internal/encryption/nonce.go b/internal/encryption/nonce.go new file mode 100644 index 0000000000..67a5467a4e --- /dev/null +++ b/internal/encryption/nonce.go @@ -0,0 +1,53 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package encryption + +import ( + "crypto/rand" + "errors" + "io" + "os" + "strings" +) + +const nonceLength = 12 + +var generateNonceFunc = generateNonce + +func generateNonce() ([]byte, error) { + nonce := make([]byte, nonceLength) + if _, err := io.ReadFull(rand.Reader, nonce); err != nil { + return nil, err + } + + return nonce, nil +} + +// generateTestNonce generates a deterministic nonce for testing. +func generateTestNonce() ([]byte, error) { + nonce := []byte("deterministic nonce for testing") + + if len(nonce) < nonceLength { + return nil, errors.New("nonce length is longer than available deterministic nonce") + } + + return nonce[:nonceLength], nil +} + +func init() { + arg := os.Args[0] + // If the binary is a test binary, use a deterministic nonce. + // TODO: We should try to find a better way to detect this https://github.com/sourcenetwork/defradb/issues/2801 + if strings.HasSuffix(arg, ".test") || strings.Contains(arg, "/defradb/tests/") { + generateNonceFunc = generateTestNonce + generateEncryptionKeyFunc = generateTestEncryptionKey + } +} diff --git a/internal/merkle/clock/clock.go b/internal/merkle/clock/clock.go index d16d1d6a5b..1cb79ed756 100644 --- a/internal/merkle/clock/clock.go +++ b/internal/merkle/clock/clock.go @@ -16,6 +16,7 @@ package clock import ( "context" + cid "github.com/ipfs/go-cid" "github.com/ipld/go-ipld-prime/linking" cidlink "github.com/ipld/go-ipld-prime/linking/cid" @@ -24,6 +25,7 @@ import ( "github.com/sourcenetwork/defradb/datastore" "github.com/sourcenetwork/defradb/internal/core" coreblock "github.com/sourcenetwork/defradb/internal/core/block" + "github.com/sourcenetwork/defradb/internal/encryption" ) var ( @@ -34,9 +36,8 @@ var ( type MerkleClock struct { headstore datastore.DSReaderWriter blockstore datastore.Blockstore - // dagSyncer - headset *heads - crdt core.ReplicatedData + headset *heads + crdt core.ReplicatedData } // NewMerkleClock returns a new MerkleClock. @@ -86,7 +87,24 @@ func (mc *MerkleClock) AddDelta( block := coreblock.New(delta, links, heads...) // Write the new block to the dag store. - link, err := mc.putBlock(ctx, block) + isEncrypted, err := mc.checkIfBlockEncryptionEnabled(ctx, heads) + if err != nil { + return cidlink.Link{}, nil, err + } + + dagBlock := block + if isEncrypted { + if !block.Delta.IsComposite() { + dagBlock, err = encryptBlock(ctx, block) + if err != nil { + return cidlink.Link{}, nil, err + } + } else { + dagBlock.IsEncrypted = &isEncrypted + } + } + + link, err := mc.putBlock(ctx, dagBlock) if err != nil { return cidlink.Link{}, nil, err } @@ -96,12 +114,13 @@ func (mc *MerkleClock) AddDelta( ctx, block, link, + false, ) if err != nil { return cidlink.Link{}, nil, err } - b, err := block.Marshal() + b, err := dagBlock.Marshal() if err != nil { return cidlink.Link{}, nil, err } @@ -109,19 +128,68 @@ func (mc *MerkleClock) AddDelta( return link, b, err } +func (mc *MerkleClock) checkIfBlockEncryptionEnabled( + ctx context.Context, + heads []cid.Cid, +) (bool, error) { + encConf := encryption.GetContextConfig(ctx) + if encConf.HasValue() && encConf.Value().IsEncrypted { + return true, nil + } + + for _, headCid := range heads { + bytes, err := mc.blockstore.AsIPLDStorage().Get(ctx, headCid.KeyString()) + if err != nil { + return false, NewErrCouldNotFindBlock(headCid, err) + } + prevBlock, err := coreblock.GetFromBytes(bytes) + if err != nil { + return false, err + } + if prevBlock.IsEncrypted != nil && *prevBlock.IsEncrypted { + return true, nil + } + } + + return false, nil +} + +func encryptBlock(ctx context.Context, block *coreblock.Block) (*coreblock.Block, error) { + clonedCRDT := block.Delta.Clone() + bytes, err := encryption.EncryptDoc(ctx, string(clonedCRDT.GetDocID()), 0, clonedCRDT.GetData()) + if err != nil { + return nil, err + } + clonedCRDT.SetData(bytes) + isEncrypted := true + return &coreblock.Block{Delta: clonedCRDT, Links: block.Links, IsEncrypted: &isEncrypted}, nil +} + // ProcessBlock merges the delta CRDT and updates the state accordingly. +// If onlyHeads is true, it will skip merging and update only the heads. func (mc *MerkleClock) ProcessBlock( ctx context.Context, block *coreblock.Block, blockLink cidlink.Link, + onlyHeads bool, ) error { - priority := block.Delta.GetPriority() - - err := mc.crdt.Merge(ctx, block.Delta.GetDelta()) - if err != nil { - return NewErrMergingDelta(blockLink.Cid, err) + if !onlyHeads { + err := mc.crdt.Merge(ctx, block.Delta.GetDelta()) + if err != nil { + return NewErrMergingDelta(blockLink.Cid, err) + } } + return mc.updateHeads(ctx, block, blockLink) +} + +func (mc *MerkleClock) updateHeads( + ctx context.Context, + block *coreblock.Block, + blockLink cidlink.Link, +) error { + priority := block.Delta.GetPriority() + // check if we have any HEAD links hasHeads := false for _, l := range block.Links { diff --git a/internal/merkle/crdt/counter.go b/internal/merkle/crdt/counter.go index 2553dcfd2f..1ff6874b08 100644 --- a/internal/merkle/crdt/counter.go +++ b/internal/merkle/crdt/counter.go @@ -49,11 +49,11 @@ func NewMerkleCounter( // Save the value of the Counter to the DAG. func (mc *MerkleCounter) Save(ctx context.Context, data any) (cidlink.Link, []byte, error) { - value, ok := data.(*client.FieldValue) + value, ok := data.(*DocField) if !ok { return cidlink.Link{}, nil, NewErrUnexpectedValueType(mc.reg.CType(), &client.FieldValue{}, data) } - bytes, err := value.Bytes() + bytes, err := value.FieldValue.Bytes() if err != nil { return cidlink.Link{}, nil, err } diff --git a/internal/merkle/crdt/errors.go b/internal/merkle/crdt/errors.go index 9e828df5dc..58ee8b6bc4 100644 --- a/internal/merkle/crdt/errors.go +++ b/internal/merkle/crdt/errors.go @@ -1,4 +1,4 @@ -// Copyright 2023 Democratized Data Foundation +// Copyright 2024 Democratized Data Foundation // // Use of this software is governed by the Business Source License // included in the file licenses/BSL.txt. diff --git a/internal/merkle/crdt/field.go b/internal/merkle/crdt/field.go new file mode 100644 index 0000000000..6426165f49 --- /dev/null +++ b/internal/merkle/crdt/field.go @@ -0,0 +1,22 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package merklecrdt + +import "github.com/sourcenetwork/defradb/client" + +// DocField is a struct that holds the document ID and the field value. +// This is used to have a link between the document and the field value. +// For example, to check if the field value needs to be encrypted depending on the document-level +// encryption is enabled or not. +type DocField struct { + DocID string + FieldValue *client.FieldValue +} diff --git a/internal/merkle/crdt/lwwreg.go b/internal/merkle/crdt/lwwreg.go index b8132ccad5..11e73089bf 100644 --- a/internal/merkle/crdt/lwwreg.go +++ b/internal/merkle/crdt/lwwreg.go @@ -47,14 +47,15 @@ func NewMerkleLWWRegister( // Save the value of the register to the DAG. func (mlwwreg *MerkleLWWRegister) Save(ctx context.Context, data any) (cidlink.Link, []byte, error) { - value, ok := data.(*client.FieldValue) + value, ok := data.(*DocField) if !ok { return cidlink.Link{}, nil, NewErrUnexpectedValueType(client.LWW_REGISTER, &client.FieldValue{}, data) } - bytes, err := value.Bytes() + bytes, err := value.FieldValue.Bytes() if err != nil { return cidlink.Link{}, nil, err } + // Set() call on underlying LWWRegister CRDT // persist/publish delta delta := mlwwreg.reg.Set(bytes) diff --git a/internal/merkle/crdt/merklecrdt.go b/internal/merkle/crdt/merklecrdt.go index fc3019b05c..c7733be778 100644 --- a/internal/merkle/crdt/merklecrdt.go +++ b/internal/merkle/crdt/merklecrdt.go @@ -47,7 +47,10 @@ type MerkleClock interface { delta core.Delta, links ...coreblock.DAGLink, ) (cidlink.Link, []byte, error) - ProcessBlock(context.Context, *coreblock.Block, cidlink.Link) error + // ProcessBlock processes a block and updates the CRDT state. + // The bool argument indicates whether only heads need to be updated. It is needed in case + // merge should be skipped for example if the block is encrypted. + ProcessBlock(context.Context, *coreblock.Block, cidlink.Link, bool) error } // baseMerkleCRDT handles the MerkleCRDT overhead functions that aren't CRDT specific like the mutations and state diff --git a/internal/planner/commit.go b/internal/planner/commit.go index 3a5bec39f9..bbb5fdc09c 100644 --- a/internal/planner/commit.go +++ b/internal/planner/commit.go @@ -112,7 +112,7 @@ func (n *dagScanNode) Spans(spans core.Spans) { } for i, span := range headSetSpans.Value { - if span.Start().FieldId != fieldId { + if span.Start().FieldID != fieldId { headSetSpans.Value[i] = core.NewSpan(span.Start().WithFieldId(fieldId), core.DataStoreKey{}) } } diff --git a/internal/planner/create.go b/internal/planner/create.go index 21a36fcc24..b03f2c1765 100644 --- a/internal/planner/create.go +++ b/internal/planner/create.go @@ -15,6 +15,7 @@ import ( "github.com/sourcenetwork/defradb/client/request" "github.com/sourcenetwork/defradb/internal/core" "github.com/sourcenetwork/defradb/internal/db/base" + "github.com/sourcenetwork/defradb/internal/encryption" "github.com/sourcenetwork/defradb/internal/planner/mapper" ) @@ -36,13 +37,12 @@ type createNode struct { collection client.Collection // input map of fields and values - input map[string]any - doc *client.Document + input []map[string]any + docs []*client.Document - err error + didCreate bool - returned bool - results planNode + results planNode execInfo createExecInfo } @@ -56,76 +56,63 @@ func (n *createNode) Kind() string { return "createNode" } func (n *createNode) Init() error { return nil } -func (n *createNode) Start() error { - doc, err := client.NewDocFromMap(n.input, n.collection.Definition()) - if err != nil { - n.err = err - return err +func docIDsToSpans(ids []string, desc client.CollectionDescription) core.Spans { + spans := make([]core.Span, len(ids)) + for i, id := range ids { + docID := base.MakeDataStoreKeyWithCollectionAndDocID(desc, id) + spans[i] = core.NewSpan(docID, docID.PrefixEnd()) } - n.doc = doc - return nil + return core.NewSpans(spans...) } -// Next only returns once. -func (n *createNode) Next() (bool, error) { - n.execInfo.iterations++ - - if n.err != nil { - return false, n.err +func documentsToDocIDs(docs []*client.Document) []string { + docIDs := make([]string, len(docs)) + for i, doc := range docs { + docIDs[i] = doc.ID().String() } + return docIDs +} - if n.returned { - return false, nil - } +func (n *createNode) Start() error { + n.docs = make([]*client.Document, len(n.input)) - if err := n.collection.Create( - n.p.ctx, - n.doc, - ); err != nil { - return false, err + for i, input := range n.input { + doc, err := client.NewDocFromMap(input, n.collection.Definition()) + if err != nil { + return err + } + n.docs[i] = doc } - currentValue := n.documentMapping.NewDoc() + return nil +} - currentValue.SetID(n.doc.ID().String()) - for i, value := range n.doc.Values() { - if len(n.documentMapping.IndexesByName[i.Name()]) > 0 { - n.documentMapping.SetFirstOfName(¤tValue, i.Name(), value.Value()) - } else if aliasName := i.Name() + request.RelatedObjectID; len(n.documentMapping.IndexesByName[aliasName]) > 0 { - n.documentMapping.SetFirstOfName(¤tValue, aliasName, value.Value()) - } else { - return false, client.NewErrFieldNotExist(i.Name()) - } - } +func (n *createNode) Next() (bool, error) { + n.execInfo.iterations++ - n.returned = true - n.currentValue = currentValue + if !n.didCreate { + err := n.collection.CreateMany(n.p.ctx, n.docs) + if err != nil { + return false, err + } - desc := n.collection.Description() - docID := base.MakeDataStoreKeyWithCollectionAndDocID(desc, currentValue.GetID()) - n.results.Spans(core.NewSpans(core.NewSpan(docID, docID.PrefixEnd()))) + n.results.Spans(docIDsToSpans(documentsToDocIDs(n.docs), n.collection.Description())) - err := n.results.Init() - if err != nil { - return false, err - } + err = n.results.Init() + if err != nil { + return false, err + } - err = n.results.Start() - if err != nil { - return false, err + err = n.results.Start() + if err != nil { + return false, err + } + n.didCreate = true } - // get the next result based on our point lookup next, err := n.results.Next() - if err != nil { - return false, err - } - if !next { - return false, nil - } - n.currentValue = n.results.Value() - return true, nil + return next, err } func (n *createNode) Spans(spans core.Spans) { /* no-op */ } @@ -155,7 +142,7 @@ func (n *createNode) Explain(explainType request.ExplainType) (map[string]any, e } } -func (p *Planner) CreateDoc(parsed *mapper.Mutation) (planNode, error) { +func (p *Planner) CreateDocs(parsed *mapper.Mutation) (planNode, error) { results, err := p.Select(&parsed.Select) if err != nil { return nil, err @@ -164,10 +151,17 @@ func (p *Planner) CreateDoc(parsed *mapper.Mutation) (planNode, error) { // create a mutation createNode. create := &createNode{ p: p, - input: parsed.Input, + input: parsed.Inputs, results: results, docMapper: docMapper{parsed.DocumentMapping}, } + if parsed.Input != nil { + create.input = []map[string]any{parsed.Input} + } + + if parsed.Encrypt { + p.ctx = encryption.SetContextConfig(p.ctx, encryption.DocEncConfig{IsEncrypted: true}) + } // get collection col, err := p.db.GetCollectionByName(p.ctx, parsed.Name) diff --git a/internal/planner/explain.go b/internal/planner/explain.go index f6d3f57209..34c3b3b644 100644 --- a/internal/planner/explain.go +++ b/internal/planner/explain.go @@ -342,7 +342,7 @@ func collectExecuteExplainInfo(executedPlan planNode) (map[string]any, error) { // Note: This function only fails if the collection of the datapoints goes wrong, otherwise // even if plan execution fails this function would return the collected datapoints. func (p *Planner) executeAndExplainRequest( - ctx context.Context, + _ context.Context, plan planNode, ) ([]map[string]any, error) { executionSuccess := false diff --git a/internal/planner/mapper/mapper.go b/internal/planner/mapper/mapper.go index be52066b54..858ef0e0ae 100644 --- a/internal/planner/mapper/mapper.go +++ b/internal/planner/mapper/mapper.go @@ -1165,9 +1165,11 @@ func ToMutation(ctx context.Context, store client.Store, mutationRequest *reques } return &Mutation{ - Select: *underlyingSelect, - Type: MutationType(mutationRequest.Type), - Input: mutationRequest.Input, + Select: *underlyingSelect, + Type: MutationType(mutationRequest.Type), + Input: mutationRequest.Input, + Inputs: mutationRequest.Inputs, + Encrypt: mutationRequest.Encrypt, }, nil } diff --git a/internal/planner/mapper/mutation.go b/internal/planner/mapper/mutation.go index a38444e01c..251d01298f 100644 --- a/internal/planner/mapper/mutation.go +++ b/internal/planner/mapper/mutation.go @@ -29,16 +29,10 @@ type Mutation struct { // Input is the map of fields and values used for the mutation. Input map[string]any -} -func (m *Mutation) CloneTo(index int) Requestable { - return m.cloneTo(index) -} + // Inputs is the array of maps of fields and values used for the mutation. + Inputs []map[string]any -func (m *Mutation) cloneTo(index int) *Mutation { - return &Mutation{ - Select: *m.Select.cloneTo(index), - Type: m.Type, - Input: m.Input, - } + // Encrypt is a flag to indicate if the input data should be encrypted. + Encrypt bool } diff --git a/internal/planner/multi.go b/internal/planner/multi.go index 27d6886d7c..de220c43e5 100644 --- a/internal/planner/multi.go +++ b/internal/planner/multi.go @@ -131,7 +131,7 @@ func (p *parallelNode) Next() (bool, error) { return orNext, nil } -func (p *parallelNode) nextMerge(index int, plan planNode) (bool, error) { +func (p *parallelNode) nextMerge(_ int, plan planNode) (bool, error) { if next, err := plan.Next(); !next { return false, err } diff --git a/internal/planner/planner.go b/internal/planner/planner.go index f7a875af70..db7b0510ab 100644 --- a/internal/planner/planner.go +++ b/internal/planner/planner.go @@ -163,7 +163,7 @@ func (p *Planner) newPlan(stmt any) (planNode, error) { func (p *Planner) newObjectMutationPlan(stmt *mapper.Mutation) (planNode, error) { switch stmt.Type { case mapper.CreateObjects: - return p.CreateDoc(stmt) + return p.CreateDocs(stmt) case mapper.UpdateObjects: return p.UpdateDocs(stmt) @@ -528,7 +528,7 @@ func walkAndFindPlanType[T planNode](planNode planNode) (T, bool) { // executeRequest executes the plan graph that represents the request that was made. func (p *Planner) executeRequest( - ctx context.Context, + _ context.Context, planNode planNode, ) ([]map[string]any, error) { if err := planNode.Start(); err != nil { diff --git a/internal/request/graphql/parser/mutation.go b/internal/request/graphql/parser/mutation.go index 92071b6e93..2ed4ebf539 100644 --- a/internal/request/graphql/parser/mutation.go +++ b/internal/request/graphql/parser/mutation.go @@ -102,6 +102,18 @@ func parseMutation(schema gql.Schema, parent *gql.Object, field *ast.Field) (*re if prop == request.Input { // parse input raw := argument.Value.(*ast.ObjectValue) mut.Input = parseMutationInputObject(raw) + } else if prop == request.Inputs { + raw := argument.Value.(*ast.ListValue) + + mut.Inputs = make([]map[string]any, len(raw.Values)) + + for i, val := range raw.Values { + doc, ok := val.(*ast.ObjectValue) + if !ok { + return nil, client.NewErrUnexpectedType[*ast.ObjectValue]("doc array element", val) + } + mut.Inputs[i] = parseMutationInputObject(doc) + } } else if prop == request.FilterClause { // parse filter obj := argument.Value.(*ast.ObjectValue) filterType, ok := getArgumentType(fieldDef, request.FilterClause) @@ -128,6 +140,8 @@ func parseMutation(schema gql.Schema, parent *gql.Object, field *ast.Field) (*re ids[i] = id.Value } mut.DocIDs = immutable.Some(ids) + } else if prop == request.EncryptArgName { + mut.Encrypt = argument.Value.(*ast.BooleanValue).Value } } diff --git a/internal/request/graphql/schema/descriptions.go b/internal/request/graphql/schema/descriptions.go index 6f89932c0a..281002366a 100644 --- a/internal/request/graphql/schema/descriptions.go +++ b/internal/request/graphql/schema/descriptions.go @@ -155,5 +155,10 @@ Indicates as to whether or not this document has been deleted. ` versionFieldDescription string = ` Returns the head commit for this document. +` + + encryptArgDescription string = ` +Encrypt flag specified if the input document(s) needs to be encrypted. If set, DefraDB will generate a +symmetric key for encryption using AES-GCM. ` ) diff --git a/internal/request/graphql/schema/generate.go b/internal/request/graphql/schema/generate.go index 5fd6b5ecf6..82ff15d057 100644 --- a/internal/request/graphql/schema/generate.go +++ b/internal/request/graphql/schema/generate.go @@ -27,6 +27,12 @@ import ( // create a fully DefraDB complaint GraphQL schema using a "code-first" dynamic // approach +const ( + filterInputNameSuffix = "FilterArg" + mutationInputNameSuffix = "MutationInputArg" + mutationInputsNameSuffix = "MutationInputsArg" +) + // Generator creates all the necessary typed schema definitions from an AST Document // and adds them to the Schema via the SchemaManager type Generator struct { @@ -171,7 +177,7 @@ func (g *Generator) generate(ctx context.Context, collections []client.Collectio for name, aggregateTarget := range def.Args { expandedField := &gql.InputObjectFieldConfig{ Description: aggregateFilterArgDescription, - Type: g.manager.schema.TypeMap()[name+"FilterArg"], + Type: g.manager.schema.TypeMap()[name+filterInputNameSuffix], } aggregateTarget.Type.(*gql.InputObject).AddFieldConfig(request.FilterClause, expandedField) } @@ -308,7 +314,7 @@ func (g *Generator) createExpandedFieldAggregate( target := aggregateTarget.Name() var filterTypeName string if target == request.GroupFieldName { - filterTypeName = obj.Name() + "FilterArg" + filterTypeName = obj.Name() + filterInputNameSuffix } else { if targeted := obj.Fields()[target]; targeted != nil { if list, isList := targeted.Type.(*gql.List); isList && gql.IsLeafType(list.OfType) { @@ -319,10 +325,10 @@ func (g *Generator) createExpandedFieldAggregate( // underlying name like this if it is a nullable type. filterTypeName = fmt.Sprintf("NotNull%sFilterArg", notNull.OfType.Name()) } else { - filterTypeName = genTypeName(list.OfType, "FilterArg") + filterTypeName = genTypeName(list.OfType, filterInputNameSuffix) } } else { - filterTypeName = targeted.Type.Name() + "FilterArg" + filterTypeName = targeted.Type.Name() + filterInputNameSuffix } } else { return NewErrAggregateTargetNotFound(obj.Name(), target) @@ -353,7 +359,7 @@ func (g *Generator) createExpandedFieldSingle( Type: t, Args: gql.FieldConfigArgument{ "filter": schemaTypes.NewArgConfig( - g.manager.schema.TypeMap()[typeName+"FilterArg"], + g.manager.schema.TypeMap()[typeName+filterInputNameSuffix], singleFieldFilterArgDescription, ), }, @@ -375,7 +381,7 @@ func (g *Generator) createExpandedFieldList( request.DocIDArgName: schemaTypes.NewArgConfig(gql.String, docIDArgDescription), request.DocIDsArgName: schemaTypes.NewArgConfig(gql.NewList(gql.NewNonNull(gql.String)), docIDsArgDescription), "filter": schemaTypes.NewArgConfig( - g.manager.schema.TypeMap()[typeName+"FilterArg"], + g.manager.schema.TypeMap()[typeName+filterInputNameSuffix], listFieldFilterArgDescription, ), "groupBy": schemaTypes.NewArgConfig( @@ -540,7 +546,7 @@ func (g *Generator) buildMutationInputTypes(collections []client.CollectionDefin // will be reassigned before the thunk is run // TODO remove when Go 1.22 collection := c - mutationInputName := collection.Description.Name.Value() + "MutationInputArg" + mutationInputName := collection.Description.Name.Value() + mutationInputNameSuffix // check if mutation input type exists if _, ok := g.manager.schema.TypeMap()[mutationInputName]; ok { @@ -1027,13 +1033,14 @@ func (g *Generator) GenerateMutationInputForGQLType(obj *gql.Object) ([]*gql.Fie return nil, obj.Error() } - filterInputName := genTypeName(obj, "FilterArg") - mutationInputName := genTypeName(obj, "MutationInputArg") + filterInputName := genTypeName(obj, filterInputNameSuffix) + mutationInputName := genTypeName(obj, mutationInputNameSuffix) filterInput, ok := g.manager.schema.TypeMap()[filterInputName].(*gql.InputObject) if !ok { return nil, NewErrTypeNotFound(filterInputName) } + mutationInput, ok := g.manager.schema.TypeMap()[mutationInputName] if !ok { return nil, NewErrTypeNotFound(mutationInputName) @@ -1044,7 +1051,9 @@ func (g *Generator) GenerateMutationInputForGQLType(obj *gql.Object) ([]*gql.Fie Description: createDocumentDescription, Type: obj, Args: gql.FieldConfigArgument{ - "input": schemaTypes.NewArgConfig(mutationInput, "Create field values"), + "input": schemaTypes.NewArgConfig(mutationInput, "Create a "+obj.Name()+" document"), + "inputs": schemaTypes.NewArgConfig(gql.NewList(mutationInput), "Create "+obj.Name()+" documents"), + "encrypt": schemaTypes.NewArgConfig(gql.Boolean, encryptArgDescription), }, } @@ -1092,7 +1101,7 @@ func (g *Generator) genTypeFilterArgInput(obj *gql.Object) *gql.InputObject { var selfRefType *gql.InputObject inputCfg := gql.InputObjectConfig{ - Name: genTypeName(obj, "FilterArg"), + Name: genTypeName(obj, filterInputNameSuffix), } fieldThunk := (gql.InputObjectConfigFieldMapThunk)( func() (gql.InputObjectConfigFieldMap, error) { @@ -1136,7 +1145,7 @@ func (g *Generator) genTypeFilterArgInput(obj *gql.Object) *gql.InputObject { // We want the FilterArg for the object, not the list of objects. fieldType = l.OfType } - filterType, isFilterable := g.manager.schema.TypeMap()[genTypeName(fieldType, "FilterArg")] + filterType, isFilterable := g.manager.schema.TypeMap()[genTypeName(fieldType, filterInputNameSuffix)] if !isFilterable { filterType = &gql.InputObjectField{} } @@ -1169,7 +1178,7 @@ func (g *Generator) genLeafFilterArgInput(obj gql.Type) *gql.InputObject { } inputCfg := gql.InputObjectConfig{ - Name: fmt.Sprintf("%s%s", filterTypeName, "FilterArg"), + Name: fmt.Sprintf("%s%s", filterTypeName, filterInputNameSuffix), } var fieldThunk gql.InputObjectConfigFieldMapThunk = func() (gql.InputObjectConfigFieldMap, error) { diff --git a/tests/bench/query/planner/utils.go b/tests/bench/query/planner/utils.go index 5a842222f5..b2a6e3c0d6 100644 --- a/tests/bench/query/planner/utils.go +++ b/tests/bench/query/planner/utils.go @@ -134,6 +134,7 @@ type dummyTxn struct{} func (*dummyTxn) Rootstore() datastore.DSReaderWriter { return nil } func (*dummyTxn) Datastore() datastore.DSReaderWriter { return nil } +func (*dummyTxn) Encstore() datastore.DSReaderWriter { return nil } func (*dummyTxn) Headstore() datastore.DSReaderWriter { return nil } func (*dummyTxn) Peerstore() datastore.DSBatching { return nil } func (*dummyTxn) Blockstore() datastore.Blockstore { return nil } diff --git a/tests/clients/cli/wrapper_collection.go b/tests/clients/cli/wrapper_collection.go index 62458dae99..f26142c8e9 100644 --- a/tests/clients/cli/wrapper_collection.go +++ b/tests/clients/cli/wrapper_collection.go @@ -21,6 +21,7 @@ import ( "github.com/sourcenetwork/defradb/client" "github.com/sourcenetwork/defradb/errors" "github.com/sourcenetwork/defradb/http" + "github.com/sourcenetwork/defradb/internal/encryption" ) var _ client.Collection = (*Collection)(nil) @@ -65,6 +66,11 @@ func (c *Collection) Create( args := []string{"client", "collection", "create"} args = append(args, "--name", c.Description().Name.Value()) + encConf := encryption.GetContextConfig(ctx) + if encConf.HasValue() && encConf.Value().IsEncrypted { + args = append(args, "--encrypt") + } + document, err := doc.String() if err != nil { return err @@ -90,21 +96,22 @@ func (c *Collection) CreateMany( args := []string{"client", "collection", "create"} args = append(args, "--name", c.Description().Name.Value()) - docMapList := make([]map[string]any, len(docs)) + encConf := encryption.GetContextConfig(ctx) + if encConf.HasValue() && encConf.Value().IsEncrypted { + args = append(args, "--encrypt") + } + + docStrings := make([]string, len(docs)) for i, doc := range docs { - docMap, err := doc.ToMap() + docStr, err := doc.String() if err != nil { return err } - docMapList[i] = docMap + docStrings[i] = docStr } - documents, err := json.Marshal(docMapList) - if err != nil { - return err - } - args = append(args, string(documents)) + args = append(args, "["+strings.Join(docStrings, ",")+"]") - _, err = c.cmd.execute(ctx, args) + _, err := c.cmd.execute(ctx, args) if err != nil { return err } diff --git a/tests/clients/cli/wrapper_tx.go b/tests/clients/cli/wrapper_tx.go index 0330b8d47e..46aefd000d 100644 --- a/tests/clients/cli/wrapper_tx.go +++ b/tests/clients/cli/wrapper_tx.go @@ -75,6 +75,10 @@ func (w *Transaction) Datastore() datastore.DSReaderWriter { return w.tx.Datastore() } +func (w *Transaction) Encstore() datastore.DSReaderWriter { + return w.tx.Encstore() +} + func (w *Transaction) Headstore() datastore.DSReaderWriter { return w.tx.Headstore() } diff --git a/tests/clients/http/wrapper_tx.go b/tests/clients/http/wrapper_tx.go index 133d3bc1d3..e4b838a2e9 100644 --- a/tests/clients/http/wrapper_tx.go +++ b/tests/clients/http/wrapper_tx.go @@ -69,6 +69,10 @@ func (w *TxWrapper) Datastore() datastore.DSReaderWriter { return w.server.Datastore() } +func (w *TxWrapper) Encstore() datastore.DSReaderWriter { + return w.server.Encstore() +} + func (w *TxWrapper) Headstore() datastore.DSReaderWriter { return w.server.Headstore() } diff --git a/tests/integration/encryption/commit_test.go b/tests/integration/encryption/commit_test.go new file mode 100644 index 0000000000..6a94621b3a --- /dev/null +++ b/tests/integration/encryption/commit_test.go @@ -0,0 +1,356 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package encryption + +import ( + "testing" + + "github.com/sourcenetwork/defradb/internal/encryption" + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func encrypt(plaintext []byte) []byte { + val, _ := encryption.EncryptAES(plaintext, []byte("examplekey1234567890examplekey12")) + return val +} + +func TestDocEncryption_WithEncryptionOnLWWCRDT_ShouldStoreCommitsDeltaEncrypted(t *testing.T) { + const docID = "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3" + + test := testUtils.TestCase{ + Actions: []any{ + updateUserCollectionSchema(), + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "age": 21 + }`, + IsEncrypted: true, + }, + testUtils.Request{ + Request: ` + query { + commits { + cid + collectionID + delta + docID + fieldId + fieldName + height + links { + cid + name + } + } + } + `, + Results: []map[string]any{ + { + "cid": "bafyreih7ry7ef26xn3lm2rhxusf2rbgyvl535tltrt6ehpwtvdnhlmptiu", + "collectionID": int64(1), + "delta": encrypt(testUtils.CBORValue(21)), + "docID": docID, + "fieldId": "1", + "fieldName": "age", + "height": int64(1), + "links": []map[string]any{}, + }, + { + "cid": "bafyreifusejlwidaqswasct37eorazlfix6vyyn5af42pmjvktilzj5cty", + "collectionID": int64(1), + "delta": encrypt(testUtils.CBORValue("John")), + "docID": docID, + "fieldId": "2", + "fieldName": "name", + "height": int64(1), + "links": []map[string]any{}, + }, + { + "cid": "bafyreicvxlfxeqghmc3gy56rp5rzfejnbng4nu77x5e3wjinfydl6wvycq", + "collectionID": int64(1), + "delta": nil, + "docID": docID, + "fieldId": "C", + "fieldName": nil, + "height": int64(1), + "links": []map[string]any{ + { + "cid": "bafyreifusejlwidaqswasct37eorazlfix6vyyn5af42pmjvktilzj5cty", + "name": "name", + }, + { + "cid": "bafyreih7ry7ef26xn3lm2rhxusf2rbgyvl535tltrt6ehpwtvdnhlmptiu", + "name": "age", + }, + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestDocEncryption_UponUpdateOnLWWCRDT_ShouldEncryptCommitDelta(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + updateUserCollectionSchema(), + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "age": 21 + }`, + IsEncrypted: true, + }, + testUtils.UpdateDoc{ + Doc: `{ + "age": 22 + }`, + }, + testUtils.Request{ + Request: ` + query { + commits(fieldId: "1") { + delta + } + } + `, + Results: []map[string]any{ + { + "delta": encrypt(testUtils.CBORValue(22)), + }, + { + "delta": encrypt(testUtils.CBORValue(21)), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestDocEncryption_WithMultipleDocsUponUpdate_ShouldEncryptOnlyRelevantDocs(t *testing.T) { + const johnDocID = "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3" + const islamDocID = "bae-d55bd956-1cc4-5d26-aa71-b98807ad49d6" + + test := testUtils.TestCase{ + Actions: []any{ + updateUserCollectionSchema(), + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "age": 21 + }`, + IsEncrypted: true, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Islam", + "age": 33 + }`, + }, + testUtils.UpdateDoc{ + DocID: 0, + Doc: `{ + "age": 22 + }`, + }, + testUtils.UpdateDoc{ + DocID: 1, + Doc: `{ + "age": 34 + }`, + }, + testUtils.Request{ + Request: ` + query { + commits(fieldId: "1") { + delta + docID + } + } + `, + Results: []map[string]any{ + { + "delta": encrypt(testUtils.CBORValue(22)), + "docID": johnDocID, + }, + { + "delta": encrypt(testUtils.CBORValue(21)), + "docID": johnDocID, + }, + { + "delta": testUtils.CBORValue(34), + "docID": islamDocID, + }, + { + "delta": testUtils.CBORValue(33), + "docID": islamDocID, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestDocEncryption_WithEncryptionOnCounterCRDT_ShouldStoreCommitsDeltaEncrypted(t *testing.T) { + const docID = "bae-d3cc98b4-38d5-5c50-85a3-d3045d44094e" + + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Users { + points: Int @crdt(type: "pcounter") + } + `}, + testUtils.CreateDoc{ + Doc: `{ "points": 5 }`, + IsEncrypted: true, + }, + testUtils.Request{ + Request: ` + query { + commits { + cid + delta + docID + } + } + `, + Results: []map[string]any{ + { + "cid": "bafyreieb6owsoljj4vondkx35ngxmhliauwvphicz4edufcy7biexij7mu", + "delta": encrypt(testUtils.CBORValue(5)), + "docID": docID, + }, + { + "cid": "bafyreif2lejhvdja2rmo237lrwpj45usrm55h6gzr4ewl6gajq3cl4ppsi", + "delta": nil, + "docID": docID, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestDocEncryption_UponUpdateOnCounterCRDT_ShouldEncryptedCommitDelta(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Users { + points: Int @crdt(type: "pcounter") + } + `}, + testUtils.CreateDoc{ + Doc: `{ "points": 5 }`, + IsEncrypted: true, + }, + testUtils.UpdateDoc{ + Doc: `{ + "points": 3 + }`, + }, + testUtils.Request{ + Request: ` + query { + commits(fieldId: "1") { + delta + } + } + `, + Results: []map[string]any{ + { + "delta": encrypt(testUtils.CBORValue(3)), + }, + { + "delta": encrypt(testUtils.CBORValue(5)), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestDocEncryption_UponEncryptionSeveralDocs_ShouldStoreAllCommitsDeltaEncrypted(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + updateUserCollectionSchema(), + testUtils.CreateDoc{ + Doc: `[{ + "name": "John", + "age": 21 + }, + { + "name": "Islam", + "age": 33 + }]`, + IsEncrypted: true, + }, + testUtils.Request{ + Request: ` + query { + commits { + cid + delta + docID + } + } + `, + Results: []map[string]any{ + { + "cid": "bafyreih7ry7ef26xn3lm2rhxusf2rbgyvl535tltrt6ehpwtvdnhlmptiu", + "delta": encrypt(testUtils.CBORValue(21)), + "docID": testUtils.NewDocIndex(0, 0), + }, + { + "cid": "bafyreifusejlwidaqswasct37eorazlfix6vyyn5af42pmjvktilzj5cty", + "delta": encrypt(testUtils.CBORValue("John")), + "docID": testUtils.NewDocIndex(0, 0), + }, + { + "cid": "bafyreicvxlfxeqghmc3gy56rp5rzfejnbng4nu77x5e3wjinfydl6wvycq", + "delta": nil, + "docID": testUtils.NewDocIndex(0, 0), + }, + { + "cid": "bafyreibe24bo67owxewoso3ekinera2bhusguij5qy2ahgyufaq3fbvaxa", + "delta": encrypt(testUtils.CBORValue(33)), + "docID": testUtils.NewDocIndex(0, 1), + }, + { + "cid": "bafyreie2fddpidgc62fhd2fjrsucq3spgh2mgvto2xwolcdmdhb5pdeok4", + "delta": encrypt(testUtils.CBORValue("Islam")), + "docID": testUtils.NewDocIndex(0, 1), + }, + { + "cid": "bafyreifulxdkf4m3wmmdxjg43l4mw7uuxl5il27eabklc22nptilrh64sa", + "delta": nil, + "docID": testUtils.NewDocIndex(0, 1), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/encryption/peer_test.go b/tests/integration/encryption/peer_test.go new file mode 100644 index 0000000000..6d9c937278 --- /dev/null +++ b/tests/integration/encryption/peer_test.go @@ -0,0 +1,147 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package encryption + +import ( + "testing" + + "github.com/sourcenetwork/immutable" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestDocEncryptionPeer_IfPeerHasNoKey_ShouldNotFetch(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.RandomNetworkingConfig(), + testUtils.RandomNetworkingConfig(), + updateUserCollectionSchema(), + testUtils.ConnectPeers{ + SourceNodeID: 1, + TargetNodeID: 0, + }, + testUtils.SubscribeToCollection{ + NodeID: 1, + CollectionIDs: []int{0}, + }, + testUtils.CreateDoc{ + NodeID: immutable.Some(0), + Doc: `{ + "name": "John", + "age": 21 + }`, + IsEncrypted: true, + }, + testUtils.WaitForSync{}, + testUtils.Request{ + NodeID: immutable.Some(1), + Request: `query { + Users { + age + } + }`, + Results: []map[string]any{}, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestDocEncryptionPeer_UponSync_ShouldSyncEncryptedDAG(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.RandomNetworkingConfig(), + testUtils.RandomNetworkingConfig(), + updateUserCollectionSchema(), + testUtils.ConnectPeers{ + SourceNodeID: 1, + TargetNodeID: 0, + }, + testUtils.SubscribeToCollection{ + NodeID: 1, + CollectionIDs: []int{0}, + }, + testUtils.CreateDoc{ + NodeID: immutable.Some(0), + Doc: `{ + "name": "John", + "age": 21 + }`, + IsEncrypted: true, + }, + testUtils.WaitForSync{}, + testUtils.Request{ + NodeID: immutable.Some(1), + Request: ` + query { + commits { + cid + collectionID + delta + docID + fieldId + fieldName + height + links { + cid + name + } + } + } + `, + Results: []map[string]any{ + { + "cid": "bafyreih7ry7ef26xn3lm2rhxusf2rbgyvl535tltrt6ehpwtvdnhlmptiu", + "collectionID": int64(1), + "delta": encrypt(testUtils.CBORValue(21)), + "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", + "fieldId": "1", + "fieldName": "age", + "height": int64(1), + "links": []map[string]any{}, + }, + { + "cid": "bafyreifusejlwidaqswasct37eorazlfix6vyyn5af42pmjvktilzj5cty", + "collectionID": int64(1), + "delta": encrypt(testUtils.CBORValue("John")), + "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", + "fieldId": "2", + "fieldName": "name", + "height": int64(1), + "links": []map[string]any{}, + }, + { + "cid": "bafyreicvxlfxeqghmc3gy56rp5rzfejnbng4nu77x5e3wjinfydl6wvycq", + "collectionID": int64(1), + "delta": nil, + "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", + "fieldId": "C", + "fieldName": nil, + "height": int64(1), + "links": []map[string]any{ + { + "cid": "bafyreifusejlwidaqswasct37eorazlfix6vyyn5af42pmjvktilzj5cty", + "name": "name", + }, + { + "cid": "bafyreih7ry7ef26xn3lm2rhxusf2rbgyvl535tltrt6ehpwtvdnhlmptiu", + "name": "age", + }, + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/encryption/query_test.go b/tests/integration/encryption/query_test.go new file mode 100644 index 0000000000..32d9bd2c94 --- /dev/null +++ b/tests/integration/encryption/query_test.go @@ -0,0 +1,110 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package encryption + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestDocEncryption_WithEncryption_ShouldFetchDecrypted(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Users { + name: String + age: Int + } + `}, + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "age": 21 + }`, + IsEncrypted: true, + }, + testUtils.Request{ + Request: ` + query { + Users { + _docID + name + age + } + }`, + Results: []map[string]any{ + { + "_docID": testUtils.NewDocIndex(0, 0), + "name": "John", + "age": int64(21), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestDocEncryption_WithEncryptionOnCounterCRDT_ShouldFetchDecrypted(t *testing.T) { + const query = ` + query { + Users { + name + points + } + }` + + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Users { + name: String + points: Int @crdt(type: "pcounter") + } + `}, + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "points": 5 + }`, + IsEncrypted: true, + }, + testUtils.Request{ + Request: query, + Results: []map[string]any{ + { + "name": "John", + "points": 5, + }, + }, + }, + testUtils.UpdateDoc{ + DocID: 0, + Doc: `{ "points": 3 }`, + }, + testUtils.Request{ + Request: query, + Results: []map[string]any{ + { + "name": "John", + "points": 8, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/encryption/utils.go b/tests/integration/encryption/utils.go new file mode 100644 index 0000000000..400a0d34c3 --- /dev/null +++ b/tests/integration/encryption/utils.go @@ -0,0 +1,31 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package encryption + +import ( + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +// we explicitly set LWW CRDT type because we want to test encryption with this specific CRDT type +// and we don't wat to rely on the default behavior +const userCollectionGQLSchema = (` + type Users { + name: String + age: Int @crdt(type: "lww") + verified: Boolean + } +`) + +func updateUserCollectionSchema() testUtils.SchemaUpdate { + return testUtils.SchemaUpdate{ + Schema: userCollectionGQLSchema, + } +} diff --git a/tests/integration/events/simple/with_update_test.go b/tests/integration/events/simple/with_update_test.go index 0b49486aa4..2d5fbfc5fe 100644 --- a/tests/integration/events/simple/with_update_test.go +++ b/tests/integration/events/simple/with_update_test.go @@ -49,17 +49,18 @@ func TestEventsSimpleWithUpdate(t *testing.T) { "Users": []func(c client.Collection){ func(c client.Collection) { err = c.Save(context.Background(), doc1) - assert.Nil(t, err) + assert.NoError(t, err) }, func(c client.Collection) { err = c.Save(context.Background(), doc2) - assert.Nil(t, err) + assert.NoError(t, err) }, func(c client.Collection) { // Update John - doc1.Set("name", "Johnnnnn") + err = doc1.Set("name", "Johnnnnn") + assert.NoError(t, err) err = c.Save(context.Background(), doc1) - assert.Nil(t, err) + assert.NoError(t, err) }, }, }, diff --git a/tests/integration/explain/default/create_test.go b/tests/integration/explain/default/create_test.go index dc57671bdd..3fdccc8b44 100644 --- a/tests/integration/explain/default/create_test.go +++ b/tests/integration/explain/default/create_test.go @@ -52,11 +52,11 @@ func TestDefaultExplainMutationRequestWithCreate(t *testing.T) { TargetNodeName: "createNode", IncludeChildNodes: false, ExpectedAttributes: dataMap{ - "input": dataMap{ + "input": []dataMap{{ "age": int32(27), "name": "Shahzad Lone", "verified": true, - }, + }}, }, }, }, @@ -90,10 +90,10 @@ func TestDefaultExplainMutationRequestDoesNotCreateDocGivenDuplicate(t *testing. TargetNodeName: "createNode", IncludeChildNodes: false, ExpectedAttributes: dataMap{ - "input": dataMap{ + "input": []dataMap{{ "age": int32(27), "name": "Shahzad Lone", - }, + }}, }, }, }, diff --git a/tests/integration/explain/execute/create_test.go b/tests/integration/explain/execute/create_test.go index 58736edb90..54876b57f5 100644 --- a/tests/integration/explain/execute/create_test.go +++ b/tests/integration/explain/execute/create_test.go @@ -42,10 +42,10 @@ func TestExecuteExplainMutationRequestWithCreate(t *testing.T) { "iterations": uint64(2), "selectTopNode": dataMap{ "selectNode": dataMap{ - "iterations": uint64(1), + "iterations": uint64(2), "filterMatches": uint64(1), "scanNode": dataMap{ - "iterations": uint64(1), + "iterations": uint64(2), "docFetches": uint64(1), "fieldFetches": uint64(1), "indexFetches": uint64(0), diff --git a/tests/integration/gql.go b/tests/integration/gql.go index 22a368adf7..1f6cd26d6e 100644 --- a/tests/integration/gql.go +++ b/tests/integration/gql.go @@ -14,15 +14,27 @@ import ( "encoding/json" "fmt" "strings" + + "github.com/sourcenetwork/defradb/client" ) -// jsonToGql transforms a json doc string to a gql string. +// jsonToGQL transforms a json doc string to a gql string. func jsonToGQL(val string) (string, error) { - var doc map[string]any - if err := json.Unmarshal([]byte(val), &doc); err != nil { - return "", err + bytes := []byte(val) + + if client.IsJSONArray(bytes) { + var doc []map[string]any + if err := json.Unmarshal(bytes, &doc); err != nil { + return "", err + } + return arrayToGQL(doc) + } else { + var doc map[string]any + if err := json.Unmarshal(bytes, &doc); err != nil { + return "", err + } + return mapToGQL(doc) } - return mapToGQL(doc) } // valueToGQL transforms a value to a gql string. @@ -41,7 +53,7 @@ func valueToGQL(val any) (string, error) { return string(out), nil } -// mapToGql transforms a map to a gql string. +// mapToGQL transforms a map to a gql string. func mapToGQL(val map[string]any) (string, error) { var entries []string for k, v := range val { @@ -66,3 +78,16 @@ func sliceToGQL(val []any) (string, error) { } return fmt.Sprintf("[%s]", strings.Join(entries, ",")), nil } + +// arrayToGQL transforms an array of maps to a gql string. +func arrayToGQL(val []map[string]any) (string, error) { + var entries []string + for _, v := range val { + out, err := mapToGQL(v) + if err != nil { + return "", err + } + entries = append(entries, out) + } + return fmt.Sprintf("[%s]", strings.Join(entries, ",")), nil +} diff --git a/tests/integration/mutation/create/simple_create_many_test.go b/tests/integration/mutation/create/simple_create_many_test.go new file mode 100644 index 0000000000..5f1e425549 --- /dev/null +++ b/tests/integration/mutation/create/simple_create_many_test.go @@ -0,0 +1,70 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package create + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestMutationCreateMany(t *testing.T) { + test := testUtils.TestCase{ + Description: "Simple create many mutation", + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Users { + name: String + age: Int + } + `, + }, + testUtils.CreateDoc{ + Doc: `[ + { + "name": "John", + "age": 27 + }, + { + "name": "Islam", + "age": 33 + } + ]`, + }, + testUtils.Request{ + Request: ` + query { + Users { + _docID + name + age + } + } + `, + Results: []map[string]any{ + { + "_docID": "bae-48339725-ed14-55b1-8e63-3fda5f590725", + "name": "Islam", + "age": int64(33), + }, + { + "_docID": "bae-8c89a573-c287-5d8c-8ba6-c47c814c594d", + "name": "John", + "age": int64(27), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/test_case.go b/tests/integration/test_case.go index 4536c0cd0a..948ae1838e 100644 --- a/tests/integration/test_case.go +++ b/tests/integration/test_case.go @@ -230,6 +230,9 @@ type CreateDoc struct { // created document(s) will be owned by this Identity. Identity immutable.Option[acpIdentity.Identity] + // Specifies whether the document should be encrypted. + IsEncrypted bool + // The collection in which this document should be created. CollectionID int diff --git a/tests/integration/utils2.go b/tests/integration/utils2.go index fab8cc5ed9..5012642f22 100644 --- a/tests/integration/utils2.go +++ b/tests/integration/utils2.go @@ -12,6 +12,7 @@ package tests import ( "context" + "encoding/json" "fmt" "os" "reflect" @@ -28,12 +29,14 @@ import ( "github.com/stretchr/testify/require" "github.com/sourcenetwork/defradb/client" + "github.com/sourcenetwork/defradb/client/request" "github.com/sourcenetwork/defradb/crypto" "github.com/sourcenetwork/defradb/datastore" badgerds "github.com/sourcenetwork/defradb/datastore/badger/v4" "github.com/sourcenetwork/defradb/errors" "github.com/sourcenetwork/defradb/event" "github.com/sourcenetwork/defradb/internal/db" + "github.com/sourcenetwork/defradb/internal/encryption" "github.com/sourcenetwork/defradb/internal/request/graphql" "github.com/sourcenetwork/defradb/net" changeDetector "github.com/sourcenetwork/defradb/tests/change_detector" @@ -105,6 +108,7 @@ func init() { if value, ok := os.LookupEnv(skipNetworkTestsEnvName); ok { skipNetworkTests, _ = strconv.ParseBool(value) } + mutationType = GQLRequestMutationType } // AssertPanic asserts that the code inside the specified PanicTestFunc panics. @@ -882,7 +886,8 @@ func refreshDocuments( continue } - ctx := db.SetContextIdentity(s.ctx, action.Identity) + ctx := makeContextForDocCreate(s.ctx, &action) + // The document may have been mutated by other actions, so to be sure we have the latest // version without having to worry about the individual update mechanics we fetch it. doc, err = collection.Get(ctx, doc.ID(), false) @@ -1169,7 +1174,7 @@ func createDoc( substituteRelations(s, action) } - var mutation func(*state, CreateDoc, client.DB, []client.Collection) (*client.Document, error) + var mutation func(*state, CreateDoc, client.DB, []client.Collection) ([]*client.Document, error) switch mutationType { case CollectionSaveMutationType: @@ -1183,7 +1188,7 @@ func createDoc( } var expectedErrorRaised bool - var doc *client.Document + var docs []*client.Document actionNodes := getNodes(action.NodeID, s.nodes) for nodeID, collections := range getNodeCollections(action.NodeID, s.collections) { err := withRetry( @@ -1191,7 +1196,7 @@ func createDoc( nodeID, func() error { var err error - doc, err = mutation(s, action, actionNodes[nodeID], collections) + docs, err = mutation(s, action, actionNodes[nodeID], collections) return err }, ) @@ -1204,7 +1209,7 @@ func createDoc( // Expand the slice if required, so that the document can be accessed by collection index s.documents = append(s.documents, make([][]*client.Document, action.CollectionID-len(s.documents)+1)...) } - s.documents[action.CollectionID] = append(s.documents[action.CollectionID], doc) + s.documents[action.CollectionID] = append(s.documents[action.CollectionID], docs...) } func createDocViaColSave( @@ -1212,13 +1217,21 @@ func createDocViaColSave( action CreateDoc, node client.DB, collections []client.Collection, -) (*client.Document, error) { - var err error +) ([]*client.Document, error) { + var docs []*client.Document var doc *client.Document + var err error if action.DocMap != nil { doc, err = client.NewDocFromMap(action.DocMap, collections[action.CollectionID].Definition()) + docs = []*client.Document{doc} } else { - doc, err = client.NewDocFromJSON([]byte(action.Doc), collections[action.CollectionID].Definition()) + bytes := []byte(action.Doc) + if client.IsJSONArray(bytes) { + docs, err = client.NewDocsFromJSON(bytes, collections[action.CollectionID].Definition()) + } else { + doc, err = client.NewDocFromJSON(bytes, collections[action.CollectionID].Definition()) + docs = []*client.Document{doc} + } } if err != nil { return nil, err @@ -1226,10 +1239,23 @@ func createDocViaColSave( txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) - ctx := db.SetContextTxn(s.ctx, txn) - ctx = db.SetContextIdentity(ctx, action.Identity) + ctx := makeContextForDocCreate(db.SetContextTxn(s.ctx, txn), &action) - return doc, collections[action.CollectionID].Save(ctx, doc) + for _, doc := range docs { + err = collections[action.CollectionID].Save(ctx, doc) + if err != nil { + return nil, err + } + } + return docs, nil +} + +func makeContextForDocCreate(ctx context.Context, action *CreateDoc) context.Context { + ctx = db.SetContextIdentity(ctx, action.Identity) + if action.IsEncrypted { + ctx = encryption.SetContextConfig(ctx, encryption.DocEncConfig{IsEncrypted: true}) + } + return ctx } func createDocViaColCreate( @@ -1237,13 +1263,20 @@ func createDocViaColCreate( action CreateDoc, node client.DB, collections []client.Collection, -) (*client.Document, error) { - var err error +) ([]*client.Document, error) { + var docs []*client.Document var doc *client.Document + var err error if action.DocMap != nil { doc, err = client.NewDocFromMap(action.DocMap, collections[action.CollectionID].Definition()) + docs = []*client.Document{doc} } else { - doc, err = client.NewDocFromJSON([]byte(action.Doc), collections[action.CollectionID].Definition()) + if client.IsJSONArray([]byte(action.Doc)) { + docs, err = client.NewDocsFromJSON([]byte(action.Doc), collections[action.CollectionID].Definition()) + } else { + doc, err = client.NewDocFromJSON([]byte(action.Doc), collections[action.CollectionID].Definition()) + docs = []*client.Document{doc} + } } if err != nil { return nil, err @@ -1251,10 +1284,15 @@ func createDocViaColCreate( txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) - ctx := db.SetContextTxn(s.ctx, txn) - ctx = db.SetContextIdentity(ctx, action.Identity) + ctx := makeContextForDocCreate(db.SetContextTxn(s.ctx, txn), &action) - return doc, collections[action.CollectionID].Create(ctx, doc) + if len(docs) > 1 { + err = collections[action.CollectionID].CreateMany(ctx, docs) + } else { + err = collections[action.CollectionID].Create(ctx, doc) + } + + return docs, err } func createDocViaGQL( @@ -1262,37 +1300,47 @@ func createDocViaGQL( action CreateDoc, node client.DB, collections []client.Collection, -) (*client.Document, error) { +) ([]*client.Document, error) { collection := collections[action.CollectionID] - var err error var input string + paramName := request.Input + + var err error if action.DocMap != nil { input, err = valueToGQL(action.DocMap) + } else if client.IsJSONArray([]byte(action.Doc)) { + var docMaps []map[string]any + err = json.Unmarshal([]byte(action.Doc), &docMaps) + require.NoError(s.t, err) + paramName = request.Inputs + input, err = arrayToGQL(docMaps) } else { input, err = jsonToGQL(action.Doc) } require.NoError(s.t, err) - request := fmt.Sprintf( + params := paramName + ": " + input + + if action.IsEncrypted { + params = params + ", " + request.EncryptArgName + ": true" + } + + req := fmt.Sprintf( `mutation { - create_%s(input: %s) { + create_%s(%s) { _docID } }`, collection.Name().Value(), - input, + params, ) txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) - ctx := db.SetContextTxn(s.ctx, txn) - ctx = db.SetContextIdentity(ctx, action.Identity) + ctx := makeContextForDocCreate(db.SetContextTxn(s.ctx, txn), &action) - result := node.ExecRequest( - ctx, - request, - ) + result := node.ExecRequest(ctx, req) if len(result.GQL.Errors) > 0 { return nil, result.GQL.Errors[0] } @@ -1302,14 +1350,20 @@ func createDocViaGQL( return nil, nil } - docIDString := resultantDocs[0]["_docID"].(string) - docID, err := client.NewDocIDFromString(docIDString) - require.NoError(s.t, err) + docs := make([]*client.Document, len(resultantDocs)) - doc, err := collection.Get(ctx, docID, false) - require.NoError(s.t, err) + for i, docMap := range resultantDocs { + docIDString := docMap[request.DocIDFieldName].(string) + docID, err := client.NewDocIDFromString(docIDString) + require.NoError(s.t, err) + + doc, err := collection.Get(ctx, docID, false) + require.NoError(s.t, err) + + docs[i] = doc + } - return doc, nil + return docs, nil } // substituteRelations scans the fields defined in [action.DocMap], if any are of type [DocIndex] From 1acc084c216f14378cf3256d098d8a0c92a5d08d Mon Sep 17 00:00:00 2001 From: AndrewSisley Date: Tue, 9 Jul 2024 10:56:34 -0400 Subject: [PATCH 06/41] fix: Allow querying of 9th, 19th, 29th, etc collections (#2819) ## Relevant issue(s) Resolves #2810 ## Description Allows querying of 9th, 19th, 29th, etc collections. The fetcher calls `PrefixEnd` which causes the start prefix to be (e.g.) `"/9"` and the end `"/10"` causing nothing to be returned to the user. This PR fixes that by encoding the DataStore CollectionRootIDs as variable sized BigEndians. https://github.com/sourcenetwork/defradb/issues/2818 has been broken out of this as it is not a user-visible issue atm and resolving it is a bit more involved due to some legacy tech. debt. --- .../i2810-allow-query-of-nth-cols.md | 3 + internal/core/data_test.go | 712 +++++++++--------- internal/core/encoding.go | 81 ++ internal/core/key.go | 48 +- internal/core/key_test.go | 80 -- internal/db/indexed_docs_test.go | 2 +- internal/planner/scan.go | 6 +- .../query/simple/with_multiple_types_test.go | 331 ++++++++ tests/integration/utils2.go | 1 - 9 files changed, 789 insertions(+), 475 deletions(-) create mode 100644 docs/data_format_changes/i2810-allow-query-of-nth-cols.md create mode 100644 tests/integration/query/simple/with_multiple_types_test.go diff --git a/docs/data_format_changes/i2810-allow-query-of-nth-cols.md b/docs/data_format_changes/i2810-allow-query-of-nth-cols.md new file mode 100644 index 0000000000..d1dd33008b --- /dev/null +++ b/docs/data_format_changes/i2810-allow-query-of-nth-cols.md @@ -0,0 +1,3 @@ +# Allow querying of 9th, 19th, 29th, etc collections + +The way collection root id was encoded in the datastore has changed from a human friendly string representation to a variable-size, big endian, machine-friendly representation. diff --git a/internal/core/data_test.go b/internal/core/data_test.go index 1ba5a71611..ae3580528f 100644 --- a/internal/core/data_test.go +++ b/internal/core/data_test.go @@ -25,678 +25,678 @@ func TestMergeAscending_ReturnsEmpty_GivenEmpty(t *testing.T) { } func TestMergeAscending_ReturnsSingle_GivenSingle(t *testing.T) { - start1 := "/1/p/0/k1" - end1 := "/1/p/0/k2" - input := []Span{NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1))} + start1 := MustNewDataStoreKey("/1/p/0/k1") + end1 := MustNewDataStoreKey("/1/p/0/k2") + input := []Span{NewSpan(start1, end1)} result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end1, result[0].End()) } func TestMergeAscending_ReturnsSecondBeforeFirst_GivenKeysInReverseOrder(t *testing.T) { - start1 := "/1/p/0/k4" - end1 := "/1/p/0/k5" - start2 := "/1/p/0/k1" - end2 := "/1/p/0/k2" + start1 := MustNewDataStoreKey("/1/p/0/k4") + end1 := MustNewDataStoreKey("/1/p/0/k5") + start2 := MustNewDataStoreKey("/1/p/0/k1") + end2 := MustNewDataStoreKey("/1/p/0/k2") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 2) - assert.Equal(t, start2, result[0].Start().ToString()) - assert.Equal(t, end2, result[0].End().ToString()) - assert.Equal(t, start1, result[1].Start().ToString()) - assert.Equal(t, end1, result[1].End().ToString()) + assert.Equal(t, start2, result[0].Start()) + assert.Equal(t, end2, result[0].End()) + assert.Equal(t, start1, result[1].Start()) + assert.Equal(t, end1, result[1].End()) } func TestMergeAscending_ReturnsItemsInOrder_GivenKeysInMixedOrder(t *testing.T) { - start1 := "/1/p/0/k1" - end1 := "/1/p/0/k2" - start2 := "/1/p/0/k7" - end2 := "/1/p/0/k8" - start3 := "/1/p/0/k4" - end3 := "/1/p/0/k5" + start1 := MustNewDataStoreKey("/1/p/0/k1") + end1 := MustNewDataStoreKey("/1/p/0/k2") + start2 := MustNewDataStoreKey("/1/p/0/k7") + end2 := MustNewDataStoreKey("/1/p/0/k8") + start3 := MustNewDataStoreKey("/1/p/0/k4") + end3 := MustNewDataStoreKey("/1/p/0/k5") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), - NewSpan(MustNewDataStoreKey(start3), MustNewDataStoreKey(end3)), + NewSpan(start1, end1), + NewSpan(start2, end2), + NewSpan(start3, end3), } result := MergeAscending(input) assert.Len(t, result, 3) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end1, result[0].End()) // Span 3 should be returned between one and two - assert.Equal(t, start3, result[1].Start().ToString()) - assert.Equal(t, end3, result[1].End().ToString()) - assert.Equal(t, start2, result[2].Start().ToString()) - assert.Equal(t, end2, result[2].End().ToString()) + assert.Equal(t, start3, result[1].Start()) + assert.Equal(t, end3, result[1].End()) + assert.Equal(t, start2, result[2].Start()) + assert.Equal(t, end2, result[2].End()) } func TestMergeAscending_ReturnsSingle_GivenStartBeforeEndEqualToStart(t *testing.T) { - start1 := "/1/p/0/k3" - end1 := "/1/p/0/k4" - start2 := "/1/p/0/k1" - end2 := "/1/p/0/k3" + start1 := MustNewDataStoreKey("/1/p/0/k3") + end1 := MustNewDataStoreKey("/1/p/0/k4") + start2 := MustNewDataStoreKey("/1/p/0/k1") + end2 := MustNewDataStoreKey("/1/p/0/k3") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start2, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start2, result[0].Start()) + assert.Equal(t, end1, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenStartBeforeEndAdjacentToStart(t *testing.T) { - start1 := "/1/p/0/k3" - end1 := "/1/p/0/k4" - start2 := "/1/p/0/k1" - end2 := "/1/p/0/k2" + start1 := MustNewDataStoreKey("/1/p/0/k3") + end1 := MustNewDataStoreKey("/1/p/0/k4") + start2 := MustNewDataStoreKey("/1/p/0/k1") + end2 := MustNewDataStoreKey("/1/p/0/k2") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start2, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start2, result[0].Start()) + assert.Equal(t, end1, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenStartBeforeEndWithin(t *testing.T) { - start1 := "/1/p/0/k3" - end1 := "/1/p/0/k4" - start2 := "/1/p/0/k1" - end2 := "/1/p/0/k3.5" + start1 := MustNewDataStoreKey("/1/p/0/k3") + end1 := MustNewDataStoreKey("/1/p/0/k4") + start2 := MustNewDataStoreKey("/1/p/0/k1") + end2 := MustNewDataStoreKey("/1/p/0/k3.5") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start2, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start2, result[0].Start()) + assert.Equal(t, end1, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenStartPrefixesEndWithin(t *testing.T) { - start1 := "/1/p/0/k1.1" - end1 := "/1/p/0/k3" - start2 := "/1/p/0/k1" - end2 := "/1/p/0/k2.5" + start1 := MustNewDataStoreKey("/1/p/0/k1.1") + end1 := MustNewDataStoreKey("/1/p/0/k3") + start2 := MustNewDataStoreKey("/1/p/0/k1") + end2 := MustNewDataStoreKey("/1/p/0/k2.5") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start2, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start2, result[0].Start()) + assert.Equal(t, end1, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenStartBeforeEndWithinEndPrefix(t *testing.T) { - start1 := "/1/p/0/k3" - end1 := "/1/p/0/k4" - start2 := "/1/p/0/k1" - end2 := "/1/p/0/k4.5" + start1 := MustNewDataStoreKey("/1/p/0/k3") + end1 := MustNewDataStoreKey("/1/p/0/k4") + start2 := MustNewDataStoreKey("/1/p/0/k1") + end2 := MustNewDataStoreKey("/1/p/0/k4.5") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start2, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start2, result[0].Start()) + assert.Equal(t, end1, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenStartPrefixesEndWithinEndPrefix(t *testing.T) { - start1 := "/1/p/0/k1.1" - end1 := "/1/p/0/k3" - start2 := "/1/p/0/k1" - end2 := "/1/p/0/k3.5" + start1 := MustNewDataStoreKey("/1/p/0/k1.1") + end1 := MustNewDataStoreKey("/1/p/0/k3") + start2 := MustNewDataStoreKey("/1/p/0/k1") + end2 := MustNewDataStoreKey("/1/p/0/k3.5") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start2, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start2, result[0].Start()) + assert.Equal(t, end1, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenStartBeforeEndEqual(t *testing.T) { - start1 := "/1/p/0/k3" - end1 := "/1/p/0/k4" - start2 := "/1/p/0/k1" - end2 := "/1/p/0/k4" + start1 := MustNewDataStoreKey("/1/p/0/k3") + end1 := MustNewDataStoreKey("/1/p/0/k4") + start2 := MustNewDataStoreKey("/1/p/0/k1") + end2 := MustNewDataStoreKey("/1/p/0/k4") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start2, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start2, result[0].Start()) + assert.Equal(t, end1, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenStartBeforeEndAdjacentAndBefore(t *testing.T) { - start1 := "/1/p/0/k3" - end1 := "/1/p/0/k5" - start2 := "/1/p/0/k1" - end2 := "/1/p/0/k4" + start1 := MustNewDataStoreKey("/1/p/0/k3") + end1 := MustNewDataStoreKey("/1/p/0/k5") + start2 := MustNewDataStoreKey("/1/p/0/k1") + end2 := MustNewDataStoreKey("/1/p/0/k4") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start2, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start2, result[0].Start()) + assert.Equal(t, end1, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenStartBeforeEndAdjacentAndGreater(t *testing.T) { - start1 := "/1/p/0/k3" - end1 := "/1/p/0/k4" - start2 := "/1/p/0/k1" - end2 := "/1/p/0/k5" + start1 := MustNewDataStoreKey("/1/p/0/k3") + end1 := MustNewDataStoreKey("/1/p/0/k4") + start2 := MustNewDataStoreKey("/1/p/0/k1") + end2 := MustNewDataStoreKey("/1/p/0/k5") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start2, result[0].Start().ToString()) - assert.Equal(t, end2, result[0].End().ToString()) + assert.Equal(t, start2, result[0].Start()) + assert.Equal(t, end2, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenStartPrefixesEndEqual(t *testing.T) { - start1 := "/1/p/0/k1.1" - end1 := "/1/p/0/k3" - start2 := "/1/p/0/k1" - end2 := "/1/p/0/k3" + start1 := MustNewDataStoreKey("/1/p/0/k1.1") + end1 := MustNewDataStoreKey("/1/p/0/k3") + start2 := MustNewDataStoreKey("/1/p/0/k1") + end2 := MustNewDataStoreKey("/1/p/0/k3") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start2, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start2, result[0].Start()) + assert.Equal(t, end1, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenStartPrefixesEndAdjacentAndBefore(t *testing.T) { - start1 := "/1/p/0/k1.1" - end1 := "/1/p/0/k3" - start2 := "/1/p/0/k1" - end2 := "/1/p/0/k2" + start1 := MustNewDataStoreKey("/1/p/0/k1.1") + end1 := MustNewDataStoreKey("/1/p/0/k3") + start2 := MustNewDataStoreKey("/1/p/0/k1") + end2 := MustNewDataStoreKey("/1/p/0/k2") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start2, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start2, result[0].Start()) + assert.Equal(t, end1, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenStartPrefixesEndAdjacentAndAfter(t *testing.T) { - start1 := "/1/p/0/k1.1" - end1 := "/1/p/0/k3" - start2 := "/1/p/0/k1" - end2 := "/1/p/0/k4" + start1 := MustNewDataStoreKey("/1/p/0/k1.1") + end1 := MustNewDataStoreKey("/1/p/0/k3") + start2 := MustNewDataStoreKey("/1/p/0/k1") + end2 := MustNewDataStoreKey("/1/p/0/k4") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start2, result[0].Start().ToString()) - assert.Equal(t, end2, result[0].End().ToString()) + assert.Equal(t, start2, result[0].Start()) + assert.Equal(t, end2, result[0].End()) } func TestMergeAscending_ReturnsMiddleSpansMerged_GivenSpanCoveringMiddleSpans(t *testing.T) { - start1 := "/1/p/0/k1" - end1 := "/1/p/0/k2" - start2 := "/1/p/0/k6" - end2 := "/1/p/0/k7" - start3 := "/1/p/0/k9" - end3 := "/1/p/0/ka" - start4 := "/1/p/0/kc" - end4 := "/1/p/0/kd" - start5 := "/1/p/0/k4" - end5 := "/1/p/0/ka" + start1 := MustNewDataStoreKey("/1/p/0/k1") + end1 := MustNewDataStoreKey("/1/p/0/k2") + start2 := MustNewDataStoreKey("/1/p/0/k6") + end2 := MustNewDataStoreKey("/1/p/0/k7") + start3 := MustNewDataStoreKey("/1/p/0/k9") + end3 := MustNewDataStoreKey("/1/p/0/ka") + start4 := MustNewDataStoreKey("/1/p/0/kc") + end4 := MustNewDataStoreKey("/1/p/0/kd") + start5 := MustNewDataStoreKey("/1/p/0/k4") + end5 := MustNewDataStoreKey("/1/p/0/ka") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), - NewSpan(MustNewDataStoreKey(start3), MustNewDataStoreKey(end3)), - NewSpan(MustNewDataStoreKey(start4), MustNewDataStoreKey(end4)), - NewSpan(MustNewDataStoreKey(start5), MustNewDataStoreKey(end5)), + NewSpan(start1, end1), + NewSpan(start2, end2), + NewSpan(start3, end3), + NewSpan(start4, end4), + NewSpan(start5, end5), } result := MergeAscending(input) assert.Len(t, result, 3) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end1, result[0].End()) // Spans 2 and 3 are within span 5 - assert.Equal(t, start5, result[1].Start().ToString()) - assert.Equal(t, end5, result[1].End().ToString()) - assert.Equal(t, start4, result[2].Start().ToString()) - assert.Equal(t, end4, result[2].End().ToString()) + assert.Equal(t, start5, result[1].Start()) + assert.Equal(t, end5, result[1].End()) + assert.Equal(t, start4, result[2].Start()) + assert.Equal(t, end4, result[2].End()) } func TestMergeAscending_ReturnsSingle_GivenStartEqualEndWithin(t *testing.T) { - start1 := "/1/p/0/k1" - end1 := "/1/p/0/k2" - start2 := "/1/p/0/k1" - end2 := "/1/p/0/k1.5" + start1 := MustNewDataStoreKey("/1/p/0/k1") + end1 := MustNewDataStoreKey("/1/p/0/k2") + start2 := MustNewDataStoreKey("/1/p/0/k1") + end2 := MustNewDataStoreKey("/1/p/0/k1.5") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end1, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenStartEqualEndWithinEndPrefix(t *testing.T) { - start1 := "/1/p/0/k1" - end1 := "/1/p/0/k2" - start2 := "/1/p/0/k1" - end2 := "/1/p/0/k2.5" + start1 := MustNewDataStoreKey("/1/p/0/k1") + end1 := MustNewDataStoreKey("/1/p/0/k2") + start2 := MustNewDataStoreKey("/1/p/0/k1") + end2 := MustNewDataStoreKey("/1/p/0/k2.5") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end1, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenDuplicates(t *testing.T) { - start1 := "/1/p/0/k1" - end1 := "/1/p/0/k2" + start1 := MustNewDataStoreKey("/1/p/0/k1") + end1 := MustNewDataStoreKey("/1/p/0/k2") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), + NewSpan(start1, end1), + NewSpan(start1, end1), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end1, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenStartWithinEndWithin(t *testing.T) { - start1 := "/1/p/0/k1" - end1 := "/1/p/0/k2" - start2 := "/1/p/0/k1.2" - end2 := "/1/p/0/k1.5" + start1 := MustNewDataStoreKey("/1/p/0/k1") + end1 := MustNewDataStoreKey("/1/p/0/k2") + start2 := MustNewDataStoreKey("/1/p/0/k1.2") + end2 := MustNewDataStoreKey("/1/p/0/k1.5") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end1, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenStartWithinEndWithinEndPrefix(t *testing.T) { - start1 := "/1/p/0/k1" - end1 := "/1/p/0/k2" - start2 := "/1/p/0/k1.2" - end2 := "/1/p/0/k2.5" + start1 := MustNewDataStoreKey("/1/p/0/k1") + end1 := MustNewDataStoreKey("/1/p/0/k2") + start2 := MustNewDataStoreKey("/1/p/0/k1.2") + end2 := MustNewDataStoreKey("/1/p/0/k2.5") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end1, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenStartWithinEndEqual(t *testing.T) { - start1 := "/1/p/0/k1" - end1 := "/1/p/0/k2" - start2 := "/1/p/0/k1.2" - end2 := "/1/p/0/k2" + start1 := MustNewDataStoreKey("/1/p/0/k1") + end1 := MustNewDataStoreKey("/1/p/0/k2") + start2 := MustNewDataStoreKey("/1/p/0/k1.2") + end2 := MustNewDataStoreKey("/1/p/0/k2") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end1, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenStartWithinEndAdjacentAndBefore(t *testing.T) { - start1 := "/1/p/0/k1" - end1 := "/1/p/0/k3" - start2 := "/1/p/0/k1.2" - end2 := "/1/p/0/k2" + start1 := MustNewDataStoreKey("/1/p/0/k1") + end1 := MustNewDataStoreKey("/1/p/0/k3") + start2 := MustNewDataStoreKey("/1/p/0/k1.2") + end2 := MustNewDataStoreKey("/1/p/0/k2") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end1, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenStartWithinEndAdjacentAndAfter(t *testing.T) { - start1 := "/1/p/0/k1" - end1 := "/1/p/0/k3" - start2 := "/1/p/0/k1.2" - end2 := "/1/p/0/k4" + start1 := MustNewDataStoreKey("/1/p/0/k1") + end1 := MustNewDataStoreKey("/1/p/0/k3") + start2 := MustNewDataStoreKey("/1/p/0/k1.2") + end2 := MustNewDataStoreKey("/1/p/0/k4") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end2, result[0].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end2, result[0].End()) } func TestMergeAscending_ReturnsMiddleSpansMerged_GivenStartEqualEndAfterSpanCoveringMiddleSpans( t *testing.T, ) { - start1 := "/1/p/0/k1" - end1 := "/1/p/0/k2" - start2 := "/1/p/0/k4" - end2 := "/1/p/0/k5" - start3 := "/1/p/0/k7" - end3 := "/1/p/0/k8" - start4 := "/1/p/0/kc" - end4 := "/1/p/0/kd" - start5 := "/1/p/0/k4" // equal to start2 - end5 := "/1/p/0/ka" + start1 := MustNewDataStoreKey("/1/p/0/k1") + end1 := MustNewDataStoreKey("/1/p/0/k2") + start2 := MustNewDataStoreKey("/1/p/0/k4") + end2 := MustNewDataStoreKey("/1/p/0/k5") + start3 := MustNewDataStoreKey("/1/p/0/k7") + end3 := MustNewDataStoreKey("/1/p/0/k8") + start4 := MustNewDataStoreKey("/1/p/0/kc") + end4 := MustNewDataStoreKey("/1/p/0/kd") + start5 := MustNewDataStoreKey("/1/p/0/k4") // equal to start2 + end5 := MustNewDataStoreKey("/1/p/0/ka") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), - NewSpan(MustNewDataStoreKey(start3), MustNewDataStoreKey(end3)), - NewSpan(MustNewDataStoreKey(start4), MustNewDataStoreKey(end4)), - NewSpan(MustNewDataStoreKey(start5), MustNewDataStoreKey(end5)), + NewSpan(start1, end1), + NewSpan(start2, end2), + NewSpan(start3, end3), + NewSpan(start4, end4), + NewSpan(start5, end5), } result := MergeAscending(input) assert.Len(t, result, 3) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end1, result[0].End()) // Spans 2 and 3 are within span 5 - assert.Equal(t, start5, result[1].Start().ToString()) - assert.Equal(t, end5, result[1].End().ToString()) - assert.Equal(t, start4, result[2].Start().ToString()) - assert.Equal(t, end4, result[2].End().ToString()) + assert.Equal(t, start5, result[1].Start()) + assert.Equal(t, end5, result[1].End()) + assert.Equal(t, start4, result[2].Start()) + assert.Equal(t, end4, result[2].End()) } func TestMergeAscending_ReturnsMiddleSpansMerged_GivenStartWithinEndAfterSpanCoveringMiddleSpans( t *testing.T, ) { - start1 := "/1/p/0/k1" - end1 := "/1/p/0/k2" - start2 := "/1/p/0/k4" - end2 := "/1/p/0/k5" - start3 := "/1/p/0/k7" - end3 := "/1/p/0/k8" - start4 := "/1/p/0/kc" - end4 := "/1/p/0/kd" - start5 := "/1/p/0/k4.5" // within span2 - end5 := "/1/p/0/ka" + start1 := MustNewDataStoreKey("/1/p/0/k1") + end1 := MustNewDataStoreKey("/1/p/0/k2") + start2 := MustNewDataStoreKey("/1/p/0/k4") + end2 := MustNewDataStoreKey("/1/p/0/k5") + start3 := MustNewDataStoreKey("/1/p/0/k7") + end3 := MustNewDataStoreKey("/1/p/0/k8") + start4 := MustNewDataStoreKey("/1/p/0/kc") + end4 := MustNewDataStoreKey("/1/p/0/kd") + start5 := MustNewDataStoreKey("/1/p/0/k4.5") // within span2 + end5 := MustNewDataStoreKey("/1/p/0/ka") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), - NewSpan(MustNewDataStoreKey(start3), MustNewDataStoreKey(end3)), - NewSpan(MustNewDataStoreKey(start4), MustNewDataStoreKey(end4)), - NewSpan(MustNewDataStoreKey(start5), MustNewDataStoreKey(end5)), + NewSpan(start1, end1), + NewSpan(start2, end2), + NewSpan(start3, end3), + NewSpan(start4, end4), + NewSpan(start5, end5), } result := MergeAscending(input) assert.Len(t, result, 3) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) - assert.Equal(t, start2, result[1].Start().ToString()) - assert.Equal(t, end5, result[1].End().ToString()) - assert.Equal(t, start4, result[2].Start().ToString()) - assert.Equal(t, end4, result[2].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end1, result[0].End()) + assert.Equal(t, start2, result[1].Start()) + assert.Equal(t, end5, result[1].End()) + assert.Equal(t, start4, result[2].Start()) + assert.Equal(t, end4, result[2].End()) } func TestMergeAscending_ReturnsMiddleSpansMerged_GivenStartEqualToEndEndAfterSpanCoveringMiddleSpans( t *testing.T, ) { - start1 := "/1/p/0/k1" - end1 := "/1/p/0/k2" - start2 := "/1/p/0/k4" - end2 := "/1/p/0/k5" - start3 := "/1/p/0/k7" - end3 := "/1/p/0/k8" - start4 := "/1/p/0/kc" - end4 := "/1/p/0/kd" - start5 := "/1/p/0/k5" // span2's end - end5 := "/1/p/0/ka" + start1 := MustNewDataStoreKey("/1/p/0/k1") + end1 := MustNewDataStoreKey("/1/p/0/k2") + start2 := MustNewDataStoreKey("/1/p/0/k4") + end2 := MustNewDataStoreKey("/1/p/0/k5") + start3 := MustNewDataStoreKey("/1/p/0/k7") + end3 := MustNewDataStoreKey("/1/p/0/k8") + start4 := MustNewDataStoreKey("/1/p/0/kc") + end4 := MustNewDataStoreKey("/1/p/0/kd") + start5 := MustNewDataStoreKey("/1/p/0/k5") // span2's end + end5 := MustNewDataStoreKey("/1/p/0/ka") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), - NewSpan(MustNewDataStoreKey(start3), MustNewDataStoreKey(end3)), - NewSpan(MustNewDataStoreKey(start4), MustNewDataStoreKey(end4)), - NewSpan(MustNewDataStoreKey(start5), MustNewDataStoreKey(end5)), + NewSpan(start1, end1), + NewSpan(start2, end2), + NewSpan(start3, end3), + NewSpan(start4, end4), + NewSpan(start5, end5), } result := MergeAscending(input) assert.Len(t, result, 3) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) - assert.Equal(t, start2, result[1].Start().ToString()) - assert.Equal(t, end5, result[1].End().ToString()) - assert.Equal(t, start4, result[2].Start().ToString()) - assert.Equal(t, end4, result[2].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end1, result[0].End()) + assert.Equal(t, start2, result[1].Start()) + assert.Equal(t, end5, result[1].End()) + assert.Equal(t, start4, result[2].Start()) + assert.Equal(t, end4, result[2].End()) } func TestMergeAscending_ReturnsMiddleSpansMerged_GivenStartAdjacentAndBeforeEndEndAfterSpanCoveringMiddleSpans( t *testing.T, ) { - start1 := "/1/p/0/k1" - end1 := "/1/p/0/k2" - start2 := "/1/p/0/k4" - end2 := "/1/p/0/k6" - start3 := "/1/p/0/k8" - end3 := "/1/p/0/k9" - start4 := "/1/p/0/kd" - end4 := "/1/p/0/ke" - start5 := "/1/p/0/k5" // adjacent but before span2's end - end5 := "/1/p/0/kb" + start1 := MustNewDataStoreKey("/1/p/0/k1") + end1 := MustNewDataStoreKey("/1/p/0/k2") + start2 := MustNewDataStoreKey("/1/p/0/k4") + end2 := MustNewDataStoreKey("/1/p/0/k6") + start3 := MustNewDataStoreKey("/1/p/0/k8") + end3 := MustNewDataStoreKey("/1/p/0/k9") + start4 := MustNewDataStoreKey("/1/p/0/kd") + end4 := MustNewDataStoreKey("/1/p/0/ke") + start5 := MustNewDataStoreKey("/1/p/0/k5") // adjacent but before span2's end + end5 := MustNewDataStoreKey("/1/p/0/kb") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), - NewSpan(MustNewDataStoreKey(start3), MustNewDataStoreKey(end3)), - NewSpan(MustNewDataStoreKey(start4), MustNewDataStoreKey(end4)), - NewSpan(MustNewDataStoreKey(start5), MustNewDataStoreKey(end5)), + NewSpan(start1, end1), + NewSpan(start2, end2), + NewSpan(start3, end3), + NewSpan(start4, end4), + NewSpan(start5, end5), } result := MergeAscending(input) assert.Len(t, result, 3) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) - assert.Equal(t, start2, result[1].Start().ToString()) - assert.Equal(t, end5, result[1].End().ToString()) - assert.Equal(t, start4, result[2].Start().ToString()) - assert.Equal(t, end4, result[2].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end1, result[0].End()) + assert.Equal(t, start2, result[1].Start()) + assert.Equal(t, end5, result[1].End()) + assert.Equal(t, start4, result[2].Start()) + assert.Equal(t, end4, result[2].End()) } func TestMergeAscending_ReturnsMiddleSpansMerged_GivenStartAdjacentAndAfterEndEndAfterSpanCoveringMiddleSpans( t *testing.T, ) { - start1 := "/1/p/0/k1" - end1 := "/1/p/0/k2" - start2 := "/1/p/0/k4" - end2 := "/1/p/0/k5" - start3 := "/1/p/0/k8" - end3 := "/1/p/0/k9" - start4 := "/1/p/0/kd" - end4 := "/1/p/0/ke" - start5 := "/1/p/0/k6" // adjacent and after span2's end - end5 := "/1/p/0/kb" + start1 := MustNewDataStoreKey("/1/p/0/k1") + end1 := MustNewDataStoreKey("/1/p/0/k2") + start2 := MustNewDataStoreKey("/1/p/0/k4") + end2 := MustNewDataStoreKey("/1/p/0/k5") + start3 := MustNewDataStoreKey("/1/p/0/k8") + end3 := MustNewDataStoreKey("/1/p/0/k9") + start4 := MustNewDataStoreKey("/1/p/0/kd") + end4 := MustNewDataStoreKey("/1/p/0/ke") + start5 := MustNewDataStoreKey("/1/p/0/k6") // adjacent and after span2's end + end5 := MustNewDataStoreKey("/1/p/0/kb") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), - NewSpan(MustNewDataStoreKey(start3), MustNewDataStoreKey(end3)), - NewSpan(MustNewDataStoreKey(start4), MustNewDataStoreKey(end4)), - NewSpan(MustNewDataStoreKey(start5), MustNewDataStoreKey(end5)), + NewSpan(start1, end1), + NewSpan(start2, end2), + NewSpan(start3, end3), + NewSpan(start4, end4), + NewSpan(start5, end5), } result := MergeAscending(input) assert.Len(t, result, 3) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) - assert.Equal(t, start2, result[1].Start().ToString()) - assert.Equal(t, end5, result[1].End().ToString()) - assert.Equal(t, start4, result[2].Start().ToString()) - assert.Equal(t, end4, result[2].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end1, result[0].End()) + assert.Equal(t, start2, result[1].Start()) + assert.Equal(t, end5, result[1].End()) + assert.Equal(t, start4, result[2].Start()) + assert.Equal(t, end4, result[2].End()) } func TestMergeAscending_ReturnsTwoItems_GivenSecondItemAfterFirst(t *testing.T) { - start1 := "/1/p/0/k1" - end1 := "/1/p/0/k2" - start2 := "/1/p/0/k4" - end2 := "/1/p/0/k5" + start1 := MustNewDataStoreKey("/1/p/0/k1") + end1 := MustNewDataStoreKey("/1/p/0/k2") + start2 := MustNewDataStoreKey("/1/p/0/k4") + end2 := MustNewDataStoreKey("/1/p/0/k5") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 2) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end1, result[0].End().ToString()) - assert.Equal(t, start2, result[1].Start().ToString()) - assert.Equal(t, end2, result[1].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end1, result[0].End()) + assert.Equal(t, start2, result[1].Start()) + assert.Equal(t, end2, result[1].End()) } func TestMergeAscending_ReturnsSingle_GivenStartAdjacentAndBeforeEndEndEqual(t *testing.T) { - start1 := "/1/p/0/k3" - end1 := "/1/p/0/k6" - start2 := "/1/p/0/k5" - end2 := "/1/p/0/k6" + start1 := MustNewDataStoreKey("/1/p/0/k3") + end1 := MustNewDataStoreKey("/1/p/0/k6") + start2 := MustNewDataStoreKey("/1/p/0/k5") + end2 := MustNewDataStoreKey("/1/p/0/k6") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end2, result[0].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end2, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenStartAdjacentAndBeforeEndEndAdjacentAndAfter( t *testing.T, ) { - start1 := "/1/p/0/k3" - end1 := "/1/p/0/k6" - start2 := "/1/p/0/k5" - end2 := "/1/p/0/k7" + start1 := MustNewDataStoreKey("/1/p/0/k3") + end1 := MustNewDataStoreKey("/1/p/0/k6") + start2 := MustNewDataStoreKey("/1/p/0/k5") + end2 := MustNewDataStoreKey("/1/p/0/k7") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end2, result[0].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end2, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenStartAdjacentAndBeforeEndEndAfter(t *testing.T) { - start1 := "/1/p/0/k3" - end1 := "/1/p/0/k6" - start2 := "/1/p/0/k5" - end2 := "/1/p/0/k8" + start1 := MustNewDataStoreKey("/1/p/0/k3") + end1 := MustNewDataStoreKey("/1/p/0/k6") + start2 := MustNewDataStoreKey("/1/p/0/k5") + end2 := MustNewDataStoreKey("/1/p/0/k8") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end2, result[0].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end2, result[0].End()) } func TestMergeAscending_ReturnsSingle_GivenStartAdjacentAndAfterEndEndAfter(t *testing.T) { - start1 := "/1/p/0/k3" - end1 := "/1/p/0/k6" - start2 := "/1/p/0/k7" - end2 := "/1/p/0/k8" + start1 := MustNewDataStoreKey("/1/p/0/k3") + end1 := MustNewDataStoreKey("/1/p/0/k6") + start2 := MustNewDataStoreKey("/1/p/0/k7") + end2 := MustNewDataStoreKey("/1/p/0/k8") input := []Span{ - NewSpan(MustNewDataStoreKey(start1), MustNewDataStoreKey(end1)), - NewSpan(MustNewDataStoreKey(start2), MustNewDataStoreKey(end2)), + NewSpan(start1, end1), + NewSpan(start2, end2), } result := MergeAscending(input) assert.Len(t, result, 1) - assert.Equal(t, start1, result[0].Start().ToString()) - assert.Equal(t, end2, result[0].End().ToString()) + assert.Equal(t, start1, result[0].Start()) + assert.Equal(t, end2, result[0].End()) } diff --git a/internal/core/encoding.go b/internal/core/encoding.go index b18733f055..14dfb072b1 100644 --- a/internal/core/encoding.go +++ b/internal/core/encoding.go @@ -288,3 +288,84 @@ func EncodeIndexDataStoreKey(key *IndexDataStoreKey) []byte { return b } + +// DecodeDataStoreKey decodes a store key into a [DataStoreKey]. +func DecodeDataStoreKey(data []byte) (DataStoreKey, error) { + if len(data) == 0 { + return DataStoreKey{}, ErrEmptyKey + } + + if data[0] != '/' { + return DataStoreKey{}, ErrInvalidKey + } + data = data[1:] + + data, colRootID, err := encoding.DecodeUvarintAscending(data) + if err != nil { + return DataStoreKey{}, err + } + + var instanceType InstanceType + if len(data) > 1 { + if data[0] == '/' { + data = data[1:] + } + instanceType = InstanceType(data[0]) + data = data[1:] + } + + const docKeyLength int = 40 + var docID string + if len(data) > docKeyLength { + if data[0] == '/' { + data = data[1:] + } + docID = string(data[:docKeyLength]) + data = data[docKeyLength:] + } + + var fieldID string + if len(data) > 1 { + if data[0] == '/' { + data = data[1:] + } + // Todo: This should be encoded/decoded properly in + // https://github.com/sourcenetwork/defradb/issues/2818 + fieldID = string(data) + } + + return DataStoreKey{ + CollectionRootID: uint32(colRootID), + InstanceType: (instanceType), + DocID: docID, + FieldID: fieldID, + }, nil +} + +// EncodeDataStoreKey encodes a [*DataStoreKey] to a byte array suitable for sorting in the store. +func EncodeDataStoreKey(key *DataStoreKey) []byte { + var result []byte + + if key.CollectionRootID != 0 { + result = encoding.EncodeUvarintAscending([]byte{'/'}, uint64(key.CollectionRootID)) + } + + if key.InstanceType != "" { + result = append(result, '/') + result = append(result, []byte(string(key.InstanceType))...) + } + + if key.DocID != "" { + result = append(result, '/') + result = append(result, []byte(key.DocID)...) + } + + if key.FieldID != "" { + result = append(result, '/') + // Todo: This should be encoded/decoded properly in + // https://github.com/sourcenetwork/defradb/issues/2818 + result = append(result, []byte(key.FieldID)...) + } + + return result +} diff --git a/internal/core/key.go b/internal/core/key.go index efc2d73017..9b56c421fc 100644 --- a/internal/core/key.go +++ b/internal/core/key.go @@ -215,33 +215,7 @@ var _ Key = (*ReplicatorKey)(nil) // // Any properties before the above (assuming a '/' deliminator) are ignored func NewDataStoreKey(key string) (DataStoreKey, error) { - dataStoreKey := DataStoreKey{} - if key == "" { - return dataStoreKey, ErrEmptyKey - } - - elements := strings.Split(strings.TrimPrefix(key, "/"), "/") - - numberOfElements := len(elements) - - // With less than 3 or more than 4 elements, we know it's an invalid key - if numberOfElements < 3 || numberOfElements > 4 { - return dataStoreKey, ErrInvalidKey - } - - colRootID, err := strconv.Atoi(elements[0]) - if err != nil { - return DataStoreKey{}, err - } - - dataStoreKey.CollectionRootID = uint32(colRootID) - dataStoreKey.InstanceType = InstanceType(elements[1]) - dataStoreKey.DocID = elements[2] - if numberOfElements == 4 { - dataStoreKey.FieldID = elements[3] - } - - return dataStoreKey, nil + return DecodeDataStoreKey([]byte(key)) } func MustNewDataStoreKey(key string) DataStoreKey { @@ -466,6 +440,18 @@ func (k HeadStoreKey) WithFieldId(fieldId string) HeadStoreKey { } func (k DataStoreKey) ToString() string { + return string(k.Bytes()) +} + +func (k DataStoreKey) Bytes() []byte { + return EncodeDataStoreKey(&k) +} + +func (k DataStoreKey) ToDS() ds.Key { + return ds.NewKey(k.ToString()) +} + +func (k DataStoreKey) PrettyPrint() string { var result string if k.CollectionRootID != 0 { @@ -484,14 +470,6 @@ func (k DataStoreKey) ToString() string { return result } -func (k DataStoreKey) Bytes() []byte { - return []byte(k.ToString()) -} - -func (k DataStoreKey) ToDS() ds.Key { - return ds.NewKey(k.ToString()) -} - func (k DataStoreKey) Equal(other DataStoreKey) bool { return k.CollectionRootID == other.CollectionRootID && k.DocID == other.DocID && diff --git a/internal/core/key_test.go b/internal/core/key_test.go index 90bd122d6f..b564fb001b 100644 --- a/internal/core/key_test.go +++ b/internal/core/key_test.go @@ -34,86 +34,6 @@ func TestNewDataStoreKey_ReturnsEmptyStruct_GivenEmptyString(t *testing.T) { assert.ErrorIs(t, ErrEmptyKey, err) } -func TestNewDataStoreKey_ReturnsCollectionIdAndIndexIdAndDocIDAndFieldIdAndInstanceType_GivenFourItemsWithType( - t *testing.T, -) { - instanceType := "anyType" - fieldID := "f1" - docID := "docID" - var collectionRootID uint32 = 2 - inputString := fmt.Sprintf("%v/%s/%s/%s", collectionRootID, instanceType, docID, fieldID) - - result, err := NewDataStoreKey(inputString) - if err != nil { - t.Error(err) - } - resultString := result.ToString() - - assert.Equal( - t, - DataStoreKey{ - CollectionRootID: collectionRootID, - DocID: docID, - FieldID: fieldID, - InstanceType: InstanceType(instanceType)}, - result) - assert.Equal(t, fmt.Sprintf("/%v/%s/%s/%s", collectionRootID, instanceType, docID, fieldID), resultString) -} - -func TestNewDataStoreKey_ReturnsEmptyStruct_GivenAStringWithMissingElements(t *testing.T) { - inputString := "/0/v" - - _, err := NewDataStoreKey(inputString) - - assert.ErrorIs(t, ErrInvalidKey, err) -} - -func TestNewDataStoreKey_GivenAShortObjectMarker(t *testing.T) { - instanceType := "anyType" - docID := "docID" - var collectionRootID uint32 = 2 - inputString := fmt.Sprintf("%v/%s/%s", collectionRootID, instanceType, docID) - - result, err := NewDataStoreKey(inputString) - if err != nil { - t.Error(err) - } - resultString := result.ToString() - - assert.Equal( - t, - DataStoreKey{ - CollectionRootID: collectionRootID, - DocID: docID, - InstanceType: InstanceType(instanceType)}, - result) - assert.Equal(t, fmt.Sprintf("/%v/%s/%s", collectionRootID, instanceType, docID), resultString) -} - -func TestNewDataStoreKey_GivenAStringWithExtraPrefixes(t *testing.T) { - instanceType := "anyType" - fieldId := "f1" - docID := "docID" - collectionId := "1" - inputString := "/db/my_database_name/data/" + collectionId + "/" + instanceType + "/" + docID + "/" + fieldId - - _, err := NewDataStoreKey(inputString) - - assert.ErrorIs(t, ErrInvalidKey, err) -} - -func TestNewDataStoreKey_GivenAStringWithExtraSuffix(t *testing.T) { - instanceType := "anyType" - fieldId := "f1" - docID := "docID" - collectionId := "1" - inputString := "/db/data/" + collectionId + "/" + instanceType + "/" + docID + "/" + fieldId + "/version_number" - - _, err := NewDataStoreKey(inputString) - - assert.ErrorIs(t, ErrInvalidKey, err) -} - func TestNewIndexKey_IfEmptyParam_ReturnPrefix(t *testing.T) { key := NewCollectionIndexKey(immutable.None[uint32](), "") assert.Equal(t, "/collection/index", key.ToString()) diff --git a/internal/db/indexed_docs_test.go b/internal/db/indexed_docs_test.go index 002e05eabe..fad45aa11f 100644 --- a/internal/db/indexed_docs_test.go +++ b/internal/db/indexed_docs_test.go @@ -709,7 +709,7 @@ func TestNonUniqueCreate_IfDatastoreFailsToStoreIndex_ReturnError(t *testing.T) require.NoError(f.t, err) _, err = f.users.CreateIndex(f.ctx, getUsersIndexDescOnName()) - require.ErrorIs(f.t, err, core.ErrInvalidKey) + require.ErrorIs(f.t, err, core.ErrFailedToGetFieldIdOfKey) } func TestNonUniqueDrop_ShouldDeleteStoredIndexedFields(t *testing.T) { diff --git a/internal/planner/scan.go b/internal/planner/scan.go index a9274fed98..5c0e3d4faf 100644 --- a/internal/planner/scan.go +++ b/internal/planner/scan.go @@ -236,8 +236,10 @@ func (n *scanNode) explainSpans() []map[string]any { spansExplainer := []map[string]any{} for _, span := range n.spans.Value { spanExplainer := map[string]any{ - "start": span.Start().ToString(), - "end": span.End().ToString(), + // These must be pretty printed as the explain results need to be returnable + // as json via some clients (e.g. http and cli) + "start": span.Start().PrettyPrint(), + "end": span.End().PrettyPrint(), } spansExplainer = append(spansExplainer, spanExplainer) diff --git a/tests/integration/query/simple/with_multiple_types_test.go b/tests/integration/query/simple/with_multiple_types_test.go new file mode 100644 index 0000000000..e46b03db28 --- /dev/null +++ b/tests/integration/query/simple/with_multiple_types_test.go @@ -0,0 +1,331 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package simple + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +/* +These tests cover a failure case where the nth collection would become unreadable by the fetcher +due to a key encoding/iteration problem. + +They were introduced with the fix to https://github.com/sourcenetwork/defradb/issues/2810 in PR +https://github.com/sourcenetwork/defradb/pull/2819 +*/ + +func TestSimple_WithSevenDummyTypesBefore(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Type0 { + f: String + } + type Type1 { + f: String + } + type Type2 { + f: String + } + type Type3 { + f: String + } + type Type4 { + f: String + } + type Type5 { + f: String + } + type Type6 { + f: String + } + + type User { + name: String + } + `, + }, + testUtils.CreateDoc{ + CollectionID: 7, + DocMap: map[string]any{ + "name": "John", + }, + }, + testUtils.Request{ + Request: ` + query { + User { + name + } + } + `, + Results: []map[string]any{ + { + "name": "John", + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestSimple_WithEightDummyTypesBefore(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Type0 { + f: String + } + type Type1 { + f: String + } + type Type2 { + f: String + } + type Type3 { + f: String + } + type Type4 { + f: String + } + type Type5 { + f: String + } + type Type6 { + f: String + } + type Type7 { + f: String + } + + type User { + name: String + } + `, + }, + testUtils.CreateDoc{ + CollectionID: 8, + DocMap: map[string]any{ + "name": "John", + }, + }, + testUtils.Request{ + Request: ` + query { + User { + name + } + } + `, + Results: []map[string]any{ + { + "name": "John", + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestSimple_WithEightDummyTypesBeforeInSplitDeclaration(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Type0 { + f: String + } + type Type1 { + f: String + } + type Type2 { + f: String + } + type Type3 { + f: String + } + type Type4 { + f: String + } + type Type5 { + f: String + } + type Type6 { + f: String + } + type Type7 { + f: String + } + `, + }, + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + } + `, + }, + testUtils.CreateDoc{ + CollectionID: 8, + DocMap: map[string]any{ + "name": "John", + }, + }, + testUtils.Request{ + Request: ` + query { + User { + name + } + } + `, + Results: []map[string]any{ + { + "name": "John", + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestSimple_WithEightDummyTypesAfter(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + } + + type Type0 { + f: String + } + type Type1 { + f: String + } + type Type2 { + f: String + } + type Type3 { + f: String + } + type Type4 { + f: String + } + type Type5 { + f: String + } + type Type6 { + f: String + } + type Type7 { + f: String + } + `, + }, + testUtils.CreateDoc{ + CollectionID: 0, + DocMap: map[string]any{ + "name": "John", + }, + }, + testUtils.Request{ + Request: ` + query { + User { + name + } + } + `, + Results: []map[string]any{ + { + "name": "John", + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestSimple_WithSevenDummyTypesBeforeAndOneAfter(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Type0 { + f: String + } + type Type1 { + f: String + } + type Type2 { + f: String + } + type Type3 { + f: String + } + type Type4 { + f: String + } + type Type5 { + f: String + } + type Type6 { + f: String + } + + type User { + name: String + } + + type Type7 { + f: String + } + `, + }, + testUtils.CreateDoc{ + CollectionID: 7, + DocMap: map[string]any{ + "name": "John", + }, + }, + testUtils.Request{ + Request: ` + query { + User { + name + } + } + `, + Results: []map[string]any{ + { + "name": "John", + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/utils2.go b/tests/integration/utils2.go index 5012642f22..05a5efe397 100644 --- a/tests/integration/utils2.go +++ b/tests/integration/utils2.go @@ -108,7 +108,6 @@ func init() { if value, ok := os.LookupEnv(skipNetworkTestsEnvName); ok { skipNetworkTests, _ = strconv.ParseBool(value) } - mutationType = GQLRequestMutationType } // AssertPanic asserts that the code inside the specified PanicTestFunc panics. From 32092ac36f39378228e704b811708fb2f4e7ce85 Mon Sep 17 00:00:00 2001 From: AndrewSisley Date: Tue, 9 Jul 2024 16:24:31 -0400 Subject: [PATCH 07/41] test: Remove hardcoded test identities (#2822) ## Relevant issue(s) Resolves #2821 ## Description Removes the hardcoded test identities from our integration tests. The current (develop) setup becomes impossible with source-hub ACP as the identity needs to include a signed bearer token containing the sourcehub address (not accessible during package init). I also think this is a bit more maintainable. --- .../i2821-no-change-tests-updated.md | 3 + tests/integration/acp.go | 33 ++++++- .../integration/acp/add_policy/basic_test.go | 6 +- tests/integration/acp/add_policy/fixture.go | 18 ---- .../acp/add_policy/with_empty_args_test.go | 7 +- .../with_extra_perms_and_relations_test.go | 4 +- .../acp/add_policy/with_extra_perms_test.go | 6 +- .../add_policy/with_extra_relations_test.go | 6 +- .../with_invalid_creator_arg_test.go | 88 ------------------- .../add_policy/with_invalid_relations_test.go | 6 +- .../with_invalid_required_relation_test.go | 6 +- .../add_policy/with_invalid_resource_test.go | 4 +- .../add_policy/with_managed_relation_test.go | 4 +- .../add_policy/with_multi_policies_test.go | 22 ++--- .../with_multiple_resources_test.go | 8 +- .../acp/add_policy/with_no_perms_test.go | 10 ++- .../acp/add_policy/with_no_resources_test.go | 8 +- .../acp/add_policy/with_perm_expr_test.go | 6 +- .../add_policy/with_perm_invalid_expr_test.go | 8 +- .../with_permissionless_owner_test.go | 8 +- .../add_policy/with_unused_relations_test.go | 4 +- tests/integration/acp/fixture.go | 39 -------- tests/integration/acp/index/create_test.go | 7 +- tests/integration/acp/index/query_test.go | 19 ++-- .../acp/index/query_with_relation_test.go | 19 ++-- tests/integration/acp/p2p/replicator_test.go | 5 +- tests/integration/acp/p2p/subscribe_test.go | 5 +- tests/integration/acp/query/avg_test.go | 7 +- tests/integration/acp/query/count_test.go | 11 +-- tests/integration/acp/query/fixture.go | 11 +-- .../acp/query/relation_objects_test.go | 11 +-- .../acp/register_and_delete_test.go | 44 ++++------ .../integration/acp/register_and_read_test.go | 24 ++--- .../acp/register_and_update_test.go | 66 +++++--------- .../add_dpi/accept_basic_dpi_fmts_test.go | 6 +- .../accept_extra_permissions_on_dpi_test.go | 8 +- .../accept_managed_relation_on_dpi_test.go | 4 +- ...ept_mixed_resources_on_partial_dpi_test.go | 4 +- .../schema/add_dpi/accept_multi_dpis_test.go | 6 +- .../accept_multi_resources_on_dpi_test.go | 6 +- ...cept_same_resource_on_diff_schemas_test.go | 4 +- .../integration/acp/schema/add_dpi/fixture.go | 18 ---- .../reject_empty_arg_on_schema_test.go | 6 +- .../reject_invalid_arg_type_on_schema_test.go | 6 +- ...ect_invalid_owner_read_perm_on_dpi_test.go | 12 +-- ...alid_owner_read_perm_symbol_on_dpi_test.go | 8 +- ...ct_invalid_owner_write_perm_on_dpi_test.go | 12 +-- ...lid_owner_write_perm_symbol_on_dpi_test.go | 8 +- .../schema/add_dpi/reject_missing_dpi_test.go | 4 +- .../reject_missing_id_arg_on_schema_test.go | 6 +- .../reject_missing_perms_on_dpi_test.go | 4 +- ...ect_missing_resource_arg_on_schema_test.go | 6 +- .../reject_missing_resource_on_dpi_test.go | 4 +- ...ect_mixed_resources_on_partial_dpi_test.go | 4 +- .../updates/remove/policy_test.go | 5 +- tests/integration/state.go | 3 + tests/integration/test_case.go | 9 +- tests/integration/utils2.go | 28 +++--- 58 files changed, 318 insertions(+), 396 deletions(-) create mode 100644 docs/data_format_changes/i2821-no-change-tests-updated.md delete mode 100644 tests/integration/acp/add_policy/fixture.go delete mode 100644 tests/integration/acp/add_policy/with_invalid_creator_arg_test.go delete mode 100644 tests/integration/acp/fixture.go delete mode 100644 tests/integration/acp/schema/add_dpi/fixture.go diff --git a/docs/data_format_changes/i2821-no-change-tests-updated.md b/docs/data_format_changes/i2821-no-change-tests-updated.md new file mode 100644 index 0000000000..603c830c65 --- /dev/null +++ b/docs/data_format_changes/i2821-no-change-tests-updated.md @@ -0,0 +1,3 @@ +# Parallel change detector + +This is is not a breaking change, the tests now use dynamically generated private keys for identities. diff --git a/tests/integration/acp.go b/tests/integration/acp.go index ccfba9ed0d..e457a2625a 100644 --- a/tests/integration/acp.go +++ b/tests/integration/acp.go @@ -11,6 +11,9 @@ package tests import ( + "math/rand" + + "github.com/decred/dcrd/dcrec/secp256k1/v4" "github.com/sourcenetwork/immutable" "github.com/stretchr/testify/require" @@ -29,7 +32,7 @@ type AddPolicy struct { Policy string // The policy creator identity, i.e. actor creating the policy. - Identity immutable.Option[acpIdentity.Identity] + Identity immutable.Option[int] // The expected policyID generated based on the Policy loaded in to the ACP system. ExpectedPolicyID string @@ -52,7 +55,8 @@ func addPolicyACP( } for _, node := range getNodes(action.NodeID, s.nodes) { - ctx := db.SetContextIdentity(s.ctx, action.Identity) + identity := getIdentity(s, action.Identity) + ctx := db.SetContextIdentity(s.ctx, identity) policyResult, err := node.AddPolicy(ctx, action.Policy) if err == nil { @@ -64,3 +68,28 @@ func addPolicyACP( assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) } } + +func getIdentity(s *state, index immutable.Option[int]) immutable.Option[acpIdentity.Identity] { + if !index.HasValue() { + return immutable.None[acpIdentity.Identity]() + } + + if len(s.identities) <= index.Value() { + // Generate the keys using the index as the seed so that multiple + // runs yield the same private key. This is important for stuff like + // the change detector. + source := rand.NewSource(int64(index.Value())) + r := rand.New(source) + + privateKey, err := secp256k1.GeneratePrivateKeyFromRand(r) + require.NoError(s.t, err) + + identity, err := acpIdentity.FromPrivateKey(privateKey) + require.NoError(s.t, err) + + s.identities = append(s.identities, identity.Value()) + return identity + } else { + return immutable.Some[acpIdentity.Identity](s.identities[index.Value()]) + } +} diff --git a/tests/integration/acp/add_policy/basic_test.go b/tests/integration/acp/add_policy/basic_test.go index 6e08bbd65b..a96a073e5c 100644 --- a/tests/integration/acp/add_policy/basic_test.go +++ b/tests/integration/acp/add_policy/basic_test.go @@ -13,6 +13,8 @@ package test_acp_add_policy import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -23,7 +25,7 @@ func TestACP_AddPolicy_BasicYAML_ValidPolicyID(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -62,7 +64,7 @@ func TestACP_AddPolicy_BasicJSON_ValidPolicyID(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` { diff --git a/tests/integration/acp/add_policy/fixture.go b/tests/integration/acp/add_policy/fixture.go deleted file mode 100644 index 97ae5e6ff6..0000000000 --- a/tests/integration/acp/add_policy/fixture.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2024 Democratized Data Foundation -// -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. - -package test_acp_add_policy - -import ( - acpUtils "github.com/sourcenetwork/defradb/tests/integration/acp" -) - -var actor1Identity = acpUtils.Actor1Identity -var actor2Identity = acpUtils.Actor2Identity diff --git a/tests/integration/acp/add_policy/with_empty_args_test.go b/tests/integration/acp/add_policy/with_empty_args_test.go index ce1af33754..1af4a5c1f3 100644 --- a/tests/integration/acp/add_policy/with_empty_args_test.go +++ b/tests/integration/acp/add_policy/with_empty_args_test.go @@ -15,7 +15,6 @@ import ( "github.com/sourcenetwork/immutable" - acpIdentity "github.com/sourcenetwork/defradb/acp/identity" testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -26,7 +25,7 @@ func TestACP_AddPolicy_EmptyPolicyData_Error(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: "", @@ -45,7 +44,7 @@ func TestACP_AddPolicy_EmptyPolicyCreator_Error(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: immutable.None[acpIdentity.Identity](), + Identity: immutable.None[int](), Policy: ` name: test @@ -84,7 +83,7 @@ func TestACP_AddPolicy_EmptyCreatorAndPolicyArgs_Error(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: immutable.None[acpIdentity.Identity](), + Identity: immutable.None[int](), Policy: "", diff --git a/tests/integration/acp/add_policy/with_extra_perms_and_relations_test.go b/tests/integration/acp/add_policy/with_extra_perms_and_relations_test.go index 04b0204c37..1db26e639e 100644 --- a/tests/integration/acp/add_policy/with_extra_perms_and_relations_test.go +++ b/tests/integration/acp/add_policy/with_extra_perms_and_relations_test.go @@ -13,6 +13,8 @@ package test_acp_add_policy import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -23,7 +25,7 @@ func TestACP_AddPolicy_ExtraPermissionsAndExtraRelations_ValidPolicyID(t *testin Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/add_policy/with_extra_perms_test.go b/tests/integration/acp/add_policy/with_extra_perms_test.go index 7832802ebc..963101356f 100644 --- a/tests/integration/acp/add_policy/with_extra_perms_test.go +++ b/tests/integration/acp/add_policy/with_extra_perms_test.go @@ -13,6 +13,8 @@ package test_acp_add_policy import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -23,7 +25,7 @@ func TestACP_AddPolicy_ExtraPermissions_ValidPolicyID(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: a policy @@ -63,7 +65,7 @@ func TestACP_AddPolicy_ExtraDuplicatePermissions_Error(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: a policy diff --git a/tests/integration/acp/add_policy/with_extra_relations_test.go b/tests/integration/acp/add_policy/with_extra_relations_test.go index 57d9e7ca2d..f4bec6479c 100644 --- a/tests/integration/acp/add_policy/with_extra_relations_test.go +++ b/tests/integration/acp/add_policy/with_extra_relations_test.go @@ -13,6 +13,8 @@ package test_acp_add_policy import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -23,7 +25,7 @@ func TestACP_AddPolicy_ExtraRelations_ValidPolicyID(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: a policy @@ -67,7 +69,7 @@ func TestACP_AddPolicy_ExtraDuplicateRelations_Error(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: a policy diff --git a/tests/integration/acp/add_policy/with_invalid_creator_arg_test.go b/tests/integration/acp/add_policy/with_invalid_creator_arg_test.go deleted file mode 100644 index 11a62528fc..0000000000 --- a/tests/integration/acp/add_policy/with_invalid_creator_arg_test.go +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2024 Democratized Data Foundation -// -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. - -package test_acp_add_policy - -import ( - "testing" - - acpIdentity "github.com/sourcenetwork/defradb/acp/identity" - testUtils "github.com/sourcenetwork/defradb/tests/integration" - - "github.com/sourcenetwork/immutable" -) - -func TestACP_AddPolicy_InvalidCreatorIdentityWithValidPolicy_Error(t *testing.T) { - test := testUtils.TestCase{ - // Using an invalid creator is not possible with other client - // types since the token authentication will fail - SupportedClientTypes: immutable.Some([]testUtils.ClientType{ - testUtils.GoClientType, - }), - - Description: "Test acp, adding policy, with invalid creator, with valid policy, return error", - - Actions: []any{ - testUtils.AddPolicy{ - Identity: immutable.Some(acpIdentity.Identity{DID: "invalid"}), - - Policy: ` - name: a policy - description: a basic policy that satisfies minimum DPI requirements - - actor: - name: actor - - resources: - users: - permissions: - read: - expr: owner - write: - expr: owner - - relations: - owner: - types: - - actor - - `, - - ExpectedError: "invalid actor ID", - }, - }, - } - - testUtils.ExecuteTestCase(t, test) -} - -func TestACP_AddPolicy_InvalidCreatorIdentityWithEmptyPolicy_Error(t *testing.T) { - test := testUtils.TestCase{ - // Using an invalid creator is not possible with other client - // types since the token authentication will fail - SupportedClientTypes: immutable.Some([]testUtils.ClientType{ - testUtils.GoClientType, - }), - - Description: "Test acp, adding policy, with invalid creator, with empty policy, return error", - - Actions: []any{ - testUtils.AddPolicy{ - Identity: immutable.Some(acpIdentity.Identity{DID: "invalid"}), - - Policy: "", - - ExpectedError: "policy data can not be empty", - }, - }, - } - - testUtils.ExecuteTestCase(t, test) -} diff --git a/tests/integration/acp/add_policy/with_invalid_relations_test.go b/tests/integration/acp/add_policy/with_invalid_relations_test.go index 2ccef61b5b..1cf3d8315b 100644 --- a/tests/integration/acp/add_policy/with_invalid_relations_test.go +++ b/tests/integration/acp/add_policy/with_invalid_relations_test.go @@ -13,6 +13,8 @@ package test_acp_add_policy import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -23,7 +25,7 @@ func TestACP_AddPolicy_NoRelations_Error(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: a policy @@ -58,7 +60,7 @@ func TestACP_AddPolicy_NoRelationsLabel_Error(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: a policy diff --git a/tests/integration/acp/add_policy/with_invalid_required_relation_test.go b/tests/integration/acp/add_policy/with_invalid_required_relation_test.go index 09b2b20a15..122d1011a5 100644 --- a/tests/integration/acp/add_policy/with_invalid_required_relation_test.go +++ b/tests/integration/acp/add_policy/with_invalid_required_relation_test.go @@ -13,6 +13,8 @@ package test_acp_add_policy import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -23,7 +25,7 @@ func TestACP_AddPolicy_MissingRequiredOwnerRelation_Error(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: a policy @@ -61,7 +63,7 @@ func TestACP_AddPolicy_DuplicateOwnerRelation_Error(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: a policy diff --git a/tests/integration/acp/add_policy/with_invalid_resource_test.go b/tests/integration/acp/add_policy/with_invalid_resource_test.go index 4eb25c8cb1..79e627e888 100644 --- a/tests/integration/acp/add_policy/with_invalid_resource_test.go +++ b/tests/integration/acp/add_policy/with_invalid_resource_test.go @@ -13,6 +13,8 @@ package test_acp_add_policy import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -23,7 +25,7 @@ func TestACP_AddPolicy_OneResourceThatIsEmpty_Error(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: a policy diff --git a/tests/integration/acp/add_policy/with_managed_relation_test.go b/tests/integration/acp/add_policy/with_managed_relation_test.go index c925d6aa82..bff8f86fb2 100644 --- a/tests/integration/acp/add_policy/with_managed_relation_test.go +++ b/tests/integration/acp/add_policy/with_managed_relation_test.go @@ -13,6 +13,8 @@ package test_acp_add_policy import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -22,7 +24,7 @@ func TestACP_AddPolicy_WithRelationManagingOtherRelation_ValidPolicyID(t *testin Description: "Test acp, where a relation is managing another relation, valid policy id", Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: a policy diff --git a/tests/integration/acp/add_policy/with_multi_policies_test.go b/tests/integration/acp/add_policy/with_multi_policies_test.go index 86f8ba963b..e413a5872a 100644 --- a/tests/integration/acp/add_policy/with_multi_policies_test.go +++ b/tests/integration/acp/add_policy/with_multi_policies_test.go @@ -13,6 +13,8 @@ package test_acp_add_policy import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -23,7 +25,7 @@ func TestACP_AddPolicy_AddMultipleDifferentPolicies_ValidPolicyIDs(t *testing.T) Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: a policy @@ -51,7 +53,7 @@ func TestACP_AddPolicy_AddMultipleDifferentPolicies_ValidPolicyIDs(t *testing.T) }, testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: a policy @@ -97,7 +99,7 @@ func TestACP_AddPolicy_AddMultipleDifferentPoliciesInDifferentFmts_ValidPolicyID Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` { @@ -132,7 +134,7 @@ func TestACP_AddPolicy_AddMultipleDifferentPoliciesInDifferentFmts_ValidPolicyID }, testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test2 @@ -199,7 +201,7 @@ func TestACP_AddPolicy_AddDuplicatePolicyByOtherCreator_ValidPolicyIDs(t *testin Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: policyUsedByBoth, @@ -207,7 +209,7 @@ func TestACP_AddPolicy_AddDuplicatePolicyByOtherCreator_ValidPolicyIDs(t *testin }, testUtils.AddPolicy{ - Identity: actor2Identity, + Identity: immutable.Some(2), Policy: policyUsedByBoth, @@ -226,7 +228,7 @@ func TestACP_AddPolicy_AddMultipleDuplicatePolicies_Error(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -254,7 +256,7 @@ func TestACP_AddPolicy_AddMultipleDuplicatePolicies_Error(t *testing.T) { }, testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -293,7 +295,7 @@ func TestACP_AddPolicy_AddMultipleDuplicatePoliciesDifferentFmts_ProducesDiffere Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -320,7 +322,7 @@ func TestACP_AddPolicy_AddMultipleDuplicatePoliciesDifferentFmts_ProducesDiffere }, testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` { diff --git a/tests/integration/acp/add_policy/with_multiple_resources_test.go b/tests/integration/acp/add_policy/with_multiple_resources_test.go index dcabf691dd..fed7ac9888 100644 --- a/tests/integration/acp/add_policy/with_multiple_resources_test.go +++ b/tests/integration/acp/add_policy/with_multiple_resources_test.go @@ -13,6 +13,8 @@ package test_acp_add_policy import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -23,7 +25,7 @@ func TestACP_AddPolicy_MultipleResources_ValidID(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -78,7 +80,7 @@ func TestACP_AddPolicy_MultipleResourcesUsingRelationDefinedInOther_Error(t *tes Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -130,7 +132,7 @@ func TestACP_AddPolicy_SecondResourcesMissingRequiredOwner_Error(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/add_policy/with_no_perms_test.go b/tests/integration/acp/add_policy/with_no_perms_test.go index 0fc3d91562..7bd55bd9d0 100644 --- a/tests/integration/acp/add_policy/with_no_perms_test.go +++ b/tests/integration/acp/add_policy/with_no_perms_test.go @@ -13,6 +13,8 @@ package test_acp_add_policy import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -31,7 +33,7 @@ func TestACP_AddPolicy_NoPermissionsOnlyOwner_ValidID(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -66,7 +68,7 @@ func TestACP_AddPolicy_NoPermissionsMultiRelations_ValidID(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -104,7 +106,7 @@ func TestACP_AddPolicy_NoPermissionsLabelOnlyOwner_ValidID(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -137,7 +139,7 @@ func TestACP_AddPolicy_NoPermissionsLabelMultiRelations_ValidID(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/add_policy/with_no_resources_test.go b/tests/integration/acp/add_policy/with_no_resources_test.go index b297ce8b3b..fd8d18b47a 100644 --- a/tests/integration/acp/add_policy/with_no_resources_test.go +++ b/tests/integration/acp/add_policy/with_no_resources_test.go @@ -13,6 +13,8 @@ package test_acp_add_policy import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -25,7 +27,7 @@ func TestACP_AddPolicy_NoResource_ValidID(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -54,7 +56,7 @@ func TestACP_AddPolicy_NoResourceLabel_ValidID(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -80,7 +82,7 @@ func TestACP_AddPolicy_PolicyWithOnlySpace_NameIsRequired(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: " ", diff --git a/tests/integration/acp/add_policy/with_perm_expr_test.go b/tests/integration/acp/add_policy/with_perm_expr_test.go index eeaf2ae69c..2329fadfe9 100644 --- a/tests/integration/acp/add_policy/with_perm_expr_test.go +++ b/tests/integration/acp/add_policy/with_perm_expr_test.go @@ -13,6 +13,8 @@ package test_acp_add_policy import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -23,7 +25,7 @@ func TestACP_AddPolicy_PermissionExprWithOwnerInTheEndWithMinus_ValidID(t *testi Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -65,7 +67,7 @@ func TestACP_AddPolicy_PermissionExprWithOwnerInTheEndWithMinusNoSpace_ValidID(t Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/add_policy/with_perm_invalid_expr_test.go b/tests/integration/acp/add_policy/with_perm_invalid_expr_test.go index 869c32c573..592c14e56d 100644 --- a/tests/integration/acp/add_policy/with_perm_invalid_expr_test.go +++ b/tests/integration/acp/add_policy/with_perm_invalid_expr_test.go @@ -13,6 +13,8 @@ package test_acp_add_policy import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -23,7 +25,7 @@ func TestACP_AddPolicy_EmptyExpressionInPermission_Error(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -64,7 +66,7 @@ func TestACP_AddPolicy_PermissionExprWithOwnerInTheEndWithInocorrectSymbol_Error Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -105,7 +107,7 @@ func TestACP_AddPolicy_PermissionExprWithOwnerInTheEndWithInocorrectSymbolNoSpac Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/add_policy/with_permissionless_owner_test.go b/tests/integration/acp/add_policy/with_permissionless_owner_test.go index 5fd70f23c5..84e76736be 100644 --- a/tests/integration/acp/add_policy/with_permissionless_owner_test.go +++ b/tests/integration/acp/add_policy/with_permissionless_owner_test.go @@ -13,6 +13,8 @@ package test_acp_add_policy import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -30,7 +32,7 @@ func TestACP_AddPolicy_PermissionlessOwnerWrite_ValidID(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -71,7 +73,7 @@ func TestACP_AddPolicy_PermissionlessOwnerRead_ValidID(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -112,7 +114,7 @@ func TestACP_AddPolicy_PermissionlessOwnerReadWrite_ValidID(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/add_policy/with_unused_relations_test.go b/tests/integration/acp/add_policy/with_unused_relations_test.go index 241720e36e..dd610150ee 100644 --- a/tests/integration/acp/add_policy/with_unused_relations_test.go +++ b/tests/integration/acp/add_policy/with_unused_relations_test.go @@ -13,6 +13,8 @@ package test_acp_add_policy import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -23,7 +25,7 @@ func TestACP_AddPolicy_UnusedRelation_ValidID(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/fixture.go b/tests/integration/acp/fixture.go deleted file mode 100644 index e1aed354b4..0000000000 --- a/tests/integration/acp/fixture.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2024 Democratized Data Foundation -// -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. - -package test_acp - -import ( - "encoding/hex" - - "github.com/decred/dcrd/dcrec/secp256k1/v4" - "github.com/sourcenetwork/immutable" - - acpIdentity "github.com/sourcenetwork/defradb/acp/identity" -) - -var ( - Actor1Identity = MustParseIdentity("028d53f37a19afb9a0dbc5b4be30c65731479ee8cfa0c9bc8f8bf198cc3c075f") - Actor2Identity = MustParseIdentity("4d092126012ebaf56161716018a71630d99443d9d5217e9d8502bb5c5456f2c5") -) - -// MustParseIdentity returns an identity that uses the given private key or panics. -func MustParseIdentity(privateKeyHex string) immutable.Option[acpIdentity.Identity] { - privateKeyBytes, err := hex.DecodeString(privateKeyHex) - if err != nil { - panic(err) - } - privateKey := secp256k1.PrivKeyFromBytes(privateKeyBytes) - identity, err := acpIdentity.FromPrivateKey(privateKey) - if err != nil { - panic(err) - } - return identity -} diff --git a/tests/integration/acp/index/create_test.go b/tests/integration/acp/index/create_test.go index 61364a0c70..c75e51bc4e 100644 --- a/tests/integration/acp/index/create_test.go +++ b/tests/integration/acp/index/create_test.go @@ -13,8 +13,9 @@ package test_acp_index import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" - acpUtils "github.com/sourcenetwork/defradb/tests/integration/acp" ) func TestACP_IndexCreateWithSeparateRequest_OnCollectionWithPolicy_NoError(t *testing.T) { @@ -23,7 +24,7 @@ func TestACP_IndexCreateWithSeparateRequest_OnCollectionWithPolicy_NoError(t *te Actions: []any{ testUtils.AddPolicy{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Policy: userPolicy, ExpectedPolicyID: "94eb195c0e459aa79e02a1986c7e731c5015721c18a373f2b2a0ed140a04b454", }, @@ -69,7 +70,7 @@ func TestACP_IndexCreateWithDirective_OnCollectionWithPolicy_NoError(t *testing. Actions: []any{ testUtils.AddPolicy{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Policy: userPolicy, ExpectedPolicyID: "94eb195c0e459aa79e02a1986c7e731c5015721c18a373f2b2a0ed140a04b454", }, diff --git a/tests/integration/acp/index/query_test.go b/tests/integration/acp/index/query_test.go index 30f0e137f9..e2818708b8 100644 --- a/tests/integration/acp/index/query_test.go +++ b/tests/integration/acp/index/query_test.go @@ -13,8 +13,9 @@ package test_acp_index import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" - acpUtils "github.com/sourcenetwork/defradb/tests/integration/acp" ) func TestACPWithIndex_UponQueryingPrivateDocWithoutIdentity_ShouldNotFetch(t *testing.T) { @@ -22,7 +23,7 @@ func TestACPWithIndex_UponQueryingPrivateDocWithoutIdentity_ShouldNotFetch(t *te Description: "Test acp, querying private doc without identity should not fetch", Actions: []any{ testUtils.AddPolicy{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Policy: userPolicy, ExpectedPolicyID: "94eb195c0e459aa79e02a1986c7e731c5015721c18a373f2b2a0ed140a04b454", }, @@ -45,7 +46,7 @@ func TestACPWithIndex_UponQueryingPrivateDocWithoutIdentity_ShouldNotFetch(t *te `, }, testUtils.CreateDoc{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Doc: ` { "name": "Islam" @@ -76,7 +77,7 @@ func TestACPWithIndex_UponQueryingPrivateDocWithIdentity_ShouldFetch(t *testing. Description: "Test acp, querying private doc with identity should fetch", Actions: []any{ testUtils.AddPolicy{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Policy: userPolicy, ExpectedPolicyID: "94eb195c0e459aa79e02a1986c7e731c5015721c18a373f2b2a0ed140a04b454", }, @@ -99,7 +100,7 @@ func TestACPWithIndex_UponQueryingPrivateDocWithIdentity_ShouldFetch(t *testing. `, }, testUtils.CreateDoc{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Doc: ` { "name": "Islam" @@ -107,7 +108,7 @@ func TestACPWithIndex_UponQueryingPrivateDocWithIdentity_ShouldFetch(t *testing. `, }, testUtils.Request{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Request: ` query { Users { @@ -134,7 +135,7 @@ func TestACPWithIndex_UponQueryingPrivateDocWithWrongIdentity_ShouldNotFetch(t * Description: "Test acp, querying private doc with wrong identity should not fetch", Actions: []any{ testUtils.AddPolicy{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Policy: userPolicy, ExpectedPolicyID: "94eb195c0e459aa79e02a1986c7e731c5015721c18a373f2b2a0ed140a04b454", }, @@ -157,7 +158,7 @@ func TestACPWithIndex_UponQueryingPrivateDocWithWrongIdentity_ShouldNotFetch(t * `, }, testUtils.CreateDoc{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Doc: ` { "name": "Islam" @@ -165,7 +166,7 @@ func TestACPWithIndex_UponQueryingPrivateDocWithWrongIdentity_ShouldNotFetch(t * `, }, testUtils.Request{ - Identity: acpUtils.Actor2Identity, + Identity: immutable.Some(2), Request: ` query { Users { diff --git a/tests/integration/acp/index/query_with_relation_test.go b/tests/integration/acp/index/query_with_relation_test.go index c68b742dad..925d35cb4f 100644 --- a/tests/integration/acp/index/query_with_relation_test.go +++ b/tests/integration/acp/index/query_with_relation_test.go @@ -13,14 +13,15 @@ package test_acp_index import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" - acpUtils "github.com/sourcenetwork/defradb/tests/integration/acp" ) func createAuthorBooksSchemaWithPolicyAndCreateDocs() []any { return []any{ testUtils.AddPolicy{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Policy: bookAuthorPolicy, ExpectedPolicyID: "f6927e8861f91122a5e3e333249297e4315b672298b5cb93ee3f49facc1e0d11", }, @@ -55,7 +56,7 @@ func createAuthorBooksSchemaWithPolicyAndCreateDocs() []any { }`, }, testUtils.CreateDoc{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), CollectionID: 0, // bae-b769708d-f552-5c3d-a402-ccfd7ac7fb04 Doc: `{ @@ -73,7 +74,7 @@ func createAuthorBooksSchemaWithPolicyAndCreateDocs() []any { }, }, testUtils.CreateDoc{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), CollectionID: 1, DocMap: map[string]any{ "name": "A Time for Mercy", @@ -82,7 +83,7 @@ func createAuthorBooksSchemaWithPolicyAndCreateDocs() []any { }, }, testUtils.CreateDoc{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), CollectionID: 1, DocMap: map[string]any{ "name": "Theif Lord", @@ -133,7 +134,7 @@ func TestACPWithIndex_UponQueryingPrivateOneToManyRelatedDocWithIdentity_ShouldF Actions: []any{ createAuthorBooksSchemaWithPolicyAndCreateDocs(), testUtils.Request{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Request: ` query { Author(filter: { @@ -179,7 +180,7 @@ func TestACPWithIndex_UponQueryingPrivateOneToManyRelatedDocWithWrongIdentity_Sh Actions: []any{ createAuthorBooksSchemaWithPolicyAndCreateDocs(), testUtils.Request{ - Identity: acpUtils.Actor2Identity, + Identity: immutable.Some(2), Request: ` query { Author(filter: { @@ -246,7 +247,7 @@ func TestACPWithIndex_UponQueryingPrivateManyToOneRelatedDocWithIdentity_ShouldF Actions: []any{ createAuthorBooksSchemaWithPolicyAndCreateDocs(), testUtils.Request{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Request: ` query { Book(filter: { @@ -291,7 +292,7 @@ func TestACPWithIndex_UponQueryingPrivateManyToOneRelatedDocWithWrongIdentity_Sh Actions: []any{ createAuthorBooksSchemaWithPolicyAndCreateDocs(), testUtils.Request{ - Identity: acpUtils.Actor2Identity, + Identity: immutable.Some(2), Request: ` query { Book(filter: { diff --git a/tests/integration/acp/p2p/replicator_test.go b/tests/integration/acp/p2p/replicator_test.go index 08aa075508..49d5b65f23 100644 --- a/tests/integration/acp/p2p/replicator_test.go +++ b/tests/integration/acp/p2p/replicator_test.go @@ -13,8 +13,9 @@ package test_acp_p2p import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" - acpUtils "github.com/sourcenetwork/defradb/tests/integration/acp" ) // This test documents that we don't allow setting replicator with a collections that has a policy @@ -32,7 +33,7 @@ func TestACP_P2POneToOneReplicatorWithPermissionedCollection_Error(t *testing.T) testUtils.AddPolicy{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/p2p/subscribe_test.go b/tests/integration/acp/p2p/subscribe_test.go index 523200e928..6ad5b84d14 100644 --- a/tests/integration/acp/p2p/subscribe_test.go +++ b/tests/integration/acp/p2p/subscribe_test.go @@ -13,8 +13,9 @@ package test_acp_p2p import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" - acpUtils "github.com/sourcenetwork/defradb/tests/integration/acp" ) // This test documents that we don't allow subscribing to a collection that has a policy @@ -32,7 +33,7 @@ func TestACP_P2PSubscribeAddGetSingleWithPermissionedCollection_Error(t *testing testUtils.AddPolicy{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/query/avg_test.go b/tests/integration/acp/query/avg_test.go index cd540f83ad..425b6e0943 100644 --- a/tests/integration/acp/query/avg_test.go +++ b/tests/integration/acp/query/avg_test.go @@ -13,8 +13,9 @@ package test_acp import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" - acpUtils "github.com/sourcenetwork/defradb/tests/integration/acp" ) func TestACP_QueryAverageWithoutIdentity(t *testing.T) { @@ -51,7 +52,7 @@ func TestACP_QueryAverageWithIdentity(t *testing.T) { getSetupEmployeeCompanyActions(), testUtils.Request{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Request: ` query { _avg(Employee: {field: salary}) @@ -78,7 +79,7 @@ func TestACP_QueryAverageWithWrongIdentity(t *testing.T) { getSetupEmployeeCompanyActions(), testUtils.Request{ - Identity: acpUtils.Actor2Identity, + Identity: immutable.Some(2), Request: ` query { _avg(Employee: {field: salary}) diff --git a/tests/integration/acp/query/count_test.go b/tests/integration/acp/query/count_test.go index 74c4025c22..33bc053a60 100644 --- a/tests/integration/acp/query/count_test.go +++ b/tests/integration/acp/query/count_test.go @@ -13,8 +13,9 @@ package test_acp import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" - acpUtils "github.com/sourcenetwork/defradb/tests/integration/acp" ) func TestACP_QueryCountDocumentsWithoutIdentity(t *testing.T) { @@ -78,7 +79,7 @@ func TestACP_QueryCountDocumentsWithIdentity(t *testing.T) { getSetupEmployeeCompanyActions(), testUtils.Request{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Request: ` query { _count(Employee: {}) @@ -104,7 +105,7 @@ func TestACP_QueryCountRelatedObjectsWithIdentity(t *testing.T) { getSetupEmployeeCompanyActions(), testUtils.Request{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Request: ` query { Company { @@ -135,7 +136,7 @@ func TestACP_QueryCountDocumentsWithWrongIdentity(t *testing.T) { getSetupEmployeeCompanyActions(), testUtils.Request{ - Identity: acpUtils.Actor2Identity, + Identity: immutable.Some(2), Request: ` query { _count(Employee: {}) @@ -161,7 +162,7 @@ func TestACP_QueryCountRelatedObjectsWithWrongIdentity(t *testing.T) { getSetupEmployeeCompanyActions(), testUtils.Request{ - Identity: acpUtils.Actor2Identity, + Identity: immutable.Some(2), Request: ` query { Company { diff --git a/tests/integration/acp/query/fixture.go b/tests/integration/acp/query/fixture.go index 2d36f9fe1b..d526a218d3 100644 --- a/tests/integration/acp/query/fixture.go +++ b/tests/integration/acp/query/fixture.go @@ -11,8 +11,9 @@ package test_acp import ( + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" - acpUtils "github.com/sourcenetwork/defradb/tests/integration/acp" ) const employeeCompanyPolicy = ` @@ -57,7 +58,7 @@ resources: func getSetupEmployeeCompanyActions() []any { return []any{ testUtils.AddPolicy{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Policy: employeeCompanyPolicy, ExpectedPolicyID: "9d6c19007a894746c3f45f7fe45513a88a20ad77637948228869546197bb1b05", }, @@ -95,7 +96,7 @@ func getSetupEmployeeCompanyActions() []any { }, testUtils.CreateDoc{ CollectionID: 1, - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Doc: ` { "name": "Private Company", @@ -121,7 +122,7 @@ func getSetupEmployeeCompanyActions() []any { }, testUtils.CreateDoc{ CollectionID: 0, - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), DocMap: map[string]any{ "name": "PrivateEmp in PubCompany", "salary": 30000, @@ -130,7 +131,7 @@ func getSetupEmployeeCompanyActions() []any { }, testUtils.CreateDoc{ CollectionID: 0, - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), DocMap: map[string]any{ "name": "PrivateEmp in PrivateCompany", "salary": 40000, diff --git a/tests/integration/acp/query/relation_objects_test.go b/tests/integration/acp/query/relation_objects_test.go index 6a1b79f8b1..92deebb788 100644 --- a/tests/integration/acp/query/relation_objects_test.go +++ b/tests/integration/acp/query/relation_objects_test.go @@ -13,8 +13,9 @@ package test_acp import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" - acpUtils "github.com/sourcenetwork/defradb/tests/integration/acp" ) func TestACP_QueryManyToOneRelationObjectsWithoutIdentity(t *testing.T) { @@ -93,7 +94,7 @@ func TestACP_QueryManyToOneRelationObjectsWithIdentity(t *testing.T) { getSetupEmployeeCompanyActions(), testUtils.Request{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Request: ` query { Employee { @@ -137,7 +138,7 @@ func TestACP_QueryOneToManyRelationObjectsWithIdentity(t *testing.T) { getSetupEmployeeCompanyActions(), testUtils.Request{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Request: ` query { Company { @@ -179,7 +180,7 @@ func TestACP_QueryManyToOneRelationObjectsWithWrongIdentity(t *testing.T) { getSetupEmployeeCompanyActions(), testUtils.Request{ - Identity: acpUtils.Actor2Identity, + Identity: immutable.Some(2), Request: ` query { Employee { @@ -215,7 +216,7 @@ func TestACP_QueryOneToManyRelationObjectsWithWrongIdentity(t *testing.T) { getSetupEmployeeCompanyActions(), testUtils.Request{ - Identity: acpUtils.Actor2Identity, + Identity: immutable.Some(2), Request: ` query { Company { diff --git a/tests/integration/acp/register_and_delete_test.go b/tests/integration/acp/register_and_delete_test.go index 910729d28e..c5a0c882ca 100644 --- a/tests/integration/acp/register_and_delete_test.go +++ b/tests/integration/acp/register_and_delete_test.go @@ -13,6 +13,8 @@ package test_acp import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -28,7 +30,7 @@ func TestACP_CreateWithoutIdentityAndDeleteWithoutIdentity_CanDelete(t *testing. Actions: []any{ testUtils.AddPolicy{ - Identity: Actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -122,7 +124,7 @@ func TestACP_CreateWithoutIdentityAndDeleteWithIdentity_CanDelete(t *testing.T) Actions: []any{ testUtils.AddPolicy{ - Identity: Actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -182,7 +184,7 @@ func TestACP_CreateWithoutIdentityAndDeleteWithIdentity_CanDelete(t *testing.T) testUtils.DeleteDoc{ CollectionID: 0, - Identity: Actor1Identity, + Identity: immutable.Some(1), DocID: 0, }, @@ -206,10 +208,6 @@ func TestACP_CreateWithoutIdentityAndDeleteWithIdentity_CanDelete(t *testing.T) } func TestACP_CreateWithIdentityAndDeleteWithIdentity_CanDelete(t *testing.T) { - // OwnerIdentity should be the same identity that is used to do the registering/creation, - // and the final read check to see the state of that registered document. - OwnerIdentity := Actor1Identity - test := testUtils.TestCase{ Description: "Test acp, create with identity, and delete with identity, can delete", @@ -217,7 +215,7 @@ func TestACP_CreateWithIdentityAndDeleteWithIdentity_CanDelete(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: OwnerIdentity, + Identity: immutable.Some(1), Policy: ` name: test @@ -266,7 +264,7 @@ func TestACP_CreateWithIdentityAndDeleteWithIdentity_CanDelete(t *testing.T) { testUtils.CreateDoc{ CollectionID: 0, - Identity: OwnerIdentity, + Identity: immutable.Some(1), Doc: ` { @@ -279,13 +277,13 @@ func TestACP_CreateWithIdentityAndDeleteWithIdentity_CanDelete(t *testing.T) { testUtils.DeleteDoc{ CollectionID: 0, - Identity: OwnerIdentity, + Identity: immutable.Some(1), DocID: 0, }, testUtils.Request{ - Identity: OwnerIdentity, + Identity: immutable.Some(1), Request: ` query { @@ -305,10 +303,6 @@ func TestACP_CreateWithIdentityAndDeleteWithIdentity_CanDelete(t *testing.T) { } func TestACP_CreateWithIdentityAndDeleteWithoutIdentity_CanNotDelete(t *testing.T) { - // OwnerIdentity should be the same identity that is used to do the registering/creation, - // and the final read check to see the state of that registered document. - OwnerIdentity := Actor1Identity - test := testUtils.TestCase{ Description: "Test acp, create with identity, and delete without identity, can not delete", @@ -316,7 +310,7 @@ func TestACP_CreateWithIdentityAndDeleteWithoutIdentity_CanNotDelete(t *testing. Actions: []any{ testUtils.AddPolicy{ - Identity: OwnerIdentity, + Identity: immutable.Some(1), Policy: ` name: test @@ -365,7 +359,7 @@ func TestACP_CreateWithIdentityAndDeleteWithoutIdentity_CanNotDelete(t *testing. testUtils.CreateDoc{ CollectionID: 0, - Identity: OwnerIdentity, + Identity: immutable.Some(1), Doc: ` { @@ -384,7 +378,7 @@ func TestACP_CreateWithIdentityAndDeleteWithoutIdentity_CanNotDelete(t *testing. }, testUtils.Request{ - Identity: OwnerIdentity, + Identity: immutable.Some(1), Request: ` query { @@ -410,12 +404,6 @@ func TestACP_CreateWithIdentityAndDeleteWithoutIdentity_CanNotDelete(t *testing. } func TestACP_CreateWithIdentityAndDeleteWithWrongIdentity_CanNotDelete(t *testing.T) { - // OwnerIdentity should be the same identity that is used to do the registering/creation, - // and the final read check to see the state of that registered document. - OwnerIdentity := Actor1Identity - - WrongIdentity := Actor2Identity - test := testUtils.TestCase{ Description: "Test acp, create with identity, and delete without identity, can not delete", @@ -423,7 +411,7 @@ func TestACP_CreateWithIdentityAndDeleteWithWrongIdentity_CanNotDelete(t *testin Actions: []any{ testUtils.AddPolicy{ - Identity: OwnerIdentity, + Identity: immutable.Some(1), Policy: ` name: test @@ -472,7 +460,7 @@ func TestACP_CreateWithIdentityAndDeleteWithWrongIdentity_CanNotDelete(t *testin testUtils.CreateDoc{ CollectionID: 0, - Identity: OwnerIdentity, + Identity: immutable.Some(1), Doc: ` { @@ -485,7 +473,7 @@ func TestACP_CreateWithIdentityAndDeleteWithWrongIdentity_CanNotDelete(t *testin testUtils.DeleteDoc{ CollectionID: 0, - Identity: WrongIdentity, + Identity: immutable.Some(2), DocID: 0, @@ -493,7 +481,7 @@ func TestACP_CreateWithIdentityAndDeleteWithWrongIdentity_CanNotDelete(t *testin }, testUtils.Request{ - Identity: OwnerIdentity, + Identity: immutable.Some(1), Request: ` query { diff --git a/tests/integration/acp/register_and_read_test.go b/tests/integration/acp/register_and_read_test.go index a60cd130b2..dabf356e3c 100644 --- a/tests/integration/acp/register_and_read_test.go +++ b/tests/integration/acp/register_and_read_test.go @@ -13,6 +13,8 @@ package test_acp import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -24,7 +26,7 @@ func TestACP_CreateWithoutIdentityAndReadWithoutIdentity_CanRead(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: Actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -113,7 +115,7 @@ func TestACP_CreateWithoutIdentityAndReadWithIdentity_CanRead(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: Actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -171,7 +173,7 @@ func TestACP_CreateWithoutIdentityAndReadWithIdentity_CanRead(t *testing.T) { }, testUtils.Request{ - Identity: Actor1Identity, + Identity: immutable.Some(1), Request: ` query { @@ -204,7 +206,7 @@ func TestACP_CreateWithIdentityAndReadWithIdentity_CanRead(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: Actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -253,7 +255,7 @@ func TestACP_CreateWithIdentityAndReadWithIdentity_CanRead(t *testing.T) { testUtils.CreateDoc{ CollectionID: 0, - Identity: Actor1Identity, + Identity: immutable.Some(1), Doc: ` { @@ -264,7 +266,7 @@ func TestACP_CreateWithIdentityAndReadWithIdentity_CanRead(t *testing.T) { }, testUtils.Request{ - Identity: Actor1Identity, + Identity: immutable.Some(1), Request: ` query { @@ -297,7 +299,7 @@ func TestACP_CreateWithIdentityAndReadWithoutIdentity_CanNotRead(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: Actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -346,7 +348,7 @@ func TestACP_CreateWithIdentityAndReadWithoutIdentity_CanNotRead(t *testing.T) { testUtils.CreateDoc{ CollectionID: 0, - Identity: Actor1Identity, + Identity: immutable.Some(1), Doc: ` { @@ -382,7 +384,7 @@ func TestACP_CreateWithIdentityAndReadWithWrongIdentity_CanNotRead(t *testing.T) Actions: []any{ testUtils.AddPolicy{ - Identity: Actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -431,7 +433,7 @@ func TestACP_CreateWithIdentityAndReadWithWrongIdentity_CanNotRead(t *testing.T) testUtils.CreateDoc{ CollectionID: 0, - Identity: Actor1Identity, + Identity: immutable.Some(1), Doc: ` { @@ -442,7 +444,7 @@ func TestACP_CreateWithIdentityAndReadWithWrongIdentity_CanNotRead(t *testing.T) }, testUtils.Request{ - Identity: Actor2Identity, + Identity: immutable.Some(2), Request: ` query { diff --git a/tests/integration/acp/register_and_update_test.go b/tests/integration/acp/register_and_update_test.go index 9394c5f012..edfeb99c97 100644 --- a/tests/integration/acp/register_and_update_test.go +++ b/tests/integration/acp/register_and_update_test.go @@ -30,7 +30,7 @@ func TestACP_CreateWithoutIdentityAndUpdateWithoutIdentity_CanUpdate(t *testing. Actions: []any{ testUtils.AddPolicy{ - Identity: Actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -136,7 +136,7 @@ func TestACP_CreateWithoutIdentityAndUpdateWithIdentity_CanUpdate(t *testing.T) Actions: []any{ testUtils.AddPolicy{ - Identity: Actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -196,7 +196,7 @@ func TestACP_CreateWithoutIdentityAndUpdateWithIdentity_CanUpdate(t *testing.T) testUtils.UpdateDoc{ CollectionID: 0, - Identity: Actor1Identity, + Identity: immutable.Some(1), DocID: 0, @@ -232,10 +232,6 @@ func TestACP_CreateWithoutIdentityAndUpdateWithIdentity_CanUpdate(t *testing.T) } func TestACP_CreateWithIdentityAndUpdateWithIdentity_CanUpdate(t *testing.T) { - // OwnerIdentity should be the same identity that is used to do the registering/creation, - // and the final read check to see the state of that registered document. - OwnerIdentity := Actor1Identity - test := testUtils.TestCase{ Description: "Test acp, create with identity, and update with identity, can update", @@ -243,7 +239,7 @@ func TestACP_CreateWithIdentityAndUpdateWithIdentity_CanUpdate(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: OwnerIdentity, + Identity: immutable.Some(1), Policy: ` name: test @@ -292,7 +288,7 @@ func TestACP_CreateWithIdentityAndUpdateWithIdentity_CanUpdate(t *testing.T) { testUtils.CreateDoc{ CollectionID: 0, - Identity: OwnerIdentity, + Identity: immutable.Some(1), Doc: ` { @@ -305,7 +301,7 @@ func TestACP_CreateWithIdentityAndUpdateWithIdentity_CanUpdate(t *testing.T) { testUtils.UpdateDoc{ CollectionID: 0, - Identity: OwnerIdentity, + Identity: immutable.Some(1), DocID: 0, @@ -317,7 +313,7 @@ func TestACP_CreateWithIdentityAndUpdateWithIdentity_CanUpdate(t *testing.T) { }, testUtils.Request{ - Identity: OwnerIdentity, + Identity: immutable.Some(1), Request: ` query { @@ -343,10 +339,6 @@ func TestACP_CreateWithIdentityAndUpdateWithIdentity_CanUpdate(t *testing.T) { } func TestACP_CreateWithIdentityAndUpdateWithoutIdentity_CanNotUpdate(t *testing.T) { - // OwnerIdentity should be the same identity that is used to do the registering/creation, - // and the final read check to see the state of that registered document. - OwnerIdentity := Actor1Identity - test := testUtils.TestCase{ Description: "Test acp, create with identity, and update without identity, can not update", @@ -360,7 +352,7 @@ func TestACP_CreateWithIdentityAndUpdateWithoutIdentity_CanNotUpdate(t *testing. Actions: []any{ testUtils.AddPolicy{ - Identity: OwnerIdentity, + Identity: immutable.Some(1), Policy: ` name: test @@ -409,7 +401,7 @@ func TestACP_CreateWithIdentityAndUpdateWithoutIdentity_CanNotUpdate(t *testing. testUtils.CreateDoc{ CollectionID: 0, - Identity: OwnerIdentity, + Identity: immutable.Some(1), Doc: ` { @@ -434,7 +426,7 @@ func TestACP_CreateWithIdentityAndUpdateWithoutIdentity_CanNotUpdate(t *testing. }, testUtils.Request{ - Identity: OwnerIdentity, + Identity: immutable.Some(1), Request: ` query { @@ -460,12 +452,6 @@ func TestACP_CreateWithIdentityAndUpdateWithoutIdentity_CanNotUpdate(t *testing. } func TestACP_CreateWithIdentityAndUpdateWithWrongIdentity_CanNotUpdate(t *testing.T) { - // OwnerIdentity should be the same identity that is used to do the registering/creation, - // and the final read check to see the state of that registered document. - OwnerIdentity := Actor1Identity - - WrongIdentity := Actor2Identity - test := testUtils.TestCase{ Description: "Test acp, create with identity, and update without identity, can not update", @@ -479,7 +465,7 @@ func TestACP_CreateWithIdentityAndUpdateWithWrongIdentity_CanNotUpdate(t *testin Actions: []any{ testUtils.AddPolicy{ - Identity: OwnerIdentity, + Identity: immutable.Some(1), Policy: ` name: test @@ -528,7 +514,7 @@ func TestACP_CreateWithIdentityAndUpdateWithWrongIdentity_CanNotUpdate(t *testin testUtils.CreateDoc{ CollectionID: 0, - Identity: OwnerIdentity, + Identity: immutable.Some(1), Doc: ` { @@ -541,7 +527,7 @@ func TestACP_CreateWithIdentityAndUpdateWithWrongIdentity_CanNotUpdate(t *testin testUtils.UpdateDoc{ CollectionID: 0, - Identity: WrongIdentity, + Identity: immutable.Some(2), DocID: 0, @@ -555,7 +541,7 @@ func TestACP_CreateWithIdentityAndUpdateWithWrongIdentity_CanNotUpdate(t *testin }, testUtils.Request{ - Identity: OwnerIdentity, + Identity: immutable.Some(1), Request: ` query { @@ -583,10 +569,6 @@ func TestACP_CreateWithIdentityAndUpdateWithWrongIdentity_CanNotUpdate(t *testin // This separate GQL test should be merged with the ones above when all the clients are fixed // to behave the same in: https://github.com/sourcenetwork/defradb/issues/2410 func TestACP_CreateWithIdentityAndUpdateWithoutIdentityGQL_CanNotUpdate(t *testing.T) { - // OwnerIdentity should be the same identity that is used to do the registering/creation, - // and the final read check to see the state of that registered document. - OwnerIdentity := Actor1Identity - test := testUtils.TestCase{ Description: "Test acp, create with identity, and update without identity (gql), can not update", @@ -599,7 +581,7 @@ func TestACP_CreateWithIdentityAndUpdateWithoutIdentityGQL_CanNotUpdate(t *testi Actions: []any{ testUtils.AddPolicy{ - Identity: OwnerIdentity, + Identity: immutable.Some(1), Policy: ` name: test @@ -648,7 +630,7 @@ func TestACP_CreateWithIdentityAndUpdateWithoutIdentityGQL_CanNotUpdate(t *testi testUtils.CreateDoc{ CollectionID: 0, - Identity: OwnerIdentity, + Identity: immutable.Some(1), Doc: ` { @@ -671,7 +653,7 @@ func TestACP_CreateWithIdentityAndUpdateWithoutIdentityGQL_CanNotUpdate(t *testi }, testUtils.Request{ - Identity: OwnerIdentity, + Identity: immutable.Some(1), Request: ` query { @@ -699,12 +681,6 @@ func TestACP_CreateWithIdentityAndUpdateWithoutIdentityGQL_CanNotUpdate(t *testi // This separate GQL test should be merged with the ones above when all the clients are fixed // to behave the same in: https://github.com/sourcenetwork/defradb/issues/2410 func TestACP_CreateWithIdentityAndUpdateWithWrongIdentityGQL_CanNotUpdate(t *testing.T) { - // OwnerIdentity should be the same identity that is used to do the registering/creation, - // and the final read check to see the state of that registered document. - OwnerIdentity := Actor1Identity - - WrongIdentity := Actor2Identity - test := testUtils.TestCase{ Description: "Test acp, create with identity, and update without identity (gql), can not update", @@ -717,7 +693,7 @@ func TestACP_CreateWithIdentityAndUpdateWithWrongIdentityGQL_CanNotUpdate(t *tes Actions: []any{ testUtils.AddPolicy{ - Identity: OwnerIdentity, + Identity: immutable.Some(1), Policy: ` name: test @@ -766,7 +742,7 @@ func TestACP_CreateWithIdentityAndUpdateWithWrongIdentityGQL_CanNotUpdate(t *tes testUtils.CreateDoc{ CollectionID: 0, - Identity: OwnerIdentity, + Identity: immutable.Some(1), Doc: ` { @@ -779,7 +755,7 @@ func TestACP_CreateWithIdentityAndUpdateWithWrongIdentityGQL_CanNotUpdate(t *tes testUtils.UpdateDoc{ CollectionID: 0, - Identity: WrongIdentity, + Identity: immutable.Some(2), DocID: 0, @@ -791,7 +767,7 @@ func TestACP_CreateWithIdentityAndUpdateWithWrongIdentityGQL_CanNotUpdate(t *tes }, testUtils.Request{ - Identity: OwnerIdentity, + Identity: immutable.Some(1), Request: ` query { diff --git a/tests/integration/acp/schema/add_dpi/accept_basic_dpi_fmts_test.go b/tests/integration/acp/schema/add_dpi/accept_basic_dpi_fmts_test.go index aed2682b65..5104309f22 100644 --- a/tests/integration/acp/schema/add_dpi/accept_basic_dpi_fmts_test.go +++ b/tests/integration/acp/schema/add_dpi/accept_basic_dpi_fmts_test.go @@ -14,6 +14,8 @@ import ( "fmt" "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" schemaUtils "github.com/sourcenetwork/defradb/tests/integration/schema" ) @@ -28,7 +30,7 @@ func TestACP_AddDPISchema_BasicYAML_SchemaAccepted(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -123,7 +125,7 @@ func TestACP_AddDPISchema_BasicJSON_SchemaAccepted(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` { diff --git a/tests/integration/acp/schema/add_dpi/accept_extra_permissions_on_dpi_test.go b/tests/integration/acp/schema/add_dpi/accept_extra_permissions_on_dpi_test.go index a06e1e68f0..4d6409c026 100644 --- a/tests/integration/acp/schema/add_dpi/accept_extra_permissions_on_dpi_test.go +++ b/tests/integration/acp/schema/add_dpi/accept_extra_permissions_on_dpi_test.go @@ -14,6 +14,8 @@ import ( "fmt" "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" schemaUtils "github.com/sourcenetwork/defradb/tests/integration/schema" ) @@ -29,7 +31,7 @@ func TestACP_AddDPISchema_WithExtraPermsHavingRequiredRelation_AcceptSchema(t *t testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -129,7 +131,7 @@ func TestACP_AddDPISchema_WithExtraPermsHavingRequiredRelationInTheEnd_AcceptSch testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -229,7 +231,7 @@ func TestACP_AddDPISchema_WithExtraPermsHavingNoRequiredRelation_AcceptSchema(t testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/schema/add_dpi/accept_managed_relation_on_dpi_test.go b/tests/integration/acp/schema/add_dpi/accept_managed_relation_on_dpi_test.go index 0d7f05394f..42eed6b876 100644 --- a/tests/integration/acp/schema/add_dpi/accept_managed_relation_on_dpi_test.go +++ b/tests/integration/acp/schema/add_dpi/accept_managed_relation_on_dpi_test.go @@ -14,6 +14,8 @@ import ( "fmt" "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" schemaUtils "github.com/sourcenetwork/defradb/tests/integration/schema" ) @@ -29,7 +31,7 @@ func TestACP_AddDPISchema_WithManagedRelation_AcceptSchemas(t *testing.T) { testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/schema/add_dpi/accept_mixed_resources_on_partial_dpi_test.go b/tests/integration/acp/schema/add_dpi/accept_mixed_resources_on_partial_dpi_test.go index b97fda9e9f..288e3ecfa3 100644 --- a/tests/integration/acp/schema/add_dpi/accept_mixed_resources_on_partial_dpi_test.go +++ b/tests/integration/acp/schema/add_dpi/accept_mixed_resources_on_partial_dpi_test.go @@ -14,6 +14,8 @@ import ( "fmt" "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" schemaUtils "github.com/sourcenetwork/defradb/tests/integration/schema" ) @@ -29,7 +31,7 @@ func TestACP_AddDPISchema_PartialValidDPIButUseOnlyValidDPIResource_AcceptSchema testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/schema/add_dpi/accept_multi_dpis_test.go b/tests/integration/acp/schema/add_dpi/accept_multi_dpis_test.go index 15bb7358dd..db64e70e8d 100644 --- a/tests/integration/acp/schema/add_dpi/accept_multi_dpis_test.go +++ b/tests/integration/acp/schema/add_dpi/accept_multi_dpis_test.go @@ -14,6 +14,8 @@ import ( "fmt" "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" schemaUtils "github.com/sourcenetwork/defradb/tests/integration/schema" ) @@ -54,7 +56,7 @@ func TestACP_AddDPISchema_AddDuplicateDPIsByOtherCreatorsUseBoth_AcceptSchema(t Actions: []any{ testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: validDPIUsedByBoth, @@ -63,7 +65,7 @@ func TestACP_AddDPISchema_AddDuplicateDPIsByOtherCreatorsUseBoth_AcceptSchema(t testUtils.AddPolicy{ - Identity: actor2Identity, + Identity: immutable.Some(2), Policy: validDPIUsedByBoth, diff --git a/tests/integration/acp/schema/add_dpi/accept_multi_resources_on_dpi_test.go b/tests/integration/acp/schema/add_dpi/accept_multi_resources_on_dpi_test.go index ed35d8ac91..a8da38040e 100644 --- a/tests/integration/acp/schema/add_dpi/accept_multi_resources_on_dpi_test.go +++ b/tests/integration/acp/schema/add_dpi/accept_multi_resources_on_dpi_test.go @@ -14,6 +14,8 @@ import ( "fmt" "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" schemaUtils "github.com/sourcenetwork/defradb/tests/integration/schema" ) @@ -29,7 +31,7 @@ func TestACP_AddDPISchema_WithMultipleResources_AcceptSchema(t *testing.T) { testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -139,7 +141,7 @@ func TestACP_AddDPISchema_WithMultipleResourcesBothBeingUsed_AcceptSchema(t *tes testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/schema/add_dpi/accept_same_resource_on_diff_schemas_test.go b/tests/integration/acp/schema/add_dpi/accept_same_resource_on_diff_schemas_test.go index 5113c5cd79..812b5ba154 100644 --- a/tests/integration/acp/schema/add_dpi/accept_same_resource_on_diff_schemas_test.go +++ b/tests/integration/acp/schema/add_dpi/accept_same_resource_on_diff_schemas_test.go @@ -14,6 +14,8 @@ import ( "fmt" "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" schemaUtils "github.com/sourcenetwork/defradb/tests/integration/schema" ) @@ -30,7 +32,7 @@ func TestACP_AddDPISchema_UseSameResourceOnDifferentSchemas_AcceptSchemas(t *tes testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/schema/add_dpi/fixture.go b/tests/integration/acp/schema/add_dpi/fixture.go deleted file mode 100644 index 3b3c83da6f..0000000000 --- a/tests/integration/acp/schema/add_dpi/fixture.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2024 Democratized Data Foundation -// -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. - -package test_acp_schema_add_dpi - -import ( - acpUtils "github.com/sourcenetwork/defradb/tests/integration/acp" -) - -var actor1Identity = acpUtils.Actor1Identity -var actor2Identity = acpUtils.Actor2Identity diff --git a/tests/integration/acp/schema/add_dpi/reject_empty_arg_on_schema_test.go b/tests/integration/acp/schema/add_dpi/reject_empty_arg_on_schema_test.go index 0827374417..bde886d7de 100644 --- a/tests/integration/acp/schema/add_dpi/reject_empty_arg_on_schema_test.go +++ b/tests/integration/acp/schema/add_dpi/reject_empty_arg_on_schema_test.go @@ -13,6 +13,8 @@ package test_acp_schema_add_dpi import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -27,7 +29,7 @@ func TestACP_AddDPISchema_NoArgWasSpecifiedOnSchema_SchemaRejected(t *testing.T) testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -102,7 +104,7 @@ func TestACP_AddDPISchema_SpecifiedArgsAreEmptyOnSchema_SchemaRejected(t *testin testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/schema/add_dpi/reject_invalid_arg_type_on_schema_test.go b/tests/integration/acp/schema/add_dpi/reject_invalid_arg_type_on_schema_test.go index 1e31ce48b8..5aaa44bc56 100644 --- a/tests/integration/acp/schema/add_dpi/reject_invalid_arg_type_on_schema_test.go +++ b/tests/integration/acp/schema/add_dpi/reject_invalid_arg_type_on_schema_test.go @@ -14,6 +14,8 @@ import ( "fmt" "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -28,7 +30,7 @@ func TestACP_AddDPISchema_InvalidPolicyIDArgTypeWasSpecifiedOnSchema_SchemaRejec testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -103,7 +105,7 @@ func TestACP_AddDPISchema_InvalidResourceArgTypeWasSpecifiedOnSchema_SchemaRejec testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/schema/add_dpi/reject_invalid_owner_read_perm_on_dpi_test.go b/tests/integration/acp/schema/add_dpi/reject_invalid_owner_read_perm_on_dpi_test.go index aeca7916c9..74747b9fb3 100644 --- a/tests/integration/acp/schema/add_dpi/reject_invalid_owner_read_perm_on_dpi_test.go +++ b/tests/integration/acp/schema/add_dpi/reject_invalid_owner_read_perm_on_dpi_test.go @@ -14,6 +14,8 @@ import ( "fmt" "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -28,7 +30,7 @@ func TestACP_AddDPISchema_OwnerMissingRequiredReadPermissionOnDPI_SchemaRejected testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -113,7 +115,7 @@ func TestACP_AddDPISchema_OwnerMissingRequiredReadPermissionLabelOnDPI_SchemaRej testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -197,7 +199,7 @@ func TestACP_AddDPISchema_OwnerSpecifiedIncorrectlyOnReadPermissionExprOnDPI_Sch testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -282,7 +284,7 @@ func TestACP_AddDPISchema_OwnerSpecifiedIncorrectlyOnReadPermissionNoSpaceExprOn testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -367,7 +369,7 @@ func TestACP_AddDPISchema_MaliciousOwnerSpecifiedOnReadPermissionExprOnDPI_Schem testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/schema/add_dpi/reject_invalid_owner_read_perm_symbol_on_dpi_test.go b/tests/integration/acp/schema/add_dpi/reject_invalid_owner_read_perm_symbol_on_dpi_test.go index 97ea88b78f..5c52c37aeb 100644 --- a/tests/integration/acp/schema/add_dpi/reject_invalid_owner_read_perm_symbol_on_dpi_test.go +++ b/tests/integration/acp/schema/add_dpi/reject_invalid_owner_read_perm_symbol_on_dpi_test.go @@ -14,6 +14,8 @@ import ( "fmt" "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -28,7 +30,7 @@ func TestACP_AddDPISchema_OwnerRelationWithDifferenceSetOpOnReadPermissionExprOn testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -114,7 +116,7 @@ func TestACP_AddDPISchema_OwnerRelationWithIntersectionSetOpOnReadPermissionExpr testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -200,7 +202,7 @@ func TestACP_AddDPISchema_OwnerRelationWithInvalidSetOpOnReadPermissionExprOnDPI testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/schema/add_dpi/reject_invalid_owner_write_perm_on_dpi_test.go b/tests/integration/acp/schema/add_dpi/reject_invalid_owner_write_perm_on_dpi_test.go index 69fd6cfa5e..a2cf05fc27 100644 --- a/tests/integration/acp/schema/add_dpi/reject_invalid_owner_write_perm_on_dpi_test.go +++ b/tests/integration/acp/schema/add_dpi/reject_invalid_owner_write_perm_on_dpi_test.go @@ -14,6 +14,8 @@ import ( "fmt" "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -28,7 +30,7 @@ func TestACP_AddDPISchema_OwnerMissingRequiredWritePermissionOnDPI_SchemaRejecte testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -113,7 +115,7 @@ func TestACP_AddDPISchema_OwnerMissingRequiredWritePermissionLabelOnDPI_SchemaRe testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -197,7 +199,7 @@ func TestACP_AddDPISchema_OwnerSpecifiedIncorrectlyOnWritePermissionExprOnDPI_Sc testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -282,7 +284,7 @@ func TestACP_AddDPISchema_OwnerSpecifiedIncorrectlyOnWritePermissionNoSpaceExprO testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -367,7 +369,7 @@ func TestACP_AddDPISchema_MaliciousOwnerSpecifiedOnWritePermissionExprOnDPI_Sche testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/schema/add_dpi/reject_invalid_owner_write_perm_symbol_on_dpi_test.go b/tests/integration/acp/schema/add_dpi/reject_invalid_owner_write_perm_symbol_on_dpi_test.go index b4699bd0c5..1c523eeb68 100644 --- a/tests/integration/acp/schema/add_dpi/reject_invalid_owner_write_perm_symbol_on_dpi_test.go +++ b/tests/integration/acp/schema/add_dpi/reject_invalid_owner_write_perm_symbol_on_dpi_test.go @@ -14,6 +14,8 @@ import ( "fmt" "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -28,7 +30,7 @@ func TestACP_AddDPISchema_OwnerRelationWithDifferenceSetOpOnWritePermissionExprO testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -114,7 +116,7 @@ func TestACP_AddDPISchema_OwnerRelationWithIntersectionSetOpOnWritePermissionExp testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -200,7 +202,7 @@ func TestACP_AddDPISchema_OwnerRelationWithInvalidSetOpOnWritePermissionExprOnDP testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/schema/add_dpi/reject_missing_dpi_test.go b/tests/integration/acp/schema/add_dpi/reject_missing_dpi_test.go index 470e11a339..df40f3b202 100644 --- a/tests/integration/acp/schema/add_dpi/reject_missing_dpi_test.go +++ b/tests/integration/acp/schema/add_dpi/reject_missing_dpi_test.go @@ -14,6 +14,8 @@ import ( "fmt" "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -79,7 +81,7 @@ func TestACP_AddDPISchema_WhereAPolicyWasAddedButLinkedPolicyWasNotAdded_SchemaR testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/schema/add_dpi/reject_missing_id_arg_on_schema_test.go b/tests/integration/acp/schema/add_dpi/reject_missing_id_arg_on_schema_test.go index e7b1e55269..7a5dc39f3a 100644 --- a/tests/integration/acp/schema/add_dpi/reject_missing_id_arg_on_schema_test.go +++ b/tests/integration/acp/schema/add_dpi/reject_missing_id_arg_on_schema_test.go @@ -13,6 +13,8 @@ package test_acp_schema_add_dpi import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -27,7 +29,7 @@ func TestACP_AddDPISchema_NoPolicyIDWasSpecifiedOnSchema_SchemaRejected(t *testi testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -102,7 +104,7 @@ func TestACP_AddDPISchema_SpecifiedPolicyIDArgIsEmptyOnSchema_SchemaRejected(t * testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/schema/add_dpi/reject_missing_perms_on_dpi_test.go b/tests/integration/acp/schema/add_dpi/reject_missing_perms_on_dpi_test.go index f5af9d515e..0b93b6df16 100644 --- a/tests/integration/acp/schema/add_dpi/reject_missing_perms_on_dpi_test.go +++ b/tests/integration/acp/schema/add_dpi/reject_missing_perms_on_dpi_test.go @@ -14,6 +14,8 @@ import ( "fmt" "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -28,7 +30,7 @@ func TestACP_AddDPISchema_MissingRequiredReadPermissionOnDPI_SchemaRejected(t *t testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/schema/add_dpi/reject_missing_resource_arg_on_schema_test.go b/tests/integration/acp/schema/add_dpi/reject_missing_resource_arg_on_schema_test.go index 1d3110bacc..2013b93225 100644 --- a/tests/integration/acp/schema/add_dpi/reject_missing_resource_arg_on_schema_test.go +++ b/tests/integration/acp/schema/add_dpi/reject_missing_resource_arg_on_schema_test.go @@ -14,6 +14,8 @@ import ( "fmt" "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -28,7 +30,7 @@ func TestACP_AddDPISchema_NoResourceWasSpecifiedOnSchema_SchemaRejected(t *testi testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test @@ -105,7 +107,7 @@ func TestACP_AddDPISchema_SpecifiedResourceArgIsEmptyOnSchema_SchemaRejected(t * testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/schema/add_dpi/reject_missing_resource_on_dpi_test.go b/tests/integration/acp/schema/add_dpi/reject_missing_resource_on_dpi_test.go index 9ab5e3b184..0c8354a625 100644 --- a/tests/integration/acp/schema/add_dpi/reject_missing_resource_on_dpi_test.go +++ b/tests/integration/acp/schema/add_dpi/reject_missing_resource_on_dpi_test.go @@ -14,6 +14,8 @@ import ( "fmt" "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -28,7 +30,7 @@ func TestACP_AddDPISchema_SpecifiedResourceDoesNotExistOnDPI_SchemaRejected(t *t testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/acp/schema/add_dpi/reject_mixed_resources_on_partial_dpi_test.go b/tests/integration/acp/schema/add_dpi/reject_mixed_resources_on_partial_dpi_test.go index 7896588f1b..e346da3536 100644 --- a/tests/integration/acp/schema/add_dpi/reject_mixed_resources_on_partial_dpi_test.go +++ b/tests/integration/acp/schema/add_dpi/reject_mixed_resources_on_partial_dpi_test.go @@ -14,6 +14,8 @@ import ( "fmt" "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -28,7 +30,7 @@ func TestACP_AddDPISchema_PartialValidDPIButUseInValidDPIResource_RejectSchema(t testUtils.AddPolicy{ - Identity: actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/collection_description/updates/remove/policy_test.go b/tests/integration/collection_description/updates/remove/policy_test.go index 1f7020308f..0c498016a4 100644 --- a/tests/integration/collection_description/updates/remove/policy_test.go +++ b/tests/integration/collection_description/updates/remove/policy_test.go @@ -13,8 +13,9 @@ package remove import ( "testing" + "github.com/sourcenetwork/immutable" + testUtils "github.com/sourcenetwork/defradb/tests/integration" - acpUtils "github.com/sourcenetwork/defradb/tests/integration/acp" ) func TestColDescrUpdateRemovePolicy_Errors(t *testing.T) { @@ -22,7 +23,7 @@ func TestColDescrUpdateRemovePolicy_Errors(t *testing.T) { Actions: []any{ testUtils.AddPolicy{ - Identity: acpUtils.Actor1Identity, + Identity: immutable.Some(1), Policy: ` name: test diff --git a/tests/integration/state.go b/tests/integration/state.go index 47affa8160..a2d8a338ca 100644 --- a/tests/integration/state.go +++ b/tests/integration/state.go @@ -16,6 +16,7 @@ import ( "github.com/libp2p/go-libp2p/core/peer" + identity "github.com/sourcenetwork/defradb/acp/identity" "github.com/sourcenetwork/defradb/client" "github.com/sourcenetwork/defradb/datastore" "github.com/sourcenetwork/defradb/event" @@ -44,6 +45,8 @@ type state struct { // This is order dependent and the property is accessed by index. txns []datastore.Txn + identities []identity.Identity + // Will recieve an item once all actions have finished processing. allActionsDone chan struct{} diff --git a/tests/integration/test_case.go b/tests/integration/test_case.go index 948ae1838e..3af3303446 100644 --- a/tests/integration/test_case.go +++ b/tests/integration/test_case.go @@ -16,7 +16,6 @@ import ( "github.com/lens-vm/lens/host-go/config/model" "github.com/sourcenetwork/immutable" - acpIdentity "github.com/sourcenetwork/defradb/acp/identity" "github.com/sourcenetwork/defradb/client" "github.com/sourcenetwork/defradb/net" "github.com/sourcenetwork/defradb/tests/gen" @@ -228,7 +227,7 @@ type CreateDoc struct { // // If an Identity is provided and the collection has a policy, then the // created document(s) will be owned by this Identity. - Identity immutable.Option[acpIdentity.Identity] + Identity immutable.Option[int] // Specifies whether the document should be encrypted. IsEncrypted bool @@ -294,7 +293,7 @@ type DeleteDoc struct { // // If an Identity is provided and the collection has a policy, then // can also delete private document(s) that are owned by this Identity. - Identity immutable.Option[acpIdentity.Identity] + Identity immutable.Option[int] // The collection in which this document should be deleted. CollectionID int @@ -327,7 +326,7 @@ type UpdateDoc struct { // // If an Identity is provided and the collection has a policy, then // can also update private document(s) that are owned by this Identity. - Identity immutable.Option[acpIdentity.Identity] + Identity immutable.Option[int] // The collection in which this document exists. CollectionID int @@ -481,7 +480,7 @@ type Request struct { // // If an Identity is provided and the collection has a policy, then can // operate over private document(s) that are owned by this Identity. - Identity immutable.Option[acpIdentity.Identity] + Identity immutable.Option[int] // Used to identify the transaction for this to run against. Optional. TransactionID immutable.Option[int] diff --git a/tests/integration/utils2.go b/tests/integration/utils2.go index 05a5efe397..1dc8006b1b 100644 --- a/tests/integration/utils2.go +++ b/tests/integration/utils2.go @@ -885,7 +885,7 @@ func refreshDocuments( continue } - ctx := makeContextForDocCreate(s.ctx, &action) + ctx := makeContextForDocCreate(s, s.ctx, &action) // The document may have been mutated by other actions, so to be sure we have the latest // version without having to worry about the individual update mechanics we fetch it. @@ -1238,7 +1238,7 @@ func createDocViaColSave( txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) - ctx := makeContextForDocCreate(db.SetContextTxn(s.ctx, txn), &action) + ctx := makeContextForDocCreate(s, db.SetContextTxn(s.ctx, txn), &action) for _, doc := range docs { err = collections[action.CollectionID].Save(ctx, doc) @@ -1249,8 +1249,9 @@ func createDocViaColSave( return docs, nil } -func makeContextForDocCreate(ctx context.Context, action *CreateDoc) context.Context { - ctx = db.SetContextIdentity(ctx, action.Identity) +func makeContextForDocCreate(s *state, ctx context.Context, action *CreateDoc) context.Context { + identity := getIdentity(s, action.Identity) + ctx = db.SetContextIdentity(ctx, identity) if action.IsEncrypted { ctx = encryption.SetContextConfig(ctx, encryption.DocEncConfig{IsEncrypted: true}) } @@ -1283,7 +1284,7 @@ func createDocViaColCreate( txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) - ctx := makeContextForDocCreate(db.SetContextTxn(s.ctx, txn), &action) + ctx := makeContextForDocCreate(s, db.SetContextTxn(s.ctx, txn), &action) if len(docs) > 1 { err = collections[action.CollectionID].CreateMany(ctx, docs) @@ -1337,7 +1338,7 @@ func createDocViaGQL( txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) - ctx := makeContextForDocCreate(db.SetContextTxn(s.ctx, txn), &action) + ctx := makeContextForDocCreate(s, db.SetContextTxn(s.ctx, txn), &action) result := node.ExecRequest(ctx, req) if len(result.GQL.Errors) > 0 { @@ -1391,7 +1392,8 @@ func deleteDoc( action DeleteDoc, ) { doc := s.documents[action.CollectionID][action.DocID] - ctx := db.SetContextIdentity(s.ctx, action.Identity) + identity := getIdentity(s, action.Identity) + ctx := db.SetContextIdentity(s.ctx, identity) var expectedErrorRaised bool actionNodes := getNodes(action.NodeID, s.nodes) @@ -1449,7 +1451,8 @@ func updateDocViaColSave( collections []client.Collection, ) error { cachedDoc := s.documents[action.CollectionID][action.DocID] - ctx := db.SetContextIdentity(s.ctx, action.Identity) + identity := getIdentity(s, action.Identity) + ctx := db.SetContextIdentity(s.ctx, identity) doc, err := collections[action.CollectionID].Get(ctx, cachedDoc.ID(), true) if err != nil { @@ -1476,7 +1479,8 @@ func updateDocViaColUpdate( collections []client.Collection, ) error { cachedDoc := s.documents[action.CollectionID][action.DocID] - ctx := db.SetContextIdentity(s.ctx, action.Identity) + identity := getIdentity(s, action.Identity) + ctx := db.SetContextIdentity(s.ctx, identity) doc, err := collections[action.CollectionID].Get(ctx, cachedDoc.ID(), true) if err != nil { @@ -1519,7 +1523,8 @@ func updateDocViaGQL( txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) ctx := db.SetContextTxn(s.ctx, txn) - ctx = db.SetContextIdentity(ctx, action.Identity) + identity := getIdentity(s, action.Identity) + ctx = db.SetContextIdentity(ctx, identity) result := node.ExecRequest(ctx, request) if len(result.GQL.Errors) > 0 { @@ -1739,7 +1744,8 @@ func executeRequest( txn := getTransaction(s, node, action.TransactionID, action.ExpectedError) ctx := db.SetContextTxn(s.ctx, txn) - ctx = db.SetContextIdentity(ctx, action.Identity) + identity := getIdentity(s, action.Identity) + ctx = db.SetContextIdentity(ctx, identity) result := node.ExecRequest(ctx, action.Request) From d73b05bd9bab52306262f7091802c97646cbeddc Mon Sep 17 00:00:00 2001 From: Islam Aliev Date: Tue, 9 Jul 2024 23:29:03 +0200 Subject: [PATCH 08/41] feat: Doc field encryption (#2817) ## Relevant issue(s) Resolves #2809 #2812 ## Description Adds field-level encryption which allows separate fields to be encryption with a dedicated symmetric key. --- cli/collection_create.go | 36 +++- cli/utils.go | 15 -- client/request/consts.go | 3 +- client/request/mutation.go | 3 + datastore/prefix_query.go | 10 +- .../i2817-doc-field-encryption.md | 3 + .../cli/defradb_client_collection_create.md | 19 +- http/client_collection.go | 9 +- http/handler_collection.go | 14 +- internal/core/key.go | 14 +- internal/db/collection.go | 28 ++- internal/db/errors.go | 6 + internal/encryption/config.go | 5 +- internal/encryption/context.go | 22 +- internal/encryption/encryptor.go | 127 ++++++++--- internal/encryption/encryptor_test.go | 177 ++++++++++------ internal/merkle/clock/clock.go | 10 +- internal/merkle/crdt/field.go | 19 +- internal/planner/create.go | 4 +- internal/planner/mapper/mapper.go | 11 +- internal/planner/mapper/mutation.go | 3 + internal/request/graphql/parser/mutation.go | 9 +- .../request/graphql/schema/descriptions.go | 12 +- internal/request/graphql/schema/generate.go | 40 +++- tests/clients/cli/wrapper_collection.go | 36 ++-- .../encryption/commit_relation_test.go | 102 +++++++++ tests/integration/encryption/commit_test.go | 167 ++++++++------- .../encryption/field_commit_test.go | 190 +++++++++++++++++ .../encryption/field_query_test.go | 54 +++++ tests/integration/encryption/field_test.go | 129 ++++++++++++ tests/integration/encryption/peer_test.go | 42 ++-- .../encryption/query_relation_test.go | 198 ++++++++++++++++++ tests/integration/encryption/query_test.go | 9 +- tests/integration/encryption/utils.go | 24 +++ .../one_to_many/with_group_related_id_test.go | 4 +- tests/integration/schema/group_test.go | 8 +- .../schema/type_explicit_fields_test.go | 60 ++++++ tests/integration/test_case.go | 5 +- tests/integration/utils2.go | 15 +- 39 files changed, 1337 insertions(+), 305 deletions(-) create mode 100644 docs/data_format_changes/i2817-doc-field-encryption.md create mode 100644 tests/integration/encryption/commit_relation_test.go create mode 100644 tests/integration/encryption/field_commit_test.go create mode 100644 tests/integration/encryption/field_query_test.go create mode 100644 tests/integration/encryption/field_test.go create mode 100644 tests/integration/encryption/query_relation_test.go create mode 100644 tests/integration/schema/type_explicit_fields_test.go diff --git a/cli/collection_create.go b/cli/collection_create.go index f4c36fbd53..eecdfef2d8 100644 --- a/cli/collection_create.go +++ b/cli/collection_create.go @@ -17,25 +17,34 @@ import ( "github.com/spf13/cobra" "github.com/sourcenetwork/defradb/client" + "github.com/sourcenetwork/defradb/datastore" "github.com/sourcenetwork/defradb/internal/db" + "github.com/sourcenetwork/defradb/internal/encryption" ) func MakeCollectionCreateCommand() *cobra.Command { var file string - var shouldEncrypt bool + var shouldEncryptDoc bool + var encryptedFields []string var cmd = &cobra.Command{ - Use: "create [-i --identity] [-e --encrypt] ", + Use: "create [-i --identity] [-e --encrypt] [--encrypt-fields] ", Short: "Create a new document.", Long: `Create a new document. Options: - -i, --identity - Marks the document as private and set the identity as the owner. The access to the document + -i, --identity + Marks the document as private and set the identity as the owner. The access to the document and permissions are controlled by ACP (Access Control Policy). -e, --encrypt Encrypt flag specified if the document needs to be encrypted. If set, DefraDB will generate a symmetric key for encryption using AES-GCM. + + --encrypt-fields + Comma-separated list of fields to encrypt. If set, DefraDB will encrypt only the specified fields + and for every field in the list it will generate a symmetric key for encryption using AES-GCM. + If combined with '--encrypt' flag, all the fields in the document not listed in '--encrypt-fields' + will be encrypted with the same key. Example: create from string: defradb client collection create --name User '{ "name": "Bob" }' @@ -81,7 +90,7 @@ Example: create from stdin: } txn, _ := db.TryGetContextTxn(cmd.Context()) - setContextDocEncryption(cmd, shouldEncrypt, txn) + setContextDocEncryption(cmd, shouldEncryptDoc, encryptedFields, txn) if client.IsJSONArray(docData) { docs, err := client.NewDocsFromJSON(docData, col.Definition()) @@ -98,8 +107,23 @@ Example: create from stdin: return col.Create(cmd.Context(), doc) }, } - cmd.PersistentFlags().BoolVarP(&shouldEncrypt, "encrypt", "e", false, + cmd.PersistentFlags().BoolVarP(&shouldEncryptDoc, "encrypt", "e", false, "Flag to enable encryption of the document") + cmd.PersistentFlags().StringSliceVar(&encryptedFields, "encrypt-fields", nil, + "Comma-separated list of fields to encrypt") cmd.Flags().StringVarP(&file, "file", "f", "", "File containing document(s)") return cmd } + +// setContextDocEncryption sets doc encryption for the current command context. +func setContextDocEncryption(cmd *cobra.Command, shouldEncryptDoc bool, encryptFields []string, txn datastore.Txn) { + if !shouldEncryptDoc && len(encryptFields) == 0 { + return + } + ctx := cmd.Context() + if txn != nil { + ctx = encryption.ContextWithStore(ctx, txn) + } + ctx = encryption.SetContextConfigFromParams(ctx, shouldEncryptDoc, encryptFields) + cmd.SetContext(ctx) +} diff --git a/cli/utils.go b/cli/utils.go index b2d4c076bc..d1ee09962b 100644 --- a/cli/utils.go +++ b/cli/utils.go @@ -25,10 +25,8 @@ import ( acpIdentity "github.com/sourcenetwork/defradb/acp/identity" "github.com/sourcenetwork/defradb/client" - "github.com/sourcenetwork/defradb/datastore" "github.com/sourcenetwork/defradb/http" "github.com/sourcenetwork/defradb/internal/db" - "github.com/sourcenetwork/defradb/internal/encryption" "github.com/sourcenetwork/defradb/keyring" ) @@ -162,19 +160,6 @@ func setContextIdentity(cmd *cobra.Command, privateKeyHex string) error { return nil } -// setContextDocEncryption sets doc encryption for the current command context. -func setContextDocEncryption(cmd *cobra.Command, shouldEncrypt bool, txn datastore.Txn) { - if !shouldEncrypt { - return - } - ctx := cmd.Context() - if txn != nil { - ctx = encryption.ContextWithStore(ctx, txn) - } - ctx = encryption.SetContextConfig(ctx, encryption.DocEncConfig{IsEncrypted: true}) - cmd.SetContext(ctx) -} - // setContextRootDir sets the rootdir for the current command context. func setContextRootDir(cmd *cobra.Command) error { rootdir, err := cmd.Root().PersistentFlags().GetString("rootdir") diff --git a/client/request/consts.go b/client/request/consts.go index cba609b788..ed39cfd4a7 100644 --- a/client/request/consts.go +++ b/client/request/consts.go @@ -26,7 +26,8 @@ const ( FieldIDName = "fieldId" ShowDeleted = "showDeleted" - EncryptArgName = "encrypt" + EncryptDocArgName = "encrypt" + EncryptFieldsArgName = "encryptFields" FilterClause = "filter" GroupByClause = "groupBy" diff --git a/client/request/mutation.go b/client/request/mutation.go index 70d0bed1d9..4f4f06fe7b 100644 --- a/client/request/mutation.go +++ b/client/request/mutation.go @@ -50,6 +50,9 @@ type ObjectMutation struct { // Encrypt is a boolean flag that indicates whether the input data should be encrypted. Encrypt bool + + // EncryptFields is a list of doc fields from input data that should be encrypted. + EncryptFields []string } // ToSelect returns a basic Select object, with the same Name, Alias, and Fields as diff --git a/datastore/prefix_query.go b/datastore/prefix_query.go index 7150aebe48..13d055893c 100644 --- a/datastore/prefix_query.go +++ b/datastore/prefix_query.go @@ -13,6 +13,7 @@ package datastore import ( "context" "encoding/json" + "errors" ds "github.com/ipfs/go-datastore" @@ -35,15 +36,13 @@ func DeserializePrefix[T any]( elements := make([]T, 0) for res := range q.Next() { if res.Error != nil { - _ = q.Close() - return nil, nil, res.Error + return nil, nil, errors.Join(res.Error, q.Close()) } var element T err = json.Unmarshal(res.Value, &element) if err != nil { - _ = q.Close() - return nil, nil, NewErrInvalidStoredValue(err) + return nil, nil, errors.Join(NewErrInvalidStoredValue(err), q.Close()) } keys = append(keys, res.Key) elements = append(elements, element) @@ -68,8 +67,7 @@ func FetchKeysForPrefix( keys := make([]ds.Key, 0) for res := range q.Next() { if res.Error != nil { - _ = q.Close() - return nil, res.Error + return nil, errors.Join(res.Error, q.Close()) } keys = append(keys, ds.NewKey(res.Key)) } diff --git a/docs/data_format_changes/i2817-doc-field-encryption.md b/docs/data_format_changes/i2817-doc-field-encryption.md new file mode 100644 index 0000000000..0d54f4e872 --- /dev/null +++ b/docs/data_format_changes/i2817-doc-field-encryption.md @@ -0,0 +1,3 @@ +# Doc field encryption +Changed hard-coded constant test encryption key to be dependant on docID and fieldName. +This produces different CIDs. \ No newline at end of file diff --git a/docs/website/references/cli/defradb_client_collection_create.md b/docs/website/references/cli/defradb_client_collection_create.md index 5425e3f860..862d30cf2e 100644 --- a/docs/website/references/cli/defradb_client_collection_create.md +++ b/docs/website/references/cli/defradb_client_collection_create.md @@ -7,13 +7,19 @@ Create a new document. Create a new document. Options: - -i, --identity - Marks the document as private and set the identity as the owner. The access to the document + -i, --identity + Marks the document as private and set the identity as the owner. The access to the document and permissions are controlled by ACP (Access Control Policy). -e, --encrypt Encrypt flag specified if the document needs to be encrypted. If set, DefraDB will generate a symmetric key for encryption using AES-GCM. + + --encrypt-fields + Comma-separated list of fields to encrypt. If set, DefraDB will encrypt only the specified fields + and for every field in the list it will generate a symmetric key for encryption using AES-GCM. + If combined with '--encrypt' flag, all the fields in the document not listed in '--encrypt-fields' + will be encrypted with the same key. Example: create from string: defradb client collection create --name User '{ "name": "Bob" }' @@ -33,15 +39,16 @@ Example: create from stdin: ``` -defradb client collection create [-i --identity] [-e --encrypt] [flags] +defradb client collection create [-i --identity] [-e --encrypt] [--encrypt-fields] [flags] ``` ### Options ``` - -e, --encrypt Flag to enable encryption of the document - -f, --file string File containing document(s) - -h, --help help for create + -e, --encrypt Flag to enable encryption of the document + --encrypt-fields strings Comma-separated list of fields to encrypt + -f, --file string File containing document(s) + -h, --help help for create ``` ### Options inherited from parent commands diff --git a/http/client_collection.go b/http/client_collection.go index 8df094f5fc..c13e4c68e9 100644 --- a/http/client_collection.go +++ b/http/client_collection.go @@ -132,9 +132,14 @@ func (c *Collection) CreateMany( func setDocEncryptionFlagIfNeeded(ctx context.Context, req *http.Request) { encConf := encryption.GetContextConfig(ctx) - if encConf.HasValue() && encConf.Value().IsEncrypted { + if encConf.HasValue() { q := req.URL.Query() - q.Set(docEncryptParam, "true") + if encConf.Value().IsDocEncrypted { + q.Set(docEncryptParam, "true") + } + if len(encConf.Value().EncryptedFields) > 0 { + q.Set(docEncryptFieldsParam, strings.Join(encConf.Value().EncryptedFields, ",")) + } req.URL.RawQuery = q.Encode() } } diff --git a/http/handler_collection.go b/http/handler_collection.go index 412f486602..57202a4b9f 100644 --- a/http/handler_collection.go +++ b/http/handler_collection.go @@ -16,6 +16,7 @@ import ( "io" "net/http" "strconv" + "strings" "github.com/getkin/kin-openapi/openapi3" "github.com/go-chi/chi/v5" @@ -25,6 +26,7 @@ import ( ) const docEncryptParam = "encrypt" +const docEncryptFieldsParam = "encryptFields" type collectionHandler struct{} @@ -47,8 +49,16 @@ func (s *collectionHandler) Create(rw http.ResponseWriter, req *http.Request) { } ctx := req.Context() - if req.URL.Query().Get(docEncryptParam) == "true" { - ctx = encryption.SetContextConfig(ctx, encryption.DocEncConfig{IsEncrypted: true}) + q := req.URL.Query() + encConf := encryption.DocEncConfig{} + if q.Get(docEncryptParam) == "true" { + encConf.IsDocEncrypted = true + } + if q.Get(docEncryptFieldsParam) != "" { + encConf.EncryptedFields = strings.Split(q.Get(docEncryptFieldsParam), ",") + } + if encConf.IsDocEncrypted || len(encConf.EncryptedFields) > 0 { + ctx = encryption.SetContextConfig(ctx, encConf) } switch { diff --git a/internal/core/key.go b/internal/core/key.go index 9b56c421fc..8f0ab3fd4e 100644 --- a/internal/core/key.go +++ b/internal/core/key.go @@ -795,25 +795,25 @@ func bytesPrefixEnd(b []byte) []byte { // EncStoreDocKey is a key for the encryption store. type EncStoreDocKey struct { - DocID string - FieldID uint32 + DocID string + FieldName string } var _ Key = (*EncStoreDocKey)(nil) // NewEncStoreDocKey creates a new EncStoreDocKey from a docID and fieldID. -func NewEncStoreDocKey(docID string, fieldID uint32) EncStoreDocKey { +func NewEncStoreDocKey(docID string, fieldName string) EncStoreDocKey { return EncStoreDocKey{ - DocID: docID, - FieldID: fieldID, + DocID: docID, + FieldName: fieldName, } } func (k EncStoreDocKey) ToString() string { - if k.FieldID == 0 { + if k.FieldName == "" { return k.DocID } - return fmt.Sprintf("%s/%d", k.DocID, k.FieldID) + return fmt.Sprintf("%s/%s", k.DocID, k.FieldName) } func (k EncStoreDocKey) Bytes() []byte { diff --git a/internal/db/collection.go b/internal/db/collection.go index 64f90960cc..d501afc4b7 100644 --- a/internal/db/collection.go +++ b/internal/db/collection.go @@ -33,6 +33,7 @@ import ( "github.com/sourcenetwork/defradb/internal/db/base" "github.com/sourcenetwork/defradb/internal/db/description" "github.com/sourcenetwork/defradb/internal/db/fetcher" + "github.com/sourcenetwork/defradb/internal/encryption" "github.com/sourcenetwork/defradb/internal/lens" merklecrdt "github.com/sourcenetwork/defradb/internal/merkle/crdt" ) @@ -561,6 +562,27 @@ func (c *collection) Save( return txn.Commit(ctx) } +func (c *collection) validateEncryptedFields(ctx context.Context) error { + encConf := encryption.GetContextConfig(ctx) + if !encConf.HasValue() { + return nil + } + fields := encConf.Value().EncryptedFields + if len(fields) == 0 { + return nil + } + + for _, field := range fields { + if _, exists := c.Schema().GetFieldByName(field); !exists { + return client.NewErrFieldNotExist(field) + } + if strings.HasPrefix(field, "_") { + return NewErrCanNotEncryptBuiltinField(field) + } + } + return nil +} + // save saves the document state. save MUST not be called outside the `c.create` // and `c.update` methods as we wrap the acp logic within those methods. Calling // save elsewhere could cause the omission of acp checks. @@ -569,6 +591,10 @@ func (c *collection) save( doc *client.Document, isCreate bool, ) (cid.Cid, error) { + if err := c.validateEncryptedFields(ctx); err != nil { + return cid.Undef, err + } + if !isCreate { err := c.updateIndexedDoc(ctx, doc) if err != nil { @@ -657,7 +683,7 @@ func (c *collection) save( return cid.Undef, err } - link, _, err := merkleCRDT.Save(ctx, &merklecrdt.DocField{DocID: primaryKey.DocID, FieldValue: val}) + link, _, err := merkleCRDT.Save(ctx, merklecrdt.NewDocField(primaryKey.DocID, k, val)) if err != nil { return cid.Undef, err } diff --git a/internal/db/errors.go b/internal/db/errors.go index 603cee8130..87828b78a8 100644 --- a/internal/db/errors.go +++ b/internal/db/errors.go @@ -100,6 +100,7 @@ const ( errReplicatorDocID string = "failed to get docID for replicator" errReplicatorCollections string = "failed to get collections for replicator" errReplicatorNotFound string = "replicator not found" + errCanNotEncryptBuiltinField string = "can not encrypt build-in field" ) var ( @@ -140,6 +141,7 @@ var ( ErrSelfTargetForReplicator = errors.New("can't target ourselves as a replicator") ErrReplicatorCollections = errors.New(errReplicatorCollections) ErrReplicatorNotFound = errors.New(errReplicatorNotFound) + ErrCanNotEncryptBuiltinField = errors.New(errCanNotEncryptBuiltinField) ) // NewErrFailedToGetHeads returns a new error indicating that the heads of a document @@ -330,6 +332,10 @@ func NewErrCannotMoveField(name string, proposedIndex, existingIndex int) error ) } +func NewErrCanNotEncryptBuiltinField(name string) error { + return errors.New(errCanNotEncryptBuiltinField, errors.NewKV("Name", name)) +} + func NewErrCannotDeleteField(name string) error { return errors.New( errCannotDeleteField, diff --git a/internal/encryption/config.go b/internal/encryption/config.go index ddb4a3815a..91edb98824 100644 --- a/internal/encryption/config.go +++ b/internal/encryption/config.go @@ -12,5 +12,8 @@ package encryption // DocEncConfig is the configuration for document encryption. type DocEncConfig struct { - IsEncrypted bool + // IsDocEncrypted is a flag to indicate if the document should be encrypted. + IsDocEncrypted bool + // EncryptedFields is a list of fields individual that should be encrypted. + EncryptedFields []string } diff --git a/internal/encryption/context.go b/internal/encryption/context.go index 10a03c89c1..96e90a7e0c 100644 --- a/internal/encryption/context.go +++ b/internal/encryption/context.go @@ -29,16 +29,13 @@ type configContextKey struct{} func TryGetContextEncryptor(ctx context.Context) (*DocEncryptor, bool) { enc, ok := ctx.Value(docEncContextKey{}).(*DocEncryptor) if ok { - checkKeyGenerationFlag(ctx, enc) + setConfig(ctx, enc) } return enc, ok } -func checkKeyGenerationFlag(ctx context.Context, enc *DocEncryptor) { - encConfig := GetContextConfig(ctx) - if encConfig.HasValue() && encConfig.Value().IsEncrypted { - enc.EnableKeyGeneration() - } +func setConfig(ctx context.Context, enc *DocEncryptor) { + enc.SetConfig(GetContextConfig(ctx)) } func ensureContextWithDocEnc(ctx context.Context) (context.Context, *DocEncryptor) { @@ -71,3 +68,16 @@ func GetContextConfig(ctx context.Context) immutable.Option[DocEncConfig] { func SetContextConfig(ctx context.Context, encConfig DocEncConfig) context.Context { return context.WithValue(ctx, configContextKey{}, encConfig) } + +// SetContextConfigFromParams returns a new context with the doc encryption config created from given params. +// If encryptDoc is false, and encryptFields is empty, the context is returned as is. +func SetContextConfigFromParams(ctx context.Context, encryptDoc bool, encryptFields []string) context.Context { + if encryptDoc || len(encryptFields) > 0 { + conf := DocEncConfig{EncryptedFields: encryptFields} + if encryptDoc { + conf.IsDocEncrypted = true + } + ctx = SetContextConfig(ctx, conf) + } + return ctx +} diff --git a/internal/encryption/encryptor.go b/internal/encryption/encryptor.go index 596e9f9903..9a6cb8f6f0 100644 --- a/internal/encryption/encryptor.go +++ b/internal/encryption/encryptor.go @@ -18,6 +18,8 @@ import ( ds "github.com/ipfs/go-datastore" + "github.com/sourcenetwork/immutable" + "github.com/sourcenetwork/defradb/datastore" "github.com/sourcenetwork/defradb/internal/core" ) @@ -29,7 +31,7 @@ const keyLength = 32 // 32 bytes for AES-256 const testEncryptionKey = "examplekey1234567890examplekey12" // generateEncryptionKey generates a random AES key. -func generateEncryptionKey() ([]byte, error) { +func generateEncryptionKey(_, _ string) ([]byte, error) { key := make([]byte, keyLength) if _, err := io.ReadFull(rand.Reader, key); err != nil { return nil, err @@ -38,44 +40,89 @@ func generateEncryptionKey() ([]byte, error) { } // generateTestEncryptionKey generates a deterministic encryption key for testing. -func generateTestEncryptionKey() ([]byte, error) { - return []byte(testEncryptionKey), nil +// While testing, we also want to make sure different keys are generated for different docs and fields +// and that's why we use the docID and fieldName to generate the key. +func generateTestEncryptionKey(docID, fieldName string) ([]byte, error) { + return []byte(fieldName + docID + testEncryptionKey)[0:keyLength], nil } +// DocEncryptor is a document encryptor that encrypts and decrypts individual document fields. +// It acts based on the configuration [DocEncConfig] provided and data stored in the provided store. +// It uses [core.EncStoreDocKey] to store and retrieve encryption keys. type DocEncryptor struct { - shouldGenerateKey bool - ctx context.Context - store datastore.DSReaderWriter + conf immutable.Option[DocEncConfig] + ctx context.Context + store datastore.DSReaderWriter } func newDocEncryptor(ctx context.Context) *DocEncryptor { return &DocEncryptor{ctx: ctx} } -func (d *DocEncryptor) EnableKeyGeneration() { - d.shouldGenerateKey = true +// SetConfig sets the configuration for the document encryptor. +func (d *DocEncryptor) SetConfig(conf immutable.Option[DocEncConfig]) { + d.conf = conf } +// SetStore sets the store for the document encryptor. func (d *DocEncryptor) SetStore(store datastore.DSReaderWriter) { d.store = store } -func (d *DocEncryptor) Encrypt(docID string, fieldID uint32, plainText []byte) ([]byte, error) { - encryptionKey, storeKey, err := d.fetchEncryptionKey(docID, fieldID) +func shouldEncryptIndividualField(conf immutable.Option[DocEncConfig], fieldName string) bool { + if !conf.HasValue() || fieldName == "" { + return false + } + for _, field := range conf.Value().EncryptedFields { + if field == fieldName { + return true + } + } + return false +} + +func shouldEncryptField(conf immutable.Option[DocEncConfig], fieldName string) bool { + if !conf.HasValue() { + return false + } + if conf.Value().IsDocEncrypted { + return true + } + if fieldName == "" { + return false + } + for _, field := range conf.Value().EncryptedFields { + if field == fieldName { + return true + } + } + return false +} + +// Encrypt encrypts the given plainText that is associated with the given docID and fieldName. +// If the current configuration is set to encrypt the given key individually, it will encrypt it with a new key. +// Otherwise, it will use document-level encryption key. +func (d *DocEncryptor) Encrypt(docID, fieldName string, plainText []byte) ([]byte, error) { + encryptionKey, err := d.fetchEncryptionKey(docID, fieldName) if err != nil { return nil, err } if len(encryptionKey) == 0 { - if !d.shouldGenerateKey { + if !shouldEncryptIndividualField(d.conf, fieldName) { + fieldName = "" + } + + if !shouldEncryptField(d.conf, fieldName) { return plainText, nil } - encryptionKey, err = generateEncryptionKeyFunc() + encryptionKey, err = generateEncryptionKeyFunc(docID, fieldName) if err != nil { return nil, err } + storeKey := core.NewEncStoreDocKey(docID, fieldName) err = d.store.Put(d.ctx, storeKey.ToDS(), encryptionKey) if err != nil { return nil, err @@ -84,8 +131,10 @@ func (d *DocEncryptor) Encrypt(docID string, fieldID uint32, plainText []byte) ( return EncryptAES(plainText, encryptionKey) } -func (d *DocEncryptor) Decrypt(docID string, fieldID uint32, cipherText []byte) ([]byte, error) { - encKey, _, err := d.fetchEncryptionKey(docID, fieldID) +// Decrypt decrypts the given cipherText that is associated with the given docID and fieldName. +// If the corresponding encryption key is not found, it returns nil. +func (d *DocEncryptor) Decrypt(docID, fieldName string, cipherText []byte) ([]byte, error) { + encKey, err := d.fetchEncryptionKey(docID, fieldName) if err != nil { return nil, err } @@ -95,33 +144,61 @@ func (d *DocEncryptor) Decrypt(docID string, fieldID uint32, cipherText []byte) return DecryptAES(cipherText, encKey) } -// fetchEncryptionKey fetches the encryption key for the given docID and fieldID. +// fetchEncryptionKey fetches the encryption key for the given docID and fieldName. // If the key is not found, it returns an empty key. -func (d *DocEncryptor) fetchEncryptionKey(docID string, fieldID uint32) ([]byte, core.EncStoreDocKey, error) { - storeKey := core.NewEncStoreDocKey(docID, fieldID) +func (d *DocEncryptor) fetchEncryptionKey(docID string, fieldName string) ([]byte, error) { if d.store == nil { - return nil, core.EncStoreDocKey{}, ErrNoStorageProvided + return nil, ErrNoStorageProvided } + // first we try to find field-level key + storeKey := core.NewEncStoreDocKey(docID, fieldName) encryptionKey, err := d.store.Get(d.ctx, storeKey.ToDS()) isNotFound := errors.Is(err, ds.ErrNotFound) - if err != nil && !isNotFound { - return nil, core.EncStoreDocKey{}, err + if err != nil { + if !isNotFound { + return nil, err + } + // if previous fetch was for doc-level, there is nothing else to look for + if fieldName == "" { + return nil, nil + } + if shouldEncryptIndividualField(d.conf, fieldName) { + return nil, nil + } + // try to find doc-level key + storeKey.FieldName = "" + encryptionKey, err = d.store.Get(d.ctx, storeKey.ToDS()) + isNotFound = errors.Is(err, ds.ErrNotFound) + if err != nil && !isNotFound { + return nil, err + } } - return encryptionKey, storeKey, nil + return encryptionKey, nil } -func EncryptDoc(ctx context.Context, docID string, fieldID uint32, plainText []byte) ([]byte, error) { +// EncryptDoc encrypts the given plainText that is associated with the given docID and fieldName with +// encryptor in the context. +// If the current configuration is set to encrypt the given key individually, it will encrypt it with a new key. +// Otherwise, it will use document-level encryption key. +func EncryptDoc(ctx context.Context, docID string, fieldName string, plainText []byte) ([]byte, error) { enc, ok := TryGetContextEncryptor(ctx) if !ok { return nil, nil } - return enc.Encrypt(docID, fieldID, plainText) + return enc.Encrypt(docID, fieldName, plainText) } -func DecryptDoc(ctx context.Context, docID string, fieldID uint32, cipherText []byte) ([]byte, error) { +// DecryptDoc decrypts the given cipherText that is associated with the given docID and fieldName with +// encryptor in the context. +func DecryptDoc(ctx context.Context, docID string, fieldName string, cipherText []byte) ([]byte, error) { enc, ok := TryGetContextEncryptor(ctx) if !ok { return nil, nil } - return enc.Decrypt(docID, fieldID, cipherText) + return enc.Decrypt(docID, fieldName, cipherText) +} + +// ShouldEncryptField returns true if the given field should be encrypted based on the context config. +func ShouldEncryptField(ctx context.Context, fieldName string) bool { + return shouldEncryptField(GetContextConfig(ctx), fieldName) } diff --git a/internal/encryption/encryptor_test.go b/internal/encryption/encryptor_test.go index 10abd1f062..76888ed4f1 100644 --- a/internal/encryption/encryptor_test.go +++ b/internal/encryption/encryptor_test.go @@ -19,157 +19,204 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" + "github.com/sourcenetwork/immutable" + "github.com/sourcenetwork/defradb/datastore/mocks" "github.com/sourcenetwork/defradb/internal/core" ) var testErr = errors.New("test error") -var docID = "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3" +const docID = "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3" + +const fieldName = "name" func getPlainText() []byte { return []byte("test") } -func getCipherText(t *testing.T) []byte { - cipherText, err := EncryptAES(getPlainText(), []byte(testEncryptionKey)) +func getEncKey(fieldName string) []byte { + key, _ := generateTestEncryptionKey(docID, fieldName) + return key +} + +func getCipherText(t *testing.T, fieldName string) []byte { + cipherText, err := EncryptAES(getPlainText(), getEncKey(fieldName)) assert.NoError(t, err) return cipherText } -func TestEncryptorEncrypt_IfStorageReturnsError_Error(t *testing.T) { +func newDefaultEncryptor(t *testing.T) (*DocEncryptor, *mocks.DSReaderWriter) { + return newEncryptorWithConfig(t, DocEncConfig{IsDocEncrypted: true}) +} + +func newEncryptorWithConfig(t *testing.T, conf DocEncConfig) (*DocEncryptor, *mocks.DSReaderWriter) { enc := newDocEncryptor(context.Background()) st := mocks.NewDSReaderWriter(t) + enc.SetConfig(immutable.Some(conf)) enc.SetStore(st) + return enc, st +} + +func TestEncryptorEncrypt_IfStorageReturnsError_Error(t *testing.T) { + enc, st := newDefaultEncryptor(t) st.EXPECT().Get(mock.Anything, mock.Anything).Return(nil, testErr) - _, err := enc.Encrypt(docID, 0, []byte("test")) + _, err := enc.Encrypt(docID, fieldName, []byte("test")) assert.ErrorIs(t, err, testErr) } -func TestEncryptorEncrypt_IfNoKeyFoundInStorage_ShouldGenerateKeyStoreItAndReturnCipherText(t *testing.T) { - enc := newDocEncryptor(context.Background()) - st := mocks.NewDSReaderWriter(t) - enc.EnableKeyGeneration() - enc.SetStore(st) +func TestEncryptorEncrypt_IfStorageReturnsErrorOnSecondCall_Error(t *testing.T) { + enc, st := newDefaultEncryptor(t) - st.EXPECT().Get(mock.Anything, mock.Anything).Return(nil, ds.ErrNotFound) + st.EXPECT().Get(mock.Anything, mock.Anything).Return(nil, ds.ErrNotFound).Once() + st.EXPECT().Get(mock.Anything, mock.Anything).Return(nil, testErr) + + _, err := enc.Encrypt(docID, fieldName, []byte("test")) + + assert.ErrorIs(t, err, testErr) +} + +func TestEncryptorEncrypt_WithEmptyFieldNameIfNoKeyFoundInStorage_ShouldGenerateKeyStoreItAndReturnCipherText(t *testing.T) { + enc, st := newDefaultEncryptor(t) + + storeKey := core.NewEncStoreDocKey(docID, "") + + st.EXPECT().Get(mock.Anything, storeKey.ToDS()).Return(nil, ds.ErrNotFound) + st.EXPECT().Put(mock.Anything, storeKey.ToDS(), getEncKey("")).Return(nil) + + cipherText, err := enc.Encrypt(docID, "", getPlainText()) + + assert.NoError(t, err) + assert.Equal(t, getCipherText(t, ""), cipherText) +} + +func TestEncryptorEncrypt_IfNoFieldEncRequestedAndNoKeyInStorage_GenerateKeyStoreItAndReturnCipherText(t *testing.T) { + enc, st := newDefaultEncryptor(t) + + docStoreKey := core.NewEncStoreDocKey(docID, "").ToDS() + fieldStoreKey := core.NewEncStoreDocKey(docID, fieldName).ToDS() + + st.EXPECT().Get(mock.Anything, fieldStoreKey).Return(nil, ds.ErrNotFound) + st.EXPECT().Get(mock.Anything, docStoreKey).Return(nil, ds.ErrNotFound) + st.EXPECT().Put(mock.Anything, docStoreKey, getEncKey("")).Return(nil) + + cipherText, err := enc.Encrypt(docID, fieldName, getPlainText()) + + assert.NoError(t, err) + assert.Equal(t, getCipherText(t, ""), cipherText) +} + +func TestEncryptorEncrypt_IfNoKeyWithFieldFoundInStorage_ShouldGenerateKeyStoreItAndReturnCipherText(t *testing.T) { + enc, st := newEncryptorWithConfig(t, DocEncConfig{EncryptedFields: []string{fieldName}}) - storeKey := core.NewEncStoreDocKey(docID, 0) + storeKey := core.NewEncStoreDocKey(docID, fieldName) - st.EXPECT().Put(mock.Anything, storeKey.ToDS(), []byte(testEncryptionKey)).Return(nil) + st.EXPECT().Get(mock.Anything, storeKey.ToDS()).Return(nil, ds.ErrNotFound) + st.EXPECT().Put(mock.Anything, storeKey.ToDS(), getEncKey(fieldName)).Return(nil) - cipherText, err := enc.Encrypt(docID, 0, getPlainText()) + cipherText, err := enc.Encrypt(docID, fieldName, getPlainText()) assert.NoError(t, err) - assert.Equal(t, getCipherText(t), cipherText) + assert.Equal(t, getCipherText(t, fieldName), cipherText) +} + +func TestEncryptorEncrypt_IfKeyWithFieldFoundInStorage_ShouldUseItToReturnCipherText(t *testing.T) { + enc, st := newEncryptorWithConfig(t, DocEncConfig{EncryptedFields: []string{fieldName}}) + + storeKey := core.NewEncStoreDocKey(docID, fieldName) + st.EXPECT().Get(mock.Anything, storeKey.ToDS()).Return(getEncKey(fieldName), nil) + + cipherText, err := enc.Encrypt(docID, fieldName, getPlainText()) + + assert.NoError(t, err) + assert.Equal(t, getCipherText(t, fieldName), cipherText) } func TestEncryptorEncrypt_IfKeyFoundInStorage_ShouldUseItToReturnCipherText(t *testing.T) { - enc := newDocEncryptor(context.Background()) - st := mocks.NewDSReaderWriter(t) - enc.EnableKeyGeneration() - enc.SetStore(st) + enc, st := newDefaultEncryptor(t) - st.EXPECT().Get(mock.Anything, mock.Anything).Return([]byte(testEncryptionKey), nil) + st.EXPECT().Get(mock.Anything, mock.Anything).Return(getEncKey(""), nil) - cipherText, err := enc.Encrypt(docID, 0, getPlainText()) + cipherText, err := enc.Encrypt(docID, "", getPlainText()) assert.NoError(t, err) - assert.Equal(t, getCipherText(t), cipherText) + assert.Equal(t, getCipherText(t, ""), cipherText) } func TestEncryptorEncrypt_IfStorageFailsToStoreEncryptionKey_ReturnError(t *testing.T) { - enc := newDocEncryptor(context.Background()) - st := mocks.NewDSReaderWriter(t) - enc.EnableKeyGeneration() - enc.SetStore(st) + enc, st := newDefaultEncryptor(t) st.EXPECT().Get(mock.Anything, mock.Anything).Return(nil, ds.ErrNotFound) st.EXPECT().Put(mock.Anything, mock.Anything, mock.Anything).Return(testErr) - _, err := enc.Encrypt(docID, 0, getPlainText()) + _, err := enc.Encrypt(docID, fieldName, getPlainText()) assert.ErrorIs(t, err, testErr) } func TestEncryptorEncrypt_IfKeyGenerationIsNotEnabled_ShouldReturnPlainText(t *testing.T) { - enc := newDocEncryptor(context.Background()) - st := mocks.NewDSReaderWriter(t) - // we don call enc.EnableKeyGeneration() - enc.SetStore(st) + enc, st := newDefaultEncryptor(t) + enc.SetConfig(immutable.None[DocEncConfig]()) st.EXPECT().Get(mock.Anything, mock.Anything).Return(nil, ds.ErrNotFound) - cipherText, err := enc.Encrypt(docID, 0, getPlainText()) + cipherText, err := enc.Encrypt(docID, fieldName, getPlainText()) assert.NoError(t, err) assert.Equal(t, getPlainText(), cipherText) } func TestEncryptorEncrypt_IfNoStorageProvided_Error(t *testing.T) { - enc := newDocEncryptor(context.Background()) - enc.EnableKeyGeneration() - // we don call enc.SetStore(st) + enc, _ := newDefaultEncryptor(t) + enc.SetStore(nil) - _, err := enc.Encrypt(docID, 0, getPlainText()) + _, err := enc.Encrypt(docID, fieldName, getPlainText()) assert.ErrorIs(t, err, ErrNoStorageProvided) } func TestEncryptorDecrypt_IfNoStorageProvided_Error(t *testing.T) { - enc := newDocEncryptor(context.Background()) - enc.EnableKeyGeneration() - // we don call enc.SetStore(st) + enc, _ := newDefaultEncryptor(t) + enc.SetStore(nil) - _, err := enc.Decrypt(docID, 0, getPlainText()) + _, err := enc.Decrypt(docID, fieldName, getPlainText()) assert.ErrorIs(t, err, ErrNoStorageProvided) } func TestEncryptorDecrypt_IfStorageReturnsError_Error(t *testing.T) { - enc := newDocEncryptor(context.Background()) - st := mocks.NewDSReaderWriter(t) - enc.SetStore(st) + enc, st := newDefaultEncryptor(t) st.EXPECT().Get(mock.Anything, mock.Anything).Return(nil, testErr) - _, err := enc.Decrypt(docID, 0, []byte("test")) + _, err := enc.Decrypt(docID, fieldName, []byte("test")) assert.ErrorIs(t, err, testErr) } func TestEncryptorDecrypt_IfKeyFoundInStorage_ShouldUseItToReturnPlainText(t *testing.T) { - enc := newDocEncryptor(context.Background()) - st := mocks.NewDSReaderWriter(t) - enc.EnableKeyGeneration() - enc.SetStore(st) + enc, st := newDefaultEncryptor(t) - st.EXPECT().Get(mock.Anything, mock.Anything).Return([]byte(testEncryptionKey), nil) + st.EXPECT().Get(mock.Anything, mock.Anything).Return(getEncKey(""), nil) - plainText, err := enc.Decrypt(docID, 0, getCipherText(t)) + plainText, err := enc.Decrypt(docID, fieldName, getCipherText(t, "")) assert.NoError(t, err) assert.Equal(t, getPlainText(), plainText) } -func TestEncryptorDecrypt_IfNoKeyFoundInStorage_ShouldGenerateKeyStoreItAndReturnCipherText(t *testing.T) { - enc := newDocEncryptor(context.Background()) - st := mocks.NewDSReaderWriter(t) - enc.EnableKeyGeneration() - enc.SetStore(st) - - st.EXPECT().Get(mock.Anything, mock.Anything).Return(nil, ds.ErrNotFound) - - storeKey := core.NewEncStoreDocKey(docID, 0) - - st.EXPECT().Put(mock.Anything, storeKey.ToDS(), []byte(testEncryptionKey)).Return(nil) - - cipherText, err := enc.Encrypt(docID, 0, getPlainText()) +func TestEncryptDoc_IfContextHasNoEncryptor_ReturnNil(t *testing.T) { + data, err := EncryptDoc(context.Background(), docID, fieldName, getPlainText()) + assert.Nil(t, data, "data should be nil") + assert.NoError(t, err, "error should be nil") +} - assert.NoError(t, err) - assert.Equal(t, getCipherText(t), cipherText) +func TestDecryptDoc_IfContextHasNoEncryptor_ReturnNil(t *testing.T) { + data, err := DecryptDoc(context.Background(), docID, fieldName, getCipherText(t, fieldName)) + assert.Nil(t, data, "data should be nil") + assert.NoError(t, err, "error should be nil") } diff --git a/internal/merkle/clock/clock.go b/internal/merkle/clock/clock.go index 1cb79ed756..b5b5f2631c 100644 --- a/internal/merkle/clock/clock.go +++ b/internal/merkle/clock/clock.go @@ -86,8 +86,7 @@ func (mc *MerkleClock) AddDelta( delta.SetPriority(height) block := coreblock.New(delta, links, heads...) - // Write the new block to the dag store. - isEncrypted, err := mc.checkIfBlockEncryptionEnabled(ctx, heads) + isEncrypted, err := mc.checkIfBlockEncryptionEnabled(ctx, block.Delta.GetFieldName(), heads) if err != nil { return cidlink.Link{}, nil, err } @@ -130,10 +129,10 @@ func (mc *MerkleClock) AddDelta( func (mc *MerkleClock) checkIfBlockEncryptionEnabled( ctx context.Context, + fieldName string, heads []cid.Cid, ) (bool, error) { - encConf := encryption.GetContextConfig(ctx) - if encConf.HasValue() && encConf.Value().IsEncrypted { + if encryption.ShouldEncryptField(ctx, fieldName) { return true, nil } @@ -156,7 +155,8 @@ func (mc *MerkleClock) checkIfBlockEncryptionEnabled( func encryptBlock(ctx context.Context, block *coreblock.Block) (*coreblock.Block, error) { clonedCRDT := block.Delta.Clone() - bytes, err := encryption.EncryptDoc(ctx, string(clonedCRDT.GetDocID()), 0, clonedCRDT.GetData()) + bytes, err := encryption.EncryptDoc(ctx, string(clonedCRDT.GetDocID()), + clonedCRDT.GetFieldName(), clonedCRDT.GetData()) if err != nil { return nil, err } diff --git a/internal/merkle/crdt/field.go b/internal/merkle/crdt/field.go index 6426165f49..10795942f0 100644 --- a/internal/merkle/crdt/field.go +++ b/internal/merkle/crdt/field.go @@ -10,13 +10,28 @@ package merklecrdt -import "github.com/sourcenetwork/defradb/client" +import ( + "github.com/sourcenetwork/defradb/client" +) // DocField is a struct that holds the document ID and the field value. // This is used to have a link between the document and the field value. // For example, to check if the field value needs to be encrypted depending on the document-level // encryption is enabled or not. type DocField struct { - DocID string + // DocID is the ID of a document associated with the field value. + DocID string + // FieldName is the name of the field. + FieldName string + // FieldValue is the field value. FieldValue *client.FieldValue } + +// NewDocField creates a new DocField instance. +func NewDocField(docID, fieldName string, fieldValue *client.FieldValue) *DocField { + return &DocField{ + DocID: docID, + FieldName: fieldName, + FieldValue: fieldValue, + } +} diff --git a/internal/planner/create.go b/internal/planner/create.go index b03f2c1765..89acfabc5d 100644 --- a/internal/planner/create.go +++ b/internal/planner/create.go @@ -159,9 +159,7 @@ func (p *Planner) CreateDocs(parsed *mapper.Mutation) (planNode, error) { create.input = []map[string]any{parsed.Input} } - if parsed.Encrypt { - p.ctx = encryption.SetContextConfig(p.ctx, encryption.DocEncConfig{IsEncrypted: true}) - } + p.ctx = encryption.SetContextConfigFromParams(p.ctx, parsed.Encrypt, parsed.EncryptFields) // get collection col, err := p.db.GetCollectionByName(p.ctx, parsed.Name) diff --git a/internal/planner/mapper/mapper.go b/internal/planner/mapper/mapper.go index 858ef0e0ae..55e2358f3e 100644 --- a/internal/planner/mapper/mapper.go +++ b/internal/planner/mapper/mapper.go @@ -1165,11 +1165,12 @@ func ToMutation(ctx context.Context, store client.Store, mutationRequest *reques } return &Mutation{ - Select: *underlyingSelect, - Type: MutationType(mutationRequest.Type), - Input: mutationRequest.Input, - Inputs: mutationRequest.Inputs, - Encrypt: mutationRequest.Encrypt, + Select: *underlyingSelect, + Type: MutationType(mutationRequest.Type), + Input: mutationRequest.Input, + Inputs: mutationRequest.Inputs, + Encrypt: mutationRequest.Encrypt, + EncryptFields: mutationRequest.EncryptFields, }, nil } diff --git a/internal/planner/mapper/mutation.go b/internal/planner/mapper/mutation.go index 251d01298f..f02bc9d067 100644 --- a/internal/planner/mapper/mutation.go +++ b/internal/planner/mapper/mutation.go @@ -35,4 +35,7 @@ type Mutation struct { // Encrypt is a flag to indicate if the input data should be encrypted. Encrypt bool + + // EncryptFields is a list of fields from the input data that should be encrypted. + EncryptFields []string } diff --git a/internal/request/graphql/parser/mutation.go b/internal/request/graphql/parser/mutation.go index 2ed4ebf539..b329eeec88 100644 --- a/internal/request/graphql/parser/mutation.go +++ b/internal/request/graphql/parser/mutation.go @@ -140,8 +140,15 @@ func parseMutation(schema gql.Schema, parent *gql.Object, field *ast.Field) (*re ids[i] = id.Value } mut.DocIDs = immutable.Some(ids) - } else if prop == request.EncryptArgName { + } else if prop == request.EncryptDocArgName { mut.Encrypt = argument.Value.(*ast.BooleanValue).Value + } else if prop == request.EncryptFieldsArgName { + raw := argument.Value.(*ast.ListValue) + fieldNames := make([]string, len(raw.Values)) + for i, val := range raw.Values { + fieldNames[i] = val.GetValue().(string) + } + mut.EncryptFields = fieldNames } } diff --git a/internal/request/graphql/schema/descriptions.go b/internal/request/graphql/schema/descriptions.go index 281002366a..526e41470e 100644 --- a/internal/request/graphql/schema/descriptions.go +++ b/internal/request/graphql/schema/descriptions.go @@ -158,7 +158,15 @@ Returns the head commit for this document. ` encryptArgDescription string = ` -Encrypt flag specified if the input document(s) needs to be encrypted. If set, DefraDB will generate a -symmetric key for encryption using AES-GCM. +Encrypt flag specifies if the input document(s) needs to be encrypted. If set, + DefraDB will generate a symmetric key for encryption using AES-GCM, and will + use it to encrypt all fields' values. +` + + encryptFieldsArgDescription string = ` +An optional list of individual fields that should be encrypted. For every field + in the list DefraDB will generate a symmetric key for encryption using AES-GCM. + If 'encrypt' is set to true, it all fields not listed in 'encryptedFields' will + be encrypted with the same key. ` ) diff --git a/internal/request/graphql/schema/generate.go b/internal/request/graphql/schema/generate.go index 82ff15d057..8bf9b74d72 100644 --- a/internal/request/graphql/schema/generate.go +++ b/internal/request/graphql/schema/generate.go @@ -33,6 +33,11 @@ const ( mutationInputsNameSuffix = "MutationInputsArg" ) +const ( + typeFieldEnumSuffix = "Field" + typeExplicitFieldEnumSuffix = "ExplicitField" +) + // Generator creates all the necessary typed schema definitions from an AST Document // and adds them to the Schema via the SchemaManager type Generator struct { @@ -385,7 +390,7 @@ func (g *Generator) createExpandedFieldList( listFieldFilterArgDescription, ), "groupBy": schemaTypes.NewArgConfig( - gql.NewList(gql.NewNonNull(g.manager.schema.TypeMap()[typeName+"Fields"])), + gql.NewList(gql.NewNonNull(g.manager.schema.TypeMap()[typeName+typeFieldEnumSuffix])), schemaTypes.GroupByArgDescription, ), "order": schemaTypes.NewArgConfig( @@ -1046,14 +1051,21 @@ func (g *Generator) GenerateMutationInputForGQLType(obj *gql.Object) ([]*gql.Fie return nil, NewErrTypeNotFound(mutationInputName) } + explicitUserFieldsEnum := g.genUserExplicitTypeFieldsEnum(obj) + + g.manager.schema.TypeMap()[explicitUserFieldsEnum.Name()] = explicitUserFieldsEnum + create := &gql.Field{ Name: "create_" + obj.Name(), Description: createDocumentDescription, Type: obj, Args: gql.FieldConfigArgument{ - "input": schemaTypes.NewArgConfig(mutationInput, "Create a "+obj.Name()+" document"), - "inputs": schemaTypes.NewArgConfig(gql.NewList(mutationInput), "Create "+obj.Name()+" documents"), - "encrypt": schemaTypes.NewArgConfig(gql.Boolean, encryptArgDescription), + request.Input: schemaTypes.NewArgConfig(mutationInput, "Create a "+obj.Name()+" document"), + request.Inputs: schemaTypes.NewArgConfig(gql.NewList(gql.NewNonNull(mutationInput)), + "Create "+obj.Name()+" documents"), + request.EncryptDocArgName: schemaTypes.NewArgConfig(gql.Boolean, encryptArgDescription), + request.EncryptFieldsArgName: schemaTypes.NewArgConfig(gql.NewList(gql.NewNonNull(explicitUserFieldsEnum)), + encryptFieldsArgDescription), }, } @@ -1065,7 +1077,7 @@ func (g *Generator) GenerateMutationInputForGQLType(obj *gql.Object) ([]*gql.Fie request.DocIDArgName: schemaTypes.NewArgConfig(gql.ID, updateIDArgDescription), request.DocIDsArgName: schemaTypes.NewArgConfig(gql.NewList(gql.ID), updateIDsArgDescription), "filter": schemaTypes.NewArgConfig(filterInput, updateFilterArgDescription), - "input": schemaTypes.NewArgConfig(mutationInput, "Update field values"), + request.Input: schemaTypes.NewArgConfig(mutationInput, "Update field values"), }, } @@ -1085,11 +1097,27 @@ func (g *Generator) GenerateMutationInputForGQLType(obj *gql.Object) ([]*gql.Fie func (g *Generator) genTypeFieldsEnum(obj *gql.Object) *gql.Enum { enumFieldsCfg := gql.EnumConfig{ - Name: genTypeName(obj, "Fields"), + Name: genTypeName(obj, typeFieldEnumSuffix), + Values: gql.EnumValueConfigMap{}, + } + + for f, field := range obj.Fields() { + enumFieldsCfg.Values[field.Name] = &gql.EnumValueConfig{Value: f} + } + + return gql.NewEnum(enumFieldsCfg) +} + +func (g *Generator) genUserExplicitTypeFieldsEnum(obj *gql.Object) *gql.Enum { + enumFieldsCfg := gql.EnumConfig{ + Name: genTypeName(obj, typeExplicitFieldEnumSuffix), Values: gql.EnumValueConfigMap{}, } for f, field := range obj.Fields() { + if strings.HasPrefix(field.Name, "_") { + continue + } enumFieldsCfg.Values[field.Name] = &gql.EnumValueConfig{Value: f} } diff --git a/tests/clients/cli/wrapper_collection.go b/tests/clients/cli/wrapper_collection.go index f26142c8e9..9ef71e8ce7 100644 --- a/tests/clients/cli/wrapper_collection.go +++ b/tests/clients/cli/wrapper_collection.go @@ -63,13 +63,7 @@ func (c *Collection) Create( return client.ErrOperationNotPermittedOnNamelessCols } - args := []string{"client", "collection", "create"} - args = append(args, "--name", c.Description().Name.Value()) - - encConf := encryption.GetContextConfig(ctx) - if encConf.HasValue() && encConf.Value().IsEncrypted { - args = append(args, "--encrypt") - } + args := makeDocCreateArgs(ctx, c) document, err := doc.String() if err != nil { @@ -93,13 +87,7 @@ func (c *Collection) CreateMany( return client.ErrOperationNotPermittedOnNamelessCols } - args := []string{"client", "collection", "create"} - args = append(args, "--name", c.Description().Name.Value()) - - encConf := encryption.GetContextConfig(ctx) - if encConf.HasValue() && encConf.Value().IsEncrypted { - args = append(args, "--encrypt") - } + args := makeDocCreateArgs(ctx, c) docStrings := make([]string, len(docs)) for i, doc := range docs { @@ -121,6 +109,26 @@ func (c *Collection) CreateMany( return nil } +func makeDocCreateArgs( + ctx context.Context, + c *Collection, +) []string { + args := []string{"client", "collection", "create"} + args = append(args, "--name", c.Description().Name.Value()) + + encConf := encryption.GetContextConfig(ctx) + if encConf.HasValue() { + if encConf.Value().IsDocEncrypted { + args = append(args, "--encrypt") + } + if len(encConf.Value().EncryptedFields) > 0 { + args = append(args, "--encrypt-fields", strings.Join(encConf.Value().EncryptedFields, ",")) + } + } + + return args +} + func (c *Collection) Update( ctx context.Context, doc *client.Document, diff --git a/tests/integration/encryption/commit_relation_test.go b/tests/integration/encryption/commit_relation_test.go new file mode 100644 index 0000000000..848afa5fd3 --- /dev/null +++ b/tests/integration/encryption/commit_relation_test.go @@ -0,0 +1,102 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package encryption + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestDocEncryption_WithEncryptionSecondaryRelations_ShouldStoreEncryptedCommit(t *testing.T) { + const userDocID = "bae-4d563681-e131-5e01-8ab4-6c65ac0d0478" + const deviceDocID = "bae-50211587-fde7-5d75-8034-e7040dfba203" + + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + devices: [Device] + } + + type Device { + model: String + manufacturer: String + owner: User + } + `, + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ + "name": "Chris" + }`, + IsDocEncrypted: true, + }, + testUtils.CreateDoc{ + CollectionID: 1, + DocMap: map[string]any{ + "model": "Walkman", + "manufacturer": "Sony", + "owner": testUtils.NewDocIndex(0, 0), + }, + IsDocEncrypted: true, + }, + testUtils.Request{ + Request: ` + query { + commits { + delta + docID + fieldName + } + } + `, + Results: []map[string]any{ + { + "delta": encrypt(testUtils.CBORValue("Chris"), userDocID, ""), + "docID": userDocID, + "fieldName": "name", + }, + { + "delta": nil, + "docID": userDocID, + "fieldName": nil, + }, + { + "delta": encrypt(testUtils.CBORValue("Sony"), deviceDocID, ""), + "docID": deviceDocID, + "fieldName": "manufacturer", + }, + { + "delta": encrypt(testUtils.CBORValue("Walkman"), deviceDocID, ""), + "docID": deviceDocID, + "fieldName": "model", + }, + { + "delta": encrypt(testUtils.CBORValue(userDocID), deviceDocID, ""), + "docID": deviceDocID, + "fieldName": "owner_id", + }, + { + "delta": nil, + "docID": deviceDocID, + "fieldName": nil, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/encryption/commit_test.go b/tests/integration/encryption/commit_test.go index 6a94621b3a..ffa5333748 100644 --- a/tests/integration/encryption/commit_test.go +++ b/tests/integration/encryption/commit_test.go @@ -13,27 +13,19 @@ package encryption import ( "testing" - "github.com/sourcenetwork/defradb/internal/encryption" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) -func encrypt(plaintext []byte) []byte { - val, _ := encryption.EncryptAES(plaintext, []byte("examplekey1234567890examplekey12")) - return val -} - func TestDocEncryption_WithEncryptionOnLWWCRDT_ShouldStoreCommitsDeltaEncrypted(t *testing.T) { - const docID = "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3" - test := testUtils.TestCase{ Actions: []any{ updateUserCollectionSchema(), testUtils.CreateDoc{ - Doc: `{ - "name": "John", - "age": 21 - }`, - IsEncrypted: true, + Doc: john21Doc, + IsDocEncrypted: true, }, testUtils.Request{ Request: ` @@ -55,41 +47,41 @@ func TestDocEncryption_WithEncryptionOnLWWCRDT_ShouldStoreCommitsDeltaEncrypted( `, Results: []map[string]any{ { - "cid": "bafyreih7ry7ef26xn3lm2rhxusf2rbgyvl535tltrt6ehpwtvdnhlmptiu", + "cid": "bafyreibdjepzhhiez4o27srv33xcd52yr336tpzqtkv36rdf3h3oue2l5m", "collectionID": int64(1), - "delta": encrypt(testUtils.CBORValue(21)), - "docID": docID, + "delta": encrypt(testUtils.CBORValue(21), john21DocID, ""), + "docID": john21DocID, "fieldId": "1", "fieldName": "age", "height": int64(1), "links": []map[string]any{}, }, { - "cid": "bafyreifusejlwidaqswasct37eorazlfix6vyyn5af42pmjvktilzj5cty", + "cid": "bafyreihkiua7jpwkye3xlex6s5hh2azckcaljfi2h3iscgub5sikacyrbu", "collectionID": int64(1), - "delta": encrypt(testUtils.CBORValue("John")), - "docID": docID, + "delta": encrypt(testUtils.CBORValue("John"), john21DocID, ""), + "docID": john21DocID, "fieldId": "2", "fieldName": "name", "height": int64(1), "links": []map[string]any{}, }, { - "cid": "bafyreicvxlfxeqghmc3gy56rp5rzfejnbng4nu77x5e3wjinfydl6wvycq", + "cid": "bafyreidxdhzhwjrv5s4x6cho5drz6xq2tc7oymzupf4p4gfk6eelsnc7ke", "collectionID": int64(1), "delta": nil, - "docID": docID, + "docID": john21DocID, "fieldId": "C", "fieldName": nil, "height": int64(1), "links": []map[string]any{ { - "cid": "bafyreifusejlwidaqswasct37eorazlfix6vyyn5af42pmjvktilzj5cty", - "name": "name", + "cid": "bafyreibdjepzhhiez4o27srv33xcd52yr336tpzqtkv36rdf3h3oue2l5m", + "name": "age", }, { - "cid": "bafyreih7ry7ef26xn3lm2rhxusf2rbgyvl535tltrt6ehpwtvdnhlmptiu", - "name": "age", + "cid": "bafyreihkiua7jpwkye3xlex6s5hh2azckcaljfi2h3iscgub5sikacyrbu", + "name": "name", }, }, }, @@ -106,11 +98,8 @@ func TestDocEncryption_UponUpdateOnLWWCRDT_ShouldEncryptCommitDelta(t *testing.T Actions: []any{ updateUserCollectionSchema(), testUtils.CreateDoc{ - Doc: `{ - "name": "John", - "age": 21 - }`, - IsEncrypted: true, + Doc: john21Doc, + IsDocEncrypted: true, }, testUtils.UpdateDoc{ Doc: `{ @@ -127,10 +116,10 @@ func TestDocEncryption_UponUpdateOnLWWCRDT_ShouldEncryptCommitDelta(t *testing.T `, Results: []map[string]any{ { - "delta": encrypt(testUtils.CBORValue(22)), + "delta": encrypt(testUtils.CBORValue(22), john21DocID, ""), }, { - "delta": encrypt(testUtils.CBORValue(21)), + "delta": encrypt(testUtils.CBORValue(21), john21DocID, ""), }, }, }, @@ -141,24 +130,15 @@ func TestDocEncryption_UponUpdateOnLWWCRDT_ShouldEncryptCommitDelta(t *testing.T } func TestDocEncryption_WithMultipleDocsUponUpdate_ShouldEncryptOnlyRelevantDocs(t *testing.T) { - const johnDocID = "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3" - const islamDocID = "bae-d55bd956-1cc4-5d26-aa71-b98807ad49d6" - test := testUtils.TestCase{ Actions: []any{ updateUserCollectionSchema(), testUtils.CreateDoc{ - Doc: `{ - "name": "John", - "age": 21 - }`, - IsEncrypted: true, + Doc: john21Doc, + IsDocEncrypted: true, }, testUtils.CreateDoc{ - Doc: `{ - "name": "Islam", - "age": 33 - }`, + Doc: islam33Doc, }, testUtils.UpdateDoc{ DocID: 0, @@ -183,20 +163,20 @@ func TestDocEncryption_WithMultipleDocsUponUpdate_ShouldEncryptOnlyRelevantDocs( `, Results: []map[string]any{ { - "delta": encrypt(testUtils.CBORValue(22)), - "docID": johnDocID, + "delta": encrypt(testUtils.CBORValue(22), john21DocID, ""), + "docID": john21DocID, }, { - "delta": encrypt(testUtils.CBORValue(21)), - "docID": johnDocID, + "delta": encrypt(testUtils.CBORValue(21), john21DocID, ""), + "docID": john21DocID, }, { "delta": testUtils.CBORValue(34), - "docID": islamDocID, + "docID": islam33DocID, }, { "delta": testUtils.CBORValue(33), - "docID": islamDocID, + "docID": islam33DocID, }, }, }, @@ -218,14 +198,13 @@ func TestDocEncryption_WithEncryptionOnCounterCRDT_ShouldStoreCommitsDeltaEncryp } `}, testUtils.CreateDoc{ - Doc: `{ "points": 5 }`, - IsEncrypted: true, + Doc: `{ "points": 5 }`, + IsDocEncrypted: true, }, testUtils.Request{ Request: ` query { commits { - cid delta docID } @@ -233,12 +212,10 @@ func TestDocEncryption_WithEncryptionOnCounterCRDT_ShouldStoreCommitsDeltaEncryp `, Results: []map[string]any{ { - "cid": "bafyreieb6owsoljj4vondkx35ngxmhliauwvphicz4edufcy7biexij7mu", - "delta": encrypt(testUtils.CBORValue(5)), + "delta": encrypt(testUtils.CBORValue(5), docID, ""), "docID": docID, }, { - "cid": "bafyreif2lejhvdja2rmo237lrwpj45usrm55h6gzr4ewl6gajq3cl4ppsi", "delta": nil, "docID": docID, }, @@ -251,6 +228,8 @@ func TestDocEncryption_WithEncryptionOnCounterCRDT_ShouldStoreCommitsDeltaEncryp } func TestDocEncryption_UponUpdateOnCounterCRDT_ShouldEncryptedCommitDelta(t *testing.T) { + const docID = "bae-d3cc98b4-38d5-5c50-85a3-d3045d44094e" + test := testUtils.TestCase{ Actions: []any{ testUtils.SchemaUpdate{ @@ -260,8 +239,8 @@ func TestDocEncryption_UponUpdateOnCounterCRDT_ShouldEncryptedCommitDelta(t *tes } `}, testUtils.CreateDoc{ - Doc: `{ "points": 5 }`, - IsEncrypted: true, + Doc: `{ "points": 5 }`, + IsDocEncrypted: true, }, testUtils.UpdateDoc{ Doc: `{ @@ -278,10 +257,10 @@ func TestDocEncryption_UponUpdateOnCounterCRDT_ShouldEncryptedCommitDelta(t *tes `, Results: []map[string]any{ { - "delta": encrypt(testUtils.CBORValue(3)), + "delta": encrypt(testUtils.CBORValue(3), docID, ""), }, { - "delta": encrypt(testUtils.CBORValue(5)), + "delta": encrypt(testUtils.CBORValue(5), docID, ""), }, }, }, @@ -296,21 +275,13 @@ func TestDocEncryption_UponEncryptionSeveralDocs_ShouldStoreAllCommitsDeltaEncry Actions: []any{ updateUserCollectionSchema(), testUtils.CreateDoc{ - Doc: `[{ - "name": "John", - "age": 21 - }, - { - "name": "Islam", - "age": 33 - }]`, - IsEncrypted: true, + Doc: "[" + john21Doc + ", " + islam33Doc + "]", + IsDocEncrypted: true, }, testUtils.Request{ Request: ` query { commits { - cid delta docID } @@ -318,32 +289,26 @@ func TestDocEncryption_UponEncryptionSeveralDocs_ShouldStoreAllCommitsDeltaEncry `, Results: []map[string]any{ { - "cid": "bafyreih7ry7ef26xn3lm2rhxusf2rbgyvl535tltrt6ehpwtvdnhlmptiu", - "delta": encrypt(testUtils.CBORValue(21)), + "delta": encrypt(testUtils.CBORValue(21), john21DocID, ""), "docID": testUtils.NewDocIndex(0, 0), }, { - "cid": "bafyreifusejlwidaqswasct37eorazlfix6vyyn5af42pmjvktilzj5cty", - "delta": encrypt(testUtils.CBORValue("John")), + "delta": encrypt(testUtils.CBORValue("John"), john21DocID, ""), "docID": testUtils.NewDocIndex(0, 0), }, { - "cid": "bafyreicvxlfxeqghmc3gy56rp5rzfejnbng4nu77x5e3wjinfydl6wvycq", "delta": nil, "docID": testUtils.NewDocIndex(0, 0), }, { - "cid": "bafyreibe24bo67owxewoso3ekinera2bhusguij5qy2ahgyufaq3fbvaxa", - "delta": encrypt(testUtils.CBORValue(33)), + "delta": encrypt(testUtils.CBORValue(33), islam33DocID, ""), "docID": testUtils.NewDocIndex(0, 1), }, { - "cid": "bafyreie2fddpidgc62fhd2fjrsucq3spgh2mgvto2xwolcdmdhb5pdeok4", - "delta": encrypt(testUtils.CBORValue("Islam")), + "delta": encrypt(testUtils.CBORValue("Islam"), islam33DocID, ""), "docID": testUtils.NewDocIndex(0, 1), }, { - "cid": "bafyreifulxdkf4m3wmmdxjg43l4mw7uuxl5il27eabklc22nptilrh64sa", "delta": nil, "docID": testUtils.NewDocIndex(0, 1), }, @@ -354,3 +319,45 @@ func TestDocEncryption_UponEncryptionSeveralDocs_ShouldStoreAllCommitsDeltaEncry testUtils.ExecuteTestCase(t, test) } + +func TestDocEncryption_IfTwoDocsHaveSameFieldValue_CipherTextShouldBeDifferent(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + updateUserCollectionSchema(), + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "age": 21 + }`, + IsDocEncrypted: true, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Islam", + "age": 21 + }`, + IsDocEncrypted: true, + }, + testUtils.Request{ + Request: ` + query { + commits(fieldId: "1") { + delta + fieldName + } + } + `, + Asserter: testUtils.ResultAsserterFunc(func(_ testing.TB, result []map[string]any) (bool, string) { + require.Equal(t, 2, len(result), "Expected 2 commits") + require.Equal(t, result[0]["fieldName"], "age") + delta1 := result[0]["delta"] + delta2 := result[1]["delta"] + assert.NotEqual(t, delta1, delta2, "docs should be encrypted with different encryption keys") + return true, "" + }), + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/encryption/field_commit_test.go b/tests/integration/encryption/field_commit_test.go new file mode 100644 index 0000000000..5a956a42b2 --- /dev/null +++ b/tests/integration/encryption/field_commit_test.go @@ -0,0 +1,190 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package encryption + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestDocEncryptionField_WithEncryptionOnField_ShouldStoreOnlyFieldsDeltaEncrypted(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + updateUserCollectionSchema(), + testUtils.CreateDoc{ + Doc: john21Doc, + EncryptedFields: []string{"age"}, + }, + testUtils.Request{ + Request: ` + query { + commits { + delta + docID + fieldName + } + } + `, + Results: []map[string]any{ + { + "delta": encrypt(testUtils.CBORValue(21), john21DocID, "age"), + "docID": john21DocID, + "fieldName": "age", + }, + { + "delta": testUtils.CBORValue("John"), + "docID": john21DocID, + "fieldName": "name", + }, + { + "delta": nil, + "docID": john21DocID, + "fieldName": nil, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestDocEncryptionField_WithDocAndFieldEncryption_ShouldUseDedicatedEncKeyForIndividualFields(t *testing.T) { + deltaForField := func(fieldName string, result []map[string]any) any { + for _, r := range result { + if r["fieldName"] == fieldName { + return r["delta"] + } + } + t.Fatalf("Field %s not found in results %v", fieldName, result) + return nil + } + + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Users { + name1: String + name2: String + name3: String + name4: String + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name1": "John", + "name2": "John", + "name3": "John", + "name4": "John" + }`, + IsDocEncrypted: true, + EncryptedFields: []string{"name1", "name3"}, + }, + testUtils.Request{ + Request: ` + query { + commits { + cid + delta + fieldName + } + } + `, + Asserter: testUtils.ResultAsserterFunc(func(_ testing.TB, result []map[string]any) (bool, string) { + name1 := deltaForField("name1", result) + name2 := deltaForField("name2", result) + name3 := deltaForField("name3", result) + name4 := deltaForField("name4", result) + assert.Equal(t, name2, name4, "name2 and name4 should have the same encryption key") + assert.NotEqual(t, name2, name1, "name2 and name1 should have different encryption keys") + assert.NotEqual(t, name2, name3, "name2 and name3 should have different encryption keys") + assert.NotEqual(t, name1, name3, "name1 and name3 should have different encryption keys") + return true, "" + }), + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestDocEncryptionField_UponUpdateWithDocAndFieldEncryption_ShouldUseDedicatedEncKeyForIndividualFields(t *testing.T) { + deltaForField := func(fieldName string, result []map[string]any) any { + for _, r := range result { + if r["fieldName"] == fieldName { + return r["delta"] + } + } + t.Fatalf("Field %s not found in results %v", fieldName, result) + return nil + } + + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Users { + name1: String + name2: String + name3: String + name4: String + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name1": "John", + "name2": "John", + "name3": "John", + "name4": "John" + }`, + IsDocEncrypted: true, + EncryptedFields: []string{"name1", "name3"}, + }, + testUtils.UpdateDoc{ + Doc: `{ + "name1": "Andy", + "name2": "Andy", + "name3": "Andy", + "name4": "Andy" + }`, + }, + testUtils.Request{ + Request: ` + query { + commits(order: {height: DESC}, limit: 5) { + cid + delta + fieldName + height + } + } + `, + Asserter: testUtils.ResultAsserterFunc(func(_ testing.TB, result []map[string]any) (bool, string) { + name1 := deltaForField("name1", result) + name2 := deltaForField("name2", result) + name3 := deltaForField("name3", result) + name4 := deltaForField("name4", result) + assert.Equal(t, name2, name4, "name2 and name4 should have the same encryption key") + assert.NotEqual(t, name2, name1, "name2 and name1 should have different encryption keys") + assert.NotEqual(t, name2, name3, "name2 and name3 should have different encryption keys") + assert.NotEqual(t, name1, name3, "name1 and name3 should have different encryption keys") + return true, "" + }), + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/encryption/field_query_test.go b/tests/integration/encryption/field_query_test.go new file mode 100644 index 0000000000..d008960448 --- /dev/null +++ b/tests/integration/encryption/field_query_test.go @@ -0,0 +1,54 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package encryption + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestDocEncryptionField_WithEncryption_ShouldFetchDecrypted(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Users { + name: String + age: Int + } + `}, + testUtils.CreateDoc{ + Doc: john21Doc, + EncryptedFields: []string{"name"}, + }, + testUtils.Request{ + Request: ` + query { + Users { + _docID + name + age + } + }`, + Results: []map[string]any{ + { + "_docID": testUtils.NewDocIndex(0, 0), + "name": "John", + "age": int64(21), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/encryption/field_test.go b/tests/integration/encryption/field_test.go new file mode 100644 index 0000000000..839e97274f --- /dev/null +++ b/tests/integration/encryption/field_test.go @@ -0,0 +1,129 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package encryption + +import ( + "testing" + + "github.com/sourcenetwork/immutable" + + "github.com/sourcenetwork/defradb/client" + "github.com/sourcenetwork/defradb/internal/db" + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestDocEncryptionField_IfFieldDoesNotExistInGQLSchema_ReturnError(t *testing.T) { + test := testUtils.TestCase{ + SupportedMutationTypes: immutable.Some([]testUtils.MutationType{ + testUtils.GQLRequestMutationType, + }), + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Users { + name: String + age: Int + } + `}, + testUtils.CreateDoc{ + Doc: john21Doc, + EncryptedFields: []string{"points"}, + ExpectedError: "Argument \"encryptFields\" has invalid value [points].", + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestDocEncryptionField_IfAttemptToEncryptBuiltinFieldInGQLSchema_ReturnError(t *testing.T) { + test := testUtils.TestCase{ + SupportedMutationTypes: immutable.Some([]testUtils.MutationType{ + testUtils.GQLRequestMutationType, + }), + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Users { + name: String + age: Int + } + `}, + testUtils.CreateDoc{ + Doc: john21Doc, + EncryptedFields: []string{"_docID"}, + ExpectedError: "Argument \"encryptFields\" has invalid value [_docID].", + }, + testUtils.CreateDoc{ + Doc: john21Doc, + EncryptedFields: []string{"_version"}, + ExpectedError: "Argument \"encryptFields\" has invalid value [_version].", + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestDocEncryptionField_IfFieldDoesNotExist_ReturnError(t *testing.T) { + test := testUtils.TestCase{ + SupportedMutationTypes: immutable.Some([]testUtils.MutationType{ + testUtils.CollectionSaveMutationType, + testUtils.CollectionNamedMutationType, + }), + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Users { + name: String + age: Int + } + `}, + testUtils.CreateDoc{ + Doc: john21Doc, + EncryptedFields: []string{"points"}, + ExpectedError: client.NewErrFieldNotExist("points").Error(), + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestDocEncryptionField_IfAttemptToEncryptBuiltinField_ReturnError(t *testing.T) { + test := testUtils.TestCase{ + SupportedMutationTypes: immutable.Some([]testUtils.MutationType{ + testUtils.CollectionSaveMutationType, + testUtils.CollectionNamedMutationType, + }), + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Users { + name: String + age: Int + } + `}, + testUtils.CreateDoc{ + Doc: john21Doc, + EncryptedFields: []string{"_docID"}, + ExpectedError: db.NewErrCanNotEncryptBuiltinField("_docID").Error(), + }, + testUtils.CreateDoc{ + Doc: john21Doc, + EncryptedFields: []string{"_version"}, + ExpectedError: client.NewErrFieldNotExist("_version").Error(), + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/encryption/peer_test.go b/tests/integration/encryption/peer_test.go index 6d9c937278..4eb0ddc19a 100644 --- a/tests/integration/encryption/peer_test.go +++ b/tests/integration/encryption/peer_test.go @@ -33,12 +33,9 @@ func TestDocEncryptionPeer_IfPeerHasNoKey_ShouldNotFetch(t *testing.T) { CollectionIDs: []int{0}, }, testUtils.CreateDoc{ - NodeID: immutable.Some(0), - Doc: `{ - "name": "John", - "age": 21 - }`, - IsEncrypted: true, + NodeID: immutable.Some(0), + Doc: john21Doc, + IsDocEncrypted: true, }, testUtils.WaitForSync{}, testUtils.Request{ @@ -71,12 +68,9 @@ func TestDocEncryptionPeer_UponSync_ShouldSyncEncryptedDAG(t *testing.T) { CollectionIDs: []int{0}, }, testUtils.CreateDoc{ - NodeID: immutable.Some(0), - Doc: `{ - "name": "John", - "age": 21 - }`, - IsEncrypted: true, + NodeID: immutable.Some(0), + Doc: john21Doc, + IsDocEncrypted: true, }, testUtils.WaitForSync{}, testUtils.Request{ @@ -100,41 +94,41 @@ func TestDocEncryptionPeer_UponSync_ShouldSyncEncryptedDAG(t *testing.T) { `, Results: []map[string]any{ { - "cid": "bafyreih7ry7ef26xn3lm2rhxusf2rbgyvl535tltrt6ehpwtvdnhlmptiu", + "cid": "bafyreibdjepzhhiez4o27srv33xcd52yr336tpzqtkv36rdf3h3oue2l5m", "collectionID": int64(1), - "delta": encrypt(testUtils.CBORValue(21)), - "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", + "delta": encrypt(testUtils.CBORValue(21), john21DocID, ""), + "docID": john21DocID, "fieldId": "1", "fieldName": "age", "height": int64(1), "links": []map[string]any{}, }, { - "cid": "bafyreifusejlwidaqswasct37eorazlfix6vyyn5af42pmjvktilzj5cty", + "cid": "bafyreihkiua7jpwkye3xlex6s5hh2azckcaljfi2h3iscgub5sikacyrbu", "collectionID": int64(1), - "delta": encrypt(testUtils.CBORValue("John")), - "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", + "delta": encrypt(testUtils.CBORValue("John"), john21DocID, ""), + "docID": john21DocID, "fieldId": "2", "fieldName": "name", "height": int64(1), "links": []map[string]any{}, }, { - "cid": "bafyreicvxlfxeqghmc3gy56rp5rzfejnbng4nu77x5e3wjinfydl6wvycq", + "cid": "bafyreidxdhzhwjrv5s4x6cho5drz6xq2tc7oymzupf4p4gfk6eelsnc7ke", "collectionID": int64(1), "delta": nil, - "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", + "docID": john21DocID, "fieldId": "C", "fieldName": nil, "height": int64(1), "links": []map[string]any{ { - "cid": "bafyreifusejlwidaqswasct37eorazlfix6vyyn5af42pmjvktilzj5cty", - "name": "name", + "cid": "bafyreibdjepzhhiez4o27srv33xcd52yr336tpzqtkv36rdf3h3oue2l5m", + "name": "age", }, { - "cid": "bafyreih7ry7ef26xn3lm2rhxusf2rbgyvl535tltrt6ehpwtvdnhlmptiu", - "name": "age", + "cid": "bafyreihkiua7jpwkye3xlex6s5hh2azckcaljfi2h3iscgub5sikacyrbu", + "name": "name", }, }, }, diff --git a/tests/integration/encryption/query_relation_test.go b/tests/integration/encryption/query_relation_test.go new file mode 100644 index 0000000000..8ca51c03aa --- /dev/null +++ b/tests/integration/encryption/query_relation_test.go @@ -0,0 +1,198 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package encryption + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestDocEncryption_WithEncryptionOnBothRelations_ShouldFetchDecrypted(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + devices: [Device] + } + + type Device { + model: String + manufacturer: String + owner: User + } + `, + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ + "name": "Chris" + }`, + IsDocEncrypted: true, + }, + testUtils.CreateDoc{ + CollectionID: 1, + DocMap: map[string]any{ + "model": "Walkman", + "manufacturer": "Sony", + "owner": testUtils.NewDocIndex(0, 0), + }, + IsDocEncrypted: true, + }, + testUtils.Request{ + Request: `query { + User { + name + devices { + model + manufacturer + } + } + }`, + Results: []map[string]any{ + { + "name": "Chris", + "devices": []map[string]any{ + { + "model": "Walkman", + "manufacturer": "Sony", + }, + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestDocEncryption_WithEncryptionOnPrimaryRelations_ShouldFetchDecrypted(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + devices: [Device] + } + + type Device { + model: String + manufacturer: String + owner: User + } + `, + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ + "name": "Chris" + }`, + }, + testUtils.CreateDoc{ + CollectionID: 1, + DocMap: map[string]any{ + "model": "Walkman", + "manufacturer": "Sony", + "owner": testUtils.NewDocIndex(0, 0), + }, + IsDocEncrypted: true, + }, + testUtils.Request{ + Request: `query { + User { + name + devices { + model + manufacturer + } + } + }`, + Results: []map[string]any{ + { + "name": "Chris", + "devices": []map[string]any{ + { + "model": "Walkman", + "manufacturer": "Sony", + }, + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestDocEncryption_WithEncryptionOnSecondaryRelations_ShouldFetchDecrypted(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + devices: [Device] + } + + type Device { + model: String + manufacturer: String + owner: User + } + `, + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ + "name": "Chris" + }`, + IsDocEncrypted: true, + }, + testUtils.CreateDoc{ + CollectionID: 1, + DocMap: map[string]any{ + "model": "Walkman", + "manufacturer": "Sony", + "owner": testUtils.NewDocIndex(0, 0), + }, + }, + testUtils.Request{ + Request: `query { + User { + name + devices { + model + manufacturer + } + } + }`, + Results: []map[string]any{ + { + "name": "Chris", + "devices": []map[string]any{ + { + "model": "Walkman", + "manufacturer": "Sony", + }, + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/encryption/query_test.go b/tests/integration/encryption/query_test.go index 32d9bd2c94..05e7b1dcdd 100644 --- a/tests/integration/encryption/query_test.go +++ b/tests/integration/encryption/query_test.go @@ -27,11 +27,8 @@ func TestDocEncryption_WithEncryption_ShouldFetchDecrypted(t *testing.T) { } `}, testUtils.CreateDoc{ - Doc: `{ - "name": "John", - "age": 21 - }`, - IsEncrypted: true, + Doc: john21Doc, + IsDocEncrypted: true, }, testUtils.Request{ Request: ` @@ -79,7 +76,7 @@ func TestDocEncryption_WithEncryptionOnCounterCRDT_ShouldFetchDecrypted(t *testi "name": "John", "points": 5 }`, - IsEncrypted: true, + IsDocEncrypted: true, }, testUtils.Request{ Request: query, diff --git a/tests/integration/encryption/utils.go b/tests/integration/encryption/utils.go index 400a0d34c3..fd9c1d17c0 100644 --- a/tests/integration/encryption/utils.go +++ b/tests/integration/encryption/utils.go @@ -11,6 +11,7 @@ package encryption import ( + "github.com/sourcenetwork/defradb/internal/encryption" testUtils "github.com/sourcenetwork/defradb/tests/integration" ) @@ -24,8 +25,31 @@ const userCollectionGQLSchema = (` } `) +const ( + john21Doc = `{ + "name": "John", + "age": 21 + }` + islam33Doc = `{ + "name": "Islam", + "age": 33 + }` + john21DocID = "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3" + islam33DocID = "bae-d55bd956-1cc4-5d26-aa71-b98807ad49d6" +) + func updateUserCollectionSchema() testUtils.SchemaUpdate { return testUtils.SchemaUpdate{ Schema: userCollectionGQLSchema, } } + +// encrypt encrypts the given plain text with a deterministic encryption key. +// We also want to make sure different keys are generated for different docs and fields +// and that's why we use the docID and fieldName to generate the key. +func encrypt(plaintext []byte, docID, fieldName string) []byte { + const keyLength = 32 + const testEncKey = "examplekey1234567890examplekey12" + val, _ := encryption.EncryptAES(plaintext, []byte(fieldName + docID + testEncKey)[0:keyLength]) + return val +} diff --git a/tests/integration/query/one_to_many/with_group_related_id_test.go b/tests/integration/query/one_to_many/with_group_related_id_test.go index 673ccfddad..509c38fc27 100644 --- a/tests/integration/query/one_to_many/with_group_related_id_test.go +++ b/tests/integration/query/one_to_many/with_group_related_id_test.go @@ -371,7 +371,7 @@ func TestQueryOneToManyWithParentGroupByOnRelatedTypeFromSingleSide(t *testing.T }, }, - ExpectedError: "Argument \"groupBy\" has invalid value [published_id].\nIn element #1: Expected type \"AuthorFields\", found published_id.", + ExpectedError: "Argument \"groupBy\" has invalid value [published_id].\nIn element #1: Expected type \"AuthorField\", found published_id.", } executeTestCase(t, test) @@ -449,7 +449,7 @@ func TestQueryOneToManyWithParentGroupByOnRelatedTypeWithIDSelectionFromSingleSi }, }, - ExpectedError: "Argument \"groupBy\" has invalid value [published_id].\nIn element #1: Expected type \"AuthorFields\", found published_id.", + ExpectedError: "Argument \"groupBy\" has invalid value [published_id].\nIn element #1: Expected type \"AuthorField\", found published_id.", } executeTestCase(t, test) diff --git a/tests/integration/schema/group_test.go b/tests/integration/schema/group_test.go index 5ac89b95ec..04a8ccfde8 100644 --- a/tests/integration/schema/group_test.go +++ b/tests/integration/schema/group_test.go @@ -41,7 +41,7 @@ func TestGroupByFieldForTheManySideInSchema(t *testing.T) { testUtils.IntrospectionRequest{ Request: ` { - __type(name: "BookFields") { + __type(name: "BookField") { name kind enumValues { @@ -53,7 +53,7 @@ func TestGroupByFieldForTheManySideInSchema(t *testing.T) { ContainsData: map[string]any{ "__type": map[string]any{ "kind": "ENUM", - "name": "BookFields", + "name": "BookField", "enumValues": []any{ // Internal related object fields. map[string]any{"name": "author"}, @@ -103,7 +103,7 @@ func TestGroupByFieldForTheSingleSideInSchema(t *testing.T) { testUtils.IntrospectionRequest{ Request: ` { - __type(name: "AuthorFields") { + __type(name: "AuthorField") { name kind enumValues { @@ -115,7 +115,7 @@ func TestGroupByFieldForTheSingleSideInSchema(t *testing.T) { ContainsData: map[string]any{ "__type": map[string]any{ "kind": "ENUM", - "name": "AuthorFields", + "name": "AuthorField", "enumValues": []any{ // Internal related object fields. map[string]any{"name": "published"}, diff --git a/tests/integration/schema/type_explicit_fields_test.go b/tests/integration/schema/type_explicit_fields_test.go new file mode 100644 index 0000000000..844bed4e52 --- /dev/null +++ b/tests/integration/schema/type_explicit_fields_test.go @@ -0,0 +1,60 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package schema + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestEncryptFieldsForCreateMutation(t *testing.T) { + test := testUtils.TestCase{ + + Description: "Test that type explicit (or user-defined) fields are generated.", + + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + age: Int + } + `, + }, + testUtils.IntrospectionRequest{ + Request: ` + { + __type(name: "UserField") { + name + kind + enumValues { + name + } + } + } + `, + ContainsData: map[string]any{ + "__type": map[string]any{ + "kind": "ENUM", + "name": "UserField", + "enumValues": []any{ + map[string]any{"name": "name"}, + map[string]any{"name": "age"}, + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/test_case.go b/tests/integration/test_case.go index 3af3303446..ad5a86a665 100644 --- a/tests/integration/test_case.go +++ b/tests/integration/test_case.go @@ -230,7 +230,10 @@ type CreateDoc struct { Identity immutable.Option[int] // Specifies whether the document should be encrypted. - IsEncrypted bool + IsDocEncrypted bool + + // Individual fields of the document to encrypt. + EncryptedFields []string // The collection in which this document should be created. CollectionID int diff --git a/tests/integration/utils2.go b/tests/integration/utils2.go index 1dc8006b1b..82ab5620c8 100644 --- a/tests/integration/utils2.go +++ b/tests/integration/utils2.go @@ -1252,9 +1252,7 @@ func createDocViaColSave( func makeContextForDocCreate(s *state, ctx context.Context, action *CreateDoc) context.Context { identity := getIdentity(s, action.Identity) ctx = db.SetContextIdentity(ctx, identity) - if action.IsEncrypted { - ctx = encryption.SetContextConfig(ctx, encryption.DocEncConfig{IsEncrypted: true}) - } + ctx = encryption.SetContextConfigFromParams(ctx, action.IsDocEncrypted, action.EncryptedFields) return ctx } @@ -1322,8 +1320,12 @@ func createDocViaGQL( params := paramName + ": " + input - if action.IsEncrypted { - params = params + ", " + request.EncryptArgName + ": true" + if action.IsDocEncrypted { + params = params + ", " + request.EncryptDocArgName + ": true" + } + if len(action.EncryptedFields) > 0 { + params = params + ", " + request.EncryptFieldsArgName + ": [" + + strings.Join(action.EncryptedFields, ", ") + "]" } req := fmt.Sprintf( @@ -1337,8 +1339,7 @@ func createDocViaGQL( ) txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) - - ctx := makeContextForDocCreate(s, db.SetContextTxn(s.ctx, txn), &action) + ctx := db.SetContextIdentity(db.SetContextTxn(s.ctx, txn), getIdentity(s, action.Identity)) result := node.ExecRequest(ctx, req) if len(result.GQL.Errors) > 0 { From 3500ce350ffab54b7898cd6675ed9d7c1ee696b7 Mon Sep 17 00:00:00 2001 From: AndrewSisley Date: Mon, 15 Jul 2024 11:09:04 -0400 Subject: [PATCH 09/41] test: Fix refreshing of docs in change detector (#2832) ## Relevant issue(s) Resolves #2812 ## Description This fixes two issues in `refreshDocuments`. - `DocIndex`es were not accounted for in refresh documents, this was introduced a while ago and lay hiding until recently - Creating multiple docs in a single action was not handled --- tests/integration/utils2.go | 41 +++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/tests/integration/utils2.go b/tests/integration/utils2.go index 82ab5620c8..4ab68930cf 100644 --- a/tests/integration/utils2.go +++ b/tests/integration/utils2.go @@ -870,33 +870,48 @@ func refreshDocuments( } for i := 0; i < startActionIndex; i++ { + // We need to add the existing documents in the order in which the test case lists them + // otherwise they cannot be referenced correctly by other actions. switch action := s.testCase.Actions[i].(type) { case CreateDoc: // Just use the collection from the first relevant node, as all will be the same for this // purpose. collection := getNodeCollections(action.NodeID, s.collections)[0][action.CollectionID] - // We need to add the existing documents in the order in which the test case lists them - // otherwise they cannot be referenced correctly by other actions. - doc, err := client.NewDocFromJSON([]byte(action.Doc), collection.Definition()) - if err != nil { - // If an err has been returned, ignore it - it may be expected and if not - // the test will fail later anyway - continue + var doc *client.Document + var docs []*client.Document + var err error + if action.DocMap != nil { + substituteRelations(s, action) + doc, err = client.NewDocFromMap(action.DocMap, collection.Definition()) + docs = append(docs, doc) + } else if client.IsJSONArray([]byte(action.Doc)) { + docs, err = client.NewDocsFromJSON([]byte(action.Doc), collection.Definition()) + } else { + doc, err = client.NewDocFromJSON([]byte(action.Doc), collection.Definition()) + docs = append(docs, doc) } - ctx := makeContextForDocCreate(s, s.ctx, &action) - - // The document may have been mutated by other actions, so to be sure we have the latest - // version without having to worry about the individual update mechanics we fetch it. - doc, err = collection.Get(ctx, doc.ID(), false) if err != nil { // If an err has been returned, ignore it - it may be expected and if not // the test will fail later anyway continue } - s.documents[action.CollectionID] = append(s.documents[action.CollectionID], doc) + for _, doc := range docs { + ctx := makeContextForDocCreate(s, s.ctx, &action) + + // The document may have been mutated by other actions, so to be sure we have the latest + // version without having to worry about the individual update mechanics we fetch it. + doc, err = collection.Get(ctx, doc.ID(), false) + if err != nil { + // If an err has been returned, ignore it - it may be expected and if not + // the test will fail later anyway + continue + } + + s.documents[action.CollectionID] = append(s.documents[action.CollectionID], doc) + } } } } From 7f6679076658c5bd080c3fd015cfa5dffb406af2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 11:31:21 -0400 Subject: [PATCH 10/41] bot: Update dependencies (bulk dependabot PRs) 05-07-2024 (#2811) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✅ This PR was created by combining the following PRs: #2807 bot: Bump github.com/go-chi/chi/v5 from 5.0.12 to 5.1.0 #2806 bot: Bump github.com/fxamacker/cbor/v2 from 2.6.0 to 2.7.0 #2805 bot: Bump github.com/multiformats/go-multiaddr from 0.12.4 to 0.13.0 #2804 bot: Bump @typescript-eslint/eslint-plugin from 7.13.1 to 7.14.1 in /playground #2802 bot: Bump vite from 5.3.1 to 5.3.2 in /playground ⚠️ The following PRs were resolved manually due to merge conflicts: #2803 bot: Bump @typescript-eslint/parser from 7.13.1 to 7.14.1 in /playground --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Shahzad Lone --- go.mod | 6 +- go.sum | 12 +- playground/package-lock.json | 317 +++++++++++++++++++++++++++++++---- playground/package.json | 6 +- 4 files changed, 298 insertions(+), 43 deletions(-) diff --git a/go.mod b/go.mod index 350e183739..8b86029164 100644 --- a/go.mod +++ b/go.mod @@ -9,9 +9,9 @@ require ( github.com/cyware/ssi-sdk v0.0.0-20231229164914-f93f3006379f github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 github.com/evanphx/json-patch/v5 v5.9.0 - github.com/fxamacker/cbor/v2 v2.6.0 + github.com/fxamacker/cbor/v2 v2.7.0 github.com/getkin/kin-openapi v0.125.0 - github.com/go-chi/chi/v5 v5.0.12 + github.com/go-chi/chi/v5 v5.1.0 github.com/go-chi/cors v1.2.1 github.com/go-errors/errors v1.5.1 github.com/gofrs/uuid/v5 v5.2.0 @@ -34,7 +34,7 @@ require ( github.com/libp2p/go-libp2p-pubsub v0.11.0 github.com/libp2p/go-libp2p-record v0.2.0 github.com/mr-tron/base58 v1.2.0 - github.com/multiformats/go-multiaddr v0.12.4 + github.com/multiformats/go-multiaddr v0.13.0 github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multicodec v0.9.0 github.com/multiformats/go-multihash v0.2.3 diff --git a/go.sum b/go.sum index 3f8aaf0ce5..eeb4bf7bdd 100644 --- a/go.sum +++ b/go.sum @@ -169,8 +169,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA= -github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= github.com/getkin/kin-openapi v0.125.0 h1:jyQCyf2qXS1qvs2U00xQzkGCqYPhEhZDmSmVt65fXno= @@ -179,8 +179,8 @@ github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s= -github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= +github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4= github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= @@ -538,8 +538,8 @@ github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9 github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.12.4 h1:rrKqpY9h+n80EwhhC/kkcunCZZ7URIF8yN1WEUt2Hvc= -github.com/multiformats/go-multiaddr v0.12.4/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= +github.com/multiformats/go-multiaddr v0.13.0 h1:BCBzs61E3AGHcYYTv8dqRH43ZfyrqM8RXVPT8t13tLQ= +github.com/multiformats/go-multiaddr v0.13.0/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= diff --git a/playground/package-lock.json b/playground/package-lock.json index 0994b93557..95ce4d5291 100644 --- a/playground/package-lock.json +++ b/playground/package-lock.json @@ -18,14 +18,14 @@ "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@types/swagger-ui-react": "^4.18.3", - "@typescript-eslint/eslint-plugin": "^7.13.1", - "@typescript-eslint/parser": "^7.13.1", + "@typescript-eslint/eslint-plugin": "^7.14.1", + "@typescript-eslint/parser": "^7.14.1", "@vitejs/plugin-react-swc": "^3.7.0", "eslint": "^8.57.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.7", "typescript": "^5.5.2", - "vite": "^5.3.1" + "vite": "^5.3.2" } }, "node_modules/@babel/runtime": { @@ -2386,16 +2386,16 @@ "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.1.tgz", - "integrity": "sha512-kZqi+WZQaZfPKnsflLJQCz6Ze9FFSMfXrrIOcyargekQxG37ES7DJNpJUE9Q/X5n3yTIP/WPutVNzgknQ7biLg==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.14.1.tgz", + "integrity": "sha512-aAJd6bIf2vvQRjUG3ZkNXkmBpN+J7Wd0mfQiiVCJMu9Z5GcZZdcc0j8XwN/BM97Fl7e3SkTXODSk4VehUv7CGw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/type-utils": "7.13.1", - "@typescript-eslint/utils": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", + "@typescript-eslint/scope-manager": "7.14.1", + "@typescript-eslint/type-utils": "7.14.1", + "@typescript-eslint/utils": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -2418,16 +2418,63 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", + "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", + "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", + "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/parser": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.1.tgz", - "integrity": "sha512-1ELDPlnLvDQ5ybTSrMhRTFDfOQEOXNM+eP+3HT/Yq7ruWpciQw+Avi73pdEbA4SooCawEWo3dtYbF68gN7Ed1A==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.14.1.tgz", + "integrity": "sha512-8lKUOebNLcR0D7RvlcloOacTOWzOqemWEWkKSVpMZVF/XVcwjPR+3MD08QzbW9TCGJ+DwIc6zUSGZ9vd8cO1IA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/typescript-estree": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", + "@typescript-eslint/scope-manager": "7.14.1", + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/typescript-estree": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", "debug": "^4.3.4" }, "engines": { @@ -2446,6 +2493,81 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", + "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", + "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", + "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", + "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "7.13.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz", @@ -2464,13 +2586,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.1.tgz", - "integrity": "sha512-aWDbLu1s9bmgPGXSzNCxELu+0+HQOapV/y+60gPXafR8e2g1Bifxzevaa+4L2ytCWm+CHqpELq4CSoN9ELiwCg==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.14.1.tgz", + "integrity": "sha512-/MzmgNd3nnbDbOi3LfasXWWe292+iuo+umJ0bCCMCPc1jLO/z2BQmWUUUXvXLbrQey/JgzdF/OV+I5bzEGwJkQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.13.1", - "@typescript-eslint/utils": "7.13.1", + "@typescript-eslint/typescript-estree": "7.14.1", + "@typescript-eslint/utils": "7.14.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -2490,6 +2612,64 @@ } } }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", + "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", + "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", + "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/types": { "version": "7.13.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", @@ -2532,15 +2712,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.1.tgz", - "integrity": "sha512-h5MzFBD5a/Gh/fvNdp9pTfqJAbuQC4sCN2WzuXme71lqFJsZtLbjxfSk4r3p02WIArOF9N94pdsLiGutpDbrXQ==", + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz", + "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/typescript-estree": "7.13.1" + "@typescript-eslint/scope-manager": "7.14.1", + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/typescript-estree": "7.14.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -2553,6 +2733,81 @@ "eslint": "^8.56.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", + "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", + "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", + "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "@typescript-eslint/visitor-keys": "7.14.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", + "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.14.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "7.13.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz", @@ -5896,9 +6151,9 @@ "optional": true }, "node_modules/vite": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.1.tgz", - "integrity": "sha512-XBmSKRLXLxiaPYamLv3/hnP/KXDai1NDexN0FpkTaZXTfycHvkRHoenpgl/fvuK/kPbB6xAgoyiryAhQNxYmAQ==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", + "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", "dev": true, "dependencies": { "esbuild": "^0.21.3", diff --git a/playground/package.json b/playground/package.json index fd04253371..d0fd624355 100644 --- a/playground/package.json +++ b/playground/package.json @@ -20,13 +20,13 @@ "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@types/swagger-ui-react": "^4.18.3", - "@typescript-eslint/eslint-plugin": "^7.13.1", - "@typescript-eslint/parser": "^7.13.1", + "@typescript-eslint/eslint-plugin": "^7.14.1", + "@typescript-eslint/parser": "^7.14.1", "@vitejs/plugin-react-swc": "^3.7.0", "eslint": "^8.57.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.7", "typescript": "^5.5.2", - "vite": "^5.3.1" + "vite": "^5.3.2" } } From bfa791dfd0b6e5fecca5e3867c48ee25056e65f5 Mon Sep 17 00:00:00 2001 From: Keenan Nemetz Date: Mon, 15 Jul 2024 09:37:11 -0700 Subject: [PATCH 11/41] fix(i): Make badger dependency optional (#2828) ## Relevant issue(s) Resolves #2827 ## Description This PR moves some things around to make the badger dependency optional to allow for JS builds. ## Tasks - [x] I made sure the code is well commented, particularly hard-to-understand areas. - [x] I made sure the repository-held documentation is changed accordingly. - [x] I made sure the pull request title adheres to the conventional commit style (the subset used in the project can be found in [tools/configs/chglog/config.yml](tools/configs/chglog/config.yml)). - [x] I made sure to discuss its limitations such as threats to validity, vulnerability to mistake and misuse, robustness to invalidation of assumptions, resource requirements, ... ## How has this been tested? `make test` Specify the platform(s) on which this was tested: - MacOS --- cli/server_dump.go | 2 +- cli/start.go | 6 +- datastore/badger/v4/datastore.go | 8 +- datastore/badger/v4/errors.go | 27 ++++++ datastore/blockstore_test.go | 4 +- datastore/concurrent_txt_test.go | 4 +- datastore/errors.go | 5 +- datastore/errors/errors.go | 24 ++++++ datastore/memory/errors.go | 13 +-- datastore/txn_test.go | 18 ++-- datastore/wrappedstore_test.go | 4 +- http/utils.go | 6 +- internal/db/messages.go | 4 +- node/errors.go | 10 ++- node/store.go | 86 +++++++------------ node/store_badger.go | 64 ++++++++++++++ node/store_badger_test.go | 43 ++++++++++ node/store_memory.go | 32 +++++++ node/store_test.go | 30 ++----- tests/integration/db.go | 12 +-- .../integration/mutation/mix/with_txn_test.go | 2 +- tests/integration/utils2.go | 3 +- 22 files changed, 281 insertions(+), 126 deletions(-) create mode 100644 datastore/errors/errors.go create mode 100644 node/store_badger.go create mode 100644 node/store_badger_test.go create mode 100644 node/store_memory.go diff --git a/cli/server_dump.go b/cli/server_dump.go index 9008c81730..d92a52e205 100644 --- a/cli/server_dump.go +++ b/cli/server_dump.go @@ -31,7 +31,7 @@ func MakeServerDumpCmd() *cobra.Command { return errors.New("server-side dump is only supported for the Badger datastore") } storeOpts := []node.StoreOpt{ - node.WithPath(cfg.GetString("datastore.badger.path")), + node.WithStorePath(cfg.GetString("datastore.badger.path")), } rootstore, err := node.NewStore(cmd.Context(), storeOpts...) if err != nil { diff --git a/cli/start.go b/cli/start.go index 970b857aa0..7e1966253c 100644 --- a/cli/start.go +++ b/cli/start.go @@ -57,8 +57,8 @@ func MakeStartCommand() *cobra.Command { } opts := []node.Option{ - node.WithPath(cfg.GetString("datastore.badger.path")), - node.WithInMemory(cfg.GetString("datastore.store") == configStoreMemory), + node.WithStorePath(cfg.GetString("datastore.badger.path")), + node.WithBadgerInMemory(cfg.GetString("datastore.store") == configStoreMemory), node.WithDisableP2P(cfg.GetBool("net.p2pDisabled")), node.WithACPType(node.LocalACPType), node.WithPeers(peers...), @@ -100,7 +100,7 @@ func MakeStartCommand() *cobra.Command { if err != nil && !errors.Is(err, keyring.ErrNotFound) { return err } - opts = append(opts, node.WithEncryptionKey(encryptionKey)) + opts = append(opts, node.WithBadgerEncryptionKey(encryptionKey)) } n, err := node.NewNode(cmd.Context(), opts...) diff --git a/datastore/badger/v4/datastore.go b/datastore/badger/v4/datastore.go index 14b841867f..caac4144a2 100644 --- a/datastore/badger/v4/datastore.go +++ b/datastore/badger/v4/datastore.go @@ -24,11 +24,6 @@ import ( var log = logger.Logger("badger") -var ( - ErrClosed = errors.New("datastore closed") - ErrTxnConflict = badger.ErrConflict -) - type Datastore struct { DB *badger.DB @@ -767,7 +762,8 @@ func (t *txn) Commit(ctx context.Context) error { } func (t *txn) commit() error { - return t.txn.Commit() + err := t.txn.Commit() + return convertError(err) } func (t *txn) Discard(ctx context.Context) { diff --git a/datastore/badger/v4/errors.go b/datastore/badger/v4/errors.go index ea78ae8b72..4a8a8d702f 100644 --- a/datastore/badger/v4/errors.go +++ b/datastore/badger/v4/errors.go @@ -12,12 +12,39 @@ package badger import ( dsq "github.com/ipfs/go-datastore/query" + badger "github.com/sourcenetwork/badger/v4" + datastoreErrors "github.com/sourcenetwork/defradb/datastore/errors" "github.com/sourcenetwork/defradb/errors" ) +var ( + ErrClosed = datastoreErrors.ErrClosed + ErrTxnConflict = datastoreErrors.ErrTxnConflict +) + const errOrderType string = "invalid order type" func ErrOrderType(orderType dsq.Order) error { return errors.New(errOrderType, errors.NewKV("Order type", orderType)) } + +// convertError converts badger specific errors into datastore errors. +func convertError(err error) error { + // The errors we are matching against are never wrapped. + // + //nolint:errorlint + switch err { + case badger.ErrConflict: + return datastoreErrors.ErrTxnConflict + + case badger.ErrReadOnlyTxn: + return datastoreErrors.ErrReadOnlyTxn + + case badger.ErrDiscardedTxn: + return datastoreErrors.ErrTxnDiscarded + + default: + return err + } +} diff --git a/datastore/blockstore_test.go b/datastore/blockstore_test.go index 29daffcc76..f3e3086893 100644 --- a/datastore/blockstore_test.go +++ b/datastore/blockstore_test.go @@ -91,7 +91,7 @@ func TestBStoreGetWithStoreClosed(t *testing.T) { require.NoError(t, err) _, err = bs.Get(ctx, cID) - require.ErrorIs(t, err, memory.ErrClosed) + require.ErrorIs(t, err, ErrClosed) } func TestBStoreGetWithReHash(t *testing.T) { @@ -190,5 +190,5 @@ func TestPutManyWithStoreClosed(t *testing.T) { require.NoError(t, err) err = bs.PutMany(ctx, []blocks.Block{b, b2}) - require.ErrorIs(t, err, memory.ErrClosed) + require.ErrorIs(t, err, ErrClosed) } diff --git a/datastore/concurrent_txt_test.go b/datastore/concurrent_txt_test.go index 1a1b43bbab..10fd5e278a 100644 --- a/datastore/concurrent_txt_test.go +++ b/datastore/concurrent_txt_test.go @@ -45,7 +45,7 @@ func TestNewConcurrentTxnFromWithStoreClosed(t *testing.T) { require.NoError(t, err) _, err = NewConcurrentTxnFrom(ctx, rootstore, 0, false) - require.ErrorIs(t, err, badgerds.ErrClosed) + require.ErrorIs(t, err, ErrClosed) } func TestNewConcurrentTxnFromNonIterable(t *testing.T) { @@ -67,7 +67,7 @@ func TestNewConcurrentTxnFromNonIterableWithStoreClosed(t *testing.T) { require.NoError(t, err) _, err = NewConcurrentTxnFrom(ctx, rootstore, 0, false) - require.ErrorIs(t, err, badgerds.ErrClosed) + require.ErrorIs(t, err, ErrClosed) } func TestConcurrentTxnSync(t *testing.T) { diff --git a/datastore/errors.go b/datastore/errors.go index b248ce6db8..17c1e773cf 100644 --- a/datastore/errors.go +++ b/datastore/errors.go @@ -11,6 +11,7 @@ package datastore import ( + datastoreErrors "github.com/sourcenetwork/defradb/datastore/errors" "github.com/sourcenetwork/defradb/errors" ) @@ -28,7 +29,9 @@ var ( // defradb/store.ErrNotFound => error // ipfs-blockstore.ErrNotFound => error // ErrNotFound is an error returned when a block is not found. - ErrNotFound = errors.New("blockstore: block not found") + ErrNotFound = errors.New("blockstore: block not found") + ErrClosed = datastoreErrors.ErrClosed + ErrTxnConflict = datastoreErrors.ErrTxnConflict ) // NewErrInvalidStoredValue returns a new error indicating that the stored diff --git a/datastore/errors/errors.go b/datastore/errors/errors.go new file mode 100644 index 0000000000..a2c8febbbf --- /dev/null +++ b/datastore/errors/errors.go @@ -0,0 +1,24 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package errors + +import "errors" + +var ( + ErrClosed = errors.New("datastore closed") + // ErrConflict is returned when a transaction conflicts with another transaction. This can + // happen if the read rows had been updated concurrently by another transaction. + ErrTxnConflict = errors.New("transaction Conflict. Please retry") + // ErrDiscardedTxn is returned if a previously discarded transaction is re-used. + ErrTxnDiscarded = errors.New("this transaction has been discarded. Create a new one") + // ErrReadOnlyTxn is returned if an update function is called on a read-only transaction. + ErrReadOnlyTxn = errors.New("no sets or deletes are allowed in a read-only transaction") +) diff --git a/datastore/memory/errors.go b/datastore/memory/errors.go index 5ea7734c60..7d32cd156c 100644 --- a/datastore/memory/errors.go +++ b/datastore/memory/errors.go @@ -10,12 +10,13 @@ package memory -import "github.com/sourcenetwork/defradb/errors" +import ( + "github.com/sourcenetwork/defradb/datastore/errors" +) var ( - ErrReadOnlyTxn = errors.New("read only transaction") - ErrTxnDiscarded = errors.New("transaction discarded") - //nolint:revive - ErrTxnConflict = errors.New("Transaction Conflict. Please retry") - ErrClosed = errors.New("datastore closed") + ErrReadOnlyTxn = errors.ErrReadOnlyTxn + ErrTxnDiscarded = errors.ErrTxnDiscarded + ErrTxnConflict = errors.ErrTxnConflict + ErrClosed = errors.ErrClosed ) diff --git a/datastore/txn_test.go b/datastore/txn_test.go index cf3cdc5c1d..9f2012ad6d 100644 --- a/datastore/txn_test.go +++ b/datastore/txn_test.go @@ -47,7 +47,7 @@ func TestNewTxnFromWithStoreClosed(t *testing.T) { require.NoError(t, err) _, err = NewTxnFrom(ctx, rootstore, 0, false) - require.ErrorIs(t, err, badgerds.ErrClosed) + require.ErrorIs(t, err, ErrClosed) } func TestOnSuccess(t *testing.T) { @@ -107,7 +107,7 @@ func TestOnError(t *testing.T) { require.NoError(t, err) err = txn.Commit(ctx) - require.ErrorIs(t, err, badgerds.ErrClosed) + require.ErrorIs(t, err, ErrClosed) require.Equal(t, text, "Source Inc") } @@ -131,7 +131,7 @@ func TestOnErrorAsync(t *testing.T) { wg.Add(1) err = txn.Commit(ctx) - require.ErrorIs(t, err, badgerds.ErrClosed) + require.ErrorIs(t, err, ErrClosed) wg.Wait() } @@ -252,7 +252,7 @@ func TestMemoryStoreTxn_TwoTransactionsWithGetPutConflict_ShouldErrorWithConflic require.NoError(t, err) err = txn1.Commit(ctx) - require.ErrorIs(t, err, badger.ErrConflict) + require.ErrorIs(t, err, ErrTxnConflict) } func TestMemoryStoreTxn_TwoTransactionsWithHasPutConflict_ShouldErrorWithConflict(t *testing.T) { @@ -281,7 +281,7 @@ func TestMemoryStoreTxn_TwoTransactionsWithHasPutConflict_ShouldErrorWithConflic require.NoError(t, err) err = txn1.Commit(ctx) - require.ErrorIs(t, err, badger.ErrConflict) + require.ErrorIs(t, err, ErrTxnConflict) } func TestBadgerMemoryStoreTxn_TwoTransactionsWithPutConflict_ShouldSucceed(t *testing.T) { @@ -338,7 +338,7 @@ func TestBadgerMemoryStoreTxn_TwoTransactionsWithGetPutConflict_ShouldErrorWithC require.NoError(t, err) err = txn1.Commit(ctx) - require.ErrorIs(t, err, badger.ErrConflict) + require.ErrorIs(t, err, ErrTxnConflict) } func TestBadgerMemoryStoreTxn_TwoTransactionsWithHasPutConflict_ShouldErrorWithConflict(t *testing.T) { @@ -369,7 +369,7 @@ func TestBadgerMemoryStoreTxn_TwoTransactionsWithHasPutConflict_ShouldErrorWithC require.NoError(t, err) err = txn1.Commit(ctx) - require.ErrorIs(t, err, badger.ErrConflict) + require.ErrorIs(t, err, ErrTxnConflict) } func TestBadgerFileStoreTxn_TwoTransactionsWithPutConflict_ShouldSucceed(t *testing.T) { @@ -426,7 +426,7 @@ func TestBadgerFileStoreTxn_TwoTransactionsWithGetPutConflict_ShouldErrorWithCon require.NoError(t, err) err = txn1.Commit(ctx) - require.ErrorIs(t, err, badger.ErrConflict) + require.ErrorIs(t, err, ErrTxnConflict) } func TestBadgerFileStoreTxn_TwoTransactionsWithHasPutConflict_ShouldErrorWithConflict(t *testing.T) { @@ -457,7 +457,7 @@ func TestBadgerFileStoreTxn_TwoTransactionsWithHasPutConflict_ShouldErrorWithCon require.NoError(t, err) err = txn1.Commit(ctx) - require.ErrorIs(t, err, badger.ErrConflict) + require.ErrorIs(t, err, ErrTxnConflict) } func TestMemoryStoreTxn_TwoTransactionsWithQueryAndPut_ShouldOmmitNewPut(t *testing.T) { diff --git a/datastore/wrappedstore_test.go b/datastore/wrappedstore_test.go index a4ca65f4af..f68e7a39a6 100644 --- a/datastore/wrappedstore_test.go +++ b/datastore/wrappedstore_test.go @@ -85,7 +85,7 @@ func TestQueryWithStoreClosed(t *testing.T) { require.NoError(t, err) _, err = dsRW.Query(ctx, query.Query{}) - require.ErrorIs(t, err, badgerds.ErrClosed) + require.ErrorIs(t, err, ErrClosed) } func TestIteratePrefix(t *testing.T) { @@ -118,5 +118,5 @@ func TestIteratePrefixWithStoreClosed(t *testing.T) { require.NoError(t, err) _, err = iter.IteratePrefix(ctx, ds.NewKey("key1"), ds.NewKey("key1")) - require.ErrorIs(t, err, badgerds.ErrClosed) + require.ErrorIs(t, err, ErrClosed) } diff --git a/http/utils.go b/http/utils.go index 81aeac1b05..835382987b 100644 --- a/http/utils.go +++ b/http/utils.go @@ -17,7 +17,7 @@ import ( "net/http" "github.com/sourcenetwork/defradb/client" - "github.com/sourcenetwork/defradb/datastore/badger/v4" + "github.com/sourcenetwork/defradb/datastore" ) func requestJSON(req *http.Request, out any) error { @@ -44,8 +44,8 @@ func parseError(msg any) error { switch msg { case client.ErrDocumentNotFoundOrNotAuthorized.Error(): return client.ErrDocumentNotFoundOrNotAuthorized - case badger.ErrTxnConflict.Error(): - return badger.ErrTxnConflict + case datastore.ErrTxnConflict.Error(): + return datastore.ErrTxnConflict default: return fmt.Errorf("%s", msg) } diff --git a/internal/db/messages.go b/internal/db/messages.go index 1967c0e238..04b81cd210 100644 --- a/internal/db/messages.go +++ b/internal/db/messages.go @@ -16,7 +16,7 @@ import ( "github.com/sourcenetwork/corelog" - "github.com/sourcenetwork/defradb/datastore/badger/v4" + "github.com/sourcenetwork/defradb/datastore" "github.com/sourcenetwork/defradb/errors" "github.com/sourcenetwork/defradb/event" ) @@ -48,7 +48,7 @@ func (db *db) handleMessages(ctx context.Context, sub *event.Subscription) { var err error for i := 0; i < db.MaxTxnRetries(); i++ { err = db.executeMerge(ctx, evt) - if errors.Is(err, badger.ErrTxnConflict) { + if errors.Is(err, datastore.ErrTxnConflict) { continue // retry merge } break // merge success or error diff --git a/node/errors.go b/node/errors.go index d19b53359b..2078915c0a 100644 --- a/node/errors.go +++ b/node/errors.go @@ -16,10 +16,18 @@ import ( const ( errLensRuntimeNotSupported string = "the selected lens runtime is not supported by this build" + errStoreTypeNotSupported string = "the selected store type is not supported by this build" ) -var ErrLensRuntimeNotSupported = errors.New(errLensRuntimeNotSupported) +var ( + ErrLensRuntimeNotSupported = errors.New(errLensRuntimeNotSupported) + ErrStoreTypeNotSupported = errors.New(errStoreTypeNotSupported) +) func NewErrLensRuntimeNotSupported(lens LensRuntimeType) error { return errors.New(errLensRuntimeNotSupported, errors.NewKV("Lens", lens)) } + +func NewErrStoreTypeNotSupported(store StoreType) error { + return errors.New(errStoreTypeNotSupported, errors.NewKV("Store", store)) +} diff --git a/node/store.go b/node/store.go index 1a5b46f8e0..373610b0e1 100644 --- a/node/store.go +++ b/node/store.go @@ -14,90 +14,66 @@ import ( "context" "github.com/sourcenetwork/defradb/datastore" - "github.com/sourcenetwork/defradb/datastore/badger/v4" - "github.com/sourcenetwork/defradb/datastore/memory" ) +type StoreType string + +const ( + // The Go-enum default StoreType. + // + // The actual store type that this resolves to depends on the build target. + DefaultStore StoreType = "" +) + +// storeConstructors is a map of [StoreType]s to store constructors. +// +// Is is populated by the `init` functions in the runtime-specific files - this +// allows it's population to be managed by build flags. +var storeConstructors = map[StoreType]func(ctx context.Context, options *StoreOptions) (datastore.Rootstore, error){} + // StoreOptions contains store configuration values. type StoreOptions struct { - path string - inMemory bool - defraStore bool - valueLogFileSize int64 - encryptionKey []byte + store StoreType + path string + badgerFileSize int64 + badgerEncryptionKey []byte + badgerInMemory bool } // DefaultStoreOptions returns new options with default values. func DefaultStoreOptions() *StoreOptions { return &StoreOptions{ - inMemory: false, - valueLogFileSize: 1 << 30, + badgerInMemory: false, + badgerFileSize: 1 << 30, } } // StoreOpt is a function for setting configuration values. type StoreOpt func(*StoreOptions) -// WithInMemory sets the in memory flag. -func WithInMemory(inMemory bool) StoreOpt { - return func(o *StoreOptions) { - o.inMemory = inMemory - } -} - -// WithDefraStore sets the defra store flag. -// -// Setting this to true will result in the defra node being created with -// the a custom defra implementation of the rootstore instead of badger. -func WithDefraStore(defraStore bool) StoreOpt { +// WithStoreType sets the store type to use. +func WithStoreType(store StoreType) StoreOpt { return func(o *StoreOptions) { - o.defraStore = defraStore + o.store = store } } -// WithPath sets the datastore path. -func WithPath(path string) StoreOpt { +// WithStorePath sets the store path. +func WithStorePath(path string) StoreOpt { return func(o *StoreOptions) { o.path = path } } -// WithValueLogFileSize sets the badger value log file size. -func WithValueLogFileSize(size int64) StoreOpt { - return func(o *StoreOptions) { - o.valueLogFileSize = size - } -} - -// WithEncryptionKey sets the badger encryption key. -func WithEncryptionKey(encryptionKey []byte) StoreOpt { - return func(o *StoreOptions) { - o.encryptionKey = encryptionKey - } -} - // NewStore returns a new store with the given options. func NewStore(ctx context.Context, opts ...StoreOpt) (datastore.Rootstore, error) { options := DefaultStoreOptions() for _, opt := range opts { opt(options) } - - if options.defraStore { - return memory.NewDatastore(ctx), nil + storeConstructor, ok := storeConstructors[options.store] + if ok { + return storeConstructor(ctx, options) } - - badgerOpts := badger.DefaultOptions - badgerOpts.InMemory = options.inMemory - badgerOpts.ValueLogFileSize = options.valueLogFileSize - badgerOpts.EncryptionKey = options.encryptionKey - - if len(options.encryptionKey) > 0 { - // Having a cache improves the performance. - // Otherwise, your reads would be very slow while encryption is enabled. - // https://dgraph.io/docs/badger/get-started/#encryption-mode - badgerOpts.IndexCacheSize = 100 << 20 - } - - return badger.NewDatastore(options.path, &badgerOpts) + return nil, NewErrStoreTypeNotSupported(options.store) } diff --git a/node/store_badger.go b/node/store_badger.go new file mode 100644 index 0000000000..5c252d3607 --- /dev/null +++ b/node/store_badger.go @@ -0,0 +1,64 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +//go:build !js + +package node + +import ( + "context" + + "github.com/sourcenetwork/defradb/datastore" + "github.com/sourcenetwork/defradb/datastore/badger/v4" +) + +// BadgerStore specifies the badger datastore +const BadgerStore = StoreType("badger") + +func init() { + constructor := func(ctx context.Context, options *StoreOptions) (datastore.Rootstore, error) { + badgerOpts := badger.DefaultOptions + badgerOpts.InMemory = options.badgerInMemory + badgerOpts.ValueLogFileSize = options.badgerFileSize + badgerOpts.EncryptionKey = options.badgerEncryptionKey + + if len(options.badgerEncryptionKey) > 0 { + // Having a cache improves the performance. + // Otherwise, your reads would be very slow while encryption is enabled. + // https://dgraph.io/docs/badger/get-started/#encryption-mode + badgerOpts.IndexCacheSize = 100 << 20 + } + + return badger.NewDatastore(options.path, &badgerOpts) + } + storeConstructors[BadgerStore] = constructor + storeConstructors[DefaultStore] = constructor +} + +// WithBadgerInMemory sets the badger in memory option. +func WithBadgerInMemory(enable bool) StoreOpt { + return func(o *StoreOptions) { + o.badgerInMemory = enable + } +} + +// WithBadgerFileSize sets the badger value log file size. +func WithBadgerFileSize(size int64) StoreOpt { + return func(o *StoreOptions) { + o.badgerFileSize = size + } +} + +// WithBadgerEncryptionKey sets the badger encryption key. +func WithBadgerEncryptionKey(encryptionKey []byte) StoreOpt { + return func(o *StoreOptions) { + o.badgerEncryptionKey = encryptionKey + } +} diff --git a/node/store_badger_test.go b/node/store_badger_test.go new file mode 100644 index 0000000000..3278851af3 --- /dev/null +++ b/node/store_badger_test.go @@ -0,0 +1,43 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +//go:build !js + +package node + +import ( + "crypto/rand" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestWithBadgerInMemory(t *testing.T) { + options := &StoreOptions{} + WithBadgerInMemory(true)(options) + assert.Equal(t, true, options.badgerInMemory) +} + +func TestWithBadgerFileSize(t *testing.T) { + options := &StoreOptions{} + WithBadgerFileSize(int64(5 << 30))(options) + assert.Equal(t, int64(5<<30), options.badgerFileSize) +} + +func TestWithBadgerEncryptionKey(t *testing.T) { + encryptionKey := make([]byte, 32) + _, err := rand.Read(encryptionKey) + require.NoError(t, err) + + options := &StoreOptions{} + WithBadgerEncryptionKey(encryptionKey)(options) + assert.Equal(t, encryptionKey, options.badgerEncryptionKey) +} diff --git a/node/store_memory.go b/node/store_memory.go new file mode 100644 index 0000000000..352381fa9d --- /dev/null +++ b/node/store_memory.go @@ -0,0 +1,32 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package node + +import ( + "context" + + "github.com/sourcenetwork/defradb/datastore" + "github.com/sourcenetwork/defradb/datastore/memory" +) + +// MemoryStore specifies the defradb in memory datastore +const MemoryStore = StoreType("memory") + +func init() { + constructor := func(ctx context.Context, options *StoreOptions) (datastore.Rootstore, error) { + return memory.NewDatastore(ctx), nil + } + // don't override the default constructor if previously set + if _, ok := storeConstructors[DefaultStore]; !ok { + storeConstructors[DefaultStore] = constructor + } + storeConstructors[MemoryStore] = constructor +} diff --git a/node/store_test.go b/node/store_test.go index 69ce98e952..3f9185c7ed 100644 --- a/node/store_test.go +++ b/node/store_test.go @@ -11,37 +11,19 @@ package node import ( - "crypto/rand" "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) -func TestWithInMemory(t *testing.T) { +func TestWithStore(t *testing.T) { options := &StoreOptions{} - WithInMemory(true)(options) - assert.Equal(t, true, options.inMemory) + WithStoreType(MemoryStore)(options) + assert.Equal(t, MemoryStore, options.store) } -func TestWithPath(t *testing.T) { +func TestWithStorePath(t *testing.T) { options := &StoreOptions{} - WithPath("tmp")(options) - assert.Equal(t, "tmp", options.path) -} - -func TestWithValueLogFileSize(t *testing.T) { - options := &StoreOptions{} - WithValueLogFileSize(int64(5 << 30))(options) - assert.Equal(t, int64(5<<30), options.valueLogFileSize) -} - -func TestWithEncryptionKey(t *testing.T) { - encryptionKey := make([]byte, 32) - _, err := rand.Read(encryptionKey) - require.NoError(t, err) - - options := &StoreOptions{} - WithEncryptionKey(encryptionKey)(options) - assert.Equal(t, encryptionKey, options.encryptionKey) + WithStorePath("test")(options) + assert.Equal(t, "test", options.path) } diff --git a/tests/integration/db.go b/tests/integration/db.go index dbbbed7ffb..d2ecccf366 100644 --- a/tests/integration/db.go +++ b/tests/integration/db.go @@ -71,7 +71,7 @@ func init() { func NewBadgerMemoryDB(ctx context.Context) (client.DB, error) { opts := []node.Option{ - node.WithInMemory(true), + node.WithBadgerInMemory(true), } node, err := node.NewNode(ctx, opts...) @@ -86,7 +86,7 @@ func NewBadgerFileDB(ctx context.Context, t testing.TB) (client.DB, error) { path := t.TempDir() opts := []node.Option{ - node.WithPath(path), + node.WithStorePath(path), } node, err := node.NewNode(ctx, opts...) @@ -121,13 +121,13 @@ func setupNode(s *state) (*node.Node, string, error) { } if encryptionKey != nil { - opts = append(opts, node.WithEncryptionKey(encryptionKey)) + opts = append(opts, node.WithBadgerEncryptionKey(encryptionKey)) } var path string switch s.dbt { case badgerIMType: - opts = append(opts, node.WithInMemory(true)) + opts = append(opts, node.WithBadgerInMemory(true)) case badgerFileType: switch { @@ -144,10 +144,10 @@ func setupNode(s *state) (*node.Node, string, error) { path = s.t.TempDir() } - opts = append(opts, node.WithPath(path), node.WithACPPath(path)) + opts = append(opts, node.WithStorePath(path), node.WithACPPath(path)) case defraIMType: - opts = append(opts, node.WithDefraStore(true)) + opts = append(opts, node.WithStoreType(node.MemoryStore)) default: return nil, "", fmt.Errorf("invalid database type: %v", s.dbt) diff --git a/tests/integration/mutation/mix/with_txn_test.go b/tests/integration/mutation/mix/with_txn_test.go index b7c193b10b..5354b69eea 100644 --- a/tests/integration/mutation/mix/with_txn_test.go +++ b/tests/integration/mutation/mix/with_txn_test.go @@ -300,7 +300,7 @@ func TestMutationWithTxnDoesNotAllowUpdateInSecondTransactionUser(t *testing.T) }, testUtils.TransactionCommit{ TransactionID: 1, - ExpectedError: "Transaction Conflict. Please retry", + ExpectedError: "transaction Conflict. Please retry", }, testUtils.Request{ // Query after transactions have been commited: diff --git a/tests/integration/utils2.go b/tests/integration/utils2.go index 4ab68930cf..3f6585824d 100644 --- a/tests/integration/utils2.go +++ b/tests/integration/utils2.go @@ -32,7 +32,6 @@ import ( "github.com/sourcenetwork/defradb/client/request" "github.com/sourcenetwork/defradb/crypto" "github.com/sourcenetwork/defradb/datastore" - badgerds "github.com/sourcenetwork/defradb/datastore/badger/v4" "github.com/sourcenetwork/defradb/errors" "github.com/sourcenetwork/defradb/event" "github.com/sourcenetwork/defradb/internal/db" @@ -1692,7 +1691,7 @@ func withRetry( ) error { for i := 0; i < nodes[nodeID].MaxTxnRetries(); i++ { err := action() - if err != nil && errors.Is(err, badgerds.ErrTxnConflict) { + if errors.Is(err, datastore.ErrTxnConflict) { time.Sleep(100 * time.Millisecond) continue } From ff03efedd4a5bf32f4a4960294ad0cfc03a59b40 Mon Sep 17 00:00:00 2001 From: AndrewSisley Date: Mon, 15 Jul 2024 13:12:44 -0400 Subject: [PATCH 12/41] chore: Bump grpc version (#2824) ## Relevant issue(s) Resolves #2823 ## Description Bump grpc version. 1.64 has a security issue --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 8b86029164..1b8ddab16e 100644 --- a/go.mod +++ b/go.mod @@ -57,7 +57,7 @@ require ( go.uber.org/zap v1.27.0 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/term v0.21.0 - google.golang.org/grpc v1.64.0 + google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 ) @@ -115,7 +115,7 @@ require ( github.com/goccy/go-json v0.10.3 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/glog v1.2.0 // indirect + github.com/golang/glog v1.2.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect diff --git a/go.sum b/go.sum index eeb4bf7bdd..f3ab8de70a 100644 --- a/go.sum +++ b/go.sum @@ -227,8 +227,8 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= -github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= +github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -1098,8 +1098,8 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac 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.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= From fe9fae665375e07086aea339935453d8a087f9bd Mon Sep 17 00:00:00 2001 From: AndrewSisley Date: Tue, 16 Jul 2024 19:59:54 -0400 Subject: [PATCH 13/41] feat: Implement SourceHub ACP (#2657) ## Relevant issue(s) Resolves #2836 ## Description Implements SourceHub ACP. Whilst the time out for a single package has been increased, the CI cost of the new jobs remains about the same as when running with `source-hub` acp, the integration test harness will skip all non-acp tests. --- .../workflows/test-and-upload-coverage.yml | 43 + CONTRIBUTING.md | 1 + Makefile | 6 +- acp/README.md | 10 +- acp/acp.go | 7 +- acp/acp_local.go | 14 +- acp/acp_local_test.go | 34 +- acp/acp_source_hub.go | 263 ++++ acp/identity/errors.go | 6 +- acp/identity/generate.go | 16 +- acp/identity/identity.go | 115 +- acp/source_hub_client.go | 41 +- cli/config.go | 43 +- cli/root.go | 5 + cli/start.go | 21 +- cli/utils.go | 26 +- docs/config.md | 32 + docs/website/references/cli/defradb.md | 29 +- docs/website/references/cli/defradb_client.md | 27 +- .../references/cli/defradb_client_acp.md | 31 +- .../cli/defradb_client_acp_policy.md | 31 +- .../cli/defradb_client_acp_policy_add.md | 31 +- .../references/cli/defradb_client_backup.md | 31 +- .../cli/defradb_client_backup_export.md | 31 +- .../cli/defradb_client_backup_import.md | 31 +- .../cli/defradb_client_collection.md | 27 +- .../cli/defradb_client_collection_create.md | 39 +- .../cli/defradb_client_collection_delete.md | 39 +- .../cli/defradb_client_collection_describe.md | 31 +- .../cli/defradb_client_collection_docIDs.md | 39 +- .../cli/defradb_client_collection_get.md | 39 +- .../cli/defradb_client_collection_patch.md | 39 +- .../cli/defradb_client_collection_update.md | 39 +- .../references/cli/defradb_client_dump.md | 31 +- .../references/cli/defradb_client_index.md | 31 +- .../cli/defradb_client_index_create.md | 31 +- .../cli/defradb_client_index_drop.md | 31 +- .../cli/defradb_client_index_list.md | 31 +- .../references/cli/defradb_client_p2p.md | 31 +- .../cli/defradb_client_p2p_collection.md | 31 +- .../cli/defradb_client_p2p_collection_add.md | 31 +- .../defradb_client_p2p_collection_getall.md | 31 +- .../defradb_client_p2p_collection_remove.md | 31 +- .../references/cli/defradb_client_p2p_info.md | 31 +- .../cli/defradb_client_p2p_replicator.md | 31 +- .../defradb_client_p2p_replicator_delete.md | 31 +- .../defradb_client_p2p_replicator_getall.md | 31 +- .../cli/defradb_client_p2p_replicator_set.md | 31 +- .../references/cli/defradb_client_query.md | 31 +- .../references/cli/defradb_client_schema.md | 31 +- .../cli/defradb_client_schema_add.md | 31 +- .../cli/defradb_client_schema_describe.md | 31 +- .../cli/defradb_client_schema_migration.md | 31 +- .../defradb_client_schema_migration_down.md | 31 +- .../defradb_client_schema_migration_reload.md | 31 +- ...db_client_schema_migration_set-registry.md | 31 +- .../defradb_client_schema_migration_set.md | 31 +- .../cli/defradb_client_schema_migration_up.md | 31 +- .../cli/defradb_client_schema_patch.md | 31 +- .../cli/defradb_client_schema_set-active.md | 31 +- .../references/cli/defradb_client_tx.md | 31 +- .../cli/defradb_client_tx_commit.md | 31 +- .../cli/defradb_client_tx_create.md | 31 +- .../cli/defradb_client_tx_discard.md | 31 +- .../references/cli/defradb_client_view.md | 31 +- .../references/cli/defradb_client_view_add.md | 31 +- .../references/cli/defradb_identity.md | 27 +- .../references/cli/defradb_identity_new.md | 27 +- .../website/references/cli/defradb_keyring.md | 27 +- .../references/cli/defradb_keyring_export.md | 27 +- .../cli/defradb_keyring_generate.md | 27 +- .../references/cli/defradb_keyring_import.md | 27 +- .../references/cli/defradb_server-dump.md | 27 +- docs/website/references/cli/defradb_start.md | 27 +- .../website/references/cli/defradb_version.md | 27 +- go.mod | 99 +- go.sum | 1147 ++++++++++++++++- http/auth.go | 79 +- http/auth_test.go | 127 +- http/http_client.go | 10 +- internal/db/db.go | 2 +- internal/db/p2p_schema_root_test.go | 10 +- internal/db/permission/register.go | 2 +- keyring/signer.go | 66 + node/acp.go | 65 +- node/errors.go | 5 +- tests/change_detector/change_detector_test.go | 15 +- tests/clients/cli/wrapper.go | 11 +- tests/clients/cli/wrapper_cli.go | 9 +- tests/clients/http/wrapper.go | 4 + tests/integration/acp.go | 384 +++++- .../acp/add_policy/with_no_resources_test.go | 7 +- tests/integration/client.go | 2 +- tests/integration/db.go | 19 + tests/integration/state.go | 6 +- tests/integration/test_case.go | 7 + tests/integration/utils2.go | 56 +- 97 files changed, 3439 insertions(+), 1176 deletions(-) create mode 100644 acp/acp_source_hub.go create mode 100644 keyring/signer.go diff --git a/.github/workflows/test-and-upload-coverage.yml b/.github/workflows/test-and-upload-coverage.yml index 392cef826b..9a8aef76fc 100644 --- a/.github/workflows/test-and-upload-coverage.yml +++ b/.github/workflows/test-and-upload-coverage.yml @@ -35,6 +35,7 @@ jobs: database-type: [badger-file, badger-memory] mutation-type: [gql, collection-named, collection-save] lens-type: [wasm-time] + acp-type: [local] database-encryption: [false] include: - os: ubuntu-latest @@ -42,24 +43,49 @@ jobs: database-type: badger-memory mutation-type: collection-save lens-type: wasm-time + acp-type: local database-encryption: true - os: ubuntu-latest client-type: go database-type: badger-memory mutation-type: collection-save lens-type: wazero + acp-type: local database-encryption: false - os: ubuntu-latest client-type: go database-type: badger-memory mutation-type: collection-save lens-type: wasmer + acp-type: local + database-encryption: false + - os: ubuntu-latest + client-type: go + database-type: badger-memory + mutation-type: collection-save + lens-type: wasm-time + acp-type: source-hub + database-encryption: false + - os: ubuntu-latest + client-type: http + database-type: badger-memory + mutation-type: collection-save + lens-type: wasm-time + acp-type: source-hub + database-encryption: false + - os: ubuntu-latest + client-type: cli + database-type: badger-memory + mutation-type: collection-save + lens-type: wasm-time + acp-type: source-hub database-encryption: false - os: macos-latest client-type: go database-type: badger-memory mutation-type: collection-save lens-type: wasm-time + acp-type: local database-encryption: false ## TODO: https://github.com/sourcenetwork/defradb/issues/2080 ## Uncomment the lines below to Re-enable the windows build once this todo is resolved. @@ -68,6 +94,7 @@ jobs: ## database-type: badger-memory ## mutation-type: collection-save ## lens-type: wasm-time +## acp-type: local ## database-encryption: false runs-on: ${{ matrix.os }} @@ -87,6 +114,7 @@ jobs: DEFRA_BADGER_ENCRYPTION: ${{ matrix.database-encryption }} DEFRA_MUTATION_TYPE: ${{ matrix.mutation-type }} DEFRA_LENS_TYPE: ${{ matrix.lens-type }} + DEFRA_ACP_TYPE: ${{ matrix.acp-type }} steps: - name: Checkout code into the directory @@ -143,6 +171,20 @@ jobs: make deps:modules make deps:test + # We have to checkout the source-hub repo and install it ourselves because it + # contains replace commands in its go.mod file. + - name: Checkout sourcehub code into the directory + if: ${{ matrix.acp-type == 'source-hub' }} + uses: actions/checkout@v4 + with: + repository: sourcenetwork/sourcehub + path: _sourceHub + + - name: Install SourceHub CLI + if: ${{ matrix.acp-type == 'source-hub' }} + working-directory: _sourceHub + run: make install + - name: Run integration tests run: make test:coverage @@ -158,6 +200,7 @@ jobs: _${{ matrix.database-type }}\ _${{ matrix.mutation-type }}\ _${{ matrix.lens-type }}\ + _${{ matrix.acp-type }}\ _${{ matrix.database-encryption }}\ " path: coverage.txt diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c590fa54f4..e63fc6afe4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -61,6 +61,7 @@ The following tools are required in order to build and run the tests within this - [Go](https://go.dev/doc/install) - Cargo/rustc, typically installed via [rustup](https://www.rust-lang.org/tools/install) +- [SourceHub](https://github.com/sourcenetwork/sourcehub), installed via `make install` ## Documentation The overall project documentation can be found at [docs.source.network](https://docs.source.network), and its source at [github.com/sourcenetwork/docs.source.network](https://github.com/sourcenetwork/docs.source.network). diff --git a/Makefile b/Makefile index efa4748d40..3f2b95dd4d 100644 --- a/Makefile +++ b/Makefile @@ -65,7 +65,7 @@ ifdef BUILD_TAGS BUILD_FLAGS+=-tags $(BUILD_TAGS) endif -TEST_FLAGS=-race -shuffle=on -timeout 5m +TEST_FLAGS=-race -shuffle=on -timeout 10m COVERAGE_DIRECTORY=$(PWD)/coverage COVERAGE_FILE=coverage.txt @@ -256,6 +256,10 @@ test\:gql-mutations: test\:col-named-mutations: DEFRA_MUTATION_TYPE=collection-named DEFRA_BADGER_MEMORY=true gotestsum --format pkgname -- $(DEFAULT_TEST_DIRECTORIES) +.PHONY: test\:source-hub +test\:source-hub: + DEFRA_ACP_TYPE=source-hub gotestsum --format pkgname -- $(DEFAULT_TEST_DIRECTORIES) + .PHONY: test\:go test\:go: go test $(DEFAULT_TEST_DIRECTORIES) $(TEST_FLAGS) diff --git a/acp/README.md b/acp/README.md index 29244103fa..58adfc3997 100644 --- a/acp/README.md +++ b/acp/README.md @@ -436,8 +436,14 @@ To perform authenticated operations you will need to build and sign a JWT token - `sub` public key of the identity - `aud` host name of the defradb api - -> The `exp` and `nbf` fields should also be set to short-lived durations. +- The `exp` and `nbf` fields should also be set to short-lived durations. + +Additionally, if using SourceHub ACP, the following must be set: +- `iss` should be set to the user's DID, e.g. `"did:key:z6MkkHsQbp3tXECqmUJoCJwyuxSKn1BDF1RHzwDGg9tHbXKw"` +- `iat` should be set to the current unix timestamp +- `authorized_account` should be set to the SourceHub address of the account signing SourceHub transactions on your + behalf - WARNING - this will currently enable this account to make any SourceHub as your user for the lifetime of the + token, so please only set this if you fully trust the node/account. The JWT must be signed with the `secp256k1` private key of the identity you wish to perform actions as. diff --git a/acp/acp.go b/acp/acp.go index af99bcb86f..4635e46f4f 100644 --- a/acp/acp.go +++ b/acp/acp.go @@ -13,9 +13,10 @@ package acp import ( "context" + "github.com/sourcenetwork/corelog" "github.com/sourcenetwork/immutable" - "github.com/sourcenetwork/corelog" + "github.com/sourcenetwork/defradb/acp/identity" ) var ( @@ -47,7 +48,7 @@ type ACP interface { // otherwise returns error. // // A policy can not be added without a creator identity (sourcehub address). - AddPolicy(ctx context.Context, creatorID string, policy string) (string, error) + AddPolicy(ctx context.Context, creator identity.Identity, policy string) (string, error) // ValidateResourceExistsOnValidDPI performs DPI validation of the resource (matching resource name) // that is on the policy (matching policyID), returns an error upon validation failure. @@ -68,7 +69,7 @@ type ACP interface { // - actorID here is the identity of the actor registering the document object. RegisterDocObject( ctx context.Context, - actorID string, + indentity identity.Identity, policyID string, resourceName string, docID string, diff --git a/acp/acp_local.go b/acp/acp_local.go index b62c4a454c..97e7a67cce 100644 --- a/acp/acp_local.go +++ b/acp/acp_local.go @@ -20,6 +20,8 @@ import ( "github.com/sourcenetwork/acp_core/pkg/runtime" "github.com/sourcenetwork/acp_core/pkg/types" "github.com/sourcenetwork/immutable" + + "github.com/sourcenetwork/defradb/acp/identity" ) const localACPStoreName = "local_acp" @@ -105,14 +107,14 @@ func (l *ACPLocal) Close() error { func (l *ACPLocal) AddPolicy( ctx context.Context, - creatorID string, + creator identity.Identity, policy string, marshalType policyMarshalType, creationTime *protoTypes.Timestamp, ) (string, error) { - principal, err := auth.NewDIDPrincipal(creatorID) + principal, err := auth.NewDIDPrincipal(creator.DID) if err != nil { - return "", newErrInvalidActorID(err, creatorID) + return "", newErrInvalidActorID(err, creator.DID) } ctx = auth.InjectPrincipal(ctx, principal) @@ -152,15 +154,15 @@ func (l *ACPLocal) Policy( func (l *ACPLocal) RegisterObject( ctx context.Context, - actorID string, + identity identity.Identity, policyID string, resourceName string, objectID string, creationTime *protoTypes.Timestamp, ) (RegistrationResult, error) { - principal, err := auth.NewDIDPrincipal(actorID) + principal, err := auth.NewDIDPrincipal(identity.DID) if err != nil { - return RegistrationResult_NoOp, newErrInvalidActorID(err, actorID) + return RegistrationResult_NoOp, newErrInvalidActorID(err, identity.DID) } ctx = auth.InjectPrincipal(ctx, principal) diff --git a/acp/acp_local_test.go b/acp/acp_local_test.go index ac024d73c6..9dbf0b36e8 100644 --- a/acp/acp_local_test.go +++ b/acp/acp_local_test.go @@ -15,11 +15,19 @@ import ( "testing" "github.com/stretchr/testify/require" + + "github.com/sourcenetwork/defradb/acp/identity" ) -var identity1 = "did:key:z7r8os2G88XXBNBTLj3kFR5rzUJ4VAesbX7PgsA68ak9B5RYcXF5EZEmjRzzinZndPSSwujXb4XKHG6vmKEFG6ZfsfcQn" -var identity2 = "did:key:z7r8ooUiNXK8TT8Xjg1EWStR2ZdfxbzVfvGWbA2FjmzcnmDxz71QkP1Er8PP3zyLZpBLVgaXbZPGJPS4ppXJDPRcqrx4F" -var invalidIdentity = "did:something" +var identity1 = identity.Identity{ + DID: "did:key:z7r8os2G88XXBNBTLj3kFR5rzUJ4VAesbX7PgsA68ak9B5RYcXF5EZEmjRzzinZndPSSwujXb4XKHG6vmKEFG6ZfsfcQn", +} +var identity2 = identity.Identity{ + DID: "did:key:z7r8ooUiNXK8TT8Xjg1EWStR2ZdfxbzVfvGWbA2FjmzcnmDxz71QkP1Er8PP3zyLZpBLVgaXbZPGJPS4ppXJDPRcqrx4F", +} +var invalidIdentity = identity.Identity{ + DID: "did:something", +} var validPolicyID string = "d59f91ba65fe142d35fc7df34482eafc7e99fed7c144961ba32c4664634e61b7" var validPolicy string = ` @@ -478,7 +486,7 @@ func Test_LocalACP_InMemory_CheckDocAccess_TrueIfHaveAccessFalseIfNotErrorOtherw hasAccess, errCheckDocAccess := localACP.CheckDocAccess( ctx, ReadPermission, - identity1, + identity1.DID, validPolicyID, "", "", @@ -491,7 +499,7 @@ func Test_LocalACP_InMemory_CheckDocAccess_TrueIfHaveAccessFalseIfNotErrorOtherw hasAccess, errCheckDocAccess = localACP.CheckDocAccess( ctx, ReadPermission, - identity1, + identity1.DID, validPolicyID, "users", "documentID_XYZ", @@ -513,7 +521,7 @@ func Test_LocalACP_InMemory_CheckDocAccess_TrueIfHaveAccessFalseIfNotErrorOtherw hasAccess, errCheckDocAccess = localACP.CheckDocAccess( ctx, ReadPermission, - identity1, + identity1.DID, validPolicyID, "users", "documentID_XYZ", @@ -525,7 +533,7 @@ func Test_LocalACP_InMemory_CheckDocAccess_TrueIfHaveAccessFalseIfNotErrorOtherw hasAccess, errCheckDocAccess = localACP.CheckDocAccess( ctx, ReadPermission, - identity2, + identity2.DID, validPolicyID, "users", "documentID_XYZ", @@ -564,7 +572,7 @@ func Test_LocalACP_PersistentMemory_CheckDocAccess_TrueIfHaveAccessFalseIfNotErr hasAccess, errCheckDocAccess := localACP.CheckDocAccess( ctx, ReadPermission, - identity1, + identity1.DID, validPolicyID, "", "", @@ -577,7 +585,7 @@ func Test_LocalACP_PersistentMemory_CheckDocAccess_TrueIfHaveAccessFalseIfNotErr hasAccess, errCheckDocAccess = localACP.CheckDocAccess( ctx, ReadPermission, - identity1, + identity1.DID, validPolicyID, "users", "documentID_XYZ", @@ -599,7 +607,7 @@ func Test_LocalACP_PersistentMemory_CheckDocAccess_TrueIfHaveAccessFalseIfNotErr hasAccess, errCheckDocAccess = localACP.CheckDocAccess( ctx, ReadPermission, - identity1, + identity1.DID, validPolicyID, "users", "documentID_XYZ", @@ -611,7 +619,7 @@ func Test_LocalACP_PersistentMemory_CheckDocAccess_TrueIfHaveAccessFalseIfNotErr hasAccess, errCheckDocAccess = localACP.CheckDocAccess( ctx, ReadPermission, - identity2, + identity2.DID, validPolicyID, "users", "documentID_XYZ", @@ -631,7 +639,7 @@ func Test_LocalACP_PersistentMemory_CheckDocAccess_TrueIfHaveAccessFalseIfNotErr hasAccess, errCheckDocAccess = localACP.CheckDocAccess( ctx, ReadPermission, - identity1, + identity1.DID, validPolicyID, "users", "documentID_XYZ", @@ -643,7 +651,7 @@ func Test_LocalACP_PersistentMemory_CheckDocAccess_TrueIfHaveAccessFalseIfNotErr hasAccess, errCheckDocAccess = localACP.CheckDocAccess( ctx, ReadPermission, - identity2, + identity2.DID, validPolicyID, "users", "documentID_XYZ", diff --git a/acp/acp_source_hub.go b/acp/acp_source_hub.go new file mode 100644 index 0000000000..4dfb26c090 --- /dev/null +++ b/acp/acp_source_hub.go @@ -0,0 +1,263 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package acp + +import ( + "context" + "strings" + + protoTypes "github.com/cosmos/gogoproto/types" + "github.com/sourcenetwork/immutable" + sourcehub "github.com/sourcenetwork/sourcehub/sdk" + acptypes "github.com/sourcenetwork/sourcehub/x/acp/types" + + "github.com/sourcenetwork/defradb/acp/identity" +) + +type acpSourceHub struct { + client *sourcehub.Client + txBuilder *sourcehub.TxBuilder + signer sourcehub.TxSigner +} + +var _ sourceHubClient = (*acpSourceHub)(nil) + +func NewACPSourceHub( + chainID string, + grpcAddress string, + cometRPCAddress string, + signer sourcehub.TxSigner, +) (*acpSourceHub, error) { + client, err := sourcehub.NewClient( + sourcehub.WithGRPCAddr(grpcAddress), + sourcehub.WithCometRPCAddr(cometRPCAddress), + ) + if err != nil { + return nil, err + } + + txBuilder, err := sourcehub.NewTxBuilder( + sourcehub.WithSDKClient(client), + sourcehub.WithChainID(chainID), + ) + if err != nil { + return nil, err + } + + return &acpSourceHub{ + client: client, + txBuilder: &txBuilder, + signer: signer, + }, nil +} + +func (a *acpSourceHub) Init(ctx context.Context, path string) { + // no-op +} + +func (a *acpSourceHub) Start(ctx context.Context) error { + return nil +} + +func (a *acpSourceHub) AddPolicy( + ctx context.Context, + creator identity.Identity, + policy string, + policyMarshalType policyMarshalType, + creationTime *protoTypes.Timestamp, +) (string, error) { + msgSet := sourcehub.MsgSet{} + policyMapper := msgSet.WithCreatePolicy( + acptypes.NewMsgCreatePolicyNow(a.signer.GetAccAddress(), policy, acptypes.PolicyMarshalingType(policyMarshalType)), + ) + tx, err := a.txBuilder.Build(ctx, a.signer, &msgSet) + if err != nil { + return "", err + } + + resp, err := a.client.BroadcastTx(ctx, tx) + if err != nil { + return "", err + } + + result, err := a.client.AwaitTx(ctx, resp.TxHash) + if err != nil { + return "", err + } + if result.Error() != nil { + return "", result.Error() + } + + policyResponse, err := policyMapper.Map(result.TxPayload()) + if err != nil { + return "", err + } + + return policyResponse.Policy.Id, nil +} + +func (a *acpSourceHub) Policy( + ctx context.Context, + policyID string, +) (immutable.Option[policy], error) { + response, err := a.client.ACPQueryClient().Policy( + ctx, + &acptypes.QueryPolicyRequest{Id: policyID}, + ) + if err != nil { + // todo: https://github.com/sourcenetwork/defradb/issues/2826 + // Sourcehub errors do not currently work with errors.Is, errors.Is + // should be used here instead of strings.Contains when that is fixed. + if strings.Contains(err.Error(), acptypes.ErrPolicyNotFound.Error()) { + return immutable.None[policy](), nil + } + + return immutable.None[policy](), err + } + + return immutable.Some( + fromSourceHubPolicy(response.Policy), + ), nil +} + +func fromSourceHubPolicy(pol *acptypes.Policy) policy { + resources := make(map[string]*resource) + for _, coreResource := range pol.Resources { + resource := fromSourceHubResource(coreResource) + resources[resource.Name] = resource + } + + return policy{ + ID: pol.Id, + Resources: resources, + } +} + +func fromSourceHubResource(policy *acptypes.Resource) *resource { + perms := make(map[string]*permission) + for _, corePermission := range policy.Permissions { + perm := fromSourceHubPermission(corePermission) + perms[perm.Name] = perm + } + + return &resource{ + Name: policy.Name, + Permissions: perms, + } +} + +func fromSourceHubPermission(perm *acptypes.Permission) *permission { + return &permission{ + Name: perm.Name, + Expression: perm.Expression, + } +} + +func (a *acpSourceHub) RegisterObject( + ctx context.Context, + identity identity.Identity, + policyID string, + resourceName string, + objectID string, + creationTime *protoTypes.Timestamp, +) (RegistrationResult, error) { + msgSet := sourcehub.MsgSet{} + cmdMapper := msgSet.WithBearerPolicyCmd(&acptypes.MsgBearerPolicyCmd{ + Creator: a.signer.GetAccAddress(), + BearerToken: identity.BearerToken, + PolicyId: policyID, + Cmd: acptypes.NewRegisterObjectCmd(acptypes.NewObject(resourceName, objectID)), + CreationTime: creationTime, + }) + tx, err := a.txBuilder.Build(ctx, a.signer, &msgSet) + if err != nil { + return 0, err + } + resp, err := a.client.BroadcastTx(ctx, tx) + if err != nil { + return 0, err + } + + result, err := a.client.AwaitTx(ctx, resp.TxHash) + if err != nil { + return 0, err + } + if result.Error() != nil { + return 0, result.Error() + } + + cmdResult, err := cmdMapper.Map(result.TxPayload()) + if err != nil { + return 0, err + } + + return RegistrationResult(cmdResult.GetResult().GetRegisterObjectResult().Result), nil +} + +func (a *acpSourceHub) ObjectOwner( + ctx context.Context, + policyID string, + resourceName string, + objectID string, +) (immutable.Option[string], error) { + owner, err := a.client.ACPQueryClient().ObjectOwner( + ctx, + &acptypes.QueryObjectOwnerRequest{ + PolicyId: policyID, + Object: acptypes.NewObject(resourceName, objectID), + }, + ) + if err != nil { + return immutable.None[string](), err + } + + if owner.OwnerId == "" { + return immutable.None[string](), nil + } + + return immutable.Some(owner.OwnerId), nil +} + +func (a *acpSourceHub) VerifyAccessRequest( + ctx context.Context, + permission DPIPermission, + actorID string, + policyID string, + resourceName string, + docID string, +) (bool, error) { + checkDocResponse, err := a.client.ACPQueryClient().VerifyAccessRequest( + ctx, + &acptypes.QueryVerifyAccessRequestRequest{ + PolicyId: policyID, + AccessRequest: &acptypes.AccessRequest{ + Operations: []*acptypes.Operation{ + { + Object: acptypes.NewObject(resourceName, docID), + Permission: permission.String(), + }, + }, + Actor: &acptypes.Actor{ + Id: actorID, + }, + }, + }, + ) + if err != nil { + return false, err + } + + return checkDocResponse.Valid, nil +} + +func (a *acpSourceHub) Close() error { + return nil +} diff --git a/acp/identity/errors.go b/acp/identity/errors.go index 3ad815b8bb..889f457d8d 100644 --- a/acp/identity/errors.go +++ b/acp/identity/errors.go @@ -17,13 +17,11 @@ import ( ) const ( - errDIDCreation = "could not produce did for key" - errFailedToGenerateIdentityFromPrivateKey = "failed to generate identity from private key" + errDIDCreation = "could not produce did for key" ) var ( - ErrDIDCreation = errors.New(errDIDCreation) - ErrFailedToGenerateIdentityFromPrivateKey = errors.New(errFailedToGenerateIdentityFromPrivateKey) + ErrDIDCreation = errors.New(errDIDCreation) ) func newErrDIDCreation(inner error, keytype string, pubKey []byte) error { diff --git a/acp/identity/generate.go b/acp/identity/generate.go index cf37ce6e46..d19ee6b2cb 100644 --- a/acp/identity/generate.go +++ b/acp/identity/generate.go @@ -36,20 +36,16 @@ func Generate() (RawIdentity, error) { return RawIdentity{}, err } - maybeNewIdentity, err := FromPrivateKey(privateKey) + publicKey := privateKey.PubKey() + + did, err := DIDFromPublicKey(publicKey) if err != nil { return RawIdentity{}, err } - if !maybeNewIdentity.HasValue() { - return RawIdentity{}, ErrFailedToGenerateIdentityFromPrivateKey - } - - newIdentity := maybeNewIdentity.Value() - return RawIdentity{ - PrivateKey: hex.EncodeToString(newIdentity.PrivateKey.Serialize()), - PublicKey: hex.EncodeToString(newIdentity.PublicKey.SerializeCompressed()), - DID: newIdentity.DID, + PrivateKey: hex.EncodeToString(privateKey.Serialize()), + PublicKey: hex.EncodeToString(publicKey.SerializeCompressed()), + DID: did, }, nil } diff --git a/acp/identity/identity.go b/acp/identity/identity.go index 8d9a84c23b..db022b8c74 100644 --- a/acp/identity/identity.go +++ b/acp/identity/identity.go @@ -11,10 +11,16 @@ package identity import ( + "encoding/hex" + "time" + "github.com/cyware/ssi-sdk/crypto" "github.com/cyware/ssi-sdk/did/key" "github.com/decred/dcrd/dcrec/secp256k1/v4" + "github.com/lestrrat-go/jwx/v2/jwa" + "github.com/lestrrat-go/jwx/v2/jwt" "github.com/sourcenetwork/immutable" + acptypes "github.com/sourcenetwork/sourcehub/x/acp/bearer_token" ) // didProducer generates a did:key from a public key @@ -23,6 +29,10 @@ type didProducer = func(crypto.KeyType, []byte) (*key.DIDKey, error) // None specifies an anonymous actor. var None = immutable.None[Identity]() +// BearerTokenSignatureScheme is the signature algorithm used to sign the +// Identity.BearerToken. +const BearerTokenSignatureScheme = jwa.ES256K + // Identity describes a unique actor. type Identity struct { // PublicKey is the actor's public key. @@ -34,33 +44,104 @@ type Identity struct { // The address is derived from the actor's public key, // using the did:key method DID string + + // BearerToken is the signed bearer token that represents this identity. + BearerToken string } // FromPrivateKey returns a new identity using the given private key. -func FromPrivateKey(privateKey *secp256k1.PrivateKey) (immutable.Option[Identity], error) { - pubKey := privateKey.PubKey() - did, err := DIDFromPublicKey(pubKey) +// +// - duration: The [time.Duration] that this identity is valid for. +// - audience: The audience that this identity is valid for. This is required +// by the Defra http client. For example `github.com/sourcenetwork/defradb` +// - authorizedAccount: An account that this identity is authorizing to make +// SourceHub calls on behalf of this actor. This is currently required when +// using SourceHub ACP. +// - skipTokenGeneration: If true, BearerToken will not be set. This parameter is +// provided as generating and signing the token is relatively slow, and only required +// by remote Defra clients (CLI, http), or if using SourceHub ACP. +func FromPrivateKey( + privateKey *secp256k1.PrivateKey, + duration time.Duration, + audience immutable.Option[string], + authorizedAccount immutable.Option[string], + skipTokenGeneration bool, +) (Identity, error) { + publicKey := privateKey.PubKey() + did, err := DIDFromPublicKey(publicKey) if err != nil { - return None, err + return Identity{}, err + } + + var signedToken []byte + if !skipTokenGeneration { + subject := hex.EncodeToString(publicKey.SerializeCompressed()) + now := time.Now() + + jwtBuilder := jwt.NewBuilder() + jwtBuilder = jwtBuilder.Subject(subject) + jwtBuilder = jwtBuilder.Expiration(now.Add(duration)) + jwtBuilder = jwtBuilder.NotBefore(now) + jwtBuilder = jwtBuilder.Issuer(did) + jwtBuilder = jwtBuilder.IssuedAt(now) + + if audience.HasValue() { + jwtBuilder = jwtBuilder.Audience([]string{audience.Value()}) + } + + token, err := jwtBuilder.Build() + if err != nil { + return Identity{}, err + } + + if authorizedAccount.HasValue() { + err = token.Set(acptypes.AuthorizedAccountClaim, authorizedAccount.Value()) + if err != nil { + return Identity{}, err + } + } + + signedToken, err = jwt.Sign(token, jwt.WithKey(BearerTokenSignatureScheme, privateKey.ToECDSA())) + if err != nil { + return Identity{}, err + } } - return immutable.Some(Identity{ - DID: did, - PublicKey: pubKey, - PrivateKey: privateKey, - }), nil + return Identity{ + DID: did, + PrivateKey: privateKey, + PublicKey: publicKey, + BearerToken: string(signedToken), + }, nil } -// FromPublicKey returns a new identity using the given public key. -func FromPublicKey(publicKey *secp256k1.PublicKey) (immutable.Option[Identity], error) { - did, err := DIDFromPublicKey(publicKey) +// FromToken constructs a new `Indentity` from a bearer token. +func FromToken(data []byte) (Identity, error) { + token, err := jwt.Parse(data, jwt.WithVerify(false)) + if err != nil { + return Identity{}, err + } + + subject, err := hex.DecodeString(token.Subject()) + if err != nil { + return Identity{}, err + } + + pubKey, err := secp256k1.ParsePubKey(subject) + if err != nil { + return Identity{}, err + } + + did, err := DIDFromPublicKey(pubKey) if err != nil { - return None, err + return Identity{}, err } - return immutable.Some(Identity{ - DID: did, - PublicKey: publicKey, - }), nil + + return Identity{ + DID: did, + PublicKey: pubKey, + BearerToken: string(data), + }, nil } // DIDFromPublicKey returns a did:key generated from the the given public key. diff --git a/acp/source_hub_client.go b/acp/source_hub_client.go index 22371cd6e2..885722f667 100644 --- a/acp/source_hub_client.go +++ b/acp/source_hub_client.go @@ -16,7 +16,10 @@ import ( protoTypes "github.com/cosmos/gogoproto/types" "github.com/sourcenetwork/corelog" "github.com/sourcenetwork/immutable" + "github.com/sourcenetwork/sourcehub/sdk" "github.com/valyala/fastjson" + + "github.com/sourcenetwork/defradb/acp/identity" ) // sourceHubClient is a private abstraction to allow multiple ACP implementations @@ -39,7 +42,7 @@ type sourceHubClient interface { // otherwise returns error. AddPolicy( ctx context.Context, - creatorID string, + creator identity.Identity, policy string, marshalType policyMarshalType, creationTime *protoTypes.Timestamp, @@ -55,7 +58,7 @@ type sourceHubClient interface { // No error is returned upon successful registering of an object. RegisterObject( ctx context.Context, - actorID string, + identity identity.Identity, policyID string, resourceName string, objectID string, @@ -100,6 +103,22 @@ func NewLocalACP() ACP { } } +func NewSourceHubACP( + chainID string, + grpcAddress string, + cometRPCAddress string, + signer sdk.TxSigner, +) (ACP, error) { + acpSourceHub, err := NewACPSourceHub(chainID, grpcAddress, cometRPCAddress, signer) + if err != nil { + return nil, err + } + + return &sourceHubBridge{ + client: acpSourceHub, + }, nil +} + func (a *sourceHubBridge) Init(ctx context.Context, path string) { a.client.Init(ctx, path) } @@ -108,9 +127,9 @@ func (a *sourceHubBridge) Start(ctx context.Context) error { return a.client.Start(ctx) } -func (a *sourceHubBridge) AddPolicy(ctx context.Context, creatorID string, policy string) (string, error) { +func (a *sourceHubBridge) AddPolicy(ctx context.Context, creator identity.Identity, policy string) (string, error) { // Having a creator identity is a MUST requirement for adding a policy. - if creatorID == "" { + if creator.DID == "" { return "", ErrPolicyCreatorMustNotBeEmpty } @@ -125,14 +144,14 @@ func (a *sourceHubBridge) AddPolicy(ctx context.Context, creatorID string, polic policyID, err := a.client.AddPolicy( ctx, - creatorID, + creator, policy, marshalType, protoTypes.TimestampNow(), ) if err != nil { - return "", NewErrFailedToAddPolicyWithACP(err, "Local", creatorID) + return "", NewErrFailedToAddPolicyWithACP(err, "Local", creator.DID) } log.InfoContext(ctx, "Created Policy", corelog.Any("PolicyID", policyID)) @@ -206,14 +225,14 @@ func (a *sourceHubBridge) ValidateResourceExistsOnValidDPI( func (a *sourceHubBridge) RegisterDocObject( ctx context.Context, - actorID string, + identity identity.Identity, policyID string, resourceName string, docID string, ) error { registerDocResult, err := a.client.RegisterObject( ctx, - actorID, + identity, policyID, resourceName, docID, @@ -221,7 +240,7 @@ func (a *sourceHubBridge) RegisterDocObject( ) if err != nil { - return NewErrFailedToRegisterDocWithACP(err, "Local", policyID, actorID, resourceName, docID) + return NewErrFailedToRegisterDocWithACP(err, "Local", policyID, identity.DID, resourceName, docID) } switch registerDocResult { @@ -233,7 +252,7 @@ func (a *sourceHubBridge) RegisterDocObject( ctx, "Document registered with local acp", corelog.Any("PolicyID", policyID), - corelog.Any("Creator", actorID), + corelog.Any("Creator", identity.DID), corelog.Any("Resource", resourceName), corelog.Any("DocID", docID), ) @@ -244,7 +263,7 @@ func (a *sourceHubBridge) RegisterDocObject( ctx, "Document re-registered (unarchived object) with local acp", corelog.Any("PolicyID", policyID), - corelog.Any("Creator", actorID), + corelog.Any("Creator", identity.DID), corelog.Any("Resource", resourceName), corelog.Any("DocID", docID), ) diff --git a/cli/config.go b/cli/config.go index d559711f8b..9a0290eb04 100644 --- a/cli/config.go +++ b/cli/config.go @@ -42,27 +42,28 @@ var configPaths = []string{ // configFlags is a mapping of cli flag names to config keys to bind. var configFlags = map[string]string{ - "log-level": "log.level", - "log-output": "log.output", - "log-format": "log.format", - "log-stacktrace": "log.stacktrace", - "log-source": "log.source", - "log-overrides": "log.overrides", - "no-log-color": "log.colordisabled", - "url": "api.address", - "max-txn-retries": "datastore.maxtxnretries", - "store": "datastore.store", - "valuelogfilesize": "datastore.badger.valuelogfilesize", - "peers": "net.peers", - "p2paddr": "net.p2paddresses", - "no-p2p": "net.p2pdisabled", - "allowed-origins": "api.allowed-origins", - "pubkeypath": "api.pubkeypath", - "privkeypath": "api.privkeypath", - "keyring-namespace": "keyring.namespace", - "keyring-backend": "keyring.backend", - "keyring-path": "keyring.path", - "no-keyring": "keyring.disabled", + "log-level": "log.level", + "log-output": "log.output", + "log-format": "log.format", + "log-stacktrace": "log.stacktrace", + "log-source": "log.source", + "log-overrides": "log.overrides", + "no-log-color": "log.colordisabled", + "url": "api.address", + "max-txn-retries": "datastore.maxtxnretries", + "store": "datastore.store", + "valuelogfilesize": "datastore.badger.valuelogfilesize", + "peers": "net.peers", + "p2paddr": "net.p2paddresses", + "no-p2p": "net.p2pdisabled", + "allowed-origins": "api.allowed-origins", + "pubkeypath": "api.pubkeypath", + "privkeypath": "api.privkeypath", + "keyring-namespace": "keyring.namespace", + "keyring-backend": "keyring.backend", + "keyring-path": "keyring.path", + "no-keyring": "keyring.disabled", + "source-hub-address": "acp.sourceHub.address", } // configDefaults contains default values for config entries. diff --git a/cli/root.go b/cli/root.go index 51bf0e2ed6..2a94202657 100644 --- a/cli/root.go +++ b/cli/root.go @@ -97,5 +97,10 @@ Start a DefraDB node, interact with a local or remote node, and much more. cfg.GetBool(configFlags["no-keyring"]), "Disable the keyring and generate ephemeral keys", ) + cmd.PersistentFlags().String( + "source-hub-address", + cfg.GetString(configFlags["source-hub-address"]), + "The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor", + ) return cmd } diff --git a/cli/start.go b/cli/start.go index 7e1966253c..212202be80 100644 --- a/cli/start.go +++ b/cli/start.go @@ -17,6 +17,8 @@ import ( "syscall" "github.com/libp2p/go-libp2p/core/peer" + "github.com/sourcenetwork/immutable" + "github.com/sourcenetwork/sourcehub/sdk" "github.com/spf13/cobra" "github.com/sourcenetwork/defradb/errors" @@ -60,7 +62,9 @@ func MakeStartCommand() *cobra.Command { node.WithStorePath(cfg.GetString("datastore.badger.path")), node.WithBadgerInMemory(cfg.GetString("datastore.store") == configStoreMemory), node.WithDisableP2P(cfg.GetBool("net.p2pDisabled")), - node.WithACPType(node.LocalACPType), + node.WithSourceHubChainID(cfg.GetString("acp.sourceHub.ChainID")), + node.WithSourceHubGRPCAddress(cfg.GetString("acp.sourceHub.GRPCAddress")), + node.WithSourceHubCometRPCAddress(cfg.GetString("acp.sourceHub.CometRPCAddress")), node.WithPeers(peers...), // db options db.WithMaxRetries(cfg.GetInt("datastore.MaxTxnRetries")), @@ -100,7 +104,22 @@ func MakeStartCommand() *cobra.Command { if err != nil && !errors.Is(err, keyring.ErrNotFound) { return err } + opts = append(opts, node.WithBadgerEncryptionKey(encryptionKey)) + + sourceHubKeyName := cfg.GetString("acp.sourceHub.KeyName") + if sourceHubKeyName != "" { + signer, err := keyring.NewTxSignerFromKeyringKey(kr, sourceHubKeyName) + if err != nil { + return err + } + opts = append(opts, node.WithTxnSigner(immutable.Some[sdk.TxSigner](signer))) + } + } + + acpType := cfg.GetString("acp.type") + if acpType != "" { + opts = append(opts, node.WithACPType(node.ACPType(acpType))) } n, err := node.NewNode(cmd.Context(), opts...) diff --git a/cli/utils.go b/cli/utils.go index d1ee09962b..f0bd6a8098 100644 --- a/cli/utils.go +++ b/cli/utils.go @@ -17,8 +17,10 @@ import ( "os" "path/filepath" "syscall" + "time" "github.com/decred/dcrd/dcrec/secp256k1/v4" + "github.com/sourcenetwork/immutable" "github.com/spf13/cobra" "github.com/spf13/viper" "golang.org/x/term" @@ -51,6 +53,11 @@ var ( colContextKey = contextKey("col") ) +const ( + // authTokenExpiration is the default expiration time for auth tokens. + authTokenExpiration = time.Minute * 15 +) + // readPassword reads a user input password without echoing it to the terminal. var readPassword = func(cmd *cobra.Command, msg string) ([]byte, error) { cmd.Print(msg) @@ -149,13 +156,28 @@ func setContextIdentity(cmd *cobra.Command, privateKeyHex string) error { if err != nil { return err } + + cfg := mustGetContextConfig(cmd) + + sourcehubAddressString := cfg.GetString("acp.sourceHub.address") + var sourcehubAddress immutable.Option[string] + if sourcehubAddressString != "" { + sourcehubAddress = immutable.Some(sourcehubAddressString) + } + privKey := secp256k1.PrivKeyFromBytes(data) - identity, err := acpIdentity.FromPrivateKey(privKey) + identity, err := acpIdentity.FromPrivateKey( + privKey, + authTokenExpiration, + immutable.Some(cfg.GetString("api.address")), + sourcehubAddress, + false, + ) if err != nil { return err } - ctx := db.SetContextIdentity(cmd.Context(), identity) + ctx := db.SetContextIdentity(cmd.Context(), immutable.Some(identity)) cmd.SetContext(ctx) return nil } diff --git a/docs/config.md b/docs/config.md index ca69d6afd2..6b592059cb 100644 --- a/docs/config.md +++ b/docs/config.md @@ -120,3 +120,35 @@ Possible values: - `wasm-time` (default): https://github.com/bytecodealliance/wasmtime-go - `wasmer` (windows not supported): https://github.com/wasmerio/wasmer-go - `wazero`: https://github.com/tetratelabs/wazero + +## `acp.type` + +The type of ACP module to use. + +Possible values: +- `none` (default): No ACP +- `local` local-only ACP +- `source-hub` source hub ACP: https://github.com/sourcenetwork/sourcehub + +## `acp.sourceHub.ChainID` + +The ID of the SourceHub chain to store ACP data in. Required when using `acp.type`:`source-hub`. + +## `acp.sourceHub.GRPCAddress` + +The address of the SourceHub GRPC server. Required when using `acp.type`:`source-hub`. + +## `acp.sourceHub.CometRPCAddress` + +The address of the SourceHub Comet RPC server. Required when using `acp.type`:`source-hub`. + +## `acp.sourceHub.KeyName` + +The name of the key in the keyring where the SourceHub credentials used to sign (and pay for) SourceHub +transactions created by the node is stored. Required when using `acp.type`:`source-hub`. + +## `acp.sourceHub.address` + +The SourceHub address of the actor that client-side actions should permit to make SourceHub actions on +their behalf. This is a client-side only config param. It is required if the client wishes to make +SourceHub ACP requests in order to create protected data. diff --git a/docs/website/references/cli/defradb.md b/docs/website/references/cli/defradb.md index f2a6c85840..93dce2adef 100644 --- a/docs/website/references/cli/defradb.md +++ b/docs/website/references/cli/defradb.md @@ -12,20 +12,21 @@ Start a DefraDB node, interact with a local or remote node, and much more. ### Options ``` - -h, --help help for defradb - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -h, --help help for defradb + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client.md b/docs/website/references/cli/defradb_client.md index 592f267e72..dfd398f53a 100644 --- a/docs/website/references/cli/defradb_client.md +++ b/docs/website/references/cli/defradb_client.md @@ -18,19 +18,20 @@ Execute queries, add schema types, obtain node info, etc. ### Options inherited from parent commands ``` - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_acp.md b/docs/website/references/cli/defradb_client_acp.md index d80da76887..d1dc39e36e 100644 --- a/docs/website/references/cli/defradb_client_acp.md +++ b/docs/website/references/cli/defradb_client_acp.md @@ -19,21 +19,22 @@ Learn more about [ACP](/acp/README.md) ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_acp_policy.md b/docs/website/references/cli/defradb_client_acp_policy.md index 8374c92c15..720c072eae 100644 --- a/docs/website/references/cli/defradb_client_acp_policy.md +++ b/docs/website/references/cli/defradb_client_acp_policy.md @@ -15,21 +15,22 @@ Interact with the acp policy features of DefraDB instance ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_acp_policy_add.md b/docs/website/references/cli/defradb_client_acp_policy_add.md index ed2938e28e..596d7eb52f 100644 --- a/docs/website/references/cli/defradb_client_acp_policy_add.md +++ b/docs/website/references/cli/defradb_client_acp_policy_add.md @@ -66,21 +66,22 @@ defradb client acp policy add [-i --identity] [policy] [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_backup.md b/docs/website/references/cli/defradb_client_backup.md index 11bdb78c23..ba6028b287 100644 --- a/docs/website/references/cli/defradb_client_backup.md +++ b/docs/website/references/cli/defradb_client_backup.md @@ -16,21 +16,22 @@ Currently only supports JSON format. ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_backup_export.md b/docs/website/references/cli/defradb_client_backup_export.md index 07a3e1bd85..e48f848b27 100644 --- a/docs/website/references/cli/defradb_client_backup_export.md +++ b/docs/website/references/cli/defradb_client_backup_export.md @@ -30,21 +30,22 @@ defradb client backup export [-c --collections | -p --pretty | -f --format] ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_backup_import.md b/docs/website/references/cli/defradb_client_backup_import.md index 69c7311d26..3a3185c1c3 100644 --- a/docs/website/references/cli/defradb_client_backup_import.md +++ b/docs/website/references/cli/defradb_client_backup_import.md @@ -22,21 +22,22 @@ defradb client backup import [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_collection.md b/docs/website/references/cli/defradb_client_collection.md index bd732d0b07..ad6322d382 100644 --- a/docs/website/references/cli/defradb_client_collection.md +++ b/docs/website/references/cli/defradb_client_collection.md @@ -21,19 +21,20 @@ Create, read, update, and delete documents within a collection. ### Options inherited from parent commands ``` - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_collection_create.md b/docs/website/references/cli/defradb_client_collection_create.md index 862d30cf2e..92ec4a549b 100644 --- a/docs/website/references/cli/defradb_client_collection_create.md +++ b/docs/website/references/cli/defradb_client_collection_create.md @@ -54,25 +54,26 @@ defradb client collection create [-i --identity] [-e --encrypt] [--encrypt-field ### Options inherited from parent commands ``` - --get-inactive Get inactive collections as well as active - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --name string Collection name - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --schema string Collection schema Root - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") - --version string Collection version ID + --get-inactive Get inactive collections as well as active + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --name string Collection name + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --schema string Collection schema Root + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + --version string Collection version ID ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_collection_delete.md b/docs/website/references/cli/defradb_client_collection_delete.md index af36d60e15..68b98d13c5 100644 --- a/docs/website/references/cli/defradb_client_collection_delete.md +++ b/docs/website/references/cli/defradb_client_collection_delete.md @@ -32,25 +32,26 @@ defradb client collection delete [-i --identity] [--filter --docID ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --name string Collection name - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --schema string Collection schema Root - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") - --version string Collection version ID + --get-inactive Get inactive collections as well as active + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --name string Collection name + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --schema string Collection schema Root + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + --version string Collection version ID ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_collection_describe.md b/docs/website/references/cli/defradb_client_collection_describe.md index 3990ad3f7b..18ca881103 100644 --- a/docs/website/references/cli/defradb_client_collection_describe.md +++ b/docs/website/references/cli/defradb_client_collection_describe.md @@ -36,21 +36,22 @@ defradb client collection describe [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_collection_docIDs.md b/docs/website/references/cli/defradb_client_collection_docIDs.md index b376cf888b..2c67725eda 100644 --- a/docs/website/references/cli/defradb_client_collection_docIDs.md +++ b/docs/website/references/cli/defradb_client_collection_docIDs.md @@ -26,25 +26,26 @@ defradb client collection docIDs [-i --identity] [flags] ### Options inherited from parent commands ``` - --get-inactive Get inactive collections as well as active - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --name string Collection name - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --schema string Collection schema Root - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") - --version string Collection version ID + --get-inactive Get inactive collections as well as active + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --name string Collection name + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --schema string Collection schema Root + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + --version string Collection version ID ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_collection_get.md b/docs/website/references/cli/defradb_client_collection_get.md index 8a04c50ffd..a115f07883 100644 --- a/docs/website/references/cli/defradb_client_collection_get.md +++ b/docs/website/references/cli/defradb_client_collection_get.md @@ -27,25 +27,26 @@ defradb client collection get [-i --identity] [--show-deleted] [flags] ### Options inherited from parent commands ``` - --get-inactive Get inactive collections as well as active - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --name string Collection name - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --schema string Collection schema Root - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") - --version string Collection version ID + --get-inactive Get inactive collections as well as active + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --name string Collection name + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --schema string Collection schema Root + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + --version string Collection version ID ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_collection_patch.md b/docs/website/references/cli/defradb_client_collection_patch.md index d27306cc43..689e897af0 100644 --- a/docs/website/references/cli/defradb_client_collection_patch.md +++ b/docs/website/references/cli/defradb_client_collection_patch.md @@ -33,25 +33,26 @@ defradb client collection patch [patch] [flags] ### Options inherited from parent commands ``` - --get-inactive Get inactive collections as well as active - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --name string Collection name - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --schema string Collection schema Root - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") - --version string Collection version ID + --get-inactive Get inactive collections as well as active + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --name string Collection name + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --schema string Collection schema Root + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + --version string Collection version ID ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_collection_update.md b/docs/website/references/cli/defradb_client_collection_update.md index 37ef8249a6..d00f44b07c 100644 --- a/docs/website/references/cli/defradb_client_collection_update.md +++ b/docs/website/references/cli/defradb_client_collection_update.md @@ -38,25 +38,26 @@ defradb client collection update [-i --identity] [--filter --docID ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --name string Collection name - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --schema string Collection schema Root - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") - --version string Collection version ID + --get-inactive Get inactive collections as well as active + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --name string Collection name + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --schema string Collection schema Root + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + --version string Collection version ID ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_dump.md b/docs/website/references/cli/defradb_client_dump.md index efc703d4c3..fbf1794eef 100644 --- a/docs/website/references/cli/defradb_client_dump.md +++ b/docs/website/references/cli/defradb_client_dump.md @@ -15,21 +15,22 @@ defradb client dump [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_index.md b/docs/website/references/cli/defradb_client_index.md index 6c6c17ff54..1282dbb99a 100644 --- a/docs/website/references/cli/defradb_client_index.md +++ b/docs/website/references/cli/defradb_client_index.md @@ -15,21 +15,22 @@ Manage (create, drop, or list) collection indexes on a DefraDB node. ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_index_create.md b/docs/website/references/cli/defradb_client_index_create.md index 7866164323..88a5b2b847 100644 --- a/docs/website/references/cli/defradb_client_index_create.md +++ b/docs/website/references/cli/defradb_client_index_create.md @@ -32,21 +32,22 @@ defradb client index create -c --collection --fields [-n - ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_index_drop.md b/docs/website/references/cli/defradb_client_index_drop.md index 1ccf845e02..df2cac7fc3 100644 --- a/docs/website/references/cli/defradb_client_index_drop.md +++ b/docs/website/references/cli/defradb_client_index_drop.md @@ -24,21 +24,22 @@ defradb client index drop -c --collection -n --name [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_index_list.md b/docs/website/references/cli/defradb_client_index_list.md index ad66d3524b..360fa7fbd9 100644 --- a/docs/website/references/cli/defradb_client_index_list.md +++ b/docs/website/references/cli/defradb_client_index_list.md @@ -26,21 +26,22 @@ defradb client index list [-c --collection ] [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_p2p.md b/docs/website/references/cli/defradb_client_p2p.md index 8896ed0b29..77104e9c4f 100644 --- a/docs/website/references/cli/defradb_client_p2p.md +++ b/docs/website/references/cli/defradb_client_p2p.md @@ -15,21 +15,22 @@ Interact with the DefraDB P2P system ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_p2p_collection.md b/docs/website/references/cli/defradb_client_p2p_collection.md index d0eea4ee83..9cef79c61e 100644 --- a/docs/website/references/cli/defradb_client_p2p_collection.md +++ b/docs/website/references/cli/defradb_client_p2p_collection.md @@ -16,21 +16,22 @@ The selected collections synchronize their events on the pubsub network. ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_p2p_collection_add.md b/docs/website/references/cli/defradb_client_p2p_collection_add.md index c9e4d60a79..0faef4908b 100644 --- a/docs/website/references/cli/defradb_client_p2p_collection_add.md +++ b/docs/website/references/cli/defradb_client_p2p_collection_add.md @@ -27,21 +27,22 @@ defradb client p2p collection add [collectionIDs] [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_p2p_collection_getall.md b/docs/website/references/cli/defradb_client_p2p_collection_getall.md index 82f9cd9588..2154256fc1 100644 --- a/docs/website/references/cli/defradb_client_p2p_collection_getall.md +++ b/docs/website/references/cli/defradb_client_p2p_collection_getall.md @@ -20,21 +20,22 @@ defradb client p2p collection getall [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_p2p_collection_remove.md b/docs/website/references/cli/defradb_client_p2p_collection_remove.md index 6faffa5204..24cbee423e 100644 --- a/docs/website/references/cli/defradb_client_p2p_collection_remove.md +++ b/docs/website/references/cli/defradb_client_p2p_collection_remove.md @@ -27,21 +27,22 @@ defradb client p2p collection remove [collectionIDs] [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_p2p_info.md b/docs/website/references/cli/defradb_client_p2p_info.md index 22e6e44288..9a23b68535 100644 --- a/docs/website/references/cli/defradb_client_p2p_info.md +++ b/docs/website/references/cli/defradb_client_p2p_info.md @@ -19,21 +19,22 @@ defradb client p2p info [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_p2p_replicator.md b/docs/website/references/cli/defradb_client_p2p_replicator.md index 2ab9a6391a..9976113c65 100644 --- a/docs/website/references/cli/defradb_client_p2p_replicator.md +++ b/docs/website/references/cli/defradb_client_p2p_replicator.md @@ -16,21 +16,22 @@ A replicator replicates one or all collection(s) from one node to another. ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_p2p_replicator_delete.md b/docs/website/references/cli/defradb_client_p2p_replicator_delete.md index 9977d9811c..cd153c081b 100644 --- a/docs/website/references/cli/defradb_client_p2p_replicator_delete.md +++ b/docs/website/references/cli/defradb_client_p2p_replicator_delete.md @@ -25,21 +25,22 @@ defradb client p2p replicator delete [-c, --collection] [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_p2p_replicator_getall.md b/docs/website/references/cli/defradb_client_p2p_replicator_getall.md index 0bca40baa0..063c70286c 100644 --- a/docs/website/references/cli/defradb_client_p2p_replicator_getall.md +++ b/docs/website/references/cli/defradb_client_p2p_replicator_getall.md @@ -24,21 +24,22 @@ defradb client p2p replicator getall [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_p2p_replicator_set.md b/docs/website/references/cli/defradb_client_p2p_replicator_set.md index 7f8623b96e..6bf37ab3f4 100644 --- a/docs/website/references/cli/defradb_client_p2p_replicator_set.md +++ b/docs/website/references/cli/defradb_client_p2p_replicator_set.md @@ -25,21 +25,22 @@ defradb client p2p replicator set [-c, --collection] [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_query.md b/docs/website/references/cli/defradb_client_query.md index ec868456b1..3a07ba7078 100644 --- a/docs/website/references/cli/defradb_client_query.md +++ b/docs/website/references/cli/defradb_client_query.md @@ -37,21 +37,22 @@ defradb client query [-i --identity] [request] [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_schema.md b/docs/website/references/cli/defradb_client_schema.md index 4ad3289b35..10f7a2237a 100644 --- a/docs/website/references/cli/defradb_client_schema.md +++ b/docs/website/references/cli/defradb_client_schema.md @@ -15,21 +15,22 @@ Make changes, updates, or look for existing schema types. ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_schema_add.md b/docs/website/references/cli/defradb_client_schema_add.md index c10496112e..3c20388acd 100644 --- a/docs/website/references/cli/defradb_client_schema_add.md +++ b/docs/website/references/cli/defradb_client_schema_add.md @@ -36,21 +36,22 @@ defradb client schema add [schema] [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_schema_describe.md b/docs/website/references/cli/defradb_client_schema_describe.md index 1a0abbc964..80e2e1b053 100644 --- a/docs/website/references/cli/defradb_client_schema_describe.md +++ b/docs/website/references/cli/defradb_client_schema_describe.md @@ -35,21 +35,22 @@ defradb client schema describe [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_schema_migration.md b/docs/website/references/cli/defradb_client_schema_migration.md index 3660095f0f..dc30e11ebc 100644 --- a/docs/website/references/cli/defradb_client_schema_migration.md +++ b/docs/website/references/cli/defradb_client_schema_migration.md @@ -15,21 +15,22 @@ Make set or look for existing schema migrations on a DefraDB node. ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_schema_migration_down.md b/docs/website/references/cli/defradb_client_schema_migration_down.md index 82f2168b04..69dca887ca 100644 --- a/docs/website/references/cli/defradb_client_schema_migration_down.md +++ b/docs/website/references/cli/defradb_client_schema_migration_down.md @@ -32,21 +32,22 @@ defradb client schema migration down --collection [fl ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_schema_migration_reload.md b/docs/website/references/cli/defradb_client_schema_migration_reload.md index c74d4987b7..d5a3ae3e82 100644 --- a/docs/website/references/cli/defradb_client_schema_migration_reload.md +++ b/docs/website/references/cli/defradb_client_schema_migration_reload.md @@ -19,21 +19,22 @@ defradb client schema migration reload [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_schema_migration_set-registry.md b/docs/website/references/cli/defradb_client_schema_migration_set-registry.md index f554ac5f48..d49213920c 100644 --- a/docs/website/references/cli/defradb_client_schema_migration_set-registry.md +++ b/docs/website/references/cli/defradb_client_schema_migration_set-registry.md @@ -25,21 +25,22 @@ defradb client schema migration set-registry [collectionID] [cfg] [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_schema_migration_set.md b/docs/website/references/cli/defradb_client_schema_migration_set.md index fde006cb05..b5063e2033 100644 --- a/docs/website/references/cli/defradb_client_schema_migration_set.md +++ b/docs/website/references/cli/defradb_client_schema_migration_set.md @@ -32,21 +32,22 @@ defradb client schema migration set [src] [dst] [cfg] [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_schema_migration_up.md b/docs/website/references/cli/defradb_client_schema_migration_up.md index fb6352c2f6..83ccd49e04 100644 --- a/docs/website/references/cli/defradb_client_schema_migration_up.md +++ b/docs/website/references/cli/defradb_client_schema_migration_up.md @@ -32,21 +32,22 @@ defradb client schema migration up --collection [flag ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_schema_patch.md b/docs/website/references/cli/defradb_client_schema_patch.md index a47ffc633c..7d18010a26 100644 --- a/docs/website/references/cli/defradb_client_schema_patch.md +++ b/docs/website/references/cli/defradb_client_schema_patch.md @@ -35,21 +35,22 @@ defradb client schema patch [schema] [migration] [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_schema_set-active.md b/docs/website/references/cli/defradb_client_schema_set-active.md index efc4dee955..fc57c21006 100644 --- a/docs/website/references/cli/defradb_client_schema_set-active.md +++ b/docs/website/references/cli/defradb_client_schema_set-active.md @@ -20,21 +20,22 @@ defradb client schema set-active [versionID] [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_tx.md b/docs/website/references/cli/defradb_client_tx.md index acc23bba4a..b341aa699e 100644 --- a/docs/website/references/cli/defradb_client_tx.md +++ b/docs/website/references/cli/defradb_client_tx.md @@ -15,21 +15,22 @@ Create, commit, and discard DefraDB transactions ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_tx_commit.md b/docs/website/references/cli/defradb_client_tx_commit.md index 7775cb5287..6c449593e2 100644 --- a/docs/website/references/cli/defradb_client_tx_commit.md +++ b/docs/website/references/cli/defradb_client_tx_commit.md @@ -19,21 +19,22 @@ defradb client tx commit [id] [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_tx_create.md b/docs/website/references/cli/defradb_client_tx_create.md index 2c3c7e5278..0b860c7ace 100644 --- a/docs/website/references/cli/defradb_client_tx_create.md +++ b/docs/website/references/cli/defradb_client_tx_create.md @@ -21,21 +21,22 @@ defradb client tx create [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_tx_discard.md b/docs/website/references/cli/defradb_client_tx_discard.md index dfbee4733c..d3e378e02b 100644 --- a/docs/website/references/cli/defradb_client_tx_discard.md +++ b/docs/website/references/cli/defradb_client_tx_discard.md @@ -19,21 +19,22 @@ defradb client tx discard [id] [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_view.md b/docs/website/references/cli/defradb_client_view.md index 498b11a59e..81a50abf60 100644 --- a/docs/website/references/cli/defradb_client_view.md +++ b/docs/website/references/cli/defradb_client_view.md @@ -15,21 +15,22 @@ Manage (add) views withing a running DefraDB instance ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_client_view_add.md b/docs/website/references/cli/defradb_client_view_add.md index e50c16d7f6..41d64d202f 100644 --- a/docs/website/references/cli/defradb_client_view_add.md +++ b/docs/website/references/cli/defradb_client_view_add.md @@ -25,21 +25,22 @@ defradb client view add [query] [sdl] [transform] [flags] ### Options inherited from parent commands ``` - -i, --identity string Hex formatted private key used to authenticate with ACP - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --tx uint Transaction ID - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + -i, --identity string Hex formatted private key used to authenticate with ACP + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --tx uint Transaction ID + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_identity.md b/docs/website/references/cli/defradb_identity.md index 1f658047b2..016561b39c 100644 --- a/docs/website/references/cli/defradb_identity.md +++ b/docs/website/references/cli/defradb_identity.md @@ -15,19 +15,20 @@ Interact with identity features of DefraDB instance ### Options inherited from parent commands ``` - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_identity_new.md b/docs/website/references/cli/defradb_identity_new.md index 24a995e8f8..05dcc6fe0a 100644 --- a/docs/website/references/cli/defradb_identity_new.md +++ b/docs/website/references/cli/defradb_identity_new.md @@ -30,19 +30,20 @@ defradb identity new [flags] ### Options inherited from parent commands ``` - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_keyring.md b/docs/website/references/cli/defradb_keyring.md index ef091ef233..c01c69bd1b 100644 --- a/docs/website/references/cli/defradb_keyring.md +++ b/docs/website/references/cli/defradb_keyring.md @@ -30,19 +30,20 @@ To learn more about the available options: ### Options inherited from parent commands ``` - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_keyring_export.md b/docs/website/references/cli/defradb_keyring_export.md index 78bee67e7d..15029b484a 100644 --- a/docs/website/references/cli/defradb_keyring_export.md +++ b/docs/website/references/cli/defradb_keyring_export.md @@ -23,19 +23,20 @@ defradb keyring export [flags] ### Options inherited from parent commands ``` - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_keyring_generate.md b/docs/website/references/cli/defradb_keyring_generate.md index 5f58c61369..3651479823 100644 --- a/docs/website/references/cli/defradb_keyring_generate.md +++ b/docs/website/references/cli/defradb_keyring_generate.md @@ -37,19 +37,20 @@ defradb keyring generate [flags] ### Options inherited from parent commands ``` - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_keyring_import.md b/docs/website/references/cli/defradb_keyring_import.md index 3206e33440..fe5df3f4ff 100644 --- a/docs/website/references/cli/defradb_keyring_import.md +++ b/docs/website/references/cli/defradb_keyring_import.md @@ -23,19 +23,20 @@ defradb keyring import [flags] ### Options inherited from parent commands ``` - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_server-dump.md b/docs/website/references/cli/defradb_server-dump.md index 403d72c972..75dd56094e 100644 --- a/docs/website/references/cli/defradb_server-dump.md +++ b/docs/website/references/cli/defradb_server-dump.md @@ -15,19 +15,20 @@ defradb server-dump [flags] ### Options inherited from parent commands ``` - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_start.md b/docs/website/references/cli/defradb_start.md index 0f2bed427f..d71dfb14e4 100644 --- a/docs/website/references/cli/defradb_start.md +++ b/docs/website/references/cli/defradb_start.md @@ -28,19 +28,20 @@ defradb start [flags] ### Options inherited from parent commands ``` - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/docs/website/references/cli/defradb_version.md b/docs/website/references/cli/defradb_version.md index c82cd43df8..c752a6936e 100644 --- a/docs/website/references/cli/defradb_version.md +++ b/docs/website/references/cli/defradb_version.md @@ -17,19 +17,20 @@ defradb version [flags] ### Options inherited from parent commands ``` - --keyring-backend string Keyring backend to use. Options are file or system (default "file") - --keyring-namespace string Service name to use when using the system backend (default "defradb") - --keyring-path string Path to store encrypted keys when using the file backend (default "keys") - --log-format string Log format to use. Options are text or json (default "text") - --log-level string Log level to use. Options are debug, info, error, fatal (default "info") - --log-output string Log output path. Options are stderr or stdout. (default "stderr") - --log-overrides string Logger config overrides. Format ,=,...;,... - --log-source Include source location in logs - --log-stacktrace Include stacktrace in error and fatal logs - --no-keyring Disable the keyring and generate ephemeral keys - --no-log-color Disable colored log output - --rootdir string Directory for persistent data (default: $HOME/.defradb) - --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") + --keyring-backend string Keyring backend to use. Options are file or system (default "file") + --keyring-namespace string Service name to use when using the system backend (default "defradb") + --keyring-path string Path to store encrypted keys when using the file backend (default "keys") + --log-format string Log format to use. Options are text or json (default "text") + --log-level string Log level to use. Options are debug, info, error, fatal (default "info") + --log-output string Log output path. Options are stderr or stdout. (default "stderr") + --log-overrides string Logger config overrides. Format ,=,...;,... + --log-source Include source location in logs + --log-stacktrace Include stacktrace in error and fatal logs + --no-keyring Disable the keyring and generate ephemeral keys + --no-log-color Disable colored log output + --rootdir string Directory for persistent data (default: $HOME/.defradb) + --source-hub-address string The SourceHub address authorized by the client to make SourceHub transactions on behalf of the actor + --url string URL of HTTP endpoint to listen on or connect to (default "127.0.0.1:9181") ``` ### SEE ALSO diff --git a/go.mod b/go.mod index 1b8ddab16e..11def6289c 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.21.3 require ( github.com/bits-and-blooms/bitset v1.13.0 github.com/bxcodec/faker v2.0.1+incompatible + github.com/cosmos/cosmos-sdk v0.50.6 github.com/cosmos/gogoproto v1.5.0 github.com/cyware/ssi-sdk v0.0.0-20231229164914-f93f3006379f github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 @@ -38,12 +39,14 @@ require ( github.com/multiformats/go-multibase v0.2.0 github.com/multiformats/go-multicodec v0.9.0 github.com/multiformats/go-multihash v0.2.3 + github.com/pelletier/go-toml v1.9.5 github.com/sourcenetwork/acp_core v0.0.0-20240607160510-47a5306b2ad2 github.com/sourcenetwork/badger/v4 v4.2.1-0.20231113215945-a63444ca5276 github.com/sourcenetwork/corelog v0.0.8 github.com/sourcenetwork/go-libp2p-pubsub-rpc v0.0.14 github.com/sourcenetwork/graphql-go v0.7.10-0.20231113214537-a9560c1898dd github.com/sourcenetwork/immutable v0.3.0 + github.com/sourcenetwork/sourcehub v0.2.1-0.20240704194128-f43f5e427274 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.19.0 @@ -63,47 +66,93 @@ require ( require ( buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.31.0-20230802163732-1c33ebd9ecfa.1 // indirect + cloud.google.com/go v0.112.1 // indirect + cloud.google.com/go/compute/metadata v0.3.0 // indirect + cloud.google.com/go/iam v1.1.6 // indirect + cloud.google.com/go/storage v1.38.0 // indirect + cosmossdk.io/api v0.7.4 // indirect + cosmossdk.io/collections v0.4.0 // indirect + cosmossdk.io/core v0.11.0 // indirect + cosmossdk.io/depinject v1.0.0-alpha.4 // indirect cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/log v1.3.1 // indirect cosmossdk.io/math v1.3.0 // indirect cosmossdk.io/store v1.1.0 // indirect + cosmossdk.io/x/circuit v0.1.0 // indirect + cosmossdk.io/x/evidence v0.1.0 // indirect + cosmossdk.io/x/feegrant v0.1.0 // indirect + cosmossdk.io/x/tx v0.13.2 // indirect + cosmossdk.io/x/upgrade v0.1.1 // indirect + filippo.io/edwards25519 v1.0.0 // indirect + github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect + github.com/99designs/keyring v1.2.2 // indirect + github.com/DataDog/datadog-go v3.2.0+incompatible // indirect github.com/DataDog/zstd v1.5.5 // indirect github.com/Jorropo/jsync v1.0.1 // indirect github.com/NathanBaulch/protoc-gen-cobra v1.2.1 // indirect + github.com/TBD54566975/ssi-sdk v0.0.4-alpha // indirect github.com/alessio/shellescape v1.4.1 // indirect github.com/awalterschulze/gographviz v2.0.3+incompatible // indirect + github.com/aws/aws-sdk-go v1.44.224 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect + github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 // indirect github.com/bytecodealliance/wasmtime-go/v15 v15.0.0 // indirect + github.com/cenkalti/backoff v2.2.1+incompatible // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/chzyer/readline v1.5.1 // indirect github.com/cloudflare/circl v1.3.7 // indirect + github.com/cockroachdb/apd/v2 v2.0.2 // indirect github.com/cockroachdb/errors v1.11.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v1.1.0 // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/cometbft/cometbft v0.38.8 // indirect + github.com/cometbft/cometbft-db v0.9.1 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/cosmos-db v1.0.2 // indirect + github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect + github.com/cosmos/go-bip39 v1.0.0 // indirect + github.com/cosmos/gogogateway v1.2.0 // indirect github.com/cosmos/iavl v1.1.2 // indirect + github.com/cosmos/ibc-go/modules/capability v1.0.0 // indirect + github.com/cosmos/ibc-go/v8 v8.0.0 // indirect github.com/cosmos/ics23/go v0.10.0 // indirect + github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/cskr/pubsub v1.0.2 // indirect github.com/danieljoos/wincred v1.2.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect + github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect + github.com/dgraph-io/badger/v2 v2.2007.4 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect + github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect + github.com/dvsekhvalnov/jose2go v1.6.0 // indirect github.com/elastic/gosigar v0.14.3 // indirect + github.com/emicklei/dot v1.6.1 // indirect + github.com/fatih/color v1.15.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.4 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect + github.com/go-jose/go-jose/v3 v3.0.1-0.20221117193127-916db76e8214 // indirect + github.com/go-kit/kit v0.12.0 // indirect + github.com/go-kit/log v0.2.1 // indirect + github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect @@ -113,35 +162,57 @@ require ( github.com/go-playground/validator/v10 v10.15.1 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/goccy/go-json v0.10.3 // indirect + github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v1.2.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.2 // indirect github.com/google/flatbuffers v2.0.6+incompatible // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gopacket v1.1.19 // indirect + github.com/google/orderedcode v0.0.1 // indirect github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8 // indirect + github.com/google/s2a-go v0.1.7 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect + github.com/googleapis/gax-go/v2 v2.12.3 // indirect + github.com/gorilla/handlers v1.5.2 // indirect + github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/websocket v1.5.3 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect + github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect + github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-getter v1.7.3 // indirect + github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-metrics v0.5.3 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-uuid v1.0.2 // indirect + github.com/hashicorp/go-plugin v1.6.0 // indirect + github.com/hashicorp/go-safetemp v1.0.0 // indirect + github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/arc/v2 v2.0.7 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/hashicorp/yamux v0.1.1 // indirect + github.com/hdevalence/ed25519consensus v0.1.0 // indirect + github.com/huandu/skiplist v1.2.0 // indirect github.com/huin/goupnp v1.3.0 // indirect github.com/hyperledger/aries-framework-go v0.3.2 // indirect github.com/hyperledger/aries-framework-go/component/kmscrypto v0.0.0-20230427134832-0c9969493bd3 // indirect github.com/hyperledger/aries-framework-go/component/log v0.0.0-20230427134832-0c9969493bd3 // indirect github.com/hyperledger/aries-framework-go/component/models v0.0.0-20230501135648-a9a7ad029347 // indirect github.com/hyperledger/aries-framework-go/spi v0.0.0-20230427134832-0c9969493bd3 // indirect + github.com/ignite/cli/v28 v28.4.0 // indirect + github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/invopop/yaml v0.2.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect @@ -154,6 +225,8 @@ require ( github.com/ipfs/kubo v0.25.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/jmhodges/levigo v1.0.0 // indirect github.com/jorrizza/ed2curve25519 v0.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 // indirect @@ -168,6 +241,7 @@ require ( github.com/lestrrat-go/httprc v1.0.5 // indirect github.com/lestrrat-go/iter v1.0.2 // indirect github.com/lestrrat-go/option v1.0.1 // indirect + github.com/lib/pq v1.10.9 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect @@ -183,15 +257,20 @@ require ( github.com/lmittmann/tint v1.0.4 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/manifoldco/promptui v0.9.0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/miekg/dns v1.1.61 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect + github.com/minio/highwayhash v1.0.2 // indirect github.com/minio/sha256-simd v1.0.1 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/mtibben/percent v0.2.1 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect @@ -199,6 +278,7 @@ require ( github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect + github.com/oklog/run v1.1.0 // indirect github.com/onsi/ginkgo/v2 v2.19.0 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect @@ -235,7 +315,9 @@ require ( github.com/quic-go/quic-go v0.45.0 // indirect github.com/quic-go/webtransport-go v0.8.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/rs/cors v1.10.1 // indirect github.com/rs/zerolog v1.32.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect @@ -252,13 +334,20 @@ require ( github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect + github.com/tendermint/go-amino v0.16.0 // indirect github.com/tetratelabs/wazero v1.5.0 // indirect github.com/textileio/go-log/v2 v2.1.3-gke-2 // indirect github.com/ugorji/go/codec v1.2.12 // indirect + github.com/ulikunitz/xz v0.5.11 // indirect github.com/wasmerio/wasmer-go v1.0.4 // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/x448/float16 v0.8.4 // indirect + github.com/zondax/hid v0.9.2 // indirect + github.com/zondax/ledger-go v0.14.3 // indirect + go.etcd.io/bbolt v1.3.8 // indirect go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect go.opentelemetry.io/otel v1.27.0 // indirect go.opentelemetry.io/otel/sdk v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect @@ -269,15 +358,23 @@ require ( golang.org/x/crypto v0.24.0 // indirect golang.org/x/mod v0.18.0 // indirect golang.org/x/net v0.26.0 // indirect + golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.21.0 // indirect golang.org/x/text v0.16.0 // indirect + golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.22.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect + google.golang.org/api v0.171.0 // indirect + google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 // indirect gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + gotest.tools/v3 v3.5.1 // indirect lukechampine.com/blake3 v1.3.0 // indirect + nhooyr.io/websocket v1.8.7 // indirect + pgregory.net/rapid v1.1.0 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/go.sum b/go.sum index f3ab8de70a..cc5208e234 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,198 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= +cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= +cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= +cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= +cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= +cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= +cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= +cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= +cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4= +cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ= +cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= +cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o= +cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s= +cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= +cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY= +cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw= +cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= +cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0= +cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= +cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY= +cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= +cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM= +cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= +cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY= +cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= +cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= +cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= +cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= +cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs= +cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= +cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM= +cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo= +cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= +cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I= +cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo= +cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo= +cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= +cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4= +cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0= +cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= +cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU= +cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= +cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y= +cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk= +cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= +cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= +cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM= +cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= +cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o= +cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0= +cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= +cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= +cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= +cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= +cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= +cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= +cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4= +cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE= +cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= +cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY= +cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= +cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA= +cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= +cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ= +cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY= +cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= +cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs= +cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= +cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E= +cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= +cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0= +cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0= +cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4= +cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o= +cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk= +cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= +cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg= +cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg= +cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= +cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y= +cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= +cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4= +cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= +cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s= +cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= +cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA= +cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4= +cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0= +cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= +cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU= +cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= +cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs= +cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= +cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM= +cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= +cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= +cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg= +cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY= +cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= +cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= +cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= +cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= +cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0= +cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo= +cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= +cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE= +cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= +cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= +cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= +cosmossdk.io/api v0.7.4 h1:sPo8wKwCty1lht8kgL3J7YL1voJywP3YWuA5JKkBz30= +cosmossdk.io/api v0.7.4/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= +cosmossdk.io/client/v2 v2.0.0-beta.1 h1:XkHh1lhrLYIT9zKl7cIOXUXg2hdhtjTPBUfqERNA1/Q= +cosmossdk.io/client/v2 v2.0.0-beta.1/go.mod h1:JEUSu9moNZQ4kU3ir1DKD5eU4bllmAexrGWjmb9k8qU= +cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= +cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0= +cosmossdk.io/core v0.11.0 h1:vtIafqUi+1ZNAE/oxLOQQ7Oek2n4S48SWLG8h/+wdbo= +cosmossdk.io/core v0.11.0/go.mod h1:LaTtayWBSoacF5xNzoF8tmLhehqlA9z1SWiPuNC6X1w= +cosmossdk.io/depinject v1.0.0-alpha.4 h1:PLNp8ZYAMPTUKyG9IK2hsbciDWqna2z1Wsl98okJopc= +cosmossdk.io/depinject v1.0.0-alpha.4/go.mod h1:HeDk7IkR5ckZ3lMGs/o91AVUc7E596vMaOmslGFM3yU= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= @@ -12,32 +204,85 @@ cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= cosmossdk.io/store v1.1.0 h1:LnKwgYMc9BInn9PhpTFEQVbL9UK475G2H911CGGnWHk= cosmossdk.io/store v1.1.0/go.mod h1:oZfW/4Fc/zYqu3JmQcQdUJ3fqu5vnYTn3LZFFy8P8ng= +cosmossdk.io/x/circuit v0.1.0 h1:IAej8aRYeuOMritczqTlljbUVHq1E85CpBqaCTwYgXs= +cosmossdk.io/x/circuit v0.1.0/go.mod h1:YDzblVE8+E+urPYQq5kq5foRY/IzhXovSYXb4nwd39w= +cosmossdk.io/x/evidence v0.1.0 h1:J6OEyDl1rbykksdGynzPKG5R/zm6TacwW2fbLTW4nCk= +cosmossdk.io/x/evidence v0.1.0/go.mod h1:hTaiiXsoiJ3InMz1uptgF0BnGqROllAN8mwisOMMsfw= +cosmossdk.io/x/feegrant v0.1.0 h1:c7s3oAq/8/UO0EiN1H5BIjwVntujVTkYs35YPvvrdQk= +cosmossdk.io/x/feegrant v0.1.0/go.mod h1:4r+FsViJRpcZif/yhTn+E0E6OFfg4n0Lx+6cCtnZElU= +cosmossdk.io/x/tx v0.13.2 h1:Kh90UH30bhnnUdJH+CmWLyaH8IKdY6BBGY3EkdOk82o= +cosmossdk.io/x/tx v0.13.2/go.mod h1:yhPokDCfXVIuAtyp49IFlWB5YAXUgD7Zek+ZHwsHzvU= +cosmossdk.io/x/upgrade v0.1.1 h1:aoPe2gNvH+Gwt/Pgq3dOxxQVU3j5P6Xf+DaUJTDZATc= +cosmossdk.io/x/upgrade v0.1.1/go.mod h1:MNLptLPcIFK9CWt7Ra//8WUZAxweyRDNcbs5nkOcQy0= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= +filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= +filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= +github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= +github.com/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XBn0= +github.com/99designs/keyring v1.2.2/go.mod h1:wes/FrByc8j7lFOAGLGSNEg8f/PaI3cgTBqhFkHUrPk= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 h1:cTp8I5+VIoKjsnZuH8vjyaysT/ses3EvZeaV/1UkF2M= github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= +github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Jorropo/jsync v1.0.1 h1:6HgRolFZnsdfzRUj+ImB9og1JYOxQoReSywkHOGSaUU= github.com/Jorropo/jsync v1.0.1/go.mod h1:jCOZj3vrBCri3bSU3ErUYvevKlnbssrXeCivybS5ABQ= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/NathanBaulch/protoc-gen-cobra v1.2.1 h1:BOqX9glwicbqDJDGndMnhHhx8psGTSjGdZzRDY1a7A8= github.com/NathanBaulch/protoc-gen-cobra v1.2.1/go.mod h1:ZLPLEPQgV3jP3a7IEp+xxYPk8tF4lhY9ViV0hn6K3iA= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= +github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= +github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/TBD54566975/ssi-sdk v0.0.4-alpha h1:GbZG0S3xeaWQi2suWw2VjGRhM/S2RrIsfiubxSHlViE= +github.com/TBD54566975/ssi-sdk v0.0.4-alpha/go.mod h1:O4iANflxGCX0NbjHOhthq0X0il2ZYNMYlUnjEa0rsC0= +github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I= +github.com/adlio/schema v1.3.3/go.mod h1:1EsRssiv9/Ce2CMzq5DoL7RiMshhuigQxrR4DMV9fHg= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 h1:ez/4by2iGztzR4L0zgAOR8lTQK9VlyBVVd7G4omaOQs= github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0= github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/awalterschulze/gographviz v2.0.3+incompatible h1:9sVEXJBJLwGX7EQVhLm2elIKCm7P2YHFC8v6096G09E= github.com/awalterschulze/gographviz v2.0.3+incompatible/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.224 h1:09CiaaF35nRmxrzWZ2uRq5v6Ghg/d2RiPjZnSgtt+RQ= +github.com/aws/aws-sdk-go v1.44.224/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= @@ -46,8 +291,15 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 h1:41iFGWnSlI2gVpmOtVTJZNodLdLQLn/KsJqFvXwnd/s= +github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrfdnWo= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= @@ -58,27 +310,54 @@ github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 h1:KdUfX2zKommPRa+PD0sWZUyXe9 github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= +github.com/bufbuild/protocompile v0.6.0 h1:Uu7WiSQ6Yj9DbkdnOe7U4mNKp58y9WDMKDn28/ZlunY= +github.com/bufbuild/protocompile v0.6.0/go.mod h1:YNP35qEYoYGme7QMtz5SBCoN4kL4g12jTtjuzRNdjpE= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/bxcodec/faker v2.0.1+incompatible h1:P0KUpUw5w6WJXwrPfv35oc91i4d8nf40Nwln+M/+faA= github.com/bxcodec/faker v2.0.1+incompatible/go.mod h1:BNzfpVdTwnFJ6GtfYTcQu6l6rHShT+veBxNCnjCx5XM= github.com/bytecodealliance/wasmtime-go/v15 v15.0.0 h1:4R2MpSPPbtSxqdsOTvsMn1pnwdEhzbDGMao6LUUSLv4= github.com/bytecodealliance/wasmtime-go/v15 v15.0.0/go.mod h1:m6vB/SsM+pnJkVHmO1wzHYUeYtciltTKuxuvkR8pYcY= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM= +github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= +github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= +github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= +github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/errors v1.11.1 h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZazG8= @@ -91,29 +370,58 @@ github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwP github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/cometbft/cometbft v0.38.8 h1:XyJ9Cu3xqap6xtNxiemrO8roXZ+KS2Zlu7qQ0w1trvU= github.com/cometbft/cometbft v0.38.8/go.mod h1:xOoGZrtUT+A5izWfHSJgl0gYZUE7lu7Z2XIS1vWG/QQ= +github.com/cometbft/cometbft-db v0.9.1 h1:MIhVX5ja5bXNHF8EYrThkG9F7r9kSfv8BX4LWaxWJ4M= +github.com/cometbft/cometbft-db v0.9.1/go.mod h1:iliyWaoV0mRwBJoizElCwwRA9Tf7jZJOURcRZF9m60U= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= +github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= +github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= +github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= github.com/cosmos/cosmos-db v1.0.2 h1:hwMjozuY1OlJs/uh6vddqnk9j7VamLv+0DBlbEXbAKs= github.com/cosmos/cosmos-db v1.0.2/go.mod h1:Z8IXcFJ9PqKK6BIsVOB3QXtkKoqUOp1vRvPT39kOXEA= +github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= +github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= +github.com/cosmos/cosmos-sdk v0.50.6 h1:efR3MsvMHX5sxS3be+hOobGk87IzlZbSpsI2x/Vw3hk= +github.com/cosmos/cosmos-sdk v0.50.6/go.mod h1:lVkRY6cdMJ0fG3gp8y4hFrsKZqF4z7y0M2UXFb9Yt40= +github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= +github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= +github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= +github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= +github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= github.com/cosmos/gogoproto v1.5.0 h1:SDVwzEqZDDBoslaeZg+dGE55hdzHfgUA40pEanMh52o= github.com/cosmos/gogoproto v1.5.0/go.mod h1:iUM31aofn3ymidYG6bUR5ZFrk+Om8p5s754eMUcyp8I= github.com/cosmos/iavl v1.1.2 h1:zL9FK7C4L/P4IF1Dm5fIwz0WXCnn7Bp1M2FxH0ayM7Y= github.com/cosmos/iavl v1.1.2/go.mod h1:jLeUvm6bGT1YutCaL2fIar/8vGUE8cPZvh/gXEWDaDM= +github.com/cosmos/ibc-go/modules/capability v1.0.0 h1:r/l++byFtn7jHYa09zlAdSeevo8ci1mVZNO9+V0xsLE= +github.com/cosmos/ibc-go/modules/capability v1.0.0/go.mod h1:D81ZxzjZAe0ZO5ambnvn1qedsFQ8lOwtqicG6liLBco= +github.com/cosmos/ibc-go/v8 v8.0.0 h1:QKipnr/NGwc+9L7NZipURvmSIu+nw9jOIWTJuDBqOhg= +github.com/cosmos/ibc-go/v8 v8.0.0/go.mod h1:C6IiJom0F3cIQCD5fKwVPDrDK9j/xTu563AWuOmXois= github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= +github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM= +github.com/cosmos/ledger-cosmos-go v0.13.3/go.mod h1:HENcEP+VtahZFw38HZ3+LS3Iv5XV6svsnkk9vdJtLr8= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 h1:ZFUue+PNxmHlu7pYv+IYMtqlaO/0VwaGEqKepZf9JpA= github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= @@ -131,37 +439,69 @@ 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/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= +github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= +github.com/dgraph-io/badger/v2 v2.2007.4/go.mod h1:vSw/ax2qojzbN6eXHIx6KPKtCSHJN/Uz0X0VPruTIhk= github.com/dgraph-io/badger/v3 v3.2011.1 h1:Hmyof0WMEF/QtutX5SQHzIMnJQxb/IrSzhjckV2SD6g= github.com/dgraph-io/badger/v3 v3.2011.1/go.mod h1:0rLLrQpKVQAL0or/lBLMQznhr6dWWX7h5AKnmnqx268= +github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/dvsekhvalnov/jose2go v1.6.0 h1:Y9gnSnP4qEI0+/uQkHvFXeD2PLPJeXEL+ySMEA2EjTY= +github.com/dvsekhvalnov/jose2go v1.6.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elastic/gosigar v0.14.3 h1:xwkKwPia+hSfg9GqrCUKYdId102m9qTJIIr7egmK/uo= github.com/elastic/gosigar v0.14.3/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/emicklei/dot v1.6.1 h1:ujpDlBkkwgWUY+qPId5IwapRW/xEoligRSYjioR6DFI= github.com/emicklei/dot v1.6.1/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg= github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -178,6 +518,11 @@ github.com/getkin/kin-openapi v0.125.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5 github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= +github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= @@ -186,10 +531,24 @@ github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vz github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-jose/go-jose/v3 v3.0.1-0.20221117193127-916db76e8214 h1:w5li6eMV6NCHh1YVbKRM/gMCVtZ2w7mnwq78eNnHXQQ= +github.com/go-jose/go-jose/v3 v3.0.1-0.20221117193127-916db76e8214/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= +github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= +github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= +github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -199,14 +558,19 @@ github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbX github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= github.com/go-openapi/swag v0.22.8 h1:/9RjDSQ0vbFR+NyjGMkFTsA1IA0fmhKSThmfGZjicbw= github.com/go-openapi/swag v0.22.8/go.mod h1:6QT22icPLEqAM/z/TChgb4WAveCHF92+2gF0CNjHpPI= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.15.1 h1:BSe8uhN+xQ4r5guV/ywQI4gO59C2raYcGffYWZEjZzM= github.com/go-playground/validator/v10 v10.15.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= @@ -214,30 +578,59 @@ github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZ github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= +github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid/v5 v5.2.0 h1:qw1GMx6/y8vhVsx626ImfKMuS5CvJmhIKKtuyvfajMM= github.com/gofrs/uuid/v5 v5.2.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= +github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= +github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -247,12 +640,16 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 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.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= github.com/google/flatbuffers v2.0.6+incompatible h1:XHFReMv7nFFusa+CEokzWbzaYocKXI6C7hdU5Kgh9Lw= @@ -261,55 +658,149 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= +github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8 h1:ASJ/LAqdCHOyMYI+dwNxn7Rd8FscNkMyTr1KZU1JI/M= github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= +github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= +github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= +github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= +github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f h1:KMlcu9X58lhTA/KrfX8Bi1LQSO4pzoVjTiL3h4Jk+Zk= github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= +github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= +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-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= +github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-getter v1.7.3 h1:bN2+Fw9XPFvOCjB0UOevFIMICZ7G2XSQHzfvLUyOM5E= +github.com/hashicorp/go-getter v1.7.3/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= +github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= +github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-metrics v0.5.3 h1:M5uADWMOGCTUNU1YuC4hfknOeHNaX54LDm4oYSucoNE= github.com/hashicorp/go-metrics v0.5.3/go.mod h1:KEjodfebIOuBYSAe/bHTm+HChmKSxAOXPBieMLYozDE= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A= +github.com/hashicorp/go-plugin v1.6.0/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= +github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/arc/v2 v2.0.7 h1:QxkVTxwColcduO+LP7eJO56r2hFiG8zEbfAAzRv52KQ= @@ -318,9 +809,22 @@ github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= +github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU= +github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hsanjuan/ipfs-lite v1.8.1 h1:Rpd9bTXYgkmnt8M5QsZnWwtW6ebxAB7HlU/d0zE4BmA= github.com/hsanjuan/ipfs-lite v1.8.1/go.mod h1:oGCaHBi+I73UFjc6wPAQ75hr4FjJhoqy6YPZjtghDIc= +github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= +github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= +github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= +github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/hyperledger/aries-framework-go v0.3.2 h1:GsSUaSEW82cr5X8b3Qf90GAi37kmTKHqpPJLhar13X8= @@ -337,9 +841,16 @@ github.com/hyperledger/aries-framework-go/spi v0.0.0-20230427134832-0c9969493bd3 github.com/hyperledger/aries-framework-go/spi v0.0.0-20230427134832-0c9969493bd3/go.mod h1:oryUyWb23l/a3tAP9KW+GBbfcfqp9tZD4y5hSkFrkqI= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ignite/cli/v28 v28.4.0 h1:i7Um7APUsBwKJexLxoMuynXmXlVZQPS0UPnfqmMBSjY= +github.com/ignite/cli/v28 v28.4.0/go.mod h1:134NUUb4d5jVtlu1jyDIGJMNrQy5XO3GwPlu03HMkhE= +github.com/improbable-eng/grpc-web v0.15.0 h1:BN+7z6uNXZ1tQGcNAuaU1YjsLTApzkjt2tzCixLaUPQ= +github.com/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY= github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= @@ -401,26 +912,50 @@ github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPw github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= +github.com/jhump/protoreflect v1.15.3 h1:6SFRuqU45u9hIZPJAoZ8c28T3nK64BNdp9w6jFonzls= +github.com/jhump/protoreflect v1.15.3/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= +github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jorrizza/ed2curve25519 v0.1.0 h1:P58ZEiVKW4vknYuGyOXuskMm82rTJyGhgRGrMRcCE8E= github.com/jorrizza/ed2curve25519 v0.1.0/go.mod h1:27VPNk2FnNqLQNvvVymiX41VE/nokPyn5HHP7gtfYlo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69 h1:kMJlf8z8wUcpyI+FQJIdGjAhfTww1y0AbQEv86bpVQI= github.com/kilic/bls12-381 v0.1.1-0.20210503002446-7b7597926c69/go.mod h1:tlkavyke+Ac7h8R3gZIjI5LKBcvMlSWnXNMgT3vZXo8= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -435,6 +970,7 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lens-vm/lens/host-go v0.0.0-20231127204031-8d858ed2926c h1:bG+mr4SqbYRU69L6CSvHDsKbRg5Q9vaN2T5g7qcrPdQ= github.com/lens-vm/lens/host-go v0.0.0-20231127204031-8d858ed2926c/go.mod h1:a4edl+KcOVk1Nj3EjG77htqg2/0Mmy3bSG0kl+FWVqQ= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N+AkAr5k= @@ -449,6 +985,8 @@ github.com/lestrrat-go/jwx/v2 v2.1.0 h1:0zs7Ya6+39qoit7gwAf+cYm1zzgS3fceIdo7RmQ5 github.com/lestrrat-go/jwx/v2 v2.1.0/go.mod h1:Xpw9QIaUGiIUD1Wx0NcY1sIHwFf8lDuZn/cmxtXYRys= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= @@ -485,27 +1023,42 @@ github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCy github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/libp2p/zeroconf/v2 v2.2.0 h1:Cup06Jv6u81HLhIj1KasuNM/RHHrJ8T7wOTS4+Tv53Q= github.com/libp2p/zeroconf/v2 v2.2.0/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/linxGnu/grocksdb v1.8.14 h1:HTgyYalNwBSG/1qCQUIott44wU5b2Y9Kr3z7SK5OfGQ= github.com/linxGnu/grocksdb v1.8.14/go.mod h1:QYiYypR2d4v63Wj1adOOfzglnoII0gLj3PNh4fZkcFA= github.com/lmittmann/tint v1.0.4 h1:LeYihpJ9hyGvE0w+K2okPTGUdVLfng1+nDNVR4vWISc= github.com/lmittmann/tint v1.0.4/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA= +github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= @@ -516,22 +1069,38 @@ github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKo github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= +github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= +github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= @@ -557,15 +1126,32 @@ github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/grpc-proxy v0.0.0-20181017164139-0f1106ef9c76/go.mod h1:x5OoJHDHqxHS801UIuhqGl6QdSAEJvtausosHSdazIo= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a h1:dlRvE5fWabOchtH7znfiFCcOvmIYgOeAS5ifBXBlh9Q= github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA= +github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= @@ -574,6 +1160,7 @@ github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042 github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= @@ -581,23 +1168,49 @@ github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAl github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= +github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/runc v1.1.12 h1:BOIssBaW1La0/qbNZHXOOa71dZfZEQOzW7dqQf3phss= +github.com/opencontainers/runc v1.1.12/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= +github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 h1:jik8PHtAIsPlCRJjJzl4udgEf7hawInF9texMeO2jrU= github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pion/datachannel v1.5.6 h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGeg= @@ -651,34 +1264,48 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE 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/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= 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/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc= github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8= github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= @@ -689,10 +1316,18 @@ github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= +github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= @@ -700,14 +1335,17 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= 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.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= @@ -736,13 +1374,18 @@ github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYED github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= @@ -761,20 +1404,34 @@ github.com/sourcenetwork/immutable v0.3.0 h1:gHPtGvLrTBTK5YpDAhMU+u+S8v1F6iYmc3n github.com/sourcenetwork/immutable v0.3.0/go.mod h1:GD7ceuh/HD7z6cdIwzKK2ctzgZ1qqYFJpsFp+8qYnbI= github.com/sourcenetwork/raccoondb v0.2.1-0.20240606193653-1e91e9be9234 h1:8dA9bVC1A0ChJygtsUfNsek3oR0GnwpLoYpmEo4t2mk= github.com/sourcenetwork/raccoondb v0.2.1-0.20240606193653-1e91e9be9234/go.mod h1:JvZ+G3QTmv7zto3tUBxnV0+fPoev0DkObSwczTm9VJE= +github.com/sourcenetwork/sourcehub v0.2.1-0.20240704194128-f43f5e427274 h1:llH2tge8H5aw2gT6bCFnXK2ZAYuUS6PjIsZg4nikWc8= +github.com/sourcenetwork/sourcehub v0.2.1-0.20240704194128-f43f5e427274/go.mod h1:spQwqm6P+KB8MsR9rPkWkncIHGFtqUqPWwjkv1nhfdA= github.com/sourcenetwork/zanzi v0.3.1-0.20240606201400-df5f801d0bd4 h1:lO0ZSZ75qdQPp+ZcHEDy+kyHQhnf6ZDB1V5TjQW422w= github.com/sourcenetwork/zanzi v0.3.1-0.20240606201400-df5f801d0bd4/go.mod h1:QdM0NfYxQd10WAPUTVAA1X10y5IgZ/CXs3gpD5YxdCE= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -801,6 +1458,8 @@ github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSW github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= +github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= github.com/tetratelabs/wazero v1.5.0 h1:Yz3fZHivfDiZFUXnWMPUoiW7s8tC1sjdBtlJn08qYa0= github.com/tetratelabs/wazero v1.5.0/go.mod h1:0U0G41+ochRKoPKCJlh0jMg1CHkyfK8kDqiirMmKY8A= github.com/textileio/go-datastore-extensions v1.0.1 h1:qIJGqJaigQ1wD4TdwS/hf73u0HChhXvvUSJuxBEKS+c= @@ -811,9 +1470,18 @@ github.com/textileio/go-log/v2 v2.1.3-gke-2 h1:YkMA5ua0Cf/X6CkbexInsoJ/HdaHQBlgi github.com/textileio/go-log/v2 v2.1.3-gke-2/go.mod h1:DwACkjFS3kjZZR/4Spx3aPfSsciyslwUe5bxV8CEU2w= github.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI= github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= +github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ= @@ -836,15 +1504,40 @@ github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdz github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8= github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= +github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= +github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= +github.com/zondax/ledger-go v0.14.3 h1:wEpJt2CEcBJ428md/5MgSLsXLBos98sBOyxNmCjfUCw= +github.com/zondax/ledger-go v0.14.3/go.mod h1:IKKaoxupuB43g4NxeQmbLXv7T9AlQyie1UpHb342ycI= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= +go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 h1:9l89oX4ba9kHbBol3Xin3leYJ+252h0zszDtBwyKe2A= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0/go.mod h1:XLZfZboOJWHNKUv7eH0inh0E9VV6eWDFB/9yJyTLPp0= go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= @@ -855,37 +1548,53 @@ go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2N go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= go.uber.org/fx v1.22.0 h1:pApUK7yL0OUHMd8vkunWSlLxZVFFk70jR2nKde8X2NM= go.uber.org/fx v1.22.0/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -898,18 +1607,43 @@ golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOM golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -918,27 +1652,65 @@ golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= @@ -953,6 +1725,31 @@ golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAG golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= 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= @@ -960,48 +1757,118 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190130150945-aca44879d564/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1017,6 +1884,7 @@ golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= @@ -1027,11 +1895,16 @@ golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/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.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= @@ -1041,8 +1914,11 @@ golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1050,16 +1926,60 @@ golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= @@ -1069,23 +1989,188 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T 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-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= +golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.15.0 h1:2lYxjRbTYyxkJxlhC+LvJIx3SsANPdRybu1tGj9/OrQ= gonum.org/v1/gonum v0.15.0/go.mod h1:xzZVBJBtS+Mz4q0Yl2LJTk+OxOg4jiXZ7qBoM0uISGo= google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= +google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI= +google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= +google.golang.org/api v0.171.0 h1:w174hnBPqut76FzW5Qaupt7zY8Kql6fiVjgys4f58sU= +google.golang.org/api v0.171.0/go.mod h1:Hnq5AHm4OTMt2BUVjael2CWZFD6vksJdWCWiUAmjC9o= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo= +google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= +google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= +google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 h1:MuYw1wJzT+ZkybKfaOXKp5hJiZDn2iHaXRw0mRYdHSc= google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4/go.mod h1:px9SlOOZBg1wM1zdnr8jEL4CNGUBZ+ZKYtNPApNQc4c= google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 h1:Di6ANFilr+S60a4S61ZM00vLdw0IrQOSMS2/6mrnOU0= @@ -1094,12 +2179,48 @@ google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmE google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1108,9 +2229,13 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= @@ -1118,17 +2243,25 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks 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-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1140,18 +2273,30 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= +pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/http/auth.go b/http/auth.go index f62f1e25af..0c2d6ae28d 100644 --- a/http/auth.go +++ b/http/auth.go @@ -11,13 +11,9 @@ package http import ( - "encoding/hex" "net/http" "strings" - "time" - "github.com/decred/dcrd/dcrec/secp256k1/v4" - "github.com/lestrrat-go/jwx/v2/jwa" "github.com/lestrrat-go/jwx/v2/jws" "github.com/lestrrat-go/jwx/v2/jwt" "github.com/sourcenetwork/immutable" @@ -33,67 +29,24 @@ const ( // authSchemaPrefix is the prefix added to the // authorization header value. authSchemaPrefix = "Bearer " - // authTokenExpiration is the default expiration time for auth tokens. - authTokenExpiration = time.Minute * 15 ) -var authTokenSignatureScheme = jwa.ES256K - -// buildAuthToken returns a new jwt auth token with the subject and audience set -// to the given values. Default expiration and not before values will also be set. -func buildAuthToken(identity acpIdentity.Identity, audience string) (jwt.Token, error) { - if identity.PublicKey == nil { - return nil, ErrMissingIdentityPublicKey - } - subject := hex.EncodeToString(identity.PublicKey.SerializeCompressed()) - now := time.Now() - return jwt.NewBuilder(). - Subject(subject). - Audience([]string{audience}). - Expiration(now.Add(authTokenExpiration)). - NotBefore(now). - Build() -} - -// signAuthToken returns a signed jwt auth token that can be used to authenticate the -// actor identified by the given identity with a defraDB node identified by the given audience. -func signAuthToken(identity acpIdentity.Identity, token jwt.Token) ([]byte, error) { - if identity.PrivateKey == nil { - return nil, ErrMissingIdentityPrivateKey - } - return jwt.Sign(token, jwt.WithKey(authTokenSignatureScheme, identity.PrivateKey.ToECDSA())) -} - -// buildAndSignAuthToken returns a signed jwt auth token that can be used to authenticate the -// actor identified by the given identity with a defraDB node identified by the given audience. -func buildAndSignAuthToken(identity acpIdentity.Identity, audience string) ([]byte, error) { - token, err := buildAuthToken(identity, audience) - if err != nil { - return nil, err - } - return signAuthToken(identity, token) -} - // verifyAuthToken verifies that the jwt auth token is valid and that the signature // matches the identity of the subject. -func verifyAuthToken(data []byte, audience string) (immutable.Option[acpIdentity.Identity], error) { - token, err := jwt.Parse(data, jwt.WithVerify(false), jwt.WithAudience(audience)) +func verifyAuthToken(identity acpIdentity.Identity, audience string) error { + _, err := jwt.Parse([]byte(identity.BearerToken), jwt.WithVerify(false), jwt.WithAudience(audience)) if err != nil { - return immutable.None[acpIdentity.Identity](), err + return err } - subject, err := hex.DecodeString(token.Subject()) - if err != nil { - return immutable.None[acpIdentity.Identity](), err - } - pubKey, err := secp256k1.ParsePubKey(subject) - if err != nil { - return immutable.None[acpIdentity.Identity](), err - } - _, err = jws.Verify(data, jws.WithKey(authTokenSignatureScheme, pubKey.ToECDSA())) + + _, err = jws.Verify( + []byte(identity.BearerToken), + jws.WithKey(acpIdentity.BearerTokenSignatureScheme, identity.PublicKey.ToECDSA()), + ) if err != nil { - return immutable.None[acpIdentity.Identity](), err + return err } - return acpIdentity.FromPublicKey(pubKey) + return nil } // AuthMiddleware authenticates an actor and sets their identity for all subsequent actions. @@ -104,12 +57,20 @@ func AuthMiddleware(next http.Handler) http.Handler { next.ServeHTTP(rw, req) return } - identity, err := verifyAuthToken([]byte(token), strings.ToLower(req.Host)) + + identity, err := acpIdentity.FromToken([]byte(token)) if err != nil { http.Error(rw, "forbidden", http.StatusForbidden) return } - ctx := db.SetContextIdentity(req.Context(), identity) + + err = verifyAuthToken(identity, strings.ToLower(req.Host)) + if err != nil { + http.Error(rw, "forbidden", http.StatusForbidden) + return + } + + ctx := db.SetContextIdentity(req.Context(), immutable.Some(identity)) next.ServeHTTP(rw, req.WithContext(ctx)) }) } diff --git a/http/auth_test.go b/http/auth_test.go index 8aa9293eaf..7e7489e862 100644 --- a/http/auth_test.go +++ b/http/auth_test.go @@ -11,11 +11,10 @@ package http import ( - "encoding/hex" "testing" "time" - "github.com/lestrrat-go/jwx/v2/jwt" + "github.com/sourcenetwork/immutable" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -23,126 +22,58 @@ import ( "github.com/sourcenetwork/defradb/crypto" ) -func TestBuildAuthToken(t *testing.T) { - privKey, err := crypto.GenerateSecp256k1() - require.NoError(t, err) - - identity, err := acpIdentity.FromPrivateKey(privKey) - require.NoError(t, err) - token, err := buildAuthToken(identity.Value(), "abc123") - require.NoError(t, err) - - subject := hex.EncodeToString(privKey.PubKey().SerializeCompressed()) - assert.Equal(t, subject, token.Subject()) - - assert.True(t, token.NotBefore().Before(time.Now())) - assert.True(t, token.Expiration().After(time.Now())) - assert.Equal(t, []string{"abc123"}, token.Audience()) -} - -func TestSignAuthTokenErrorsWithPublicIdentity(t *testing.T) { - privKey, err := crypto.GenerateSecp256k1() - require.NoError(t, err) - - identity, err := acpIdentity.FromPublicKey(privKey.PubKey()) - require.NoError(t, err) - token, err := buildAuthToken(identity.Value(), "abc123") - require.NoError(t, err) - - _, err = signAuthToken(identity.Value(), token) - assert.ErrorIs(t, err, ErrMissingIdentityPrivateKey) -} - func TestVerifyAuthToken(t *testing.T) { - privKey, err := crypto.GenerateSecp256k1() - require.NoError(t, err) + audience := "abc123" - identity, err := acpIdentity.FromPrivateKey(privKey) - require.NoError(t, err) - token, err := buildAndSignAuthToken(identity.Value(), "abc123") + privKey, err := crypto.GenerateSecp256k1() require.NoError(t, err) - actual, err := verifyAuthToken(token, "abc123") + identity, err := acpIdentity.FromPrivateKey( + privKey, + time.Hour, + immutable.Some(audience), + immutable.None[string](), + false, + ) require.NoError(t, err) - expected, err := acpIdentity.FromPublicKey(privKey.PubKey()) + err = verifyAuthToken(identity, audience) require.NoError(t, err) - assert.Equal(t, expected.Value().DID, actual.Value().DID) } func TestVerifyAuthTokenErrorsWithNonMatchingAudience(t *testing.T) { privKey, err := crypto.GenerateSecp256k1() require.NoError(t, err) - identity, err := acpIdentity.FromPrivateKey(privKey) - require.NoError(t, err) - token, err := buildAndSignAuthToken(identity.Value(), "valid") - require.NoError(t, err) - - _, err = verifyAuthToken(token, "invalid") - assert.Error(t, err) -} - -func TestVerifyAuthTokenErrorsWithWrongPublicKey(t *testing.T) { - privKey, err := crypto.GenerateSecp256k1() - require.NoError(t, err) - - otherKey, err := crypto.GenerateSecp256k1() - require.NoError(t, err) - - identity, err := acpIdentity.FromPrivateKey(privKey) - require.NoError(t, err) - token, err := buildAuthToken(identity.Value(), "123abc") - require.NoError(t, err) - - // override subject - subject := hex.EncodeToString(otherKey.PubKey().SerializeCompressed()) - err = token.Set(jwt.SubjectKey, subject) - require.NoError(t, err) - - data, err := signAuthToken(identity.Value(), token) + identity, err := acpIdentity.FromPrivateKey( + privKey, + time.Hour, + immutable.Some("valid"), + immutable.None[string](), + false, + ) require.NoError(t, err) - _, err = verifyAuthToken(data, "123abc") + err = verifyAuthToken(identity, "invalid") assert.Error(t, err) } func TestVerifyAuthTokenErrorsWithExpired(t *testing.T) { - privKey, err := crypto.GenerateSecp256k1() - require.NoError(t, err) + audience := "abc123" - identity, err := acpIdentity.FromPrivateKey(privKey) - require.NoError(t, err) - token, err := buildAuthToken(identity.Value(), "123abc") - require.NoError(t, err) - - // override expiration - err = token.Set(jwt.ExpirationKey, time.Now().Add(-15*time.Minute)) - require.NoError(t, err) - - data, err := signAuthToken(identity.Value(), token) - require.NoError(t, err) - - _, err = verifyAuthToken(data, "123abc") - assert.Error(t, err) -} - -func TestVerifyAuthTokenErrorsWithNotBefore(t *testing.T) { privKey, err := crypto.GenerateSecp256k1() require.NoError(t, err) - identity, err := acpIdentity.FromPrivateKey(privKey) - require.NoError(t, err) - token, err := buildAuthToken(identity.Value(), "123abc") - require.NoError(t, err) - - // override not before - err = token.Set(jwt.NotBeforeKey, time.Now().Add(15*time.Minute)) - require.NoError(t, err) - - data, err := signAuthToken(identity.Value(), token) + identity, err := acpIdentity.FromPrivateKey( + privKey, + // negative expiration + -time.Hour, + immutable.Some(audience), + immutable.None[string](), + false, + ) require.NoError(t, err) - _, err = verifyAuthToken(data, "123abc") + err = verifyAuthToken(identity, "123abc") assert.Error(t, err) } diff --git a/http/http_client.go b/http/http_client.go index b3dfcb9e3f..e13b40dd11 100644 --- a/http/http_client.go +++ b/http/http_client.go @@ -12,7 +12,6 @@ package http import ( "encoding/json" - "errors" "fmt" "io" "net/http" @@ -53,14 +52,7 @@ func (c *httpClient) setDefaultHeaders(req *http.Request) error { if !id.HasValue() { return nil } - token, err := buildAndSignAuthToken(id.Value(), strings.ToLower(c.baseURL.Host)) - if errors.Is(err, ErrMissingIdentityPrivateKey) { - return nil - } - if err != nil { - return err - } - req.Header.Set(authHeaderName, fmt.Sprintf("%s%s", authSchemaPrefix, token)) + req.Header.Set(authHeaderName, fmt.Sprintf("%s%s", authSchemaPrefix, []byte(id.Value().BearerToken))) return nil } diff --git a/internal/db/db.go b/internal/db/db.go index 197ab493d5..81ec48e199 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -186,7 +186,7 @@ func (db *db) AddPolicy( policyID, err := db.acp.Value().AddPolicy( ctx, - identity.Value().DID, + identity.Value(), policy, ) if err != nil { diff --git a/internal/db/p2p_schema_root_test.go b/internal/db/p2p_schema_root_test.go index 8039f815b0..16d95394f6 100644 --- a/internal/db/p2p_schema_root_test.go +++ b/internal/db/p2p_schema_root_test.go @@ -15,11 +15,11 @@ import ( "encoding/hex" "fmt" "testing" + "time" "github.com/decred/dcrd/dcrec/secp256k1/v4" - "github.com/stretchr/testify/require" - "github.com/sourcenetwork/immutable" + "github.com/stretchr/testify/require" "github.com/sourcenetwork/defradb/acp" acpIdentity "github.com/sourcenetwork/defradb/acp/identity" @@ -279,17 +279,17 @@ func TestAddP2PCollectionsWithPermissionedCollection_Error(t *testing.T) { privKeyBytes, err := hex.DecodeString("028d53f37a19afb9a0dbc5b4be30c65731479ee8cfa0c9bc8f8bf198cc3c075f") require.NoError(t, err) privKey := secp256k1.PrivKeyFromBytes(privKeyBytes) - identity, err := acpIdentity.FromPrivateKey(privKey) + identity, err := acpIdentity.FromPrivateKey(privKey, time.Hour, immutable.None[string](), immutable.None[string](), false) require.NoError(t, err) - ctx = SetContextIdentity(ctx, identity) + ctx = SetContextIdentity(ctx, immutable.Some(identity)) policyResult, err := db.AddPolicy(ctx, policy) policyID := policyResult.PolicyID require.NoError(t, err) require.Equal(t, "7b5ed30570e8d9206027ef6d5469879a6c1ea4595625c6ca33a19063a6ed6214", policyID) schema := fmt.Sprintf(` - type User @policy(id: "%s", resource: "user") { + type User @policy(id: "%s", resource: "user") { name: String age: Int } diff --git a/internal/db/permission/register.go b/internal/db/permission/register.go index 0f6e0c8587..dedbdd8d63 100644 --- a/internal/db/permission/register.go +++ b/internal/db/permission/register.go @@ -40,7 +40,7 @@ func RegisterDocOnCollectionWithACP( if policyID, resourceName, hasPolicy := isPermissioned(collection); hasPolicy && identity.HasValue() { return acpSystem.RegisterDocObject( ctx, - identity.Value().DID, + identity.Value(), policyID, resourceName, docID, diff --git a/keyring/signer.go b/keyring/signer.go new file mode 100644 index 0000000000..25b8db8db8 --- /dev/null +++ b/keyring/signer.go @@ -0,0 +1,66 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package keyring + +import ( + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + cosmostypes "github.com/cosmos/cosmos-sdk/types" + "github.com/sourcenetwork/sourcehub/sdk" +) + +type txnSigner struct { + keyring Keyring + keyName string + + // accAddress is public info and can be safely cached + accAddress string +} + +var _ sdk.TxSigner = (*txnSigner)(nil) + +// NewTxSignerFromKeyringKey creates a new TxSigner backed by a keyring. +// +// The key used for signing is not cached and will be fetched from the keyring every time it +// is requested. This minimizes the risk of it being leaked via stuff like memory paging. +func NewTxSignerFromKeyringKey(keyring Keyring, keyName string) (*txnSigner, error) { + bytes, err := keyring.Get(keyName) + if err != nil { + return nil, err + } + + key := &secp256k1.PrivKey{ + Key: bytes, + } + addr := key.PubKey().Address().Bytes() + accAddress := cosmostypes.AccAddress(addr).String() + + return &txnSigner{ + keyring: keyring, + keyName: keyName, + accAddress: accAddress, + }, nil +} + +func (s *txnSigner) GetAccAddress() string { + return s.accAddress +} + +func (s *txnSigner) GetPrivateKey() cryptotypes.PrivKey { + bytes, err := s.keyring.Get(s.keyName) + if err != nil { + panic(err) + } + + return &secp256k1.PrivKey{ + Key: bytes, + } +} diff --git a/node/acp.go b/node/acp.go index 0df33269e9..4123df00f1 100644 --- a/node/acp.go +++ b/node/acp.go @@ -14,15 +14,17 @@ import ( "context" "github.com/sourcenetwork/immutable" + "github.com/sourcenetwork/sourcehub/sdk" "github.com/sourcenetwork/defradb/acp" ) -type ACPType uint8 +type ACPType string const ( - NoACPType ACPType = 0 - LocalACPType ACPType = 1 + NoACPType ACPType = "none" + LocalACPType ACPType = "local" + SourceHubACPType ACPType = "source-hub" ) // ACPOptions contains ACP configuration values. @@ -30,7 +32,14 @@ type ACPOptions struct { acpType ACPType // Note: An empty path will result in an in-memory ACP instance. + // + // This is only used for local acp. path string + + signer immutable.Option[sdk.TxSigner] + sourceHubChainID string + sourceHubGRPCAddress string + sourceHubCometRPCAddress string } // DefaultACPOptions returns new options with default values. @@ -59,6 +68,39 @@ func WithACPPath(path string) ACPOpt { } } +// WithKeyring sets the txn signer for Defra to use. +// +// It is only required when SourceHub ACP is active. +func WithTxnSigner(signer immutable.Option[sdk.TxSigner]) ACPOpt { + return func(o *ACPOptions) { + o.signer = signer + } +} + +// WithSourceHubChainID specifies the chainID of the SourceHub (cosmos) chain +// to use for SourceHub ACP. +func WithSourceHubChainID(sourceHubChainID string) ACPOpt { + return func(o *ACPOptions) { + o.sourceHubChainID = sourceHubChainID + } +} + +// WithSourceHubGRPCAddress specifies the GRPC address of the SourceHub node to use +// for ACP calls. +func WithSourceHubGRPCAddress(address string) ACPOpt { + return func(o *ACPOptions) { + o.sourceHubGRPCAddress = address + } +} + +// WithSourceHubCometRPCAddress specifies the Comet RPC address of the SourceHub node to use +// for ACP calls. +func WithSourceHubCometRPCAddress(address string) ACPOpt { + return func(o *ACPOptions) { + o.sourceHubCometRPCAddress = address + } +} + // NewACP returns a new ACP module with the given options. func NewACP(ctx context.Context, opts ...ACPOpt) (immutable.Option[acp.ACP], error) { options := DefaultACPOptions() @@ -75,6 +117,23 @@ func NewACP(ctx context.Context, opts ...ACPOpt) (immutable.Option[acp.ACP], err acpLocal.Init(ctx, options.path) return immutable.Some[acp.ACP](acpLocal), nil + case SourceHubACPType: + if !options.signer.HasValue() { + return acp.NoACP, ErrSignerMissingForSourceHubACP + } + + acpSourceHub, err := acp.NewSourceHubACP( + options.sourceHubChainID, + options.sourceHubGRPCAddress, + options.sourceHubCometRPCAddress, + options.signer.Value(), + ) + if err != nil { + return acp.NoACP, err + } + + return immutable.Some(acpSourceHub), nil + default: acpLocal := acp.NewLocalACP() acpLocal.Init(ctx, options.path) diff --git a/node/errors.go b/node/errors.go index 2078915c0a..84f0cdb006 100644 --- a/node/errors.go +++ b/node/errors.go @@ -20,8 +20,9 @@ const ( ) var ( - ErrLensRuntimeNotSupported = errors.New(errLensRuntimeNotSupported) - ErrStoreTypeNotSupported = errors.New(errStoreTypeNotSupported) + ErrSignerMissingForSourceHubACP = errors.New("a txn signer must be provided for SourceHub ACP") + ErrLensRuntimeNotSupported = errors.New(errLensRuntimeNotSupported) + ErrStoreTypeNotSupported = errors.New(errStoreTypeNotSupported) ) func NewErrLensRuntimeNotSupported(lens LensRuntimeType) error { diff --git a/tests/change_detector/change_detector_test.go b/tests/change_detector/change_detector_test.go index badfc45ecb..3816493410 100644 --- a/tests/change_detector/change_detector_test.go +++ b/tests/change_detector/change_detector_test.go @@ -59,6 +59,8 @@ func TestChanges(t *testing.T) { sourceRepoPkgMap[pkg] = true } + hasRunOnce := false + for _, pkg := range targetRepoPkgList { pkgName := strings.TrimPrefix(pkg, "github.com/sourcenetwork/defradb/") t.Run(pkgName, func(t *testing.T) { @@ -66,7 +68,18 @@ func TestChanges(t *testing.T) { t.Skip("skipping unknown or new test package") } - t.Parallel() + if hasRunOnce { + // The first test runs very slowly, and if multiple tests are running concurrently + // all will be affected and the costs multiplied. It seems likely that this is + // compilation related, but that is not yet proven. + // + // Because of this the first sub-test will run on it's own, followed by the rest + // running in parallel. + t.Parallel() + } else { + hasRunOnce = true + } + dataDir := t.TempDir() sourceTestPkg := filepath.Join(sourceRepoDir, pkgName) diff --git a/tests/clients/cli/wrapper.go b/tests/clients/cli/wrapper.go index a6f3feef4c..14e4df7cc4 100644 --- a/tests/clients/cli/wrapper.go +++ b/tests/clients/cli/wrapper.go @@ -43,14 +43,17 @@ type Wrapper struct { httpServer *httptest.Server } -func NewWrapper(node *node.Node) (*Wrapper, error) { +// NewWrapper takes a Node, and a SourceHub address used to pay for SourceHub transactions. +// +// sourceHubAddress can (and will) be empty when testing non sourceHub ACP implementations. +func NewWrapper(node *node.Node, sourceHubAddress string) (*Wrapper, error) { handler, err := http.NewHandler(node.DB) if err != nil { return nil, err } httpServer := httptest.NewServer(handler) - cmd := newCliWrapper(httpServer.URL) + cmd := newCliWrapper(httpServer.URL, sourceHubAddress) return &Wrapper{ node: node, @@ -540,3 +543,7 @@ func (w *Wrapper) PrintDump(ctx context.Context) error { func (w *Wrapper) Bootstrap(addrs []peer.AddrInfo) { w.node.Peer.Bootstrap(addrs) } + +func (w *Wrapper) Host() string { + return w.httpServer.URL +} diff --git a/tests/clients/cli/wrapper_cli.go b/tests/clients/cli/wrapper_cli.go index ab3dd9ace4..39e5ef6290 100644 --- a/tests/clients/cli/wrapper_cli.go +++ b/tests/clients/cli/wrapper_cli.go @@ -22,12 +22,14 @@ import ( ) type cliWrapper struct { - address string + address string + sourceHubAddress string } -func newCliWrapper(address string) *cliWrapper { +func newCliWrapper(address string, sourceHubAddress string) *cliWrapper { return &cliWrapper{ - address: strings.TrimPrefix(address, "http://"), + address: strings.TrimPrefix(address, "http://"), + sourceHubAddress: sourceHubAddress, } } @@ -61,6 +63,7 @@ func (w *cliWrapper) executeStream(ctx context.Context, args []string) (io.ReadC id := db.GetContextIdentity(ctx) if id.HasValue() && id.Value().PrivateKey != nil { args = append(args, "--identity", hex.EncodeToString(id.Value().PrivateKey.Serialize())) + args = append(args, "--source-hub-address", w.sourceHubAddress) } args = append(args, "--url", w.address) diff --git a/tests/clients/http/wrapper.go b/tests/clients/http/wrapper.go index f183a4671a..76e31d9cbd 100644 --- a/tests/clients/http/wrapper.go +++ b/tests/clients/http/wrapper.go @@ -236,3 +236,7 @@ func (w *Wrapper) PrintDump(ctx context.Context) error { func (w *Wrapper) Bootstrap(addrs []peer.AddrInfo) { w.node.Peer.Bootstrap(addrs) } + +func (w *Wrapper) Host() string { + return w.httpServer.URL +} diff --git a/tests/integration/acp.go b/tests/integration/acp.go index e457a2625a..9a31856f5f 100644 --- a/tests/integration/acp.go +++ b/tests/integration/acp.go @@ -11,16 +11,60 @@ package tests import ( + "context" + "encoding/hex" + "fmt" + "io" "math/rand" + "net" + "os" + "os/exec" + "path/filepath" + "strings" + "sync/atomic" + "time" "github.com/decred/dcrd/dcrec/secp256k1/v4" + toml "github.com/pelletier/go-toml" "github.com/sourcenetwork/immutable" + "github.com/sourcenetwork/sourcehub/sdk" "github.com/stretchr/testify/require" acpIdentity "github.com/sourcenetwork/defradb/acp/identity" "github.com/sourcenetwork/defradb/internal/db" + "github.com/sourcenetwork/defradb/keyring" + "github.com/sourcenetwork/defradb/node" + "github.com/sourcenetwork/defradb/tests/clients/cli" + "github.com/sourcenetwork/defradb/tests/clients/http" ) +type ACPType string + +const ( + acpTypeEnvName = "DEFRA_ACP_TYPE" +) + +const ( + SourceHubACPType ACPType = "source-hub" + LocalACPType ACPType = "local" +) + +const ( + // authTokenExpiration is the expiration time for auth tokens. + authTokenExpiration = time.Minute * 1 +) + +var ( + acpType ACPType +) + +func init() { + acpType = ACPType(os.Getenv(acpTypeEnvName)) + if acpType == "" { + acpType = LocalACPType + } +} + // AddPolicy will attempt to add the given policy using DefraDB's ACP system. type AddPolicy struct { // NodeID may hold the ID (index) of the node we want to add policy to. @@ -54,8 +98,8 @@ func addPolicyACP( require.Fail(s.t, "Expected error should not have an expected policyID with it.", s.testCase.Description) } - for _, node := range getNodes(action.NodeID, s.nodes) { - identity := getIdentity(s, action.Identity) + for i, node := range getNodes(action.NodeID, s.nodes) { + identity := getIdentity(s, i, action.Identity) ctx := db.SetContextIdentity(s.ctx, identity) policyResult, err := node.AddPolicy(ctx, action.Policy) @@ -69,12 +113,306 @@ func addPolicyACP( } } -func getIdentity(s *state, index immutable.Option[int]) immutable.Option[acpIdentity.Identity] { +func setupSourceHub(s *state) ([]node.ACPOpt, error) { + var isACPTest bool + for _, a := range s.testCase.Actions { + if _, ok := a.(AddPolicy); ok { + isACPTest = true + break + } + } + if !isACPTest { + // Spinning up SourceHub instances is a bit slow, so we should be quite aggressive in trimming down the + // runtime of the test suite when SourceHub ACP is selected. + s.t.Skipf("test has no ACP elements when testing with SourceHub ACP") + } + + const moniker string = "foo" + const chainID string = "sourcehub-test" + const validatorName string = "test-validator" + const keyringBackend string = "test" + directory := s.t.TempDir() + + kr, err := keyring.OpenFileKeyring( + directory, + keyring.PromptFunc(func(s string) ([]byte, error) { + return []byte("secret"), nil + }), + ) + if err != nil { + return nil, err + } + + // Generate the keys using the index as the seed so that multiple + // runs yield the same private key. This is important for stuff like + // the change detector. + source := rand.NewSource(0) + r := rand.New(source) + + acpKey, err := secp256k1.GeneratePrivateKeyFromRand(r) + require.NoError(s.t, err) + acpKeyHex := hex.EncodeToString(acpKey.Serialize()) + + err = kr.Set(validatorName, acpKey.Serialize()) + if err != nil { + return nil, err + } + + out, err := exec.Command("sourcehubd", "init", moniker, "--chain-id", chainID, "--home", directory).CombinedOutput() + s.t.Log(string(out)) + if err != nil { + return nil, err + } + + // Annoyingly, the CLI does not support changing the comet config params that we need, + // so we have to manually rewrite the config file. + cfg, err := toml.LoadFile(filepath.Join(directory, "config", "config.toml")) + if err != nil { + return nil, err + } + + fo, err := os.Create(filepath.Join(directory, "config", "config.toml")) + if err != nil { + return nil, err + } + + // Speed up the rate at which the blocks are created, this is particularly important for getting + // the first block created on the `sourcehubd start` call at the end of this function as + // we cannot use the node until the first block has been created. + cfg.Set("consensus.timeout_propose", "0.5s") + cfg.Set("consensus.timeout_commit", "1s") + + _, err = cfg.WriteTo(fo) + if err != nil { + return nil, err + } + err = fo.Close() + if err != nil { + return nil, err + } + + out, err = exec.Command( + "sourcehubd", "keys", "import-hex", validatorName, acpKeyHex, + "--keyring-backend", keyringBackend, + "--home", directory, + ).CombinedOutput() + s.t.Log(string(out)) + if err != nil { + return nil, err + } + + out, err = exec.Command( + "sourcehubd", "keys", "show", validatorName, + "--address", + "--keyring-backend", keyringBackend, + "--home", directory, + ).CombinedOutput() + s.t.Log(string(out)) + if err != nil { + return nil, err + } + + // The result is suffexed with a newline char so we must trim the whitespace + validatorAddress := strings.TrimSpace(string(out)) + s.sourcehubAddress = validatorAddress + + out, err = exec.Command( + "sourcehubd", "genesis", "add-genesis-account", validatorAddress, "900000000stake", + "--keyring-backend", keyringBackend, + "--home", directory, + ).CombinedOutput() + s.t.Log(string(out)) + if err != nil { + return nil, err + } + + out, err = exec.Command( + "sourcehubd", "genesis", "gentx", validatorName, "10000000stake", + "--chain-id", chainID, + "--keyring-backend", keyringBackend, + "--home", directory, + ).CombinedOutput() + s.t.Log(string(out)) + if err != nil { + return nil, err + } + + out, err = exec.Command("sourcehubd", "genesis", "collect-gentxs", "--home", directory).CombinedOutput() + s.t.Log(string(out)) + if err != nil { + return nil, err + } + + // We need to lock across all the test processes as we assign ports to the source hub instance as this + // process involves finding free ports, dropping them, and then assigning them to the source hub node. + // + // We have to do this because source hub (cosmos) annoyingly does not support automatic port assignment + // (appart from the p2p port which we just manage here for consistency). + // + // We need to lock before getting the ports, otherwise they may try and use the port we use for locking. + // We can only unlock after the source hub node has started and begun listening on the assigned ports. + unlock, err := crossLock(55555) + if err != nil { + return nil, err + } + defer unlock() + + gRpcPort, releaseGrpcPort, err := getFreePort() + if err != nil { + return nil, err + } + + rpcPort, releaseRpcPort, err := getFreePort() + if err != nil { + return nil, err + } + + p2pPort, releaseP2pPort, err := getFreePort() + if err != nil { + return nil, err + } + + pprofPort, releasePprofPort, err := getFreePort() + if err != nil { + return nil, err + } + + gRpcAddress := fmt.Sprintf("127.0.0.1:%v", gRpcPort) + rpcAddress := fmt.Sprintf("tcp://127.0.0.1:%v", rpcPort) + p2pAddress := fmt.Sprintf("tcp://127.0.0.1:%v", p2pPort) + pprofAddress := fmt.Sprintf("127.0.0.1:%v", pprofPort) + + releaseGrpcPort() + releaseRpcPort() + releaseP2pPort() + releasePprofPort() + + sourceHubCmd := exec.Command( + "sourcehubd", + "start", + "--minimum-gas-prices", "0stake", + "--home", directory, + "--grpc.address", gRpcAddress, + "--rpc.laddr", rpcAddress, + "--p2p.laddr", p2pAddress, + "--rpc.pprof_laddr", pprofAddress, + ) + var bf testBuffer + bf.Lines = make(chan string, 100) + sourceHubCmd.Stdout = &bf + sourceHubCmd.Stderr = &bf + + err = sourceHubCmd.Start() + if err != nil { + return nil, err + } + + timeout, cancel := context.WithTimeout(context.Background(), 5*time.Second) + +cmdReaderLoop: + for { + select { + case <-timeout.Done(): + break cmdReaderLoop + case line := <-bf.Lines: + if strings.Contains(line, "starting gRPC server...") { + // The Comet RPC server is spun up before the gRPC one, so we + // can safely unlock here. + unlock() + } + // This is guarenteed to be logged after the gRPC server has been spun up + // so we can be sure that the lock has been unlocked. + if strings.Contains(line, "committed state") { + break cmdReaderLoop + } + } + } + + cancel() + // Void the buffer so that it doesn't fill up and block the process under test + bf.Void() + + s.t.Cleanup( + func() { + err := sourceHubCmd.Process.Kill() + require.NoError(s.t, err) + }, + ) + + signer, err := keyring.NewTxSignerFromKeyringKey(kr, validatorName) + if err != nil { + return nil, err + } + + return []node.ACPOpt{ + node.WithTxnSigner(immutable.Some[sdk.TxSigner](signer)), + node.WithSourceHubChainID(chainID), + node.WithSourceHubGRPCAddress(gRpcAddress), + node.WithSourceHubCometRPCAddress(rpcAddress), + }, nil +} + +func getFreePort() (int, func(), error) { + l, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + return 0, nil, err + } + + return l.Addr().(*net.TCPAddr).Port, + func() { + // there are no errors that this returns that we actually care about + _ = l.Close() + }, + nil +} + +// crossLock forms a cross process lock by attempting to listen to the given port. +// +// This function will only return once the port is free. A function to unbind from the +// port is returned - this unlock function may be called multiple times without issue. +func crossLock(port uint16) (func(), error) { + l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%v", port)) + if err != nil { + if strings.Contains(err.Error(), "address already in use") { + time.Sleep(5 * time.Millisecond) + return crossLock(port) + } + return nil, err + } + + return func() { + // there are no errors that this returns that we actually care about + _ = l.Close() + }, + nil +} + +func getIdentity(s *state, nodeIndex int, index immutable.Option[int]) immutable.Option[acpIdentity.Identity] { if !index.HasValue() { return immutable.None[acpIdentity.Identity]() } - if len(s.identities) <= index.Value() { + if len(s.identities) <= nodeIndex { + identities := make([][]acpIdentity.Identity, nodeIndex+1) + copy(identities, s.identities) + s.identities = identities + } + nodeIdentities := s.identities[nodeIndex] + + if len(nodeIdentities) <= index.Value() { + identities := make([]acpIdentity.Identity, index.Value()+1) + copy(identities, nodeIdentities) + nodeIdentities = identities + s.identities[nodeIndex] = nodeIdentities + + var audience immutable.Option[string] + switch client := s.nodes[nodeIndex].(type) { + case *http.Wrapper: + audience = immutable.Some(strings.TrimPrefix(client.Host(), "http://")) + case *cli.Wrapper: + audience = immutable.Some(strings.TrimPrefix(client.Host(), "http://")) + } + // Generate the keys using the index as the seed so that multiple // runs yield the same private key. This is important for stuff like // the change detector. @@ -84,12 +422,42 @@ func getIdentity(s *state, index immutable.Option[int]) immutable.Option[acpIden privateKey, err := secp256k1.GeneratePrivateKeyFromRand(r) require.NoError(s.t, err) - identity, err := acpIdentity.FromPrivateKey(privateKey) + identity, err := acpIdentity.FromPrivateKey( + privateKey, + authTokenExpiration, + audience, + immutable.Some(s.sourcehubAddress), + // Creating and signing the bearer token is slow, so we skip it if it not + // required. + !(acpType == SourceHubACPType || audience.HasValue()), + ) require.NoError(s.t, err) - s.identities = append(s.identities, identity.Value()) - return identity + nodeIdentities[index.Value()] = identity + return immutable.Some(identity) } else { - return immutable.Some[acpIdentity.Identity](s.identities[index.Value()]) + return immutable.Some(nodeIdentities[index.Value()]) } } + +// testBuffer is a very simple, thread-safe (--race flag friendly), io.Writer +// implementation that allows us to easily access the out/err outputs of CLI commands. +// +// Calling void will result in all writes being discarded. +type testBuffer struct { + Lines chan string + void atomic.Bool +} + +var _ io.Writer = (*testBuffer)(nil) + +func (b *testBuffer) Write(p []byte) (n int, err error) { + if !b.void.Load() { + b.Lines <- string(p) + } + return len(p), nil +} + +func (b *testBuffer) Void() { + b.void.Swap(true) +} diff --git a/tests/integration/acp/add_policy/with_no_resources_test.go b/tests/integration/acp/add_policy/with_no_resources_test.go index fd8d18b47a..5bcf3f141b 100644 --- a/tests/integration/acp/add_policy/with_no_resources_test.go +++ b/tests/integration/acp/add_policy/with_no_resources_test.go @@ -77,9 +77,12 @@ func TestACP_AddPolicy_NoResourceLabel_ValidID(t *testing.T) { // A Policy can have no resources (incompatible with DPI) but it needs a name. func TestACP_AddPolicy_PolicyWithOnlySpace_NameIsRequired(t *testing.T) { test := testUtils.TestCase{ - Description: "Test acp, adding a policy that has only space", - + SupportedACPTypes: immutable.Some([]testUtils.ACPType{ + // This is currently a local-acp only limitation, this test-restriction + // can be lifted if/when SourceHub introduces the same limitation. + testUtils.LocalACPType, + }), Actions: []any{ testUtils.AddPolicy{ Identity: immutable.Some(1), diff --git a/tests/integration/client.go b/tests/integration/client.go index dee5a3f0c9..d9c9f74334 100644 --- a/tests/integration/client.go +++ b/tests/integration/client.go @@ -73,7 +73,7 @@ func setupClient(s *state, node *node.Node) (impl clients.Client, err error) { impl, err = http.NewWrapper(node) case CLIClientType: - impl, err = cli.NewWrapper(node) + impl, err = cli.NewWrapper(node, s.sourcehubAddress) case GoClientType: impl = newGoClientWrapper(node) diff --git a/tests/integration/db.go b/tests/integration/db.go index d2ecccf366..2a7ab2893d 100644 --- a/tests/integration/db.go +++ b/tests/integration/db.go @@ -17,6 +17,8 @@ import ( "strconv" "testing" + "github.com/stretchr/testify/require" + "github.com/sourcenetwork/defradb/client" "github.com/sourcenetwork/defradb/crypto" "github.com/sourcenetwork/defradb/node" @@ -124,6 +126,23 @@ func setupNode(s *state) (*node.Node, string, error) { opts = append(opts, node.WithBadgerEncryptionKey(encryptionKey)) } + switch acpType { + case LocalACPType: + opts = append(opts, node.WithACPType(node.LocalACPType)) + + case SourceHubACPType: + acpOpts, err := setupSourceHub(s) + require.NoError(s.t, err) + + opts = append(opts, node.WithACPType(node.SourceHubACPType)) + for _, opt := range acpOpts { + opts = append(opts, opt) + } + + default: + // no-op, use the `node` package default + } + var path string switch s.dbt { case badgerIMType: diff --git a/tests/integration/state.go b/tests/integration/state.go index a2d8a338ca..fd9bd6b12c 100644 --- a/tests/integration/state.go +++ b/tests/integration/state.go @@ -45,7 +45,8 @@ type state struct { // This is order dependent and the property is accessed by index. txns []datastore.Txn - identities []identity.Identity + // Identities by node index, by identity index. + identities [][]identity.Identity // Will recieve an item once all actions have finished processing. allActionsDone chan struct{} @@ -90,6 +91,9 @@ type state struct { // isBench indicates wether the test is currently being benchmarked. isBench bool + + // The SourceHub address used to pay for SourceHub transactions. + sourcehubAddress string } // newState returns a new fresh state for the given testCase. diff --git a/tests/integration/test_case.go b/tests/integration/test_case.go index ad5a86a665..0013ceab0c 100644 --- a/tests/integration/test_case.go +++ b/tests/integration/test_case.go @@ -45,6 +45,13 @@ type TestCase struct { // This is to only be used in the very rare cases where we really do want behavioural // differences between client types, or we need to temporarily document a bug. SupportedClientTypes immutable.Option[[]ClientType] + + // If provided a value, SupportedACPTypes will cause this test to be skipped + // if the active acp type is not within the given set. + // + // This is to only be used in the very rare cases where we really do want behavioural + // differences between acp types, or we need to temporarily document a bug. + SupportedACPTypes immutable.Option[[]ACPType] } // SetupComplete is a flag to explicitly notify the change detector at which point diff --git a/tests/integration/utils2.go b/tests/integration/utils2.go index 3f6585824d..ad6ef2a85d 100644 --- a/tests/integration/utils2.go +++ b/tests/integration/utils2.go @@ -143,6 +143,7 @@ func ExecuteTestCase( collectionNames := getCollectionNames(testCase) changeDetector.PreTestChecks(t, collectionNames) skipIfMutationTypeUnsupported(t, testCase.SupportedMutationTypes) + skipIfACPTypeUnsupported(t, testCase.SupportedACPTypes) skipIfNetworkTest(t, testCase.Actions) var clients []ClientType @@ -898,7 +899,7 @@ func refreshDocuments( } for _, doc := range docs { - ctx := makeContextForDocCreate(s, s.ctx, &action) + ctx := makeContextForDocCreate(s, s.ctx, 0, &action) // The document may have been mutated by other actions, so to be sure we have the latest // version without having to worry about the individual update mechanics we fetch it. @@ -1187,7 +1188,7 @@ func createDoc( substituteRelations(s, action) } - var mutation func(*state, CreateDoc, client.DB, []client.Collection) ([]*client.Document, error) + var mutation func(*state, CreateDoc, client.DB, int, []client.Collection) ([]*client.Document, error) switch mutationType { case CollectionSaveMutationType: @@ -1209,7 +1210,7 @@ func createDoc( nodeID, func() error { var err error - docs, err = mutation(s, action, actionNodes[nodeID], collections) + docs, err = mutation(s, action, actionNodes[nodeID], nodeID, collections) return err }, ) @@ -1229,6 +1230,7 @@ func createDocViaColSave( s *state, action CreateDoc, node client.DB, + nodeIndex int, collections []client.Collection, ) ([]*client.Document, error) { var docs []*client.Document @@ -1252,7 +1254,7 @@ func createDocViaColSave( txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) - ctx := makeContextForDocCreate(s, db.SetContextTxn(s.ctx, txn), &action) + ctx := makeContextForDocCreate(s, db.SetContextTxn(s.ctx, txn), nodeIndex, &action) for _, doc := range docs { err = collections[action.CollectionID].Save(ctx, doc) @@ -1263,8 +1265,8 @@ func createDocViaColSave( return docs, nil } -func makeContextForDocCreate(s *state, ctx context.Context, action *CreateDoc) context.Context { - identity := getIdentity(s, action.Identity) +func makeContextForDocCreate(s *state, ctx context.Context, nodeIndex int, action *CreateDoc) context.Context { + identity := getIdentity(s, nodeIndex, action.Identity) ctx = db.SetContextIdentity(ctx, identity) ctx = encryption.SetContextConfigFromParams(ctx, action.IsDocEncrypted, action.EncryptedFields) return ctx @@ -1274,6 +1276,7 @@ func createDocViaColCreate( s *state, action CreateDoc, node client.DB, + nodeIndex int, collections []client.Collection, ) ([]*client.Document, error) { var docs []*client.Document @@ -1296,7 +1299,7 @@ func createDocViaColCreate( txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) - ctx := makeContextForDocCreate(s, db.SetContextTxn(s.ctx, txn), &action) + ctx := makeContextForDocCreate(s, db.SetContextTxn(s.ctx, txn), nodeIndex, &action) if len(docs) > 1 { err = collections[action.CollectionID].CreateMany(ctx, docs) @@ -1311,6 +1314,7 @@ func createDocViaGQL( s *state, action CreateDoc, node client.DB, + nodeIndex int, collections []client.Collection, ) ([]*client.Document, error) { collection := collections[action.CollectionID] @@ -1353,7 +1357,7 @@ func createDocViaGQL( ) txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) - ctx := db.SetContextIdentity(db.SetContextTxn(s.ctx, txn), getIdentity(s, action.Identity)) + ctx := db.SetContextIdentity(db.SetContextTxn(s.ctx, txn), getIdentity(s, nodeIndex, action.Identity)) result := node.ExecRequest(ctx, req) if len(result.GQL.Errors) > 0 { @@ -1407,12 +1411,13 @@ func deleteDoc( action DeleteDoc, ) { doc := s.documents[action.CollectionID][action.DocID] - identity := getIdentity(s, action.Identity) - ctx := db.SetContextIdentity(s.ctx, identity) var expectedErrorRaised bool actionNodes := getNodes(action.NodeID, s.nodes) for nodeID, collections := range getNodeCollections(action.NodeID, s.collections) { + identity := getIdentity(s, nodeID, action.Identity) + ctx := db.SetContextIdentity(s.ctx, identity) + err := withRetry( actionNodes, nodeID, @@ -1432,7 +1437,7 @@ func updateDoc( s *state, action UpdateDoc, ) { - var mutation func(*state, UpdateDoc, client.DB, []client.Collection) error + var mutation func(*state, UpdateDoc, client.DB, int, []client.Collection) error switch mutationType { case CollectionSaveMutationType: @@ -1451,7 +1456,7 @@ func updateDoc( err := withRetry( actionNodes, nodeID, - func() error { return mutation(s, action, actionNodes[nodeID], collections) }, + func() error { return mutation(s, action, actionNodes[nodeID], nodeID, collections) }, ) expectedErrorRaised = AssertError(s.t, s.testCase.Description, err, action.ExpectedError) } @@ -1463,10 +1468,11 @@ func updateDocViaColSave( s *state, action UpdateDoc, node client.DB, + nodeIndex int, collections []client.Collection, ) error { cachedDoc := s.documents[action.CollectionID][action.DocID] - identity := getIdentity(s, action.Identity) + identity := getIdentity(s, nodeIndex, action.Identity) ctx := db.SetContextIdentity(s.ctx, identity) doc, err := collections[action.CollectionID].Get(ctx, cachedDoc.ID(), true) @@ -1491,10 +1497,11 @@ func updateDocViaColUpdate( s *state, action UpdateDoc, node client.DB, + nodeIndex int, collections []client.Collection, ) error { cachedDoc := s.documents[action.CollectionID][action.DocID] - identity := getIdentity(s, action.Identity) + identity := getIdentity(s, nodeIndex, action.Identity) ctx := db.SetContextIdentity(s.ctx, identity) doc, err := collections[action.CollectionID].Get(ctx, cachedDoc.ID(), true) @@ -1516,6 +1523,7 @@ func updateDocViaGQL( s *state, action UpdateDoc, node client.DB, + nodeIndex int, collections []client.Collection, ) error { doc := s.documents[action.CollectionID][action.DocID] @@ -1538,7 +1546,7 @@ func updateDocViaGQL( txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) ctx := db.SetContextTxn(s.ctx, txn) - identity := getIdentity(s, action.Identity) + identity := getIdentity(s, nodeIndex, action.Identity) ctx = db.SetContextIdentity(ctx, identity) result := node.ExecRequest(ctx, request) @@ -1759,7 +1767,7 @@ func executeRequest( txn := getTransaction(s, node, action.TransactionID, action.ExpectedError) ctx := db.SetContextTxn(s.ctx, txn) - identity := getIdentity(s, action.Identity) + identity := getIdentity(s, nodeID, action.Identity) ctx = db.SetContextIdentity(ctx, identity) result := node.ExecRequest(ctx, action.Request) @@ -2160,6 +2168,22 @@ func skipIfClientTypeUnsupported( return filteredClients } +func skipIfACPTypeUnsupported(t testing.TB, supporteACPTypes immutable.Option[[]ACPType]) { + if supporteACPTypes.HasValue() { + var isTypeSupported bool + for _, supportedType := range supporteACPTypes.Value() { + if supportedType == acpType { + isTypeSupported = true + break + } + } + + if !isTypeSupported { + t.Skipf("test does not support given acp type. Type: %s", acpType) + } + } +} + // skipIfNetworkTest skips the current test if the given actions // contain network actions and skipNetworkTests is true. func skipIfNetworkTest(t testing.TB, actions []any) { From f6b6485e51fbb492fe7b6b27dfa459382d34c887 Mon Sep 17 00:00:00 2001 From: Islam Aliev Date: Wed, 17 Jul 2024 18:29:23 +0200 Subject: [PATCH 14/41] fix: Enable filtering doc by fields of JSON and Blob types (#2841) ## Relevant issue(s) Resolves #2840 ## Description Fixes the issue not being able to filter by JSON and Blob fields --- internal/request/graphql/schema/manager.go | 11 +- internal/request/graphql/schema/types/base.go | 167 ++++++++++++++++++ .../simple/with_filter/with_eq_blob_test.go | 54 ++++++ .../simple/with_filter/with_eq_json_test.go | 55 ++++++ .../simple/with_filter/with_in_blob_test.go | 54 ++++++ .../simple/with_filter/with_in_json_test.go | 55 ++++++ .../simple/with_filter/with_like_blob_test.go | 54 ++++++ .../simple/with_filter/with_like_json_test.go | 54 ++++++ 8 files changed, 502 insertions(+), 2 deletions(-) create mode 100644 tests/integration/query/simple/with_filter/with_eq_blob_test.go create mode 100644 tests/integration/query/simple/with_filter/with_eq_json_test.go create mode 100644 tests/integration/query/simple/with_filter/with_in_blob_test.go create mode 100644 tests/integration/query/simple/with_filter/with_in_json_test.go create mode 100644 tests/integration/query/simple/with_filter/with_like_blob_test.go create mode 100644 tests/integration/query/simple/with_filter/with_like_json_test.go diff --git a/internal/request/graphql/schema/manager.go b/internal/request/graphql/schema/manager.go index fee626b45c..d409fe96b5 100644 --- a/internal/request/graphql/schema/manager.go +++ b/internal/request/graphql/schema/manager.go @@ -166,6 +166,9 @@ func defaultTypes( crdtEnum *gql.Enum, explainEnum *gql.Enum, ) []gql.Type { + blobScalarType := schemaTypes.BlobScalarType() + jsonScalarType := schemaTypes.JSONScalarType() + return []gql.Type{ // Base Scalar types gql.Boolean, @@ -176,8 +179,8 @@ func defaultTypes( gql.String, // Custom Scalar types - schemaTypes.BlobScalarType(), - schemaTypes.JSONScalarType(), + blobScalarType, + jsonScalarType, // Base Query types @@ -195,6 +198,10 @@ func defaultTypes( schemaTypes.NotNullIntOperatorBlock(), schemaTypes.StringOperatorBlock(), schemaTypes.NotNullstringOperatorBlock(), + schemaTypes.JSONOperatorBlock(jsonScalarType), + schemaTypes.NotNullJSONOperatorBlock(jsonScalarType), + schemaTypes.BlobOperatorBlock(blobScalarType), + schemaTypes.NotNullBlobOperatorBlock(blobScalarType), commitsOrderArg, commitLinkObject, diff --git a/internal/request/graphql/schema/types/base.go b/internal/request/graphql/schema/types/base.go index ca4c8f2372..fd49fbb45a 100644 --- a/internal/request/graphql/schema/types/base.go +++ b/internal/request/graphql/schema/types/base.go @@ -360,6 +360,173 @@ func NotNullstringOperatorBlock() *gql.InputObject { }) } +// JSONOperatorBlock filter block for string types. +func JSONOperatorBlock(jsonScalarType *gql.Scalar) *gql.InputObject { + return gql.NewInputObject(gql.InputObjectConfig{ + Name: "JSONOperatorBlock", + Description: stringOperatorBlockDescription, + Fields: gql.InputObjectConfigFieldMap{ + "_eq": &gql.InputObjectFieldConfig{ + Description: eqOperatorDescription, + Type: jsonScalarType, + }, + "_ne": &gql.InputObjectFieldConfig{ + Description: neOperatorDescription, + Type: jsonScalarType, + }, + "_in": &gql.InputObjectFieldConfig{ + Description: inOperatorDescription, + Type: gql.NewList(jsonScalarType), + }, + "_nin": &gql.InputObjectFieldConfig{ + Description: ninOperatorDescription, + Type: gql.NewList(jsonScalarType), + }, + "_like": &gql.InputObjectFieldConfig{ + Description: likeStringOperatorDescription, + Type: gql.String, + }, + "_nlike": &gql.InputObjectFieldConfig{ + Description: nlikeStringOperatorDescription, + Type: gql.String, + }, + "_ilike": &gql.InputObjectFieldConfig{ + Description: ilikeStringOperatorDescription, + Type: gql.String, + }, + "_nilike": &gql.InputObjectFieldConfig{ + Description: nilikeStringOperatorDescription, + Type: gql.String, + }, + }, + }) +} + +// NotNullJSONOperatorBlock filter block for string! types. +func NotNullJSONOperatorBlock(jsonScalarType *gql.Scalar) *gql.InputObject { + return gql.NewInputObject(gql.InputObjectConfig{ + Name: "NotNullJSONOperatorBlock", + Description: notNullStringOperatorBlockDescription, + Fields: gql.InputObjectConfigFieldMap{ + "_eq": &gql.InputObjectFieldConfig{ + Description: eqOperatorDescription, + Type: jsonScalarType, + }, + "_ne": &gql.InputObjectFieldConfig{ + Description: neOperatorDescription, + Type: jsonScalarType, + }, + "_in": &gql.InputObjectFieldConfig{ + Description: inOperatorDescription, + Type: gql.NewList(gql.NewNonNull(jsonScalarType)), + }, + "_nin": &gql.InputObjectFieldConfig{ + Description: ninOperatorDescription, + Type: gql.NewList(gql.NewNonNull(jsonScalarType)), + }, + "_like": &gql.InputObjectFieldConfig{ + Description: likeStringOperatorDescription, + Type: gql.String, + }, + "_nlike": &gql.InputObjectFieldConfig{ + Description: nlikeStringOperatorDescription, + Type: gql.String, + }, + "_ilike": &gql.InputObjectFieldConfig{ + Description: ilikeStringOperatorDescription, + Type: gql.String, + }, + "_nilike": &gql.InputObjectFieldConfig{ + Description: nilikeStringOperatorDescription, + Type: gql.String, + }, + }, + }) +} + +func BlobOperatorBlock(blobScalarType *gql.Scalar) *gql.InputObject { + return gql.NewInputObject(gql.InputObjectConfig{ + Name: "BlobOperatorBlock", + Description: stringOperatorBlockDescription, + Fields: gql.InputObjectConfigFieldMap{ + "_eq": &gql.InputObjectFieldConfig{ + Description: eqOperatorDescription, + Type: blobScalarType, + }, + "_ne": &gql.InputObjectFieldConfig{ + Description: neOperatorDescription, + Type: blobScalarType, + }, + "_in": &gql.InputObjectFieldConfig{ + Description: inOperatorDescription, + Type: gql.NewList(blobScalarType), + }, + "_nin": &gql.InputObjectFieldConfig{ + Description: ninOperatorDescription, + Type: gql.NewList(blobScalarType), + }, + "_like": &gql.InputObjectFieldConfig{ + Description: likeStringOperatorDescription, + Type: gql.String, + }, + "_nlike": &gql.InputObjectFieldConfig{ + Description: nlikeStringOperatorDescription, + Type: gql.String, + }, + "_ilike": &gql.InputObjectFieldConfig{ + Description: ilikeStringOperatorDescription, + Type: gql.String, + }, + "_nilike": &gql.InputObjectFieldConfig{ + Description: nilikeStringOperatorDescription, + Type: gql.String, + }, + }, + }) +} + +// NotNullJSONOperatorBlock filter block for string! types. +func NotNullBlobOperatorBlock(blobScalarType *gql.Scalar) *gql.InputObject { + return gql.NewInputObject(gql.InputObjectConfig{ + Name: "NotNullBlobOperatorBlock", + Description: notNullStringOperatorBlockDescription, + Fields: gql.InputObjectConfigFieldMap{ + "_eq": &gql.InputObjectFieldConfig{ + Description: eqOperatorDescription, + Type: blobScalarType, + }, + "_ne": &gql.InputObjectFieldConfig{ + Description: neOperatorDescription, + Type: blobScalarType, + }, + "_in": &gql.InputObjectFieldConfig{ + Description: inOperatorDescription, + Type: gql.NewList(gql.NewNonNull(blobScalarType)), + }, + "_nin": &gql.InputObjectFieldConfig{ + Description: ninOperatorDescription, + Type: gql.NewList(gql.NewNonNull(blobScalarType)), + }, + "_like": &gql.InputObjectFieldConfig{ + Description: likeStringOperatorDescription, + Type: gql.String, + }, + "_nlike": &gql.InputObjectFieldConfig{ + Description: nlikeStringOperatorDescription, + Type: gql.String, + }, + "_ilike": &gql.InputObjectFieldConfig{ + Description: ilikeStringOperatorDescription, + Type: gql.String, + }, + "_nilike": &gql.InputObjectFieldConfig{ + Description: nilikeStringOperatorDescription, + Type: gql.String, + }, + }, + }) +} + // IdOperatorBlock filter block for ID types. func IdOperatorBlock() *gql.InputObject { return gql.NewInputObject(gql.InputObjectConfig{ diff --git a/tests/integration/query/simple/with_filter/with_eq_blob_test.go b/tests/integration/query/simple/with_filter/with_eq_blob_test.go new file mode 100644 index 0000000000..76a804f98a --- /dev/null +++ b/tests/integration/query/simple/with_filter/with_eq_blob_test.go @@ -0,0 +1,54 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package simple + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestQuerySimple_WithEqOpOnBlobField_ShouldFilter(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Users { + name: String + data: Blob + } + `, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "data": "00FF99AA" + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Andy", + "data": "FA02CC45" + }`, + }, + testUtils.Request{ + Request: `query { + Users(filter: {data: {_eq: "00FF99AA"}}) { + name + } + }`, + Results: []map[string]any{{"name": "John"}}, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/query/simple/with_filter/with_eq_json_test.go b/tests/integration/query/simple/with_filter/with_eq_json_test.go new file mode 100644 index 0000000000..d0d9e93369 --- /dev/null +++ b/tests/integration/query/simple/with_filter/with_eq_json_test.go @@ -0,0 +1,55 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package simple + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestQuerySimple_WithEqOpOnJSONField_ShouldFilter(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Users { + name: String + custom: JSON + } + `, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "name": "John", + "custom": "{\"tree\": \"maple\", \"age\": 250}", + }, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "name": "Andy", + "custom": "{\"tree\": \"oak\", \"age\": 450}", + }, + }, + testUtils.Request{ + // the filtered-by JSON has no spaces, because this is now it's stored. + Request: `query { + Users(filter: {custom: {_eq: "{\"tree\":\"oak\",\"age\":450}"}}) { + name + } + }`, + Results: []map[string]any{{"name": "Andy"}}, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/query/simple/with_filter/with_in_blob_test.go b/tests/integration/query/simple/with_filter/with_in_blob_test.go new file mode 100644 index 0000000000..a168a297ac --- /dev/null +++ b/tests/integration/query/simple/with_filter/with_in_blob_test.go @@ -0,0 +1,54 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package simple + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestQuerySimple_WithInOpOnBlobField_ShouldFilter(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Users { + name: String + data: Blob + } + `, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "data": "00FF99AA" + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Andy", + "data": "FA02CC45" + }`, + }, + testUtils.Request{ + Request: `query { + Users(filter: {data: {_in: ["00FF99AA"]}}) { + name + } + }`, + Results: []map[string]any{{"name": "John"}}, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/query/simple/with_filter/with_in_json_test.go b/tests/integration/query/simple/with_filter/with_in_json_test.go new file mode 100644 index 0000000000..cb4fcdc7da --- /dev/null +++ b/tests/integration/query/simple/with_filter/with_in_json_test.go @@ -0,0 +1,55 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package simple + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestQuerySimple_WithInOpOnJSONField_ShouldFilter(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Users { + name: String + custom: JSON + } + `, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "name": "John", + "custom": "{\"tree\": \"maple\", \"age\": 250}", + }, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "name": "Andy", + "custom": "{\"tree\": \"oak\", \"age\": 450}", + }, + }, + testUtils.Request{ + // the filtered-by JSON has no spaces, because this is now it's stored. + Request: `query { + Users(filter: {custom: {_in: ["{\"tree\":\"oak\",\"age\":450}"]}}) { + name + } + }`, + Results: []map[string]any{{"name": "Andy"}}, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/query/simple/with_filter/with_like_blob_test.go b/tests/integration/query/simple/with_filter/with_like_blob_test.go new file mode 100644 index 0000000000..bc51930f06 --- /dev/null +++ b/tests/integration/query/simple/with_filter/with_like_blob_test.go @@ -0,0 +1,54 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package simple + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestQuerySimple_WithLikeOpOnBlobField_ShouldFilter(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Users { + name: String + data: Blob + } + `, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "data": "00FF99AA" + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Andy", + "data": "FA02CC45" + }`, + }, + testUtils.Request{ + Request: `query { + Users(filter: {data: {_like: "%FF99%"}}) { + name + } + }`, + Results: []map[string]any{{"name": "John"}}, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/query/simple/with_filter/with_like_json_test.go b/tests/integration/query/simple/with_filter/with_like_json_test.go new file mode 100644 index 0000000000..ed092dd502 --- /dev/null +++ b/tests/integration/query/simple/with_filter/with_like_json_test.go @@ -0,0 +1,54 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package simple + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestQuerySimple_WithLikeOpOnJSONField_ShouldFilter(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Users { + name: String + custom: JSON + } + `, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "name": "John", + "custom": "{\"tree\": \"maple\", \"age\": 250}", + }, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "name": "Andy", + "custom": "{\"tree\": \"oak\", \"age\": 450}", + }, + }, + testUtils.Request{ + Request: `query { + Users(filter: {custom: {_like: "%oak%"}}) { + name + } + }`, + Results: []map[string]any{{"name": "Andy"}}, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} From a7fe53946c9e9ea0630e9ec2dc28cba8d2d893a3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 18 Jul 2024 08:47:33 -0400 Subject: [PATCH 15/41] bot: Update dependencies (bulk dependabot PRs) 18-07-2024 (#2846) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✅ This PR was created by combining the following PRs: #2845 bot: Bump vite from 5.3.2 to 5.3.4 in /playground #2844 bot: Bump github.com/hashicorp/go-getter from 1.7.3 to 1.7.5 #2843 bot: Bump github.com/cosmos/ibc-go/v8 from 8.0.0 to 8.2.0 #2842 bot: Bump github.com/rs/cors from 1.10.1 to 1.11.0 #2815 bot: Bump go.opentelemetry.io/otel/sdk/metric from 1.27.0 to 1.28.0 #2814 bot: Bump graphiql from 3.3.1 to 3.3.2 in /playground ⚠️ The following PRs were resolved manually due to merge conflicts: #2838 bot: Bump @typescript-eslint/eslint-plugin from 7.14.1 to 7.16.1 in /playground #2837 bot: Bump @typescript-eslint/parser from 7.14.1 to 7.16.1 in /playground #2813 bot: Bump typescript from 5.5.2 to 5.5.3 in /playground --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Shahzad Lone --- go.mod | 16 +- go.sum | 32 +- playground/package-lock.json | 1234 +++++++++++++--------------------- playground/package.json | 10 +- 4 files changed, 514 insertions(+), 778 deletions(-) diff --git a/go.mod b/go.mod index 11def6289c..6af60bcdf1 100644 --- a/go.mod +++ b/go.mod @@ -55,8 +55,8 @@ require ( github.com/valyala/fastjson v1.6.4 github.com/vito/go-sse v1.0.0 github.com/zalando/go-keyring v0.2.5 - go.opentelemetry.io/otel/metric v1.27.0 - go.opentelemetry.io/otel/sdk/metric v1.27.0 + go.opentelemetry.io/otel/metric v1.28.0 + go.opentelemetry.io/otel/sdk/metric v1.28.0 go.uber.org/zap v1.27.0 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/term v0.21.0 @@ -125,7 +125,7 @@ require ( github.com/cosmos/gogogateway v1.2.0 // indirect github.com/cosmos/iavl v1.1.2 // indirect github.com/cosmos/ibc-go/modules/capability v1.0.0 // indirect - github.com/cosmos/ibc-go/v8 v8.0.0 // indirect + github.com/cosmos/ibc-go/v8 v8.2.0 // indirect github.com/cosmos/ics23/go v0.10.0 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect @@ -190,7 +190,7 @@ require ( github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-getter v1.7.3 // indirect + github.com/hashicorp/go-getter v1.7.5 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-metrics v0.5.3 // indirect @@ -317,7 +317,7 @@ require ( github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect - github.com/rs/cors v1.10.1 // indirect + github.com/rs/cors v1.11.0 // indirect github.com/rs/zerolog v1.32.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect @@ -348,9 +348,9 @@ require ( go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 // indirect - go.opentelemetry.io/otel v1.27.0 // indirect - go.opentelemetry.io/otel/sdk v1.27.0 // indirect - go.opentelemetry.io/otel/trace v1.27.0 // indirect + go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/otel/sdk v1.28.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 // indirect go.uber.org/dig v1.17.1 // indirect go.uber.org/fx v1.22.0 // indirect go.uber.org/mock v0.4.0 // indirect diff --git a/go.sum b/go.sum index cc5208e234..3d191a245f 100644 --- a/go.sum +++ b/go.sum @@ -408,8 +408,8 @@ github.com/cosmos/iavl v1.1.2 h1:zL9FK7C4L/P4IF1Dm5fIwz0WXCnn7Bp1M2FxH0ayM7Y= github.com/cosmos/iavl v1.1.2/go.mod h1:jLeUvm6bGT1YutCaL2fIar/8vGUE8cPZvh/gXEWDaDM= github.com/cosmos/ibc-go/modules/capability v1.0.0 h1:r/l++byFtn7jHYa09zlAdSeevo8ci1mVZNO9+V0xsLE= github.com/cosmos/ibc-go/modules/capability v1.0.0/go.mod h1:D81ZxzjZAe0ZO5ambnvn1qedsFQ8lOwtqicG6liLBco= -github.com/cosmos/ibc-go/v8 v8.0.0 h1:QKipnr/NGwc+9L7NZipURvmSIu+nw9jOIWTJuDBqOhg= -github.com/cosmos/ibc-go/v8 v8.0.0/go.mod h1:C6IiJom0F3cIQCD5fKwVPDrDK9j/xTu563AWuOmXois= +github.com/cosmos/ibc-go/v8 v8.2.0 h1:7oCzyy1sZCcgpeQLnHxC56brsSz3KWwQGKXalXwXFzE= +github.com/cosmos/ibc-go/v8 v8.2.0/go.mod h1:wj3qx75iC/XNnsMqbPDCIGs0G6Y3E/lo3bdqCyoCy+8= github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM= @@ -770,8 +770,8 @@ github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-getter v1.7.3 h1:bN2+Fw9XPFvOCjB0UOevFIMICZ7G2XSQHzfvLUyOM5E= -github.com/hashicorp/go-getter v1.7.3/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= +github.com/hashicorp/go-getter v1.7.5 h1:dT58k9hQ/vbxNMwoI5+xFYAJuv6152UNvdHokfI5wE4= +github.com/hashicorp/go-getter v1.7.5/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -1326,8 +1326,8 @@ github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/f github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= -github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po= +github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= @@ -1538,16 +1538,16 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.4 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0 h1:9l89oX4ba9kHbBol3Xin3leYJ+252h0zszDtBwyKe2A= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.52.0/go.mod h1:XLZfZboOJWHNKUv7eH0inh0E9VV6eWDFB/9yJyTLPp0= -go.opentelemetry.io/otel v1.27.0 h1:9BZoF3yMK/O1AafMiQTVu0YDj5Ea4hPhxCs7sGva+cg= -go.opentelemetry.io/otel v1.27.0/go.mod h1:DMpAK8fzYRzs+bi3rS5REupisuqTheUlSZJ1WnZaPAQ= -go.opentelemetry.io/otel/metric v1.27.0 h1:hvj3vdEKyeCi4YaYfNjv2NUje8FqKqUY8IlF0FxV/ik= -go.opentelemetry.io/otel/metric v1.27.0/go.mod h1:mVFgmRlhljgBiuk/MP/oKylr4hs85GZAylncepAX/ak= -go.opentelemetry.io/otel/sdk v1.27.0 h1:mlk+/Y1gLPLn84U4tI8d3GNJmGT/eXe3ZuOXN9kTWmI= -go.opentelemetry.io/otel/sdk v1.27.0/go.mod h1:Ha9vbLwJE6W86YstIywK2xFfPjbWlCuwPtMkKdz/Y4A= -go.opentelemetry.io/otel/sdk/metric v1.27.0 h1:5uGNOlpXi+Hbo/DRoI31BSb1v+OGcpv2NemcCrOL8gI= -go.opentelemetry.io/otel/sdk/metric v1.27.0/go.mod h1:we7jJVrYN2kh3mVBlswtPU22K0SA+769l93J6bsyvqw= -go.opentelemetry.io/otel/trace v1.27.0 h1:IqYb813p7cmbHk0a5y6pD5JPakbVfftRXABGt5/Rscw= -go.opentelemetry.io/otel/trace v1.27.0/go.mod h1:6RiD1hkAprV4/q+yd2ln1HG9GoPx39SuvvstaLBl+l4= +go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= +go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/sdk/metric v1.28.0 h1:OkuaKgKrgAbYrrY0t92c+cC+2F6hsFNnCQArXCKlg08= +go.opentelemetry.io/otel/sdk/metric v1.28.0/go.mod h1:cWPjykihLAPvXKi4iZc1dpER3Jdq2Z0YLse3moQUCpg= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= diff --git a/playground/package-lock.json b/playground/package-lock.json index 95ce4d5291..127c51617e 100644 --- a/playground/package-lock.json +++ b/playground/package-lock.json @@ -8,7 +8,7 @@ "name": "playground", "version": "0.0.0", "dependencies": { - "graphiql": "^3.3.1", + "graphiql": "^3.3.2", "graphql": "^16.9.0", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -18,20 +18,20 @@ "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@types/swagger-ui-react": "^4.18.3", - "@typescript-eslint/eslint-plugin": "^7.14.1", - "@typescript-eslint/parser": "^7.14.1", + "@typescript-eslint/eslint-plugin": "^7.16.1", + "@typescript-eslint/parser": "^7.16.1", "@vitejs/plugin-react-swc": "^3.7.0", "eslint": "^8.57.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.7", - "typescript": "^5.5.2", - "vite": "^5.3.2" + "typescript": "^5.5.3", + "vite": "^5.3.4" } }, "node_modules/@babel/runtime": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", - "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", + "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -40,9 +40,9 @@ } }, "node_modules/@babel/runtime-corejs3": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.24.5.tgz", - "integrity": "sha512-GWO0mgzNMLWaSYM4z4NVIuY0Cd1fl8cPnuetuddu5w/qGuvt5Y7oUi/kvvQGK9xgOkFJDQX2heIvTRn/OQ1XTg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.24.8.tgz", + "integrity": "sha512-DXG/BhegtMHhnN7YPIvxWd303/9aXvYFD1TjNL3CD6tUrhI2LVsg3Lck0aql5TRH29n4sj3emcROypkZVUfSuA==", "dependencies": { "core-js-pure": "^3.30.2", "regenerator-runtime": "^0.14.0" @@ -77,9 +77,9 @@ "peer": true }, "node_modules/@codemirror/view": { - "version": "6.28.2", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.28.2.tgz", - "integrity": "sha512-A3DmyVfjgPsGIjiJqM/zvODUAPQdQl3ci0ghehYNnbt5x+o76xq+dL5+mMBuysDXnI3kapgOkoeJ0sbtL/3qPw==", + "version": "6.28.5", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.28.5.tgz", + "integrity": "sha512-NkUtfUa1lV7Jqg5DfHE/uLl7jKyoymDkaueMQXzePYuezL7FwX3ATANy74iAGlHCGe25hBGB0R+I5dC5EZ5JBg==", "peer": true, "dependencies": { "@codemirror/state": "^6.4.0", @@ -486,9 +486,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -549,26 +549,26 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.2.tgz", - "integrity": "sha512-+2XpQV9LLZeanU4ZevzRnGFg2neDeKHgFLjP6YLW+tly0IvrhqT4u8enLGjLH3qeh85g19xY5rsAusfwTdn5lg==", + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.4.tgz", + "integrity": "sha512-a4IowK4QkXl4SCWTGUR0INAfEOX3wtsYw3rKK5InQEHMGObkR8Xk44qYQD9P4r6HHw0iIfK6GUKECmY8sTkqRA==", "dependencies": { - "@floating-ui/utils": "^0.2.0" + "@floating-ui/utils": "^0.2.4" } }, "node_modules/@floating-ui/dom": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.5.tgz", - "integrity": "sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.7.tgz", + "integrity": "sha512-wmVfPG5o2xnKDU4jx/m4w5qva9FWHcnZ8BvzEe90D/RpwsJaTAVYPEPdQ8sbr/N8zZTAHlZUTQdqg8ZUbzHmng==", "dependencies": { - "@floating-ui/core": "^1.0.0", - "@floating-ui/utils": "^0.2.0" + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.4" } }, "node_modules/@floating-ui/react-dom": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.0.tgz", - "integrity": "sha512-lNzj5EQmEKn5FFKc04+zasr09h/uX8RtJRNj5gUXsSQIXHVWTVh+hVAg1vOMCexkX8EgvemMvIFpQfkosnVNyA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", + "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", "dependencies": { "@floating-ui/dom": "^1.0.0" }, @@ -578,14 +578,14 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.2.tgz", - "integrity": "sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==" + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.4.tgz", + "integrity": "sha512-dWO2pw8hhi+WrXq1YJy2yCuWoL20PddgGaqTgVe4cOS9Q6qklXCiA1tJEqX6BEwRNSCP84/afac9hd4MS+zEUA==" }, "node_modules/@graphiql/react": { - "version": "0.22.3", - "resolved": "https://registry.npmjs.org/@graphiql/react/-/react-0.22.3.tgz", - "integrity": "sha512-rZGs0BbJ4ImFy6l489aXUEB3HzGVoD7hI8CycydNRXR6+qYgp/fuNFCXMJe+q9gDyC/XhBXni8Pdugk8HxJ05g==", + "version": "0.22.4", + "resolved": "https://registry.npmjs.org/@graphiql/react/-/react-0.22.4.tgz", + "integrity": "sha512-FsupNjAUJ17qhdyCjKo150wpNH7gr0ScAm/Rmk7VHP4Mh0Osid+1bKLPtXEOjGI+InuTPSKhJw3Zbm8dD3+o1A==", "dependencies": { "@graphiql/toolkit": "^0.9.1", "@headlessui/react": "^1.7.15", @@ -647,6 +647,7 @@ "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", @@ -696,6 +697,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", "dev": true }, "node_modules/@lezer/common": { @@ -1247,9 +1249,9 @@ } }, "node_modules/@radix-ui/react-tooltip": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.1.tgz", - "integrity": "sha512-LLE8nzNE4MzPMw3O2zlVlkLFid3y9hMUs7uCbSHyKSo+tCN4yMCf+ZCCcfrYgsOC0TiHBPQ1mtpJ2liY3ZT3SQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.2.tgz", + "integrity": "sha512-9XRsLwe6Yb9B/tlnYCPVUd/TFS4J7HuOZW345DCeC6vKIxQGMZdx21RK4VoZauPD5frgkXTYVS5y90L+3YBn4w==", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", @@ -1403,9 +1405,9 @@ "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", - "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.1.tgz", + "integrity": "sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==", "cpu": [ "arm" ], @@ -1416,9 +1418,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", - "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.1.tgz", + "integrity": "sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==", "cpu": [ "arm64" ], @@ -1429,9 +1431,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", - "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.1.tgz", + "integrity": "sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==", "cpu": [ "arm64" ], @@ -1442,9 +1444,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", - "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.1.tgz", + "integrity": "sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==", "cpu": [ "x64" ], @@ -1455,9 +1457,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", - "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.1.tgz", + "integrity": "sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==", "cpu": [ "arm" ], @@ -1468,9 +1470,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", - "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.1.tgz", + "integrity": "sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==", "cpu": [ "arm" ], @@ -1481,9 +1483,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", - "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.1.tgz", + "integrity": "sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==", "cpu": [ "arm64" ], @@ -1494,9 +1496,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", - "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.1.tgz", + "integrity": "sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==", "cpu": [ "arm64" ], @@ -1507,9 +1509,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", - "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.1.tgz", + "integrity": "sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==", "cpu": [ "ppc64" ], @@ -1520,9 +1522,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", - "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.1.tgz", + "integrity": "sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==", "cpu": [ "riscv64" ], @@ -1533,9 +1535,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", - "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.1.tgz", + "integrity": "sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==", "cpu": [ "s390x" ], @@ -1546,9 +1548,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", - "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.1.tgz", + "integrity": "sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==", "cpu": [ "x64" ], @@ -1559,9 +1561,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", - "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.1.tgz", + "integrity": "sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==", "cpu": [ "x64" ], @@ -1572,9 +1574,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", - "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.1.tgz", + "integrity": "sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==", "cpu": [ "arm64" ], @@ -1585,9 +1587,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", - "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.1.tgz", + "integrity": "sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==", "cpu": [ "ia32" ], @@ -1598,9 +1600,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", - "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.1.tgz", + "integrity": "sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==", "cpu": [ "x64" ], @@ -1611,12 +1613,12 @@ ] }, "node_modules/@swagger-api/apidom-ast": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-1.0.0-alpha.3.tgz", - "integrity": "sha512-C2gPpPlfHXoOyFndgKWGrfUbtyv9fUIuRuUiWJ3X5JIt0cN7/6I+DqGKrolQrA4W3JwPxbtl5N0LixTEwFJRsg==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-1.0.0-alpha.6.tgz", + "integrity": "sha512-uzDNIeTLFeITzK7yX9PSsu3dl92rHP/gKMNAlJhmDRr7r+OLr5dCpAzyZ0WvONRxjxR8Otj5LX4AD12+EX32fg==", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-error": "^1.0.0-alpha.1", + "@swagger-api/apidom-error": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1624,13 +1626,13 @@ } }, "node_modules/@swagger-api/apidom-core": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-1.0.0-alpha.3.tgz", - "integrity": "sha512-kvACv+NXgMKp5oNdq5RVo7+1b2GVUSnOKRU+SafjnfUHqHgeQw5Fyf+W6iELIdmx0ZzTlQvPRyOLKC15e+rTBg==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-1.0.0-alpha.6.tgz", + "integrity": "sha512-5u7dK3+8cF2h5bHEI/qrA6JrfXX+HIHSmUgPGbeMAqSCEfpsjnsngXK6gHtd4ktLlPz3TplNZAQl88wIp+39nw==", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^1.0.0-alpha.3", - "@swagger-api/apidom-error": "^1.0.0-alpha.1", + "@swagger-api/apidom-ast": "^1.0.0-alpha.6", + "@swagger-api/apidom-error": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "minim": "~0.23.8", "ramda": "~0.30.0", @@ -1640,36 +1642,36 @@ } }, "node_modules/@swagger-api/apidom-error": { - "version": "1.0.0-alpha.1", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-error/-/apidom-error-1.0.0-alpha.1.tgz", - "integrity": "sha512-AyaQQjpjBHPMQeVT1n5R92NRNEbTbbUGZYf1nEzPk9KEQm2y9K6HBbxg3htSrI3sgUj8LzxQocx8umEkDmj4FA==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-error/-/apidom-error-1.0.0-alpha.6.tgz", + "integrity": "sha512-eOcqaXwLitjp5CIGYR0W2oM6p4UiTL7EjNdkCcfrELKHdgNS6U7kZdl3KCBlOuMb14CijwtZNEJbIGhhGZUYHg==", "dependencies": { "@babel/runtime-corejs3": "^7.20.7" } }, "node_modules/@swagger-api/apidom-json-pointer": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-1.0.0-alpha.3.tgz", - "integrity": "sha512-hqNVqjzxY2ZDdIvbffgmjgtOJOijEVy5zyMh5mU8Aq+p5NH4WO3W9oCTCTjIoMWQC/Sg9s1S14UddDU0owCLzQ==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-1.0.0-alpha.6.tgz", + "integrity": "sha512-8ULBcQRQ1UPgqJ+ZuuKjmeKeuxqbuIUHwWHRRA848jK5+IHmNw/Cp68MhNiwYXLmTLkTIGaDubcOplMeHCxSyA==", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-error": "^1.0.0-alpha.1", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-error": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-ns-api-design-systems": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-api-design-systems/-/apidom-ns-api-design-systems-1.0.0-alpha.3.tgz", - "integrity": "sha512-tDCmIwyLByn99sjhI8l9A2OMrN7M+W51E5gyvHmd1QORziol5Cp5bOUe6eh6VKVaXuKTWqxJc8H49+Kqq7+o5A==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-api-design-systems/-/apidom-ns-api-design-systems-1.0.0-alpha.6.tgz", + "integrity": "sha512-JRiImw3XKrfm22pzlx7uM6XYJtWM71QkCLy86gOTBFybWgTOCECnN4c8jFBnYl6KYuIb2VV9kXZs38xjK4NfBQ==", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-error": "^1.0.0-alpha.1", - "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.3", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-error": "^1.0.0-alpha.6", + "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1677,14 +1679,14 @@ } }, "node_modules/@swagger-api/apidom-ns-asyncapi-2": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-asyncapi-2/-/apidom-ns-asyncapi-2-1.0.0-alpha.3.tgz", - "integrity": "sha512-H2biAFpzibnl0meeQIItTqnRW9R6icnkjrzdKzqtnHFMxZ5dLAAbwUTB3Ps5au0SnGvVb1/8Vf4UFJQh5Dhe/A==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-asyncapi-2/-/apidom-ns-asyncapi-2-1.0.0-alpha.6.tgz", + "integrity": "sha512-I8Yq+AmJPUJihGneBv1/m/ly+2dp4FJiCxW/auRQSicvYIV7hoBO5qGZqcEEoVt7OpuhFbFqI2pwnambz90Uvg==", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-ns-json-schema-draft-7": "^1.0.0-alpha.3", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-ns-json-schema-draft-7": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1692,13 +1694,13 @@ } }, "node_modules/@swagger-api/apidom-ns-json-schema-draft-4": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-1.0.0-alpha.3.tgz", - "integrity": "sha512-kt0xVFf7FZP0tzxqS9wciwzDNj1veIUVZH1reop8XjSnmnL3osL9UReQm7C/D9NHmU4rcqWnL4Oc4m+AbXOs5A==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-1.0.0-alpha.6.tgz", + "integrity": "sha512-E8JjqdDgopnLd4HXEXGSrc6rkbDyB8Qk6sYgmyT6lB8caFUMRdJ5Rp57fPePETnVpegb8cAuKjBdjTImX1gQ3Q==", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^1.0.0-alpha.3", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", + "@swagger-api/apidom-ast": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1706,15 +1708,15 @@ } }, "node_modules/@swagger-api/apidom-ns-json-schema-draft-6": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-1.0.0-alpha.3.tgz", - "integrity": "sha512-aiaw91NCSxzAq0wZqe7z5PILK4dTei7YU6W8Xxu9g95yZ/jyLc9AEaNMPEYXUMxzn/fjbGdfHaOH0um7cLcdRw==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-1.0.0-alpha.6.tgz", + "integrity": "sha512-uzYmV65nn7i6nlp7Kp7ldGfAoXWPPquIocoHLWDBTx5sPdS+ALu2T2yvytav0z6StKeV+gU2HZjMLVRWdLzLZA==", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-error": "^1.0.0-alpha.1", - "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-alpha.3", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-error": "^1.0.0-alpha.6", + "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1722,15 +1724,15 @@ } }, "node_modules/@swagger-api/apidom-ns-json-schema-draft-7": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-1.0.0-alpha.3.tgz", - "integrity": "sha512-ioq/fTnjGwouGiDs3luav2O0jAWRqDyf5RJbQNYqLfO4sBkDCRCDnWWzBMOmWV1cjwxqxSw+Eh8JsM3G0duNMA==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-1.0.0-alpha.6.tgz", + "integrity": "sha512-dWEVUVMByOs5JIMsgcceETOYH3nTiAHoIIjXbYeHP6m6HaNP8IE5ex0ZgfmQc29uH0E6H+6aYAv1flfvy56rVQ==", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-error": "^1.0.0-alpha.1", - "@swagger-api/apidom-ns-json-schema-draft-6": "^1.0.0-alpha.3", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-error": "^1.0.0-alpha.6", + "@swagger-api/apidom-ns-json-schema-draft-6": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1738,15 +1740,15 @@ } }, "node_modules/@swagger-api/apidom-ns-openapi-2": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-2/-/apidom-ns-openapi-2-1.0.0-alpha.3.tgz", - "integrity": "sha512-SKXglSEFQESs4QAR1+39GSFzCz5Mt8Bw0on0oEFt8ltOsaLeHlZZaX0eKbJXr8c63Y0zbd5KgONadYBBLsuwJg==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-2/-/apidom-ns-openapi-2-1.0.0-alpha.6.tgz", + "integrity": "sha512-sPwvOY+FGd5yEAijYLupmIYwf4HIpW6yegzrz6uUvGmONZpiCNIidCu+2m6GyYCoZ/lQZdPMw29DuU2O4iiDKw==", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-error": "^1.0.0-alpha.1", - "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-alpha.3", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-error": "^1.0.0-alpha.6", + "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1754,14 +1756,14 @@ } }, "node_modules/@swagger-api/apidom-ns-openapi-3-0": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-1.0.0-alpha.3.tgz", - "integrity": "sha512-Km9FlwayXGAn0402D4YAeJWFO1kAhP/eCs9TgfhAL4Ak1NiQLSDIs+DfI3EAOgROBoUEE2v2Ki/P6yQAFuIgDg==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-1.0.0-alpha.6.tgz", + "integrity": "sha512-kE4s17j69DDvXrf7xeRTunmSQJLiX52fCX1YnfC81e1IPm3q/mdpkZiysM87FuJQQj522fX2G+QUIJlDkD5U9w==", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-error": "^1.0.0-alpha.1", - "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-alpha.3", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-error": "^1.0.0-alpha.6", + "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1769,14 +1771,15 @@ } }, "node_modules/@swagger-api/apidom-ns-openapi-3-1": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-1.0.0-alpha.3.tgz", - "integrity": "sha512-Cl0t+z+ylCPdqGpe8uJslh/DUj3d0oTwlZ0nxUQn1Gocaa5OodZqwyL5NiQj83PLec7MsfHnpfhSwaZIDd+3sA==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-1.0.0-alpha.6.tgz", + "integrity": "sha512-2QA2z9beyaVyZDOXbLg4Nu8o8xKWo9L0WHWOP+hg/haGRyyPHXgyg2XdwRuFBozBI9wBaIfEg1lvNC+J0taDjg==", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^1.0.0-alpha.3", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-alpha.3", + "@swagger-api/apidom-ast": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-json-pointer": "^1.0.0-alpha.6", + "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1784,14 +1787,14 @@ } }, "node_modules/@swagger-api/apidom-ns-workflows-1": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-workflows-1/-/apidom-ns-workflows-1-1.0.0-alpha.3.tgz", - "integrity": "sha512-wdImblzbHOwjuchg15XdZXHhXxoOxWgxwf0NV0qgPEyvhuxvHwpL0tuAYvxiRllPFHPP48dI8aszbFjNOXk1kg==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-workflows-1/-/apidom-ns-workflows-1-1.0.0-alpha.6.tgz", + "integrity": "sha512-9kXU7hUdz25TTGF8b1pmKGugkET4gkW7ING+qSUjU5nWdrkdUIVuq1o8qjaZwRDRvkNynnlRbWHqXeWgRWyi/w==", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.3", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1799,75 +1802,75 @@ } }, "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-json": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-json/-/apidom-parser-adapter-api-design-systems-json-1.0.0-alpha.3.tgz", - "integrity": "sha512-E7uQ+g+TxhE6/IM4sv/zD+341HwnWUNk/jqqDNJtPzjfNAUXw9kBOIrU08cJIIAH8wSr/jNwOFLySt2CsqE1eQ==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-json/-/apidom-parser-adapter-api-design-systems-json-1.0.0-alpha.6.tgz", + "integrity": "sha512-7THBmhvwTmsb1eFXvj/tbIK91g5tzkvhxGSUVbpGt1zApEFmKvjZbDhGnMx15CImIUURW1QZ6TQ/cZ7jRWk8kQ==", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-ns-api-design-systems": "^1.0.0-alpha.3", - "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.3", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-ns-api-design-systems": "^1.0.0-alpha.6", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-yaml": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/-/apidom-parser-adapter-api-design-systems-yaml-1.0.0-alpha.3.tgz", - "integrity": "sha512-Im83uYqh6vIa4xl7BCcgWlRphIyzo4UFU/BX7jE0XKCNeDPemgkRhxjjyx/vOi6ySZI81bAO1UuGb/joE3uA2w==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/-/apidom-parser-adapter-api-design-systems-yaml-1.0.0-alpha.6.tgz", + "integrity": "sha512-xD0aRgRGPaM1J+H3nRg8qP6bQ4fNtsUopoc6JEKzi7NJxd+r/mZV4pVa+Gr6CS+xv4d6TJ53UCJmGsjgmR1bQw==", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-ns-api-design-systems": "^1.0.0-alpha.3", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.3", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-ns-api-design-systems": "^1.0.0-alpha.6", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-json-2": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-json-2/-/apidom-parser-adapter-asyncapi-json-2-1.0.0-alpha.3.tgz", - "integrity": "sha512-tR8nILhc6n8gGyYXr88EaaQXs0gnOD2/2acQg1XS+WKWP4CX+/qsp7mUSC4DEkHrkbpWbbgBSvrK/Stfuzi6AQ==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-json-2/-/apidom-parser-adapter-asyncapi-json-2-1.0.0-alpha.6.tgz", + "integrity": "sha512-BVouq+7XiS2/HmNHd/CHHieyRT5mTN+kqYACnKV/TAzC5+fK3t2mcdng4I81m3Mzb9OJ/VpHiEVlSZiWZoPU/Q==", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-alpha.3", - "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.3", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-alpha.6", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/-/apidom-parser-adapter-asyncapi-yaml-2-1.0.0-alpha.3.tgz", - "integrity": "sha512-6ffIwxLJTE24/6xhVR7F0DRPfrJOIIcXDa8Qfj3iGLE4sbI97WmXBaSwY0k55lwgndVjr1V2Iu4BTuGJpu74Ag==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/-/apidom-parser-adapter-asyncapi-yaml-2-1.0.0-alpha.6.tgz", + "integrity": "sha512-CsUu5t6ijflz0DDjdoxE/OUbSjBAeh5v2zfMRVOfGdnNDhDhrE/3P0VTpdKdVmbWQ1ueIbq2QaC8thQ+Jcxwyg==", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-alpha.3", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.3", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-alpha.6", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-json": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-json/-/apidom-parser-adapter-json-1.0.0-alpha.3.tgz", - "integrity": "sha512-GMGHsJzCI0x+40CMh9wQh+zft3T17CDts/ijYWpllPMZDqZ+1rejSvtwZ2/5vUoDATXue/lWBNnNR0DtxgC0EQ==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-json/-/apidom-parser-adapter-json-1.0.0-alpha.6.tgz", + "integrity": "sha512-ruEkgvJSmBUUsGZdYiHeczekTWCJSWHrNvhAczY6c1ZFhpCukZg9tCqdVhnni/LPp4r4h7BdNldjY7dtrUkCiQ==", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^1.0.0-alpha.3", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-error": "^1.0.0-alpha.1", + "@swagger-api/apidom-ast": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-error": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1877,135 +1880,135 @@ } }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-2": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-2/-/apidom-parser-adapter-openapi-json-2-1.0.0-alpha.3.tgz", - "integrity": "sha512-RphzjaKtb9JwQPJjg014lreEyBNxEOddhTD7nsgPoloYFXglFk+zSoidMCh9J1v1WsirRksuvk0BNhnDupma5A==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-2/-/apidom-parser-adapter-openapi-json-2-1.0.0-alpha.6.tgz", + "integrity": "sha512-RLvjHvjURnqfWxEdLFOW6agBS8CzVyV9++Vg4TSB9gPCNsTlz5w9iy82NYvApExHJIlN55Ga92OZ6CuWXJ8iKw==", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-ns-openapi-2": "^1.0.0-alpha.3", - "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.3", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-ns-openapi-2": "^1.0.0-alpha.6", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-0": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-0/-/apidom-parser-adapter-openapi-json-3-0-1.0.0-alpha.3.tgz", - "integrity": "sha512-zRLQr0XO99HiVzEEJvB1xYqYl6CaNv5O5y5scDg+I1Vlge3gpQOBaCOZdxkGibmHGSkDxV/pCyjN+YptUlnq3Q==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-0/-/apidom-parser-adapter-openapi-json-3-0-1.0.0-alpha.6.tgz", + "integrity": "sha512-cf9+M9vySTrUZW+m2SR04IMnl+5QX6P7S2xgFF705ySOMkPiA9GTgAZJFqwzncAEPovkp7/A24adxyhFz52iZg==", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-alpha.3", - "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.3", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-alpha.6", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-1": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-1/-/apidom-parser-adapter-openapi-json-3-1-1.0.0-alpha.3.tgz", - "integrity": "sha512-paky+VbtVg+tSWfH0Sa+ej0nOkBX/MmuI48i33hIBDP9opbh05e6Rn0rHRdVCx53XdBQNKGjzGYY50Q6cpwC9g==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-1/-/apidom-parser-adapter-openapi-json-3-1-1.0.0-alpha.6.tgz", + "integrity": "sha512-Z7TCUWB/VotmHU5kjUcAlu3qMHCVr1pOpnsuI01I6vCHGJOqUZPelnNqVyw5tjiVbgwDCKzXiPSQo9gGG1HoGA==", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.3", - "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.3", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.6", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-2": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-2/-/apidom-parser-adapter-openapi-yaml-2-1.0.0-alpha.3.tgz", - "integrity": "sha512-2EkWW33Kv6xxsQTa6trSAtnrQHEkdLOrP4IapARXmcdzS02+NSUjE8wT2wfPsDxGAcv856cCmTvEg6Ea/sZWpQ==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-2/-/apidom-parser-adapter-openapi-yaml-2-1.0.0-alpha.6.tgz", + "integrity": "sha512-XI0qlTjL2Q1TMvzxjjEki2iuJqt43C0mwGHremjcpbNHpJejnkEGFDPJqs1rp3RobwRl1ftHVFJi7JVPiA8Zvw==", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-ns-openapi-2": "^1.0.0-alpha.3", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.3", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-ns-openapi-2": "^1.0.0-alpha.6", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/-/apidom-parser-adapter-openapi-yaml-3-0-1.0.0-alpha.3.tgz", - "integrity": "sha512-YKYEImUrp5/ta6X70qUj1NX0DY0Bx7dOqGIY/q/9FZHq3OCsfTHznlF8H4E8B6BAo+u4xyyekvuvql3shQp1hQ==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/-/apidom-parser-adapter-openapi-yaml-3-0-1.0.0-alpha.6.tgz", + "integrity": "sha512-yGd5dP52BrBMO4/nCJdcvotxCbmbXYOi/nQrj7rL4/7VFdKbC4ngT0ggprvKE8CVQC99qPz4qR1y728QdioPAg==", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-alpha.3", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.3", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-alpha.6", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/-/apidom-parser-adapter-openapi-yaml-3-1-1.0.0-alpha.3.tgz", - "integrity": "sha512-X0uotMmUkYWRBPxzpNNZ1288yt3Xt8uXgMrwm/hXAHlUxnRtrWgplPRtlaYzSu2LnRQIluJWYzj8wTmZtGGjBQ==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/-/apidom-parser-adapter-openapi-yaml-3-1-1.0.0-alpha.6.tgz", + "integrity": "sha512-4F/rWh7bi97y20SRskrqz9UdO+YwHOn+vcOvNs5/arI5niSmTeAN3dgH9emTx1LJi8d7woUAct+TEqshwoh/zQ==", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.3", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.3", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.6", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-workflows-json-1": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-workflows-json-1/-/apidom-parser-adapter-workflows-json-1-1.0.0-alpha.3.tgz", - "integrity": "sha512-7zzCK9V0qf7Jd/wUPXSzqENInhbaCbtV+JDB+j6YvqGAN6BR8OjJnGxNQ/du+BUOtaQPEPjBwWXf7gMqmurtEQ==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-workflows-json-1/-/apidom-parser-adapter-workflows-json-1-1.0.0-alpha.6.tgz", + "integrity": "sha512-K2gZFUHtp+Vw9rcizanIJLxSsaYQWNh1QtsEVGtAkn3RBVa130i3umcgQBKuvaBzfhi+Zr21sR4LSrs4XiRHiQ==", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-ns-workflows-1": "^1.0.0-alpha.3", - "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.3", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-ns-workflows-1": "^1.0.0-alpha.6", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-workflows-yaml-1": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-workflows-yaml-1/-/apidom-parser-adapter-workflows-yaml-1-1.0.0-alpha.3.tgz", - "integrity": "sha512-5pIZ4sDFDaMC6LtdQgw0g2quS2dNY5A4M7XJHRpFg+7EmBBiljFsUlfNBfCY1ektdVEIkxp4smDHF9lfS1p7mg==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-workflows-yaml-1/-/apidom-parser-adapter-workflows-yaml-1-1.0.0-alpha.6.tgz", + "integrity": "sha512-yaJ9Iir43odK/zTB0tVL43RBC4ktQvNRfuT21vedqNaxO9J2pjTPy9NkIXJuOrcizinAASDLLUYX/b0UONhVxg==", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-ns-workflows-1": "^1.0.0-alpha.3", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.3", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-ns-workflows-1": "^1.0.0-alpha.6", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-yaml-1-2/-/apidom-parser-adapter-yaml-1-2-1.0.0-alpha.3.tgz", - "integrity": "sha512-h5qFWSa3HPZxUBDYU8eFnTB+1fGF70kwqkHfhOkx7LDeFXIdip0j44mkQPSTDIy9i6F7Nn91AaXHTJJMeEEIZQ==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-yaml-1-2/-/apidom-parser-adapter-yaml-1-2-1.0.0-alpha.6.tgz", + "integrity": "sha512-qevJf2IRvskyvgeGnkJXCGKFnmrcnuMoFHoboI3nJFqdesN74g1hGm1VIVAOOkM4AcdG1w7BviCHEt4YEYGPcQ==", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^1.0.0-alpha.3", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", - "@swagger-api/apidom-error": "^1.0.0-alpha.1", + "@swagger-api/apidom-ast": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-error": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -2015,12 +2018,12 @@ } }, "node_modules/@swagger-api/apidom-reference": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-reference/-/apidom-reference-1.0.0-alpha.3.tgz", - "integrity": "sha512-ir3QbAE8j7+9e0he381O0l3g4DkGDSKQELu6mKPC+W/w0SkG0gJQBqBq9KCltoAURwMpi94MoUWTFq1UfxgyIQ==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-reference/-/apidom-reference-1.0.0-alpha.6.tgz", + "integrity": "sha512-DbsxxgQCVd8ZTJag3EOtzJ2rtsaq4z5z/A4nEgzVQhStuHdRwrbQfxem1g7p6dOK2VrGEGf73UllGJvGV+uPpg==", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.3", + "@swagger-api/apidom-core": "^1.0.0-alpha.6", "@types/ramda": "~0.30.0", "axios": "^1.4.0", "minimatch": "^7.4.3", @@ -2030,26 +2033,26 @@ }, "optionalDependencies": { "@swagger-api/apidom-error": "^1.0.0-alpha.1", - "@swagger-api/apidom-json-pointer": "^1.0.0-alpha.0", - "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-alpha.0", - "@swagger-api/apidom-ns-openapi-2": "^1.0.0-alpha.0", - "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-alpha.0", - "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.0", - "@swagger-api/apidom-ns-workflows-1": "^1.0.0-alpha.0", - "@swagger-api/apidom-parser-adapter-api-design-systems-json": "^1.0.0-alpha.0", - "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": "^1.0.0-alpha.0", - "@swagger-api/apidom-parser-adapter-asyncapi-json-2": "^1.0.0-alpha.0", - "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": "^1.0.0-alpha.0", - "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.0", - "@swagger-api/apidom-parser-adapter-openapi-json-2": "^1.0.0-alpha.0", - "@swagger-api/apidom-parser-adapter-openapi-json-3-0": "^1.0.0-alpha.0", - "@swagger-api/apidom-parser-adapter-openapi-json-3-1": "^1.0.0-alpha.0", - "@swagger-api/apidom-parser-adapter-openapi-yaml-2": "^1.0.0-alpha.0", - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": "^1.0.0-alpha.0", - "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": "^1.0.0-alpha.0", - "@swagger-api/apidom-parser-adapter-workflows-json-1": "^1.0.0-alpha.0", - "@swagger-api/apidom-parser-adapter-workflows-yaml-1": "^1.0.0-alpha.0", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.0" + "@swagger-api/apidom-json-pointer": "^1.0.0-alpha.1", + "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-alpha.1", + "@swagger-api/apidom-ns-openapi-2": "^1.0.0-alpha.1", + "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-alpha.1", + "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.1", + "@swagger-api/apidom-ns-workflows-1": "^1.0.0-alpha.1", + "@swagger-api/apidom-parser-adapter-api-design-systems-json": "^1.0.0-alpha.1", + "@swagger-api/apidom-parser-adapter-api-design-systems-yaml": "^1.0.0-alpha.1", + "@swagger-api/apidom-parser-adapter-asyncapi-json-2": "^1.0.0-alpha.1", + "@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": "^1.0.0-alpha.1", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.1", + "@swagger-api/apidom-parser-adapter-openapi-json-2": "^1.0.0-alpha.1", + "@swagger-api/apidom-parser-adapter-openapi-json-3-0": "^1.0.0-alpha.1", + "@swagger-api/apidom-parser-adapter-openapi-json-3-1": "^1.0.0-alpha.1", + "@swagger-api/apidom-parser-adapter-openapi-yaml-2": "^1.0.0-alpha.1", + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": "^1.0.0-alpha.1", + "@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": "^1.0.0-alpha.1", + "@swagger-api/apidom-parser-adapter-workflows-json-1": "^1.0.0-alpha.1", + "@swagger-api/apidom-parser-adapter-workflows-yaml-1": "^1.0.0-alpha.1", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.1" } }, "node_modules/@swagger-api/apidom-reference/node_modules/minimatch": { @@ -2067,14 +2070,14 @@ } }, "node_modules/@swc/core": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.5.7.tgz", - "integrity": "sha512-U4qJRBefIJNJDRCCiVtkfa/hpiZ7w0R6kASea+/KLp+vkus3zcLSB8Ub8SvKgTIxjWpwsKcZlPf5nrv4ls46SQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.7.0.tgz", + "integrity": "sha512-d4vMzH6ICllDwlPuhset2h8gu/USHdbyfJim+2hQEdxC0UONtfpmu38XBgNqRjStrji1Q5M10jfeUZL3cu1i8g==", "dev": true, "hasInstallScript": true, "dependencies": { - "@swc/counter": "^0.1.2", - "@swc/types": "0.1.7" + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.9" }, "engines": { "node": ">=10" @@ -2084,19 +2087,19 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.5.7", - "@swc/core-darwin-x64": "1.5.7", - "@swc/core-linux-arm-gnueabihf": "1.5.7", - "@swc/core-linux-arm64-gnu": "1.5.7", - "@swc/core-linux-arm64-musl": "1.5.7", - "@swc/core-linux-x64-gnu": "1.5.7", - "@swc/core-linux-x64-musl": "1.5.7", - "@swc/core-win32-arm64-msvc": "1.5.7", - "@swc/core-win32-ia32-msvc": "1.5.7", - "@swc/core-win32-x64-msvc": "1.5.7" + "@swc/core-darwin-arm64": "1.7.0", + "@swc/core-darwin-x64": "1.7.0", + "@swc/core-linux-arm-gnueabihf": "1.7.0", + "@swc/core-linux-arm64-gnu": "1.7.0", + "@swc/core-linux-arm64-musl": "1.7.0", + "@swc/core-linux-x64-gnu": "1.7.0", + "@swc/core-linux-x64-musl": "1.7.0", + "@swc/core-win32-arm64-msvc": "1.7.0", + "@swc/core-win32-ia32-msvc": "1.7.0", + "@swc/core-win32-x64-msvc": "1.7.0" }, "peerDependencies": { - "@swc/helpers": "^0.5.0" + "@swc/helpers": "*" }, "peerDependenciesMeta": { "@swc/helpers": { @@ -2105,9 +2108,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.5.7.tgz", - "integrity": "sha512-bZLVHPTpH3h6yhwVl395k0Mtx8v6CGhq5r4KQdAoPbADU974Mauz1b6ViHAJ74O0IVE5vyy7tD3OpkQxL/vMDQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.0.tgz", + "integrity": "sha512-2ylhM7f0HwUwLrFYZAe/dse8PCbPsYcJS3Dt7Q8NT3PUn7vy6QOMxNcOPPuDrnmaXqQQO3oxdmRapguTxaat9g==", "cpu": [ "arm64" ], @@ -2121,9 +2124,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.5.7.tgz", - "integrity": "sha512-RpUyu2GsviwTc2qVajPL0l8nf2vKj5wzO3WkLSHAHEJbiUZk83NJrZd1RVbEknIMO7+Uyjh54hEh8R26jSByaw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.7.0.tgz", + "integrity": "sha512-SgVnN4gT1Rb9YfTkp4FCUITqSs7Yj0uB2SUciu5CV3HuGvS5YXCUzh+KrwpLFtx8NIgivISKcNnb41mJi98X8Q==", "cpu": [ "x64" ], @@ -2137,9 +2140,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.5.7.tgz", - "integrity": "sha512-cTZWTnCXLABOuvWiv6nQQM0hP6ZWEkzdgDvztgHI/+u/MvtzJBN5lBQ2lue/9sSFYLMqzqff5EHKlFtrJCA9dQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.0.tgz", + "integrity": "sha512-+Z9Dayart1iKJQEJJ9N/KS4z5EdXJE3WPFikY0jonKTo4Dd8RuyVz5yLvqcIMeVdz/SwximATaL6iJXw7hZS9A==", "cpu": [ "arm" ], @@ -2153,9 +2156,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.5.7.tgz", - "integrity": "sha512-hoeTJFBiE/IJP30Be7djWF8Q5KVgkbDtjySmvYLg9P94bHg9TJPSQoC72tXx/oXOgXvElDe/GMybru0UxhKx4g==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.0.tgz", + "integrity": "sha512-UnLrCiZ1EI4shznJn0xP6DLgsXUSwtfsdgHhGYCrvbgVBBve3S9iFgVFEB3SPl7Q/TdowNbrN4zHU0oChfiNfw==", "cpu": [ "arm64" ], @@ -2169,9 +2172,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.5.7.tgz", - "integrity": "sha512-+NDhK+IFTiVK1/o7EXdCeF2hEzCiaRSrb9zD7X2Z7inwWlxAntcSuzZW7Y6BRqGQH89KA91qYgwbnjgTQ22PiQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.0.tgz", + "integrity": "sha512-H724UANA+ptsfwKRr9mnaDa9cb5fw0oFysiGKTgb3DMYcgk3Od0jMTnXVPFSVpo7FlmyxeC9K8ueUPBOoOK6XA==", "cpu": [ "arm64" ], @@ -2185,9 +2188,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.5.7.tgz", - "integrity": "sha512-25GXpJmeFxKB+7pbY7YQLhWWjkYlR+kHz5I3j9WRl3Lp4v4UD67OGXwPe+DIcHqcouA1fhLhsgHJWtsaNOMBNg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.0.tgz", + "integrity": "sha512-SY3HA0K0Dpqt1HIfMLGpwL4hd4UaL2xHP5oZXPlRQPhUDZrbb4PbI3ZJnh66c63eL4ZR8EJ+HRFI0Alx5p69Zw==", "cpu": [ "x64" ], @@ -2201,9 +2204,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.5.7.tgz", - "integrity": "sha512-0VN9Y5EAPBESmSPPsCJzplZHV26akC0sIgd3Hc/7S/1GkSMoeuVL+V9vt+F/cCuzr4VidzSkqftdP3qEIsXSpg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.0.tgz", + "integrity": "sha512-cEJ2ebtV1v/5Ilb55E05J6F5SrHKQWzUttIhR5Mkayyo+yvPslcpByuFC3D+J7X1ebziTOBpWuMpUdjLfh3SMQ==", "cpu": [ "x64" ], @@ -2217,9 +2220,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.5.7.tgz", - "integrity": "sha512-RtoNnstBwy5VloNCvmvYNApkTmuCe4sNcoYWpmY7C1+bPR+6SOo8im1G6/FpNem8AR5fcZCmXHWQ+EUmRWJyuA==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.0.tgz", + "integrity": "sha512-ecQOOmzEssz+m0pR4xDYCGuvn3E/l0nQ3tk5jp1NA1lsAy4bMV0YbYCHjptYvWL/UjhIerIp3IlCJ8x5DodSog==", "cpu": [ "arm64" ], @@ -2233,9 +2236,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.5.7.tgz", - "integrity": "sha512-Xm0TfvcmmspvQg1s4+USL3x8D+YPAfX2JHygvxAnCJ0EHun8cm2zvfNBcsTlnwYb0ybFWXXY129aq1wgFC9TpQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.0.tgz", + "integrity": "sha512-gz81seZkRn3zMnVOc7L5k6F4vQC82gIxmHiL+GedK+A37XI/X26AASU3zxvORnqQbwQYXQ+AEVckxBmFlz3v2g==", "cpu": [ "ia32" ], @@ -2249,9 +2252,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.5.7.tgz", - "integrity": "sha512-tp43WfJLCsKLQKBmjmY/0vv1slVywR5Q4qKjF5OIY8QijaEW7/8VwPyUyVoJZEnDgv9jKtUTG5PzqtIYPZGnyg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.0.tgz", + "integrity": "sha512-b5Fd1xEOw9uqBpj2lqsaR4Iq9UhiL84hNDcEsi6DQA7Y1l85waQAslTbS0E4/pJ1PISAs0jW0zIGLco1eaWBOg==", "cpu": [ "x64" ], @@ -2271,20 +2274,20 @@ "dev": true }, "node_modules/@swc/types": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.7.tgz", - "integrity": "sha512-scHWahbHF0eyj3JsxG9CFJgFdFNaVQCNAimBlT6PzS3n/HptxqREjsm4OH6AN3lYcffZYSPxXW8ua2BEHp0lJQ==", + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.9.tgz", + "integrity": "sha512-qKnCno++jzcJ4lM4NTfYifm1EFSCeIfKiAHAfkENZAV5Kl9PjJIyd2yeeVv6c/2CckuLyv2NmRC5pv6pm2WQBg==", "dev": true, "dependencies": { "@swc/counter": "^0.1.3" } }, "node_modules/@tanstack/react-virtual": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.7.0.tgz", - "integrity": "sha512-3RtOwEU1HKS4iFBoTcCrV3Szqt4KoERMhZr8v57dvnh5o70sR9GAdF+0aE/qhiOmePrKujGwAayFNJSr/8Dbqw==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.8.3.tgz", + "integrity": "sha512-9ICwbDUUzN99CJIGc373i8NLoj6zFTKI2Hlcmo0+lCSAhPQ5mxq4dGOMKmLYoEFyHcGQ64Bd6ZVbnPpM6lNK5w==", "dependencies": { - "@tanstack/virtual-core": "3.7.0" + "@tanstack/virtual-core": "3.8.3" }, "funding": { "type": "github", @@ -2296,9 +2299,9 @@ } }, "node_modules/@tanstack/virtual-core": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.7.0.tgz", - "integrity": "sha512-p0CWuqn+n8iZmsL7/l0Xg7kbyIKnHNqkEJkMDOkg4x3Ni3LohszmnJY8FPhTgG7Ad9ZFGcdKmn1R1mKUGEh9Xg==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.8.3.tgz", + "integrity": "sha512-vd2A2TnM5lbnWZnHi9B+L2gPtkSeOtJOAw358JqokIH1+v2J7vUAzFVPwB/wrye12RFOurffXu33plm4uQ+JBQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" @@ -2332,11 +2335,11 @@ "devOptional": true }, "node_modules/@types/ramda": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.30.0.tgz", - "integrity": "sha512-DQtfqUbSB18iM9NHbQ++kVUDuBWHMr6T2FpW1XTiksYRGjq4WnNPZLt712OEHEBJs7aMyJ68Mf2kGMOP1srVVw==", + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-aoyF/ADPL6N+/NXXfhPWF+Qj6w1Cql59m9wX0Gi15uyF+bpzXeLd63HPdiTDE2bmLXfNcVufsDPKmbfOrOzTBA==", "dependencies": { - "types-ramda": "^0.30.0" + "types-ramda": "^0.30.1" } }, "node_modules/@types/react": { @@ -2386,16 +2389,16 @@ "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.14.1.tgz", - "integrity": "sha512-aAJd6bIf2vvQRjUG3ZkNXkmBpN+J7Wd0mfQiiVCJMu9Z5GcZZdcc0j8XwN/BM97Fl7e3SkTXODSk4VehUv7CGw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", + "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.14.1", - "@typescript-eslint/type-utils": "7.14.1", - "@typescript-eslint/utils": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/type-utils": "7.16.1", + "@typescript-eslint/utils": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -2418,63 +2421,16 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", - "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", - "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", - "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/parser": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.14.1.tgz", - "integrity": "sha512-8lKUOebNLcR0D7RvlcloOacTOWzOqemWEWkKSVpMZVF/XVcwjPR+3MD08QzbW9TCGJ+DwIc6zUSGZ9vd8cO1IA==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz", + "integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.14.1", - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/typescript-estree": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "debug": "^4.3.4" }, "engines": { @@ -2493,89 +2449,14 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", - "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", - "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", - "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", - "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz", - "integrity": "sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", + "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1" + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -2586,13 +2467,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.14.1.tgz", - "integrity": "sha512-/MzmgNd3nnbDbOi3LfasXWWe292+iuo+umJ0bCCMCPc1jLO/z2BQmWUUUXvXLbrQey/JgzdF/OV+I5bzEGwJkQ==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz", + "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.14.1", - "@typescript-eslint/utils": "7.14.1", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/utils": "7.16.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -2612,68 +2493,10 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", - "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", - "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", - "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/types": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", - "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", + "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -2684,13 +2507,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.1.tgz", - "integrity": "sha512-uxNr51CMV7npU1BxZzYjoVz9iyjckBduFBP0S5sLlh1tXYzHzgZ3BR9SVsNed+LmwKrmnqN3Kdl5t7eZ5TS1Yw==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", + "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2712,15 +2535,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz", - "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", + "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.14.1", - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/typescript-estree": "7.14.1" + "@typescript-eslint/scope-manager": "7.16.1", + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -2733,88 +2556,13 @@ "eslint": "^8.56.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz", - "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz", - "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz", - "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "@typescript-eslint/visitor-keys": "7.14.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.14.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz", - "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.14.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz", - "integrity": "sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==", + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", + "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/types": "7.16.1", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -2844,9 +2592,9 @@ } }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2905,9 +2653,9 @@ } }, "node_modules/apg-lite": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/apg-lite/-/apg-lite-1.0.3.tgz", - "integrity": "sha512-lOoNkL7vN7PGdyQMFPey1aok2oVVqvs3n7UMFBRvQ9FoELSbKhgPc3rd7JptaGwCmo4125gLX9Cqb8ElvLCFaQ==" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/apg-lite/-/apg-lite-1.0.4.tgz", + "integrity": "sha512-B32zCN3IdHIc99Vy7V9BaYTUzLeRA8YXYY1aQD1/5I2aqIrO0coi4t6hJPqMisidlBxhyME8UexkHt31SlR6Og==" }, "node_modules/argparse": { "version": "2.0.1", @@ -3253,9 +3001,9 @@ "devOptional": true }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -3538,9 +3286,9 @@ } }, "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.7.tgz", - "integrity": "sha512-yrj+KInFmwuQS2UQcg1SF83ha1tuHC1jMQbRNyuWtlEzzKRDgAl7L4Yp4NlDUZTZNlWvHEzOtJhMi40R7JxcSw==", + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.8.tgz", + "integrity": "sha512-MIKAclwaDFIiYtVBLzDdm16E+Ty4GwhB6wZlCAG1R3Ur+F9Qbo6PRxpA5DK7XtDgm+WlCoAY2WxAwqhmIDHg6Q==", "dev": true, "peerDependencies": { "eslint": ">=7" @@ -3614,9 +3362,9 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -3934,6 +3682,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -4037,11 +3786,11 @@ "dev": true }, "node_modules/graphiql": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/graphiql/-/graphiql-3.3.1.tgz", - "integrity": "sha512-UA29FQ418Pcxat54CvM//S5G+7DKG7XQ7s9UyAEdb7zMAKPANIDd222XEYNxG2I/FgAxsiq3ZTBpxwvPbB9Mcw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/graphiql/-/graphiql-3.3.2.tgz", + "integrity": "sha512-LJ8Q6UM3kUzTXvybud9a4sj/QBEVHwHWd5Oc3OjLp9DQiKjqVY/2P/Q3RdPQD/MihwaO+6eC69R4MYnPQGd2Hw==", "dependencies": { - "@graphiql/react": "^0.22.3", + "@graphiql/react": "^0.22.4", "@graphiql/toolkit": "^0.9.1", "graphql-language-service": "^5.2.1", "markdown-it": "^14.1.0" @@ -4231,6 +3980,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, "dependencies": { "once": "^1.3.0", @@ -4492,18 +4242,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "devOptional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/markdown-it": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", @@ -4551,12 +4289,12 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "dev": true, "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -4606,9 +4344,9 @@ } }, "node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -4642,9 +4380,9 @@ "dev": true }, "node_modules/nan": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.19.0.tgz", - "integrity": "sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz", + "integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==", "optional": true }, "node_modules/nanoid": { @@ -4678,9 +4416,9 @@ "dev": true }, "node_modules/node-abi": { - "version": "3.62.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.62.0.tgz", - "integrity": "sha512-CPMcGa+y33xuL1E0TcNIu4YyaZCxnnvkVaEXrsosR3FxN+fV8xvb7Mzpb7IgKler10qeMkE6+Dp8qJhpzdq35g==", + "version": "3.65.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.65.0.tgz", + "integrity": "sha512-ThjYBfoDNr08AWx6hGaRbfPwxKV9kVzAzOzlLKbk2CuqXE2xnCh+cbAGnwM3t8Lq4v9rUB7VfondlkBckcJrVA==", "optional": true, "dependencies": { "semver": "^7.3.5" @@ -4742,9 +4480,12 @@ } }, "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4759,9 +4500,20 @@ } }, "node_modules/openapi-path-templating": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/openapi-path-templating/-/openapi-path-templating-1.5.1.tgz", - "integrity": "sha512-kgRHToVP571U1YzUnaZnWaUIygon2itg5g96kwaFIi8bnpsw4oXYOk7k59Ivn+ley1iQnMENe/1HSovpPVZuXA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/openapi-path-templating/-/openapi-path-templating-1.6.0.tgz", + "integrity": "sha512-1atBNwOUrZXthTvlvvX8k8ovFEF3iA8mDidYMkdOtvVdndBhTrspbwGXNOzEUaJhm9iUl4Tf5uQaeTLAJvwPig==", + "dependencies": { + "apg-lite": "^1.0.3" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/openapi-server-url-templating": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/openapi-server-url-templating/-/openapi-server-url-templating-1.1.0.tgz", + "integrity": "sha512-dtyTFKx2xVcO0W8JKaluXIHC9l/MLjHeflBaWjiWNMCHp/TBs9dEjQDbj/VFlHR4omFOKjjmqm1pW1aCAhmPBg==", "dependencies": { "apg-lite": "^1.0.3" }, @@ -4882,9 +4634,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", "dev": true }, "node_modules/picomatch": { @@ -4911,9 +4663,9 @@ } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", "dev": true, "funding": [ { @@ -4931,7 +4683,7 @@ ], "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "source-map-js": "^1.2.0" }, "engines": { @@ -5044,9 +4796,9 @@ } }, "node_modules/qs": { - "version": "6.12.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz", - "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==", + "version": "6.12.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.3.tgz", + "integrity": "sha512-AWJm14H1vVaO/iNZ4/hO+HyaTehuy9nRqVdkTqlJt0HWvBiBIEXFmb4C0DGeYo3Xes9rrEW+TxHsaigCbN5ICQ==", "dependencies": { "side-channel": "^1.0.6" }, @@ -5083,18 +4835,18 @@ ] }, "node_modules/ramda": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.0.tgz", - "integrity": "sha512-13Y0iMhIQuAm/wNGBL/9HEqIfRGmNmjKnTPlKWfA9f7dnDkr8d45wQ+S7+ZLh/Pq9PdcGxkqKUEA7ySu1QSd9Q==", + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", "funding": { "type": "opencollective", "url": "https://opencollective.com/ramda" } }, "node_modules/ramda-adjunct": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.0.0.tgz", - "integrity": "sha512-iEehjqp/ZGjYZybZByDaDu27c+79SE7rKDcySLdmjAwKWkz6jNhvGgZwzUGaMsij8Llp9+1N1Gy0drpAq8ZSyA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.0.1.tgz", + "integrity": "sha512-UTQCcWnoiuYH+ua+jGg3GTktcmCSD2W7OO2++tmv8p2Ze+N9VgVACERg4g36rRfIXklVMtqazyBLBWXfoPKgRQ==", "engines": { "node": ">=0.10.3" }, @@ -5426,9 +5178,9 @@ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, "node_modules/reselect": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.0.tgz", - "integrity": "sha512-aw7jcGLDpSgNDyWBQLv2cedml85qd95/iszJjN988zX1t7AVRJi19d9kto5+W7oCfQ94gyo40dVbT6g2k4/kXg==" + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==" }, "node_modules/resolve-from": { "version": "4.0.0", @@ -5461,6 +5213,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "dependencies": { "glob": "^7.1.3" @@ -5473,9 +5226,9 @@ } }, "node_modules/rollup": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", - "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.1.tgz", + "integrity": "sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -5488,22 +5241,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.17.2", - "@rollup/rollup-android-arm64": "4.17.2", - "@rollup/rollup-darwin-arm64": "4.17.2", - "@rollup/rollup-darwin-x64": "4.17.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", - "@rollup/rollup-linux-arm-musleabihf": "4.17.2", - "@rollup/rollup-linux-arm64-gnu": "4.17.2", - "@rollup/rollup-linux-arm64-musl": "4.17.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", - "@rollup/rollup-linux-riscv64-gnu": "4.17.2", - "@rollup/rollup-linux-s390x-gnu": "4.17.2", - "@rollup/rollup-linux-x64-gnu": "4.17.2", - "@rollup/rollup-linux-x64-musl": "4.17.2", - "@rollup/rollup-win32-arm64-msvc": "4.17.2", - "@rollup/rollup-win32-ia32-msvc": "4.17.2", - "@rollup/rollup-win32-x64-msvc": "4.17.2", + "@rollup/rollup-android-arm-eabi": "4.18.1", + "@rollup/rollup-android-arm64": "4.18.1", + "@rollup/rollup-darwin-arm64": "4.18.1", + "@rollup/rollup-darwin-x64": "4.18.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.1", + "@rollup/rollup-linux-arm-musleabihf": "4.18.1", + "@rollup/rollup-linux-arm64-gnu": "4.18.1", + "@rollup/rollup-linux-arm64-musl": "4.18.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.1", + "@rollup/rollup-linux-riscv64-gnu": "4.18.1", + "@rollup/rollup-linux-s390x-gnu": "4.18.1", + "@rollup/rollup-linux-x64-gnu": "4.18.1", + "@rollup/rollup-linux-x64-musl": "4.18.1", + "@rollup/rollup-win32-arm64-msvc": "4.18.1", + "@rollup/rollup-win32-ia32-msvc": "4.18.1", + "@rollup/rollup-win32-x64-msvc": "4.18.1", "fsevents": "~2.3.2" } }, @@ -5558,13 +5311,10 @@ } }, "node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "devOptional": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -5816,37 +5566,29 @@ } }, "node_modules/swagger-client": { - "version": "3.28.1", - "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.28.1.tgz", - "integrity": "sha512-tt3/54GTImgOLrjzl83FZ+koJ7Kq6uuyBNS7mTpZeUQsBi2a/4IvqPcfY2qKhf7CFrbv6lzPm+MmSudrxU8J5g==", + "version": "3.28.2", + "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.28.2.tgz", + "integrity": "sha512-g30KCdSVyZlMulWOJnheNo7Ea+L06OZebl0oRU6zHd5Zf5AZKHTqurKRdNOLsMWA3l3bWJiEh7s3JlzFJHRmoQ==", "dependencies": { "@babel/runtime-corejs3": "^7.22.15", - "@swagger-api/apidom-core": ">=1.0.0-alpha.3 <1.0.0-beta.0", - "@swagger-api/apidom-error": ">=1.0.0-alpha.1 <1.0.0-beta.0", - "@swagger-api/apidom-json-pointer": ">=1.0.0-alpha.3 <1.0.0-beta.0", - "@swagger-api/apidom-ns-openapi-3-1": ">=1.0.0-alpha.3 <1.0.0-beta.0", - "@swagger-api/apidom-reference": ">=1.0.0-alpha.3 <1.0.0-beta.0", + "@swagger-api/apidom-core": ">=1.0.0-alpha.5 <1.0.0-beta.0", + "@swagger-api/apidom-error": ">=1.0.0-alpha.5 <1.0.0-beta.0", + "@swagger-api/apidom-json-pointer": ">=1.0.0-alpha.5 <1.0.0-beta.0", + "@swagger-api/apidom-ns-openapi-3-1": ">=1.0.0-alpha.5 <1.0.0-beta.0", + "@swagger-api/apidom-reference": ">=1.0.0-alpha.5 <1.0.0-beta.0", "cookie": "~0.6.0", "deepmerge": "~4.3.0", "fast-json-patch": "^3.0.0-1", - "is-plain-object": "^5.0.0", "js-yaml": "^4.1.0", "node-abort-controller": "^3.1.1", "node-fetch-commonjs": "^3.3.2", "openapi-path-templating": "^1.5.1", + "openapi-server-url-templating": "^1.0.0", "qs": "^6.10.2", "ramda-adjunct": "^5.0.0", "traverse": "=0.6.8" } }, - "node_modules/swagger-client/node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/swagger-ui-react": { "version": "5.17.14", "resolved": "https://registry.npmjs.org/swagger-ui-react/-/swagger-ui-react-5.17.14.tgz", @@ -6007,9 +5749,9 @@ "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==" }, "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/tunnel-agent": { "version": "0.6.0", @@ -6047,17 +5789,17 @@ } }, "node_modules/types-ramda": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/types-ramda/-/types-ramda-0.30.0.tgz", - "integrity": "sha512-oVPw/KHB5M0Du0txTEKKM8xZOG9cZBRdCVXvwHYuNJUVkAiJ9oWyqkA+9Bj2gjMsHgkkhsYevobQBWs8I2/Xvw==", + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/types-ramda/-/types-ramda-0.30.1.tgz", + "integrity": "sha512-1HTsf5/QVRmLzcGfldPFvkVsAdi1db1BBKzi7iW3KBUlOICg/nKnFS+jGqDJS3YD8VsWbAh7JiHeBvbsw8RPxA==", "dependencies": { "ts-toolbelt": "^9.6.0" } }, "node_modules/typescript": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", - "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -6151,13 +5893,13 @@ "optional": true }, "node_modules/vite": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz", - "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", + "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==", "dev": true, "dependencies": { "esbuild": "^0.21.3", - "postcss": "^8.4.38", + "postcss": "^8.4.39", "rollup": "^4.13.0" }, "bin": { @@ -6281,12 +6023,6 @@ "node": ">=0.4" } }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "devOptional": true - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/playground/package.json b/playground/package.json index d0fd624355..b8b263a9a3 100644 --- a/playground/package.json +++ b/playground/package.json @@ -10,7 +10,7 @@ "preview": "vite preview" }, "dependencies": { - "graphiql": "^3.3.1", + "graphiql": "^3.3.2", "graphql": "^16.9.0", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -20,13 +20,13 @@ "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@types/swagger-ui-react": "^4.18.3", - "@typescript-eslint/eslint-plugin": "^7.14.1", - "@typescript-eslint/parser": "^7.14.1", + "@typescript-eslint/eslint-plugin": "^7.16.1", + "@typescript-eslint/parser": "^7.16.1", "@vitejs/plugin-react-swc": "^3.7.0", "eslint": "^8.57.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.7", - "typescript": "^5.5.2", - "vite": "^5.3.2" + "typescript": "^5.5.3", + "vite": "^5.3.4" } } From 517333cbdd8856f638701047c2b86c5d58dfd786 Mon Sep 17 00:00:00 2001 From: Keenan Nemetz Date: Thu, 18 Jul 2024 13:48:56 -0700 Subject: [PATCH 16/41] refactor: Network test sync logic (#2748) ## Relevant issue(s) Resolves #2747 ## Description This PR improves the network sync test logic to allow for further improvements to the network implementation. ## Tasks - [x] I made sure the code is well commented, particularly hard-to-understand areas. - [x] I made sure the repository-held documentation is changed accordingly. - [x] I made sure the pull request title adheres to the conventional commit style (the subset used in the project can be found in [tools/configs/chglog/config.yml](tools/configs/chglog/config.yml)). - [x] I made sure to discuss its limitations such as threats to validity, vulnerability to mistake and misuse, robustness to invalidation of assumptions, resource requirements, ... ## How has this been tested? `make test` Specify the platform(s) on which this was tested: - MacOS --- net/peer.go | 13 + net/server.go | 75 +++-- .../acp/register_and_update_test.go | 4 + tests/integration/events.go | 242 ++++++++++++++ .../net/simple/peer/with_delete_test.go | 10 +- .../net/simple/replicator/with_create_test.go | 2 - tests/integration/p2p.go | 295 +----------------- tests/integration/state.go | 95 +++++- tests/integration/test_case.go | 10 +- tests/integration/utils2.go | 95 ++---- 10 files changed, 457 insertions(+), 384 deletions(-) create mode 100644 tests/integration/events.go diff --git a/net/peer.go b/net/peer.go index 00ea8653a0..7222d7cf9f 100644 --- a/net/peer.go +++ b/net/peer.go @@ -24,6 +24,7 @@ import ( "github.com/ipfs/boxo/blockservice" exchange "github.com/ipfs/boxo/exchange" "github.com/ipfs/boxo/ipns" + blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" ds "github.com/ipfs/go-datastore" libp2p "github.com/libp2p/go-libp2p" @@ -446,6 +447,13 @@ func (p *Peer) handleDocUpdateLog(evt event.Update) error { } func (p *Peer) pushLogToReplicators(lg event.Update) { + // let the exchange know we have this block + // this should speed up the dag sync process + err := p.bserv.Exchange().NotifyNewBlocks(p.ctx, blocks.NewBlock(lg.Block)) + if err != nil { + log.ErrorContextE(p.ctx, "Failed to notify new blocks", err) + } + // push to each peer (replicator) peers := make(map[string]struct{}) for _, peer := range p.ps.ListPeers(lg.DocID) { @@ -504,6 +512,11 @@ func stopGRPCServer(ctx context.Context, server *grpc.Server) { } } +// Connect initiates a connection to the peer with the given address. +func (p *Peer) Connect(ctx context.Context, addr peer.AddrInfo) error { + return p.host.Connect(ctx, addr) +} + // Bootstrap connects to the given peers. func (p *Peer) Bootstrap(addrs []peer.AddrInfo) { var connected uint64 diff --git a/net/server.go b/net/server.go index 3b4922fe5e..0e36eb7e3c 100644 --- a/net/server.go +++ b/net/server.go @@ -125,18 +125,24 @@ func (s *server) PushLog(ctx context.Context, req *pb.PushLogRequest) (*pb.PushL if err != nil { return nil, err } + + log.InfoContext(ctx, "Received pushlog", + corelog.Any("PeerID", pid.String()), + corelog.Any("Creator", byPeer.String()), + corelog.Any("DocID", docID.String())) + + log.InfoContext(ctx, "Starting DAG sync", + corelog.Any("PeerID", pid.String()), + corelog.Any("DocID", docID.String())) + err = syncDAG(ctx, s.peer.bserv, block) if err != nil { return nil, err } - s.peer.bus.Publish(event.NewMessage(event.MergeName, event.Merge{ - DocID: docID.String(), - ByPeer: byPeer, - FromPeer: pid, - Cid: headCID, - SchemaRoot: string(req.Body.SchemaRoot), - })) + log.InfoContext(ctx, "DAG sync complete", + corelog.Any("PeerID", pid.String()), + corelog.Any("DocID", docID.String())) // Once processed, subscribe to the DocID topic on the pubsub network unless we already // suscribe to the collection. @@ -146,6 +152,15 @@ func (s *server) PushLog(ctx context.Context, req *pb.PushLogRequest) (*pb.PushL return nil, err } } + + s.peer.bus.Publish(event.NewMessage(event.MergeName, event.Merge{ + DocID: docID.String(), + ByPeer: byPeer, + FromPeer: pid, + Cid: headCID, + SchemaRoot: string(req.Body.SchemaRoot), + })) + return &pb.PushLogReply{}, nil } @@ -163,6 +178,10 @@ func (s *server) addPubSubTopic(topic string, subscribe bool) error { return nil } + log.InfoContext(s.peer.ctx, "Adding pubsub topic", + corelog.String("PeerID", s.peer.PeerID().String()), + corelog.String("Topic", topic)) + s.mu.Lock() defer s.mu.Unlock() if t, ok := s.topics[topic]; ok { @@ -205,6 +224,10 @@ func (s *server) removePubSubTopic(topic string) error { return nil } + log.InfoContext(s.peer.ctx, "Removing pubsub topic", + corelog.String("PeerID", s.peer.PeerID().String()), + corelog.String("Topic", topic)) + s.mu.Lock() defer s.mu.Unlock() if t, ok := s.topics[topic]; ok { @@ -218,6 +241,10 @@ func (s *server) removeAllPubsubTopics() error { if s.peer.ps == nil { return nil } + + log.InfoContext(s.peer.ctx, "Removing all pubsub topics", + corelog.String("PeerID", s.peer.PeerID().String())) + s.mu.Lock() defer s.mu.Unlock() for id, t := range s.topics { @@ -232,6 +259,10 @@ func (s *server) removeAllPubsubTopics() error { // publishLog publishes the given PushLogRequest object on the PubSub network via the // corresponding topic func (s *server) publishLog(ctx context.Context, topic string, req *pb.PushLogRequest) error { + log.InfoContext(ctx, "Publish log", + corelog.String("PeerID", s.peer.PeerID().String()), + corelog.String("Topic", topic)) + if s.peer.ps == nil { // skip if we aren't running with a pubsub net return nil } @@ -259,12 +290,16 @@ func (s *server) publishLog(ctx context.Context, topic string, req *pb.PushLogRe // pubSubMessageHandler handles incoming PushLog messages from the pubsub network. func (s *server) pubSubMessageHandler(from libpeer.ID, topic string, msg []byte) ([]byte, error) { + log.InfoContext(s.peer.ctx, "Received new pubsub event", + corelog.String("PeerID", s.peer.PeerID().String()), + corelog.Any("SenderId", from), + corelog.String("Topic", topic)) + req := new(pb.PushLogRequest) if err := proto.Unmarshal(msg, req); err != nil { log.ErrorContextE(s.peer.ctx, "Failed to unmarshal pubsub message %s", err) return nil, err } - ctx := grpcpeer.NewContext(s.peer.ctx, &grpcpeer.Peer{ Addr: addr{from}, }) @@ -276,9 +311,8 @@ func (s *server) pubSubMessageHandler(from libpeer.ID, topic string, msg []byte) // pubSubEventHandler logs events from the subscribed DocID topics. func (s *server) pubSubEventHandler(from libpeer.ID, topic string, msg []byte) { - log.InfoContext( - s.peer.ctx, - "Received new pubsub event", + log.InfoContext(s.peer.ctx, "Received new pubsub event", + corelog.String("PeerID", s.peer.PeerID().String()), corelog.Any("SenderId", from), corelog.String("Topic", topic), corelog.String("Message", string(msg)), @@ -329,7 +363,18 @@ func (s *server) updatePubSubTopics(evt event.P2PTopic) { } func (s *server) updateReplicators(evt event.Replicator) { - isDeleteRep := len(evt.Schemas) == 0 + if len(evt.Schemas) == 0 { + // remove peer from store + s.peer.host.Peerstore().ClearAddrs(evt.Info.ID) + } else { + // add peer to store + s.peer.host.Peerstore().AddAddrs(evt.Info.ID, evt.Info.Addrs, peerstore.PermanentAddrTTL) + // connect to the peer + if err := s.peer.Connect(s.peer.ctx, evt.Info); err != nil { + log.ErrorContextE(s.peer.ctx, "Failed to connect to replicator peer", err) + } + } + // update the cached replicators s.mu.Lock() for schema, peers := range s.replicators { @@ -350,12 +395,6 @@ func (s *server) updateReplicators(evt event.Replicator) { } s.mu.Unlock() - if isDeleteRep { - s.peer.host.Peerstore().ClearAddrs(evt.Info.ID) - } else { - s.peer.host.Peerstore().AddAddrs(evt.Info.ID, evt.Info.Addrs, peerstore.PermanentAddrTTL) - } - if evt.Docs != nil { for update := range evt.Docs { if err := s.pushLog(s.peer.ctx, update, evt.Info.ID); err != nil { diff --git a/tests/integration/acp/register_and_update_test.go b/tests/integration/acp/register_and_update_test.go index edfeb99c97..842ef1b754 100644 --- a/tests/integration/acp/register_and_update_test.go +++ b/tests/integration/acp/register_and_update_test.go @@ -650,6 +650,8 @@ func TestACP_CreateWithIdentityAndUpdateWithoutIdentityGQL_CanNotUpdate(t *testi "name": "Shahzad Lone" } `, + + SkipLocalUpdateEvent: true, }, testUtils.Request{ @@ -764,6 +766,8 @@ func TestACP_CreateWithIdentityAndUpdateWithWrongIdentityGQL_CanNotUpdate(t *tes "name": "Shahzad Lone" } `, + + SkipLocalUpdateEvent: true, }, testUtils.Request{ diff --git a/tests/integration/events.go b/tests/integration/events.go new file mode 100644 index 0000000000..946c089d4a --- /dev/null +++ b/tests/integration/events.go @@ -0,0 +1,242 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package tests + +import ( + "time" + + "github.com/sourcenetwork/immutable" + "github.com/stretchr/testify/require" + + "github.com/sourcenetwork/defradb/event" +) + +// eventTimeout is the amount of time to wait +// for an event before timing out +const eventTimeout = 1 * time.Second + +// waitForNetworkSetupEvents waits for p2p topic completed and +// replicator completed events to be published on the local node event bus. +func waitForNetworkSetupEvents(s *state, nodeID int) { + cols, err := s.nodes[nodeID].GetAllP2PCollections(s.ctx) + require.NoError(s.t, err) + + reps, err := s.nodes[nodeID].GetAllReplicators(s.ctx) + require.NoError(s.t, err) + + replicatorEvents := len(reps) + p2pTopicEvent := len(cols) > 0 + + for p2pTopicEvent && replicatorEvents > 0 { + select { + case _, ok := <-s.nodeEvents[nodeID].replicator.Message(): + if !ok { + require.Fail(s.t, "subscription closed waiting for network setup events") + } + replicatorEvents-- + + case _, ok := <-s.nodeEvents[nodeID].p2pTopic.Message(): + if !ok { + require.Fail(s.t, "subscription closed waiting for network setup events") + } + p2pTopicEvent = false + + case <-time.After(eventTimeout): + s.t.Fatalf("timeout waiting for network setup events") + } + } +} + +// waitForReplicatorConfigureEvent waits for a node to publish a +// replicator completed event on the local event bus. +// +// Expected document heads will be updated for the targeted node. +func waitForReplicatorConfigureEvent(s *state, cfg ConfigureReplicator) { + select { + case _, ok := <-s.nodeEvents[cfg.SourceNodeID].replicator.Message(): + if !ok { + require.Fail(s.t, "subscription closed waiting for replicator event") + } + + case <-time.After(eventTimeout): + require.Fail(s.t, "timeout waiting for replicator event") + } + + // all previous documents should be merged on the subscriber node + for key, val := range s.nodeP2P[cfg.SourceNodeID].actualDocHeads { + s.nodeP2P[cfg.TargetNodeID].expectedDocHeads[key] = val + } + + // update node connections and replicators + s.nodeP2P[cfg.TargetNodeID].connections[cfg.SourceNodeID] = struct{}{} + s.nodeP2P[cfg.SourceNodeID].connections[cfg.TargetNodeID] = struct{}{} + s.nodeP2P[cfg.SourceNodeID].replicators[cfg.TargetNodeID] = struct{}{} +} + +// waitForReplicatorConfigureEvent waits for a node to publish a +// replicator completed event on the local event bus. +func waitForReplicatorDeleteEvent(s *state, cfg DeleteReplicator) { + select { + case _, ok := <-s.nodeEvents[cfg.SourceNodeID].replicator.Message(): + if !ok { + require.Fail(s.t, "subscription closed waiting for replicator event") + } + + case <-time.After(eventTimeout): + require.Fail(s.t, "timeout waiting for replicator event") + } + + delete(s.nodeP2P[cfg.TargetNodeID].connections, cfg.SourceNodeID) + delete(s.nodeP2P[cfg.SourceNodeID].connections, cfg.TargetNodeID) + delete(s.nodeP2P[cfg.SourceNodeID].replicators, cfg.TargetNodeID) +} + +// waitForSubscribeToCollectionEvent waits for a node to publish a +// p2p topic completed event on the local event bus. +// +// Expected document heads will be updated for the subscriber node. +func waitForSubscribeToCollectionEvent(s *state, action SubscribeToCollection) { + select { + case _, ok := <-s.nodeEvents[action.NodeID].p2pTopic.Message(): + if !ok { + require.Fail(s.t, "subscription closed waiting for p2p topic event") + } + + case <-time.After(eventTimeout): + require.Fail(s.t, "timeout waiting for p2p topic event") + } + + // update peer collections of target node + for _, collectionIndex := range action.CollectionIDs { + if collectionIndex == NonExistentCollectionID { + continue // don't track non existent collections + } + s.nodeP2P[action.NodeID].peerCollections[collectionIndex] = struct{}{} + } +} + +// waitForSubscribeToCollectionEvent waits for a node to publish a +// p2p topic completed event on the local event bus. +func waitForUnsubscribeToCollectionEvent(s *state, action UnsubscribeToCollection) { + select { + case _, ok := <-s.nodeEvents[action.NodeID].p2pTopic.Message(): + if !ok { + require.Fail(s.t, "subscription closed waiting for p2p topic event") + } + + case <-time.After(eventTimeout): + require.Fail(s.t, "timeout waiting for p2p topic event") + } + + for _, collectionIndex := range action.CollectionIDs { + if collectionIndex == NonExistentCollectionID { + continue // don't track non existent collections + } + delete(s.nodeP2P[action.NodeID].peerCollections, collectionIndex) + } +} + +// waitForUpdateEvents waits for all selected nodes to publish an +// update event to the local event bus. +// +// Expected document heads will be updated for any connected nodes. +func waitForUpdateEvents(s *state, nodeID immutable.Option[int], collectionID int) { + for i := 0; i < len(s.nodes); i++ { + if nodeID.HasValue() && nodeID.Value() != i { + continue // node is not selected + } + + var evt event.Update + select { + case msg, ok := <-s.nodeEvents[i].update.Message(): + if !ok { + require.Fail(s.t, "subscription closed waiting for update event") + } + evt = msg.Data.(event.Update) + + case <-time.After(eventTimeout): + require.Fail(s.t, "timeout waiting for update event") + } + + if i >= len(s.nodeConfigs) { + return // not testing network state + } + + // make sure the event is published on the network before proceeding + // this prevents nodes from missing messages that are sent before + // subscriptions are setup + time.Sleep(100 * time.Millisecond) + + // update the actual document head on the node that updated it + s.nodeP2P[i].actualDocHeads[evt.DocID] = evt.Cid + + // update the expected document heads of replicator targets + for id := range s.nodeP2P[i].replicators { + // replicator target nodes push updates to source nodes + s.nodeP2P[id].expectedDocHeads[evt.DocID] = evt.Cid + } + + // update the expected document heads of connected nodes + for id := range s.nodeP2P[i].connections { + // connected nodes share updates of documents they have in common + if _, ok := s.nodeP2P[id].actualDocHeads[evt.DocID]; ok { + s.nodeP2P[id].expectedDocHeads[evt.DocID] = evt.Cid + } + // peer collection subscribers receive updates from any other subscriber node + if _, ok := s.nodeP2P[id].peerCollections[collectionID]; ok { + s.nodeP2P[id].expectedDocHeads[evt.DocID] = evt.Cid + } + } + } +} + +// waitForMergeEvents waits for all expected document heads to be merged to all nodes. +// +// Will fail the test if an event is not received within the expected time interval to prevent tests +// from running forever. +func waitForMergeEvents(s *state) { + for nodeID := 0; nodeID < len(s.nodes); nodeID++ { + expect := s.nodeP2P[nodeID].expectedDocHeads + + // remove any docs that are already merged + // up to the expected document head + for key, val := range s.nodeP2P[nodeID].actualDocHeads { + if head, ok := expect[key]; ok && head.String() == val.String() { + delete(expect, key) + } + } + + // wait for all expected doc heads to be merged + // + // the order of merges does not matter as we only + // expect the latest head to eventually be merged + // + // unexpected merge events are ignored + for len(expect) > 0 { + var evt event.Merge + select { + case msg, ok := <-s.nodeEvents[nodeID].merge.Message(): + if !ok { + require.Fail(s.t, "subscription closed waiting for merge complete event") + } + evt = msg.Data.(event.Merge) + + case <-time.After(30 * eventTimeout): + require.Fail(s.t, "timeout waiting for merge complete event") + } + + head, ok := expect[evt.DocID] + if ok && head.String() == evt.Cid.String() { + delete(expect, evt.DocID) + } + } + } +} diff --git a/tests/integration/net/simple/peer/with_delete_test.go b/tests/integration/net/simple/peer/with_delete_test.go index b0b5fe3ded..01f03e2c75 100644 --- a/tests/integration/net/simple/peer/with_delete_test.go +++ b/tests/integration/net/simple/peer/with_delete_test.go @@ -175,7 +175,6 @@ func TestP2PWithMultipleDocumentsWithSingleUpdateBeforeConnectSingleDeleteWithSh Doc: `{ "Age": 60 }`, - DontSync: true, }, testUtils.ConnectPeers{ SourceNodeID: 0, @@ -247,7 +246,6 @@ func TestP2PWithMultipleDocumentsWithMultipleUpdatesBeforeConnectSingleDeleteWit Doc: `{ "Age": 60 }`, - DontSync: true, }, testUtils.UpdateDoc{ // Update John's Age on the first node only @@ -256,7 +254,6 @@ func TestP2PWithMultipleDocumentsWithMultipleUpdatesBeforeConnectSingleDeleteWit Doc: `{ "Age": 62 }`, - DontSync: true, }, testUtils.ConnectPeers{ SourceNodeID: 0, @@ -328,7 +325,6 @@ func TestP2PWithMultipleDocumentsWithUpdateAndDeleteBeforeConnectSingleDeleteWit Doc: `{ "Age": 60 }`, - DontSync: true, }, testUtils.UpdateDoc{ // Update John's Age on the first node only @@ -337,12 +333,10 @@ func TestP2PWithMultipleDocumentsWithUpdateAndDeleteBeforeConnectSingleDeleteWit Doc: `{ "Age": 62 }`, - DontSync: true, }, testUtils.DeleteDoc{ - NodeID: immutable.Some(0), - DocID: 0, - DontSync: true, + NodeID: immutable.Some(0), + DocID: 0, }, testUtils.ConnectPeers{ SourceNodeID: 0, diff --git a/tests/integration/net/simple/replicator/with_create_test.go b/tests/integration/net/simple/replicator/with_create_test.go index 5785337b98..08ef2baeec 100644 --- a/tests/integration/net/simple/replicator/with_create_test.go +++ b/tests/integration/net/simple/replicator/with_create_test.go @@ -12,7 +12,6 @@ package replicator import ( "testing" - "time" "github.com/sourcenetwork/immutable" @@ -182,7 +181,6 @@ func TestP2POneToOneReplicatorDoesNotSyncFromDeletedReplicator(t *testing.T) { }, testUtils.WaitForSync{ // No documents should be synced - ExpectedTimeout: 100 * time.Millisecond, }, testUtils.Request{ // Assert that John has not been synced to the second (target) node diff --git a/tests/integration/p2p.go b/tests/integration/p2p.go index 4a57ac7a1a..b1b79982cf 100644 --- a/tests/integration/p2p.go +++ b/tests/integration/p2p.go @@ -14,7 +14,6 @@ import ( "time" "github.com/sourcenetwork/defradb/client" - "github.com/sourcenetwork/defradb/event" "github.com/sourcenetwork/defradb/net" "github.com/libp2p/go-libp2p/core/peer" @@ -135,10 +134,7 @@ type GetAllP2PCollections struct { // // For example you will likely wish to `WaitForSync` after creating a document in node 0 before querying // node 1 to see if it has been replicated. -type WaitForSync struct { - // ExpectedTimeout is the duration to wait when expecting a timeout to occur. - ExpectedTimeout time.Duration -} +type WaitForSync struct{} // connectPeers connects two existing, started, nodes as peers. It returns a channel // that will receive an empty struct upon sync completion of all expected peer-sync events. @@ -148,9 +144,6 @@ func connectPeers( s *state, cfg ConnectPeers, ) { - // If we have some database actions prior to connecting the peers, we want to ensure that they had time to - // complete before we connect. Otherwise we might wrongly catch them in our wait function. - time.Sleep(100 * time.Millisecond) sourceNode := s.nodes[cfg.SourceNodeID] targetNode := s.nodes[cfg.TargetNodeID] @@ -158,119 +151,13 @@ func connectPeers( log.InfoContext(s.ctx, "Bootstrapping with peers", corelog.Any("Addresses", addrs)) sourceNode.Bootstrap(addrs) + s.nodeP2P[cfg.SourceNodeID].connections[cfg.TargetNodeID] = struct{}{} + s.nodeP2P[cfg.TargetNodeID].connections[cfg.SourceNodeID] = struct{}{} + // Bootstrap triggers a bunch of async stuff for which we have no good way of waiting on. It must be // allowed to complete before documentation begins or it will not even try and sync it. So for now, we // sleep a little. time.Sleep(100 * time.Millisecond) - setupPeerWaitSync(s, 0, cfg) -} - -func setupPeerWaitSync( - s *state, - startIndex int, - cfg ConnectPeers, -) { - sourceToTargetEvents := []int{0} - targetToSourceEvents := []int{0} - - nodeCollections := map[int][]int{} - waitIndex := 0 - for i := startIndex; i < len(s.testCase.Actions); i++ { - switch action := s.testCase.Actions[i].(type) { - case SubscribeToCollection: - if action.ExpectedError != "" { - // If the subscription action is expected to error, then we should do nothing here. - continue - } - // This is order dependent, items should be added in the same action-loop that reads them - // as 'stuff' done before collection subscription should not be synced. - nodeCollections[action.NodeID] = append(nodeCollections[action.NodeID], action.CollectionIDs...) - - case UnsubscribeToCollection: - if action.ExpectedError != "" { - // If the unsubscribe action is expected to error, then we should do nothing here. - continue - } - - // This is order dependent, items should be added in the same action-loop that reads them - // as 'stuff' done before collection subscription should not be synced. - existingCollectionIndexes := nodeCollections[action.NodeID] - for _, collectionIndex := range action.CollectionIDs { - for i, existingCollectionIndex := range existingCollectionIndexes { - if collectionIndex == existingCollectionIndex { - // Remove the matching collection index from the set: - existingCollectionIndexes = append(existingCollectionIndexes[:i], existingCollectionIndexes[i+1:]...) - } - } - } - nodeCollections[action.NodeID] = existingCollectionIndexes - - case CreateDoc: - sourceCollectionSubscribed := collectionSubscribedTo(nodeCollections, cfg.SourceNodeID, action.CollectionID) - targetCollectionSubscribed := collectionSubscribedTo(nodeCollections, cfg.TargetNodeID, action.CollectionID) - - // Peers sync trigger sync events for documents that exist prior to configuration, even if they already - // exist at the destination, so we need to wait for documents created on all nodes, as well as those - // created on the target. - if (!action.NodeID.HasValue() || - action.NodeID.Value() == cfg.TargetNodeID) && - sourceCollectionSubscribed { - targetToSourceEvents[waitIndex] += 1 - } - - // Peers sync trigger sync events for documents that exist prior to configuration, even if they already - // exist at the destination, so we need to wait for documents created on all nodes, as well as those - // created on the source. - if (!action.NodeID.HasValue() || - action.NodeID.Value() == cfg.SourceNodeID) && - targetCollectionSubscribed { - sourceToTargetEvents[waitIndex] += 1 - } - - case DeleteDoc: - // Updates to existing docs should always sync (no-sub required) - if !action.DontSync && action.NodeID.HasValue() && action.NodeID.Value() == cfg.TargetNodeID { - targetToSourceEvents[waitIndex] += 1 - } - if !action.DontSync && action.NodeID.HasValue() && action.NodeID.Value() == cfg.SourceNodeID { - sourceToTargetEvents[waitIndex] += 1 - } - - case UpdateDoc: - // Updates to existing docs should always sync (no-sub required) - if !action.DontSync && action.NodeID.HasValue() && action.NodeID.Value() == cfg.TargetNodeID { - targetToSourceEvents[waitIndex] += 1 - } - if !action.DontSync && action.NodeID.HasValue() && action.NodeID.Value() == cfg.SourceNodeID { - sourceToTargetEvents[waitIndex] += 1 - } - - case WaitForSync: - waitIndex += 1 - targetToSourceEvents = append(targetToSourceEvents, 0) - sourceToTargetEvents = append(sourceToTargetEvents, 0) - } - } - - nodeSynced := make(chan struct{}) - go waitForMerge(s, cfg.SourceNodeID, cfg.TargetNodeID, sourceToTargetEvents, targetToSourceEvents, nodeSynced) - s.syncChans = append(s.syncChans, nodeSynced) -} - -// collectionSubscribedTo returns true if the collection on the given node -// has been subscribed to. -func collectionSubscribedTo( - nodeCollections map[int][]int, - nodeID int, - collectionID int, -) bool { - targetSubscriptionCollections := nodeCollections[nodeID] - for _, collectionId := range targetSubscriptionCollections { - if collectionId == collectionID { - return true - } - } - return false } // configureReplicator configures a replicator relationship between two existing, started, nodes. @@ -282,26 +169,18 @@ func configureReplicator( s *state, cfg ConfigureReplicator, ) { - // If we have some database actions prior to configuring the replicator, we want to ensure that they had time to - // complete before the configuration. Otherwise we might wrongly catch them in our wait function. - time.Sleep(100 * time.Millisecond) sourceNode := s.nodes[cfg.SourceNodeID] targetNode := s.nodes[cfg.TargetNodeID] - sub, err := sourceNode.Events().Subscribe(event.ReplicatorCompletedName) - require.NoError(s.t, err) - err = sourceNode.SetReplicator(s.ctx, client.Replicator{ + err := sourceNode.SetReplicator(s.ctx, client.Replicator{ Info: targetNode.PeerInfo(), }) - if err == nil { - // wait for the replicator setup to complete - <-sub.Message() - } expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, cfg.ExpectedError) assertExpectedErrorRaised(s.t, s.testCase.Description, cfg.ExpectedError, expectedErrorRaised) + if err == nil { - setupReplicatorWaitSync(s, 0, cfg) + waitForReplicatorConfigureEvent(s, cfg) } } @@ -312,74 +191,11 @@ func deleteReplicator( sourceNode := s.nodes[cfg.SourceNodeID] targetNode := s.nodes[cfg.TargetNodeID] - sub, err := sourceNode.Events().Subscribe(event.ReplicatorCompletedName) - require.NoError(s.t, err) - err = sourceNode.DeleteReplicator(s.ctx, client.Replicator{ + err := sourceNode.DeleteReplicator(s.ctx, client.Replicator{ Info: targetNode.PeerInfo(), }) - if err == nil { - // wait for the replicator setup to complete - <-sub.Message() - } require.NoError(s.t, err) -} - -func setupReplicatorWaitSync( - s *state, - startIndex int, - cfg ConfigureReplicator, -) { - sourceToTargetEvents := []int{0} - targetToSourceEvents := []int{0} - - docIDsSyncedToSource := map[int]struct{}{} - waitIndex := 0 - currentDocID := 0 - for i := startIndex; i < len(s.testCase.Actions); i++ { - switch action := s.testCase.Actions[i].(type) { - case CreateDoc: - if !action.NodeID.HasValue() || action.NodeID.Value() == cfg.SourceNodeID { - docIDsSyncedToSource[currentDocID] = struct{}{} - } - - // A document created on the source or one that is created on all nodes will be sent to the target even - // it already has it. It will create a `received push log` event on the target which we need to wait for. - if !action.NodeID.HasValue() || action.NodeID.Value() == cfg.SourceNodeID { - sourceToTargetEvents[waitIndex] += 1 - } - - currentDocID++ - - case DeleteDoc: - if _, shouldSyncFromTarget := docIDsSyncedToSource[action.DocID]; shouldSyncFromTarget && - action.NodeID.HasValue() && action.NodeID.Value() == cfg.TargetNodeID { - targetToSourceEvents[waitIndex] += 1 - } - - if action.NodeID.HasValue() && action.NodeID.Value() == cfg.SourceNodeID { - sourceToTargetEvents[waitIndex] += 1 - } - - case UpdateDoc: - if _, shouldSyncFromTarget := docIDsSyncedToSource[action.DocID]; shouldSyncFromTarget && - action.NodeID.HasValue() && action.NodeID.Value() == cfg.TargetNodeID { - targetToSourceEvents[waitIndex] += 1 - } - - if action.NodeID.HasValue() && action.NodeID.Value() == cfg.SourceNodeID { - sourceToTargetEvents[waitIndex] += 1 - } - - case WaitForSync: - waitIndex += 1 - targetToSourceEvents = append(targetToSourceEvents, 0) - sourceToTargetEvents = append(sourceToTargetEvents, 0) - } - } - - nodeSynced := make(chan struct{}) - go waitForMerge(s, cfg.SourceNodeID, cfg.TargetNodeID, sourceToTargetEvents, targetToSourceEvents, nodeSynced) - s.syncChans = append(s.syncChans, nodeSynced) + waitForReplicatorDeleteEvent(s, cfg) } // subscribeToCollection sets up a collection subscription on the given node/collection. @@ -402,13 +218,9 @@ func subscribeToCollection( schemaRoots = append(schemaRoots, col.SchemaRoot()) } - sub, err := n.Events().Subscribe(event.P2PTopicCompletedName) - require.NoError(s.t, err) - - err = n.AddP2PCollections(s.ctx, schemaRoots) + err := n.AddP2PCollections(s.ctx, schemaRoots) if err == nil { - // wait for the p2p collection setup to complete - <-sub.Message() + waitForSubscribeToCollectionEvent(s, action) } expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) @@ -440,13 +252,9 @@ func unsubscribeToCollection( schemaRoots = append(schemaRoots, col.SchemaRoot()) } - sub, err := n.Events().Subscribe(event.P2PTopicCompletedName) - require.NoError(s.t, err) - - err = n.RemoveP2PCollections(s.ctx, schemaRoots) + err := n.RemoveP2PCollections(s.ctx, schemaRoots) if err == nil { - // wait for the p2p collection setup to complete - <-sub.Message() + waitForUnsubscribeToCollectionEvent(s, action) } expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) @@ -479,83 +287,6 @@ func getAllP2PCollections( assert.Equal(s.t, expectedCollections, cols) } -// waitForSync waits for all given wait channels to receive an item signaling completion. -// -// Will fail the test if an event is not received within the expected time interval to prevent tests -// from running forever. -func waitForSync( - s *state, - action WaitForSync, -) { - var timeout time.Duration - if action.ExpectedTimeout != 0 { - timeout = action.ExpectedTimeout - } else { - timeout = subscriptionTimeout * 10 - } - - for _, resultsChan := range s.syncChans { - select { - case <-resultsChan: - assert.True( - s.t, - action.ExpectedTimeout == 0, - "unexpected document has been synced", - s.testCase.Description, - ) - - // a safety in case the stream hangs - we don't want the tests to run forever. - case <-time.After(timeout): - assert.True( - s.t, - action.ExpectedTimeout != 0, - "timeout occurred while waiting for data stream", - s.testCase.Description, - ) - } - } -} - -// waitForMerge waits for the source and target nodes to synchronize their state -// by listening to merge events sent from the network subsystem on the event bus. -// -// sourceToTargetEvents and targetToSourceEvents are slices containing the number -// of expected merge events to be received after each test action has executed. -func waitForMerge( - s *state, - sourceNodeID int, - targetNodeID int, - sourceToTargetEvents []int, - targetToSourceEvents []int, - nodeSynced chan struct{}, -) { - sourceSub := s.eventSubs[sourceNodeID] - targetSub := s.eventSubs[targetNodeID] - - sourcePeerInfo := s.nodeAddresses[sourceNodeID] - targetPeerInfo := s.nodeAddresses[targetNodeID] - - for waitIndex := 0; waitIndex < len(sourceToTargetEvents); waitIndex++ { - for i := 0; i < targetToSourceEvents[waitIndex]; i++ { - // wait for message or unsubscribe - msg, ok := <-sourceSub.Message() - if ok { - // ensure the message is sent from the target node - require.Equal(s.t, targetPeerInfo.ID, msg.Data.(event.Merge).ByPeer) - } - } - for i := 0; i < sourceToTargetEvents[waitIndex]; i++ { - // wait for message or unsubscribe - msg, ok := <-targetSub.Message() - if ok { - // ensure the message is sent from the source node - require.Equal(s.t, sourcePeerInfo.ID, msg.Data.(event.Merge).ByPeer) - } - } - nodeSynced <- struct{}{} - } -} - func RandomNetworkingConfig() ConfigureNode { return func() []net.NodeOpt { return []net.NodeOpt{ diff --git a/tests/integration/state.go b/tests/integration/state.go index fd9bd6b12c..613462d40f 100644 --- a/tests/integration/state.go +++ b/tests/integration/state.go @@ -14,6 +14,7 @@ import ( "context" "testing" + "github.com/ipfs/go-cid" "github.com/libp2p/go-libp2p/core/peer" identity "github.com/sourcenetwork/defradb/acp/identity" @@ -24,6 +25,86 @@ import ( "github.com/sourcenetwork/defradb/tests/clients" ) +// p2pState contains all p2p related testing state. +type p2pState struct { + // connections contains all connected nodes. + // + // The map key is the connected node id. + connections map[int]struct{} + + // replicators is a mapping of replicator targets. + // + // The map key is the source node id. + replicators map[int]struct{} + + // peerCollections contains all active peer collection subscriptions. + // + // The map key is the node id of the subscriber. + peerCollections map[int]struct{} + + // actualDocHeads contains all document heads that exist on a node. + // + // The map key is the doc id. The map value is the doc head. + actualDocHeads map[string]cid.Cid + + // expectedDocHeads contains all document heads that are expected to exist on a node. + // + // The map key is the doc id. The map value is the doc head. + expectedDocHeads map[string]cid.Cid +} + +// newP2PState returns a new empty p2p state. +func newP2PState() *p2pState { + return &p2pState{ + connections: make(map[int]struct{}), + replicators: make(map[int]struct{}), + peerCollections: make(map[int]struct{}), + actualDocHeads: make(map[string]cid.Cid), + expectedDocHeads: make(map[string]cid.Cid), + } +} + +// eventState contains all event related testing state for a node. +type eventState struct { + // merge is the `event.MergeCompleteName` subscription + merge *event.Subscription + + // update is the `event.UpdateName` subscription + update *event.Subscription + + // replicator is the `event.ReplicatorCompletedName` subscription + replicator *event.Subscription + + // p2pTopic is the `event.P2PTopicCompletedName` subscription + p2pTopic *event.Subscription +} + +// newEventState returns an eventState with all required subscriptions. +func newEventState(bus *event.Bus) (*eventState, error) { + merge, err := bus.Subscribe(event.MergeCompleteName) + if err != nil { + return nil, err + } + update, err := bus.Subscribe(event.UpdateName) + if err != nil { + return nil, err + } + replicator, err := bus.Subscribe(event.ReplicatorCompletedName) + if err != nil { + return nil, err + } + p2pTopic, err := bus.Subscribe(event.P2PTopicCompletedName) + if err != nil { + return nil, err + } + return &eventState{ + merge: merge, + update: update, + replicator: replicator, + p2pTopic: p2pTopic, + }, nil +} + type state struct { // The test context. ctx context.Context @@ -54,11 +135,8 @@ type state struct { // These channels will recieve a function which asserts results of any subscription requests. subscriptionResultsChans []chan func() - // These synchronisation channels allow async actions to track their completion. - syncChans []chan struct{} - - // eventSubs is a list of all event subscriptions - eventSubs []*event.Subscription + // nodeEvents contains all event node subscriptions. + nodeEvents []*eventState // The addresses of any nodes configured. nodeAddresses []peer.AddrInfo @@ -69,6 +147,9 @@ type state struct { // The nodes active in this test. nodes []clients.Client + // nodeP2P contains p2p states for all nodes + nodeP2P []*p2pState + // The paths to any file-based databases active in this test. dbPaths []string @@ -114,10 +195,10 @@ func newState( txns: []datastore.Txn{}, allActionsDone: make(chan struct{}), subscriptionResultsChans: []chan func(){}, - syncChans: []chan struct{}{}, - eventSubs: []*event.Subscription{}, + nodeEvents: []*eventState{}, nodeAddresses: []peer.AddrInfo{}, nodeConfigs: [][]net.NodeOpt{}, + nodeP2P: []*p2pState{}, nodes: []clients.Client{}, dbPaths: []string{}, collections: [][]client.Collection{}, diff --git a/tests/integration/test_case.go b/tests/integration/test_case.go index 0013ceab0c..1ebf396253 100644 --- a/tests/integration/test_case.go +++ b/tests/integration/test_case.go @@ -318,9 +318,6 @@ type DeleteDoc struct { // String can be a partial, and the test will pass if an error is returned that // contains this string. ExpectedError string - - // Setting DontSync to true will prevent waiting for that delete. - DontSync bool } // UpdateDoc will attempt to update the given document using the set [MutationType]. @@ -356,8 +353,11 @@ type UpdateDoc struct { // contains this string. ExpectedError string - // Setting DontSync to true will prevent waiting for that update. - DontSync bool + // Skip waiting for an update event on the local event bus. + // + // This should only be used for tests that do not correctly + // publish an update event to the local event bus. + SkipLocalUpdateEvent bool } // IndexField describes a field to be indexed. diff --git a/tests/integration/utils2.go b/tests/integration/utils2.go index ad6ef2a85d..67ed5dd3d1 100644 --- a/tests/integration/utils2.go +++ b/tests/integration/utils2.go @@ -33,7 +33,6 @@ import ( "github.com/sourcenetwork/defradb/crypto" "github.com/sourcenetwork/defradb/datastore" "github.com/sourcenetwork/defradb/errors" - "github.com/sourcenetwork/defradb/event" "github.com/sourcenetwork/defradb/internal/db" "github.com/sourcenetwork/defradb/internal/encryption" "github.com/sourcenetwork/defradb/internal/request/graphql" @@ -253,7 +252,7 @@ func performAction( configureNode(s, action) case Restart: - restartNodes(s, actionIndex) + restartNodes(s) case ConnectPeers: connectPeers(s, action) @@ -343,7 +342,7 @@ func performAction( assertClientIntrospectionResults(s, action) case WaitForSync: - waitForSync(s, action) + waitForMergeEvents(s) case Benchmark: benchmarkAction(s, actionIndex, action) @@ -658,14 +657,18 @@ func setStartingNodes( c, err := setupClient(s, node) require.Nil(s.t, err) + eventState, err := newEventState(c.Events()) + require.NoError(s.t, err) + s.nodes = append(s.nodes, c) + s.nodeEvents = append(s.nodeEvents, eventState) + s.nodeP2P = append(s.nodeP2P, newP2PState()) s.dbPaths = append(s.dbPaths, path) } } func restartNodes( s *state, - actionIndex int, ) { if s.dbt == badgerIMType || s.dbt == defraIMType { return @@ -686,24 +689,12 @@ func restartNodes( c, err := setupClient(s, node) require.NoError(s.t, err) s.nodes[i] = c - continue - } - // We need to ensure that on restart, the node pubsub is configured before - // we continue with the test. Otherwise, we may miss update events. - readySub, err := node.DB.Events().Subscribe(event.P2PTopicCompletedName, event.ReplicatorCompletedName) - require.NoError(s.t, err) - waitLen := 0 - cols, err := node.DB.GetAllP2PCollections(s.ctx) - require.NoError(s.t, err) - if len(cols) > 0 { - // there is only one message for loading of P2P collections - waitLen++ + eventState, err := newEventState(c.Events()) + require.NoError(s.t, err) + s.nodeEvents[i] = eventState + continue } - reps, err := node.DB.GetAllReplicators(s.ctx) - require.NoError(s.t, err) - // there is one message per replicator - waitLen += len(reps) // We need to make sure the node is configured with its old address, otherwise // a new one may be selected and reconnnection to it will fail. @@ -728,45 +719,11 @@ func restartNodes( require.NoError(s.t, err) s.nodes[i] = c - // subscribe to merge complete events - sub, err := c.Events().Subscribe(event.MergeCompleteName) + eventState, err := newEventState(c.Events()) require.NoError(s.t, err) - s.eventSubs[i] = sub - for waitLen > 0 { - select { - case <-readySub.Message(): - waitLen-- - case <-time.After(10 * time.Second): - s.t.Fatalf("timeout waiting for node to be ready") - } - } - } - - // The index of the action after the last wait action before the current restart action. - // We wish to resume the wait clock from this point onwards. - waitGroupStartIndex := 0 -actionLoop: - for i := actionIndex; i >= 0; i-- { - switch s.testCase.Actions[i].(type) { - case WaitForSync: - // +1 as we do not wish to resume from the wait itself, but the next action - // following it. This may be the current restart action. - waitGroupStartIndex = i + 1 - break actionLoop - } - } + s.nodeEvents[i] = eventState - for _, tc := range s.testCase.Actions { - switch action := tc.(type) { - case ConnectPeers: - // Give the nodes a chance to connect to each other and learn about each other's subscribed topics. - time.Sleep(100 * time.Millisecond) - setupPeerWaitSync(s, waitGroupStartIndex, action) - case ConfigureReplicator: - // Give the nodes a chance to connect to each other and learn about each other's subscribed topics. - time.Sleep(100 * time.Millisecond) - setupReplicatorWaitSync(s, waitGroupStartIndex, action) - } + waitForNetworkSetupEvents(s, i) } // If the db was restarted we need to refresh the collection definitions as the old instances @@ -840,13 +797,13 @@ func configureNode( c, err := setupClient(s, node) require.NoError(s.t, err) + eventState, err := newEventState(c.Events()) + require.NoError(s.t, err) + s.nodes = append(s.nodes, c) + s.nodeEvents = append(s.nodeEvents, eventState) + s.nodeP2P = append(s.nodeP2P, newP2PState()) s.dbPaths = append(s.dbPaths, path) - - // subscribe to merge complete events - sub, err := c.Events().Subscribe(event.MergeCompleteName) - require.NoError(s.t, err) - s.eventSubs = append(s.eventSubs, sub) } func refreshDocuments( @@ -1224,6 +1181,12 @@ func createDoc( s.documents = append(s.documents, make([][]*client.Document, action.CollectionID-len(s.documents)+1)...) } s.documents[action.CollectionID] = append(s.documents[action.CollectionID], docs...) + + if action.ExpectedError == "" { + for i := 0; i < len(docs); i++ { + waitForUpdateEvents(s, action.NodeID, action.CollectionID) + } + } } func createDocViaColSave( @@ -1430,6 +1393,10 @@ func deleteDoc( } assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) + + if action.ExpectedError == "" { + waitForUpdateEvents(s, action.NodeID, action.CollectionID) + } } // updateDoc updates a document using the chosen [mutationType]. @@ -1462,6 +1429,10 @@ func updateDoc( } assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) + + if action.ExpectedError == "" && !action.SkipLocalUpdateEvent { + waitForUpdateEvents(s, action.NodeID, action.CollectionID) + } } func updateDocViaColSave( From 25a30634559aef23e9210c4de787621be7aeca4b Mon Sep 17 00:00:00 2001 From: AndrewSisley Date: Fri, 19 Jul 2024 12:11:35 -0400 Subject: [PATCH 17/41] feat: Handle P2P with SourceHub ACP (#2848) ## Relevant issue(s) Resolves #2366 ## Description Handles P2P with SourceHub ACP. Local ACP remains blocked off, as documents synced would essentially become public unless encrypted. --- acp/README.md | 5 +- acp/acp.go | 3 + acp/source_hub_client.go | 5 + internal/db/errors.go | 1 - internal/db/p2p_replicator.go | 19 +-- internal/db/p2p_schema_root.go | 15 +-- internal/db/p2p_schema_root_test.go | 65 --------- tests/integration/acp.go | 9 +- tests/integration/acp/p2p/replicator_test.go | 132 ++++++++++++++++--- tests/integration/acp/p2p/subscribe_test.go | 128 +++++++++++++++++- tests/integration/db.go | 9 +- tests/integration/state.go | 4 + 12 files changed, 277 insertions(+), 118 deletions(-) diff --git a/acp/README.md b/acp/README.md index 58adfc3997..54c479b5ea 100644 --- a/acp/README.md +++ b/acp/README.md @@ -458,9 +458,10 @@ If authentication fails for any reason a `403` forbidden response will be return ## _FAC Usage: (coming soon)_ ## Warning / Caveats +- If using Local ACP, P2P will only work with collections that do not have a policy assigned. If you wish to use ACP +on collections connected to a multi-node network, please use SourceHub ACP. + The following features currently don't work with ACP, they are being actively worked on. -- [P2P: Adding a replicator with permissioned collection](https://github.com/sourcenetwork/defradb/issues/2366) -- [P2P: Subscription to a permissioned collection](https://github.com/sourcenetwork/defradb/issues/2366) - [Adding Secondary Indexes](https://github.com/sourcenetwork/defradb/issues/2365) - [Backing/Restoring Private Documents](https://github.com/sourcenetwork/defradb/issues/2430) diff --git a/acp/acp.go b/acp/acp.go index 4635e46f4f..973181ae91 100644 --- a/acp/acp.go +++ b/acp/acp.go @@ -98,4 +98,7 @@ type ACP interface { resourceName string, docID string, ) (bool, error) + + // SupportsP2P returns true if the implementation supports ACP across a peer network. + SupportsP2P() bool } diff --git a/acp/source_hub_client.go b/acp/source_hub_client.go index 885722f667..0bf344afb8 100644 --- a/acp/source_hub_client.go +++ b/acp/source_hub_client.go @@ -335,6 +335,11 @@ func (a *sourceHubBridge) CheckDocAccess( } } +func (a *sourceHubBridge) SupportsP2P() bool { + _, ok := a.client.(*acpSourceHub) + return ok +} + func (a *sourceHubBridge) Close() error { return a.client.Close() } diff --git a/internal/db/errors.go b/internal/db/errors.go index 87828b78a8..e8a835f3f2 100644 --- a/internal/db/errors.go +++ b/internal/db/errors.go @@ -137,7 +137,6 @@ var ( ErrP2PColHasPolicy = errors.New("p2p collection specified has a policy on it") ErrNoTransactionInContext = errors.New(errNoTransactionInContext) ErrReplicatorColHasPolicy = errors.New("replicator collection specified has a policy on it") - ErrReplicatorSomeColsHavePolicy = errors.New("replicator can not use all collections, as some have policy") ErrSelfTargetForReplicator = errors.New("can't target ourselves as a replicator") ErrReplicatorCollections = errors.New(errReplicatorCollections) ErrReplicatorNotFound = errors.New(errReplicatorNotFound) diff --git a/internal/db/p2p_replicator.go b/internal/db/p2p_replicator.go index 9f2fd84215..409419ea3f 100644 --- a/internal/db/p2p_replicator.go +++ b/internal/db/p2p_replicator.go @@ -45,8 +45,6 @@ func (db *db) SetReplicator(ctx context.Context, rep client.Replicator) error { return ErrSelfTargetForReplicator } - // TODO-ACP: Support ACP <> P2P - https://github.com/sourcenetwork/defradb/issues/2366 - // ctx = db.SetContextIdentity(ctx, identity) ctx = SetContextTxn(ctx, txn) storedRep := client.Replicator{} @@ -82,29 +80,22 @@ func (db *db) SetReplicator(ctx context.Context, rep client.Replicator) error { return NewErrReplicatorCollections(err) } - if col.Description().Policy.HasValue() { - return ErrReplicatorColHasPolicy - } - collections = append(collections, col) } default: - // default to all collections (unless a collection contains a policy). - // TODO-ACP: default to all collections after resolving https://github.com/sourcenetwork/defradb/issues/2366 - allCollections, err := db.GetCollections(ctx, client.CollectionFetchOptions{}) + collections, err = db.GetCollections(ctx, client.CollectionFetchOptions{}) if err != nil { return NewErrReplicatorCollections(err) } + } - for _, col := range allCollections { - // Can not default to all collections if any collection has a policy. - // TODO-ACP: remove this check/loop after https://github.com/sourcenetwork/defradb/issues/2366 + if db.acp.HasValue() && !db.acp.Value().SupportsP2P() { + for _, col := range collections { if col.Description().Policy.HasValue() { - return ErrReplicatorSomeColsHavePolicy + return ErrReplicatorColHasPolicy } } - collections = allCollections } addedCols := []client.Collection{} diff --git a/internal/db/p2p_schema_root.go b/internal/db/p2p_schema_root.go index b16af0ff4e..6f85ea682b 100644 --- a/internal/db/p2p_schema_root.go +++ b/internal/db/p2p_schema_root.go @@ -31,8 +31,6 @@ func (db *db) AddP2PCollections(ctx context.Context, collectionIDs []string) err } defer txn.Discard(ctx) - // TODO-ACP: Support ACP <> P2P - https://github.com/sourcenetwork/defradb/issues/2366 - // ctx = db.SetContextIdentity(ctx, identity) ctx = SetContextTxn(ctx, txn) // first let's make sure the collections actually exists @@ -53,11 +51,11 @@ func (db *db) AddP2PCollections(ctx context.Context, collectionIDs []string) err storeCollections = append(storeCollections, storeCol...) } - // Ensure none of the collections have a policy on them, until following is implemented: - // TODO-ACP: ACP <> P2P https://github.com/sourcenetwork/defradb/issues/2366 - for _, col := range storeCollections { - if col.Description().Policy.HasValue() { - return ErrP2PColHasPolicy + if db.acp.HasValue() && !db.acp.Value().SupportsP2P() { + for _, col := range storeCollections { + if col.Description().Policy.HasValue() { + return ErrP2PColHasPolicy + } } } @@ -98,8 +96,6 @@ func (db *db) RemoveP2PCollections(ctx context.Context, collectionIDs []string) } defer txn.Discard(ctx) - // TODO-ACP: Support ACP <> P2P - https://github.com/sourcenetwork/defradb/issues/2366 - // ctx = db.SetContextIdentity(ctx, identity) ctx = SetContextTxn(ctx, txn) // first let's make sure the collections actually exists @@ -211,7 +207,6 @@ func (db *db) loadAndPublishP2PCollections(ctx context.Context) error { if _, ok := colMap[col.SchemaRoot()]; ok { continue } - // TODO-ACP: Support ACP <> P2P - https://github.com/sourcenetwork/defradb/issues/2366 docIDChan, err := col.GetAllDocIDs(ctx) if err != nil { return err diff --git a/internal/db/p2p_schema_root_test.go b/internal/db/p2p_schema_root_test.go index 16d95394f6..b41905267b 100644 --- a/internal/db/p2p_schema_root_test.go +++ b/internal/db/p2p_schema_root_test.go @@ -12,19 +12,11 @@ package db import ( "context" - "encoding/hex" - "fmt" "testing" - "time" - "github.com/decred/dcrd/dcrec/secp256k1/v4" - "github.com/sourcenetwork/immutable" "github.com/stretchr/testify/require" - "github.com/sourcenetwork/defradb/acp" - acpIdentity "github.com/sourcenetwork/defradb/acp/identity" "github.com/sourcenetwork/defradb/client" - "github.com/sourcenetwork/defradb/datastore/memory" "github.com/sourcenetwork/defradb/event" ) @@ -248,60 +240,3 @@ func TestGetAllP2PCollections_WithMultipleValidCollections_ShouldSucceed(t *test require.NoError(t, err) require.Equal(t, []string{schema2.Root, schema1.Root}, cols) } - -// This test documents that we don't allow adding p2p collections that have a policy -// until the following is implemented: -// TODO-ACP: ACP <> P2P https://github.com/sourcenetwork/defradb/issues/2366 -func TestAddP2PCollectionsWithPermissionedCollection_Error(t *testing.T) { - ctx := context.Background() - rootstore := memory.NewDatastore(ctx) - db, err := newDB(ctx, rootstore, immutable.Some[acp.ACP](acp.NewLocalACP()), nil) - require.NoError(t, err) - - policy := ` - name: test - description: a policy - actor: - name: actor - resources: - user: - permissions: - read: - expr: owner - write: - expr: owner - relations: - owner: - types: - - actor - ` - - privKeyBytes, err := hex.DecodeString("028d53f37a19afb9a0dbc5b4be30c65731479ee8cfa0c9bc8f8bf198cc3c075f") - require.NoError(t, err) - privKey := secp256k1.PrivKeyFromBytes(privKeyBytes) - identity, err := acpIdentity.FromPrivateKey(privKey, time.Hour, immutable.None[string](), immutable.None[string](), false) - require.NoError(t, err) - - ctx = SetContextIdentity(ctx, immutable.Some(identity)) - policyResult, err := db.AddPolicy(ctx, policy) - policyID := policyResult.PolicyID - require.NoError(t, err) - require.Equal(t, "7b5ed30570e8d9206027ef6d5469879a6c1ea4595625c6ca33a19063a6ed6214", policyID) - - schema := fmt.Sprintf(` - type User @policy(id: "%s", resource: "user") { - name: String - age: Int - } - `, policyID, - ) - _, err = db.AddSchema(ctx, schema) - require.NoError(t, err) - - col, err := db.GetCollectionByName(ctx, "User") - require.NoError(t, err) - - err = db.AddP2PCollections(ctx, []string{col.SchemaRoot()}) - require.Error(t, err) - require.ErrorIs(t, err, ErrP2PColHasPolicy) -} diff --git a/tests/integration/acp.go b/tests/integration/acp.go index 9a31856f5f..831e7f6cac 100644 --- a/tests/integration/acp.go +++ b/tests/integration/acp.go @@ -69,7 +69,8 @@ func init() { type AddPolicy struct { // NodeID may hold the ID (index) of the node we want to add policy to. // - // If a value is not provided the policy will be added in all nodes. + // If a value is not provided the policy will be added in all nodes, unless testing with + // sourcehub ACP, in which case the policy will only be defined once. NodeID immutable.Option[int] // The raw policy string. @@ -110,6 +111,12 @@ func addPolicyACP( expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) + + // The policy should only be added to a SourceHub chain once - there is no need to loop through + // the nodes. + if acpType == SourceHubACPType { + break + } } } diff --git a/tests/integration/acp/p2p/replicator_test.go b/tests/integration/acp/p2p/replicator_test.go index 49d5b65f23..169e682658 100644 --- a/tests/integration/acp/p2p/replicator_test.go +++ b/tests/integration/acp/p2p/replicator_test.go @@ -18,23 +18,18 @@ import ( testUtils "github.com/sourcenetwork/defradb/tests/integration" ) -// This test documents that we don't allow setting replicator with a collections that has a policy -// until the following is implemented: -// TODO-ACP: ACP <> P2P https://github.com/sourcenetwork/defradb/issues/2366 -func TestACP_P2POneToOneReplicatorWithPermissionedCollection_Error(t *testing.T) { +func TestACP_P2POneToOneReplicatorWithPermissionedCollection_LocalACP(t *testing.T) { test := testUtils.TestCase{ - - Description: "Test acp, with p2p replicator with permissioned collection, error", - + SupportedACPTypes: immutable.Some( + []testUtils.ACPType{ + testUtils.LocalACPType, + }, + ), Actions: []any{ - testUtils.RandomNetworkingConfig(), testUtils.RandomNetworkingConfig(), - testUtils.AddPolicy{ - Identity: immutable.Some(1), - Policy: ` name: test description: a test policy which marks a collection in a database as a resource @@ -63,10 +58,8 @@ func TestACP_P2POneToOneReplicatorWithPermissionedCollection_Error(t *testing.T) types: - actor `, - ExpectedPolicyID: "94eb195c0e459aa79e02a1986c7e731c5015721c18a373f2b2a0ed140a04b454", }, - testUtils.SchemaUpdate{ Schema: ` type Users @policy( @@ -78,11 +71,120 @@ func TestACP_P2POneToOneReplicatorWithPermissionedCollection_Error(t *testing.T) } `, }, - testUtils.ConfigureReplicator{ SourceNodeID: 0, TargetNodeID: 1, - ExpectedError: "replicator can not use all collections, as some have policy", + ExpectedError: "replicator collection specified has a policy on it", + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_P2POneToOneReplicatorWithPermissionedCollection_SourceHubACP(t *testing.T) { + test := testUtils.TestCase{ + SupportedACPTypes: immutable.Some( + []testUtils.ACPType{ + testUtils.SourceHubACPType, + }, + ), + Actions: []any{ + testUtils.RandomNetworkingConfig(), + testUtils.RandomNetworkingConfig(), + testUtils.AddPolicy{ + Identity: immutable.Some(1), + Policy: ` + name: test + description: a test policy which marks a collection in a database as a resource + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + admin: + manages: + - reader + types: + - actor + `, + ExpectedPolicyID: "94eb195c0e459aa79e02a1986c7e731c5015721c18a373f2b2a0ed140a04b454", + }, + testUtils.SchemaUpdate{ + Schema: ` + type Users @policy( + id: "94eb195c0e459aa79e02a1986c7e731c5015721c18a373f2b2a0ed140a04b454", + resource: "users" + ) { + name: String + age: Int + } + `, + }, + testUtils.ConfigureReplicator{ + SourceNodeID: 0, + TargetNodeID: 1, + }, + testUtils.CreateDoc{ + NodeID: immutable.Some(0), + Identity: immutable.Some(1), + DocMap: map[string]any{ + "name": "John", + }, + }, + testUtils.WaitForSync{}, + testUtils.Request{ + // Ensure that the document is accessible on all nodes to authorized actors + Identity: immutable.Some(1), + Request: ` + query { + Users { + name + } + } + `, + Results: []map[string]any{ + { + "name": "John", + }, + }, + }, + testUtils.Request{ + // Ensure that the document is hidden on all nodes to unidentified actors + Request: ` + query { + Users { + name + } + } + `, + Results: []map[string]any{}, + }, + testUtils.Request{ + // Ensure that the document is hidden on all nodes to unauthorized actors + Identity: immutable.Some(2), + Request: ` + query { + Users { + name + } + } + `, + Results: []map[string]any{}, }, }, } diff --git a/tests/integration/acp/p2p/subscribe_test.go b/tests/integration/acp/p2p/subscribe_test.go index 6ad5b84d14..4e8cf4cc2e 100644 --- a/tests/integration/acp/p2p/subscribe_test.go +++ b/tests/integration/acp/p2p/subscribe_test.go @@ -18,14 +18,13 @@ import ( testUtils "github.com/sourcenetwork/defradb/tests/integration" ) -// This test documents that we don't allow subscribing to a collection that has a policy -// until the following is implemented: -// TODO-ACP: ACP <> P2P https://github.com/sourcenetwork/defradb/issues/2366 -func TestACP_P2PSubscribeAddGetSingleWithPermissionedCollection_Error(t *testing.T) { +func TestACP_P2PSubscribeAddGetSingleWithPermissionedCollection_LocalACP(t *testing.T) { test := testUtils.TestCase{ - - Description: "Test acp, with p2p subscribe with permissioned collection, error", - + SupportedACPTypes: immutable.Some( + []testUtils.ACPType{ + testUtils.LocalACPType, + }, + ), Actions: []any{ testUtils.RandomNetworkingConfig(), @@ -99,3 +98,118 @@ func TestACP_P2PSubscribeAddGetSingleWithPermissionedCollection_Error(t *testing testUtils.ExecuteTestCase(t, test) } + +func TestACP_P2PSubscribeAddGetSingleWithPermissionedCollection_SourceHubACP(t *testing.T) { + test := testUtils.TestCase{ + SupportedACPTypes: immutable.Some( + []testUtils.ACPType{ + testUtils.SourceHubACPType, + }, + ), + Actions: []any{ + testUtils.RandomNetworkingConfig(), + testUtils.RandomNetworkingConfig(), + testUtils.AddPolicy{ + Identity: immutable.Some(1), + Policy: ` + name: test + description: a test policy which marks a collection in a database as a resource + + actor: + name: actor + + resources: + users: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + admin: + manages: + - reader + types: + - actor + `, + + ExpectedPolicyID: "94eb195c0e459aa79e02a1986c7e731c5015721c18a373f2b2a0ed140a04b454", + }, + testUtils.SchemaUpdate{ + Schema: ` + type Users @policy( + id: "94eb195c0e459aa79e02a1986c7e731c5015721c18a373f2b2a0ed140a04b454", + resource: "users" + ) { + name: String + age: Int + } + `, + }, + testUtils.ConnectPeers{ + SourceNodeID: 1, + TargetNodeID: 0, + }, + testUtils.SubscribeToCollection{ + NodeID: 1, + CollectionIDs: []int{0}, + }, + testUtils.CreateDoc{ + NodeID: immutable.Some(0), + Identity: immutable.Some(1), + DocMap: map[string]any{ + "name": "John", + }, + }, + testUtils.WaitForSync{}, + testUtils.Request{ + // Ensure that the document is accessible on all nodes to authorized actors + Identity: immutable.Some(1), + Request: ` + query { + Users { + name + } + } + `, + Results: []map[string]any{ + { + "name": "John", + }, + }, + }, + testUtils.Request{ + // Ensure that the document is hidden on all nodes to unidentified actors + Request: ` + query { + Users { + name + } + } + `, + Results: []map[string]any{}, + }, + testUtils.Request{ + // Ensure that the document is hidden on all nodes to unauthorized actors + Identity: immutable.Some(2), + Request: ` + query { + Users { + name + } + } + `, + Results: []map[string]any{}, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/db.go b/tests/integration/db.go index 2a7ab2893d..54175784c0 100644 --- a/tests/integration/db.go +++ b/tests/integration/db.go @@ -131,11 +131,14 @@ func setupNode(s *state) (*node.Node, string, error) { opts = append(opts, node.WithACPType(node.LocalACPType)) case SourceHubACPType: - acpOpts, err := setupSourceHub(s) - require.NoError(s.t, err) + if len(s.acpOptions) == 0 { + var err error + s.acpOptions, err = setupSourceHub(s) + require.NoError(s.t, err) + } opts = append(opts, node.WithACPType(node.SourceHubACPType)) - for _, opt := range acpOpts { + for _, opt := range s.acpOptions { opts = append(opts, opt) } diff --git a/tests/integration/state.go b/tests/integration/state.go index 613462d40f..140857aa80 100644 --- a/tests/integration/state.go +++ b/tests/integration/state.go @@ -22,6 +22,7 @@ import ( "github.com/sourcenetwork/defradb/datastore" "github.com/sourcenetwork/defradb/event" "github.com/sourcenetwork/defradb/net" + "github.com/sourcenetwork/defradb/node" "github.com/sourcenetwork/defradb/tests/clients" ) @@ -175,6 +176,9 @@ type state struct { // The SourceHub address used to pay for SourceHub transactions. sourcehubAddress string + + // The ACP options to share between each node. + acpOptions []node.ACPOpt } // newState returns a new fresh state for the given testCase. From dc76eba6663d9d247bce48a4c67c8c511cf0a973 Mon Sep 17 00:00:00 2001 From: AndrewSisley Date: Tue, 23 Jul 2024 14:49:30 -0400 Subject: [PATCH 18/41] feat: Remove IsObjectArray (#2859) ## Relevant issue(s) Resolves #2356 ## Description Removes IsObjectArray. --- client/document.go | 10 +++++----- client/schema_field_description.go | 19 ------------------- internal/db/collection.go | 2 +- internal/db/definition_validation.go | 2 +- internal/planner/mapper/mapper.go | 7 ++++--- internal/planner/type_join.go | 12 +++++++----- internal/request/graphql/schema/collection.go | 7 +++---- internal/request/graphql/schema/generate.go | 19 +++++++++---------- 8 files changed, 30 insertions(+), 48 deletions(-) diff --git a/client/document.go b/client/document.go index f8d427c349..05cefd02e4 100644 --- a/client/document.go +++ b/client/document.go @@ -186,11 +186,11 @@ func validateFieldSchema(val any, field FieldDefinition) (NormalValue, error) { } } - if field.Kind.IsObjectArray() { - return nil, NewErrFieldNotExist(field.Name) - } - if field.Kind.IsObject() { + if field.Kind.IsArray() { + return nil, NewErrFieldNotExist(field.Name) + } + v, err := getString(val) if err != nil { return nil, err @@ -592,7 +592,7 @@ func (doc *Document) Set(field string, value any) error { if !exists { return NewErrFieldNotExist(field) } - if fd.Kind.IsObject() && !fd.Kind.IsObjectArray() { + if fd.Kind.IsObject() && !fd.Kind.IsArray() { if !strings.HasSuffix(field, request.RelatedObjectID) { field = field + request.RelatedObjectID } diff --git a/client/schema_field_description.go b/client/schema_field_description.go index cad233b67c..4c8f0f72d0 100644 --- a/client/schema_field_description.go +++ b/client/schema_field_description.go @@ -33,9 +33,6 @@ type FieldKind interface { // IsObject returns true if this FieldKind is an object type, or an array of object types. IsObject() bool - // IsObjectArray returns true if this FieldKind is an object array type. - IsObjectArray() bool - // IsArray returns true if this FieldKind is an array type which includes inline arrays as well // as relation arrays. IsArray() bool @@ -111,10 +108,6 @@ func (k ScalarKind) IsObject() bool { return false } -func (k ScalarKind) IsObjectArray() bool { - return false -} - func (k ScalarKind) IsArray() bool { return false } @@ -154,10 +147,6 @@ func (k ScalarArrayKind) IsObject() bool { return false } -func (k ScalarArrayKind) IsObjectArray() bool { - return false -} - func (k ScalarArrayKind) IsArray() bool { return true } @@ -178,10 +167,6 @@ func (k ObjectKind) IsObject() bool { return true } -func (k ObjectKind) IsObjectArray() bool { - return false -} - func (k ObjectKind) IsArray() bool { return false } @@ -202,10 +187,6 @@ func (k ObjectArrayKind) IsObject() bool { return true } -func (k ObjectArrayKind) IsObjectArray() bool { - return true -} - func (k ObjectArrayKind) IsArray() bool { return true } diff --git a/internal/db/collection.go b/internal/db/collection.go index d501afc4b7..9c643b5da4 100644 --- a/internal/db/collection.go +++ b/internal/db/collection.go @@ -948,7 +948,7 @@ func (c *collection) tryGetFieldKey(primaryKey core.PrimaryDataStoreKey, fieldNa func (c *collection) tryGetFieldID(fieldName string) (uint32, bool) { for _, field := range c.Definition().GetFields() { if field.Name == fieldName { - if field.Kind.IsObject() || field.Kind.IsObjectArray() { + if field.Kind.IsObject() { // We do not wish to match navigational properties, only // fields directly on the collection. return uint32(0), false diff --git a/internal/db/definition_validation.go b/internal/db/definition_validation.go index 08e6e603a7..9e28624982 100644 --- a/internal/db/definition_validation.go +++ b/internal/db/definition_validation.go @@ -851,7 +851,7 @@ func validateSecondaryNotOnSchema( ) error { for _, newSchema := range newState.schemaByName { for _, newField := range newSchema.Fields { - if newField.Kind.IsObjectArray() { + if newField.Kind.IsObject() && newField.Kind.IsArray() { return NewErrSecondaryFieldOnSchema(newField.Name) } } diff --git a/internal/planner/mapper/mapper.go b/internal/planner/mapper/mapper.go index 55e2358f3e..195e895ffd 100644 --- a/internal/planner/mapper/mapper.go +++ b/internal/planner/mapper/mapper.go @@ -140,10 +140,11 @@ func toSelect( // Remap all alias field names to use their internal field name mappings. for index, groupByField := range groupByFields { fieldDesc, ok := definition.GetFieldByName(groupByField) - if ok && fieldDesc.Kind.IsObject() && !fieldDesc.Kind.IsObjectArray() { + if ok && fieldDesc.Kind.IsObject() { + if fieldDesc.Kind.IsArray() { + return nil, NewErrInvalidFieldToGroupBy(groupByField) + } groupByFields[index] = groupByField + request.RelatedObjectID - } else if ok && fieldDesc.Kind.IsObjectArray() { - return nil, NewErrInvalidFieldToGroupBy(groupByField) } } diff --git a/internal/planner/type_join.go b/internal/planner/type_join.go index cd20ad3c8d..ce97f98723 100644 --- a/internal/planner/type_join.go +++ b/internal/planner/type_join.go @@ -85,13 +85,15 @@ func (p *Planner) makeTypeIndexJoin( return nil, client.NewErrFieldNotExist(subType.Name) } - if typeFieldDesc.Kind.IsObject() && !typeFieldDesc.Kind.IsArray() { // One-to-One, or One side of One-to-Many - joinPlan, err = p.makeTypeJoinOne(parent, source, subType) - } else if typeFieldDesc.Kind.IsObjectArray() { // Many side of One-to-Many - joinPlan, err = p.makeTypeJoinMany(parent, source, subType) - } else { // more to come, Many-to-Many, Embedded? + if !typeFieldDesc.Kind.IsObject() { return nil, ErrUnknownRelationType } + + if typeFieldDesc.Kind.IsArray() { + joinPlan, err = p.makeTypeJoinMany(parent, source, subType) + } else { + joinPlan, err = p.makeTypeJoinOne(parent, source, subType) + } if err != nil { return nil, err } diff --git a/internal/request/graphql/schema/collection.go b/internal/request/graphql/schema/collection.go index d6ae0854d0..be361e0ec2 100644 --- a/internal/request/graphql/schema/collection.go +++ b/internal/request/graphql/schema/collection.go @@ -494,11 +494,10 @@ func setCRDTType(field *ast.FieldDefinition, kind client.FieldKind) (client.CTyp } } - if kind.IsObjectArray() { - return client.NONE_CRDT, nil - } - if kind.IsObject() { + if kind.IsArray() { + return client.NONE_CRDT, nil + } return client.LWW_REGISTER, nil } diff --git a/internal/request/graphql/schema/generate.go b/internal/request/graphql/schema/generate.go index 8bf9b74d72..22524391fd 100644 --- a/internal/request/graphql/schema/generate.go +++ b/internal/request/graphql/schema/generate.go @@ -471,18 +471,15 @@ func (g *Generator) buildTypes( } var ttype gql.Type - if field.Kind.IsObject() && !field.Kind.IsArray() { + if field.Kind.IsObject() { var ok bool ttype, ok = g.manager.schema.TypeMap()[field.Kind.Underlying()] if !ok { return nil, NewErrTypeNotFound(field.Kind.Underlying()) } - } else if field.Kind.IsObjectArray() { - t, ok := g.manager.schema.TypeMap()[field.Kind.Underlying()] - if !ok { - return nil, NewErrTypeNotFound(field.Kind.Underlying()) + if field.Kind.IsArray() { + ttype = gql.NewList(ttype) } - ttype = gql.NewList(t) } else { var ok bool ttype, ok = fieldKindToGQLType[field.Kind] @@ -576,10 +573,12 @@ func (g *Generator) buildMutationInputTypes(collections []client.CollectionDefin } var ttype gql.Type - if field.Kind.IsObject() && !field.Kind.IsArray() { - ttype = gql.ID - } else if field.Kind.IsObjectArray() { - ttype = gql.NewList(gql.ID) + if field.Kind.IsObject() { + if field.Kind.IsArray() { + ttype = gql.NewList(gql.ID) + } else { + ttype = gql.ID + } } else { var ok bool ttype, ok = fieldKindToGQLType[field.Kind] From 8e4690fed1de62a76f91169ffeae494cd8142230 Mon Sep 17 00:00:00 2001 From: Keenan Nemetz Date: Tue, 23 Jul 2024 15:27:50 -0700 Subject: [PATCH 19/41] fix(i): Tests with primary doc patch update events (#2850) ## Relevant issue(s) Resolves #2849 ## Description This PR fixes an issue with primary document patch updates. We also now assert that the document updates match the expected updates. We can most likely remove the `events` test package now that every test asserts the expected events. ## Tasks - [x] I made sure the code is well commented, particularly hard-to-understand areas. - [x] I made sure the repository-held documentation is changed accordingly. - [x] I made sure the pull request title adheres to the conventional commit style (the subset used in the project can be found in [tools/configs/chglog/config.yml](tools/configs/chglog/config.yml)). - [x] I made sure to discuss its limitations such as threats to validity, vulnerability to mistake and misuse, robustness to invalidation of assumptions, resource requirements, ... ## How has this been tested? `make test` Specify the platform(s) on which this was tested: - MacOS --- client/definitions.go | 17 ++ internal/db/collection.go | 2 +- internal/db/collection_update.go | 13 -- tests/integration/events.go | 178 ++++++++++++--- tests/integration/events/simple/utils.go | 39 ---- .../events/simple/with_create_test.go | 71 ------ .../events/simple/with_create_txn_test.go | 69 ------ .../events/simple/with_delete_test.go | 61 ----- .../events/simple/with_update_test.go | 83 ------- tests/integration/events/utils.go | 173 -------------- tests/integration/state.go | 6 +- tests/integration/utils2.go | 216 ++++++++---------- 12 files changed, 254 insertions(+), 674 deletions(-) delete mode 100644 tests/integration/events/simple/utils.go delete mode 100644 tests/integration/events/simple/with_create_test.go delete mode 100644 tests/integration/events/simple/with_create_txn_test.go delete mode 100644 tests/integration/events/simple/with_delete_test.go delete mode 100644 tests/integration/events/simple/with_update_test.go delete mode 100644 tests/integration/events/utils.go diff --git a/client/definitions.go b/client/definitions.go index c04159f679..c32fd41b4f 100644 --- a/client/definitions.go +++ b/client/definitions.go @@ -10,6 +10,12 @@ package client +import ( + "strings" + + "github.com/sourcenetwork/defradb/client/request" +) + // CollectionDefinition contains the metadata defining what a Collection is. // // The definition types ([CollectionDefinition], [FieldDefinition]) are read-only types returned @@ -178,3 +184,14 @@ func NewSchemaOnlyFieldDefinition(global SchemaFieldDescription) FieldDefinition func (f FieldDefinition) IsRelation() bool { return f.RelationName != "" } + +// GetSecondaryRelationField returns the secondary side field definition of this field +// from the relationship on the given collection definition and a bool indicating +// if the secondary side of the relation was found. +func (f FieldDefinition) GetSecondaryRelationField(c CollectionDefinition) (FieldDefinition, bool) { + if f.RelationName == "" || f.Kind != FieldKind_DocID { + return FieldDefinition{}, false + } + secondary, valid := c.GetFieldByName(strings.TrimSuffix(f.Name, request.RelatedObjectID)) + return secondary, valid && !secondary.IsPrimaryRelation +} diff --git a/internal/db/collection.go b/internal/db/collection.go index 9c643b5da4..088e5075fa 100644 --- a/internal/db/collection.go +++ b/internal/db/collection.go @@ -641,7 +641,7 @@ func (c *collection) save( // that it's set to the same as the field description CRDT type. val.SetType(fieldDescription.Typ) - relationFieldDescription, isSecondaryRelationID := c.isSecondaryIDField(fieldDescription) + relationFieldDescription, isSecondaryRelationID := fieldDescription.GetSecondaryRelationField(c.Definition()) if isSecondaryRelationID { primaryId := val.Value().(string) diff --git a/internal/db/collection_update.go b/internal/db/collection_update.go index 7dbc9c72d9..612d47a883 100644 --- a/internal/db/collection_update.go +++ b/internal/db/collection_update.go @@ -12,7 +12,6 @@ package db import ( "context" - "strings" ds "github.com/ipfs/go-datastore" "github.com/sourcenetwork/immutable" @@ -134,18 +133,6 @@ func (c *collection) updateWithFilter( return results, nil } -// isSecondaryIDField returns true if the given field description represents a secondary relation field ID. -func (c *collection) isSecondaryIDField(fieldDesc client.FieldDefinition) (client.FieldDefinition, bool) { - if fieldDesc.RelationName == "" || fieldDesc.Kind != client.FieldKind_DocID { - return client.FieldDefinition{}, false - } - - relationFieldDescription, valid := c.Definition().GetFieldByName( - strings.TrimSuffix(fieldDesc.Name, request.RelatedObjectID), - ) - return relationFieldDescription, valid && !relationFieldDescription.IsPrimaryRelation -} - // patchPrimaryDoc patches the (primary) document linked to from the document of the given DocID via the // given (secondary) relationship field description (hosted on the collection of the document matching the // given DocID). diff --git a/tests/integration/events.go b/tests/integration/events.go index 946c089d4a..c2db144d93 100644 --- a/tests/integration/events.go +++ b/tests/integration/events.go @@ -11,11 +11,13 @@ package tests import ( + "encoding/json" "time" "github.com/sourcenetwork/immutable" "github.com/stretchr/testify/require" + "github.com/sourcenetwork/defradb/client" "github.com/sourcenetwork/defradb/event" ) @@ -148,51 +150,43 @@ func waitForUnsubscribeToCollectionEvent(s *state, action UnsubscribeToCollectio // update event to the local event bus. // // Expected document heads will be updated for any connected nodes. -func waitForUpdateEvents(s *state, nodeID immutable.Option[int], collectionID int) { +func waitForUpdateEvents( + s *state, + nodeID immutable.Option[int], + docIDs map[string]struct{}, +) { for i := 0; i < len(s.nodes); i++ { if nodeID.HasValue() && nodeID.Value() != i { continue // node is not selected } - var evt event.Update - select { - case msg, ok := <-s.nodeEvents[i].update.Message(): - if !ok { - require.Fail(s.t, "subscription closed waiting for update event") - } - evt = msg.Data.(event.Update) - - case <-time.After(eventTimeout): - require.Fail(s.t, "timeout waiting for update event") - } - - if i >= len(s.nodeConfigs) { - return // not testing network state + expect := make(map[string]struct{}, len(docIDs)) + for k := range docIDs { + expect[k] = struct{}{} } - // make sure the event is published on the network before proceeding - // this prevents nodes from missing messages that are sent before - // subscriptions are setup - time.Sleep(100 * time.Millisecond) + for len(expect) > 0 { + var evt event.Update + select { + case msg, ok := <-s.nodeEvents[i].update.Message(): + if !ok { + require.Fail(s.t, "subscription closed waiting for update event") + } + evt = msg.Data.(event.Update) - // update the actual document head on the node that updated it - s.nodeP2P[i].actualDocHeads[evt.DocID] = evt.Cid + case <-time.After(eventTimeout): + require.Fail(s.t, "timeout waiting for update event") + } - // update the expected document heads of replicator targets - for id := range s.nodeP2P[i].replicators { - // replicator target nodes push updates to source nodes - s.nodeP2P[id].expectedDocHeads[evt.DocID] = evt.Cid - } + // make sure the event is expected + _, ok := expect[evt.DocID] + require.True(s.t, ok, "unexpected document update") + delete(expect, evt.DocID) - // update the expected document heads of connected nodes - for id := range s.nodeP2P[i].connections { - // connected nodes share updates of documents they have in common - if _, ok := s.nodeP2P[id].actualDocHeads[evt.DocID]; ok { - s.nodeP2P[id].expectedDocHeads[evt.DocID] = evt.Cid - } - // peer collection subscribers receive updates from any other subscriber node - if _, ok := s.nodeP2P[id].peerCollections[collectionID]; ok { - s.nodeP2P[id].expectedDocHeads[evt.DocID] = evt.Cid + // we only need to update the network state if the nodes + // are configured for networking + if i < len(s.nodeConfigs) { + updateNetworkState(s, i, evt) } } } @@ -240,3 +234,117 @@ func waitForMergeEvents(s *state) { } } } + +// updateNetworkState updates the network state by checking which +// nodes should receive the updated document in the given update event. +func updateNetworkState(s *state, nodeID int, evt event.Update) { + // find the correct collection index for this update + collectionID := -1 + for i, c := range s.collections[nodeID] { + if c.SchemaRoot() == evt.SchemaRoot { + collectionID = i + } + } + + // update the actual document head on the node that updated it + s.nodeP2P[nodeID].actualDocHeads[evt.DocID] = evt.Cid + + // update the expected document heads of replicator targets + for id := range s.nodeP2P[nodeID].replicators { + // replicator target nodes push updates to source nodes + s.nodeP2P[id].expectedDocHeads[evt.DocID] = evt.Cid + } + + // update the expected document heads of connected nodes + for id := range s.nodeP2P[nodeID].connections { + // connected nodes share updates of documents they have in common + if _, ok := s.nodeP2P[id].actualDocHeads[evt.DocID]; ok { + s.nodeP2P[id].expectedDocHeads[evt.DocID] = evt.Cid + } + // peer collection subscribers receive updates from any other subscriber node + if _, ok := s.nodeP2P[id].peerCollections[collectionID]; ok { + s.nodeP2P[id].expectedDocHeads[evt.DocID] = evt.Cid + } + } + + // make sure the event is published on the network before proceeding + // this prevents nodes from missing messages that are sent before + // subscriptions are setup + time.Sleep(100 * time.Millisecond) +} + +// getEventsForUpdateDoc returns a map of docIDs that should be +// published to the local event bus after an UpdateDoc action. +// +// This will take into account any primary documents that are patched as a result +// of the create or update. +func getEventsForUpdateDoc(s *state, action UpdateDoc) map[string]struct{} { + var collection client.Collection + if action.NodeID.HasValue() { + collection = s.collections[action.NodeID.Value()][action.CollectionID] + } else { + collection = s.collections[0][action.CollectionID] + } + + docID := s.docIDs[action.CollectionID][action.DocID] + def := collection.Definition() + + docMap := make(map[string]any) + err := json.Unmarshal([]byte(action.Doc), &docMap) + require.NoError(s.t, err) + + expect := make(map[string]struct{}) + expect[docID.String()] = struct{}{} + + // check for any secondary relation fields that could publish an event + for name, value := range docMap { + field, ok := def.GetFieldByName(name) + if !ok { + continue // ignore unknown field + } + _, ok = field.GetSecondaryRelationField(def) + if ok { + expect[value.(string)] = struct{}{} + } + } + + return expect +} + +// getEventsForCreateDoc returns a map of docIDs that should be +// published to the local event bus after a CreateDoc action. +// +// This will take into account any primary documents that are patched as a result +// of the create or update. +func getEventsForCreateDoc(s *state, action CreateDoc) map[string]struct{} { + var collection client.Collection + if action.NodeID.HasValue() { + collection = s.collections[action.NodeID.Value()][action.CollectionID] + } else { + collection = s.collections[0][action.CollectionID] + } + + docs, err := parseCreateDocs(action, collection) + require.NoError(s.t, err) + + def := collection.Definition() + expect := make(map[string]struct{}) + + for _, doc := range docs { + expect[doc.ID().String()] = struct{}{} + + // check for any secondary relation fields that could publish an event + for f, v := range doc.Values() { + field, ok := def.GetFieldByName(f.Name()) + if !ok { + continue // ignore unknown field + } + _, ok = field.GetSecondaryRelationField(def) + if ok { + expect[v.Value().(string)] = struct{}{} + } + } + } + + return expect +} diff --git a/tests/integration/events/simple/utils.go b/tests/integration/events/simple/utils.go deleted file mode 100644 index 199a2a7c07..0000000000 --- a/tests/integration/events/simple/utils.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2022 Democratized Data Foundation -// -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. - -package simple - -import ( - "testing" - - "github.com/sourcenetwork/defradb/client" - testUtils "github.com/sourcenetwork/defradb/tests/integration" - testUtilsEvt "github.com/sourcenetwork/defradb/tests/integration/events" -) - -var schema = ` - type Users { - name: String - } -` - -var colDefMap = make(map[string]client.CollectionDefinition) - -func init() { - c, err := testUtils.ParseSDL(schema) - if err != nil { - panic(err) - } - colDefMap = c -} - -func executeTestCase(t *testing.T, test testUtilsEvt.TestCase) { - testUtilsEvt.ExecuteRequestTestCase(t, schema, test) -} diff --git a/tests/integration/events/simple/with_create_test.go b/tests/integration/events/simple/with_create_test.go deleted file mode 100644 index c3f88eea58..0000000000 --- a/tests/integration/events/simple/with_create_test.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2022 Democratized Data Foundation -// -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. - -package simple - -import ( - "context" - "testing" - - "github.com/sourcenetwork/immutable" - "github.com/stretchr/testify/assert" - - "github.com/sourcenetwork/defradb/client" - testUtils "github.com/sourcenetwork/defradb/tests/integration/events" -) - -func TestEventsSimpleWithCreate(t *testing.T) { - doc1, err := client.NewDocFromJSON( - []byte( - `{ - "name": "John" - }`, - ), - colDefMap["Users"], - ) - assert.Nil(t, err) - docID1 := doc1.ID().String() - - doc2, err := client.NewDocFromJSON( - []byte( - `{ - "name": "Shahzad" - }`, - ), - colDefMap["Users"], - ) - assert.Nil(t, err) - docID2 := doc2.ID().String() - - test := testUtils.TestCase{ - CollectionCalls: map[string][]func(client.Collection){ - "Users": []func(c client.Collection){ - func(c client.Collection) { - err = c.Save(context.Background(), doc1) - assert.Nil(t, err) - }, - func(c client.Collection) { - err = c.Save(context.Background(), doc2) - assert.Nil(t, err) - }, - }, - }, - ExpectedUpdates: []testUtils.ExpectedUpdate{ - { - DocID: immutable.Some(docID1), - }, - { - DocID: immutable.Some(docID2), - }, - }, - } - - executeTestCase(t, test) -} diff --git a/tests/integration/events/simple/with_create_txn_test.go b/tests/integration/events/simple/with_create_txn_test.go deleted file mode 100644 index c60c47bd34..0000000000 --- a/tests/integration/events/simple/with_create_txn_test.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2022 Democratized Data Foundation -// -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. - -package simple - -import ( - "context" - "testing" - - "github.com/sourcenetwork/immutable" - "github.com/stretchr/testify/assert" - - "github.com/sourcenetwork/defradb/client" - "github.com/sourcenetwork/defradb/internal/db" - testUtils "github.com/sourcenetwork/defradb/tests/integration/events" -) - -func TestEventsSimpleWithCreateWithTxnDiscarded(t *testing.T) { - test := testUtils.TestCase{ - DatabaseCalls: []func(context.Context, client.DB){ - func(ctx context.Context, d client.DB) { - r := d.ExecRequest( - ctx, - `mutation { - create_Users(input: {name: "John"}) { - _docID - } - }`, - ) - for _, err := range r.GQL.Errors { - assert.Nil(t, err) - } - }, - func(ctx context.Context, d client.DB) { - txn, err := d.NewTxn(ctx, false) - assert.Nil(t, err) - - ctx = db.SetContextTxn(ctx, txn) - r := d.ExecRequest( - ctx, - `mutation { - create_Users(input: {name: "Shahzad"}) { - _docID - } - }`, - ) - for _, err := range r.GQL.Errors { - assert.Nil(t, err) - } - txn.Discard(ctx) - }, - }, - ExpectedUpdates: []testUtils.ExpectedUpdate{ - { - DocID: immutable.Some("bae-6845cfdf-cb0f-56a3-be3a-b5a67be5fbdc"), - }, - // No event should be received for Shahzad, as the transaction was discarded. - }, - } - - executeTestCase(t, test) -} diff --git a/tests/integration/events/simple/with_delete_test.go b/tests/integration/events/simple/with_delete_test.go deleted file mode 100644 index 141965966f..0000000000 --- a/tests/integration/events/simple/with_delete_test.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2022 Democratized Data Foundation -// -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. - -package simple - -import ( - "context" - "testing" - - "github.com/sourcenetwork/immutable" - "github.com/stretchr/testify/assert" - - "github.com/sourcenetwork/defradb/client" - testUtils "github.com/sourcenetwork/defradb/tests/integration/events" -) - -func TestEventsSimpleWithDelete(t *testing.T) { - doc1, err := client.NewDocFromJSON( - []byte( - `{ - "name": "John" - }`, - ), - colDefMap["Users"], - ) - assert.Nil(t, err) - docID1 := doc1.ID().String() - - test := testUtils.TestCase{ - CollectionCalls: map[string][]func(client.Collection){ - "Users": []func(c client.Collection){ - func(c client.Collection) { - err = c.Save(context.Background(), doc1) - assert.Nil(t, err) - }, - func(c client.Collection) { - wasDeleted, err := c.Delete(context.Background(), doc1.ID()) - assert.Nil(t, err) - assert.True(t, wasDeleted) - }, - }, - }, - ExpectedUpdates: []testUtils.ExpectedUpdate{ - { - DocID: immutable.Some(docID1), - }, - { - DocID: immutable.Some(docID1), - }, - }, - } - - executeTestCase(t, test) -} diff --git a/tests/integration/events/simple/with_update_test.go b/tests/integration/events/simple/with_update_test.go deleted file mode 100644 index 2d5fbfc5fe..0000000000 --- a/tests/integration/events/simple/with_update_test.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2022 Democratized Data Foundation -// -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. - -package simple - -import ( - "context" - "testing" - - "github.com/sourcenetwork/immutable" - "github.com/stretchr/testify/assert" - - "github.com/sourcenetwork/defradb/client" - testUtils "github.com/sourcenetwork/defradb/tests/integration/events" -) - -func TestEventsSimpleWithUpdate(t *testing.T) { - doc1, err := client.NewDocFromJSON( - []byte( - `{ - "name": "John" - }`, - ), - colDefMap["Users"], - ) - assert.Nil(t, err) - docID1 := doc1.ID().String() - - doc2, err := client.NewDocFromJSON( - []byte( - `{ - "name": "Shahzad" - }`, - ), - colDefMap["Users"], - ) - assert.Nil(t, err) - docID2 := doc2.ID().String() - - test := testUtils.TestCase{ - CollectionCalls: map[string][]func(client.Collection){ - "Users": []func(c client.Collection){ - func(c client.Collection) { - err = c.Save(context.Background(), doc1) - assert.NoError(t, err) - }, - func(c client.Collection) { - err = c.Save(context.Background(), doc2) - assert.NoError(t, err) - }, - func(c client.Collection) { - // Update John - err = doc1.Set("name", "Johnnnnn") - assert.NoError(t, err) - err = c.Save(context.Background(), doc1) - assert.NoError(t, err) - }, - }, - }, - ExpectedUpdates: []testUtils.ExpectedUpdate{ - { - DocID: immutable.Some(docID1), - Cid: immutable.Some("bafyreih5kmftjua6lihlm7lwohamezecomnwgxv6jtowfnrrfdev43lquq"), - }, - { - DocID: immutable.Some(docID2), - }, - { - DocID: immutable.Some(docID1), - Cid: immutable.Some("bafyreifzav4o7q4sljthu2vks3idyd67hg34llnyv44ii6pstal2woc65q"), - }, - }, - } - - executeTestCase(t, test) -} diff --git a/tests/integration/events/utils.go b/tests/integration/events/utils.go deleted file mode 100644 index 4988f25a66..0000000000 --- a/tests/integration/events/utils.go +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright 2022 Democratized Data Foundation -// -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. - -package events - -import ( - "context" - "testing" - "time" - - "github.com/sourcenetwork/immutable" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/sourcenetwork/defradb/client" - "github.com/sourcenetwork/defradb/event" - testUtils "github.com/sourcenetwork/defradb/tests/integration" -) - -type TestCase struct { - Description string - - // docs is a map from Collection name, to a list - // of docs in stringified JSON format - Docs map[string][]string - - // The collection calls to make after subscribing to the events channel. - // - // Any errors generated within these calls are of no interest to this test - // framework and should be handled as desired by the caller. - CollectionCalls map[string][]func(client.Collection) - - // The daabase calls to make after subscribing to the events channel. - // - // Any errors generated within these calls are of no interest to this test - // framework and should be handled as desired by the caller. - DatabaseCalls []func(context.Context, client.DB) - - // The update events expected during the specified calls. The length will - // be asserted (within timeout). - ExpectedUpdates []ExpectedUpdate -} - -// A struct holding properties that can be asserted upon. -// -// Properties with a `None` value will not be asserted. If all properties -// are `None` the Update event will still be expected and will contribute -// to the asserted count. -type ExpectedUpdate struct { - DocID immutable.Option[string] - // The expected Cid, as a string (results in much more readable errors) - Cid immutable.Option[string] - SchemaRoot immutable.Option[string] - IsCreate immutable.Option[bool] -} - -const eventTimeout = 100 * time.Millisecond - -func ExecuteRequestTestCase( - t *testing.T, - schema string, - testCase TestCase, -) { - ctx := context.Background() - - db, err := testUtils.NewBadgerMemoryDB(ctx) - require.NoError(t, err) - - _, err = db.AddSchema(ctx, schema) - require.NoError(t, err) - - setupDatabase(ctx, t, db, testCase) - - testRoutineClosedChan := make(chan struct{}) - closeTestRoutineChan := make(chan struct{}) - - eventsSub, err := db.Events().Subscribe(event.UpdateName) - require.NoError(t, err) - - indexOfNextExpectedUpdate := 0 - go func() { - for { - select { - case value := <-eventsSub.Message(): - update, ok := value.Data.(event.Update) - if !ok { - continue // ignore invalid value - } - - if indexOfNextExpectedUpdate >= len(testCase.ExpectedUpdates) { - assert.Fail(t, "More events recieved than were expected", update) - testRoutineClosedChan <- struct{}{} - return - } - - expectedEvent := testCase.ExpectedUpdates[indexOfNextExpectedUpdate] - assertIfExpected(t, expectedEvent.Cid, update.Cid.String()) - assertIfExpected(t, expectedEvent.DocID, update.DocID) - assertIfExpected(t, expectedEvent.IsCreate, update.IsCreate) - assertIfExpected(t, expectedEvent.SchemaRoot, update.SchemaRoot) - - indexOfNextExpectedUpdate++ - case <-closeTestRoutineChan: - return - } - } - }() - - for collectionName, collectionCallSet := range testCase.CollectionCalls { - col, err := db.GetCollectionByName(ctx, collectionName) - require.NoError(t, err) - - for _, collectionCall := range collectionCallSet { - collectionCall(col) - } - } - - for _, databaseCall := range testCase.DatabaseCalls { - databaseCall(ctx, db) - } - - select { - case <-time.After(eventTimeout): - // Trigger an exit from the go routine monitoring the eventsChan. - // As well as being a bit cleaner it stops the `--race` flag from - // (rightly) seeing the assert of indexOfNextExpectedUpdate as a - // data race. - closeTestRoutineChan <- struct{}{} - case <-testRoutineClosedChan: - // no-op - just allow the host func to continue - } - - // This is expressed verbosely, as `len(testCase.ExpectedUpdates) == indexOfNextExpectedUpdate` - // is less easy to understand than the below - indexOfLastExpectedUpdate := len(testCase.ExpectedUpdates) - 1 - indexOfLastAssertedUpdate := indexOfNextExpectedUpdate - 1 - assert.Equal(t, indexOfLastExpectedUpdate, indexOfLastAssertedUpdate) -} - -func setupDatabase( - ctx context.Context, - t *testing.T, - db client.DB, - testCase TestCase, -) { - for collectionName, docs := range testCase.Docs { - col, err := db.GetCollectionByName(ctx, collectionName) - require.NoError(t, err) - - for _, docStr := range docs { - doc, err := client.NewDocFromJSON([]byte(docStr), col.Definition()) - require.NoError(t, err) - - err = col.Save(ctx, doc) - require.NoError(t, err) - } - } -} - -// assertIfExpected asserts that the given values are Equal, if the expected parameter -// has a value. Otherwise this function will do nothing. -func assertIfExpected[T any](t *testing.T, expected immutable.Option[T], actual T) { - if expected.HasValue() { - assert.Equal(t, expected.Value(), actual) - } -} diff --git a/tests/integration/state.go b/tests/integration/state.go index 140857aa80..0ea720b09f 100644 --- a/tests/integration/state.go +++ b/tests/integration/state.go @@ -162,11 +162,11 @@ type state struct { // Indexes matches that of collections. collectionNames []string - // Documents by index, by collection index. + // Document IDs by index, by collection index. // // Each index is assumed to be global, and may be expected across multiple // nodes. - documents [][]*client.Document + docIDs [][]client.DocID // Indexes, by index, by collection index, by node index. indexes [][][]client.IndexDescription @@ -207,7 +207,7 @@ func newState( dbPaths: []string{}, collections: [][]client.Collection{}, collectionNames: collectionNames, - documents: [][]*client.Document{}, + docIDs: [][]client.DocID{}, indexes: [][][]client.IndexDescription{}, isBench: false, } diff --git a/tests/integration/utils2.go b/tests/integration/utils2.go index 67ed5dd3d1..fcac0c299e 100644 --- a/tests/integration/utils2.go +++ b/tests/integration/utils2.go @@ -820,10 +820,10 @@ func refreshDocuments( // For now just do the initial setup using the collections on the first node, // this may need to become more involved at a later date depending on testing // requirements. - s.documents = make([][]*client.Document, len(s.collections[0])) + s.docIDs = make([][]client.DocID, len(s.collections[0])) for i := range s.collections[0] { - s.documents[i] = []*client.Document{} + s.docIDs[i] = []client.DocID{} } for i := 0; i < startActionIndex; i++ { @@ -835,20 +835,10 @@ func refreshDocuments( // purpose. collection := getNodeCollections(action.NodeID, s.collections)[0][action.CollectionID] - var doc *client.Document - var docs []*client.Document - var err error if action.DocMap != nil { substituteRelations(s, action) - doc, err = client.NewDocFromMap(action.DocMap, collection.Definition()) - docs = append(docs, doc) - } else if client.IsJSONArray([]byte(action.Doc)) { - docs, err = client.NewDocsFromJSON([]byte(action.Doc), collection.Definition()) - } else { - doc, err = client.NewDocFromJSON([]byte(action.Doc), collection.Definition()) - docs = append(docs, doc) } - + docs, err := parseCreateDocs(action, collection) if err != nil { // If an err has been returned, ignore it - it may be expected and if not // the test will fail later anyway @@ -856,18 +846,7 @@ func refreshDocuments( } for _, doc := range docs { - ctx := makeContextForDocCreate(s, s.ctx, 0, &action) - - // The document may have been mutated by other actions, so to be sure we have the latest - // version without having to worry about the individual update mechanics we fetch it. - doc, err = collection.Get(ctx, doc.ID(), false) - if err != nil { - // If an err has been returned, ignore it - it may be expected and if not - // the test will fail later anyway - continue - } - - s.documents[action.CollectionID] = append(s.documents[action.CollectionID], doc) + s.docIDs[action.CollectionID] = append(s.docIDs[action.CollectionID], doc.ID()) } } } @@ -1145,8 +1124,7 @@ func createDoc( substituteRelations(s, action) } - var mutation func(*state, CreateDoc, client.DB, int, []client.Collection) ([]*client.Document, error) - + var mutation func(*state, CreateDoc, client.DB, int, client.Collection) ([]client.DocID, error) switch mutationType { case CollectionSaveMutationType: mutation = createDocViaColSave @@ -1159,7 +1137,7 @@ func createDoc( } var expectedErrorRaised bool - var docs []*client.Document + var docIDs []client.DocID actionNodes := getNodes(action.NodeID, s.nodes) for nodeID, collections := range getNodeCollections(action.NodeID, s.collections) { err := withRetry( @@ -1167,7 +1145,7 @@ func createDoc( nodeID, func() error { var err error - docs, err = mutation(s, action, actionNodes[nodeID], nodeID, collections) + docIDs, err = mutation(s, action, actionNodes[nodeID], nodeID, collections[action.CollectionID]) return err }, ) @@ -1176,16 +1154,14 @@ func createDoc( assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) - if action.CollectionID >= len(s.documents) { + if action.CollectionID >= len(s.docIDs) { // Expand the slice if required, so that the document can be accessed by collection index - s.documents = append(s.documents, make([][]*client.Document, action.CollectionID-len(s.documents)+1)...) + s.docIDs = append(s.docIDs, make([][]client.DocID, action.CollectionID-len(s.docIDs)+1)...) } - s.documents[action.CollectionID] = append(s.documents[action.CollectionID], docs...) + s.docIDs[action.CollectionID] = append(s.docIDs[action.CollectionID], docIDs...) if action.ExpectedError == "" { - for i := 0; i < len(docs); i++ { - waitForUpdateEvents(s, action.NodeID, action.CollectionID) - } + waitForUpdateEvents(s, action.NodeID, getEventsForCreateDoc(s, action)) } } @@ -1194,38 +1170,25 @@ func createDocViaColSave( action CreateDoc, node client.DB, nodeIndex int, - collections []client.Collection, -) ([]*client.Document, error) { - var docs []*client.Document - var doc *client.Document - var err error - if action.DocMap != nil { - doc, err = client.NewDocFromMap(action.DocMap, collections[action.CollectionID].Definition()) - docs = []*client.Document{doc} - } else { - bytes := []byte(action.Doc) - if client.IsJSONArray(bytes) { - docs, err = client.NewDocsFromJSON(bytes, collections[action.CollectionID].Definition()) - } else { - doc, err = client.NewDocFromJSON(bytes, collections[action.CollectionID].Definition()) - docs = []*client.Document{doc} - } - } + collection client.Collection, +) ([]client.DocID, error) { + docs, err := parseCreateDocs(action, collection) if err != nil { return nil, err } txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) - ctx := makeContextForDocCreate(s, db.SetContextTxn(s.ctx, txn), nodeIndex, &action) - for _, doc := range docs { - err = collections[action.CollectionID].Save(ctx, doc) + docIDs := make([]client.DocID, len(docs)) + for i, doc := range docs { + err := collection.Save(ctx, doc) if err != nil { return nil, err } + docIDs[i] = doc.ID() } - return docs, nil + return docIDs, nil } func makeContextForDocCreate(s *state, ctx context.Context, nodeIndex int, action *CreateDoc) context.Context { @@ -1240,37 +1203,35 @@ func createDocViaColCreate( action CreateDoc, node client.DB, nodeIndex int, - collections []client.Collection, -) ([]*client.Document, error) { - var docs []*client.Document - var doc *client.Document - var err error - if action.DocMap != nil { - doc, err = client.NewDocFromMap(action.DocMap, collections[action.CollectionID].Definition()) - docs = []*client.Document{doc} - } else { - if client.IsJSONArray([]byte(action.Doc)) { - docs, err = client.NewDocsFromJSON([]byte(action.Doc), collections[action.CollectionID].Definition()) - } else { - doc, err = client.NewDocFromJSON([]byte(action.Doc), collections[action.CollectionID].Definition()) - docs = []*client.Document{doc} - } - } + collection client.Collection, +) ([]client.DocID, error) { + docs, err := parseCreateDocs(action, collection) if err != nil { return nil, err } txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) - ctx := makeContextForDocCreate(s, db.SetContextTxn(s.ctx, txn), nodeIndex, &action) - if len(docs) > 1 { - err = collections[action.CollectionID].CreateMany(ctx, docs) - } else { - err = collections[action.CollectionID].Create(ctx, doc) + switch { + case len(docs) > 1: + err := collection.CreateMany(ctx, docs) + if err != nil { + return nil, err + } + + default: + err := collection.Create(ctx, docs[0]) + if err != nil { + return nil, err + } } - return docs, err + docIDs := make([]client.DocID, len(docs)) + for i, doc := range docs { + docIDs[i] = doc.ID() + } + return docIDs, nil } func createDocViaGQL( @@ -1278,9 +1239,8 @@ func createDocViaGQL( action CreateDoc, node client.DB, nodeIndex int, - collections []client.Collection, -) ([]*client.Document, error) { - collection := collections[action.CollectionID] + collection client.Collection, +) ([]client.DocID, error) { var input string paramName := request.Input @@ -1332,20 +1292,15 @@ func createDocViaGQL( return nil, nil } - docs := make([]*client.Document, len(resultantDocs)) - + docIDs := make([]client.DocID, len(resultantDocs)) for i, docMap := range resultantDocs { docIDString := docMap[request.DocIDFieldName].(string) docID, err := client.NewDocIDFromString(docIDString) require.NoError(s.t, err) - - doc, err := collection.Get(ctx, docID, false) - require.NoError(s.t, err) - - docs[i] = doc + docIDs[i] = docID } - return docs, nil + return docIDs, nil } // substituteRelations scans the fields defined in [action.DocMap], if any are of type [DocIndex] @@ -1362,8 +1317,8 @@ func substituteRelations( continue } - doc := s.documents[index.CollectionIndex][index.Index] - action.DocMap[k] = doc.ID().String() + docID := s.docIDs[index.CollectionIndex][index.Index] + action.DocMap[k] = docID.String() } } @@ -1373,7 +1328,7 @@ func deleteDoc( s *state, action DeleteDoc, ) { - doc := s.documents[action.CollectionID][action.DocID] + docID := s.docIDs[action.CollectionID][action.DocID] var expectedErrorRaised bool actionNodes := getNodes(action.NodeID, s.nodes) @@ -1385,7 +1340,7 @@ func deleteDoc( actionNodes, nodeID, func() error { - _, err := collections[action.CollectionID].Delete(ctx, doc.ID()) + _, err := collections[action.CollectionID].Delete(ctx, docID) return err }, ) @@ -1395,7 +1350,10 @@ func deleteDoc( assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) if action.ExpectedError == "" { - waitForUpdateEvents(s, action.NodeID, action.CollectionID) + docIDs := map[string]struct{}{ + docID.String(): {}, + } + waitForUpdateEvents(s, action.NodeID, docIDs) } } @@ -1404,8 +1362,7 @@ func updateDoc( s *state, action UpdateDoc, ) { - var mutation func(*state, UpdateDoc, client.DB, int, []client.Collection) error - + var mutation func(*state, UpdateDoc, client.DB, int, client.Collection) error switch mutationType { case CollectionSaveMutationType: mutation = updateDocViaColSave @@ -1423,7 +1380,9 @@ func updateDoc( err := withRetry( actionNodes, nodeID, - func() error { return mutation(s, action, actionNodes[nodeID], nodeID, collections) }, + func() error { + return mutation(s, action, actionNodes[nodeID], nodeID, collections[action.CollectionID]) + }, ) expectedErrorRaised = AssertError(s.t, s.testCase.Description, err, action.ExpectedError) } @@ -1431,7 +1390,7 @@ func updateDoc( assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) if action.ExpectedError == "" && !action.SkipLocalUpdateEvent { - waitForUpdateEvents(s, action.NodeID, action.CollectionID) + waitForUpdateEvents(s, action.NodeID, getEventsForUpdateDoc(s, action)) } } @@ -1440,28 +1399,20 @@ func updateDocViaColSave( action UpdateDoc, node client.DB, nodeIndex int, - collections []client.Collection, + collection client.Collection, ) error { - cachedDoc := s.documents[action.CollectionID][action.DocID] identity := getIdentity(s, nodeIndex, action.Identity) ctx := db.SetContextIdentity(s.ctx, identity) - doc, err := collections[action.CollectionID].Get(ctx, cachedDoc.ID(), true) + doc, err := collection.Get(ctx, s.docIDs[action.CollectionID][action.DocID], true) if err != nil { return err } - err = doc.SetWithJSON([]byte(action.Doc)) if err != nil { return err } - - s.documents[action.CollectionID][action.DocID] = doc - - return collections[action.CollectionID].Save( - ctx, - doc, - ) + return collection.Save(ctx, doc) } func updateDocViaColUpdate( @@ -1469,25 +1420,20 @@ func updateDocViaColUpdate( action UpdateDoc, node client.DB, nodeIndex int, - collections []client.Collection, + collection client.Collection, ) error { - cachedDoc := s.documents[action.CollectionID][action.DocID] identity := getIdentity(s, nodeIndex, action.Identity) ctx := db.SetContextIdentity(s.ctx, identity) - doc, err := collections[action.CollectionID].Get(ctx, cachedDoc.ID(), true) + doc, err := collection.Get(ctx, s.docIDs[action.CollectionID][action.DocID], true) if err != nil { return err } - err = doc.SetWithJSON([]byte(action.Doc)) if err != nil { return err } - - s.documents[action.CollectionID][action.DocID] = doc - - return collections[action.CollectionID].Update(ctx, doc) + return collection.Update(ctx, doc) } func updateDocViaGQL( @@ -1495,10 +1441,9 @@ func updateDocViaGQL( action UpdateDoc, node client.DB, nodeIndex int, - collections []client.Collection, + collection client.Collection, ) error { - doc := s.documents[action.CollectionID][action.DocID] - collection := collections[action.CollectionID] + docID := s.docIDs[action.CollectionID][action.DocID] input, err := jsonToGQL(action.Doc) require.NoError(s.t, err) @@ -1510,15 +1455,12 @@ func updateDocViaGQL( } }`, collection.Name().Value(), - doc.ID().String(), + docID.String(), input, ) - txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) - - ctx := db.SetContextTxn(s.ctx, txn) identity := getIdentity(s, nodeIndex, action.Identity) - ctx = db.SetContextIdentity(ctx, identity) + ctx := db.SetContextIdentity(s.ctx, identity) result := node.ExecRequest(ctx, request) if len(result.GQL.Errors) > 0 { @@ -1940,7 +1882,7 @@ func assertRequestResults( valueSet = append(valueSet, actualValue) anyOfByField[dfk] = valueSet case DocIndex: - expectedDocID := s.documents[r.CollectionIndex][r.Index].ID().String() + expectedDocID := s.docIDs[r.CollectionIndex][r.Index].String() assertResultsEqual( s.t, s.clientType, @@ -2201,3 +2143,25 @@ func CBORValue(value any) []byte { } return enc } + +// parseCreateDocs parses and returns documents from a CreateDoc action. +func parseCreateDocs(action CreateDoc, collection client.Collection) ([]*client.Document, error) { + switch { + case action.DocMap != nil: + val, err := client.NewDocFromMap(action.DocMap, collection.Definition()) + if err != nil { + return nil, err + } + return []*client.Document{val}, nil + + case client.IsJSONArray([]byte(action.Doc)): + return client.NewDocsFromJSON([]byte(action.Doc), collection.Definition()) + + default: + val, err := client.NewDocFromJSON([]byte(action.Doc), collection.Definition()) + if err != nil { + return nil, err + } + return []*client.Document{val}, nil + } +} From 5cd01856bb115bfbefe8950fe778cd3603383a24 Mon Sep 17 00:00:00 2001 From: Keenan Nemetz Date: Wed, 24 Jul 2024 14:28:53 -0700 Subject: [PATCH 20/41] fix(i): Lock sourcehub version (#2866) ## Relevant issue(s) Related #2865 ## Description This PR locks the sourcehub version until the dev branch is stable again. ## Tasks - [x] I made sure the code is well commented, particularly hard-to-understand areas. - [x] I made sure the repository-held documentation is changed accordingly. - [x] I made sure the pull request title adheres to the conventional commit style (the subset used in the project can be found in [tools/configs/chglog/config.yml](tools/configs/chglog/config.yml)). - [x] I made sure to discuss its limitations such as threats to validity, vulnerability to mistake and misuse, robustness to invalidation of assumptions, resource requirements, ... ## How has this been tested? CI Specify the platform(s) on which this was tested: - MacOS --- .github/workflows/test-and-upload-coverage.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/test-and-upload-coverage.yml b/.github/workflows/test-and-upload-coverage.yml index 9a8aef76fc..b94ae0686a 100644 --- a/.github/workflows/test-and-upload-coverage.yml +++ b/.github/workflows/test-and-upload-coverage.yml @@ -179,6 +179,9 @@ jobs: with: repository: sourcenetwork/sourcehub path: _sourceHub + # Lock the sourcehub version until the dev branch is stable + # remove this when closed https://github.com/sourcenetwork/defradb/issues/2865 + ref: c232133c35c96924509a4d955a7b450eb3624a15 - name: Install SourceHub CLI if: ${{ matrix.acp-type == 'source-hub' }} From cca14ac50b38d8ff77059993274bcdb3b4670a70 Mon Sep 17 00:00:00 2001 From: AndrewSisley Date: Wed, 24 Jul 2024 18:37:14 -0400 Subject: [PATCH 21/41] fix: Handle multiple child index joins (#2867) ## Relevant issue(s) Resolves #2862 ## Description Handles multiple child index joins. Init is called multiple times (IIRC when joining in this direction it is called 1+NPrimaryDocs times) and the state was preserved between calls. The new `resetState` func duplicates the overwriting of props set in init, but I see that as worth it (very cheap, and means devs don't have to care what is set outside of the constructor). --- internal/db/fetcher/indexer.go | 18 +++++ .../index/query_with_relation_filter_test.go | 69 +++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/internal/db/fetcher/indexer.go b/internal/db/fetcher/indexer.go index eff5146d6f..e75cc18067 100644 --- a/internal/db/fetcher/indexer.go +++ b/internal/db/fetcher/indexer.go @@ -68,6 +68,8 @@ func (f *IndexFetcher) Init( reverse bool, showDeleted bool, ) error { + f.resetState() + f.col = col f.docFilter = filter f.doc = &encodedDocument{} @@ -207,3 +209,19 @@ func (f *IndexFetcher) Close() error { } return nil } + +// resetState resets the mutable state of this IndexFetcher, returning the state to how it +// was immediately after construction. +func (f *IndexFetcher) resetState() { + // WARNING: Do not reset properties set in the constructor! + + f.col = nil + f.txn = nil + f.docFilter = nil + f.doc = nil + f.mapping = nil + f.indexedFields = nil + f.docFields = nil + f.indexIter = nil + f.execInfo.Reset() +} diff --git a/tests/integration/index/query_with_relation_filter_test.go b/tests/integration/index/query_with_relation_filter_test.go index ef4ec989ca..bf8762a144 100644 --- a/tests/integration/index/query_with_relation_filter_test.go +++ b/tests/integration/index/query_with_relation_filter_test.go @@ -910,3 +910,72 @@ func TestQueryWithIndexOnOneToMany_IfIndexedRelationIsNil_EqNilFilterShouldUseIn testUtils.ExecuteTestCase(t, test) } + +// This test was added during https://github.com/sourcenetwork/defradb/issues/2862 +// multiple indexed fields on the second object are required for the failure. +func TestQueryWithIndexOnManyToOne_MultipleViaOneToMany(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + devices: [Device] + } + + type Device { + model: String + owner: User @index + manufacturer: Manufacturer @index + } + + type Manufacturer { + name: String + devices: [Device] + } + `, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "name": "John", + }, + }, + testUtils.CreateDoc{ + CollectionID: 2, + DocMap: map[string]any{ + "name": "Apple", + }, + }, + testUtils.CreateDoc{ + CollectionID: 1, + DocMap: map[string]any{ + "model": "MacBook Pro", + "owner": testUtils.NewDocIndex(0, 0), + "manufacturer": testUtils.NewDocIndex(2, 0), + }, + }, + testUtils.Request{ + Request: `query { + User { + devices { + owner_id + manufacturer_id + } + } + }`, + Results: []map[string]any{ + { + "devices": []map[string]any{ + { + "owner_id": "bae-1ef746f8-821e-586f-99b2-4cb1fb9b782f", + "manufacturer_id": "bae-18c7d707-c44d-552f-b6d6-9e3d05bbf9c1", + }, + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} From 12b762432ce953017cf5e3ec09346dbed8e89a18 Mon Sep 17 00:00:00 2001 From: Islam Aliev Date: Thu, 25 Jul 2024 08:36:36 +0200 Subject: [PATCH 22/41] test: Add assert on DocIndex for child documents (#2871) ## Relevant issue(s) Resolves #2870 ## Description Enables asserting using `testUsilts.NewDocIndex` on child documents --- .../index/query_with_relation_filter_test.go | 20 +++--- .../query/one_to_many_to_many/joins_test.go | 30 ++++----- tests/integration/utils2.go | 64 ++++++++++++++----- 3 files changed, 74 insertions(+), 40 deletions(-) diff --git a/tests/integration/index/query_with_relation_filter_test.go b/tests/integration/index/query_with_relation_filter_test.go index bf8762a144..a7f13788dd 100644 --- a/tests/integration/index/query_with_relation_filter_test.go +++ b/tests/integration/index/query_with_relation_filter_test.go @@ -864,19 +864,19 @@ func TestQueryWithIndexOnOneToMany_IfIndexedRelationIsNil_EqNilFilterShouldUseIn }, testUtils.CreateDoc{ CollectionID: 1, - Doc: `{ - "model": "Walkman", + DocMap: map[string]any{ + "model": "Walkman", "manufacturer": "Sony", - "owner": "bae-5622129c-b893-5768-a3f4-8f745db4cc04" - }`, + "owner": testUtils.NewDocIndex(0, 0), + }, }, testUtils.CreateDoc{ CollectionID: 1, - Doc: `{ - "model": "iPhone", + DocMap: map[string]any{ + "model": "iPhone", "manufacturer": "Apple", - "owner": "bae-5622129c-b893-5768-a3f4-8f745db4cc04" - }`, + "owner": testUtils.NewDocIndex(0, 0), + }, }, testUtils.CreateDoc{ CollectionID: 1, @@ -967,8 +967,8 @@ func TestQueryWithIndexOnManyToOne_MultipleViaOneToMany(t *testing.T) { { "devices": []map[string]any{ { - "owner_id": "bae-1ef746f8-821e-586f-99b2-4cb1fb9b782f", - "manufacturer_id": "bae-18c7d707-c44d-552f-b6d6-9e3d05bbf9c1", + "owner_id": testUtils.NewDocIndex(0, 0), + "manufacturer_id": testUtils.NewDocIndex(2, 0), }, }, }, diff --git a/tests/integration/query/one_to_many_to_many/joins_test.go b/tests/integration/query/one_to_many_to_many/joins_test.go index d4d4da2ca5..1143eb1ba9 100644 --- a/tests/integration/query/one_to_many_to_many/joins_test.go +++ b/tests/integration/query/one_to_many_to_many/joins_test.go @@ -187,20 +187,20 @@ func TestOneToManyToManyJoinsAreLinkedProperly(t *testing.T) { }`, Results: []map[string]any{ { - "_docID": "bae-4819f8a1-b519-5b46-ae39-4fdda8558e4f", + "_docID": testUtils.NewDocIndex(0, 2), "book": []map[string]any{}, "name": "Not a Writer", }, { "name": "Cornelia Funke", - "_docID": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace", + "_docID": testUtils.NewDocIndex(0, 1), "book": []map[string]any{ { - "_docID": "bae-4dbc2bbc-0652-5412-8063-486499f1c341", + "_docID": testUtils.NewDocIndex(1, 0), "name": "The Rooster Bar", "publisher": []map[string]any{ { - "_docID": "bae-8a8cbab7-65db-5955-b618-b82f44761cee", + "_docID": testUtils.NewDocIndex(2, 0), "name": "Only Publisher of The Rooster Bar", }, }, @@ -209,53 +209,53 @@ func TestOneToManyToManyJoinsAreLinkedProperly(t *testing.T) { }, { "name": "John Grisham", - "_docID": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", + "_docID": testUtils.NewDocIndex(0, 0), "book": []map[string]any{ { - "_docID": "bae-13164fd9-60fd-5c32-9cb5-8bff3ef8ea53", + "_docID": testUtils.NewDocIndex(1, 1), "name": "Theif Lord", "publisher": []map[string]any{ { - "_docID": "bae-0107f5cc-c25a-5295-8439-2b08a286af83", + "_docID": testUtils.NewDocIndex(2, 1), "name": "Only Publisher of Theif Lord", }, }, }, { - "_docID": "bae-1ccf3043-d760-543e-be1b-6691fa6aa7a8", + "_docID": testUtils.NewDocIndex(1, 2), "name": "The Associate", "publisher": []map[string]any{}, }, { - "_docID": "bae-5366ba09-54e8-5381-8169-a770aa9282ae", + "_docID": testUtils.NewDocIndex(1, 3), "name": "Painted House", "publisher": []map[string]any{ { - "_docID": "bae-35f1e55a-c51b-53d7-9b28-9beb904a1343", + "_docID": testUtils.NewDocIndex(2, 2), "name": "Only Publisher of Painted House", }, }, }, { - "_docID": "bae-96c9de0f-2903-5589-9604-b42882afde8c", + "_docID": testUtils.NewDocIndex(1, 4), "name": "A Time for Mercy", "publisher": []map[string]any{ { - "_docID": "bae-37451579-7e50-541d-8a3c-849b290ea416", + "_docID": testUtils.NewDocIndex(2, 3), "name": "Only Publisher of A Time for Mercy", }, }, }, { - "_docID": "bae-f52abfc3-9026-5713-9622-2d3458a386e0", + "_docID": testUtils.NewDocIndex(1, 5), "name": "Sooley", "publisher": []map[string]any{ { - "_docID": "bae-c46b7771-843e-51ac-92be-d145aa2cfc07", + "_docID": testUtils.NewDocIndex(2, 5), "name": "Second of Two Publishers of Sooley", }, { - "_docID": "bae-fc233f9c-f117-59de-be2b-60e4f6f0a898", + "_docID": testUtils.NewDocIndex(2, 4), "name": "First of Two Publishers of Sooley", }, }, diff --git a/tests/integration/utils2.go b/tests/integration/utils2.go index fcac0c299e..139b53652b 100644 --- a/tests/integration/utils2.go +++ b/tests/integration/utils2.go @@ -1852,43 +1852,61 @@ func assertRequestResults( log.InfoContext(s.ctx, "", corelog.Any("RequestResults", result.Data)) + return assertRequestResultDocs(s, nodeID, expectedResults, resultantData, anyOfByField) +} + +func assertRequestResultDocs( + s *state, + nodeID int, + expectedResults []map[string]any, + actualResults []map[string]any, + anyOfByField map[docFieldKey][]any, +) bool { // compare results - require.Equal(s.t, len(expectedResults), len(resultantData), + require.Equal(s.t, len(expectedResults), len(actualResults), s.testCase.Description+" \n(number of results don't match)") - for docIndex, result := range resultantData { - expectedResult := expectedResults[docIndex] + for actualDocIndex, actualDoc := range actualResults { + expectedDoc := expectedResults[actualDocIndex] require.Equal( s.t, - len(expectedResult), - len(result), + len(expectedDoc), + len(actualDoc), fmt.Sprintf( "%s \n(number of properties for item at index %v don't match)", s.testCase.Description, - docIndex, + actualDocIndex, ), ) - for field, actualValue := range result { - expectedValue := expectedResult[field] - - switch r := expectedValue.(type) { + for field, actualValue := range actualDoc { + switch expectedValue := expectedDoc[field].(type) { case AnyOf: - assertResultsAnyOf(s.t, s.clientType, r, actualValue) + assertResultsAnyOf(s.t, s.clientType, expectedValue, actualValue) - dfk := docFieldKey{docIndex, field} + dfk := docFieldKey{actualDocIndex, field} valueSet := anyOfByField[dfk] valueSet = append(valueSet, actualValue) anyOfByField[dfk] = valueSet case DocIndex: - expectedDocID := s.docIDs[r.CollectionIndex][r.Index].String() + expectedDocID := s.docIDs[expectedValue.CollectionIndex][expectedValue.Index].String() assertResultsEqual( s.t, s.clientType, expectedDocID, actualValue, - fmt.Sprintf("node: %v, doc: %v", nodeID, docIndex), + fmt.Sprintf("node: %v, doc: %v", nodeID, actualDocIndex), + ) + case []map[string]any: + actualValueMap := convertToArrayOfMaps(s.t, actualValue) + + assertRequestResultDocs( + s, + nodeID, + expectedValue, + actualValueMap, + anyOfByField, ) default: @@ -1897,7 +1915,7 @@ func assertRequestResults( s.clientType, expectedValue, actualValue, - fmt.Sprintf("node: %v, doc: %v", nodeID, docIndex), + fmt.Sprintf("node: %v, doc: %v", nodeID, actualDocIndex), ) } } @@ -1906,6 +1924,22 @@ func assertRequestResults( return false } +func convertToArrayOfMaps(t testing.TB, value any) []map[string]any { + valueArrayMap, ok := value.([]map[string]any) + if ok { + return valueArrayMap + } + valueArray, ok := value.([]any) + require.True(t, ok, "expected value to be an array of maps %v", value) + + valueArrayMap = make([]map[string]any, len(valueArray)) + for i, v := range valueArray { + valueArrayMap[i], ok = v.(map[string]any) + require.True(t, ok, "expected value to be an array of maps %v", value) + } + return valueArrayMap +} + func assertExpectedErrorRaised(t testing.TB, description string, expectedError string, wasRaised bool) { if expectedError != "" && !wasRaised { assert.Fail(t, "Expected an error however none was raised.", description) From e42205889e6edaa9618e7083b2c14f601d59f8b9 Mon Sep 17 00:00:00 2001 From: Keenan Nemetz Date: Fri, 26 Jul 2024 13:31:04 -0700 Subject: [PATCH 23/41] refactor(i): Collection tests (#2861) ## Relevant issue(s) Resolves #2860 ## Description This PR refactors the collection tests to use the test integration test framework. It also adds a new `UpdateWithFilter` test action. ## Tasks - [x] I made sure the code is well commented, particularly hard-to-understand areas. - [x] I made sure the repository-held documentation is changed accordingly. - [x] I made sure the pull request title adheres to the conventional commit style (the subset used in the project can be found in [tools/configs/chglog/config.yml](tools/configs/chglog/config.yml)). - [x] I made sure to discuss its limitations such as threats to validity, vulnerability to mistake and misuse, robustness to invalidation of assumptions, resource requirements, ... ## How has this been tested? (*replace*) Describe the tests performed to verify the changes. Provide instructions to reproduce them. Specify the platform(s) on which this was tested: - MacOS --- cli/collection_update.go | 10 +- .../collection/update/simple/utils.go | 34 ++- .../update/simple/with_filter_test.go | 257 ++++++++---------- tests/integration/collection/utils.go | 116 -------- tests/integration/events.go | 43 +++ tests/integration/test_case.go | 37 +++ tests/integration/utils2.go | 31 +++ 7 files changed, 242 insertions(+), 286 deletions(-) delete mode 100644 tests/integration/collection/utils.go diff --git a/cli/collection_update.go b/cli/collection_update.go index fb7e352249..228bff0053 100644 --- a/cli/collection_update.go +++ b/cli/collection_update.go @@ -11,6 +11,8 @@ package cli import ( + "encoding/json" + "github.com/spf13/cobra" "github.com/sourcenetwork/defradb/client" @@ -48,8 +50,12 @@ Example: update private docID, with identity: } switch { - case filter != "" && updater != "": - res, err := col.UpdateWithFilter(cmd.Context(), filter, updater) + case filter != "" || updater != "": + var filterValue any + if err := json.Unmarshal([]byte(filter), &filterValue); err != nil { + return err + } + res, err := col.UpdateWithFilter(cmd.Context(), filterValue, updater) if err != nil { return err } diff --git a/tests/integration/collection/update/simple/utils.go b/tests/integration/collection/update/simple/utils.go index 91cbe700f7..224c3b9ce5 100644 --- a/tests/integration/collection/update/simple/utils.go +++ b/tests/integration/collection/update/simple/utils.go @@ -13,12 +13,10 @@ package update import ( "testing" - "github.com/sourcenetwork/defradb/client" testUtils "github.com/sourcenetwork/defradb/tests/integration" - testUtilsCol "github.com/sourcenetwork/defradb/tests/integration/collection" ) -var userCollectionGQLSchema = ` +var schema = ` type Users { name: String age: Int @@ -27,19 +25,19 @@ var userCollectionGQLSchema = ` } ` -var colDefMap = make(map[string]client.CollectionDefinition) - -func init() { - c, err := testUtils.ParseSDL(userCollectionGQLSchema) - if err != nil { - panic(err) - } - u := c["Users"] - u.Schema.Root = "bafkreiclkqkxhq3xu3sz5fqcixykk2qfpva5asj3elcaqyxscax66ok4za" - c["Users"] = u - colDefMap = c -} - -func executeTestCase(t *testing.T, test testUtilsCol.TestCase) { - testUtilsCol.ExecuteRequestTestCase(t, userCollectionGQLSchema, test) +func executeTestCase(t *testing.T, test testUtils.TestCase) { + testUtils.ExecuteTestCase( + t, + testUtils.TestCase{ + Description: test.Description, + Actions: append( + []any{ + testUtils.SchemaUpdate{ + Schema: schema, + }, + }, + test.Actions..., + ), + }, + ) } diff --git a/tests/integration/collection/update/simple/with_filter_test.go b/tests/integration/collection/update/simple/with_filter_test.go index ebe45e0b4f..a99f340753 100644 --- a/tests/integration/collection/update/simple/with_filter_test.go +++ b/tests/integration/collection/update/simple/with_filter_test.go @@ -11,193 +11,150 @@ package update import ( - "context" "testing" - "github.com/stretchr/testify/assert" - - "github.com/sourcenetwork/defradb/client" - testUtils "github.com/sourcenetwork/defradb/tests/integration/collection" + testUtils "github.com/sourcenetwork/defradb/tests/integration" ) -func TestUpdateWithInvalidFilterType(t *testing.T) { +func TestUpdateWithInvalidFilterType_ReturnsError(t *testing.T) { test := testUtils.TestCase{ Description: "Test update users with invalid filter type", - Docs: map[string][]string{}, - CollectionCalls: map[string][]func(client.Collection) error{ - "Users": []func(c client.Collection) error{ - func(c client.Collection) error { - ctx := context.Background() - // test with an invalid filter type - _, err := c.UpdateWithFilter( - ctx, - t, - `{"name": "Eric"}`, - ) - return err - }, + Actions: []any{ + testUtils.UpdateWithFilter{ + CollectionID: 0, + Filter: t, + Updater: `{"name": "Eric"}`, + ExpectedError: "invalid filter", }, }, - ExpectedError: "invalid filter", } executeTestCase(t, test) } -func TestUpdateWithEmptyFilter(t *testing.T) { +func TestUpdateWithEmptyFilter_ReturnsError(t *testing.T) { test := testUtils.TestCase{ Description: "Test update users with empty filter", - Docs: map[string][]string{}, - CollectionCalls: map[string][]func(client.Collection) error{ - "Users": []func(c client.Collection) error{ - func(c client.Collection) error { - ctx := context.Background() - // test with an empty filter - _, err := c.UpdateWithFilter( - ctx, - "", - `{"name": "Eric"}`, - ) - return err - }, + Actions: []any{ + testUtils.UpdateWithFilter{ + CollectionID: 0, + Filter: "", + Updater: `{"name": "Eric"}`, + ExpectedError: "invalid filter", }, }, - ExpectedError: "invalid filter", } executeTestCase(t, test) } -func TestUpdateWithFilter(t *testing.T) { - docStr := `{ - "name": "John", - "age": 21 - }` - - doc, err := client.NewDocFromJSON([]byte(docStr), colDefMap["Users"]) - if err != nil { - assert.Fail(t, err.Error()) +func TestUpdateWithInvalidJSON_ReturnsError(t *testing.T) { + test := testUtils.TestCase{ + Description: "Test update users with filter and invalid JSON", + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ + "name": "John", + "age": 21 + }`, + }, + testUtils.UpdateWithFilter{ + CollectionID: 0, + Filter: `{name: {_eq: "John"}}`, + Updater: `{name: "Eric"}`, + ExpectedError: "cannot parse JSON: cannot parse object", + }, + }, } - filter := `{name: {_eq: "John"}}` + executeTestCase(t, test) +} - tests := []testUtils.TestCase{ - { - Description: "Test update users with filter and invalid JSON", - Docs: map[string][]string{ - "Users": {docStr}, +func TestUpdateWithInvalidUpdater_ReturnsError(t *testing.T) { + test := testUtils.TestCase{ + Description: "Test update users with filter and invalid updator", + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ + "name": "John", + "age": 21 + }`, }, - CollectionCalls: map[string][]func(client.Collection) error{ - "Users": []func(c client.Collection) error{ - func(c client.Collection) error { - ctx := context.Background() - _, err := c.UpdateWithFilter( - ctx, - filter, - `{name: "Eric"}`, - ) - return err - }, - }, + testUtils.UpdateWithFilter{ + CollectionID: 0, + Filter: `{name: {_eq: "John"}}`, + Updater: `"name: Eric"`, + ExpectedError: "the updater of a document is of invalid type", }, - ExpectedError: "cannot parse JSON: cannot parse object", - }, { - Description: "Test update users with filter and invalid updator", - Docs: map[string][]string{ - "Users": {docStr}, + }, + } + + executeTestCase(t, test) +} + +func TestUpdateWithPatch_DoesNothing(t *testing.T) { + test := testUtils.TestCase{ + Description: "Test update users with filter and patch updator (not implemented so no change)", + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ + "name": "John", + "age": 21 + }`, }, - CollectionCalls: map[string][]func(client.Collection) error{ - "Users": []func(c client.Collection) error{ - func(c client.Collection) error { - ctx := context.Background() - _, err := c.UpdateWithFilter( - ctx, - filter, - `"name: Eric"`, - ) - return err - }, - }, + testUtils.UpdateWithFilter{ + CollectionID: 0, + Filter: `{name: {_eq: "John"}}`, + Updater: `[{"name": "Eric"}, {"name": "Sam"}]`, + SkipLocalUpdateEvent: true, }, - ExpectedError: "the updater of a document is of invalid type", - }, { - Description: "Test update users with filter and patch updator (not implemented so no change)", - Docs: map[string][]string{ - "Users": {docStr}, + testUtils.Request{ + Request: `query{ + Users { + name + } + }`, + Results: []map[string]any{ + {"name": "John"}, + }, }, - CollectionCalls: map[string][]func(client.Collection) error{ - "Users": []func(c client.Collection) error{ - func(c client.Collection) error { - ctx := context.Background() - _, err := c.UpdateWithFilter( - ctx, - filter, - `[ - { - "name": "Eric" - }, { - "name": "Sam" - } - ]`, - ) - if err != nil { - return err - } - - d, err := c.Get(ctx, doc.ID(), false) - if err != nil { - return err - } - - name, err := d.Get("name") - if err != nil { - return err - } + }, + } - assert.Equal(t, "John", name) + executeTestCase(t, test) +} - return nil - }, - }, +func TestUpdateWithFilter_Succeeds(t *testing.T) { + test := testUtils.TestCase{ + Description: "Test update users with filter", + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ + "name": "John", + "age": 21 + }`, }, - }, { - Description: "Test update users with filter", - Docs: map[string][]string{ - "Users": {docStr}, + testUtils.UpdateWithFilter{ + CollectionID: 0, + Filter: `{name: {_eq: "John"}}`, + Updater: `{"name": "Eric"}`, }, - CollectionCalls: map[string][]func(client.Collection) error{ - "Users": []func(c client.Collection) error{ - func(c client.Collection) error { - ctx := context.Background() - _, err := c.UpdateWithFilter( - ctx, - filter, - `{"name": "Eric"}`, - ) - if err != nil { - return err - } - - d, err := c.Get(ctx, doc.ID(), false) - if err != nil { - return err - } - - name, err := d.Get("name") - if err != nil { - return err - } - - assert.Equal(t, "Eric", name) - - return nil - }, + testUtils.Request{ + Request: `query{ + Users { + name + } + }`, + Results: []map[string]any{ + {"name": "Eric"}, }, }, }, } - for _, test := range tests { - executeTestCase(t, test) - } + executeTestCase(t, test) } diff --git a/tests/integration/collection/utils.go b/tests/integration/collection/utils.go deleted file mode 100644 index 497637a5c3..0000000000 --- a/tests/integration/collection/utils.go +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2022 Democratized Data Foundation -// -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. - -package collection - -import ( - "context" - "strings" - "testing" - - "github.com/stretchr/testify/assert" - - "github.com/sourcenetwork/defradb/client" - "github.com/sourcenetwork/defradb/errors" - testUtils "github.com/sourcenetwork/defradb/tests/integration" -) - -type TestCase struct { - Description string - - // docs is a map from Collection name, to a list - // of docs in stringified JSON format - Docs map[string][]string - - CollectionCalls map[string][]func(client.Collection) error - - // Any error expected to be returned by collection calls. - ExpectedError string -} - -func ExecuteRequestTestCase( - t *testing.T, - schema string, - testCase TestCase, -) { - ctx := context.Background() - - db, err := testUtils.NewBadgerMemoryDB(ctx) - if err != nil { - t.Fatal(err) - } - - _, err = db.AddSchema(ctx, schema) - if assertError(t, testCase.Description, err, testCase.ExpectedError) { - return - } - - setupDatabase(ctx, t, db, testCase) - - for collectionName, collectionCallSet := range testCase.CollectionCalls { - col, err := db.GetCollectionByName(ctx, collectionName) - if assertError(t, testCase.Description, err, testCase.ExpectedError) { - return - } - - for _, collectionCall := range collectionCallSet { - err := collectionCall(col) - if assertError(t, testCase.Description, err, testCase.ExpectedError) { - return - } - } - } - - if testCase.ExpectedError != "" { - assert.Fail(t, "Expected an error however none was raised.", testCase.Description) - } -} - -func setupDatabase( - ctx context.Context, - t *testing.T, - db client.DB, - testCase TestCase, -) { - for collectionName, docs := range testCase.Docs { - col, err := db.GetCollectionByName(ctx, collectionName) - if assertError(t, testCase.Description, err, testCase.ExpectedError) { - return - } - - for _, docStr := range docs { - doc, err := client.NewDocFromJSON([]byte(docStr), col.Definition()) - if assertError(t, testCase.Description, err, testCase.ExpectedError) { - return - } - err = col.Save(ctx, doc) - if assertError(t, testCase.Description, err, testCase.ExpectedError) { - return - } - } - } -} - -func assertError(t *testing.T, description string, err error, expectedError string) bool { - if err == nil { - return false - } - - if expectedError == "" { - assert.NoError(t, err, description) - return false - } else { - if !strings.Contains(err.Error(), expectedError) { - assert.ErrorIs(t, err, errors.New(expectedError)) - return false - } - return true - } -} diff --git a/tests/integration/events.go b/tests/integration/events.go index c2db144d93..87b157a662 100644 --- a/tests/integration/events.go +++ b/tests/integration/events.go @@ -348,3 +348,46 @@ func getEventsForCreateDoc(s *state, action CreateDoc) map[string]struct{} { return expect } + +// getEventsForUpdateWithFilter returns a map of docIDs that should be +// published to the local event bus after a UpdateWithFilter action. +// +// This will take into account any primary documents that are patched as a result +// of the create or update. +func getEventsForUpdateWithFilter( + s *state, + action UpdateWithFilter, + result *client.UpdateResult, +) map[string]struct{} { + var collection client.Collection + if action.NodeID.HasValue() { + collection = s.collections[action.NodeID.Value()][action.CollectionID] + } else { + collection = s.collections[0][action.CollectionID] + } + + var docPatch map[string]any + err := json.Unmarshal([]byte(action.Updater), &docPatch) + require.NoError(s.t, err) + + def := collection.Definition() + expect := make(map[string]struct{}) + + for _, docID := range result.DocIDs { + expect[docID] = struct{}{} + + // check for any secondary relation fields that could publish an event + for name, value := range docPatch { + field, ok := def.GetFieldByName(name) + if !ok { + continue // ignore unknown field + } + _, ok = field.GetSecondaryRelationField(def) + if ok { + expect[value.(string)] = struct{}{} + } + } + } + + return expect +} diff --git a/tests/integration/test_case.go b/tests/integration/test_case.go index 1ebf396253..930146c8bb 100644 --- a/tests/integration/test_case.go +++ b/tests/integration/test_case.go @@ -360,6 +360,43 @@ type UpdateDoc struct { SkipLocalUpdateEvent bool } +// UpdateWithFilter will update the set of documents that match the given filter. +type UpdateWithFilter struct { + // NodeID may hold the ID (index) of a node to apply this update to. + // + // If a value is not provided the update will be applied to all nodes. + NodeID immutable.Option[int] + + // The identity of this request. Optional. + // + // If an Identity is not provided then can only update public document(s). + // + // If an Identity is provided and the collection has a policy, then + // can also update private document(s) that are owned by this Identity. + Identity immutable.Option[int] + + // The collection in which this document exists. + CollectionID int + + // The filter to match documents against. + Filter any + + // The update to apply to matched documents. + Updater string + + // Any error expected from the action. Optional. + // + // String can be a partial, and the test will pass if an error is returned that + // contains this string. + ExpectedError string + + // Skip waiting for an update event on the local event bus. + // + // This should only be used for tests that do not correctly + // publish an update event to the local event bus. + SkipLocalUpdateEvent bool +} + // IndexField describes a field to be indexed. type IndexedField struct { // Name contains the name of the field. diff --git a/tests/integration/utils2.go b/tests/integration/utils2.go index 139b53652b..31a93a0281 100644 --- a/tests/integration/utils2.go +++ b/tests/integration/utils2.go @@ -308,6 +308,9 @@ func performAction( case UpdateDoc: updateDoc(s, action) + case UpdateWithFilter: + updateWithFilter(s, action) + case CreateIndex: createIndex(s, action) @@ -1469,6 +1472,34 @@ func updateDocViaGQL( return nil } +// updateWithFilter updates the set of matched documents. +func updateWithFilter(s *state, action UpdateWithFilter) { + var res *client.UpdateResult + var expectedErrorRaised bool + actionNodes := getNodes(action.NodeID, s.nodes) + for nodeID, collections := range getNodeCollections(action.NodeID, s.collections) { + identity := getIdentity(s, nodeID, action.Identity) + ctx := db.SetContextIdentity(s.ctx, identity) + + err := withRetry( + actionNodes, + nodeID, + func() error { + var err error + res, err = collections[action.CollectionID].UpdateWithFilter(ctx, action.Filter, action.Updater) + return err + }, + ) + expectedErrorRaised = AssertError(s.t, s.testCase.Description, err, action.ExpectedError) + } + + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) + + if action.ExpectedError == "" && !action.SkipLocalUpdateEvent { + waitForUpdateEvents(s, action.NodeID, getEventsForUpdateWithFilter(s, action, res)) + } +} + // createIndex creates a secondary index using the collection api. func createIndex( s *state, From 82659f8cd55f291d091bff0597d0084ef61a5b51 Mon Sep 17 00:00:00 2001 From: Keenan Nemetz Date: Fri, 26 Jul 2024 14:55:55 -0700 Subject: [PATCH 24/41] refactor(i): Subscription test results (#2874) ## Relevant issue(s) Resolves #2873 ## Description This PR is small refactor of the subscription tests to make it easier to test ordering of results and eventually multiple selections within the results. ## Tasks - [x] I made sure the code is well commented, particularly hard-to-understand areas. - [x] I made sure the repository-held documentation is changed accordingly. - [x] I made sure the pull request title adheres to the conventional commit style (the subset used in the project can be found in [tools/configs/chglog/config.yml](tools/configs/chglog/config.yml)). - [x] I made sure to discuss its limitations such as threats to validity, vulnerability to mistake and misuse, robustness to invalidation of assumptions, resource requirements, ... ## How has this been tested? `make test` Specify the platform(s) on which this was tested: - MacOS --- .../subscription/subscription_test.go | 64 +++++++++++-------- tests/integration/test_case.go | 2 +- tests/integration/utils2.go | 56 ++++++---------- 3 files changed, 60 insertions(+), 62 deletions(-) diff --git a/tests/integration/subscription/subscription_test.go b/tests/integration/subscription/subscription_test.go index 2de42f2793..dc7a91d7c6 100644 --- a/tests/integration/subscription/subscription_test.go +++ b/tests/integration/subscription/subscription_test.go @@ -28,16 +28,20 @@ func TestSubscriptionWithCreateMutations(t *testing.T) { age } }`, - Results: []map[string]any{ + Results: [][]map[string]any{ { - "_docID": "bae-b3ce089b-f543-5984-be9f-ad7d08969f4e", - "age": int64(27), - "name": "John", + { + "_docID": "bae-b3ce089b-f543-5984-be9f-ad7d08969f4e", + "age": int64(27), + "name": "John", + }, }, { - "_docID": "bae-bc20b854-10b3-5408-b28c-f273ddda9434", - "age": int64(31), - "name": "Addo", + { + "_docID": "bae-bc20b854-10b3-5408-b28c-f273ddda9434", + "age": int64(31), + "name": "Addo", + }, }, }, }, @@ -82,10 +86,12 @@ func TestSubscriptionWithFilterAndOneCreateMutation(t *testing.T) { age } }`, - Results: []map[string]any{ + Results: [][]map[string]any{ { - "age": int64(27), - "name": "John", + { + "age": int64(27), + "name": "John", + }, }, }, }, @@ -119,7 +125,7 @@ func TestSubscriptionWithFilterAndOneCreateMutationOutsideFilter(t *testing.T) { age } }`, - Results: []map[string]any{}, + Results: [][]map[string]any{}, }, testUtils.Request{ Request: `mutation { @@ -150,10 +156,12 @@ func TestSubscriptionWithFilterAndCreateMutations(t *testing.T) { age } }`, - Results: []map[string]any{ + Results: [][]map[string]any{ { - "age": int64(27), - "name": "John", + { + "age": int64(27), + "name": "John", + }, }, }, }, @@ -217,11 +225,13 @@ func TestSubscriptionWithUpdateMutations(t *testing.T) { points } }`, - Results: []map[string]any{ + Results: [][]map[string]any{ { - "age": int64(27), - "name": "John", - "points": float64(45), + { + "age": int64(27), + "name": "John", + "points": float64(45), + }, }, }, }, @@ -273,16 +283,20 @@ func TestSubscriptionWithUpdateAllMutations(t *testing.T) { points } }`, - Results: []map[string]any{ + Results: [][]map[string]any{ { - "age": int64(31), - "name": "Addo", - "points": float64(55), + { + "age": int64(31), + "name": "Addo", + "points": float64(55), + }, }, { - "age": int64(27), - "name": "John", - "points": float64(55), + { + "age": int64(27), + "name": "John", + "points": float64(55), + }, }, }, }, diff --git a/tests/integration/test_case.go b/tests/integration/test_case.go index 930146c8bb..a384318dd2 100644 --- a/tests/integration/test_case.go +++ b/tests/integration/test_case.go @@ -616,7 +616,7 @@ type SubscriptionRequest struct { Request string // The expected (data) results yielded through the subscription across its lifetime. - Results []map[string]any + Results [][]map[string]any // Any error expected from the action. Optional. // diff --git a/tests/integration/utils2.go b/tests/integration/utils2.go index 31a93a0281..a9bd8aa4c3 100644 --- a/tests/integration/utils2.go +++ b/tests/integration/utils2.go @@ -1752,50 +1752,34 @@ func executeSubscriptionRequest( } go func() { - data := []map[string]any{} - errs := []error{} - + var results []*client.GQLResult allActionsAreDone := false - expectedDataRecieved := len(action.Results) == 0 - for { + for !allActionsAreDone || len(results) < len(action.Results) { select { case s := <-result.Subscription: - sData, _ := s.Data.([]map[string]any) - errs = append(errs, s.Errors...) - data = append(data, sData...) - - if len(data) >= len(action.Results) { - expectedDataRecieved = true - } + results = append(results, &s) case <-s.allActionsDone: allActionsAreDone = true } + } - if expectedDataRecieved && allActionsAreDone { - finalResult := &client.GQLResult{ - Data: data, - Errors: errs, - } - - subscriptionAssert <- func() { - // This assert should be executed from the main test routine - // so that failures will be properly handled. - expectedErrorRaised := assertRequestResults( - s, - finalResult, - action.Results, - action.ExpectedError, - nil, - // anyof is not yet supported by subscription requests - 0, - map[docFieldKey][]any{}, - ) - - assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) - } - - return + subscriptionAssert <- func() { + for i, r := range action.Results { + // This assert should be executed from the main test routine + // so that failures will be properly handled. + expectedErrorRaised := assertRequestResults( + s, + results[i], + r, + action.ExpectedError, + nil, + // anyof is not yet supported by subscription requests + 0, + map[docFieldKey][]any{}, + ) + + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) } } }() From 8bd255ffe21fc59c049e11a3f335de78df15876a Mon Sep 17 00:00:00 2001 From: Keenan Nemetz Date: Tue, 30 Jul 2024 11:54:08 -0700 Subject: [PATCH 25/41] refactor: GQL responses (#2872) ## Relevant issue(s) Resolves #2869 ## Description This PR makes our GQL response types spec compliant. It also enables running multiple selections within `queries` and `mutations`. - [x] Update readme examples ## Tasks - [x] I made sure the code is well commented, particularly hard-to-understand areas. - [x] I made sure the repository-held documentation is changed accordingly. - [x] I made sure the pull request title adheres to the conventional commit style (the subset used in the project can be found in [tools/configs/chglog/config.yml](tools/configs/chglog/config.yml)). - [x] I made sure to discuss its limitations such as threats to validity, vulnerability to mistake and misuse, robustness to invalidation of assumptions, resource requirements, ... ## How has this been tested? `make test` Specify the platform(s) on which this was tested: - MacOS --- README.md | 66 +-- docs/website/getting-started.md | 52 +- docs/website/guides/explain-systems.md | 38 +- docs/website/guides/schema-relationship.md | 112 +++-- http/handler_ccip_test.go | 4 +- http/handler_store.go | 15 +- internal/db/collection_update.go | 10 +- internal/db/request.go | 2 - internal/db/subscriptions.go | 7 +- internal/planner/explain.go | 68 ++- internal/planner/mapper/errors.go | 1 + internal/planner/mapper/mapper.go | 80 ++- internal/planner/mapper/operation.go | 46 ++ internal/planner/operation.go | 167 +++++++ internal/planner/operations.go | 1 + internal/planner/planner.go | 147 +++--- tests/integration/acp/index/create_test.go | 7 +- tests/integration/acp/index/query_test.go | 28 +- .../acp/index/query_with_relation_test.go | 116 +++-- tests/integration/acp/p2p/replicator_test.go | 16 +- tests/integration/acp/p2p/subscribe_test.go | 16 +- tests/integration/acp/query/avg_test.go | 24 +- tests/integration/acp/query/count_test.go | 52 +- .../acp/query/relation_objects_test.go | 120 ++--- .../acp/register_and_delete_test.go | 36 +- .../integration/acp/register_and_read_test.go | 44 +- .../acp/register_and_update_test.go | 84 ++-- .../backup/one_to_many/import_test.go | 80 +-- .../backup/one_to_one/import_test.go | 94 ++-- .../backup/self_reference/import_test.go | 74 +-- .../integration/backup/simple/import_test.go | 58 ++- .../update/simple/with_filter_test.go | 12 +- .../updates/copy/name_test.go | 8 +- .../updates/move/name_test.go | 8 +- .../remove/col_source_transform_test.go | 8 +- .../replace/col_source_transform_test.go | 8 +- .../updates/replace/name_test.go | 16 +- .../replace/query_source_query_test.go | 16 +- .../replace/query_source_transform_test.go | 8 +- .../encryption/commit_relation_test.go | 62 +-- tests/integration/encryption/commit_test.go | 217 +++++---- .../encryption/field_commit_test.go | 54 ++- .../encryption/field_query_test.go | 12 +- tests/integration/encryption/peer_test.go | 80 +-- .../encryption/query_relation_test.go | 48 +- tests/integration/encryption/query_test.go | 32 +- tests/integration/explain.go | 52 +- tests/integration/explain/debug/basic_test.go | 2 +- .../integration/explain/debug/create_test.go | 16 +- .../integration/explain/debug/dagscan_test.go | 18 +- .../integration/explain/debug/delete_test.go | 24 +- tests/integration/explain/debug/fixture.go | 10 +- tests/integration/explain/debug/group_test.go | 18 +- .../explain/debug/group_with_average_test.go | 28 +- .../debug/group_with_doc_id_child_test.go | 2 +- .../explain/debug/group_with_doc_id_test.go | 4 +- .../debug/group_with_filter_child_test.go | 4 +- .../explain/debug/group_with_filter_test.go | 2 +- .../debug/group_with_limit_child_test.go | 4 +- .../explain/debug/group_with_limit_test.go | 20 +- .../debug/group_with_order_child_test.go | 6 +- .../explain/debug/group_with_order_test.go | 22 +- .../explain/debug/top_with_average_test.go | 34 +- .../explain/debug/top_with_count_test.go | 22 +- .../explain/debug/top_with_sum_test.go | 22 +- .../explain/debug/type_join_many_test.go | 16 +- .../explain/debug/type_join_one_test.go | 48 +- .../explain/debug/type_join_test.go | 36 +- .../type_join_with_filter_doc_id_test.go | 44 +- .../debug/type_join_with_filter_test.go | 44 +- .../integration/explain/debug/update_test.go | 20 +- .../explain/debug/with_average_join_test.go | 54 ++- .../explain/debug/with_average_test.go | 18 +- .../explain/debug/with_count_join_test.go | 46 +- .../explain/debug/with_count_test.go | 14 +- .../explain/debug/with_filter_doc_id_test.go | 10 +- .../explain/debug/with_filter_test.go | 12 +- .../explain/debug/with_limit_count_test.go | 62 +-- .../explain/debug/with_limit_join_test.go | 66 +-- .../explain/debug/with_limit_test.go | 18 +- .../explain/debug/with_order_join_test.go | 34 +- .../explain/debug/with_order_test.go | 16 +- .../explain/debug/with_sum_join_test.go | 48 +- .../explain/debug/with_sum_test.go | 14 +- .../explain/debug/with_view_test.go | 18 +- .../explain/debug/with_view_transform_test.go | 20 +- .../integration/explain/default/basic_test.go | 34 +- .../explain/default/create_test.go | 16 +- .../explain/default/dagscan_test.go | 18 +- .../explain/default/delete_test.go | 24 +- tests/integration/explain/default/fixture.go | 10 +- .../integration/explain/default/group_test.go | 16 +- .../default/group_with_average_test.go | 26 +- .../default/group_with_doc_id_child_test.go | 2 +- .../explain/default/group_with_doc_id_test.go | 4 +- .../default/group_with_filter_child_test.go | 4 +- .../explain/default/group_with_filter_test.go | 2 +- .../default/group_with_limit_child_test.go | 4 +- .../explain/default/group_with_limit_test.go | 18 +- .../default/group_with_order_child_test.go | 6 +- .../explain/default/group_with_order_test.go | 20 +- .../explain/default/top_with_average_test.go | 34 +- .../explain/default/top_with_count_test.go | 22 +- .../explain/default/top_with_sum_test.go | 22 +- .../explain/default/type_join_many_test.go | 14 +- .../explain/default/type_join_one_test.go | 42 +- .../explain/default/type_join_test.go | 30 +- .../type_join_with_filter_doc_id_test.go | 38 +- .../default/type_join_with_filter_test.go | 38 +- .../explain/default/update_test.go | 20 +- .../explain/default/with_average_join_test.go | 68 +-- .../explain/default/with_average_test.go | 18 +- .../explain/default/with_count_join_test.go | 82 ++-- .../explain/default/with_count_test.go | 14 +- .../default/with_filter_doc_id_test.go | 10 +- .../explain/default/with_filter_test.go | 12 +- .../explain/default/with_limit_count_test.go | 54 ++- .../explain/default/with_limit_join_test.go | 58 ++- .../explain/default/with_limit_test.go | 18 +- .../explain/default/with_order_join_test.go | 30 +- .../explain/default/with_order_test.go | 16 +- .../explain/default/with_sum_join_test.go | 42 +- .../explain/default/with_sum_test.go | 14 +- .../explain/execute/create_test.go | 36 +- .../explain/execute/dagscan_test.go | 52 +- .../explain/execute/delete_test.go | 72 +-- .../integration/explain/execute/group_test.go | 46 +- .../execute/query_deleted_docs_test.go | 38 +- .../integration/explain/execute/scan_test.go | 128 ++--- .../explain/execute/top_level_test.go | 148 +++--- .../explain/execute/type_join_test.go | 178 +++---- .../explain/execute/update_test.go | 76 +-- .../explain/execute/with_average_test.go | 96 ++-- .../explain/execute/with_count_test.go | 52 +- .../explain/execute/with_limit_test.go | 88 ++-- .../explain/execute/with_order_test.go | 172 +++---- .../explain/execute/with_sum_test.go | 88 ++-- .../integration/explain/simple/basic_test.go | 32 +- tests/integration/explain_result_asserter.go | 9 +- tests/integration/index/create_drop_test.go | 10 +- tests/integration/index/create_test.go | 20 +- tests/integration/index/create_unique_test.go | 4 +- tests/integration/index/drop_test.go | 10 +- tests/integration/index/index_p2p_test.go | 24 +- ...y_with_composite_index_field_order_test.go | 260 +++++----- ...y_with_composite_index_only_filter_test.go | 214 +++++--- ...uery_with_compound_filter_relation_test.go | 60 ++- .../query_with_index_combined_filter_test.go | 26 +- .../query_with_index_only_field_order_test.go | 72 +-- .../query_with_index_only_filter_test.go | 172 ++++--- .../index/query_with_relation_filter_test.go | 236 +++++---- ...with_unique_composite_index_filter_test.go | 280 +++++++---- ...uery_with_unique_index_only_filter_test.go | 188 ++++--- tests/integration/issues/2566_test.go | 48 +- .../mutation/create/crdt/pcounter_test.go | 12 +- .../mutation/create/crdt/pncounter_test.go | 12 +- .../field_kinds/field_kind_json_test.go | 12 +- .../one_to_many/with_alias_test.go | 58 ++- .../one_to_many/with_simple_test.go | 34 +- .../field_kinds/one_to_one/with_alias_test.go | 56 ++- .../one_to_one/with_simple_test.go | 56 ++- .../one_to_one_to_one/with_txn_test.go | 176 ++++--- .../create/simple_create_many_test.go | 22 +- .../mutation/create/simple_test.go | 24 +- .../mutation/create/with_version_test.go | 12 +- .../one_to_many/with_show_deleted_test.go | 40 +- .../one_to_one_to_one/with_id_test.go | 24 +- .../one_to_one_to_one/with_txn_test.go | 128 +++-- .../delete/with_deleted_field_test.go | 10 +- .../mutation/delete/with_filter_test.go | 50 +- .../mutation/delete/with_id_alias_test.go | 8 +- .../mutation/delete/with_id_test.go | 8 +- .../mutation/delete/with_id_txn_test.go | 12 +- .../mutation/delete/with_ids_alias_test.go | 14 +- .../mutation/delete/with_ids_filter_test.go | 8 +- .../mutation/delete/with_ids_test.go | 48 +- .../mutation/delete/with_ids_txn_test.go | 12 +- .../delete/with_ids_update_alias_test.go | 14 +- .../integration/mutation/mix/with_txn_test.go | 124 +++-- .../mutation/update/crdt/pcounter_test.go | 52 +- .../mutation/update/crdt/pncounter_test.go | 62 ++- .../update/field_kinds/array_bool_test.go | 40 +- .../update/field_kinds/array_float_test.go | 40 +- .../update/field_kinds/array_int_test.go | 48 +- .../field_kinds/array_nillable_bool_test.go | 18 +- .../field_kinds/array_nillable_float_test.go | 16 +- .../field_kinds/array_nillable_int_test.go | 18 +- .../field_kinds/array_nillable_string_test.go | 20 +- .../update/field_kinds/array_string_test.go | 52 +- .../mutation/update/field_kinds/blob_test.go | 16 +- .../mutation/update/field_kinds/bool_test.go | 8 +- .../update/field_kinds/date_time_test.go | 34 +- .../mutation/update/field_kinds/float_test.go | 8 +- .../mutation/update/field_kinds/int_test.go | 8 +- .../mutation/update/field_kinds/json_test.go | 8 +- .../field_kinds/one_to_many/simple_test.go | 54 ++- .../one_to_many/with_alias_test.go | 64 +-- .../one_to_one/with_self_ref_test.go | 76 +-- .../one_to_one/with_simple_test.go | 56 ++- .../update/field_kinds/string_test.go | 8 +- .../update/underscored_schema_test.go | 8 +- .../mutation/update/with_filter_test.go | 22 +- .../mutation/update/with_id_test.go | 14 +- .../mutation/update/with_ids_test.go | 18 +- .../peer/with_create_update_test.go | 32 +- .../replicator/with_create_test.go | 12 +- .../net/simple/peer/crdt/pcounter_test.go | 16 +- .../net/simple/peer/crdt/pncounter_test.go | 16 +- .../peer/subscribe/with_add_remove_test.go | 36 +- .../simple/peer/subscribe/with_add_test.go | 66 ++- .../simple/peer/with_create_add_field_test.go | 58 ++- .../net/simple/peer/with_create_test.go | 74 +-- .../net/simple/peer/with_delete_test.go | 122 ++--- .../simple/peer/with_update_add_field_test.go | 36 +- .../simple/peer/with_update_restart_test.go | 8 +- .../net/simple/peer/with_update_test.go | 108 +++-- .../peer_replicator/crdt/pcounter_test.go | 44 +- .../peer_replicator/crdt/pncounter_test.go | 44 +- .../peer_replicator/with_create_test.go | 36 +- .../peer_replicator/with_delete_test.go | 12 +- .../with_update_restart_test.go | 8 +- .../peer_replicator/with_update_test.go | 8 +- .../simple/replicator/crdt/pcounter_test.go | 8 +- .../simple/replicator/crdt/pncounter_test.go | 8 +- .../replicator/with_create_add_field_test.go | 26 +- .../replicator/with_create_restart_test.go | 8 +- .../net/simple/replicator/with_create_test.go | 112 +++-- .../replicator/with_create_update_test.go | 24 +- .../net/simple/replicator/with_delete_test.go | 24 +- .../replicator/with_update_add_field_test.go | 36 +- .../net/simple/replicator/with_update_test.go | 16 +- .../integration/query/commits/simple_test.go | 324 +++++++------ .../query/commits/with_cid_test.go | 28 +- .../with_collectionid_group_order_test.go | 28 +- .../commits/with_collectionid_prop_test.go | 32 +- .../query/commits/with_depth_test.go | 140 +++--- .../query/commits/with_doc_id_cid_test.go | 16 +- .../query/commits/with_doc_id_count_test.go | 26 +- .../query/commits/with_doc_id_field_test.go | 28 +- .../commits/with_doc_id_group_order_test.go | 14 +- .../commits/with_doc_id_limit_offset_test.go | 14 +- .../query/commits/with_doc_id_limit_test.go | 14 +- .../with_doc_id_order_limit_offset_test.go | 18 +- .../query/commits/with_doc_id_order_test.go | 242 ++++----- .../query/commits/with_doc_id_prop_test.go | 20 +- .../query/commits/with_doc_id_test.go | 182 +++---- .../commits/with_doc_id_typename_test.go | 26 +- .../query/commits/with_field_test.go | 30 +- .../query/commits/with_group_test.go | 250 +++++----- .../query/inline_array/simple_test.go | 226 +++++---- .../inline_array/with_average_filter_test.go | 40 +- .../inline_array/with_average_sum_test.go | 12 +- .../query/inline_array/with_average_test.go | 101 ++-- .../inline_array/with_count_filter_test.go | 90 ++-- .../with_count_limit_offset_test.go | 20 +- .../inline_array/with_count_limit_test.go | 20 +- .../query/inline_array/with_count_test.go | 40 +- .../query/inline_array/with_group_test.go | 52 +- .../inline_array/with_sum_filter_test.go | 40 +- .../with_sum_limit_offset_order_test.go | 96 ++-- .../with_sum_limit_offset_test.go | 10 +- .../query/inline_array/with_sum_limit_test.go | 10 +- .../query/inline_array/with_sum_test.go | 80 +-- .../with_collectionid_prop_test.go | 16 +- .../latest_commits/with_doc_id_field_test.go | 38 +- .../latest_commits/with_doc_id_prop_test.go | 8 +- .../query/latest_commits/with_doc_id_test.go | 34 +- .../query/one_to_many/simple_test.go | 70 +-- .../query/one_to_many/with_cid_doc_id_test.go | 54 ++- .../one_to_many/with_count_filter_test.go | 54 ++- .../with_count_limit_offset_test.go | 86 ++-- .../one_to_many/with_count_limit_test.go | 78 +-- .../query/one_to_many/with_count_test.go | 28 +- .../query/one_to_many/with_doc_id_test.go | 14 +- .../query/one_to_many/with_doc_ids_test.go | 20 +- .../with_filter_related_id_test.go | 38 +- .../query/one_to_many/with_filter_test.go | 134 ++--- .../one_to_many/with_group_filter_test.go | 154 +++--- .../with_group_related_id_alias_test.go | 458 +++++++++--------- .../one_to_many/with_group_related_id_test.go | 208 ++++---- .../query/one_to_many/with_group_test.go | 140 +++--- .../query/one_to_many/with_limit_test.go | 88 ++-- .../with_order_filter_limit_test.go | 36 +- .../one_to_many/with_order_filter_test.go | 68 +-- .../query/one_to_many/with_related_id_test.go | 50 +- .../one_to_many/with_same_field_name_test.go | 26 +- .../one_to_many/with_sum_filter_order_test.go | 232 ++++----- .../with_sum_limit_offset_order_test.go | 130 ++--- .../one_to_many/with_sum_limit_offset_test.go | 18 +- .../query/one_to_many/with_sum_limit_test.go | 20 +- .../query/one_to_many/with_typename_test.go | 16 +- .../with_average_filter_test.go | 36 +- .../one_to_many_multiple/with_average_test.go | 18 +- .../with_count_filter_test.go | 36 +- .../one_to_many_multiple/with_count_test.go | 40 +- .../with_multiple_filter_test.go | 8 +- .../with_sum_filter_test.go | 36 +- .../one_to_many_multiple/with_sum_test.go | 18 +- .../query/one_to_many_to_many/joins_test.go | 126 ++--- .../query/one_to_many_to_one/joins_test.go | 108 +++-- .../query/one_to_many_to_one/simple_test.go | 46 +- .../one_to_many_to_one/with_filter_test.go | 202 ++++---- .../with_order_limit_test.go | 52 +- .../one_to_many_to_one/with_order_test.go | 164 ++++--- .../with_sum_order_limit_test.go | 180 +++---- .../query/one_to_many_to_one/with_sum_test.go | 22 +- .../query/one_to_one/simple_test.go | 116 +++-- .../one_to_one/with_clashing_id_field_test.go | 14 +- .../one_to_one/with_count_filter_test.go | 6 +- .../one_to_one/with_filter_order_test.go | 36 +- .../query/one_to_one/with_filter_test.go | 162 ++++--- .../with_group_related_id_alias_test.go | 138 +++--- .../one_to_one/with_group_related_id_test.go | 126 ++--- .../query/one_to_one/with_order_test.go | 96 ++-- .../query/one_to_one_multiple/simple_test.go | 102 ++-- .../query/one_to_one_to_many/simple_test.go | 68 +-- .../query/one_to_one_to_one/simple_test.go | 120 ++--- .../one_to_one_to_one/with_order_test.go | 30 +- .../query/one_to_two_many/simple_test.go | 288 +++++------ .../query/one_to_two_many/with_order_test.go | 60 +-- tests/integration/query/simple/simple_test.go | 72 +-- .../query/simple/with_average_filter_test.go | 12 +- .../query/simple/with_average_test.go | 12 +- .../query/simple/with_cid_doc_id_test.go | 86 ++-- .../query/simple/with_count_filter_test.go | 12 +- .../query/simple/with_count_test.go | 12 +- .../query/simple/with_deleted_field_test.go | 18 +- .../query/simple/with_doc_id_filter_test.go | 10 +- .../query/simple/with_doc_id_test.go | 24 +- .../query/simple/with_doc_ids_test.go | 46 +- .../query/simple/with_filter/with_and_test.go | 18 +- .../simple/with_filter/with_eq_blob_test.go | 6 +- .../with_filter/with_eq_datetime_test.go | 24 +- .../simple/with_filter/with_eq_float_test.go | 20 +- .../simple/with_filter/with_eq_int_test.go | 20 +- .../simple/with_filter/with_eq_json_test.go | 6 +- .../simple/with_filter/with_eq_string_test.go | 40 +- .../with_filter/with_ge_datetime_test.go | 34 +- .../simple/with_filter/with_ge_float_test.go | 38 +- .../simple/with_filter/with_ge_int_test.go | 30 +- .../with_filter/with_gt_datetime_test.go | 28 +- .../simple/with_filter/with_gt_float_test.go | 42 +- .../simple/with_filter/with_gt_int_test.go | 40 +- .../simple/with_filter/with_in_blob_test.go | 6 +- .../simple/with_filter/with_in_json_test.go | 6 +- .../query/simple/with_filter/with_in_test.go | 58 ++- .../with_filter/with_le_datetime_test.go | 24 +- .../simple/with_filter/with_le_float_test.go | 32 +- .../simple/with_filter/with_le_int_test.go | 24 +- .../simple/with_filter/with_like_blob_test.go | 6 +- .../simple/with_filter/with_like_json_test.go | 6 +- .../with_filter/with_like_string_test.go | 106 ++-- .../with_filter/with_lt_datetime_test.go | 12 +- .../simple/with_filter/with_lt_float_test.go | 20 +- .../simple/with_filter/with_lt_int_test.go | 12 +- .../simple/with_filter/with_ne_bool_test.go | 42 +- .../with_filter/with_ne_datetime_test.go | 22 +- .../simple/with_filter/with_ne_float_test.go | 22 +- .../simple/with_filter/with_ne_int_test.go | 22 +- .../simple/with_filter/with_ne_string_test.go | 22 +- .../query/simple/with_filter/with_nin_test.go | 14 +- .../with_filter/with_nlike_string_test.go | 112 +++-- .../query/simple/with_filter/with_not_test.go | 92 ++-- .../query/simple/with_filter/with_or_test.go | 18 +- .../simple/with_group_average_count_test.go | 22 +- .../simple/with_group_average_filter_test.go | 212 ++++---- .../with_group_average_limit_offset_test.go | 18 +- .../simple/with_group_average_limit_test.go | 18 +- .../simple/with_group_average_sum_test.go | 80 +-- .../query/simple/with_group_average_test.go | 290 +++++------ .../simple/with_group_count_filter_test.go | 128 ++--- .../with_group_count_limit_offset_test.go | 54 ++- .../simple/with_group_count_limit_test.go | 54 ++- .../query/simple/with_group_count_sum_test.go | 58 +-- .../query/simple/with_group_count_test.go | 98 ++-- .../query/simple/with_group_doc_id_test.go | 22 +- .../query/simple/with_group_doc_ids_test.go | 28 +- .../query/simple/with_group_filter_test.go | 176 +++---- .../simple/with_group_limit_offset_test.go | 32 +- .../query/simple/with_group_limit_test.go | 120 ++--- .../query/simple/with_group_order_test.go | 280 +++++------ .../simple/with_group_sum_filter_test.go | 128 ++--- .../with_group_sum_limit_offset_test.go | 18 +- .../query/simple/with_group_sum_limit_test.go | 18 +- .../query/simple/with_group_sum_test.go | 290 +++++------ .../query/simple/with_group_test.go | 438 +++++++++-------- .../query/simple/with_group_typename_test.go | 24 +- .../query/simple/with_limit_offset_test.go | 106 ++-- .../query/simple/with_multiple_types_test.go | 40 +- .../query/simple/with_operation_alias_test.go | 49 ++ .../query/simple/with_order_filter_test.go | 18 +- .../query/simple/with_order_test.go | 204 ++++---- .../query/simple/with_restart_test.go | 10 +- .../query/simple/with_sum_filter_test.go | 6 +- .../integration/query/simple/with_sum_test.go | 12 +- .../query/simple/with_typename_test.go | 22 +- .../query/simple/with_version_test.go | 238 ++++----- .../schema/migrations/query/simple_test.go | 190 +++++--- .../migrations/query/with_doc_id_test.go | 70 +-- .../migrations/query/with_inverse_test.go | 12 +- .../query/with_p2p_schema_branch_test.go | 26 +- .../schema/migrations/query/with_p2p_test.go | 72 +-- .../migrations/query/with_restart_test.go | 20 +- .../query/with_schema_branch_test.go | 14 +- .../migrations/query/with_set_default_test.go | 34 +- .../schema/migrations/query/with_txn_test.go | 20 +- .../migrations/query/with_update_test.go | 42 +- .../schema/updates/add/field/crdt/lww_test.go | 4 +- .../updates/add/field/crdt/none_test.go | 8 +- .../updates/add/field/crdt/pcounter_test.go | 4 +- .../updates/add/field/crdt/pncounter_test.go | 4 +- .../schema/updates/add/field/create_test.go | 30 +- .../updates/add/field/create_update_test.go | 58 ++- .../updates/add/field/kind/blob_test.go | 24 +- .../updates/add/field/kind/bool_array_test.go | 24 +- .../add/field/kind/bool_nil_array_test.go | 24 +- .../updates/add/field/kind/bool_test.go | 24 +- .../updates/add/field/kind/datetime_test.go | 24 +- .../updates/add/field/kind/doc_id_test.go | 24 +- .../add/field/kind/float_array_test.go | 24 +- .../add/field/kind/float_nil_array_test.go | 36 +- .../updates/add/field/kind/float_test.go | 24 +- .../add/field/kind/foreign_object_test.go | 18 +- .../updates/add/field/kind/int_array_test.go | 24 +- .../add/field/kind/int_nil_array_test.go | 36 +- .../schema/updates/add/field/kind/int_test.go | 24 +- .../updates/add/field/kind/json_test.go | 24 +- .../add/field/kind/string_array_test.go | 24 +- .../add/field/kind/string_nil_array_test.go | 36 +- .../updates/add/field/kind/string_test.go | 24 +- .../schema/updates/add/field/simple_test.go | 20 +- .../updates/add/field/with_filter_test.go | 12 +- .../updates/add/field/with_index_sub_test.go | 12 +- .../updates/add/field/with_index_test.go | 4 +- .../schema/updates/add/simple_test.go | 12 +- .../schema/updates/copy/field/simple_test.go | 20 +- .../schema/updates/move/simple_test.go | 26 +- .../schema/updates/remove/simple_test.go | 4 +- .../schema/updates/test/add_field_test.go | 4 +- .../schema/updates/with_schema_branch_test.go | 16 +- .../schema/with_update_set_default_test.go | 4 +- .../subscription/subscription_test.go | 148 +++--- tests/integration/test_case.go | 10 +- tests/integration/utils.go | 2 +- tests/integration/utils2.go | 68 ++- .../view/one_to_many/simple_test.go | 36 +- .../view/one_to_many/with_alias_test.go | 28 +- .../view/one_to_many/with_count_test.go | 18 +- .../view/one_to_many/with_transform_test.go | 34 +- .../view/one_to_one/identical_schema_test.go | 12 +- .../view/one_to_one/with_transform_test.go | 12 +- tests/integration/view/simple/simple_test.go | 46 +- .../view/simple/with_alias_test.go | 8 +- .../view/simple/with_filter_test.go | 18 +- .../view/simple/with_transform_test.go | 66 +-- 455 files changed, 13087 insertions(+), 10074 deletions(-) create mode 100644 internal/planner/mapper/operation.go create mode 100644 internal/planner/operation.go create mode 100644 tests/integration/query/simple/with_operation_alias_test.go diff --git a/README.md b/README.md index 6e1f2b3d1a..f61ec5d34d 100644 --- a/README.md +++ b/README.md @@ -151,11 +151,13 @@ Expected response: ```json { - "data": [ - { - "_docID": "bae-91171025-ed21-50e3-b0dc-e31bccdfa1ab", - } - ] + "data": { + "create_User": [ + { + "_docID": "bae-91171025-ed21-50e3-b0dc-e31bccdfa1ab", + } + ] + } } ``` @@ -223,37 +225,39 @@ It returns a structure similar to the following, which contains the update paylo ```json { - "data": [ - { - "cid": "bafybeifhtfs6vgu7cwbhkojneh7gghwwinh5xzmf7nqkqqdebw5rqino7u", - "delta": "pGNhZ2UYH2RuYW1lY0JvYmZwb2ludHMYWmh2ZXJpZmllZPU=", - "height": 1, - "links": [ - { - "cid": "bafybeiet6foxcipesjurdqi4zpsgsiok5znqgw4oa5poef6qtiby5hlpzy", - "name": "age" - }, - { - "cid": "bafybeielahxy3r3ulykwoi5qalvkluojta4jlg6eyxvt7lbon3yd6ignby", - "name": "name" - }, - { - "cid": "bafybeia3tkpz52s3nx4uqadbm7t5tir6gagkvjkgipmxs2xcyzlkf4y4dm", - "name": "points" - }, - { - "cid": "bafybeia4off4javopmxcdyvr6fgb5clo7m5bblxic5sqr2vd52s6khyksm", - "name": "verified" - } - ] - } - ] + "data": { + "latestCommits": [ + { + "cid": "bafybeifhtfs6vgu7cwbhkojneh7gghwwinh5xzmf7nqkqqdebw5rqino7u", + "delta": "pGNhZ2UYH2RuYW1lY0JvYmZwb2ludHMYWmh2ZXJpZmllZPU=", + "height": 1, + "links": [ + { + "cid": "bafybeiet6foxcipesjurdqi4zpsgsiok5znqgw4oa5poef6qtiby5hlpzy", + "name": "age" + }, + { + "cid": "bafybeielahxy3r3ulykwoi5qalvkluojta4jlg6eyxvt7lbon3yd6ignby", + "name": "name" + }, + { + "cid": "bafybeia3tkpz52s3nx4uqadbm7t5tir6gagkvjkgipmxs2xcyzlkf4y4dm", + "name": "points" + }, + { + "cid": "bafybeia4off4javopmxcdyvr6fgb5clo7m5bblxic5sqr2vd52s6khyksm", + "name": "verified" + } + ] + } + ] + } } ``` Obtain a specific commit by its content identifier (`cid`): -```gql +```shell defradb client query ' query { commits(cid: "bafybeifhtfs6vgu7cwbhkojneh7gghwwinh5xzmf7nqkqqdebw5rqino7u") { diff --git a/docs/website/getting-started.md b/docs/website/getting-started.md index 739f27b893..ad1230fea6 100644 --- a/docs/website/getting-started.md +++ b/docs/website/getting-started.md @@ -153,31 +153,33 @@ It returns a structure similar to the following, which contains the update paylo ```json { - "data": [ - { - "cid": "bafybeifhtfs6vgu7cwbhkojneh7gghwwinh5xzmf7nqkqqdebw5rqino7u", - "delta": "pGNhZ2UYH2RuYW1lY0JvYmZwb2ludHMYWmh2ZXJpZmllZPU=", - "height": 1, - "links": [ - { - "cid": "bafybeiet6foxcipesjurdqi4zpsgsiok5znqgw4oa5poef6qtiby5hlpzy", - "name": "age" - }, - { - "cid": "bafybeielahxy3r3ulykwoi5qalvkluojta4jlg6eyxvt7lbon3yd6ignby", - "name": "name" - }, - { - "cid": "bafybeia3tkpz52s3nx4uqadbm7t5tir6gagkvjkgipmxs2xcyzlkf4y4dm", - "name": "points" - }, - { - "cid": "bafybeia4off4javopmxcdyvr6fgb5clo7m5bblxic5sqr2vd52s6khyksm", - "name": "verified" - } - ] - } - ] + "data": { + "latestCommits": [ + { + "cid": "bafybeifhtfs6vgu7cwbhkojneh7gghwwinh5xzmf7nqkqqdebw5rqino7u", + "delta": "pGNhZ2UYH2RuYW1lY0JvYmZwb2ludHMYWmh2ZXJpZmllZPU=", + "height": 1, + "links": [ + { + "cid": "bafybeiet6foxcipesjurdqi4zpsgsiok5znqgw4oa5poef6qtiby5hlpzy", + "name": "age" + }, + { + "cid": "bafybeielahxy3r3ulykwoi5qalvkluojta4jlg6eyxvt7lbon3yd6ignby", + "name": "name" + }, + { + "cid": "bafybeia3tkpz52s3nx4uqadbm7t5tir6gagkvjkgipmxs2xcyzlkf4y4dm", + "name": "points" + }, + { + "cid": "bafybeia4off4javopmxcdyvr6fgb5clo7m5bblxic5sqr2vd52s6khyksm", + "name": "verified" + } + ] + } + ] + } } ``` diff --git a/docs/website/guides/explain-systems.md b/docs/website/guides/explain-systems.md index a1d770fc2e..c185afd003 100644 --- a/docs/website/guides/explain-systems.md +++ b/docs/website/guides/explain-systems.md @@ -134,26 +134,24 @@ query @explain(type: execute) { ```json // Response -[ - { - "explain": { - "executionSuccess": true, - "sizeOfResult": 1, - "planExecutions": 2, - "selectTopNode": { - "selectNode": { - "iterations": 2, - "filterMatches": 1, - "scanNode": { - "iterations": 2, - "docFetches": 2, - "filterMatches": 1 - } - } - } - } - } -] +{ + "explain": { + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": 2, + "selectTopNode": { + "selectNode": { + "iterations": 2, + "filterMatches": 1, + "scanNode": { + "iterations": 2, + "docFetches": 2, + "filterMatches": 1 + } + } + } + } +} ``` Because Execute Explain actually executes the plan, it will of course take more time to complete and return results than the Simple Explain. It will actually take slightly longer to execute than the non-explain counterpart, as it has the overhead of measuring and collecting information. diff --git a/docs/website/guides/schema-relationship.md b/docs/website/guides/schema-relationship.md index 5eb77dc8d4..073932970f 100644 --- a/docs/website/guides/schema-relationship.md +++ b/docs/website/guides/schema-relationship.md @@ -234,23 +234,25 @@ query { ```json // Results: -[ - { - "name": "Saadi Shirazi", - "dateOfBirth": "1210-07-23T03:46:56.647Z", - "authoredBooks": [ - { - "name": "Gulistan", - "genre": "Poetry", - "description": "Persian poetry of ideas" - }, - { - "name": "Bustan", - "genre": "Poetry" - } - ] - } -] +{ + "Author": [ + { + "name": "Saadi Shirazi", + "dateOfBirth": "1210-07-23T03:46:56.647Z", + "authoredBooks": [ + { + "name": "Gulistan", + "genre": "Poetry", + "description": "Persian poetry of ideas" + }, + { + "name": "Bustan", + "genre": "Poetry" + } + ] + } + ] +} ``` ```graphql @@ -268,24 +270,26 @@ query { ```json // Results: -[ - { - "name": "Gulistan", - "genre": "Poetry", - "Author": { - "name": "Saadi Shirazi", - "dateOfBirth": "1210-07-23T03:46:56.647Z", - } - }, - { - "name": "Bustan", - "genre": "Poetry", - "Author": { - "name": "Saadi Shirazi", - "dateOfBirth": "1210-07-23T03:46:56.647Z", +{ + "Book": [ + { + "name": "Gulistan", + "genre": "Poetry", + "Author": { + "name": "Saadi Shirazi", + "dateOfBirth": "1210-07-23T03:46:56.647Z", + } + }, + { + "name": "Bustan", + "genre": "Poetry", + "Author": { + "name": "Saadi Shirazi", + "dateOfBirth": "1210-07-23T03:46:56.647Z", + } } - } -] + ] +} ``` ```graphql @@ -303,18 +307,20 @@ query { ```json // Results: -[ - { - "name": "Saadi Shirazi", - "dateOfBirth": "1210-07-23T03:46:56.647Z", - "authoredBooks": [ - { - "name": "Gulistan", - "genre": "Poetry" - } - ] - } -] +{ + "Author": [ + { + "name": "Saadi Shirazi", + "dateOfBirth": "1210-07-23T03:46:56.647Z", + "authoredBooks": [ + { + "name": "Gulistan", + "genre": "Poetry" + } + ] + } + ] +} ``` ```graphql @@ -330,12 +336,14 @@ query { ```json // Results: -[ - { - "name": "Saadi Shirazi", - "dateOfBirth": "1210-07-23T03:46:56.647Z" - } -] +{ + "Author": [ + { + "name": "Saadi Shirazi", + "dateOfBirth": "1210-07-23T03:46:56.647Z" + } + ] +} ``` Note: diff --git a/http/handler_ccip_test.go b/http/handler_ccip_test.go index d35a910161..43797b622d 100644 --- a/http/handler_ccip_test.go +++ b/http/handler_ccip_test.go @@ -67,7 +67,7 @@ func TestCCIPGet_WithValidData(t *testing.T) { resHex, err := hex.DecodeString(strings.TrimPrefix(ccipRes.Data, "0x")) require.NoError(t, err) - assert.JSONEq(t, `{"data": [{"name": "bob"}]}`, string(resHex)) + assert.JSONEq(t, `{"data": {"User": [{"name": "bob"}]}}`, string(resHex)) } func TestCCIPGet_WithSubscription(t *testing.T) { @@ -153,7 +153,7 @@ func TestCCIPPost_WithValidData(t *testing.T) { resHex, err := hex.DecodeString(strings.TrimPrefix(ccipRes.Data, "0x")) require.NoError(t, err) - assert.JSONEq(t, `{"data": [{"name": "bob"}]}`, string(resHex)) + assert.JSONEq(t, `{"data": {"User": [{"name": "bob"}]}}`, string(resHex)) } func TestCCIPPost_WithInvalidGraphQLRequest(t *testing.T) { diff --git a/http/handler_store.go b/http/handler_store.go index de534a8c1d..f9438d443f 100644 --- a/http/handler_store.go +++ b/http/handler_store.go @@ -267,6 +267,7 @@ func (res *GraphQLResponse) UnmarshalJSON(data []byte) error { if err := dec.Decode(&out); err != nil { return err } + res.Data = out["data"] // fix errors type to match tests switch t := out["errors"].(type) { @@ -278,20 +279,6 @@ func (res *GraphQLResponse) UnmarshalJSON(data []byte) error { res.Errors = nil } - // fix data type to match tests - switch t := out["data"].(type) { - case []any: - var fixed []map[string]any - for _, v := range t { - fixed = append(fixed, v.(map[string]any)) - } - res.Data = fixed - case map[string]any: - res.Data = t - default: - res.Data = []map[string]any{} - } - return nil } diff --git a/internal/db/collection_update.go b/internal/db/collection_update.go index 612d47a883..d29e562977 100644 --- a/internal/db/collection_update.go +++ b/internal/db/collection_update.go @@ -259,15 +259,7 @@ func (c *collection) makeSelectionPlan( txn, ) - return planner.MakePlan(&request.Request{ - Queries: []*request.OperationDefinition{ - { - Selections: []request.Selection{ - slct, - }, - }, - }, - }) + return planner.MakeSelectionPlan(slct) } func (c *collection) makeSelectLocal(filter immutable.Option[request.Filter]) (*request.Select, error) { diff --git a/internal/db/request.go b/internal/db/request.go index e5ba3d5cf5..b7d77185fb 100644 --- a/internal/db/request.go +++ b/internal/db/request.go @@ -53,9 +53,7 @@ func (db *db) execRequest(ctx context.Context, request string) *client.RequestRe results, err := planner.RunRequest(ctx, parsedRequest) if err != nil { res.GQL.Errors = []error{err} - return res } - res.GQL.Data = results return res } diff --git a/internal/db/subscriptions.go b/internal/db/subscriptions.go index 491ae44468..03fe41cc25 100644 --- a/internal/db/subscriptions.go +++ b/internal/db/subscriptions.go @@ -70,17 +70,16 @@ func (db *db) handleSubscription(ctx context.Context, r *request.Request) (<-cha p := planner.New(ctx, identity, db.acp, db, txn) s := subRequest.ToSelect(evt.DocID, evt.Cid.String()) - result, err := p.RunSubscriptionRequest(ctx, s) + result, err := p.RunSelection(ctx, s) if err == nil && len(result) == 0 { txn.Discard(ctx) continue // Don't send anything back to the client if the request yields an empty dataset. } - res := client.GQLResult{ - Data: result, - } + res := client.GQLResult{} if err != nil { res.Errors = []error{err} } + res.Data = result select { case <-ctx.Done(): diff --git a/internal/planner/explain.go b/internal/planner/explain.go index 34c3b3b644..1f17968489 100644 --- a/internal/planner/explain.go +++ b/internal/planner/explain.go @@ -344,18 +344,16 @@ func collectExecuteExplainInfo(executedPlan planNode) (map[string]any, error) { func (p *Planner) executeAndExplainRequest( _ context.Context, plan planNode, -) ([]map[string]any, error) { +) (map[string]any, error) { executionSuccess := false planExecutions := uint64(0) if err := plan.Start(); err != nil { - return []map[string]any{ - { - request.ExplainLabel: map[string]any{ - "executionSuccess": executionSuccess, - "executionErrors": []string{"plan failed to start"}, - "planExecutions": planExecutions, - }, + return map[string]any{ + request.ExplainLabel: map[string]any{ + "executionSuccess": executionSuccess, + "executionErrors": []string{"plan failed to start"}, + "planExecutions": planExecutions, }, }, nil } @@ -363,16 +361,14 @@ func (p *Planner) executeAndExplainRequest( next, err := plan.Next() planExecutions++ if err != nil { - return []map[string]any{ - { - request.ExplainLabel: map[string]any{ - "executionSuccess": executionSuccess, - "executionErrors": []string{ - "failure at plan execution count: " + strconv.FormatUint(planExecutions, 10), - err.Error(), - }, - "planExecutions": planExecutions, + return map[string]any{ + request.ExplainLabel: map[string]any{ + "executionSuccess": executionSuccess, + "executionErrors": []string{ + "failure at plan execution count: " + strconv.FormatUint(planExecutions, 10), + err.Error(), }, + "planExecutions": planExecutions, }, }, nil } @@ -388,17 +384,15 @@ func (p *Planner) executeAndExplainRequest( planExecutions++ if err != nil { - return []map[string]any{ - { - request.ExplainLabel: map[string]any{ - "executionSuccess": executionSuccess, - "executionErrors": []string{ - "failure at plan execution count: " + strconv.FormatUint(planExecutions, 10), - err.Error(), - }, - "planExecutions": planExecutions, - "sizeOfResultSoFar": len(docs), + return map[string]any{ + request.ExplainLabel: map[string]any{ + "executionSuccess": executionSuccess, + "executionErrors": []string{ + "failure at plan execution count: " + strconv.FormatUint(planExecutions, 10), + err.Error(), }, + "planExecutions": planExecutions, + "sizeOfResultSoFar": len(docs), }, }, nil } @@ -414,10 +408,8 @@ func (p *Planner) executeAndExplainRequest( executeExplain["planExecutions"] = planExecutions executeExplain["sizeOfResult"] = len(docs) - return []map[string]any{ - { - request.ExplainLabel: executeExplain, - }, + return map[string]any{ + request.ExplainLabel: executeExplain, }, err } @@ -426,7 +418,7 @@ func (p *Planner) explainRequest( ctx context.Context, plan planNode, explainType request.ExplainType, -) ([]map[string]any, error) { +) (map[string]any, error) { switch explainType { case request.SimpleExplain: // walks through the plan graph, and outputs the concrete planNodes that should @@ -436,10 +428,8 @@ func (p *Planner) explainRequest( return nil, err } - explainResult := []map[string]any{ - { - request.ExplainLabel: explainGraph, - }, + explainResult := map[string]any{ + request.ExplainLabel: explainGraph, } return explainResult, nil @@ -452,10 +442,8 @@ func (p *Planner) explainRequest( return nil, err } - explainResult := []map[string]any{ - { - request.ExplainLabel: explainGraph, - }, + explainResult := map[string]any{ + request.ExplainLabel: explainGraph, } return explainResult, nil diff --git a/internal/planner/mapper/errors.go b/internal/planner/mapper/errors.go index b7477274a1..43f7f56a7a 100644 --- a/internal/planner/mapper/errors.go +++ b/internal/planner/mapper/errors.go @@ -23,6 +23,7 @@ var ( ErrFailedToFindHostField = errors.New("failed to find host field") ErrInvalidFieldIndex = errors.New("given field doesn't have any indexes") ErrMissingSelect = errors.New("missing target select field") + ErrInvalidSelect = errors.New("select type is invalid") ) func NewErrInvalidFieldToGroupBy(field string) error { diff --git a/internal/planner/mapper/mapper.go b/internal/planner/mapper/mapper.go index 195e895ffd..7542449727 100644 --- a/internal/planner/mapper/mapper.go +++ b/internal/planner/mapper/mapper.go @@ -41,7 +41,54 @@ const ( CommitSelection ) -// ToSelect converts the given [parser.Select] into a [Select]. +// ToOperation converts the given [request.OperationDefinition] into an [Operation]. +// +// In the process of doing so it will construct the document map required to access the data +// yielded by the [Operation]. +func ToOperation( + ctx context.Context, + store client.Store, + operationRequest *request.OperationDefinition, +) (*Operation, error) { + operation := &Operation{ + DocumentMapping: core.NewDocumentMapping(), + } + + for i, s := range operationRequest.Selections { + switch t := s.(type) { + case *request.CommitSelect: + s, err := toCommitSelect(ctx, store, t, i) + if err != nil { + return nil, err + } + operation.CommitSelects = append(operation.CommitSelects, s) + operation.addSelection(i, t.Field, s.Select) + + case *request.Select: + s, err := toSelect(ctx, store, ObjectSelection, i, t, "") + if err != nil { + return nil, err + } + operation.Selects = append(operation.Selects, s) + operation.addSelection(i, t.Field, *s) + + case *request.ObjectMutation: + m, err := toMutation(ctx, store, t, i) + if err != nil { + return nil, err + } + operation.Mutations = append(operation.Mutations, m) + operation.addSelection(i, t.Field, m.Select) + + default: + return nil, ErrInvalidSelect + } + } + + return operation, nil +} + +// ToSelect converts the given [request.Select] into a [Select]. // // In the process of doing so it will construct the document map required to access the data // yielded by the [Select]. @@ -1142,7 +1189,20 @@ func ToCommitSelect( store client.Store, selectRequest *request.CommitSelect, ) (*CommitSelect, error) { - underlyingSelect, err := ToSelect(ctx, store, CommitSelection, selectRequest.ToSelect()) + return toCommitSelect(ctx, store, selectRequest, 0) +} + +// toCommitSelect converts the given [request.CommitSelect] into a [CommitSelect]. +// +// In the process of doing so it will construct the document map required to access the data +// yielded by the [Select] embedded in the [CommitSelect]. +func toCommitSelect( + ctx context.Context, + store client.Store, + selectRequest *request.CommitSelect, + thisIndex int, +) (*CommitSelect, error) { + underlyingSelect, err := toSelect(ctx, store, CommitSelection, thisIndex, selectRequest.ToSelect(), "") if err != nil { return nil, err } @@ -1160,11 +1220,23 @@ func ToCommitSelect( // In the process of doing so it will construct the document map required to access the data // yielded by the [Select] embedded in the [Mutation]. func ToMutation(ctx context.Context, store client.Store, mutationRequest *request.ObjectMutation) (*Mutation, error) { - underlyingSelect, err := ToSelect(ctx, store, ObjectSelection, mutationRequest.ToSelect()) + return toMutation(ctx, store, mutationRequest, 0) +} + +// toMutation converts the given [request.Mutation] into a [Mutation]. +// +// In the process of doing so it will construct the document map required to access the data +// yielded by the [Select] embedded in the [Mutation]. +func toMutation( + ctx context.Context, + store client.Store, + mutationRequest *request.ObjectMutation, + thisIndex int, +) (*Mutation, error) { + underlyingSelect, err := toSelect(ctx, store, ObjectSelection, thisIndex, mutationRequest.ToSelect(), "") if err != nil { return nil, err } - return &Mutation{ Select: *underlyingSelect, Type: MutationType(mutationRequest.Type), diff --git a/internal/planner/mapper/operation.go b/internal/planner/mapper/operation.go new file mode 100644 index 0000000000..9748a9e90b --- /dev/null +++ b/internal/planner/mapper/operation.go @@ -0,0 +1,46 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package mapper + +import ( + "github.com/sourcenetwork/defradb/client/request" + "github.com/sourcenetwork/defradb/internal/core" +) + +// Operation represents an operation such as query or mutation. +// +// It wraps child Selects belonging to this operation. +type Operation struct { + // The document mapping for this select, describing how items yielded + // for this select can be accessed and rendered. + *core.DocumentMapping + + // Selects is the list of selections in the operation. + Selects []*Select + + // Mutations is the list of mutations in the operation. + Mutations []*Mutation + + // CommitSelects is the list of commit selections in the operation. + CommitSelects []*CommitSelect +} + +// addSelection adds a new selection to the operation's document mapping. +// The request.Field is used as the key for the core.RenderKey and the Select +// document mapping is added as a child field. +func (o *Operation) addSelection(i int, f request.Field, s Select) { + o.DocumentMapping.Add(i, s.Name) + o.DocumentMapping.SetChildAt(i, s.DocumentMapping) + o.DocumentMapping.RenderKeys = append(o.DocumentMapping.RenderKeys, core.RenderKey{ + Key: getRenderKey(&f), + Index: s.Index, + }) +} diff --git a/internal/planner/operation.go b/internal/planner/operation.go new file mode 100644 index 0000000000..934fe2d4b4 --- /dev/null +++ b/internal/planner/operation.go @@ -0,0 +1,167 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package planner + +import ( + "github.com/sourcenetwork/defradb/client/request" + "github.com/sourcenetwork/defradb/internal/core" + "github.com/sourcenetwork/defradb/internal/planner/mapper" +) + +const operationNodeKind string = "operationNode" + +// operationNode is the top level node for operations with +// one or more child selections, such as queries or mutations. +type operationNode struct { + documentIterator + docMapper + + children map[int]planNode + isDone bool +} + +func (n *operationNode) Spans(spans core.Spans) { + for _, child := range n.children { + child.Spans(spans) + } +} + +func (n *operationNode) Kind() string { + return operationNodeKind +} + +func (n *operationNode) Init() error { + n.isDone = false + n.currentValue = core.Doc{} + + for _, child := range n.children { + err := child.Init() + if err != nil { + return err + } + } + return nil +} + +func (n *operationNode) Start() error { + for _, child := range n.children { + err := child.Start() + if err != nil { + return err + } + } + return nil +} + +func (n *operationNode) Close() error { + for _, child := range n.children { + err := child.Close() + if err != nil { + return err + } + } + return nil +} + +func (n *operationNode) Source() planNode { + return nil +} + +func (p *operationNode) Children() []planNode { + children := make([]planNode, 0, len(p.children)) + for _, child := range p.children { + children = append(children, child) + } + return children +} + +func (n *operationNode) Next() (bool, error) { + if n.isDone { + return false, nil + } + + n.currentValue = n.documentMapping.NewDoc() + for i, child := range n.children { + switch child.(type) { + case *topLevelNode: + hasChild, err := child.Next() + if err != nil { + return false, err + } + if !hasChild { + return false, ErrMissingChildValue + } + n.currentValue.Fields[i] = child.Value().Fields[0] + + default: + var docs []core.Doc + for { + hasChild, err := child.Next() + if err != nil { + return false, err + } + if !hasChild { + break + } + docs = append(docs, child.Value()) + } + n.currentValue.Fields[i] = docs + } + } + + n.isDone = true + return true, nil +} + +// Operation creates a new operationNode using the given Selects. +func (p *Planner) Operation(operation *mapper.Operation) (*operationNode, error) { + children := make(map[int]planNode) + + for _, s := range operation.Selects { + if _, isAgg := request.Aggregates[s.Name]; isAgg { + // If this Select is an aggregate, then it must be a top-level + // aggregate and we need to resolve it within the context of a + // top-level node. + child, err := p.Top(s) + if err != nil { + return nil, err + } + children[s.Index] = child + } else { + child, err := p.Select(s) + if err != nil { + return nil, err + } + children[s.Index] = child + } + } + + for _, m := range operation.Mutations { + child, err := p.newObjectMutationPlan(m) + if err != nil { + return nil, err + } + children[m.Index] = child + } + + for _, s := range operation.CommitSelects { + child, err := p.CommitSelect(s) + if err != nil { + return nil, err + } + children[s.Index] = child + } + + return &operationNode{ + docMapper: docMapper{operation.DocumentMapping}, + children: children, + }, nil +} diff --git a/internal/planner/operations.go b/internal/planner/operations.go index 59aa00a3c3..e08ebae5c3 100644 --- a/internal/planner/operations.go +++ b/internal/planner/operations.go @@ -37,6 +37,7 @@ var ( _ MultiNode = (*parallelNode)(nil) _ MultiNode = (*topLevelNode)(nil) + _ MultiNode = (*operationNode)(nil) ) // type joinNode struct { diff --git a/internal/planner/planner.go b/internal/planner/planner.go index db7b0510ab..e6f67668ea 100644 --- a/internal/planner/planner.go +++ b/internal/planner/planner.go @@ -110,56 +110,6 @@ func New( } } -func (p *Planner) newPlan(stmt any) (planNode, error) { - switch n := stmt.(type) { - case *request.Request: - if len(n.Queries) > 0 { - return p.newPlan(n.Queries[0]) // @todo, handle multiple query operation statements - } else if len(n.Mutations) > 0 { - return p.newPlan(n.Mutations[0]) // @todo: handle multiple mutation operation statements - } else { - return nil, ErrMissingQueryOrMutation - } - - case *request.OperationDefinition: - if len(n.Selections) == 0 { - return nil, ErrOperationDefinitionMissingSelection - } - return p.newPlan(n.Selections[0]) - - case *request.Select: - m, err := mapper.ToSelect(p.ctx, p.db, mapper.ObjectSelection, n) - if err != nil { - return nil, err - } - - if _, isAgg := request.Aggregates[n.Name]; isAgg { - // If this Select is an aggregate, then it must be a top-level - // aggregate and we need to resolve it within the context of a - // top-level node. - return p.Top(m) - } - - return p.Select(m) - - case *request.CommitSelect: - m, err := mapper.ToCommitSelect(p.ctx, p.db, n) - if err != nil { - return nil, err - } - return p.CommitSelect(m) - - case *request.ObjectMutation: - m, err := mapper.ToMutation(p.ctx, p.db, n) - if err != nil { - return nil, err - } - return p.newObjectMutationPlan(m) - } - - return nil, client.NewErrUnhandledType("statement", stmt) -} - func (p *Planner) newObjectMutationPlan(stmt *mapper.Mutation) (planNode, error) { switch stmt.Type { case mapper.CreateObjects: @@ -176,23 +126,6 @@ func (p *Planner) newObjectMutationPlan(stmt *mapper.Mutation) (planNode, error) } } -// makePlan creates a new plan from the parsed data, optimizes the plan and returns -// it. The caller of makePlan is also responsible of calling Close() on the plan to -// free it's resources. -func (p *Planner) makePlan(stmt any) (planNode, error) { - planNode, err := p.newPlan(stmt) - if err != nil { - return nil, err - } - - err = p.optimizePlan(planNode) - if err != nil { - return nil, err - } - - return planNode, err -} - // optimizePlan optimizes the plan using plan expansion and wiring. func (p *Planner) optimizePlan(planNode planNode) error { err := p.expandPlan(planNode, nil) @@ -555,12 +488,25 @@ func (p *Planner) executeRequest( return docs, err } +// RunSelection runs a selection and returns the result(s). +func (p *Planner) RunSelection( + ctx context.Context, + sel *request.Select, +) (map[string]any, error) { + req := &request.Request{ + Queries: []*request.OperationDefinition{{ + Selections: []request.Selection{sel}, + }}, + } + return p.RunRequest(ctx, req) +} + // RunRequest classifies the type of request to run, runs it, and then returns the result(s). func (p *Planner) RunRequest( ctx context.Context, req *request.Request, -) (result []map[string]any, err error) { - planNode, err := p.makePlan(req) +) (map[string]any, error) { + planNode, err := p.MakePlan(req) if err != nil { return nil, err } @@ -590,35 +536,36 @@ func (p *Planner) RunRequest( } // This won't / should NOT execute if it's any kind of explain request. - return p.executeRequest(ctx, planNode) -} - -// RunSubscriptionRequest plans a request specific to a subscription and returns the result. -func (p *Planner) RunSubscriptionRequest( - ctx context.Context, - request *request.Select, -) (result []map[string]any, err error) { - planNode, err := p.makePlan(request) + res, err := p.executeRequest(ctx, planNode) if err != nil { return nil, err } - defer func() { - if e := planNode.Close(); e != nil { - err = NewErrFailedToClosePlan(e, "running subscription request") - } - }() + if len(res) > 0 { + return res[0], nil + } - err = planNode.Init() + return nil, nil +} + +// MakeSelectionPlan makes a plan for a single selection. +// +// Note: Caller is responsible to call the `Close()` method to free the allocated +// resources of the returned plan. +func (p *Planner) MakeSelectionPlan(selection *request.Select) (planNode, error) { + s, err := mapper.ToSelect(p.ctx, p.db, mapper.ObjectSelection, selection) if err != nil { return nil, err } - - data, err := p.executeRequest(ctx, planNode) + planNode, err := p.Select(s) + if err != nil { + return nil, err + } + err = p.optimizePlan(planNode) if err != nil { return nil, err } - return data, nil + return planNode, err } // MakePlan makes a plan from the parsed request. @@ -627,6 +574,28 @@ func (p *Planner) RunSubscriptionRequest( // resources of the returned plan. // // @TODO {defradb/issues/368}: Test this exported function. -func (p *Planner) MakePlan(request *request.Request) (planNode, error) { - return p.makePlan(request) +func (p *Planner) MakePlan(req *request.Request) (planNode, error) { + // TODO handle multiple operation statements + // https://github.com/sourcenetwork/defradb/issues/1395 + var operation *request.OperationDefinition + if len(req.Mutations) > 0 { + operation = req.Mutations[0] + } else if len(req.Queries) > 0 { + operation = req.Queries[0] + } else { + return nil, ErrMissingQueryOrMutation + } + m, err := mapper.ToOperation(p.ctx, p.db, operation) + if err != nil { + return nil, err + } + planNode, err := p.Operation(m) + if err != nil { + return nil, err + } + err = p.optimizePlan(planNode) + if err != nil { + return nil, err + } + return planNode, err } diff --git a/tests/integration/acp/index/create_test.go b/tests/integration/acp/index/create_test.go index c75e51bc4e..da9e9b96b9 100644 --- a/tests/integration/acp/index/create_test.go +++ b/tests/integration/acp/index/create_test.go @@ -56,7 +56,9 @@ func TestACP_IndexCreateWithSeparateRequest_OnCollectionWithPolicy_NoError(t *te } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -95,6 +97,9 @@ func TestACP_IndexCreateWithDirective_OnCollectionWithPolicy_NoError(t *testing. age } }`, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/acp/index/query_test.go b/tests/integration/acp/index/query_test.go index e2818708b8..3fafeb4b10 100644 --- a/tests/integration/acp/index/query_test.go +++ b/tests/integration/acp/index/query_test.go @@ -60,9 +60,9 @@ func TestACPWithIndex_UponQueryingPrivateDocWithoutIdentity_ShouldNotFetch(t *te name } }`, - Results: []map[string]any{ - { - "name": "Shahzad", + Results: map[string]any{ + "Users": []map[string]any{ + {"name": "Shahzad"}, }, }, }, @@ -115,12 +115,14 @@ func TestACPWithIndex_UponQueryingPrivateDocWithIdentity_ShouldFetch(t *testing. name } }`, - Results: []map[string]any{ - { - "name": "Islam", - }, - { - "name": "Shahzad", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Islam", + }, + { + "name": "Shahzad", + }, }, }, }, @@ -173,9 +175,11 @@ func TestACPWithIndex_UponQueryingPrivateDocWithWrongIdentity_ShouldNotFetch(t * name } }`, - Results: []map[string]any{ - { - "name": "Shahzad", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + }, }, }, }, diff --git a/tests/integration/acp/index/query_with_relation_test.go b/tests/integration/acp/index/query_with_relation_test.go index 925d35cb4f..5a406e6575 100644 --- a/tests/integration/acp/index/query_with_relation_test.go +++ b/tests/integration/acp/index/query_with_relation_test.go @@ -111,12 +111,14 @@ func TestACPWithIndex_UponQueryingPrivateOneToManyRelatedDocWithoutIdentity_Shou } } }`, - Results: []map[string]any{ - { - "name": "John Grisham", - "published": []map[string]any{ - { - "name": "Painted House", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "published": []map[string]any{ + { + "name": "Painted House", + }, }, }, }, @@ -146,23 +148,25 @@ func TestACPWithIndex_UponQueryingPrivateOneToManyRelatedDocWithIdentity_ShouldF } } }`, - Results: []map[string]any{ - { - "name": "John Grisham", - "published": []map[string]any{ - { - "name": "Painted House", - }, - { - "name": "A Time for Mercy", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "published": []map[string]any{ + { + "name": "Painted House", + }, + { + "name": "A Time for Mercy", + }, }, }, - }, - { - "name": "Cornelia Funke", - "published": []map[string]any{ - { - "name": "Theif Lord", + { + "name": "Cornelia Funke", + "published": []map[string]any{ + { + "name": "Theif Lord", + }, }, }, }, @@ -192,12 +196,14 @@ func TestACPWithIndex_UponQueryingPrivateOneToManyRelatedDocWithWrongIdentity_Sh } } }`, - Results: []map[string]any{ - { - "name": "John Grisham", - "published": []map[string]any{ - { - "name": "Painted House", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "published": []map[string]any{ + { + "name": "Painted House", + }, }, }, }, @@ -226,11 +232,13 @@ func TestACPWithIndex_UponQueryingPrivateManyToOneRelatedDocWithoutIdentity_Shou } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "author": map[string]any{ - "name": "John Grisham", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, @@ -259,23 +267,25 @@ func TestACPWithIndex_UponQueryingPrivateManyToOneRelatedDocWithIdentity_ShouldF } } }`, - Results: []map[string]any{ - { - "name": "Theif Lord", - "author": map[string]any{ - "name": "Cornelia Funke", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Theif Lord", + "author": map[string]any{ + "name": "Cornelia Funke", + }, }, - }, - { - "name": "Painted House", - "author": map[string]any{ - "name": "John Grisham", + { + "name": "Painted House", + "author": map[string]any{ + "name": "John Grisham", + }, }, - }, - { - "name": "A Time for Mercy", - "author": map[string]any{ - "name": "John Grisham", + { + "name": "A Time for Mercy", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, @@ -304,11 +314,13 @@ func TestACPWithIndex_UponQueryingPrivateManyToOneRelatedDocWithWrongIdentity_Sh } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "author": map[string]any{ - "name": "John Grisham", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, diff --git a/tests/integration/acp/p2p/replicator_test.go b/tests/integration/acp/p2p/replicator_test.go index 169e682658..8afaafebc0 100644 --- a/tests/integration/acp/p2p/replicator_test.go +++ b/tests/integration/acp/p2p/replicator_test.go @@ -157,9 +157,11 @@ func TestACP_P2POneToOneReplicatorWithPermissionedCollection_SourceHubACP(t *tes } } `, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -172,7 +174,9 @@ func TestACP_P2POneToOneReplicatorWithPermissionedCollection_SourceHubACP(t *tes } } `, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, testUtils.Request{ // Ensure that the document is hidden on all nodes to unauthorized actors @@ -184,7 +188,9 @@ func TestACP_P2POneToOneReplicatorWithPermissionedCollection_SourceHubACP(t *tes } } `, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/acp/p2p/subscribe_test.go b/tests/integration/acp/p2p/subscribe_test.go index 4e8cf4cc2e..e95fbaca97 100644 --- a/tests/integration/acp/p2p/subscribe_test.go +++ b/tests/integration/acp/p2p/subscribe_test.go @@ -179,9 +179,11 @@ func TestACP_P2PSubscribeAddGetSingleWithPermissionedCollection_SourceHubACP(t * } } `, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -194,7 +196,9 @@ func TestACP_P2PSubscribeAddGetSingleWithPermissionedCollection_SourceHubACP(t * } } `, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, testUtils.Request{ // Ensure that the document is hidden on all nodes to unauthorized actors @@ -206,7 +210,9 @@ func TestACP_P2PSubscribeAddGetSingleWithPermissionedCollection_SourceHubACP(t * } } `, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/acp/query/avg_test.go b/tests/integration/acp/query/avg_test.go index 425b6e0943..34b03de6ea 100644 --- a/tests/integration/acp/query/avg_test.go +++ b/tests/integration/acp/query/avg_test.go @@ -31,11 +31,9 @@ func TestACP_QueryAverageWithoutIdentity(t *testing.T) { _avg(Employee: {field: salary}) } `, - Results: []map[string]any{ - { - // 2 public employees, 1 with salary 10k, 1 with salary 20k - "_avg": int(15000), - }, + Results: map[string]any{ + // 2 public employees, 1 with salary 10k, 1 with salary 20k + "_avg": int(15000), }, }, }, @@ -58,11 +56,9 @@ func TestACP_QueryAverageWithIdentity(t *testing.T) { _avg(Employee: {field: salary}) } `, - Results: []map[string]any{ - { - // 4 employees with salaries 10k, 20k, 30k, 40k - "_avg": int(25000), - }, + Results: map[string]any{ + // 4 employees with salaries 10k, 20k, 30k, 40k + "_avg": int(25000), }, }, }, @@ -85,11 +81,9 @@ func TestACP_QueryAverageWithWrongIdentity(t *testing.T) { _avg(Employee: {field: salary}) } `, - Results: []map[string]any{ - { - // 2 public employees, 1 with salary 10k, 1 with salary 20k - "_avg": int(15000), - }, + Results: map[string]any{ + // 2 public employees, 1 with salary 10k, 1 with salary 20k + "_avg": int(15000), }, }, }, diff --git a/tests/integration/acp/query/count_test.go b/tests/integration/acp/query/count_test.go index 33bc053a60..e5f867b3d5 100644 --- a/tests/integration/acp/query/count_test.go +++ b/tests/integration/acp/query/count_test.go @@ -31,10 +31,8 @@ func TestACP_QueryCountDocumentsWithoutIdentity(t *testing.T) { _count(Employee: {}) } `, - Results: []map[string]any{ - { - "_count": int(2), - }, + Results: map[string]any{ + "_count": int(2), }, }, }, @@ -58,10 +56,12 @@ func TestACP_QueryCountRelatedObjectsWithoutIdentity(t *testing.T) { } } `, - Results: []map[string]any{ - { - // 1 of 2 companies is public and has 1 public employee out of 2 - "_count": int(1), + Results: map[string]any{ + "Company": []map[string]any{ + { + // 1 of 2 companies is public and has 1 public employee out of 2 + "_count": int(1), + }, }, }, }, @@ -85,10 +85,8 @@ func TestACP_QueryCountDocumentsWithIdentity(t *testing.T) { _count(Employee: {}) } `, - Results: []map[string]any{ - { - "_count": int(4), - }, + Results: map[string]any{ + "_count": int(4), }, }, }, @@ -113,12 +111,14 @@ func TestACP_QueryCountRelatedObjectsWithIdentity(t *testing.T) { } } `, - Results: []map[string]any{ - { - "_count": int(2), - }, - { - "_count": int(2), + Results: map[string]any{ + "Company": []map[string]any{ + { + "_count": int(2), + }, + { + "_count": int(2), + }, }, }, }, @@ -142,10 +142,8 @@ func TestACP_QueryCountDocumentsWithWrongIdentity(t *testing.T) { _count(Employee: {}) } `, - Results: []map[string]any{ - { - "_count": int(2), - }, + Results: map[string]any{ + "_count": int(2), }, }, }, @@ -170,10 +168,12 @@ func TestACP_QueryCountRelatedObjectsWithWrongIdentity(t *testing.T) { } } `, - Results: []map[string]any{ - { - // 1 of 2 companies is public and has 1 public employee out of 2 - "_count": int(1), + Results: map[string]any{ + "Company": []map[string]any{ + { + // 1 of 2 companies is public and has 1 public employee out of 2 + "_count": int(1), + }, }, }, }, diff --git a/tests/integration/acp/query/relation_objects_test.go b/tests/integration/acp/query/relation_objects_test.go index 92deebb788..afbc014c08 100644 --- a/tests/integration/acp/query/relation_objects_test.go +++ b/tests/integration/acp/query/relation_objects_test.go @@ -36,14 +36,16 @@ func TestACP_QueryManyToOneRelationObjectsWithoutIdentity(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "PubEmp in PubCompany", - "company": map[string]any{"name": "Public Company"}, - }, - { - "name": "PubEmp in PrivateCompany", - "company": nil, + Results: map[string]any{ + "Employee": []map[string]any{ + { + "name": "PubEmp in PubCompany", + "company": map[string]any{"name": "Public Company"}, + }, + { + "name": "PubEmp in PrivateCompany", + "company": nil, + }, }, }, }, @@ -71,11 +73,13 @@ func TestACP_QueryOneToManyRelationObjectsWithoutIdentity(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "Public Company", - "employees": []map[string]any{ - {"name": "PubEmp in PubCompany"}, + Results: map[string]any{ + "Company": []map[string]any{ + { + "name": "Public Company", + "employees": []map[string]any{ + {"name": "PubEmp in PubCompany"}, + }, }, }, }, @@ -105,22 +109,24 @@ func TestACP_QueryManyToOneRelationObjectsWithIdentity(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "PrivateEmp in PubCompany", - "company": map[string]any{"name": "Public Company"}, - }, - { - "name": "PrivateEmp in PrivateCompany", - "company": map[string]any{"name": "Private Company"}, - }, - { - "name": "PubEmp in PubCompany", - "company": map[string]any{"name": "Public Company"}, - }, - { - "name": "PubEmp in PrivateCompany", - "company": map[string]any{"name": "Private Company"}, + Results: map[string]any{ + "Employee": []map[string]any{ + { + "name": "PrivateEmp in PubCompany", + "company": map[string]any{"name": "Public Company"}, + }, + { + "name": "PrivateEmp in PrivateCompany", + "company": map[string]any{"name": "Private Company"}, + }, + { + "name": "PubEmp in PubCompany", + "company": map[string]any{"name": "Public Company"}, + }, + { + "name": "PubEmp in PrivateCompany", + "company": map[string]any{"name": "Private Company"}, + }, }, }, }, @@ -149,19 +155,21 @@ func TestACP_QueryOneToManyRelationObjectsWithIdentity(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "Public Company", - "employees": []map[string]any{ - {"name": "PrivateEmp in PubCompany"}, - {"name": "PubEmp in PubCompany"}, + Results: map[string]any{ + "Company": []map[string]any{ + { + "name": "Public Company", + "employees": []map[string]any{ + {"name": "PrivateEmp in PubCompany"}, + {"name": "PubEmp in PubCompany"}, + }, }, - }, - { - "name": "Private Company", - "employees": []map[string]any{ - {"name": "PrivateEmp in PrivateCompany"}, - {"name": "PubEmp in PrivateCompany"}, + { + "name": "Private Company", + "employees": []map[string]any{ + {"name": "PrivateEmp in PrivateCompany"}, + {"name": "PubEmp in PrivateCompany"}, + }, }, }, }, @@ -191,14 +199,16 @@ func TestACP_QueryManyToOneRelationObjectsWithWrongIdentity(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "PubEmp in PubCompany", - "company": map[string]any{"name": "Public Company"}, - }, - { - "name": "PubEmp in PrivateCompany", - "company": nil, + Results: map[string]any{ + "Employee": []map[string]any{ + { + "name": "PubEmp in PubCompany", + "company": map[string]any{"name": "Public Company"}, + }, + { + "name": "PubEmp in PrivateCompany", + "company": nil, + }, }, }, }, @@ -227,11 +237,13 @@ func TestACP_QueryOneToManyRelationObjectsWithWrongIdentity(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "Public Company", - "employees": []map[string]any{ - {"name": "PubEmp in PubCompany"}, + Results: map[string]any{ + "Company": []map[string]any{ + { + "name": "Public Company", + "employees": []map[string]any{ + {"name": "PubEmp in PubCompany"}, + }, }, }, }, diff --git a/tests/integration/acp/register_and_delete_test.go b/tests/integration/acp/register_and_delete_test.go index c5a0c882ca..e30388bd76 100644 --- a/tests/integration/acp/register_and_delete_test.go +++ b/tests/integration/acp/register_and_delete_test.go @@ -104,7 +104,9 @@ func TestACP_CreateWithoutIdentityAndDeleteWithoutIdentity_CanDelete(t *testing. } `, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -199,7 +201,9 @@ func TestACP_CreateWithoutIdentityAndDeleteWithIdentity_CanDelete(t *testing.T) } } `, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -294,7 +298,9 @@ func TestACP_CreateWithIdentityAndDeleteWithIdentity_CanDelete(t *testing.T) { } } `, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -389,11 +395,13 @@ func TestACP_CreateWithIdentityAndDeleteWithoutIdentity_CanNotDelete(t *testing. } } `, - Results: []map[string]any{ - { - "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", - "name": "Shahzad", - "age": int64(28), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", + "name": "Shahzad", + "age": int64(28), + }, }, }, }, @@ -492,11 +500,13 @@ func TestACP_CreateWithIdentityAndDeleteWithWrongIdentity_CanNotDelete(t *testin } } `, - Results: []map[string]any{ - { - "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", - "name": "Shahzad", - "age": int64(28), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", + "name": "Shahzad", + "age": int64(28), + }, }, }, }, diff --git a/tests/integration/acp/register_and_read_test.go b/tests/integration/acp/register_and_read_test.go index dabf356e3c..83d0819f54 100644 --- a/tests/integration/acp/register_and_read_test.go +++ b/tests/integration/acp/register_and_read_test.go @@ -93,11 +93,13 @@ func TestACP_CreateWithoutIdentityAndReadWithoutIdentity_CanRead(t *testing.T) { } } `, - Results: []map[string]any{ - { - "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", - "name": "Shahzad", - "age": int64(28), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", + "name": "Shahzad", + "age": int64(28), + }, }, }, }, @@ -184,11 +186,13 @@ func TestACP_CreateWithoutIdentityAndReadWithIdentity_CanRead(t *testing.T) { } } `, - Results: []map[string]any{ - { - "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", - "name": "Shahzad", - "age": int64(28), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", + "name": "Shahzad", + "age": int64(28), + }, }, }, }, @@ -277,11 +281,13 @@ func TestACP_CreateWithIdentityAndReadWithIdentity_CanRead(t *testing.T) { } } `, - Results: []map[string]any{ - { - "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", - "name": "Shahzad", - "age": int64(28), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", + "name": "Shahzad", + "age": int64(28), + }, }, }, }, @@ -368,7 +374,9 @@ func TestACP_CreateWithIdentityAndReadWithoutIdentity_CanNotRead(t *testing.T) { } } `, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -455,7 +463,9 @@ func TestACP_CreateWithIdentityAndReadWithWrongIdentity_CanNotRead(t *testing.T) } } `, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/acp/register_and_update_test.go b/tests/integration/acp/register_and_update_test.go index 842ef1b754..4bf39a0508 100644 --- a/tests/integration/acp/register_and_update_test.go +++ b/tests/integration/acp/register_and_update_test.go @@ -110,11 +110,13 @@ func TestACP_CreateWithoutIdentityAndUpdateWithoutIdentity_CanUpdate(t *testing. } `, - Results: []map[string]any{ - { - "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", - "name": "Shahzad Lone", - "age": int64(28), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", + "name": "Shahzad Lone", + "age": int64(28), + }, }, }, }, @@ -217,11 +219,13 @@ func TestACP_CreateWithoutIdentityAndUpdateWithIdentity_CanUpdate(t *testing.T) } } `, - Results: []map[string]any{ - { - "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", - "name": "Shahzad Lone", - "age": int64(28), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", + "name": "Shahzad Lone", + "age": int64(28), + }, }, }, }, @@ -324,11 +328,13 @@ func TestACP_CreateWithIdentityAndUpdateWithIdentity_CanUpdate(t *testing.T) { } } `, - Results: []map[string]any{ - { - "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", - "name": "Shahzad Lone", - "age": int64(28), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", + "name": "Shahzad Lone", + "age": int64(28), + }, }, }, }, @@ -437,11 +443,13 @@ func TestACP_CreateWithIdentityAndUpdateWithoutIdentity_CanNotUpdate(t *testing. } } `, - Results: []map[string]any{ - { - "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", - "name": "Shahzad", - "age": int64(28), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", + "name": "Shahzad", + "age": int64(28), + }, }, }, }, @@ -552,11 +560,13 @@ func TestACP_CreateWithIdentityAndUpdateWithWrongIdentity_CanNotUpdate(t *testin } } `, - Results: []map[string]any{ - { - "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", - "name": "Shahzad", - "age": int64(28), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", + "name": "Shahzad", + "age": int64(28), + }, }, }, }, @@ -666,11 +676,13 @@ func TestACP_CreateWithIdentityAndUpdateWithoutIdentityGQL_CanNotUpdate(t *testi } } `, - Results: []map[string]any{ - { - "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", - "name": "Shahzad", - "age": int64(28), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", + "name": "Shahzad", + "age": int64(28), + }, }, }, }, @@ -782,11 +794,13 @@ func TestACP_CreateWithIdentityAndUpdateWithWrongIdentityGQL_CanNotUpdate(t *tes } } `, - Results: []map[string]any{ - { - "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", - "name": "Shahzad", - "age": int64(28), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-9d443d0c-52f6-568b-8f74-e8ff0825697b", + "name": "Shahzad", + "age": int64(28), + }, }, }, }, diff --git a/tests/integration/backup/one_to_many/import_test.go b/tests/integration/backup/one_to_many/import_test.go index 70260d58d8..2a48fb878f 100644 --- a/tests/integration/backup/one_to_many/import_test.go +++ b/tests/integration/backup/one_to_many/import_test.go @@ -40,18 +40,20 @@ func TestBackupImport_WithMultipleNoKeyAndMultipleCollections_NoError(t *testing age } }`, - Results: []map[string]any{ - { - "name": "John", - "age": int64(30), - }, - { - "name": "Bob", - "age": int64(32), - }, - { - "name": "Smith", - "age": int64(31), + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "John", + "age": int64(30), + }, + { + "name": "Bob", + "age": int64(32), + }, + { + "name": "Smith", + "age": int64(31), + }, }, }, }, @@ -62,12 +64,14 @@ func TestBackupImport_WithMultipleNoKeyAndMultipleCollections_NoError(t *testing name } }`, - Results: []map[string]any{ - { - "name": "Game of chains", - }, - { - "name": "John and the sourcerers' stone", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Game of chains", + }, + { + "name": "John and the sourcerers' stone", + }, }, }, }, @@ -120,14 +124,16 @@ func TestBackupImport_WithMultipleNoKeyAndMultipleCollectionsAndUpdatedDocs_NoEr age } }`, - Results: []map[string]any{ - { - "name": "John", - "age": int64(31), - }, - { - "name": "Bob", - "age": int64(31), + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "John", + "age": int64(31), + }, + { + "name": "Bob", + "age": int64(31), + }, }, }, }, @@ -141,17 +147,19 @@ func TestBackupImport_WithMultipleNoKeyAndMultipleCollectionsAndUpdatedDocs_NoEr } } }`, - Results: []map[string]any{ - { - "name": "Game of chains", - "author": map[string]any{ - "_docID": "bae-9918e1ec-c62b-5de2-8fbf-c82795b8ac7f", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Game of chains", + "author": map[string]any{ + "_docID": "bae-9918e1ec-c62b-5de2-8fbf-c82795b8ac7f", + }, }, - }, - { - "name": "John and the sourcerers' stone", - "author": map[string]any{ - "_docID": "bae-9918e1ec-c62b-5de2-8fbf-c82795b8ac7f", + { + "name": "John and the sourcerers' stone", + "author": map[string]any{ + "_docID": "bae-9918e1ec-c62b-5de2-8fbf-c82795b8ac7f", + }, }, }, }, diff --git a/tests/integration/backup/one_to_one/import_test.go b/tests/integration/backup/one_to_one/import_test.go index 4451841163..15bdad354b 100644 --- a/tests/integration/backup/one_to_one/import_test.go +++ b/tests/integration/backup/one_to_one/import_test.go @@ -40,18 +40,20 @@ func TestBackupImport_WithMultipleNoKeyAndMultipleCollections_NoError(t *testing age } }`, - Results: []map[string]any{ - { - "name": "John", - "age": int64(30), - }, - { - "name": "Bob", - "age": int64(32), - }, - { - "name": "Smith", - "age": int64(31), + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "John", + "age": int64(30), + }, + { + "name": "Bob", + "age": int64(32), + }, + { + "name": "Smith", + "age": int64(31), + }, }, }, }, @@ -62,12 +64,14 @@ func TestBackupImport_WithMultipleNoKeyAndMultipleCollections_NoError(t *testing name } }`, - Results: []map[string]any{ - { - "name": "Game of chains", - }, - { - "name": "John and the sourcerers' stone", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Game of chains", + }, + { + "name": "John and the sourcerers' stone", + }, }, }, }, @@ -114,14 +118,16 @@ func TestBackupImport_WithMultipleNoKeyAndMultipleCollectionsAndUpdatedDocs_NoEr age } }`, - Results: []map[string]any{ - { - "name": "John", - "age": int64(31), - }, - { - "name": "Bob", - "age": int64(31), + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "John", + "age": int64(31), + }, + { + "name": "Bob", + "age": int64(31), + }, }, }, }, @@ -135,11 +141,13 @@ func TestBackupImport_WithMultipleNoKeyAndMultipleCollectionsAndUpdatedDocs_NoEr } } }`, - Results: []map[string]any{ - { - "name": "John and the sourcerers' stone", - "author": map[string]any{ - "_docID": "bae-9918e1ec-c62b-5de2-8fbf-c82795b8ac7f", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "John and the sourcerers' stone", + "author": map[string]any{ + "_docID": "bae-9918e1ec-c62b-5de2-8fbf-c82795b8ac7f", + }, }, }, }, @@ -226,19 +234,21 @@ func TestBackupImport_DoubleRelationshipWithUpdate_NoError(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "John and the sourcerers' stone", - "author": map[string]any{ - "name": "John", - "favouriteBook": map[string]any{ - "name": "John and the sourcerers' stone", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "John and the sourcerers' stone", + "author": map[string]any{ + "name": "John", + "favouriteBook": map[string]any{ + "name": "John and the sourcerers' stone", + }, }, }, - }, - { - "name": "Game of chains", - "author": nil, + { + "name": "Game of chains", + "author": nil, + }, }, }, }, diff --git a/tests/integration/backup/self_reference/import_test.go b/tests/integration/backup/self_reference/import_test.go index 5ddb800a41..1d0b39d2e7 100644 --- a/tests/integration/backup/self_reference/import_test.go +++ b/tests/integration/backup/self_reference/import_test.go @@ -48,15 +48,17 @@ func TestBackupSelfRefImport_Simple_NoError(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "John", - "boss": nil, - }, - { - "name": "Bob", - "boss": map[string]any{ + Results: map[string]any{ + "User": []map[string]any{ + { "name": "John", + "boss": nil, + }, + { + "name": "Bob", + "boss": map[string]any{ + "name": "John", + }, }, }, }, @@ -120,11 +122,13 @@ func TestBackupSelfRefImport_SelfRef_NoError(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Bob", - "boss": map[string]any{ + Results: map[string]any{ + "User": []map[string]any{ + { "name": "Bob", + "boss": map[string]any{ + "name": "Bob", + }, }, }, }, @@ -181,13 +185,15 @@ func TestBackupSelfRefImport_PrimaryRelationWithSecondCollection_NoError(t *test } } }`, - Results: []map[string]any{ - { - "name": "John and the sourcerers' stone", - "author": map[string]any{ - "name": "John", - "reviewed": map[string]any{ - "name": "John and the sourcerers' stone", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "John and the sourcerers' stone", + "author": map[string]any{ + "name": "John", + "reviewed": map[string]any{ + "name": "John and the sourcerers' stone", + }, }, }, }, @@ -245,13 +251,15 @@ func TestBackupSelfRefImport_PrimaryRelationWithSecondCollectionWrongOrder_NoErr } } }`, - Results: []map[string]any{ - { - "name": "John and the sourcerers' stone", - "author": map[string]any{ - "name": "John", - "reviewed": map[string]any{ - "name": "John and the sourcerers' stone", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "John and the sourcerers' stone", + "author": map[string]any{ + "name": "John", + "reviewed": map[string]any{ + "name": "John and the sourcerers' stone", + }, }, }, }, @@ -355,12 +363,14 @@ func TestBackupSelfRefImport_SplitPrimaryRelationWithSecondCollection_NoError(t } } }`, - Results: []map[string]any{ - { - "name": "John and the sourcerers' stone", - "author": map[string]any{ - "name": "John", - "reviewed": nil, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "John and the sourcerers' stone", + "author": map[string]any{ + "name": "John", + "reviewed": nil, + }, }, }, }, diff --git a/tests/integration/backup/simple/import_test.go b/tests/integration/backup/simple/import_test.go index 5d8d4a6ccc..0565a76c3f 100644 --- a/tests/integration/backup/simple/import_test.go +++ b/tests/integration/backup/simple/import_test.go @@ -30,10 +30,12 @@ func TestBackupImport_Simple_NoError(t *testing.T) { age } }`, - Results: []map[string]any{ - { - "name": "John", - "age": int64(30), + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "John", + "age": int64(30), + }, }, }, }, @@ -100,10 +102,12 @@ func TestBackupImport_WithNoKeys_NoError(t *testing.T) { age } }`, - Results: []map[string]any{ - { - "name": "John", - "age": int64(30), + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "John", + "age": int64(30), + }, }, }, }, @@ -131,18 +135,20 @@ func TestBackupImport_WithMultipleNoKeys_NoError(t *testing.T) { age } }`, - Results: []map[string]any{ - { - "name": "John", - "age": int64(30), - }, - { - "name": "Bob", - "age": int64(32), - }, - { - "name": "Smith", - "age": int64(31), + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "John", + "age": int64(30), + }, + { + "name": "Bob", + "age": int64(32), + }, + { + "name": "Smith", + "age": int64(31), + }, }, }, }, @@ -165,9 +171,11 @@ func TestBackupImport_EmptyObject_NoError(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": nil, + Results: map[string]any{ + "User": []map[string]any{ + { + "name": nil, + }, }, }, }, @@ -197,7 +205,9 @@ func TestBackupImport_WithMultipleNoKeysAndInvalidField_Errors(t *testing.T) { } }`, // No documents should have been commited - Results: []map[string]any{}, + Results: map[string]any{ + "User": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/collection/update/simple/with_filter_test.go b/tests/integration/collection/update/simple/with_filter_test.go index a99f340753..9be676476f 100644 --- a/tests/integration/collection/update/simple/with_filter_test.go +++ b/tests/integration/collection/update/simple/with_filter_test.go @@ -117,8 +117,10 @@ func TestUpdateWithPatch_DoesNothing(t *testing.T) { name } }`, - Results: []map[string]any{ - {"name": "John"}, + Results: map[string]any{ + "Users": []map[string]any{ + {"name": "John"}, + }, }, }, }, @@ -149,8 +151,10 @@ func TestUpdateWithFilter_Succeeds(t *testing.T) { name } }`, - Results: []map[string]any{ - {"name": "Eric"}, + Results: map[string]any{ + "Users": []map[string]any{ + {"name": "Eric"}, + }, }, }, }, diff --git a/tests/integration/collection_description/updates/copy/name_test.go b/tests/integration/collection_description/updates/copy/name_test.go index f5cbd3a83b..2af643361d 100644 --- a/tests/integration/collection_description/updates/copy/name_test.go +++ b/tests/integration/collection_description/updates/copy/name_test.go @@ -85,9 +85,11 @@ func TestColDescrUpdateCopyName(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + }, }, }, }, diff --git a/tests/integration/collection_description/updates/move/name_test.go b/tests/integration/collection_description/updates/move/name_test.go index f493b03c1a..f1e16f02c5 100644 --- a/tests/integration/collection_description/updates/move/name_test.go +++ b/tests/integration/collection_description/updates/move/name_test.go @@ -53,9 +53,11 @@ func TestColDescrUpdateMoveName(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + }, }, }, }, diff --git a/tests/integration/collection_description/updates/remove/col_source_transform_test.go b/tests/integration/collection_description/updates/remove/col_source_transform_test.go index 73179c16b0..253063c45f 100644 --- a/tests/integration/collection_description/updates/remove/col_source_transform_test.go +++ b/tests/integration/collection_description/updates/remove/col_source_transform_test.go @@ -67,9 +67,11 @@ func TestColDescrUpdateRemoveCollectionSourceTransform(t *testing.T) { } }`, // If the transform was not removed, `"Fred"` would have been returned - Results: []map[string]any{ - { - "name": "Shahzad", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + }, }, }, }, diff --git a/tests/integration/collection_description/updates/replace/col_source_transform_test.go b/tests/integration/collection_description/updates/replace/col_source_transform_test.go index b933dcd2ed..93db3e9ab1 100644 --- a/tests/integration/collection_description/updates/replace/col_source_transform_test.go +++ b/tests/integration/collection_description/updates/replace/col_source_transform_test.go @@ -75,9 +75,11 @@ func TestColDescrUpdateReplaceCollectionSourceTransform(t *testing.T) { } }`, // Without the new transform, `"Shahzad"` would have been returned - Results: []map[string]any{ - { - "name": "Fred", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Fred", + }, }, }, }, diff --git a/tests/integration/collection_description/updates/replace/name_test.go b/tests/integration/collection_description/updates/replace/name_test.go index 55e8160969..e2fe9886d1 100644 --- a/tests/integration/collection_description/updates/replace/name_test.go +++ b/tests/integration/collection_description/updates/replace/name_test.go @@ -63,9 +63,11 @@ func TestColDescrUpdateReplaceName_GivenExistingName(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "Actors": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -197,9 +199,11 @@ func TestColDescrUpdateReplaceName_RemoveExistingName(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "Actors": []map[string]any{ + { + "name": "John", + }, }, }, }, diff --git a/tests/integration/collection_description/updates/replace/query_source_query_test.go b/tests/integration/collection_description/updates/replace/query_source_query_test.go index 789f4b2d7b..1891923b46 100644 --- a/tests/integration/collection_description/updates/replace/query_source_query_test.go +++ b/tests/integration/collection_description/updates/replace/query_source_query_test.go @@ -66,9 +66,11 @@ func TestColDescrUpdateReplaceQuerySourceQuery(t *testing.T) { } }`, // If the view was still querying `Books` there would be no results - Results: []map[string]any{ - { - "name": "Shahzad", + Results: map[string]any{ + "View": []map[string]any{ + { + "name": "Shahzad", + }, }, }, }, @@ -128,9 +130,11 @@ func TestColDescrUpdateReplaceQuerySourceQueryName(t *testing.T) { } }`, // If the view was still querying `Books` there would be no results - Results: []map[string]any{ - { - "name": "Shahzad", + Results: map[string]any{ + "View": []map[string]any{ + { + "name": "Shahzad", + }, }, }, }, diff --git a/tests/integration/collection_description/updates/replace/query_source_transform_test.go b/tests/integration/collection_description/updates/replace/query_source_transform_test.go index 89a2598010..a66e3bc3b5 100644 --- a/tests/integration/collection_description/updates/replace/query_source_transform_test.go +++ b/tests/integration/collection_description/updates/replace/query_source_transform_test.go @@ -100,9 +100,11 @@ func TestColDescrUpdateReplaceQuerySourceTransform(t *testing.T) { } } `, - Results: []map[string]any{ - { - "fullName": "S", + Results: map[string]any{ + "UserView": []map[string]any{ + { + "fullName": "S", + }, }, }, }, diff --git a/tests/integration/encryption/commit_relation_test.go b/tests/integration/encryption/commit_relation_test.go index 848afa5fd3..7097c0fb56 100644 --- a/tests/integration/encryption/commit_relation_test.go +++ b/tests/integration/encryption/commit_relation_test.go @@ -62,36 +62,38 @@ func TestDocEncryption_WithEncryptionSecondaryRelations_ShouldStoreEncryptedComm } } `, - Results: []map[string]any{ - { - "delta": encrypt(testUtils.CBORValue("Chris"), userDocID, ""), - "docID": userDocID, - "fieldName": "name", - }, - { - "delta": nil, - "docID": userDocID, - "fieldName": nil, - }, - { - "delta": encrypt(testUtils.CBORValue("Sony"), deviceDocID, ""), - "docID": deviceDocID, - "fieldName": "manufacturer", - }, - { - "delta": encrypt(testUtils.CBORValue("Walkman"), deviceDocID, ""), - "docID": deviceDocID, - "fieldName": "model", - }, - { - "delta": encrypt(testUtils.CBORValue(userDocID), deviceDocID, ""), - "docID": deviceDocID, - "fieldName": "owner_id", - }, - { - "delta": nil, - "docID": deviceDocID, - "fieldName": nil, + Results: map[string]any{ + "commits": []map[string]any{ + { + "delta": encrypt(testUtils.CBORValue("Chris"), userDocID, ""), + "docID": userDocID, + "fieldName": "name", + }, + { + "delta": nil, + "docID": userDocID, + "fieldName": nil, + }, + { + "delta": encrypt(testUtils.CBORValue("Sony"), deviceDocID, ""), + "docID": deviceDocID, + "fieldName": "manufacturer", + }, + { + "delta": encrypt(testUtils.CBORValue("Walkman"), deviceDocID, ""), + "docID": deviceDocID, + "fieldName": "model", + }, + { + "delta": encrypt(testUtils.CBORValue(userDocID), deviceDocID, ""), + "docID": deviceDocID, + "fieldName": "owner_id", + }, + { + "delta": nil, + "docID": deviceDocID, + "fieldName": nil, + }, }, }, }, diff --git a/tests/integration/encryption/commit_test.go b/tests/integration/encryption/commit_test.go index ffa5333748..86ea5d88df 100644 --- a/tests/integration/encryption/commit_test.go +++ b/tests/integration/encryption/commit_test.go @@ -45,43 +45,45 @@ func TestDocEncryption_WithEncryptionOnLWWCRDT_ShouldStoreCommitsDeltaEncrypted( } } `, - Results: []map[string]any{ - { - "cid": "bafyreibdjepzhhiez4o27srv33xcd52yr336tpzqtkv36rdf3h3oue2l5m", - "collectionID": int64(1), - "delta": encrypt(testUtils.CBORValue(21), john21DocID, ""), - "docID": john21DocID, - "fieldId": "1", - "fieldName": "age", - "height": int64(1), - "links": []map[string]any{}, - }, - { - "cid": "bafyreihkiua7jpwkye3xlex6s5hh2azckcaljfi2h3iscgub5sikacyrbu", - "collectionID": int64(1), - "delta": encrypt(testUtils.CBORValue("John"), john21DocID, ""), - "docID": john21DocID, - "fieldId": "2", - "fieldName": "name", - "height": int64(1), - "links": []map[string]any{}, - }, - { - "cid": "bafyreidxdhzhwjrv5s4x6cho5drz6xq2tc7oymzupf4p4gfk6eelsnc7ke", - "collectionID": int64(1), - "delta": nil, - "docID": john21DocID, - "fieldId": "C", - "fieldName": nil, - "height": int64(1), - "links": []map[string]any{ - { - "cid": "bafyreibdjepzhhiez4o27srv33xcd52yr336tpzqtkv36rdf3h3oue2l5m", - "name": "age", - }, - { - "cid": "bafyreihkiua7jpwkye3xlex6s5hh2azckcaljfi2h3iscgub5sikacyrbu", - "name": "name", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreibdjepzhhiez4o27srv33xcd52yr336tpzqtkv36rdf3h3oue2l5m", + "collectionID": int64(1), + "delta": encrypt(testUtils.CBORValue(21), john21DocID, ""), + "docID": john21DocID, + "fieldId": "1", + "fieldName": "age", + "height": int64(1), + "links": []map[string]any{}, + }, + { + "cid": "bafyreihkiua7jpwkye3xlex6s5hh2azckcaljfi2h3iscgub5sikacyrbu", + "collectionID": int64(1), + "delta": encrypt(testUtils.CBORValue("John"), john21DocID, ""), + "docID": john21DocID, + "fieldId": "2", + "fieldName": "name", + "height": int64(1), + "links": []map[string]any{}, + }, + { + "cid": "bafyreidxdhzhwjrv5s4x6cho5drz6xq2tc7oymzupf4p4gfk6eelsnc7ke", + "collectionID": int64(1), + "delta": nil, + "docID": john21DocID, + "fieldId": "C", + "fieldName": nil, + "height": int64(1), + "links": []map[string]any{ + { + "cid": "bafyreibdjepzhhiez4o27srv33xcd52yr336tpzqtkv36rdf3h3oue2l5m", + "name": "age", + }, + { + "cid": "bafyreihkiua7jpwkye3xlex6s5hh2azckcaljfi2h3iscgub5sikacyrbu", + "name": "name", + }, }, }, }, @@ -114,12 +116,14 @@ func TestDocEncryption_UponUpdateOnLWWCRDT_ShouldEncryptCommitDelta(t *testing.T } } `, - Results: []map[string]any{ - { - "delta": encrypt(testUtils.CBORValue(22), john21DocID, ""), - }, - { - "delta": encrypt(testUtils.CBORValue(21), john21DocID, ""), + Results: map[string]any{ + "commits": []map[string]any{ + { + "delta": encrypt(testUtils.CBORValue(22), john21DocID, ""), + }, + { + "delta": encrypt(testUtils.CBORValue(21), john21DocID, ""), + }, }, }, }, @@ -161,22 +165,24 @@ func TestDocEncryption_WithMultipleDocsUponUpdate_ShouldEncryptOnlyRelevantDocs( } } `, - Results: []map[string]any{ - { - "delta": encrypt(testUtils.CBORValue(22), john21DocID, ""), - "docID": john21DocID, - }, - { - "delta": encrypt(testUtils.CBORValue(21), john21DocID, ""), - "docID": john21DocID, - }, - { - "delta": testUtils.CBORValue(34), - "docID": islam33DocID, - }, - { - "delta": testUtils.CBORValue(33), - "docID": islam33DocID, + Results: map[string]any{ + "commits": []map[string]any{ + { + "delta": encrypt(testUtils.CBORValue(22), john21DocID, ""), + "docID": john21DocID, + }, + { + "delta": encrypt(testUtils.CBORValue(21), john21DocID, ""), + "docID": john21DocID, + }, + { + "delta": testUtils.CBORValue(34), + "docID": islam33DocID, + }, + { + "delta": testUtils.CBORValue(33), + "docID": islam33DocID, + }, }, }, }, @@ -210,14 +216,16 @@ func TestDocEncryption_WithEncryptionOnCounterCRDT_ShouldStoreCommitsDeltaEncryp } } `, - Results: []map[string]any{ - { - "delta": encrypt(testUtils.CBORValue(5), docID, ""), - "docID": docID, - }, - { - "delta": nil, - "docID": docID, + Results: map[string]any{ + "commits": []map[string]any{ + { + "delta": encrypt(testUtils.CBORValue(5), docID, ""), + "docID": docID, + }, + { + "delta": nil, + "docID": docID, + }, }, }, }, @@ -255,12 +263,14 @@ func TestDocEncryption_UponUpdateOnCounterCRDT_ShouldEncryptedCommitDelta(t *tes } } `, - Results: []map[string]any{ - { - "delta": encrypt(testUtils.CBORValue(3), docID, ""), - }, - { - "delta": encrypt(testUtils.CBORValue(5), docID, ""), + Results: map[string]any{ + "commits": []map[string]any{ + { + "delta": encrypt(testUtils.CBORValue(3), docID, ""), + }, + { + "delta": encrypt(testUtils.CBORValue(5), docID, ""), + }, }, }, }, @@ -287,30 +297,32 @@ func TestDocEncryption_UponEncryptionSeveralDocs_ShouldStoreAllCommitsDeltaEncry } } `, - Results: []map[string]any{ - { - "delta": encrypt(testUtils.CBORValue(21), john21DocID, ""), - "docID": testUtils.NewDocIndex(0, 0), - }, - { - "delta": encrypt(testUtils.CBORValue("John"), john21DocID, ""), - "docID": testUtils.NewDocIndex(0, 0), - }, - { - "delta": nil, - "docID": testUtils.NewDocIndex(0, 0), - }, - { - "delta": encrypt(testUtils.CBORValue(33), islam33DocID, ""), - "docID": testUtils.NewDocIndex(0, 1), - }, - { - "delta": encrypt(testUtils.CBORValue("Islam"), islam33DocID, ""), - "docID": testUtils.NewDocIndex(0, 1), - }, - { - "delta": nil, - "docID": testUtils.NewDocIndex(0, 1), + Results: map[string]any{ + "commits": []map[string]any{ + { + "delta": encrypt(testUtils.CBORValue(21), john21DocID, ""), + "docID": testUtils.NewDocIndex(0, 0), + }, + { + "delta": encrypt(testUtils.CBORValue("John"), john21DocID, ""), + "docID": testUtils.NewDocIndex(0, 0), + }, + { + "delta": nil, + "docID": testUtils.NewDocIndex(0, 0), + }, + { + "delta": encrypt(testUtils.CBORValue(33), islam33DocID, ""), + "docID": testUtils.NewDocIndex(0, 1), + }, + { + "delta": encrypt(testUtils.CBORValue("Islam"), islam33DocID, ""), + "docID": testUtils.NewDocIndex(0, 1), + }, + { + "delta": nil, + "docID": testUtils.NewDocIndex(0, 1), + }, }, }, }, @@ -347,11 +359,12 @@ func TestDocEncryption_IfTwoDocsHaveSameFieldValue_CipherTextShouldBeDifferent(t } } `, - Asserter: testUtils.ResultAsserterFunc(func(_ testing.TB, result []map[string]any) (bool, string) { - require.Equal(t, 2, len(result), "Expected 2 commits") - require.Equal(t, result[0]["fieldName"], "age") - delta1 := result[0]["delta"] - delta2 := result[1]["delta"] + Asserter: testUtils.ResultAsserterFunc(func(t testing.TB, result map[string]any) (bool, string) { + commits := testUtils.ConvertToArrayOfMaps(t, result["commits"]) + require.Equal(t, 2, len(commits), "Expected 2 commits") + require.Equal(t, commits[0]["fieldName"], "age") + delta1 := commits[0]["delta"] + delta2 := commits[1]["delta"] assert.NotEqual(t, delta1, delta2, "docs should be encrypted with different encryption keys") return true, "" }), diff --git a/tests/integration/encryption/field_commit_test.go b/tests/integration/encryption/field_commit_test.go index 5a956a42b2..e1531bca1c 100644 --- a/tests/integration/encryption/field_commit_test.go +++ b/tests/integration/encryption/field_commit_test.go @@ -36,21 +36,23 @@ func TestDocEncryptionField_WithEncryptionOnField_ShouldStoreOnlyFieldsDeltaEncr } } `, - Results: []map[string]any{ - { - "delta": encrypt(testUtils.CBORValue(21), john21DocID, "age"), - "docID": john21DocID, - "fieldName": "age", - }, - { - "delta": testUtils.CBORValue("John"), - "docID": john21DocID, - "fieldName": "name", - }, - { - "delta": nil, - "docID": john21DocID, - "fieldName": nil, + Results: map[string]any{ + "commits": []map[string]any{ + { + "delta": encrypt(testUtils.CBORValue(21), john21DocID, "age"), + "docID": john21DocID, + "fieldName": "age", + }, + { + "delta": testUtils.CBORValue("John"), + "docID": john21DocID, + "fieldName": "name", + }, + { + "delta": nil, + "docID": john21DocID, + "fieldName": nil, + }, }, }, }, @@ -102,11 +104,12 @@ func TestDocEncryptionField_WithDocAndFieldEncryption_ShouldUseDedicatedEncKeyFo } } `, - Asserter: testUtils.ResultAsserterFunc(func(_ testing.TB, result []map[string]any) (bool, string) { - name1 := deltaForField("name1", result) - name2 := deltaForField("name2", result) - name3 := deltaForField("name3", result) - name4 := deltaForField("name4", result) + Asserter: testUtils.ResultAsserterFunc(func(t testing.TB, result map[string]any) (bool, string) { + commits := testUtils.ConvertToArrayOfMaps(t, result["commits"]) + name1 := deltaForField("name1", commits) + name2 := deltaForField("name2", commits) + name3 := deltaForField("name3", commits) + name4 := deltaForField("name4", commits) assert.Equal(t, name2, name4, "name2 and name4 should have the same encryption key") assert.NotEqual(t, name2, name1, "name2 and name1 should have different encryption keys") assert.NotEqual(t, name2, name3, "name2 and name3 should have different encryption keys") @@ -171,11 +174,12 @@ func TestDocEncryptionField_UponUpdateWithDocAndFieldEncryption_ShouldUseDedicat } } `, - Asserter: testUtils.ResultAsserterFunc(func(_ testing.TB, result []map[string]any) (bool, string) { - name1 := deltaForField("name1", result) - name2 := deltaForField("name2", result) - name3 := deltaForField("name3", result) - name4 := deltaForField("name4", result) + Asserter: testUtils.ResultAsserterFunc(func(_ testing.TB, result map[string]any) (bool, string) { + commits := testUtils.ConvertToArrayOfMaps(t, result["commits"]) + name1 := deltaForField("name1", commits) + name2 := deltaForField("name2", commits) + name3 := deltaForField("name3", commits) + name4 := deltaForField("name4", commits) assert.Equal(t, name2, name4, "name2 and name4 should have the same encryption key") assert.NotEqual(t, name2, name1, "name2 and name1 should have different encryption keys") assert.NotEqual(t, name2, name3, "name2 and name3 should have different encryption keys") diff --git a/tests/integration/encryption/field_query_test.go b/tests/integration/encryption/field_query_test.go index d008960448..acf4ada937 100644 --- a/tests/integration/encryption/field_query_test.go +++ b/tests/integration/encryption/field_query_test.go @@ -39,11 +39,13 @@ func TestDocEncryptionField_WithEncryption_ShouldFetchDecrypted(t *testing.T) { age } }`, - Results: []map[string]any{ - { - "_docID": testUtils.NewDocIndex(0, 0), - "name": "John", - "age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": testUtils.NewDocIndex(0, 0), + "name": "John", + "age": int64(21), + }, }, }, }, diff --git a/tests/integration/encryption/peer_test.go b/tests/integration/encryption/peer_test.go index 4eb0ddc19a..7a94c22e13 100644 --- a/tests/integration/encryption/peer_test.go +++ b/tests/integration/encryption/peer_test.go @@ -45,7 +45,9 @@ func TestDocEncryptionPeer_IfPeerHasNoKey_ShouldNotFetch(t *testing.T) { age } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -92,43 +94,45 @@ func TestDocEncryptionPeer_UponSync_ShouldSyncEncryptedDAG(t *testing.T) { } } `, - Results: []map[string]any{ - { - "cid": "bafyreibdjepzhhiez4o27srv33xcd52yr336tpzqtkv36rdf3h3oue2l5m", - "collectionID": int64(1), - "delta": encrypt(testUtils.CBORValue(21), john21DocID, ""), - "docID": john21DocID, - "fieldId": "1", - "fieldName": "age", - "height": int64(1), - "links": []map[string]any{}, - }, - { - "cid": "bafyreihkiua7jpwkye3xlex6s5hh2azckcaljfi2h3iscgub5sikacyrbu", - "collectionID": int64(1), - "delta": encrypt(testUtils.CBORValue("John"), john21DocID, ""), - "docID": john21DocID, - "fieldId": "2", - "fieldName": "name", - "height": int64(1), - "links": []map[string]any{}, - }, - { - "cid": "bafyreidxdhzhwjrv5s4x6cho5drz6xq2tc7oymzupf4p4gfk6eelsnc7ke", - "collectionID": int64(1), - "delta": nil, - "docID": john21DocID, - "fieldId": "C", - "fieldName": nil, - "height": int64(1), - "links": []map[string]any{ - { - "cid": "bafyreibdjepzhhiez4o27srv33xcd52yr336tpzqtkv36rdf3h3oue2l5m", - "name": "age", - }, - { - "cid": "bafyreihkiua7jpwkye3xlex6s5hh2azckcaljfi2h3iscgub5sikacyrbu", - "name": "name", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreibdjepzhhiez4o27srv33xcd52yr336tpzqtkv36rdf3h3oue2l5m", + "collectionID": int64(1), + "delta": encrypt(testUtils.CBORValue(21), john21DocID, ""), + "docID": john21DocID, + "fieldId": "1", + "fieldName": "age", + "height": int64(1), + "links": []map[string]any{}, + }, + { + "cid": "bafyreihkiua7jpwkye3xlex6s5hh2azckcaljfi2h3iscgub5sikacyrbu", + "collectionID": int64(1), + "delta": encrypt(testUtils.CBORValue("John"), john21DocID, ""), + "docID": john21DocID, + "fieldId": "2", + "fieldName": "name", + "height": int64(1), + "links": []map[string]any{}, + }, + { + "cid": "bafyreidxdhzhwjrv5s4x6cho5drz6xq2tc7oymzupf4p4gfk6eelsnc7ke", + "collectionID": int64(1), + "delta": nil, + "docID": john21DocID, + "fieldId": "C", + "fieldName": nil, + "height": int64(1), + "links": []map[string]any{ + { + "cid": "bafyreibdjepzhhiez4o27srv33xcd52yr336tpzqtkv36rdf3h3oue2l5m", + "name": "age", + }, + { + "cid": "bafyreihkiua7jpwkye3xlex6s5hh2azckcaljfi2h3iscgub5sikacyrbu", + "name": "name", + }, }, }, }, diff --git a/tests/integration/encryption/query_relation_test.go b/tests/integration/encryption/query_relation_test.go index 8ca51c03aa..fb9a0b0730 100644 --- a/tests/integration/encryption/query_relation_test.go +++ b/tests/integration/encryption/query_relation_test.go @@ -59,13 +59,15 @@ func TestDocEncryption_WithEncryptionOnBothRelations_ShouldFetchDecrypted(t *tes } } }`, - Results: []map[string]any{ - { - "name": "Chris", - "devices": []map[string]any{ - { - "model": "Walkman", - "manufacturer": "Sony", + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Chris", + "devices": []map[string]any{ + { + "model": "Walkman", + "manufacturer": "Sony", + }, }, }, }, @@ -119,13 +121,15 @@ func TestDocEncryption_WithEncryptionOnPrimaryRelations_ShouldFetchDecrypted(t * } } }`, - Results: []map[string]any{ - { - "name": "Chris", - "devices": []map[string]any{ - { - "model": "Walkman", - "manufacturer": "Sony", + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Chris", + "devices": []map[string]any{ + { + "model": "Walkman", + "manufacturer": "Sony", + }, }, }, }, @@ -179,13 +183,15 @@ func TestDocEncryption_WithEncryptionOnSecondaryRelations_ShouldFetchDecrypted(t } } }`, - Results: []map[string]any{ - { - "name": "Chris", - "devices": []map[string]any{ - { - "model": "Walkman", - "manufacturer": "Sony", + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Chris", + "devices": []map[string]any{ + { + "model": "Walkman", + "manufacturer": "Sony", + }, }, }, }, diff --git a/tests/integration/encryption/query_test.go b/tests/integration/encryption/query_test.go index 05e7b1dcdd..a949081120 100644 --- a/tests/integration/encryption/query_test.go +++ b/tests/integration/encryption/query_test.go @@ -39,11 +39,13 @@ func TestDocEncryption_WithEncryption_ShouldFetchDecrypted(t *testing.T) { age } }`, - Results: []map[string]any{ - { - "_docID": testUtils.NewDocIndex(0, 0), - "name": "John", - "age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": testUtils.NewDocIndex(0, 0), + "name": "John", + "age": int64(21), + }, }, }, }, @@ -80,10 +82,12 @@ func TestDocEncryption_WithEncryptionOnCounterCRDT_ShouldFetchDecrypted(t *testi }, testUtils.Request{ Request: query, - Results: []map[string]any{ - { - "name": "John", - "points": 5, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "points": 5, + }, }, }, }, @@ -93,10 +97,12 @@ func TestDocEncryption_WithEncryptionOnCounterCRDT_ShouldFetchDecrypted(t *testi }, testUtils.Request{ Request: query, - Results: []map[string]any{ - { - "name": "John", - "points": 8, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "points": 8, + }, }, }, }, diff --git a/tests/integration/explain.go b/tests/integration/explain.go index fafab87134..7bc7f9074a 100644 --- a/tests/integration/explain.go +++ b/tests/integration/explain.go @@ -57,6 +57,7 @@ var ( "valuesNode": {}, "viewNode": {}, "lensNode": {}, + "operationNode": {}, } ) @@ -86,12 +87,12 @@ type ExplainRequest struct { // The raw expected explain graph with everything (helpful for debugging purposes). // Note: This is not always asserted (i.e. ignored from the comparison if not provided). - ExpectedFullGraph []map[string]any + ExpectedFullGraph map[string]any // Pattern is used to assert that the plan nodes are in the correct order (attributes are omitted). // Note: - Explain requests of type 'debug' will only have Pattern (as they don't have attributes). // - This is not always asserted (i.e. ignored from the comparison if not provided). - ExpectedPatterns []map[string]any + ExpectedPatterns map[string]any // Every target helps assert an individual node somewhere in the explain graph (node's position is omitted). // Each target assertion is only responsible to check if the node's attributes are correct. @@ -156,42 +157,33 @@ func assertExplainRequestResults( } // Note: if returned gql result is `nil` this panics (the panic seems useful while testing). - resultantData := actualResult.Data.([]map[string]any) + resultantData := actualResult.Data.(map[string]any) log.InfoContext(s.ctx, "", corelog.Any("FullExplainGraphResult", actualResult.Data)) // Check if the expected full explain graph (if provided) matches the actual full explain graph // that is returned, if doesn't match we would like to still see a diff comparison (handy while debugging). - if lengthOfExpectedFullGraph := len(action.ExpectedFullGraph); action.ExpectedFullGraph != nil { - require.Equal(s.t, lengthOfExpectedFullGraph, len(resultantData), s.testCase.Description) - for index, actualResult := range resultantData { - if lengthOfExpectedFullGraph > index { - assertResultsEqual( - s.t, - s.clientType, - action.ExpectedFullGraph[index], - actualResult, - s.testCase.Description, - ) - } - } + if action.ExpectedFullGraph != nil { + assertResultsEqual( + s.t, + s.clientType, + action.ExpectedFullGraph, + resultantData, + s.testCase.Description, + ) } // Ensure the complete high-level pattern matches, inother words check that all the // explain graph nodes are in the correct expected ordering. if action.ExpectedPatterns != nil { - require.Equal(s.t, len(action.ExpectedPatterns), len(resultantData), s.testCase.Description) - - for index, actualResult := range resultantData { - // Trim away all attributes (non-plan nodes) from the returned full explain graph result. - actualResultWithoutAttributes := trimExplainAttributes(s.t, s.testCase.Description, actualResult) - assertResultsEqual( - s.t, - s.clientType, - action.ExpectedPatterns[index], - actualResultWithoutAttributes, - s.testCase.Description, - ) - } + // Trim away all attributes (non-plan nodes) from the returned full explain graph result. + actualResultWithoutAttributes := trimExplainAttributes(s.t, s.testCase.Description, resultantData) + assertResultsEqual( + s.t, + s.clientType, + action.ExpectedPatterns, + actualResultWithoutAttributes, + s.testCase.Description, + ) } // Match the targeted node's attributes (subset assertions), with the expected attributes. @@ -206,7 +198,7 @@ func assertExplainRequestResults( func assertExplainTargetCase( s *state, targetCase PlanNodeTargetCase, - actualResults []map[string]any, + actualResults map[string]any, ) { for _, actualResult := range actualResults { foundActualTarget, _, isFound := findTargetNode( diff --git a/tests/integration/explain/debug/basic_test.go b/tests/integration/explain/debug/basic_test.go index f97305d091..68be571469 100644 --- a/tests/integration/explain/debug/basic_test.go +++ b/tests/integration/explain/debug/basic_test.go @@ -32,7 +32,7 @@ func TestDebugExplainRequest(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{basicPattern}, + ExpectedFullGraph: basicPattern, }, }, } diff --git a/tests/integration/explain/debug/create_test.go b/tests/integration/explain/debug/create_test.go index 21d334bb84..dc43fc5365 100644 --- a/tests/integration/explain/debug/create_test.go +++ b/tests/integration/explain/debug/create_test.go @@ -19,10 +19,14 @@ import ( var createPattern = dataMap{ "explain": dataMap{ - "createNode": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "createNode": dataMap{ + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -45,7 +49,7 @@ func TestDebugExplainMutationRequestWithCreate(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{createPattern}, + ExpectedPatterns: createPattern, }, }, } @@ -69,7 +73,7 @@ func TestDebugExplainMutationRequestDoesNotCreateDocGivenDuplicate(t *testing.T) } }`, - ExpectedPatterns: []dataMap{createPattern}, + ExpectedPatterns: createPattern, }, }, } diff --git a/tests/integration/explain/debug/dagscan_test.go b/tests/integration/explain/debug/dagscan_test.go index 8da73b747f..868b048915 100644 --- a/tests/integration/explain/debug/dagscan_test.go +++ b/tests/integration/explain/debug/dagscan_test.go @@ -19,9 +19,13 @@ import ( var dagScanPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "dagScanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "dagScanNode": dataMap{}, + }, + }, }, }, }, @@ -45,7 +49,7 @@ func TestDebugExplainCommitsDagScanQueryOp(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{dagScanPattern}, + ExpectedFullGraph: dagScanPattern, }, }, } @@ -71,7 +75,7 @@ func TestDebugExplainCommitsDagScanQueryOpWithoutField(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{dagScanPattern}, + ExpectedFullGraph: dagScanPattern, }, }, } @@ -98,7 +102,7 @@ func TestDebugExplainLatestCommitsDagScanQueryOp(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{dagScanPattern}, + ExpectedFullGraph: dagScanPattern, }, }, } @@ -125,7 +129,7 @@ func TestDebugExplainLatestCommitsDagScanQueryOpWithoutField(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{dagScanPattern}, + ExpectedFullGraph: dagScanPattern, }, }, } diff --git a/tests/integration/explain/debug/delete_test.go b/tests/integration/explain/debug/delete_test.go index 88159152e0..7162b1b428 100644 --- a/tests/integration/explain/debug/delete_test.go +++ b/tests/integration/explain/debug/delete_test.go @@ -19,10 +19,14 @@ import ( var deletePattern = dataMap{ "explain": dataMap{ - "deleteNode": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "deleteNode": dataMap{ + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -45,7 +49,7 @@ func TestDebugExplainMutationRequestWithDeleteUsingFilter(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{deletePattern}, + ExpectedPatterns: deletePattern, }, }, } @@ -69,7 +73,7 @@ func TestDebugExplainMutationRequestWithDeleteUsingFilterToMatchEverything(t *te } }`, - ExpectedPatterns: []dataMap{deletePattern}, + ExpectedPatterns: deletePattern, }, }, } @@ -93,7 +97,7 @@ func TestDebugExplainMutationRequestWithDeleteUsingId(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{deletePattern}, + ExpectedPatterns: deletePattern, }, }, } @@ -120,7 +124,7 @@ func TestDebugExplainMutationRequestWithDeleteUsingIds(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{deletePattern}, + ExpectedPatterns: deletePattern, }, }, } @@ -144,7 +148,7 @@ func TestDebugExplainMutationRequestWithDeleteUsingNoIds(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{deletePattern}, + ExpectedPatterns: deletePattern, }, }, } @@ -176,7 +180,7 @@ func TestDebugExplainMutationRequestWithDeleteUsingFilterAndIds(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{deletePattern}, + ExpectedPatterns: deletePattern, }, }, } diff --git a/tests/integration/explain/debug/fixture.go b/tests/integration/explain/debug/fixture.go index f77c0a3839..5a149eed36 100644 --- a/tests/integration/explain/debug/fixture.go +++ b/tests/integration/explain/debug/fixture.go @@ -14,9 +14,13 @@ type dataMap = map[string]any var basicPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, diff --git a/tests/integration/explain/debug/group_test.go b/tests/integration/explain/debug/group_test.go index af738627b8..3300523313 100644 --- a/tests/integration/explain/debug/group_test.go +++ b/tests/integration/explain/debug/group_test.go @@ -19,11 +19,15 @@ import ( var groupPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "groupNode": dataMap{ - "selectNode": dataMap{ - "pipeNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "groupNode": dataMap{ + "selectNode": dataMap{ + "pipeNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -50,7 +54,7 @@ func TestDebugExplainRequestWithGroupByOnParent(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{groupPattern}, + ExpectedFullGraph: groupPattern, }, }, } @@ -77,7 +81,7 @@ func TestDebugExplainRequestWithGroupByTwoFieldsOnParent(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{groupPattern}, + ExpectedFullGraph: groupPattern, }, }, } diff --git a/tests/integration/explain/debug/group_with_average_test.go b/tests/integration/explain/debug/group_with_average_test.go index e001c1a529..1586a37649 100644 --- a/tests/integration/explain/debug/group_with_average_test.go +++ b/tests/integration/explain/debug/group_with_average_test.go @@ -19,14 +19,18 @@ import ( var debugGroupAveragePattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "averageNode": dataMap{ - "countNode": dataMap{ - "sumNode": dataMap{ - "groupNode": dataMap{ - "selectNode": dataMap{ - "pipeNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "averageNode": dataMap{ + "countNode": dataMap{ + "sumNode": dataMap{ + "groupNode": dataMap{ + "selectNode": dataMap{ + "pipeNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -54,7 +58,7 @@ func TestDebugExplainRequestWithGroupByWithAverageOnAnInnerField(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{debugGroupAveragePattern}, + ExpectedPatterns: debugGroupAveragePattern, }, }, } @@ -83,7 +87,7 @@ func TestDebugExplainRequestWithAverageInsideTheInnerGroupOnAField(t *testing.T) } }`, - ExpectedPatterns: []dataMap{debugGroupAveragePattern}, + ExpectedPatterns: debugGroupAveragePattern, }, }, } @@ -115,7 +119,7 @@ func TestDebugExplainRequestWithAverageInsideTheInnerGroupOnAFieldAndNestedGroup } }`, - ExpectedPatterns: []dataMap{debugGroupAveragePattern}, + ExpectedPatterns: debugGroupAveragePattern, }, }, } @@ -148,7 +152,7 @@ func TestDebugExplainRequestWithAverageInsideTheInnerGroupAndNestedGroupByWithAv } }`, - ExpectedPatterns: []dataMap{debugGroupAveragePattern}, + ExpectedPatterns: debugGroupAveragePattern, }, }, } diff --git a/tests/integration/explain/debug/group_with_doc_id_child_test.go b/tests/integration/explain/debug/group_with_doc_id_child_test.go index 43301f1fac..7da680dbbc 100644 --- a/tests/integration/explain/debug/group_with_doc_id_child_test.go +++ b/tests/integration/explain/debug/group_with_doc_id_child_test.go @@ -38,7 +38,7 @@ func TestDebugExplainRequestWithDocIDsOnInnerGroupSelection(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, }, }, } diff --git a/tests/integration/explain/debug/group_with_doc_id_test.go b/tests/integration/explain/debug/group_with_doc_id_test.go index ebbfbdb3c9..75728e77e0 100644 --- a/tests/integration/explain/debug/group_with_doc_id_test.go +++ b/tests/integration/explain/debug/group_with_doc_id_test.go @@ -39,7 +39,7 @@ func TestDebugExplainRequestWithDocIDOnParentGroupBy(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, }, }, } @@ -73,7 +73,7 @@ func TestDebugExplainRequestWithDocIDsAndFilterOnParentGroupBy(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, }, }, } diff --git a/tests/integration/explain/debug/group_with_filter_child_test.go b/tests/integration/explain/debug/group_with_filter_child_test.go index 61a8a72f3e..7da654f8d1 100644 --- a/tests/integration/explain/debug/group_with_filter_child_test.go +++ b/tests/integration/explain/debug/group_with_filter_child_test.go @@ -36,7 +36,7 @@ func TestDebugExplainRequestWithFilterOnInnerGroupSelection(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, }, }, } @@ -66,7 +66,7 @@ func TestDebugExplainRequestWithFilterOnParentGroupByAndInnerGroupSelection(t *t } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, }, }, } diff --git a/tests/integration/explain/debug/group_with_filter_test.go b/tests/integration/explain/debug/group_with_filter_test.go index b55d798c3a..62785a98a8 100644 --- a/tests/integration/explain/debug/group_with_filter_test.go +++ b/tests/integration/explain/debug/group_with_filter_test.go @@ -39,7 +39,7 @@ func TestDebugExplainRequestWithFilterOnGroupByParent(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, }, }, } diff --git a/tests/integration/explain/debug/group_with_limit_child_test.go b/tests/integration/explain/debug/group_with_limit_child_test.go index 335c8866f0..f6e938350a 100644 --- a/tests/integration/explain/debug/group_with_limit_child_test.go +++ b/tests/integration/explain/debug/group_with_limit_child_test.go @@ -36,7 +36,7 @@ func TestDebugExplainRequestWithLimitAndOffsetOnInnerGroupSelection(t *testing.T } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, }, }, } @@ -66,7 +66,7 @@ func TestDebugExplainRequestWithLimitAndOffsetOnMultipleInnerGroupSelections(t * } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, }, }, } diff --git a/tests/integration/explain/debug/group_with_limit_test.go b/tests/integration/explain/debug/group_with_limit_test.go index 82c84969fc..af5b0afa37 100644 --- a/tests/integration/explain/debug/group_with_limit_test.go +++ b/tests/integration/explain/debug/group_with_limit_test.go @@ -19,12 +19,16 @@ import ( var debugGroupLimitPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "limitNode": dataMap{ - "groupNode": dataMap{ - "selectNode": dataMap{ - "pipeNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "limitNode": dataMap{ + "groupNode": dataMap{ + "selectNode": dataMap{ + "pipeNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -56,7 +60,7 @@ func TestDebugExplainRequestWithLimitAndOffsetOnParentGroupBy(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{debugGroupLimitPattern}, + ExpectedPatterns: debugGroupLimitPattern, }, }, } @@ -86,7 +90,7 @@ func TestDebugExplainRequestWithLimitOnParentGroupByAndInnerGroupSelection(t *te } }`, - ExpectedPatterns: []dataMap{debugGroupLimitPattern}, + ExpectedPatterns: debugGroupLimitPattern, }, }, } diff --git a/tests/integration/explain/debug/group_with_order_child_test.go b/tests/integration/explain/debug/group_with_order_child_test.go index 19d97424dc..e2e9681dad 100644 --- a/tests/integration/explain/debug/group_with_order_child_test.go +++ b/tests/integration/explain/debug/group_with_order_child_test.go @@ -36,7 +36,7 @@ func TestDebugExplainRequestWithDescendingOrderOnInnerGroupSelection(t *testing. } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, }, }, } @@ -63,7 +63,7 @@ func TestDebugExplainRequestWithAscendingOrderOnInnerGroupSelection(t *testing.T } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, }, }, } @@ -96,7 +96,7 @@ func TestDebugExplainRequestWithOrderOnNestedParentGroupByAndOnNestedParentsInne } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, }, }, } diff --git a/tests/integration/explain/debug/group_with_order_test.go b/tests/integration/explain/debug/group_with_order_test.go index a7e3b717b0..9379c9088c 100644 --- a/tests/integration/explain/debug/group_with_order_test.go +++ b/tests/integration/explain/debug/group_with_order_test.go @@ -19,12 +19,16 @@ import ( var debugGroupOrderPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "orderNode": dataMap{ - "groupNode": dataMap{ - "selectNode": dataMap{ - "pipeNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "orderNode": dataMap{ + "groupNode": dataMap{ + "selectNode": dataMap{ + "pipeNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -55,7 +59,7 @@ func TestDebugExplainRequestWithDescendingOrderOnParentGroupBy(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{debugGroupOrderPattern}, + ExpectedPatterns: debugGroupOrderPattern, }, }, } @@ -85,7 +89,7 @@ func TestDebugExplainRequestWithAscendingOrderOnParentGroupBy(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{debugGroupOrderPattern}, + ExpectedPatterns: debugGroupOrderPattern, }, }, } @@ -115,7 +119,7 @@ func TestDebugExplainRequestWithOrderOnParentGroupByAndOnInnerGroupSelection(t * } }`, - ExpectedPatterns: []dataMap{debugGroupOrderPattern}, + ExpectedPatterns: debugGroupOrderPattern, }, }, } diff --git a/tests/integration/explain/debug/top_with_average_test.go b/tests/integration/explain/debug/top_with_average_test.go index de16b72c4b..a5b656ab7f 100644 --- a/tests/integration/explain/debug/top_with_average_test.go +++ b/tests/integration/explain/debug/top_with_average_test.go @@ -19,23 +19,27 @@ import ( var topLevelAveragePattern = dataMap{ "explain": dataMap{ - "topLevelNode": []dataMap{ + "operationNode": []dataMap{ { - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "topLevelNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, + }, + { + "sumNode": dataMap{}, + }, + { + "countNode": dataMap{}, + }, + { + "averageNode": dataMap{}, }, }, }, - { - "sumNode": dataMap{}, - }, - { - "countNode": dataMap{}, - }, - { - "averageNode": dataMap{}, - }, }, }, } @@ -58,7 +62,7 @@ func TestDebugExplainTopLevelAverageRequest(t *testing.T) { ) }`, - ExpectedPatterns: []dataMap{topLevelAveragePattern}, + ExpectedPatterns: topLevelAveragePattern, }, }, } @@ -89,7 +93,7 @@ func TestDebugExplainTopLevelAverageRequestWithFilter(t *testing.T) { ) }`, - ExpectedPatterns: []dataMap{topLevelAveragePattern}, + ExpectedPatterns: topLevelAveragePattern, }, }, } diff --git a/tests/integration/explain/debug/top_with_count_test.go b/tests/integration/explain/debug/top_with_count_test.go index cceb3d1467..5dd40860bf 100644 --- a/tests/integration/explain/debug/top_with_count_test.go +++ b/tests/integration/explain/debug/top_with_count_test.go @@ -19,17 +19,21 @@ import ( var topLevelCountPattern = dataMap{ "explain": dataMap{ - "topLevelNode": []dataMap{ + "operationNode": []dataMap{ { - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "topLevelNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, + }, + { + "countNode": dataMap{}, }, }, }, - { - "countNode": dataMap{}, - }, }, }, } @@ -48,7 +52,7 @@ func TestDebugExplainTopLevelCountRequest(t *testing.T) { _count(Author: {}) }`, - ExpectedPatterns: []dataMap{topLevelCountPattern}, + ExpectedPatterns: topLevelCountPattern, }, }, } @@ -78,7 +82,7 @@ func TestDebugExplainTopLevelCountRequestWithFilter(t *testing.T) { ) }`, - ExpectedPatterns: []dataMap{topLevelCountPattern}, + ExpectedPatterns: topLevelCountPattern, }, }, } diff --git a/tests/integration/explain/debug/top_with_sum_test.go b/tests/integration/explain/debug/top_with_sum_test.go index ba2381a7cf..3c6250c607 100644 --- a/tests/integration/explain/debug/top_with_sum_test.go +++ b/tests/integration/explain/debug/top_with_sum_test.go @@ -19,17 +19,21 @@ import ( var topLevelSumPattern = dataMap{ "explain": dataMap{ - "topLevelNode": []dataMap{ + "operationNode": []dataMap{ { - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "topLevelNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, + }, + { + "sumNode": dataMap{}, }, }, }, - { - "sumNode": dataMap{}, - }, }, }, } @@ -52,7 +56,7 @@ func TestDebugExplainTopLevelSumRequest(t *testing.T) { ) }`, - ExpectedPatterns: []dataMap{topLevelSumPattern}, + ExpectedPatterns: topLevelSumPattern, }, }, } @@ -83,7 +87,7 @@ func TestDebugExplainTopLevelSumRequestWithFilter(t *testing.T) { ) }`, - ExpectedPatterns: []dataMap{topLevelSumPattern}, + ExpectedPatterns: topLevelSumPattern, }, }, } diff --git a/tests/integration/explain/debug/type_join_many_test.go b/tests/integration/explain/debug/type_join_many_test.go index 85ca3399a5..4150e9a85b 100644 --- a/tests/integration/explain/debug/type_join_many_test.go +++ b/tests/integration/explain/debug/type_join_many_test.go @@ -35,13 +35,15 @@ func TestDebugExplainRequestWithAOneToManyJoin(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": dataMap{ - "typeJoinMany": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": dataMap{ + "typeJoinMany": normalTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/debug/type_join_one_test.go b/tests/integration/explain/debug/type_join_one_test.go index 55b1bc9b57..16522c2098 100644 --- a/tests/integration/explain/debug/type_join_one_test.go +++ b/tests/integration/explain/debug/type_join_one_test.go @@ -35,13 +35,15 @@ func TestDebugExplainRequestWithAOneToOneJoin(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": dataMap{ - "typeJoinOne": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": dataMap{ + "typeJoinOne": normalTypeJoinPattern, + }, }, }, }, @@ -77,21 +79,23 @@ func TestDebugExplainRequestWithTwoLevelDeepNestedJoins(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": dataMap{ - "typeJoinOne": dataMap{ - "root": dataMap{ - "scanNode": dataMap{}, - }, - "subType": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": dataMap{ - "typeJoinOne": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": dataMap{ + "typeJoinOne": dataMap{ + "root": dataMap{ + "scanNode": dataMap{}, + }, + "subType": dataMap{ + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": dataMap{ + "typeJoinOne": normalTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/debug/type_join_test.go b/tests/integration/explain/debug/type_join_test.go index 21608521c4..8aece904da 100644 --- a/tests/integration/explain/debug/type_join_test.go +++ b/tests/integration/explain/debug/type_join_test.go @@ -70,25 +70,27 @@ func TestDebugExplainRequestWith2SingleJoinsAnd1ManyJoin(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "parallelNode": []dataMap{ - { - "typeIndexJoin": dataMap{ - "typeJoinOne": debugTypeJoinPattern, + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "parallelNode": []dataMap{ + { + "typeIndexJoin": dataMap{ + "typeJoinOne": debugTypeJoinPattern, + }, }, - }, - { - "typeIndexJoin": dataMap{ - "typeJoinMany": debugTypeJoinPattern, + { + "typeIndexJoin": dataMap{ + "typeJoinMany": debugTypeJoinPattern, + }, }, - }, - { - "typeIndexJoin": dataMap{ - "typeJoinOne": debugTypeJoinPattern, + { + "typeIndexJoin": dataMap{ + "typeJoinOne": debugTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/debug/type_join_with_filter_doc_id_test.go b/tests/integration/explain/debug/type_join_with_filter_doc_id_test.go index 5a8f2c5ba2..351ada42ef 100644 --- a/tests/integration/explain/debug/type_join_with_filter_doc_id_test.go +++ b/tests/integration/explain/debug/type_join_with_filter_doc_id_test.go @@ -43,13 +43,15 @@ func TestDebugExplainRequestWithRelatedAndRegularFilterAndDocIDs(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": dataMap{ - "typeJoinMany": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": dataMap{ + "typeJoinMany": normalTypeJoinPattern, + }, }, }, }, @@ -87,20 +89,22 @@ func TestDebugExplainRequestWithManyRelatedFiltersAndDocID(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "parallelNode": []dataMap{ - { - "typeIndexJoin": dataMap{ - "typeJoinMany": debugTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "parallelNode": []dataMap{ + { + "typeIndexJoin": dataMap{ + "typeJoinMany": debugTypeJoinPattern, + }, }, - }, - { - "typeIndexJoin": dataMap{ - "typeJoinMany": debugTypeJoinPattern, + { + "typeIndexJoin": dataMap{ + "typeJoinMany": debugTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/debug/type_join_with_filter_test.go b/tests/integration/explain/debug/type_join_with_filter_test.go index 2d4940b5bc..151d7c008d 100644 --- a/tests/integration/explain/debug/type_join_with_filter_test.go +++ b/tests/integration/explain/debug/type_join_with_filter_test.go @@ -39,13 +39,15 @@ func TestDebugExplainRequestWithRelatedAndRegularFilter(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": dataMap{ - "typeJoinMany": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": dataMap{ + "typeJoinMany": normalTypeJoinPattern, + }, }, }, }, @@ -82,20 +84,22 @@ func TestDebugExplainRequestWithManyRelatedFilters(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "parallelNode": []dataMap{ - { - "typeIndexJoin": dataMap{ - "typeJoinMany": debugTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "parallelNode": []dataMap{ + { + "typeIndexJoin": dataMap{ + "typeJoinMany": debugTypeJoinPattern, + }, }, - }, - { - "typeIndexJoin": dataMap{ - "typeJoinMany": debugTypeJoinPattern, + { + "typeIndexJoin": dataMap{ + "typeJoinMany": debugTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/debug/update_test.go b/tests/integration/explain/debug/update_test.go index d9c190ca0c..dc69553619 100644 --- a/tests/integration/explain/debug/update_test.go +++ b/tests/integration/explain/debug/update_test.go @@ -19,10 +19,14 @@ import ( var updatePattern = dataMap{ "explain": dataMap{ - "updateNode": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "updateNode": dataMap{ + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -54,7 +58,7 @@ func TestDebugExplainMutationRequestWithUpdateUsingBooleanFilter(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{updatePattern}, + ExpectedPatterns: updatePattern, }, }, } @@ -86,7 +90,7 @@ func TestDebugExplainMutationRequestWithUpdateUsingIds(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{updatePattern}, + ExpectedPatterns: updatePattern, }, }, } @@ -115,7 +119,7 @@ func TestDebugExplainMutationRequestWithUpdateUsingId(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{updatePattern}, + ExpectedPatterns: updatePattern, }, }, } @@ -152,7 +156,7 @@ func TestDebugExplainMutationRequestWithUpdateUsingIdsAndFilter(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{updatePattern}, + ExpectedPatterns: updatePattern, }, }, } diff --git a/tests/integration/explain/debug/with_average_join_test.go b/tests/integration/explain/debug/with_average_join_test.go index 63d910d117..115d6ca2ca 100644 --- a/tests/integration/explain/debug/with_average_join_test.go +++ b/tests/integration/explain/debug/with_average_join_test.go @@ -19,13 +19,17 @@ import ( var debugAverageTypeIndexJoinManyPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "averageNode": dataMap{ - "countNode": dataMap{ - "sumNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": dataMap{ - "typeJoinMany": normalTypeJoinPattern, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "averageNode": dataMap{ + "countNode": dataMap{ + "sumNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": dataMap{ + "typeJoinMany": normalTypeJoinPattern, + }, + }, }, }, }, @@ -52,7 +56,7 @@ func TestDebugExplainRequestWithAverageOnJoinedField(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{debugAverageTypeIndexJoinManyPattern}, + ExpectedPatterns: debugAverageTypeIndexJoinManyPattern, }, }, } @@ -80,23 +84,25 @@ func TestDebugExplainRequestWithAverageOnMultipleJoinedFieldsWithFilter(t *testi } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "averageNode": dataMap{ - "countNode": dataMap{ - "sumNode": dataMap{ - "selectNode": dataMap{ - "parallelNode": []dataMap{ - { - "typeIndexJoin": dataMap{ - "typeJoinMany": debugTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "averageNode": dataMap{ + "countNode": dataMap{ + "sumNode": dataMap{ + "selectNode": dataMap{ + "parallelNode": []dataMap{ + { + "typeIndexJoin": dataMap{ + "typeJoinMany": debugTypeJoinPattern, + }, }, - }, - { - "typeIndexJoin": dataMap{ - "typeJoinMany": debugTypeJoinPattern, + { + "typeIndexJoin": dataMap{ + "typeJoinMany": debugTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/debug/with_average_test.go b/tests/integration/explain/debug/with_average_test.go index 9bc0f70194..9ae0298457 100644 --- a/tests/integration/explain/debug/with_average_test.go +++ b/tests/integration/explain/debug/with_average_test.go @@ -19,12 +19,16 @@ import ( var averagePattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "averageNode": dataMap{ - "countNode": dataMap{ - "sumNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "averageNode": dataMap{ + "countNode": dataMap{ + "sumNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -50,7 +54,7 @@ func TestDebugExplainRequestWithAverageOnArrayField(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{averagePattern}, + ExpectedFullGraph: averagePattern, }, }, } diff --git a/tests/integration/explain/debug/with_count_join_test.go b/tests/integration/explain/debug/with_count_join_test.go index ae96eeb2c5..2caa853f08 100644 --- a/tests/integration/explain/debug/with_count_join_test.go +++ b/tests/integration/explain/debug/with_count_join_test.go @@ -19,11 +19,15 @@ import ( var debugCountTypeIndexJoinManyPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "countNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": dataMap{ - "typeJoinMany": normalTypeJoinPattern, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "countNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": dataMap{ + "typeJoinMany": normalTypeJoinPattern, + }, + }, }, }, }, @@ -48,7 +52,7 @@ func TestDebugExplainRequestWithCountOnOneToManyJoinedField(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{debugCountTypeIndexJoinManyPattern}, + ExpectedPatterns: debugCountTypeIndexJoinManyPattern, }, }, } @@ -76,21 +80,23 @@ func TestDebugExplainRequestWithCountOnOneToManyJoinedFieldWithManySources(t *te } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "countNode": dataMap{ - "selectNode": dataMap{ - "parallelNode": []dataMap{ - { - "typeIndexJoin": dataMap{ - "typeJoinMany": debugTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "countNode": dataMap{ + "selectNode": dataMap{ + "parallelNode": []dataMap{ + { + "typeIndexJoin": dataMap{ + "typeJoinMany": debugTypeJoinPattern, + }, }, - }, - { - "typeIndexJoin": dataMap{ - "typeJoinMany": debugTypeJoinPattern, + { + "typeIndexJoin": dataMap{ + "typeJoinMany": debugTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/debug/with_count_test.go b/tests/integration/explain/debug/with_count_test.go index ec542bed8e..57b8328883 100644 --- a/tests/integration/explain/debug/with_count_test.go +++ b/tests/integration/explain/debug/with_count_test.go @@ -19,10 +19,14 @@ import ( var countPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "countNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "countNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -46,7 +50,7 @@ func TestDebugExplainRequestWithCountOnInlineArrayField(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{countPattern}, + ExpectedPatterns: countPattern, }, }, } diff --git a/tests/integration/explain/debug/with_filter_doc_id_test.go b/tests/integration/explain/debug/with_filter_doc_id_test.go index 89bf3f35aa..800a3a3c77 100644 --- a/tests/integration/explain/debug/with_filter_doc_id_test.go +++ b/tests/integration/explain/debug/with_filter_doc_id_test.go @@ -34,7 +34,7 @@ func TestDebugExplainRequestWithDocIDFilter(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, }, }, } @@ -59,7 +59,7 @@ func TestDebugExplainRequestWithDocIDsFilterUsingOneID(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, }, }, } @@ -89,7 +89,7 @@ func TestDebugExplainRequestWithDocIDsFilterUsingMultipleButDuplicateIDs(t *test } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, }, }, } @@ -119,7 +119,7 @@ func TestDebugExplainRequestWithDocIDsFilterUsingMultipleUniqueIDs(t *testing.T) } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, }, }, } @@ -150,7 +150,7 @@ func TestDebugExplainRequestWithMatchingIDFilter(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, }, }, } diff --git a/tests/integration/explain/debug/with_filter_test.go b/tests/integration/explain/debug/with_filter_test.go index 67f69a406c..f82238f841 100644 --- a/tests/integration/explain/debug/with_filter_test.go +++ b/tests/integration/explain/debug/with_filter_test.go @@ -34,7 +34,7 @@ func TestDebugExplainRequestWithStringEqualFilter(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, }, }, } @@ -59,7 +59,7 @@ func TestDebugExplainRequestWithIntegerEqualFilter(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, }, }, } @@ -84,7 +84,7 @@ func TestDebugExplainRequestWithGreaterThanFilter(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, }, }, } @@ -109,7 +109,7 @@ func TestDebugExplainRequestWithLogicalCompoundAndFilter(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, }, }, } @@ -134,7 +134,7 @@ func TestDebugExplainRequestWithLogicalCompoundOrFilter(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, }, }, } @@ -159,7 +159,7 @@ func TestDebugExplainRequestWithMatchInsideList(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, }, }, } diff --git a/tests/integration/explain/debug/with_limit_count_test.go b/tests/integration/explain/debug/with_limit_count_test.go index 84327fdaae..e570bfeebb 100644 --- a/tests/integration/explain/debug/with_limit_count_test.go +++ b/tests/integration/explain/debug/with_limit_count_test.go @@ -36,21 +36,23 @@ func TestDebugExplainRequestWithOnlyLimitOnRelatedChildWithCount(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "countNode": dataMap{ - "selectNode": dataMap{ - "parallelNode": []dataMap{ - { - "typeIndexJoin": dataMap{ - "typeJoinMany": debugLimitTypeJoinManyPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "countNode": dataMap{ + "selectNode": dataMap{ + "parallelNode": []dataMap{ + { + "typeIndexJoin": dataMap{ + "typeJoinMany": debugLimitTypeJoinManyPattern, + }, }, - }, - { - "typeIndexJoin": dataMap{ - "typeJoinMany": debugTypeJoinPattern, + { + "typeIndexJoin": dataMap{ + "typeJoinMany": debugTypeJoinPattern, + }, }, }, }, @@ -86,22 +88,24 @@ func TestDebugExplainRequestWithLimitArgsOnParentAndRelatedChildWithCount(t *tes } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "limitNode": dataMap{ - "countNode": dataMap{ - "selectNode": dataMap{ - "parallelNode": []dataMap{ - { - "typeIndexJoin": dataMap{ - "typeJoinMany": debugLimitTypeJoinManyPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "limitNode": dataMap{ + "countNode": dataMap{ + "selectNode": dataMap{ + "parallelNode": []dataMap{ + { + "typeIndexJoin": dataMap{ + "typeJoinMany": debugLimitTypeJoinManyPattern, + }, }, - }, - { - "typeIndexJoin": dataMap{ - "typeJoinMany": debugTypeJoinPattern, + { + "typeIndexJoin": dataMap{ + "typeJoinMany": debugTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/debug/with_limit_join_test.go b/tests/integration/explain/debug/with_limit_join_test.go index 028ac2f69b..f80bcc3f17 100644 --- a/tests/integration/explain/debug/with_limit_join_test.go +++ b/tests/integration/explain/debug/with_limit_join_test.go @@ -68,13 +68,15 @@ func TestDebugExplainRequestWithOnlyLimitOnRelatedChild(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": dataMap{ - "typeJoinMany": limitTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": dataMap{ + "typeJoinMany": limitTypeJoinPattern, + }, }, }, }, @@ -107,13 +109,15 @@ func TestDebugExplainRequestWithOnlyOffsetOnRelatedChild(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": dataMap{ - "typeJoinMany": limitTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": dataMap{ + "typeJoinMany": limitTypeJoinPattern, + }, }, }, }, @@ -146,13 +150,15 @@ func TestDebugExplainRequestWithBothLimitAndOffsetOnRelatedChild(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": dataMap{ - "typeJoinMany": limitTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": dataMap{ + "typeJoinMany": limitTypeJoinPattern, + }, }, }, }, @@ -185,14 +191,16 @@ func TestDebugExplainRequestWithLimitOnRelatedChildAndBothLimitAndOffsetOnParent } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "limitNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": dataMap{ - "typeJoinMany": limitTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "limitNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": dataMap{ + "typeJoinMany": limitTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/debug/with_limit_test.go b/tests/integration/explain/debug/with_limit_test.go index 993032a364..8545e59e92 100644 --- a/tests/integration/explain/debug/with_limit_test.go +++ b/tests/integration/explain/debug/with_limit_test.go @@ -19,10 +19,14 @@ import ( var limitPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "limitNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "limitNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -45,7 +49,7 @@ func TestDebugExplainRequestWithOnlyLimit(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{limitPattern}, + ExpectedPatterns: limitPattern, }, }, } @@ -69,7 +73,7 @@ func TestDebugExplainRequestWithOnlyOffset(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{limitPattern}, + ExpectedPatterns: limitPattern, }, }, } @@ -93,7 +97,7 @@ func TestDebugExplainRequestWithLimitAndOffset(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{limitPattern}, + ExpectedPatterns: limitPattern, }, }, } diff --git a/tests/integration/explain/debug/with_order_join_test.go b/tests/integration/explain/debug/with_order_join_test.go index 02b96496e6..ba67b6256c 100644 --- a/tests/integration/explain/debug/with_order_join_test.go +++ b/tests/integration/explain/debug/with_order_join_test.go @@ -51,13 +51,15 @@ func TestDebugExplainRequestWithOrderFieldOnRelatedChild(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": dataMap{ - "typeJoinMany": orderTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": dataMap{ + "typeJoinMany": orderTypeJoinPattern, + }, }, }, }, @@ -90,14 +92,16 @@ func TestDebugExplainRequestWithOrderFieldOnParentAndRelatedChild(t *testing.T) } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "orderNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": dataMap{ - "typeJoinMany": orderTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "orderNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": dataMap{ + "typeJoinMany": orderTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/debug/with_order_test.go b/tests/integration/explain/debug/with_order_test.go index cdcdfe35ac..663514f558 100644 --- a/tests/integration/explain/debug/with_order_test.go +++ b/tests/integration/explain/debug/with_order_test.go @@ -19,10 +19,14 @@ import ( var orderPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "orderNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "orderNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -46,7 +50,7 @@ func TestDebugExplainRequestWithAscendingOrderOnParent(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{orderPattern}, + ExpectedFullGraph: orderPattern, }, }, } @@ -71,7 +75,7 @@ func TestDebugExplainRequestWithMultiOrderFieldsOnParent(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{orderPattern}, + ExpectedFullGraph: orderPattern, }, }, } diff --git a/tests/integration/explain/debug/with_sum_join_test.go b/tests/integration/explain/debug/with_sum_join_test.go index d098eec2f1..815d9c6ee8 100644 --- a/tests/integration/explain/debug/with_sum_join_test.go +++ b/tests/integration/explain/debug/with_sum_join_test.go @@ -19,11 +19,15 @@ import ( var debugSumTypeIndexJoinManyPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "sumNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": dataMap{ - "typeJoinMany": normalTypeJoinPattern, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "sumNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": dataMap{ + "typeJoinMany": normalTypeJoinPattern, + }, + }, }, }, }, @@ -51,7 +55,7 @@ func TestDebugExplainRequestWithSumOnOneToManyJoinedField(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{debugSumTypeIndexJoinManyPattern}, + ExpectedPatterns: debugSumTypeIndexJoinManyPattern, }, }, } @@ -85,7 +89,7 @@ func TestDebugExplainRequestWithSumOnOneToManyJoinedFieldWithFilter(t *testing.T } }`, - ExpectedPatterns: []dataMap{debugSumTypeIndexJoinManyPattern}, + ExpectedPatterns: debugSumTypeIndexJoinManyPattern, }, }, } @@ -113,21 +117,23 @@ func TestDebugExplainRequestWithSumOnOneToManyJoinedFieldWithManySources(t *test } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "sumNode": dataMap{ - "selectNode": dataMap{ - "parallelNode": []dataMap{ - { - "typeIndexJoin": dataMap{ - "typeJoinMany": debugTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "sumNode": dataMap{ + "selectNode": dataMap{ + "parallelNode": []dataMap{ + { + "typeIndexJoin": dataMap{ + "typeJoinMany": debugTypeJoinPattern, + }, }, - }, - { - "typeIndexJoin": dataMap{ - "typeJoinMany": debugTypeJoinPattern, + { + "typeIndexJoin": dataMap{ + "typeJoinMany": debugTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/debug/with_sum_test.go b/tests/integration/explain/debug/with_sum_test.go index 00ed6ddcc7..eaca8b7c9a 100644 --- a/tests/integration/explain/debug/with_sum_test.go +++ b/tests/integration/explain/debug/with_sum_test.go @@ -19,10 +19,14 @@ import ( var sumPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "sumNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "sumNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -46,7 +50,7 @@ func TestDebugExplainRequestWithSumOnInlineArrayField_ChildFieldWillBeEmpty(t *t } }`, - ExpectedPatterns: []dataMap{sumPattern}, + ExpectedPatterns: sumPattern, }, }, } diff --git a/tests/integration/explain/debug/with_view_test.go b/tests/integration/explain/debug/with_view_test.go index 44341ae521..43d83a4dee 100644 --- a/tests/integration/explain/debug/with_view_test.go +++ b/tests/integration/explain/debug/with_view_test.go @@ -18,12 +18,16 @@ import ( var viewPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "viewNode": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "viewNode": dataMap{ + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -62,7 +66,7 @@ func TestDebugExplainRequestWithView(t *testing.T) { name } }`, - ExpectedPatterns: []dataMap{viewPattern}, + ExpectedPatterns: viewPattern, }, }, } diff --git a/tests/integration/explain/debug/with_view_transform_test.go b/tests/integration/explain/debug/with_view_transform_test.go index 386324067a..b2da390e8a 100644 --- a/tests/integration/explain/debug/with_view_transform_test.go +++ b/tests/integration/explain/debug/with_view_transform_test.go @@ -22,13 +22,17 @@ import ( var transformViewPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "viewNode": dataMap{ - "lensNode": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "viewNode": dataMap{ + "lensNode": dataMap{ + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -79,7 +83,7 @@ func TestDebugExplainRequestWithViewWithTransform(t *testing.T) { fullName } }`, - ExpectedPatterns: []dataMap{transformViewPattern}, + ExpectedPatterns: transformViewPattern, }, }, } diff --git a/tests/integration/explain/default/basic_test.go b/tests/integration/explain/default/basic_test.go index 30a5810de6..2f02f6c67c 100644 --- a/tests/integration/explain/default/basic_test.go +++ b/tests/integration/explain/default/basic_test.go @@ -59,21 +59,23 @@ func TestDefaultExplainRequestWithFullBasicGraph(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "docIDs": nil, - "filter": nil, - "scanNode": dataMap{ - "filter": nil, - "collectionID": "3", - "collectionName": "Author", - "spans": []dataMap{ - { - "start": "/3", - "end": "/4", + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "docIDs": nil, + "filter": nil, + "scanNode": dataMap{ + "filter": nil, + "collectionID": "3", + "collectionName": "Author", + "spans": []dataMap{ + { + "start": "/3", + "end": "/4", + }, }, }, }, @@ -106,7 +108,7 @@ func TestDefaultExplainWithAlias(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, }, }, } diff --git a/tests/integration/explain/default/create_test.go b/tests/integration/explain/default/create_test.go index 3fdccc8b44..b939ad08fb 100644 --- a/tests/integration/explain/default/create_test.go +++ b/tests/integration/explain/default/create_test.go @@ -19,10 +19,14 @@ import ( var createPattern = dataMap{ "explain": dataMap{ - "createNode": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "createNode": dataMap{ + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -45,7 +49,7 @@ func TestDefaultExplainMutationRequestWithCreate(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{createPattern}, + ExpectedPatterns: createPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -83,7 +87,7 @@ func TestDefaultExplainMutationRequestDoesNotCreateDocGivenDuplicate(t *testing. } }`, - ExpectedPatterns: []dataMap{createPattern}, + ExpectedPatterns: createPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/dagscan_test.go b/tests/integration/explain/default/dagscan_test.go index 321d3c3251..6b216ab061 100644 --- a/tests/integration/explain/default/dagscan_test.go +++ b/tests/integration/explain/default/dagscan_test.go @@ -19,9 +19,13 @@ import ( var dagScanPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "dagScanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "dagScanNode": dataMap{}, + }, + }, }, }, }, @@ -45,7 +49,7 @@ func TestDefaultExplainCommitsDagScanQueryOp(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{dagScanPattern}, + ExpectedPatterns: dagScanPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -88,7 +92,7 @@ func TestDefaultExplainCommitsDagScanQueryOpWithoutField(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{dagScanPattern}, + ExpectedPatterns: dagScanPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -132,7 +136,7 @@ func TestDefaultExplainLatestCommitsDagScanQueryOp(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{dagScanPattern}, + ExpectedPatterns: dagScanPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -176,7 +180,7 @@ func TestDefaultExplainLatestCommitsDagScanQueryOpWithoutField(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{dagScanPattern}, + ExpectedPatterns: dagScanPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/delete_test.go b/tests/integration/explain/default/delete_test.go index 660785f6a4..a8918b9141 100644 --- a/tests/integration/explain/default/delete_test.go +++ b/tests/integration/explain/default/delete_test.go @@ -19,10 +19,14 @@ import ( var deletePattern = dataMap{ "explain": dataMap{ - "deleteNode": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "deleteNode": dataMap{ + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -45,7 +49,7 @@ func TestDefaultExplainMutationRequestWithDeleteUsingFilter(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{deletePattern}, + ExpectedPatterns: deletePattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -104,7 +108,7 @@ func TestDefaultExplainMutationRequestWithDeleteUsingFilterToMatchEverything(t * } }`, - ExpectedPatterns: []dataMap{deletePattern}, + ExpectedPatterns: deletePattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -155,7 +159,7 @@ func TestDefaultExplainMutationRequestWithDeleteUsingId(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{deletePattern}, + ExpectedPatterns: deletePattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -211,7 +215,7 @@ func TestDefaultExplainMutationRequestWithDeleteUsingIds(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{deletePattern}, + ExpectedPatterns: deletePattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -269,7 +273,7 @@ func TestDefaultExplainMutationRequestWithDeleteUsingNoIds(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{deletePattern}, + ExpectedPatterns: deletePattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -323,7 +327,7 @@ func TestDefaultExplainMutationRequestWithDeleteUsingFilterAndIds(t *testing.T) } }`, - ExpectedPatterns: []dataMap{deletePattern}, + ExpectedPatterns: deletePattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/fixture.go b/tests/integration/explain/default/fixture.go index 399a59ac20..01d1c31238 100644 --- a/tests/integration/explain/default/fixture.go +++ b/tests/integration/explain/default/fixture.go @@ -14,9 +14,13 @@ type dataMap = map[string]any var basicPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, diff --git a/tests/integration/explain/default/group_test.go b/tests/integration/explain/default/group_test.go index d631badcde..7b3cc2872f 100644 --- a/tests/integration/explain/default/group_test.go +++ b/tests/integration/explain/default/group_test.go @@ -19,10 +19,14 @@ import ( var groupPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "groupNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "groupNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -48,7 +52,7 @@ func TestDefaultExplainRequestWithGroupByOnParent(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -88,7 +92,7 @@ func TestDefaultExplainRequestWithGroupByTwoFieldsOnParent(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/group_with_average_test.go b/tests/integration/explain/default/group_with_average_test.go index 4346ec6a9a..aa04a737a1 100644 --- a/tests/integration/explain/default/group_with_average_test.go +++ b/tests/integration/explain/default/group_with_average_test.go @@ -19,13 +19,17 @@ import ( var groupAveragePattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "averageNode": dataMap{ - "countNode": dataMap{ - "sumNode": dataMap{ - "groupNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "averageNode": dataMap{ + "countNode": dataMap{ + "sumNode": dataMap{ + "groupNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -52,7 +56,7 @@ func TestDefaultExplainRequestWithGroupByWithAverageOnAnInnerField(t *testing.T) } }`, - ExpectedPatterns: []dataMap{groupAveragePattern}, + ExpectedPatterns: groupAveragePattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -143,7 +147,7 @@ func TestDefaultExplainRequestWithAverageInsideTheInnerGroupOnAField(t *testing. } }`, - ExpectedPatterns: []dataMap{groupAveragePattern}, + ExpectedPatterns: groupAveragePattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -225,7 +229,7 @@ func TestDefaultExplainRequestWithAverageInsideTheInnerGroupOnAFieldAndNestedGro } }`, - ExpectedPatterns: []dataMap{groupAveragePattern}, + ExpectedPatterns: groupAveragePattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -308,7 +312,7 @@ func TestDefaultExplainRequestWithAverageInsideTheInnerGroupAndNestedGroupByWith } }`, - ExpectedPatterns: []dataMap{groupAveragePattern}, + ExpectedPatterns: groupAveragePattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/group_with_doc_id_child_test.go b/tests/integration/explain/default/group_with_doc_id_child_test.go index 6ce3b8c041..a721bb571a 100644 --- a/tests/integration/explain/default/group_with_doc_id_child_test.go +++ b/tests/integration/explain/default/group_with_doc_id_child_test.go @@ -38,7 +38,7 @@ func TestDefaultExplainRequestWithDocIDsOnInnerGroupSelection(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/group_with_doc_id_test.go b/tests/integration/explain/default/group_with_doc_id_test.go index d458ad9015..2178701a4e 100644 --- a/tests/integration/explain/default/group_with_doc_id_test.go +++ b/tests/integration/explain/default/group_with_doc_id_test.go @@ -39,7 +39,7 @@ func TestDefaultExplainRequestWithDocIDOnParentGroupBy(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -101,7 +101,7 @@ func TestDefaultExplainRequestWithDocIDsAndFilterOnParentGroupBy(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/group_with_filter_child_test.go b/tests/integration/explain/default/group_with_filter_child_test.go index a8522962eb..9ce44342d1 100644 --- a/tests/integration/explain/default/group_with_filter_child_test.go +++ b/tests/integration/explain/default/group_with_filter_child_test.go @@ -36,7 +36,7 @@ func TestDefaultExplainRequestWithFilterOnInnerGroupSelection(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -105,7 +105,7 @@ func TestDefaultExplainRequestWithFilterOnParentGroupByAndInnerGroupSelection(t } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/group_with_filter_test.go b/tests/integration/explain/default/group_with_filter_test.go index 6221fd0f02..23651934e3 100644 --- a/tests/integration/explain/default/group_with_filter_test.go +++ b/tests/integration/explain/default/group_with_filter_test.go @@ -39,7 +39,7 @@ func TestDefaultExplainRequestWithFilterOnGroupByParent(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/group_with_limit_child_test.go b/tests/integration/explain/default/group_with_limit_child_test.go index fb6dc83f77..a62859aeda 100644 --- a/tests/integration/explain/default/group_with_limit_child_test.go +++ b/tests/integration/explain/default/group_with_limit_child_test.go @@ -36,7 +36,7 @@ func TestDefaultExplainRequestWithLimitAndOffsetOnInnerGroupSelection(t *testing } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -89,7 +89,7 @@ func TestDefaultExplainRequestWithLimitAndOffsetOnMultipleInnerGroupSelections(t } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/group_with_limit_test.go b/tests/integration/explain/default/group_with_limit_test.go index b88496c7dd..1696e3ccd2 100644 --- a/tests/integration/explain/default/group_with_limit_test.go +++ b/tests/integration/explain/default/group_with_limit_test.go @@ -19,11 +19,15 @@ import ( var groupLimitPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "limitNode": dataMap{ - "groupNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "limitNode": dataMap{ + "groupNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -54,7 +58,7 @@ func TestDefaultExplainRequestWithLimitAndOffsetOnParentGroupBy(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{groupLimitPattern}, + ExpectedPatterns: groupLimitPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -105,7 +109,7 @@ func TestDefaultExplainRequestWithLimitOnParentGroupByAndInnerGroupSelection(t * } }`, - ExpectedPatterns: []dataMap{groupLimitPattern}, + ExpectedPatterns: groupLimitPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/group_with_order_child_test.go b/tests/integration/explain/default/group_with_order_child_test.go index e8ba14d697..969f048c0c 100644 --- a/tests/integration/explain/default/group_with_order_child_test.go +++ b/tests/integration/explain/default/group_with_order_child_test.go @@ -36,7 +36,7 @@ func TestDefaultExplainRequestWithDescendingOrderOnInnerGroupSelection(t *testin } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -88,7 +88,7 @@ func TestDefaultExplainRequestWithAscendingOrderOnInnerGroupSelection(t *testing } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -146,7 +146,7 @@ func TestDefaultExplainRequestWithOrderOnNestedParentGroupByAndOnNestedParentsIn } }`, - ExpectedPatterns: []dataMap{groupPattern}, + ExpectedPatterns: groupPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/group_with_order_test.go b/tests/integration/explain/default/group_with_order_test.go index 43e6b7ba05..4ab526474e 100644 --- a/tests/integration/explain/default/group_with_order_test.go +++ b/tests/integration/explain/default/group_with_order_test.go @@ -19,11 +19,15 @@ import ( var groupOrderPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "orderNode": dataMap{ - "groupNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "orderNode": dataMap{ + "groupNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -53,7 +57,7 @@ func TestDefaultExplainRequestWithDescendingOrderOnParentGroupBy(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{groupOrderPattern}, + ExpectedPatterns: groupOrderPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -108,7 +112,7 @@ func TestDefaultExplainRequestWithAscendingOrderOnParentGroupBy(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{groupOrderPattern}, + ExpectedPatterns: groupOrderPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -163,7 +167,7 @@ func TestDefaultExplainRequestWithOrderOnParentGroupByAndOnInnerGroupSelection(t } }`, - ExpectedPatterns: []dataMap{groupOrderPattern}, + ExpectedPatterns: groupOrderPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/top_with_average_test.go b/tests/integration/explain/default/top_with_average_test.go index 249aa209e9..1921a142f7 100644 --- a/tests/integration/explain/default/top_with_average_test.go +++ b/tests/integration/explain/default/top_with_average_test.go @@ -19,23 +19,27 @@ import ( var topLevelAveragePattern = dataMap{ "explain": dataMap{ - "topLevelNode": []dataMap{ + "operationNode": []dataMap{ { - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "topLevelNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, + }, + { + "sumNode": dataMap{}, + }, + { + "countNode": dataMap{}, + }, + { + "averageNode": dataMap{}, }, }, }, - { - "sumNode": dataMap{}, - }, - { - "countNode": dataMap{}, - }, - { - "averageNode": dataMap{}, - }, }, }, } @@ -58,7 +62,7 @@ func TestDefaultExplainTopLevelAverageRequest(t *testing.T) { ) }`, - ExpectedPatterns: []dataMap{topLevelAveragePattern}, + ExpectedPatterns: topLevelAveragePattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -149,7 +153,7 @@ func TestDefaultExplainTopLevelAverageRequestWithFilter(t *testing.T) { ) }`, - ExpectedPatterns: []dataMap{topLevelAveragePattern}, + ExpectedPatterns: topLevelAveragePattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/top_with_count_test.go b/tests/integration/explain/default/top_with_count_test.go index 8129013911..6ac039f764 100644 --- a/tests/integration/explain/default/top_with_count_test.go +++ b/tests/integration/explain/default/top_with_count_test.go @@ -19,17 +19,21 @@ import ( var topLevelCountPattern = dataMap{ "explain": dataMap{ - "topLevelNode": []dataMap{ + "operationNode": []dataMap{ { - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "topLevelNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, + }, + { + "countNode": dataMap{}, }, }, }, - { - "countNode": dataMap{}, - }, }, }, } @@ -48,7 +52,7 @@ func TestDefaultExplainTopLevelCountRequest(t *testing.T) { _count(Author: {}) }`, - ExpectedPatterns: []dataMap{topLevelCountPattern}, + ExpectedPatterns: topLevelCountPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -108,7 +112,7 @@ func TestDefaultExplainTopLevelCountRequestWithFilter(t *testing.T) { ) }`, - ExpectedPatterns: []dataMap{topLevelCountPattern}, + ExpectedPatterns: topLevelCountPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/top_with_sum_test.go b/tests/integration/explain/default/top_with_sum_test.go index 764663a8bd..a2927beb25 100644 --- a/tests/integration/explain/default/top_with_sum_test.go +++ b/tests/integration/explain/default/top_with_sum_test.go @@ -19,17 +19,21 @@ import ( var topLevelSumPattern = dataMap{ "explain": dataMap{ - "topLevelNode": []dataMap{ + "operationNode": []dataMap{ { - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "topLevelNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, + }, + { + "sumNode": dataMap{}, }, }, }, - { - "sumNode": dataMap{}, - }, }, }, } @@ -52,7 +56,7 @@ func TestDefaultExplainTopLevelSumRequest(t *testing.T) { ) }`, - ExpectedPatterns: []dataMap{topLevelSumPattern}, + ExpectedPatterns: topLevelSumPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -114,7 +118,7 @@ func TestDefaultExplainTopLevelSumRequestWithFilter(t *testing.T) { ) }`, - ExpectedPatterns: []dataMap{topLevelSumPattern}, + ExpectedPatterns: topLevelSumPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/type_join_many_test.go b/tests/integration/explain/default/type_join_many_test.go index 031b509950..30bd530a99 100644 --- a/tests/integration/explain/default/type_join_many_test.go +++ b/tests/integration/explain/default/type_join_many_test.go @@ -37,12 +37,14 @@ func TestDefaultExplainRequestWithAOneToManyJoin(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": normalTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/default/type_join_one_test.go b/tests/integration/explain/default/type_join_one_test.go index 3059bf8528..05daf41539 100644 --- a/tests/integration/explain/default/type_join_one_test.go +++ b/tests/integration/explain/default/type_join_one_test.go @@ -37,12 +37,14 @@ func TestDefaultExplainRequestWithAOneToOneJoin(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": normalTypeJoinPattern, + }, }, }, }, @@ -134,19 +136,21 @@ func TestDefaultExplainRequestWithTwoLevelDeepNestedJoins(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": dataMap{ - "root": dataMap{ - "scanNode": dataMap{}, - }, - "subType": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": dataMap{ + "root": dataMap{ + "scanNode": dataMap{}, + }, + "subType": dataMap{ + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": normalTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/default/type_join_test.go b/tests/integration/explain/default/type_join_test.go index c09c1b0f12..5f4d93df3b 100644 --- a/tests/integration/explain/default/type_join_test.go +++ b/tests/integration/explain/default/type_join_test.go @@ -57,20 +57,22 @@ func TestDefaultExplainRequestWith2SingleJoinsAnd1ManyJoin(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "parallelNode": []dataMap{ - { - "typeIndexJoin": normalTypeJoinPattern, - }, - { - "typeIndexJoin": normalTypeJoinPattern, - }, - { - "typeIndexJoin": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "parallelNode": []dataMap{ + { + "typeIndexJoin": normalTypeJoinPattern, + }, + { + "typeIndexJoin": normalTypeJoinPattern, + }, + { + "typeIndexJoin": normalTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/default/type_join_with_filter_doc_id_test.go b/tests/integration/explain/default/type_join_with_filter_doc_id_test.go index 7b320b01b7..63aa689fa6 100644 --- a/tests/integration/explain/default/type_join_with_filter_doc_id_test.go +++ b/tests/integration/explain/default/type_join_with_filter_doc_id_test.go @@ -43,12 +43,14 @@ func TestDefaultExplainRequestWithRelatedAndRegularFilterAndDocIDs(t *testing.T) } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": normalTypeJoinPattern, + }, }, }, }, @@ -127,17 +129,19 @@ func TestDefaultExplainRequestWithManyRelatedFiltersAndDocID(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "parallelNode": []dataMap{ - { - "typeIndexJoin": normalTypeJoinPattern, - }, - { - "typeIndexJoin": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "parallelNode": []dataMap{ + { + "typeIndexJoin": normalTypeJoinPattern, + }, + { + "typeIndexJoin": normalTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/default/type_join_with_filter_test.go b/tests/integration/explain/default/type_join_with_filter_test.go index 78ed484b0c..43880c9d79 100644 --- a/tests/integration/explain/default/type_join_with_filter_test.go +++ b/tests/integration/explain/default/type_join_with_filter_test.go @@ -39,12 +39,14 @@ func TestDefaultExplainRequestWithRelatedAndRegularFilter(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": normalTypeJoinPattern, + }, }, }, }, @@ -115,17 +117,19 @@ func TestDefaultExplainRequestWithManyRelatedFilters(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "parallelNode": []dataMap{ - { - "typeIndexJoin": normalTypeJoinPattern, - }, - { - "typeIndexJoin": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "parallelNode": []dataMap{ + { + "typeIndexJoin": normalTypeJoinPattern, + }, + { + "typeIndexJoin": normalTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/default/update_test.go b/tests/integration/explain/default/update_test.go index e2d52e8b73..12f69568dd 100644 --- a/tests/integration/explain/default/update_test.go +++ b/tests/integration/explain/default/update_test.go @@ -19,10 +19,14 @@ import ( var updatePattern = dataMap{ "explain": dataMap{ - "updateNode": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "updateNode": dataMap{ + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -54,7 +58,7 @@ func TestDefaultExplainMutationRequestWithUpdateUsingBooleanFilter(t *testing.T) } }`, - ExpectedPatterns: []dataMap{updatePattern}, + ExpectedPatterns: updatePattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -123,7 +127,7 @@ func TestDefaultExplainMutationRequestWithUpdateUsingIds(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{updatePattern}, + ExpectedPatterns: updatePattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -188,7 +192,7 @@ func TestDefaultExplainMutationRequestWithUpdateUsingId(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{updatePattern}, + ExpectedPatterns: updatePattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -256,7 +260,7 @@ func TestDefaultExplainMutationRequestWithUpdateUsingIdsAndFilter(t *testing.T) } }`, - ExpectedPatterns: []dataMap{updatePattern}, + ExpectedPatterns: updatePattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/with_average_join_test.go b/tests/integration/explain/default/with_average_join_test.go index d1cd68046e..5d65408540 100644 --- a/tests/integration/explain/default/with_average_join_test.go +++ b/tests/integration/explain/default/with_average_join_test.go @@ -21,12 +21,16 @@ import ( var averageTypeIndexJoinPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "averageNode": dataMap{ - "countNode": dataMap{ - "sumNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": normalTypeJoinPattern, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "averageNode": dataMap{ + "countNode": dataMap{ + "sumNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": normalTypeJoinPattern, + }, + }, }, }, }, @@ -52,7 +56,7 @@ func TestDefaultExplainRequestWithAverageOnJoinedField(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{averageTypeIndexJoinPattern}, + ExpectedPatterns: averageTypeIndexJoinPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -166,20 +170,22 @@ func TestDefaultExplainRequestWithAverageOnMultipleJoinedFieldsWithFilter(t *tes } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "averageNode": dataMap{ - "countNode": dataMap{ - "sumNode": dataMap{ - "selectNode": dataMap{ - "parallelNode": []dataMap{ - { - "typeIndexJoin": normalTypeJoinPattern, - }, - { - "typeIndexJoin": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "averageNode": dataMap{ + "countNode": dataMap{ + "sumNode": dataMap{ + "selectNode": dataMap{ + "parallelNode": []dataMap{ + { + "typeIndexJoin": normalTypeJoinPattern, + }, + { + "typeIndexJoin": normalTypeJoinPattern, + }, }, }, }, @@ -372,15 +378,17 @@ func TestDefaultExplainRequestOneToManyWithAverageAndChildNeNilFilterSharesJoinF } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "averageNode": dataMap{ - "countNode": dataMap{ - "sumNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "averageNode": dataMap{ + "countNode": dataMap{ + "sumNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": normalTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/default/with_average_test.go b/tests/integration/explain/default/with_average_test.go index 41198fd88a..71a66aa6f8 100644 --- a/tests/integration/explain/default/with_average_test.go +++ b/tests/integration/explain/default/with_average_test.go @@ -19,12 +19,16 @@ import ( var averagePattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "averageNode": dataMap{ - "countNode": dataMap{ - "sumNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "averageNode": dataMap{ + "countNode": dataMap{ + "sumNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -50,7 +54,7 @@ func TestDefaultExplainRequestWithAverageOnArrayField(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{averagePattern}, + ExpectedPatterns: averagePattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/with_count_join_test.go b/tests/integration/explain/default/with_count_join_test.go index 4833354bba..a406855b71 100644 --- a/tests/integration/explain/default/with_count_join_test.go +++ b/tests/integration/explain/default/with_count_join_test.go @@ -21,10 +21,14 @@ import ( var countTypeIndexJoinPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "countNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": normalTypeJoinPattern, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "countNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": normalTypeJoinPattern, + }, + }, }, }, }, @@ -48,7 +52,7 @@ func TestDefaultExplainRequestWithCountOnOneToManyJoinedField(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{countTypeIndexJoinPattern}, + ExpectedPatterns: countTypeIndexJoinPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -132,18 +136,20 @@ func TestDefaultExplainRequestWithCountOnOneToManyJoinedFieldWithManySources(t * } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "countNode": dataMap{ - "selectNode": dataMap{ - "parallelNode": []dataMap{ - { - "typeIndexJoin": normalTypeJoinPattern, - }, - { - "typeIndexJoin": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "countNode": dataMap{ + "selectNode": dataMap{ + "parallelNode": []dataMap{ + { + "typeIndexJoin": normalTypeJoinPattern, + }, + { + "typeIndexJoin": normalTypeJoinPattern, + }, }, }, }, @@ -285,13 +291,15 @@ func TestDefaultExplainRequestOneToManyWithCountWithFilterAndChildFilterSharesJo } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "countNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "countNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": normalTypeJoinPattern, + }, }, }, }, @@ -327,18 +335,20 @@ func TestDefaultExplainRequestOneToManyWithCountAndChildFilterDoesNotShareJoinFi } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "countNode": dataMap{ - "selectNode": dataMap{ - "parallelNode": []dataMap{ - { - "typeIndexJoin": normalTypeJoinPattern, - }, - { - "typeIndexJoin": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "countNode": dataMap{ + "selectNode": dataMap{ + "parallelNode": []dataMap{ + { + "typeIndexJoin": normalTypeJoinPattern, + }, + { + "typeIndexJoin": normalTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/default/with_count_test.go b/tests/integration/explain/default/with_count_test.go index 212a4464c9..311c52d599 100644 --- a/tests/integration/explain/default/with_count_test.go +++ b/tests/integration/explain/default/with_count_test.go @@ -19,10 +19,14 @@ import ( var countPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "countNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "countNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -46,7 +50,7 @@ func TestDefaultExplainRequestWithCountOnInlineArrayField(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{countPattern}, + ExpectedPatterns: countPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/with_filter_doc_id_test.go b/tests/integration/explain/default/with_filter_doc_id_test.go index a5807d1da7..4e69361e2e 100644 --- a/tests/integration/explain/default/with_filter_doc_id_test.go +++ b/tests/integration/explain/default/with_filter_doc_id_test.go @@ -34,7 +34,7 @@ func TestDefaultExplainRequestWithDocIDFilter(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -86,7 +86,7 @@ func TestDefaultExplainRequestWithDocIDsFilterUsingOneID(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -143,7 +143,7 @@ func TestDefaultExplainRequestWithDocIDsFilterUsingMultipleButDuplicateIDs(t *te } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -205,7 +205,7 @@ func TestDefaultExplainRequestWithDocIDsFilterUsingMultipleUniqueIDs(t *testing. } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -268,7 +268,7 @@ func TestDefaultExplainRequestWithMatchingIDFilter(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/with_filter_test.go b/tests/integration/explain/default/with_filter_test.go index a165f28876..2d3751f562 100644 --- a/tests/integration/explain/default/with_filter_test.go +++ b/tests/integration/explain/default/with_filter_test.go @@ -34,7 +34,7 @@ func TestDefaultExplainRequestWithStringEqualFilter(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -81,7 +81,7 @@ func TestDefaultExplainRequestWithIntegerEqualFilter(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -128,7 +128,7 @@ func TestDefaultExplainRequestWithGreaterThanFilter(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -175,7 +175,7 @@ func TestDefaultExplainRequestWithLogicalCompoundAndFilter(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -231,7 +231,7 @@ func TestDefaultExplainRequestWithLogicalCompoundOrFilter(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -287,7 +287,7 @@ func TestDefaultExplainRequestWithMatchInsideList(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{basicPattern}, + ExpectedPatterns: basicPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/with_limit_count_test.go b/tests/integration/explain/default/with_limit_count_test.go index 5ac40a24c5..ab440a62b4 100644 --- a/tests/integration/explain/default/with_limit_count_test.go +++ b/tests/integration/explain/default/with_limit_count_test.go @@ -36,18 +36,20 @@ func TestDefaultExplainRequestWithOnlyLimitOnRelatedChildWithCount(t *testing.T) } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "countNode": dataMap{ - "selectNode": dataMap{ - "parallelNode": []dataMap{ - { - "typeIndexJoin": limitTypeJoinPattern, - }, - { - "typeIndexJoin": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "countNode": dataMap{ + "selectNode": dataMap{ + "parallelNode": []dataMap{ + { + "typeIndexJoin": limitTypeJoinPattern, + }, + { + "typeIndexJoin": normalTypeJoinPattern, + }, }, }, }, @@ -105,19 +107,21 @@ func TestDefaultExplainRequestWithLimitArgsOnParentAndRelatedChildWithCount(t *t } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "limitNode": dataMap{ - "countNode": dataMap{ - "selectNode": dataMap{ - "parallelNode": []dataMap{ - { - "typeIndexJoin": limitTypeJoinPattern, - }, - { - "typeIndexJoin": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "limitNode": dataMap{ + "countNode": dataMap{ + "selectNode": dataMap{ + "parallelNode": []dataMap{ + { + "typeIndexJoin": limitTypeJoinPattern, + }, + { + "typeIndexJoin": normalTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/default/with_limit_join_test.go b/tests/integration/explain/default/with_limit_join_test.go index c56af3d646..5216cdc75d 100644 --- a/tests/integration/explain/default/with_limit_join_test.go +++ b/tests/integration/explain/default/with_limit_join_test.go @@ -51,12 +51,14 @@ func TestDefaultExplainRequestWithOnlyLimitOnRelatedChild(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": limitTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": limitTypeJoinPattern, + }, }, }, }, @@ -99,12 +101,14 @@ func TestDefaultExplainRequestWithOnlyOffsetOnRelatedChild(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": limitTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": limitTypeJoinPattern, + }, }, }, }, @@ -147,12 +151,14 @@ func TestDefaultExplainRequestWithBothLimitAndOffsetOnRelatedChild(t *testing.T) } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": limitTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": limitTypeJoinPattern, + }, }, }, }, @@ -195,13 +201,15 @@ func TestDefaultExplainRequestWithLimitOnRelatedChildAndBothLimitAndOffsetOnPare } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "limitNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": limitTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "limitNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": limitTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/default/with_limit_test.go b/tests/integration/explain/default/with_limit_test.go index 0d2ebbae23..8a5a86972b 100644 --- a/tests/integration/explain/default/with_limit_test.go +++ b/tests/integration/explain/default/with_limit_test.go @@ -19,10 +19,14 @@ import ( var limitPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "limitNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "limitNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -45,7 +49,7 @@ func TestDefaultExplainRequestWithOnlyLimit(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{limitPattern}, + ExpectedPatterns: limitPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -80,7 +84,7 @@ func TestDefaultExplainRequestWithOnlyOffset(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{limitPattern}, + ExpectedPatterns: limitPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -115,7 +119,7 @@ func TestDefaultExplainRequestWithLimitAndOffset(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{limitPattern}, + ExpectedPatterns: limitPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/with_order_join_test.go b/tests/integration/explain/default/with_order_join_test.go index ddffdeb776..1f1388ff51 100644 --- a/tests/integration/explain/default/with_order_join_test.go +++ b/tests/integration/explain/default/with_order_join_test.go @@ -51,12 +51,14 @@ func TestDefaultExplainRequestWithOrderFieldOnRelatedChild(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": orderTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": orderTypeJoinPattern, + }, }, }, }, @@ -105,13 +107,15 @@ func TestDefaultExplainRequestWithOrderFieldOnParentAndRelatedChild(t *testing.T } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "orderNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": orderTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "orderNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": orderTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/default/with_order_test.go b/tests/integration/explain/default/with_order_test.go index fda0eda753..6f0e3909f0 100644 --- a/tests/integration/explain/default/with_order_test.go +++ b/tests/integration/explain/default/with_order_test.go @@ -19,10 +19,14 @@ import ( var orderPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "orderNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "orderNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -46,7 +50,7 @@ func TestDefaultExplainRequestWithAscendingOrderOnParent(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{orderPattern}, + ExpectedPatterns: orderPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -88,7 +92,7 @@ func TestDefaultExplainRequestWithMultiOrderFieldsOnParent(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{orderPattern}, + ExpectedPatterns: orderPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/default/with_sum_join_test.go b/tests/integration/explain/default/with_sum_join_test.go index 0889b3bd85..d2b7b6dc64 100644 --- a/tests/integration/explain/default/with_sum_join_test.go +++ b/tests/integration/explain/default/with_sum_join_test.go @@ -21,10 +21,14 @@ import ( var sumTypeIndexJoinPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "sumNode": dataMap{ - "selectNode": dataMap{ - "typeIndexJoin": normalTypeJoinPattern, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "sumNode": dataMap{ + "selectNode": dataMap{ + "typeIndexJoin": normalTypeJoinPattern, + }, + }, }, }, }, @@ -51,7 +55,7 @@ func TestDefaultExplainRequestWithSumOnOneToManyJoinedField(t *testing.T) { } }`, - ExpectedPatterns: []dataMap{sumTypeIndexJoinPattern}, + ExpectedPatterns: sumTypeIndexJoinPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -142,7 +146,7 @@ func TestDefaultExplainRequestWithSumOnOneToManyJoinedFieldWithFilter(t *testing } }`, - ExpectedPatterns: []dataMap{sumTypeIndexJoinPattern}, + ExpectedPatterns: sumTypeIndexJoinPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { @@ -235,18 +239,20 @@ func TestDefaultExplainRequestWithSumOnOneToManyJoinedFieldWithManySources(t *te } }`, - ExpectedPatterns: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "sumNode": dataMap{ - "selectNode": dataMap{ - "parallelNode": []dataMap{ - { - "typeIndexJoin": normalTypeJoinPattern, - }, - { - "typeIndexJoin": normalTypeJoinPattern, + ExpectedPatterns: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "sumNode": dataMap{ + "selectNode": dataMap{ + "parallelNode": []dataMap{ + { + "typeIndexJoin": normalTypeJoinPattern, + }, + { + "typeIndexJoin": normalTypeJoinPattern, + }, }, }, }, diff --git a/tests/integration/explain/default/with_sum_test.go b/tests/integration/explain/default/with_sum_test.go index f7fbc8e715..2f1673ce3a 100644 --- a/tests/integration/explain/default/with_sum_test.go +++ b/tests/integration/explain/default/with_sum_test.go @@ -19,10 +19,14 @@ import ( var sumPattern = dataMap{ "explain": dataMap{ - "selectTopNode": dataMap{ - "sumNode": dataMap{ - "selectNode": dataMap{ - "scanNode": dataMap{}, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "sumNode": dataMap{ + "selectNode": dataMap{ + "scanNode": dataMap{}, + }, + }, }, }, }, @@ -46,7 +50,7 @@ func TestDefaultExplainRequestWithSumOnInlineArrayField_ChildFieldWillBeEmpty(t } }`, - ExpectedPatterns: []dataMap{sumPattern}, + ExpectedPatterns: sumPattern, ExpectedTargets: []testUtils.PlanNodeTargetCase{ { diff --git a/tests/integration/explain/execute/create_test.go b/tests/integration/explain/execute/create_test.go index 54876b57f5..29816b47c6 100644 --- a/tests/integration/explain/execute/create_test.go +++ b/tests/integration/explain/execute/create_test.go @@ -32,23 +32,25 @@ func TestExecuteExplainMutationRequestWithCreate(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 1, - "planExecutions": uint64(2), - "createNode": dataMap{ - "iterations": uint64(2), - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "iterations": uint64(2), - "filterMatches": uint64(1), - "scanNode": dataMap{ - "iterations": uint64(2), - "docFetches": uint64(1), - "fieldFetches": uint64(1), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "createNode": dataMap{ + "iterations": uint64(2), + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "iterations": uint64(2), + "filterMatches": uint64(1), + "scanNode": dataMap{ + "iterations": uint64(2), + "docFetches": uint64(1), + "fieldFetches": uint64(1), + "indexFetches": uint64(0), + }, }, }, }, diff --git a/tests/integration/explain/execute/dagscan_test.go b/tests/integration/explain/execute/dagscan_test.go index 524e2a1204..8093accba4 100644 --- a/tests/integration/explain/execute/dagscan_test.go +++ b/tests/integration/explain/execute/dagscan_test.go @@ -37,18 +37,20 @@ func TestExecuteExplainCommitsDagScan(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 5, - "planExecutions": uint64(6), - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "iterations": uint64(6), - "filterMatches": uint64(5), - "dagScanNode": dataMap{ - "iterations": uint64(6), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "iterations": uint64(6), + "filterMatches": uint64(5), + "dagScanNode": dataMap{ + "iterations": uint64(6), + }, }, }, }, @@ -83,18 +85,20 @@ func TestExecuteExplainLatestCommitsDagScan(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 1, - "planExecutions": uint64(2), - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "iterations": uint64(2), - "filterMatches": uint64(1), - "dagScanNode": dataMap{ - "iterations": uint64(2), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "iterations": uint64(2), + "filterMatches": uint64(1), + "dagScanNode": dataMap{ + "iterations": uint64(2), + }, }, }, }, diff --git a/tests/integration/explain/execute/delete_test.go b/tests/integration/explain/execute/delete_test.go index 99edd857a3..2d29f3a276 100644 --- a/tests/integration/explain/execute/delete_test.go +++ b/tests/integration/explain/execute/delete_test.go @@ -35,23 +35,25 @@ func TestExecuteExplainMutationRequestWithDeleteUsingID(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 1, - "planExecutions": uint64(2), - "deleteNode": dataMap{ - "iterations": uint64(2), - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "iterations": uint64(2), - "filterMatches": uint64(1), - "scanNode": dataMap{ - "iterations": uint64(2), - "docFetches": uint64(1), - "fieldFetches": uint64(1), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "deleteNode": dataMap{ + "iterations": uint64(2), + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "iterations": uint64(2), + "filterMatches": uint64(1), + "scanNode": dataMap{ + "iterations": uint64(2), + "docFetches": uint64(1), + "fieldFetches": uint64(1), + "indexFetches": uint64(0), + }, }, }, }, @@ -84,23 +86,25 @@ func TestExecuteExplainMutationRequestWithDeleteUsingFilter(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 1, - "planExecutions": uint64(2), - "deleteNode": dataMap{ - "iterations": uint64(2), - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "iterations": uint64(2), - "filterMatches": uint64(1), - "scanNode": dataMap{ - "iterations": uint64(2), - "docFetches": uint64(2), - "fieldFetches": uint64(2), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "deleteNode": dataMap{ + "iterations": uint64(2), + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "iterations": uint64(2), + "filterMatches": uint64(1), + "scanNode": dataMap{ + "iterations": uint64(2), + "docFetches": uint64(2), + "fieldFetches": uint64(2), + "indexFetches": uint64(0), + }, }, }, }, diff --git a/tests/integration/explain/execute/group_test.go b/tests/integration/explain/execute/group_test.go index 9d4dc096f9..6bd0870a38 100644 --- a/tests/integration/explain/execute/group_test.go +++ b/tests/integration/explain/execute/group_test.go @@ -38,28 +38,30 @@ func TestExecuteExplainRequestWithGroup(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 1, - "planExecutions": uint64(2), - "selectTopNode": dataMap{ - "groupNode": dataMap{ - "iterations": uint64(2), - "groups": uint64(1), - "childSelections": uint64(1), - "hiddenBeforeOffset": uint64(0), - "hiddenAfterLimit": uint64(0), - "hiddenChildSelections": uint64(0), - "selectNode": dataMap{ - "iterations": uint64(3), - "filterMatches": uint64(2), - "scanNode": dataMap{ - "iterations": uint64(4), - "docFetches": uint64(2), - "fieldFetches": uint64(4), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "groupNode": dataMap{ + "iterations": uint64(2), + "groups": uint64(1), + "childSelections": uint64(1), + "hiddenBeforeOffset": uint64(0), + "hiddenAfterLimit": uint64(0), + "hiddenChildSelections": uint64(0), + "selectNode": dataMap{ + "iterations": uint64(3), + "filterMatches": uint64(2), + "scanNode": dataMap{ + "iterations": uint64(4), + "docFetches": uint64(2), + "fieldFetches": uint64(4), + "indexFetches": uint64(0), + }, }, }, }, diff --git a/tests/integration/explain/execute/query_deleted_docs_test.go b/tests/integration/explain/execute/query_deleted_docs_test.go index 77a3b3708a..e925910bb6 100644 --- a/tests/integration/explain/execute/query_deleted_docs_test.go +++ b/tests/integration/explain/execute/query_deleted_docs_test.go @@ -30,8 +30,10 @@ func TestExecuteExplainQueryDeletedDocs(t *testing.T) { _docID } }`, - Results: []map[string]any{ - {"_docID": "bae-49f715e7-7f01-5509-a213-ed98cb81583f"}, + Results: map[string]any{ + "delete_ContactAddress": []map[string]any{ + {"_docID": "bae-49f715e7-7f01-5509-a213-ed98cb81583f"}, + }, }, }, testUtils.ExplainRequest{ @@ -42,21 +44,23 @@ func TestExecuteExplainQueryDeletedDocs(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 2, - "planExecutions": uint64(3), - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "iterations": uint64(3), - "filterMatches": uint64(2), - "scanNode": dataMap{ - "iterations": uint64(3), - "docFetches": uint64(2), - "fieldFetches": uint64(4), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "iterations": uint64(3), + "filterMatches": uint64(2), + "scanNode": dataMap{ + "iterations": uint64(3), + "docFetches": uint64(2), + "fieldFetches": uint64(4), + "indexFetches": uint64(0), + }, }, }, }, diff --git a/tests/integration/explain/execute/scan_test.go b/tests/integration/explain/execute/scan_test.go index a68f175015..b2c3192e43 100644 --- a/tests/integration/explain/execute/scan_test.go +++ b/tests/integration/explain/execute/scan_test.go @@ -53,21 +53,23 @@ func TestExecuteExplainRequestWithAllDocumentsMatching(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 2, - "planExecutions": uint64(3), - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "iterations": uint64(3), - "filterMatches": uint64(2), - "scanNode": dataMap{ - "iterations": uint64(3), - "docFetches": uint64(2), - "fieldFetches": uint64(4), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "iterations": uint64(3), + "filterMatches": uint64(2), + "scanNode": dataMap{ + "iterations": uint64(3), + "docFetches": uint64(2), + "fieldFetches": uint64(4), + "indexFetches": uint64(0), + }, }, }, }, @@ -96,21 +98,23 @@ func TestExecuteExplainRequestWithNoDocuments(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 0, - "planExecutions": uint64(1), - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "iterations": uint64(1), - "filterMatches": uint64(0), - "scanNode": dataMap{ - "iterations": uint64(1), - "docFetches": uint64(0), - "fieldFetches": uint64(0), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "iterations": uint64(1), + "filterMatches": uint64(0), + "scanNode": dataMap{ + "iterations": uint64(1), + "docFetches": uint64(0), + "fieldFetches": uint64(0), + "indexFetches": uint64(0), + }, }, }, }, @@ -160,21 +164,23 @@ func TestExecuteExplainRequestWithSomeDocumentsMatching(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "planExecutions": uint64(2), - "sizeOfResult": 1, - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "iterations": uint64(2), - "filterMatches": uint64(1), - "scanNode": dataMap{ - "iterations": uint64(2), - "docFetches": uint64(2), - "fieldFetches": uint64(4), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "planExecutions": uint64(2), + "sizeOfResult": 1, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "iterations": uint64(2), + "filterMatches": uint64(1), + "scanNode": dataMap{ + "iterations": uint64(2), + "docFetches": uint64(2), + "fieldFetches": uint64(4), + "indexFetches": uint64(0), + }, }, }, }, @@ -224,21 +230,23 @@ func TestExecuteExplainRequestWithDocumentsButNoMatches(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "planExecutions": uint64(1), - "sizeOfResult": 0, - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "iterations": uint64(1), - "filterMatches": uint64(0), - "scanNode": dataMap{ - "iterations": uint64(1), - "docFetches": uint64(2), - "fieldFetches": uint64(4), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "planExecutions": uint64(2), + "sizeOfResult": 1, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "iterations": uint64(1), + "filterMatches": uint64(0), + "scanNode": dataMap{ + "iterations": uint64(1), + "docFetches": uint64(2), + "fieldFetches": uint64(4), + "indexFetches": uint64(0), + }, }, }, }, diff --git a/tests/integration/explain/execute/top_level_test.go b/tests/integration/explain/execute/top_level_test.go index 360c9a3d2c..784d7fe8a9 100644 --- a/tests/integration/explain/execute/top_level_test.go +++ b/tests/integration/explain/execute/top_level_test.go @@ -54,44 +54,46 @@ func TestExecuteExplainTopLevelAverageRequest(t *testing.T) { ) }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 1, - "planExecutions": uint64(2), - "topLevelNode": []dataMap{ - { - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "iterations": uint64(3), - "filterMatches": uint64(2), - "scanNode": dataMap{ - "iterations": uint64(3), - "docFetches": uint64(2), - "fieldFetches": uint64(2), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "topLevelNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "iterations": uint64(3), + "filterMatches": uint64(2), + "scanNode": dataMap{ + "iterations": uint64(3), + "docFetches": uint64(2), + "fieldFetches": uint64(2), + "indexFetches": uint64(0), + }, }, }, }, - }, - { - "sumNode": dataMap{ - "iterations": uint64(1), + { + "sumNode": dataMap{ + "iterations": uint64(1), + }, }, - }, - { - "countNode": dataMap{ - "iterations": uint64(1), + { + "countNode": dataMap{ + "iterations": uint64(1), + }, }, - }, - { - "averageNode": dataMap{ + { + "averageNode": dataMap{ - "iterations": uint64(1), + "iterations": uint64(1), + }, }, }, }, @@ -138,31 +140,33 @@ func TestExecuteExplainTopLevelCountRequest(t *testing.T) { _count(Author: {}) }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 1, - "planExecutions": uint64(2), - "topLevelNode": []dataMap{ - { - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "iterations": uint64(3), - "filterMatches": uint64(2), - "scanNode": dataMap{ - "iterations": uint64(3), - "docFetches": uint64(2), - "fieldFetches": uint64(4), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "topLevelNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "iterations": uint64(3), + "filterMatches": uint64(2), + "scanNode": dataMap{ + "iterations": uint64(3), + "docFetches": uint64(2), + "fieldFetches": uint64(4), + "indexFetches": uint64(0), + }, }, }, }, - }, - { - "countNode": dataMap{ - "iterations": uint64(1), + { + "countNode": dataMap{ + "iterations": uint64(1), + }, }, }, }, @@ -213,31 +217,33 @@ func TestExecuteExplainTopLevelSumRequest(t *testing.T) { ) }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 1, - "planExecutions": uint64(2), - "topLevelNode": []dataMap{ - { - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "iterations": uint64(3), - "filterMatches": uint64(2), - "scanNode": dataMap{ - "iterations": uint64(3), - "docFetches": uint64(2), - "fieldFetches": uint64(2), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "topLevelNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "iterations": uint64(3), + "filterMatches": uint64(2), + "scanNode": dataMap{ + "iterations": uint64(3), + "docFetches": uint64(2), + "fieldFetches": uint64(2), + "indexFetches": uint64(0), + }, }, }, }, - }, - { - "sumNode": dataMap{ - "iterations": uint64(1), + { + "sumNode": dataMap{ + "iterations": uint64(1), + }, }, }, }, diff --git a/tests/integration/explain/execute/type_join_test.go b/tests/integration/explain/execute/type_join_test.go index ab89890f02..60f717a84f 100644 --- a/tests/integration/explain/execute/type_join_test.go +++ b/tests/integration/explain/execute/type_join_test.go @@ -40,29 +40,31 @@ func TestExecuteExplainRequestWithAOneToOneJoin(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 2, - "planExecutions": uint64(3), - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "iterations": uint64(3), - "filterMatches": uint64(2), - "typeIndexJoin": dataMap{ - "iterations": uint64(3), - "scanNode": dataMap{ - "iterations": uint64(3), - "docFetches": uint64(2), - "fieldFetches": uint64(2), - "indexFetches": uint64(0), - }, - "subTypeScanNode": dataMap{ - "iterations": uint64(2), - "docFetches": uint64(2), - "fieldFetches": uint64(2), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "iterations": uint64(3), + "filterMatches": uint64(2), + "typeIndexJoin": dataMap{ + "iterations": uint64(3), + "scanNode": dataMap{ + "iterations": uint64(3), + "docFetches": uint64(2), + "fieldFetches": uint64(2), + "indexFetches": uint64(0), + }, + "subTypeScanNode": dataMap{ + "iterations": uint64(2), + "docFetches": uint64(2), + "fieldFetches": uint64(2), + "indexFetches": uint64(0), + }, }, }, }, @@ -104,48 +106,50 @@ func TestExecuteExplainWithMultipleOneToOneJoins(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 2, - "planExecutions": uint64(3), - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "iterations": uint64(3), - "filterMatches": uint64(2), - "parallelNode": []dataMap{ - { - "typeIndexJoin": dataMap{ - "iterations": uint64(3), - "scanNode": dataMap{ - "iterations": uint64(3), - "docFetches": uint64(2), - "fieldFetches": uint64(2), - "indexFetches": uint64(0), - }, - "subTypeScanNode": dataMap{ - "iterations": uint64(2), - "docFetches": uint64(2), - "fieldFetches": uint64(2), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "iterations": uint64(3), + "filterMatches": uint64(2), + "parallelNode": []dataMap{ + { + "typeIndexJoin": dataMap{ + "iterations": uint64(3), + "scanNode": dataMap{ + "iterations": uint64(3), + "docFetches": uint64(2), + "fieldFetches": uint64(2), + "indexFetches": uint64(0), + }, + "subTypeScanNode": dataMap{ + "iterations": uint64(2), + "docFetches": uint64(2), + "fieldFetches": uint64(2), + "indexFetches": uint64(0), + }, }, }, - }, - { - "typeIndexJoin": dataMap{ - "iterations": uint64(3), - "scanNode": dataMap{ - "iterations": uint64(3), - "docFetches": uint64(2), - "fieldFetches": uint64(2), - "indexFetches": uint64(0), - }, - "subTypeScanNode": dataMap{ - "iterations": uint64(2), - "docFetches": uint64(2), - "fieldFetches": uint64(4), - "indexFetches": uint64(0), + { + "typeIndexJoin": dataMap{ + "iterations": uint64(3), + "scanNode": dataMap{ + "iterations": uint64(3), + "docFetches": uint64(2), + "fieldFetches": uint64(2), + "indexFetches": uint64(0), + }, + "subTypeScanNode": dataMap{ + "iterations": uint64(2), + "docFetches": uint64(2), + "fieldFetches": uint64(4), + "indexFetches": uint64(0), + }, }, }, }, @@ -187,29 +191,31 @@ func TestExecuteExplainWithTwoLevelDeepNestedJoins(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 2, - "planExecutions": uint64(3), - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "iterations": uint64(3), - "filterMatches": uint64(2), - "typeIndexJoin": dataMap{ - "iterations": uint64(3), - "scanNode": dataMap{ - "iterations": uint64(3), - "docFetches": uint64(2), - "fieldFetches": uint64(4), - "indexFetches": uint64(0), - }, - "subTypeScanNode": dataMap{ - "iterations": uint64(2), - "docFetches": uint64(2), - "fieldFetches": uint64(4), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "iterations": uint64(3), + "filterMatches": uint64(2), + "typeIndexJoin": dataMap{ + "iterations": uint64(3), + "scanNode": dataMap{ + "iterations": uint64(3), + "docFetches": uint64(2), + "fieldFetches": uint64(4), + "indexFetches": uint64(0), + }, + "subTypeScanNode": dataMap{ + "iterations": uint64(2), + "docFetches": uint64(2), + "fieldFetches": uint64(4), + "indexFetches": uint64(0), + }, }, }, }, diff --git a/tests/integration/explain/execute/update_test.go b/tests/integration/explain/execute/update_test.go index 0eaf8cbb22..4ed5e471c2 100644 --- a/tests/integration/explain/execute/update_test.go +++ b/tests/integration/explain/execute/update_test.go @@ -42,24 +42,26 @@ func TestExecuteExplainMutationRequestWithUpdateUsingIDs(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 2, - "planExecutions": uint64(3), - "updateNode": dataMap{ - "iterations": uint64(3), - "updates": uint64(2), - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "iterations": uint64(6), - "filterMatches": uint64(4), - "scanNode": dataMap{ - "iterations": uint64(6), - "docFetches": uint64(4), - "fieldFetches": uint64(8), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "updateNode": dataMap{ + "iterations": uint64(3), + "updates": uint64(2), + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "iterations": uint64(6), + "filterMatches": uint64(4), + "scanNode": dataMap{ + "iterations": uint64(6), + "docFetches": uint64(4), + "fieldFetches": uint64(8), + "indexFetches": uint64(0), + }, }, }, }, @@ -100,24 +102,26 @@ func TestExecuteExplainMutationRequestWithUpdateUsingFilter(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 1, - "planExecutions": uint64(2), - "updateNode": dataMap{ - "iterations": uint64(2), - "updates": uint64(1), - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "iterations": uint64(4), - "filterMatches": uint64(2), - "scanNode": dataMap{ - "iterations": uint64(4), - "docFetches": uint64(4), - "fieldFetches": uint64(6), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "updateNode": dataMap{ + "iterations": uint64(2), + "updates": uint64(1), + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "iterations": uint64(4), + "filterMatches": uint64(2), + "scanNode": dataMap{ + "iterations": uint64(4), + "docFetches": uint64(4), + "fieldFetches": uint64(6), + "indexFetches": uint64(0), + }, }, }, }, diff --git a/tests/integration/explain/execute/with_average_test.go b/tests/integration/explain/execute/with_average_test.go index 33a238eb68..1c81ce5021 100644 --- a/tests/integration/explain/execute/with_average_test.go +++ b/tests/integration/explain/execute/with_average_test.go @@ -35,27 +35,29 @@ func TestExecuteExplainAverageRequestOnArrayField(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 3, - "planExecutions": uint64(4), - "selectTopNode": dataMap{ - "averageNode": dataMap{ - "iterations": uint64(4), - "countNode": dataMap{ + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "averageNode": dataMap{ "iterations": uint64(4), - "sumNode": dataMap{ + "countNode": dataMap{ "iterations": uint64(4), - "selectNode": dataMap{ - "iterations": uint64(4), - "filterMatches": uint64(3), - "scanNode": dataMap{ - "iterations": uint64(4), - "docFetches": uint64(3), - "fieldFetches": uint64(5), - "indexFetches": uint64(0), + "sumNode": dataMap{ + "iterations": uint64(4), + "selectNode": dataMap{ + "iterations": uint64(4), + "filterMatches": uint64(3), + "scanNode": dataMap{ + "iterations": uint64(4), + "docFetches": uint64(3), + "fieldFetches": uint64(5), + "indexFetches": uint64(0), + }, }, }, }, @@ -90,35 +92,37 @@ func TestExplainExplainAverageRequestOnJoinedField(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 2, - "planExecutions": uint64(3), - "selectTopNode": dataMap{ - "averageNode": dataMap{ - "iterations": uint64(3), - "countNode": dataMap{ + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "averageNode": dataMap{ "iterations": uint64(3), - "sumNode": dataMap{ + "countNode": dataMap{ "iterations": uint64(3), - "selectNode": dataMap{ - "iterations": uint64(3), - "filterMatches": uint64(2), - "typeIndexJoin": dataMap{ - "iterations": uint64(3), - "scanNode": dataMap{ - "iterations": uint64(3), - "docFetches": uint64(2), - "fieldFetches": uint64(2), - "indexFetches": uint64(0), - }, - "subTypeScanNode": dataMap{ - "iterations": uint64(5), - "docFetches": uint64(6), - "fieldFetches": uint64(12), - "indexFetches": uint64(0), + "sumNode": dataMap{ + "iterations": uint64(3), + "selectNode": dataMap{ + "iterations": uint64(3), + "filterMatches": uint64(2), + "typeIndexJoin": dataMap{ + "iterations": uint64(3), + "scanNode": dataMap{ + "iterations": uint64(3), + "docFetches": uint64(2), + "fieldFetches": uint64(2), + "indexFetches": uint64(0), + }, + "subTypeScanNode": dataMap{ + "iterations": uint64(5), + "docFetches": uint64(6), + "fieldFetches": uint64(12), + "indexFetches": uint64(0), + }, }, }, }, diff --git a/tests/integration/explain/execute/with_count_test.go b/tests/integration/explain/execute/with_count_test.go index 23858e49d2..81dafce0d9 100644 --- a/tests/integration/explain/execute/with_count_test.go +++ b/tests/integration/explain/execute/with_count_test.go @@ -36,31 +36,33 @@ func TestExecuteExplainRequestWithCountOnOneToManyRelation(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 2, - "planExecutions": uint64(3), - "selectTopNode": dataMap{ - "countNode": dataMap{ - "iterations": uint64(3), - "selectNode": dataMap{ - "iterations": uint64(3), - "filterMatches": uint64(2), - "typeIndexJoin": dataMap{ - "iterations": uint64(3), - "scanNode": dataMap{ - "iterations": uint64(3), - "docFetches": uint64(2), - "fieldFetches": uint64(2), - "indexFetches": uint64(0), - }, - "subTypeScanNode": dataMap{ - "iterations": uint64(5), - "docFetches": uint64(6), - "fieldFetches": uint64(6), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "countNode": dataMap{ + "iterations": uint64(3), + "selectNode": dataMap{ + "iterations": uint64(3), + "filterMatches": uint64(2), + "typeIndexJoin": dataMap{ + "iterations": uint64(3), + "scanNode": dataMap{ + "iterations": uint64(3), + "docFetches": uint64(2), + "fieldFetches": uint64(2), + "indexFetches": uint64(0), + }, + "subTypeScanNode": dataMap{ + "iterations": uint64(5), + "docFetches": uint64(6), + "fieldFetches": uint64(6), + "indexFetches": uint64(0), + }, }, }, }, diff --git a/tests/integration/explain/execute/with_limit_test.go b/tests/integration/explain/execute/with_limit_test.go index cc703c9082..1f40902525 100644 --- a/tests/integration/explain/execute/with_limit_test.go +++ b/tests/integration/explain/execute/with_limit_test.go @@ -34,23 +34,25 @@ func TestExecuteExplainRequestWithBothLimitAndOffsetOnParent(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 1, - "planExecutions": uint64(2), - "selectTopNode": dataMap{ - "limitNode": dataMap{ - "iterations": uint64(2), - "selectNode": dataMap{ - "iterations": uint64(2), - "filterMatches": uint64(2), - "scanNode": dataMap{ - "iterations": uint64(2), - "docFetches": uint64(2), - "fieldFetches": uint64(2), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "limitNode": dataMap{ + "iterations": uint64(2), + "selectNode": dataMap{ + "iterations": uint64(2), + "filterMatches": uint64(2), + "scanNode": dataMap{ + "iterations": uint64(2), + "docFetches": uint64(2), + "fieldFetches": uint64(2), + "indexFetches": uint64(0), + }, }, }, }, @@ -86,31 +88,33 @@ func TestExecuteExplainRequestWithBothLimitAndOffsetOnParentAndLimitOnChild(t *t } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "planExecutions": uint64(2), - "sizeOfResult": 1, - "selectTopNode": dataMap{ - "limitNode": dataMap{ - "iterations": uint64(2), - "selectNode": dataMap{ - "iterations": uint64(2), - "filterMatches": uint64(2), - "typeIndexJoin": dataMap{ - "iterations": uint64(2), - "scanNode": dataMap{ - "iterations": uint64(2), - "docFetches": uint64(2), - "fieldFetches": uint64(2), - "indexFetches": uint64(0), - }, - "subTypeScanNode": dataMap{ - "iterations": uint64(2), - "docFetches": uint64(3), - "fieldFetches": uint64(5), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "planExecutions": uint64(2), + "sizeOfResult": 1, + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "limitNode": dataMap{ + "iterations": uint64(2), + "selectNode": dataMap{ + "iterations": uint64(2), + "filterMatches": uint64(2), + "typeIndexJoin": dataMap{ + "iterations": uint64(2), + "scanNode": dataMap{ + "iterations": uint64(2), + "docFetches": uint64(2), + "fieldFetches": uint64(2), + "indexFetches": uint64(0), + }, + "subTypeScanNode": dataMap{ + "iterations": uint64(2), + "docFetches": uint64(3), + "fieldFetches": uint64(5), + "indexFetches": uint64(0), + }, }, }, }, diff --git a/tests/integration/explain/execute/with_order_test.go b/tests/integration/explain/execute/with_order_test.go index a2441b9cd5..8b27cdbf04 100644 --- a/tests/integration/explain/execute/with_order_test.go +++ b/tests/integration/explain/execute/with_order_test.go @@ -36,23 +36,25 @@ func TestExecuteExplainRequestWithOrderFieldOnParent(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 2, - "planExecutions": uint64(3), - "selectTopNode": dataMap{ - "orderNode": dataMap{ - "iterations": uint64(3), - "selectNode": dataMap{ - "filterMatches": uint64(2), - "iterations": uint64(3), - "scanNode": dataMap{ - "iterations": uint64(3), - "docFetches": uint64(2), - "fieldFetches": uint64(4), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "orderNode": dataMap{ + "iterations": uint64(3), + "selectNode": dataMap{ + "filterMatches": uint64(2), + "iterations": uint64(3), + "scanNode": dataMap{ + "iterations": uint64(3), + "docFetches": uint64(2), + "fieldFetches": uint64(4), + "indexFetches": uint64(0), + }, }, }, }, @@ -120,23 +122,25 @@ func TestExecuteExplainRequestWithMultiOrderFieldsOnParent(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 4, - "planExecutions": uint64(5), - "selectTopNode": dataMap{ - "orderNode": dataMap{ - "iterations": uint64(5), - "selectNode": dataMap{ - "filterMatches": uint64(4), - "iterations": uint64(5), - "scanNode": dataMap{ - "iterations": uint64(5), - "docFetches": uint64(4), - "fieldFetches": uint64(8), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "orderNode": dataMap{ + "iterations": uint64(5), + "selectNode": dataMap{ + "filterMatches": uint64(4), + "iterations": uint64(5), + "scanNode": dataMap{ + "iterations": uint64(5), + "docFetches": uint64(4), + "fieldFetches": uint64(8), + "indexFetches": uint64(0), + }, }, }, }, @@ -172,29 +176,31 @@ func TestExecuteExplainRequestWithOrderFieldOnChild(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 2, - "planExecutions": uint64(3), - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "iterations": uint64(3), - "filterMatches": uint64(2), - "typeIndexJoin": dataMap{ - "iterations": uint64(3), - "scanNode": dataMap{ - "iterations": uint64(3), - "docFetches": uint64(2), - "fieldFetches": uint64(2), - "indexFetches": uint64(0), - }, - "subTypeScanNode": dataMap{ - "iterations": uint64(5), - "docFetches": uint64(6), - "fieldFetches": uint64(9), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "iterations": uint64(3), + "filterMatches": uint64(2), + "typeIndexJoin": dataMap{ + "iterations": uint64(3), + "scanNode": dataMap{ + "iterations": uint64(3), + "docFetches": uint64(2), + "fieldFetches": uint64(2), + "indexFetches": uint64(0), + }, + "subTypeScanNode": dataMap{ + "iterations": uint64(5), + "docFetches": uint64(6), + "fieldFetches": uint64(9), + "indexFetches": uint64(0), + }, }, }, }, @@ -231,31 +237,33 @@ func TestExecuteExplainRequestWithOrderFieldOnBothParentAndChild(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 2, - "planExecutions": uint64(3), - "selectTopNode": dataMap{ - "orderNode": dataMap{ - "iterations": uint64(3), - "selectNode": dataMap{ - "iterations": uint64(3), - "filterMatches": uint64(2), - "typeIndexJoin": dataMap{ - "iterations": uint64(3), - "scanNode": dataMap{ - "iterations": uint64(3), - "docFetches": uint64(2), - "fieldFetches": uint64(4), - "indexFetches": uint64(0), - }, - "subTypeScanNode": dataMap{ - "iterations": uint64(5), - "docFetches": uint64(6), - "fieldFetches": uint64(9), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "orderNode": dataMap{ + "iterations": uint64(3), + "selectNode": dataMap{ + "iterations": uint64(3), + "filterMatches": uint64(2), + "typeIndexJoin": dataMap{ + "iterations": uint64(3), + "scanNode": dataMap{ + "iterations": uint64(3), + "docFetches": uint64(2), + "fieldFetches": uint64(4), + "indexFetches": uint64(0), + }, + "subTypeScanNode": dataMap{ + "iterations": uint64(5), + "docFetches": uint64(6), + "fieldFetches": uint64(9), + "indexFetches": uint64(0), + }, }, }, }, diff --git a/tests/integration/explain/execute/with_sum_test.go b/tests/integration/explain/execute/with_sum_test.go index e9e3462045..dbc6b3761f 100644 --- a/tests/integration/explain/execute/with_sum_test.go +++ b/tests/integration/explain/execute/with_sum_test.go @@ -35,23 +35,25 @@ func TestExecuteExplainRequestWithSumOfInlineArrayField(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 3, - "planExecutions": uint64(4), - "selectTopNode": dataMap{ - "sumNode": dataMap{ - "iterations": uint64(4), - "selectNode": dataMap{ - "iterations": uint64(4), - "filterMatches": uint64(3), - "scanNode": dataMap{ - "iterations": uint64(4), - "docFetches": uint64(3), - "fieldFetches": uint64(5), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "sumNode": dataMap{ + "iterations": uint64(4), + "selectNode": dataMap{ + "iterations": uint64(4), + "filterMatches": uint64(3), + "scanNode": dataMap{ + "iterations": uint64(4), + "docFetches": uint64(3), + "fieldFetches": uint64(5), + "indexFetches": uint64(0), + }, }, }, }, @@ -88,31 +90,33 @@ func TestExecuteExplainRequestSumOfRelatedOneToManyField(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "executionSuccess": true, - "sizeOfResult": 2, - "planExecutions": uint64(3), - "selectTopNode": dataMap{ - "sumNode": dataMap{ - "iterations": uint64(3), - "selectNode": dataMap{ - "iterations": uint64(3), - "filterMatches": uint64(2), - "typeIndexJoin": dataMap{ - "iterations": uint64(3), - "scanNode": dataMap{ - "iterations": uint64(3), - "docFetches": uint64(2), - "fieldFetches": uint64(2), - "indexFetches": uint64(0), - }, - "subTypeScanNode": dataMap{ - "iterations": uint64(5), - "docFetches": uint64(6), - "fieldFetches": uint64(9), - "indexFetches": uint64(0), + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "executionSuccess": true, + "sizeOfResult": 1, + "planExecutions": uint64(2), + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "sumNode": dataMap{ + "iterations": uint64(3), + "selectNode": dataMap{ + "iterations": uint64(3), + "filterMatches": uint64(2), + "typeIndexJoin": dataMap{ + "iterations": uint64(3), + "scanNode": dataMap{ + "iterations": uint64(3), + "docFetches": uint64(2), + "fieldFetches": uint64(2), + "indexFetches": uint64(0), + }, + "subTypeScanNode": dataMap{ + "iterations": uint64(5), + "docFetches": uint64(6), + "fieldFetches": uint64(9), + "indexFetches": uint64(0), + }, }, }, }, diff --git a/tests/integration/explain/simple/basic_test.go b/tests/integration/explain/simple/basic_test.go index d94deb01a9..04de88cd45 100644 --- a/tests/integration/explain/simple/basic_test.go +++ b/tests/integration/explain/simple/basic_test.go @@ -35,21 +35,23 @@ func TestSimpleExplainRequest(t *testing.T) { } }`, - ExpectedFullGraph: []dataMap{ - { - "explain": dataMap{ - "selectTopNode": dataMap{ - "selectNode": dataMap{ - "docIDs": nil, - "filter": nil, - "scanNode": dataMap{ - "filter": nil, - "collectionID": "3", - "collectionName": "Author", - "spans": []dataMap{ - { - "start": "/3", - "end": "/4", + ExpectedFullGraph: dataMap{ + "explain": dataMap{ + "operationNode": []dataMap{ + { + "selectTopNode": dataMap{ + "selectNode": dataMap{ + "docIDs": nil, + "filter": nil, + "scanNode": dataMap{ + "filter": nil, + "collectionID": "3", + "collectionName": "Author", + "spans": []dataMap{ + { + "start": "/3", + "end": "/4", + }, }, }, }, diff --git a/tests/integration/explain_result_asserter.go b/tests/integration/explain_result_asserter.go index 7d510bdc1a..e4c1e80988 100644 --- a/tests/integration/explain_result_asserter.go +++ b/tests/integration/explain_result_asserter.go @@ -55,9 +55,8 @@ func readNumberProp(t testing.TB, val any, prop string) uint64 { return 0 } -func (a *ExplainResultAsserter) Assert(t testing.TB, result []dataMap) { - require.Len(t, result, 1, "Expected len(result) = 1, got %d", len(result)) - explainNode, ok := result[0]["explain"].(dataMap) +func (a *ExplainResultAsserter) Assert(t testing.TB, result map[string]any) { + explainNode, ok := result["explain"].(dataMap) require.True(t, ok, "Expected explain none") assert.Equal(t, true, explainNode["executionSuccess"], "Expected executionSuccess property") if a.sizeOfResults.HasValue() { @@ -70,7 +69,9 @@ func (a *ExplainResultAsserter) Assert(t testing.TB, result []dataMap) { assert.Equal(t, a.planExecutions.Value(), actual, "Expected %d planExecutions, got %d", a.planExecutions.Value(), actual) } - selectTopNode, ok := explainNode["selectTopNode"].(dataMap) + operationNode := ConvertToArrayOfMaps(t, explainNode["operationNode"]) + require.Len(t, operationNode, 1) + selectTopNode, ok := operationNode[0]["selectTopNode"].(dataMap) require.True(t, ok, "Expected selectTopNode") selectNode, ok := selectTopNode["selectNode"].(dataMap) require.True(t, ok, "Expected selectNode") diff --git a/tests/integration/index/create_drop_test.go b/tests/integration/index/create_drop_test.go index a9e55f0322..17cd47df2a 100644 --- a/tests/integration/index/create_drop_test.go +++ b/tests/integration/index/create_drop_test.go @@ -49,10 +49,12 @@ func TestIndexDrop_ShouldNotHinderQuerying(t *testing.T) { age } }`, - Results: []map[string]any{ - { - "name": "John", - "age": int64(21), + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "John", + "age": int64(21), + }, }, }, }, diff --git a/tests/integration/index/create_test.go b/tests/integration/index/create_test.go index 9afb8ea333..7b7242ca1a 100644 --- a/tests/integration/index/create_test.go +++ b/tests/integration/index/create_test.go @@ -46,10 +46,12 @@ func TestIndexCreateWithCollection_ShouldNotHinderQuerying(t *testing.T) { age } }`, - Results: []map[string]any{ - { - "name": "John", - "age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "age": int64(21), + }, }, }, }, @@ -93,10 +95,12 @@ func TestIndexCreate_ShouldNotHinderQuerying(t *testing.T) { age } }`, - Results: []map[string]any{ - { - "name": "John", - "age": int64(21), + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "John", + "age": int64(21), + }, }, }, }, diff --git a/tests/integration/index/create_unique_test.go b/tests/integration/index/create_unique_test.go index 36488ecaab..eb353ca70e 100644 --- a/tests/integration/index/create_unique_test.go +++ b/tests/integration/index/create_unique_test.go @@ -110,7 +110,9 @@ func TestUniqueIndexCreate_UponAddingDocWithExistingFieldValue_ReturnError(t *te name } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "User": []map[string]any{}, + }, }, testUtils.GetIndexes{ CollectionID: 0, diff --git a/tests/integration/index/drop_test.go b/tests/integration/index/drop_test.go index 4639bfa756..a32f9706c7 100644 --- a/tests/integration/index/drop_test.go +++ b/tests/integration/index/drop_test.go @@ -50,10 +50,12 @@ func TestIndexDrop_IfIndexDoesNotExist_ReturnError(t *testing.T) { age } }`, - Results: []map[string]any{ - { - "name": "John", - "age": int64(21), + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "John", + "age": int64(21), + }, }, }, }, diff --git a/tests/integration/index/index_p2p_test.go b/tests/integration/index/index_p2p_test.go index 820d6d2c5b..7be45dd61c 100644 --- a/tests/integration/index/index_p2p_test.go +++ b/tests/integration/index/index_p2p_test.go @@ -56,9 +56,11 @@ func TestIndexP2P_IfPeerCreatedDoc_ListeningPeerShouldIndexIt(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "Fred", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Fred", + }, }, }, }, @@ -113,9 +115,11 @@ func TestIndexP2P_IfPeerUpdateDoc_ListeningPeerShouldUpdateIndex(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "Islam", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Islam", + }, }, }, }, @@ -177,9 +181,11 @@ func TestIndexP2P_IfPeerDeleteDoc_ListeningPeerShouldDeleteIndex(t *testing.T) { age } }`, - Results: []map[string]any{ - { - "age": int64(30), + Results: map[string]any{ + "Users": []map[string]any{ + { + "age": int64(30), + }, }, }, }, diff --git a/tests/integration/index/query_with_composite_index_field_order_test.go b/tests/integration/index/query_with_composite_index_field_order_test.go index 611bfed998..7b38163c1c 100644 --- a/tests/integration/index/query_with_composite_index_field_order_test.go +++ b/tests/integration/index/query_with_composite_index_field_order_test.go @@ -67,22 +67,24 @@ func TestQueryWithCompositeIndex_WithDefaultOrder_ShouldFetchInDefaultOrder(t *t age } }`, - Results: []map[string]any{ - { - "name": "Alan", - "age": 29, - }, - { - "name": "Alice", - "age": 22, - }, - { - "name": "Alice", - "age": 24, - }, - { - "name": "Alice", - "age": 38, + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Alan", + "age": 29, + }, + { + "name": "Alice", + "age": 22, + }, + { + "name": "Alice", + "age": 24, + }, + { + "name": "Alice", + "age": 38, + }, }, }, }, @@ -143,22 +145,24 @@ func TestQueryWithCompositeIndex_WithDefaultOrderCaseInsensitive_ShouldFetchInDe age } }`, - Results: []map[string]any{ - { - "name": "Alan", - "age": 29, - }, - { - "name": "Alice", - "age": 22, - }, - { - "name": "Alice", - "age": 24, - }, - { - "name": "Alice", - "age": 38, + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Alan", + "age": 29, + }, + { + "name": "Alice", + "age": 22, + }, + { + "name": "Alice", + "age": 24, + }, + { + "name": "Alice", + "age": 38, + }, }, }, }, @@ -227,26 +231,28 @@ func TestQueryWithCompositeIndex_WithRevertedOrderOnFirstField_ShouldFetchInReve age } }`, - Results: []map[string]any{ - { - "name": "Andy", - "age": 24, - }, - { - "name": "Alice", - "age": 22, - }, - { - "name": "Alice", - "age": 24, - }, - { - "name": "Alice", - "age": 38, - }, - { - "name": "Alan", - "age": 29, + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Andy", + "age": 24, + }, + { + "name": "Alice", + "age": 22, + }, + { + "name": "Alice", + "age": 24, + }, + { + "name": "Alice", + "age": 38, + }, + { + "name": "Alan", + "age": 29, + }, }, }, }, @@ -315,26 +321,28 @@ func TestQueryWithCompositeIndex_WithRevertedOrderOnFirstFieldCaseInsensitive_Sh age } }`, - Results: []map[string]any{ - { - "name": "Andy", - "age": 24, - }, - { - "name": "Alice", - "age": 22, - }, - { - "name": "Alice", - "age": 24, - }, - { - "name": "Alice", - "age": 38, - }, - { - "name": "Alan", - "age": 29, + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Andy", + "age": 24, + }, + { + "name": "Alice", + "age": 22, + }, + { + "name": "Alice", + "age": 24, + }, + { + "name": "Alice", + "age": 38, + }, + { + "name": "Alan", + "age": 29, + }, }, }, }, @@ -395,22 +403,24 @@ func TestQueryWithCompositeIndex_WithRevertedOrderOnSecondField_ShouldFetchInRev age } }`, - Results: []map[string]any{ - { - "name": "Alan", - "age": 29, - }, - { - "name": "Alice", - "age": 38, - }, - { - "name": "Alice", - "age": 24, - }, - { - "name": "Alice", - "age": 22, + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Alan", + "age": 29, + }, + { + "name": "Alice", + "age": 38, + }, + { + "name": "Alice", + "age": 24, + }, + { + "name": "Alice", + "age": 22, + }, }, }, }, @@ -473,22 +483,24 @@ func TestQueryWithCompositeIndex_WithRevertedOrderOnSecondFieldCaseInsensitive_S age } }`, - Results: []map[string]any{ - { - "name": "Alan", - "age": 29, - }, - { - "name": "Alice", - "age": 38, - }, - { - "name": "Alice", - "age": 24, - }, - { - "name": "Alice", - "age": 22, + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Alan", + "age": 29, + }, + { + "name": "Alice", + "age": 38, + }, + { + "name": "Alice", + "age": 24, + }, + { + "name": "Alice", + "age": 22, + }, }, }, }, @@ -541,10 +553,12 @@ func TestQueryWithCompositeIndex_IfExactMatchWithRevertedOrderOnFirstField_Shoul age } }`, - Results: []map[string]any{ - { - "name": "Alice", - "age": 22, + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Alice", + "age": 22, + }, }, }, }, @@ -597,10 +611,12 @@ func TestQueryWithCompositeIndex_IfExactMatchWithRevertedOrderOnSecondField_Shou age } }`, - Results: []map[string]any{ - { - "name": "Alice", - "age": 22, + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Alice", + "age": 22, + }, }, }, }, @@ -631,10 +647,12 @@ func TestQueryWithCompositeIndex_WithInFilterOnFirstFieldWithRevertedOrder_Shoul name } }`, - Results: []map[string]any{ - {"name": "Addo"}, - {"name": "Andy"}, - {"name": "Fred"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Addo"}, + {"name": "Andy"}, + {"name": "Fred"}, + }, }, }, }, @@ -664,10 +682,12 @@ func TestQueryWithCompositeIndex_WithInFilterOnSecondFieldWithRevertedOrder_Shou name } }`, - Results: []map[string]any{ - {"name": "Shahzad"}, - {"name": "Andy"}, - {"name": "Fred"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Shahzad"}, + {"name": "Andy"}, + {"name": "Fred"}, + }, }, }, }, diff --git a/tests/integration/index/query_with_composite_index_only_filter_test.go b/tests/integration/index/query_with_composite_index_only_filter_test.go index ccb2a43e66..94e6a54727 100644 --- a/tests/integration/index/query_with_composite_index_only_filter_test.go +++ b/tests/integration/index/query_with_composite_index_only_filter_test.go @@ -51,8 +51,10 @@ func TestQueryWithCompositeIndex_WithEqualFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req1, - Results: []map[string]any{ - {"name": "Islam", "age": 32}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Islam", "age": 32}, + }, }, }, testUtils.Request{ @@ -61,8 +63,10 @@ func TestQueryWithCompositeIndex_WithEqualFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req2, - Results: []map[string]any{ - {"name": "Islam", "age": 32}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Islam", "age": 32}, + }, }, }, testUtils.Request{ @@ -71,7 +75,9 @@ func TestQueryWithCompositeIndex_WithEqualFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req3, - Results: []map[string]any{}, + Results: map[string]any{ + "User": []map[string]any{}, + }, }, }, } @@ -101,8 +107,10 @@ func TestQueryWithCompositeIndex_WithGreaterThanFilterOnFirstField_ShouldFetch(t }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Chris"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Chris"}, + }, }, }, testUtils.Request{ @@ -137,8 +145,10 @@ func TestQueryWithCompositeIndex_WithGreaterThanFilterOnSecondField_ShouldFetch( }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Chris"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Chris"}, + }, }, }, testUtils.Request{ @@ -173,9 +183,11 @@ func TestQueryWithCompositeIndex_WithGreaterOrEqualFilterOnFirstField_ShouldFetc }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Roy"}, - {"name": "Chris"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Roy"}, + {"name": "Chris"}, + }, }, }, testUtils.Request{ @@ -210,9 +222,11 @@ func TestQueryWithCompositeIndex_WithGreaterOrEqualFilterOnSecondField_ShouldFet }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Chris"}, - {"name": "Roy"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Chris"}, + {"name": "Roy"}, + }, }, }, testUtils.Request{ @@ -247,8 +261,10 @@ func TestQueryWithCompositeIndex_WithLessThanFilterOnFirstField_ShouldFetch(t *t }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Bruno"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Bruno"}, + }, }, }, testUtils.Request{ @@ -283,8 +299,10 @@ func TestQueryWithCompositeIndex_WithLessThanFilterOnSecondField_ShouldFetch(t * }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Bruno"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Bruno"}, + }, }, }, testUtils.Request{ @@ -319,9 +337,11 @@ func TestQueryWithCompositeIndex_WithLessOrEqualFilterOnFirstField_ShouldFetch(t }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Shahzad"}, - {"name": "Fred"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Shahzad"}, + {"name": "Fred"}, + }, }, }, testUtils.Request{ @@ -356,9 +376,11 @@ func TestQueryWithCompositeIndex_WithLessOrEqualFilterOnSecondField_ShouldFetch( }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Fred"}, - {"name": "Shahzad"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Fred"}, + {"name": "Shahzad"}, + }, }, }, testUtils.Request{ @@ -393,15 +415,17 @@ func TestQueryWithCompositeIndex_WithNotEqualFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Addo"}, - {"name": "Andy"}, - {"name": "Bruno"}, - {"name": "Chris"}, - {"name": "John"}, - {"name": "Keenan"}, - {"name": "Roy"}, - {"name": "Shahzad"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Addo"}, + {"name": "Andy"}, + {"name": "Bruno"}, + {"name": "Chris"}, + {"name": "John"}, + {"name": "Keenan"}, + {"name": "Roy"}, + {"name": "Shahzad"}, + }, }, }, testUtils.Request{ @@ -436,9 +460,11 @@ func TestQueryWithCompositeIndex_WithInFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Andy"}, - {"name": "Fred"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Andy"}, + {"name": "Fred"}, + }, }, }, testUtils.Request{ @@ -473,10 +499,12 @@ func TestQueryWithCompositeIndex_WithNotInFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Islam"}, - {"name": "Keenan"}, - {"name": "Roy"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Islam"}, + {"name": "Keenan"}, + {"name": "Roy"}, + }, }, }, testUtils.Request{ @@ -540,8 +568,10 @@ func TestQueryWithCompositeIndex_WithLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req1, - Results: []map[string]any{ - {"name": "Addo"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Addo"}, + }, }, }, testUtils.Request{ @@ -550,8 +580,10 @@ func TestQueryWithCompositeIndex_WithLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req2, - Results: []map[string]any{ - {"name": "Fred"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Fred"}, + }, }, }, testUtils.Request{ @@ -560,8 +592,10 @@ func TestQueryWithCompositeIndex_WithLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req3, - Results: []map[string]any{ - {"name": "Keenan"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Keenan"}, + }, }, }, testUtils.Request{ @@ -570,8 +604,10 @@ func TestQueryWithCompositeIndex_WithLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req4, - Results: []map[string]any{ - {"name": "Fred"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Fred"}, + }, }, }, testUtils.Request{ @@ -580,8 +616,10 @@ func TestQueryWithCompositeIndex_WithLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req5, - Results: []map[string]any{ - {"name": "Addo"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Addo"}, + }, }, }, testUtils.Request{ @@ -590,11 +628,15 @@ func TestQueryWithCompositeIndex_WithLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req6, - Results: []map[string]any{}, + Results: map[string]any{ + "User": []map[string]any{}, + }, }, testUtils.Request{ Request: req7, - Results: []map[string]any{}, + Results: map[string]any{ + "User": []map[string]any{}, + }, }, }, } @@ -623,11 +665,13 @@ func TestQueryWithCompositeIndex_WithNotLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Bruno"}, - {"name": "Islam"}, - {"name": "Keenan"}, - {"name": "Roy"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Bruno"}, + {"name": "Islam"}, + {"name": "Keenan"}, + {"name": "Roy"}, + }, }, }, testUtils.Request{ @@ -704,8 +748,10 @@ func TestQueryWithCompositeIndex_WithEqualFilterOnNilValueOnFirst_ShouldFetch(t age } }`, - Results: []map[string]any{ - {"name": nil, "age": 32}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": nil, "age": 32}, + }, }, }, }, @@ -756,10 +802,12 @@ func TestQueryWithCompositeIndex_WithEqualFilterOnNilValueOnSecond_ShouldFetch(t age } }`, - Results: []map[string]any{ - { - "name": "Alice", - "age": nil, + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Alice", + "age": nil, + }, }, }, }, @@ -815,9 +863,11 @@ func TestQueryWithCompositeIndex_IfMiddleFieldIsNotInFilter_ShouldIgnoreValue(t name } }`, - Results: []map[string]any{ - { - "name": "Alan", + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Alan", + }, }, }, }, @@ -907,11 +957,13 @@ func TestQueryWithCompositeIndex_IfConsecutiveEqOps_ShouldUseAllToOptimizeQuery( }, testUtils.Request{ Request: reqWithName, - Results: []map[string]any{ - {"about": "bob3"}, - {"about": "bob2"}, - {"about": "bob1"}, - {"about": "bob4"}, + Results: map[string]any{ + "User": []map[string]any{ + {"about": "bob3"}, + {"about": "bob2"}, + {"about": "bob1"}, + {"about": "bob4"}, + }, }, }, testUtils.Request{ @@ -920,10 +972,12 @@ func TestQueryWithCompositeIndex_IfConsecutiveEqOps_ShouldUseAllToOptimizeQuery( }, testUtils.Request{ Request: reqWithNameAge, - Results: []map[string]any{ - {"about": "bob3"}, - {"about": "bob2"}, - {"about": "bob1"}, + Results: map[string]any{ + "User": []map[string]any{ + {"about": "bob3"}, + {"about": "bob2"}, + {"about": "bob1"}, + }, }, }, testUtils.Request{ @@ -932,9 +986,11 @@ func TestQueryWithCompositeIndex_IfConsecutiveEqOps_ShouldUseAllToOptimizeQuery( }, testUtils.Request{ Request: reqWithNameAgeNumChildren, - Results: []map[string]any{ - {"about": "bob2"}, - {"about": "bob1"}, + Results: map[string]any{ + "User": []map[string]any{ + {"about": "bob2"}, + {"about": "bob1"}, + }, }, }, testUtils.Request{ diff --git a/tests/integration/index/query_with_compound_filter_relation_test.go b/tests/integration/index/query_with_compound_filter_relation_test.go index 8f74411536..4708bb2c2a 100644 --- a/tests/integration/index/query_with_compound_filter_relation_test.go +++ b/tests/integration/index/query_with_compound_filter_relation_test.go @@ -43,7 +43,9 @@ func TestIndex_QueryWithIndexOnOneToManyRelationAndFilter_NoData(t *testing.T) { name } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Program": []map[string]any{}, + }, }, }, } @@ -78,7 +80,9 @@ func TestIndex_QueryWithIndexOnOneToManyRelationOrFilter_NoData(t *testing.T) { name } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Program": []map[string]any{}, + }, }, }, } @@ -113,7 +117,9 @@ func TestIndex_QueryWithIndexOnOneToManyRelationNotFilter_NoData(t *testing.T) { name } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Program": []map[string]any{}, + }, }, }, } @@ -187,12 +193,14 @@ func TestIndex_QueryWithIndexOnOneToManyRelationAndFilter_Data(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "LensVM", - }, - { - "name": "DefraDB", + Results: map[string]any{ + "Program": []map[string]any{ + { + "name": "LensVM", + }, + { + "name": "DefraDB", + }, }, }, }, @@ -269,15 +277,17 @@ func TestIndex_QueryWithIndexOnOneToManyRelationOrFilter_Data(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "Zanzi", - }, - { - "name": "LensVM", - }, - { - "name": "DefraDB", + Results: map[string]any{ + "Program": []map[string]any{ + { + "name": "Zanzi", + }, + { + "name": "LensVM", + }, + { + "name": "DefraDB", + }, }, }, }, @@ -346,12 +356,14 @@ func TestIndex_QueryWithIndexOnOneToManyRelationNotFilter_Data(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "Zanzi", - }, - { - "name": "Horizon", + Results: map[string]any{ + "Program": []map[string]any{ + { + "name": "Zanzi", + }, + { + "name": "Horizon", + }, }, }, }, diff --git a/tests/integration/index/query_with_index_combined_filter_test.go b/tests/integration/index/query_with_index_combined_filter_test.go index 595bf5fe44..0a6251db46 100644 --- a/tests/integration/index/query_with_index_combined_filter_test.go +++ b/tests/integration/index/query_with_index_combined_filter_test.go @@ -40,8 +40,10 @@ func TestQueryWithIndex_IfIndexFilterWithRegular_ShouldFilter(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Addo"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Addo"}, + }, }, }, testUtils.Request{ @@ -80,8 +82,10 @@ func TestQueryWithIndex_IfMultipleIndexFiltersWithRegular_ShouldFilter(t *testin }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Islam"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Islam"}, + }, }, }, testUtils.Request{ @@ -119,9 +123,11 @@ func TestQueryWithIndex_IfMultipleIndexFiltersWithRegularCaseInsensitive_ShouldF }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Andy"}, - {"name": "Addo"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Andy"}, + {"name": "Addo"}, + }, }, }, testUtils.Request{ @@ -157,8 +163,10 @@ func TestQueryWithIndex_FilterOnNonIndexedField_ShouldIgnoreIndex(t *testing.T) }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Roy"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Roy"}, + }, }, }, testUtils.Request{ diff --git a/tests/integration/index/query_with_index_only_field_order_test.go b/tests/integration/index/query_with_index_only_field_order_test.go index 13a2f7cb77..6fdccf249a 100644 --- a/tests/integration/index/query_with_index_only_field_order_test.go +++ b/tests/integration/index/query_with_index_only_field_order_test.go @@ -56,16 +56,22 @@ func TestQueryWithIndex_IfIntFieldInDescOrder_ShouldFetchInRevertedOrder(t *test age } }`, - Results: []map[string]any{{ - "name": "Bob", - "age": 24, - }, { - "name": "Kate", - "age": 23, - }, { - "name": "Alice", - "age": 22, - }}, + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Bob", + "age": 24, + }, + { + "name": "Kate", + "age": 23, + }, + { + "name": "Alice", + "age": 22, + }, + }, + }, }, }, } @@ -113,16 +119,22 @@ func TestQueryWithIndex_IfFloatFieldInDescOrder_ShouldFetchInRevertedOrder(t *te iq } }`, - Results: []map[string]any{{ - "name": "Bob", - "iq": 0.4, - }, { - "name": "Kate", - "iq": 0.3, - }, { - "name": "Alice", - "iq": 0.2, - }}, + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Bob", + "iq": 0.4, + }, + { + "name": "Kate", + "iq": 0.3, + }, + { + "name": "Alice", + "iq": 0.2, + }, + }, + }, }, }, } @@ -165,13 +177,19 @@ func TestQueryWithIndex_IfStringFieldInDescOrder_ShouldFetchInRevertedOrder(t *t name } }`, - Results: []map[string]any{{ - "name": "Andy", - }, { - "name": "Alice", - }, { - "name": "Aaron", - }}, + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Andy", + }, + { + "name": "Alice", + }, + { + "name": "Aaron", + }, + }, + }, }, }, } diff --git a/tests/integration/index/query_with_index_only_filter_test.go b/tests/integration/index/query_with_index_only_filter_test.go index 1baf7248ac..1800b855aa 100644 --- a/tests/integration/index/query_with_index_only_filter_test.go +++ b/tests/integration/index/query_with_index_only_filter_test.go @@ -38,10 +38,14 @@ func TestQueryWithIndex_WithNonIndexedFields_ShouldFetchAllOfThem(t *testing.T) }, testUtils.Request{ Request: req, - Results: []map[string]any{{ - "name": "Islam", - "age": int64(32), - }}, + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Islam", + "age": int64(32), + }, + }, + }, }, testUtils.Request{ Request: makeExplainQuery(req), @@ -73,8 +77,10 @@ func TestQueryWithIndex_WithEqualFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Islam"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Islam"}, + }, }, }, testUtils.Request{ @@ -115,9 +121,11 @@ func TestQueryWithIndex_IfSeveralDocsWithEqFilter_ShouldFetchAll(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"age": int64(32)}, - {"age": int64(18)}, + Results: map[string]any{ + "User": []map[string]any{ + {"age": int64(32)}, + {"age": int64(18)}, + }, }, }, testUtils.Request{ @@ -151,8 +159,10 @@ func TestQueryWithIndex_WithGreaterThanFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Chris"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Chris"}, + }, }, }, testUtils.Request{ @@ -186,9 +196,11 @@ func TestQueryWithIndex_WithGreaterOrEqualFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Keenan"}, - {"name": "Chris"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Keenan"}, + {"name": "Chris"}, + }, }, }, testUtils.Request{ @@ -222,8 +234,10 @@ func TestQueryWithIndex_WithLessThanFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Shahzad"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Shahzad"}, + }, }, }, testUtils.Request{ @@ -257,9 +271,11 @@ func TestQueryWithIndex_WithLessOrEqualFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Shahzad"}, - {"name": "Bruno"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Shahzad"}, + {"name": "Bruno"}, + }, }, }, testUtils.Request{ @@ -293,16 +309,18 @@ func TestQueryWithIndex_WithNotEqualFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Addo"}, - {"name": "Andy"}, - {"name": "Bruno"}, - {"name": "Chris"}, - {"name": "Fred"}, - {"name": "John"}, - {"name": "Keenan"}, - {"name": "Roy"}, - {"name": "Shahzad"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Addo"}, + {"name": "Andy"}, + {"name": "Bruno"}, + {"name": "Chris"}, + {"name": "Fred"}, + {"name": "John"}, + {"name": "Keenan"}, + {"name": "Roy"}, + {"name": "Shahzad"}, + }, }, }, testUtils.Request{ @@ -336,9 +354,11 @@ func TestQueryWithIndex_WithInFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Shahzad"}, - {"name": "Andy"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Shahzad"}, + {"name": "Andy"}, + }, }, }, testUtils.Request{ @@ -393,9 +413,11 @@ func TestQueryWithIndex_WithInFilterOnFloat_ShouldFetch(t *testing.T) { name } }`, - Results: []map[string]any{ - {"name": "Islam"}, - {"name": "Fred"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Islam"}, + {"name": "Fred"}, + }, }, }, }, @@ -432,9 +454,11 @@ func TestQueryWithIndex_IfSeveralDocsWithInFilter_ShouldFetchAll(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"age": int64(32)}, - {"age": int64(18)}, + Results: map[string]any{ + "User": []map[string]any{ + {"age": int64(32)}, + {"age": int64(18)}, + }, }, }, testUtils.Request{ @@ -468,11 +492,13 @@ func TestQueryWithIndex_WithNotInFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "John"}, - {"name": "Islam"}, - {"name": "Roy"}, - {"name": "Keenan"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "John"}, + {"name": "Islam"}, + {"name": "Roy"}, + {"name": "Keenan"}, + }, }, }, testUtils.Request{ @@ -531,9 +557,11 @@ func TestQueryWithIndex_WithLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req1, - Results: []map[string]any{ - {"name": "Addo"}, - {"name": "Andy"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Addo"}, + {"name": "Andy"}, + }, }, }, testUtils.Request{ @@ -542,9 +570,11 @@ func TestQueryWithIndex_WithLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req2, - Results: []map[string]any{ - {"name": "Fred"}, - {"name": "Shahzad"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Fred"}, + {"name": "Shahzad"}, + }, }, }, testUtils.Request{ @@ -553,9 +583,11 @@ func TestQueryWithIndex_WithLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req3, - Results: []map[string]any{ - {"name": "Fred"}, - {"name": "Keenan"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Fred"}, + {"name": "Keenan"}, + }, }, }, testUtils.Request{ @@ -564,8 +596,10 @@ func TestQueryWithIndex_WithLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req4, - Results: []map[string]any{ - {"name": "Fred"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Fred"}, + }, }, }, testUtils.Request{ @@ -574,9 +608,11 @@ func TestQueryWithIndex_WithLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req5, - Results: []map[string]any{ - {"name": "Addo"}, - {"name": "Andy"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Addo"}, + {"name": "Andy"}, + }, }, }, testUtils.Request{ @@ -585,7 +621,9 @@ func TestQueryWithIndex_WithLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req6, - Results: []map[string]any{}, + Results: map[string]any{ + "User": []map[string]any{}, + }, }, testUtils.Request{ Request: makeExplainQuery(req6), @@ -618,14 +656,16 @@ func TestQueryWithIndex_WithNotLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Addo"}, - {"name": "Andy"}, - {"name": "Bruno"}, - {"name": "Fred"}, - {"name": "Islam"}, - {"name": "Keenan"}, - {"name": "Roy"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Addo"}, + {"name": "Andy"}, + {"name": "Bruno"}, + {"name": "Fred"}, + {"name": "Islam"}, + {"name": "Keenan"}, + {"name": "Roy"}, + }, }, }, testUtils.Request{ diff --git a/tests/integration/index/query_with_relation_filter_test.go b/tests/integration/index/query_with_relation_filter_test.go index a7f13788dd..10492a99aa 100644 --- a/tests/integration/index/query_with_relation_filter_test.go +++ b/tests/integration/index/query_with_relation_filter_test.go @@ -54,10 +54,12 @@ func TestQueryWithIndexOnOneToManyRelation_IfFilterOnIndexedRelation_ShouldFilte }, testUtils.Request{ Request: req1, - Results: []map[string]any{ - {"name": "Islam"}, - {"name": "Shahzad"}, - {"name": "Keenan"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Islam"}, + {"name": "Shahzad"}, + {"name": "Keenan"}, + }, }, }, testUtils.Request{ @@ -66,8 +68,10 @@ func TestQueryWithIndexOnOneToManyRelation_IfFilterOnIndexedRelation_ShouldFilte }, testUtils.Request{ Request: req2, - Results: []map[string]any{ - {"name": "Addo"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Addo"}, + }, }, }, testUtils.Request{ @@ -118,10 +122,12 @@ func TestQueryWithIndexOnOneToManyRelation_IfFilterOnIndexedRelation_ShouldFilte }, testUtils.Request{ Request: req1, - Results: []map[string]any{ - {"name": "Islam"}, - {"name": "Shahzad"}, - {"name": "Keenan"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Islam"}, + {"name": "Shahzad"}, + {"name": "Keenan"}, + }, }, }, testUtils.Request{ @@ -130,8 +136,10 @@ func TestQueryWithIndexOnOneToManyRelation_IfFilterOnIndexedRelation_ShouldFilte }, testUtils.Request{ Request: req2, - Results: []map[string]any{ - {"name": "Addo"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Addo"}, + }, }, }, testUtils.Request{ @@ -182,8 +190,10 @@ func TestQueryWithIndexOnOneToOnesSecondaryRelation_IfFilterOnIndexedRelation_Sh }, testUtils.Request{ Request: req1, - Results: []map[string]any{ - {"name": "Islam"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Islam"}, + }, }, }, testUtils.Request{ @@ -192,10 +202,12 @@ func TestQueryWithIndexOnOneToOnesSecondaryRelation_IfFilterOnIndexedRelation_Sh }, testUtils.Request{ Request: req2, - Results: []map[string]any{ - {"name": "Shahzad"}, - {"name": "John"}, - {"name": "Fred"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Shahzad"}, + {"name": "John"}, + {"name": "Fred"}, + }, }, }, testUtils.Request{ @@ -247,8 +259,10 @@ func TestQueryWithIndexOnOneToOnePrimaryRelation_IfFilterOnIndexedFieldOfRelatio }, testUtils.Request{ Request: req1, - Results: []map[string]any{ - {"name": "Andy"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Andy"}, + }, }, }, testUtils.Request{ @@ -260,10 +274,12 @@ func TestQueryWithIndexOnOneToOnePrimaryRelation_IfFilterOnIndexedFieldOfRelatio }, testUtils.Request{ Request: req2, - Results: []map[string]any{ - {"name": "Shahzad"}, - {"name": "John"}, - {"name": "Fred"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Shahzad"}, + {"name": "John"}, + {"name": "Fred"}, + }, }, }, testUtils.Request{ @@ -318,8 +334,10 @@ func TestQueryWithIndexOnOneToOnePrimaryRelation_IfFilterOnIndexedFieldOfRelatio }, testUtils.Request{ Request: req1, - Results: []map[string]any{ - {"name": "Andy"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Andy"}, + }, }, }, testUtils.Request{ @@ -331,10 +349,12 @@ func TestQueryWithIndexOnOneToOnePrimaryRelation_IfFilterOnIndexedFieldOfRelatio }, testUtils.Request{ Request: req2, - Results: []map[string]any{ - {"name": "Shahzad"}, - {"name": "John"}, - {"name": "Fred"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Shahzad"}, + {"name": "John"}, + {"name": "Fred"}, + }, }, }, testUtils.Request{ @@ -381,8 +401,10 @@ func TestQueryWithIndexOnOneToOnePrimaryRelation_IfFilterOnIndexedRelationWhileI }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Andy"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Andy"}, + }, }, }, testUtils.Request{ @@ -461,22 +483,24 @@ func TestQueryWithIndexOnOneToMany_IfFilterOnIndexedRelation_ShouldFilter(t *tes } } }`, - Results: []map[string]any{ - { - "name": "Chris", - "devices": []map[string]any{ - { - "model": "Walkman", - "manufacturer": "The Proclaimers", - }, - { - "model": "Walkman", - "manufacturer": "Sony", - }, - // The filter is on User, so all devices belonging to it will be returned - { - "model": "Running Man", - "manufacturer": "Braveworld Productions", + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Chris", + "devices": []map[string]any{ + { + "model": "Walkman", + "manufacturer": "The Proclaimers", + }, + { + "model": "Walkman", + "manufacturer": "Sony", + }, + // The filter is on User, so all devices belonging to it will be returned + { + "model": "Running Man", + "manufacturer": "Braveworld Productions", + }, }, }, }, @@ -549,21 +573,23 @@ func TestQueryWithIndexOnOneToMany_IfFilterOnIndexedRelation_ShouldFilterWithExp }, testUtils.Request{ Request: req, - Results: []map[string]any{ - { - "name": "Chris", - "devices": []map[string]any{ - { - "model": "Walkman", - "manufacturer": "The Proclaimers", - }, - { - "model": "Walkman", - "manufacturer": "Sony", - }, - { - "model": "Running Man", - "manufacturer": "Braveworld Productions", + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Chris", + "devices": []map[string]any{ + { + "model": "Walkman", + "manufacturer": "The Proclaimers", + }, + { + "model": "Walkman", + "manufacturer": "Sony", + }, + { + "model": "Running Man", + "manufacturer": "Braveworld Productions", + }, }, }, }, @@ -612,11 +638,13 @@ func TestQueryWithIndexOnOneToOne_IfFilterOnIndexedRelation_ShouldFilter(t *test }, testUtils.Request{ Request: req, - Results: []map[string]any{ - { - "name": "Islam", - "address": map[string]any{ - "city": "Munich", + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Islam", + "address": map[string]any{ + "city": "Munich", + }, }, }, }, @@ -666,23 +694,25 @@ func TestQueryWithIndexOnManyToOne_IfFilterOnIndexedField_ShouldFilterWithExplai }, testUtils.Request{ Request: req, - Results: []map[string]any{ - { - "model": "Playstation 5", - "owner": map[string]any{ - "name": "Addo", + Results: map[string]any{ + "Device": []map[string]any{ + { + "model": "Playstation 5", + "owner": map[string]any{ + "name": "Addo", + }, }, - }, - { - "model": "iPhone 10", - "owner": map[string]any{ - "name": "Addo", + { + "model": "iPhone 10", + "owner": map[string]any{ + "name": "Addo", + }, }, - }, - { - "model": "Playstation 5", - "owner": map[string]any{ - "name": "Islam", + { + "model": "Playstation 5", + "owner": map[string]any{ + "name": "Islam", + }, }, }, }, @@ -731,10 +761,12 @@ func TestQueryWithIndexOnManyToOne_IfFilterOnIndexedRelation_ShouldFilterWithExp }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"model": "MacBook Pro"}, - {"model": "iPad Mini"}, - {"model": "iPhone 13"}, + Results: map[string]any{ + "Device": []map[string]any{ + {"model": "MacBook Pro"}, + {"model": "iPad Mini"}, + {"model": "iPhone 13"}, + }, }, }, testUtils.Request{ @@ -813,9 +845,11 @@ func TestQueryWithIndexOnOneToMany_IfIndexedRelationIsNil_NeNilFilterShouldUseIn }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"model": "Walkman"}, - {"model": "iPhone"}, + Results: map[string]any{ + "Device": []map[string]any{ + {"model": "Walkman"}, + {"model": "iPhone"}, + }, }, }, testUtils.Request{ @@ -894,9 +928,11 @@ func TestQueryWithIndexOnOneToMany_IfIndexedRelationIsNil_EqNilFilterShouldUseIn }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"model": "PlayStation 5"}, - {"model": "Running Man"}, + Results: map[string]any{ + "Device": []map[string]any{ + {"model": "PlayStation 5"}, + {"model": "Running Man"}, + }, }, }, testUtils.Request{ @@ -963,12 +999,14 @@ func TestQueryWithIndexOnManyToOne_MultipleViaOneToMany(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "devices": []map[string]any{ - { - "owner_id": testUtils.NewDocIndex(0, 0), - "manufacturer_id": testUtils.NewDocIndex(2, 0), + Results: map[string]any{ + "User": []map[string]any{ + { + "devices": []map[string]any{ + { + "owner_id": testUtils.NewDocIndex(0, 0), + "manufacturer_id": testUtils.NewDocIndex(2, 0), + }, }, }, }, diff --git a/tests/integration/index/query_with_unique_composite_index_filter_test.go b/tests/integration/index/query_with_unique_composite_index_filter_test.go index 26f35a0165..0df9b349ca 100644 --- a/tests/integration/index/query_with_unique_composite_index_filter_test.go +++ b/tests/integration/index/query_with_unique_composite_index_filter_test.go @@ -67,10 +67,12 @@ func TestQueryWithUniqueCompositeIndex_WithEqualFilter_ShouldFetch(t *testing.T) }, testUtils.Request{ Request: req1, - Results: []map[string]any{ - {"name": "Islam", "age": 32}, - {"name": "Islam", "age": 40}, - {"name": "Islam", "age": 50}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Islam", "age": 32}, + {"name": "Islam", "age": 40}, + {"name": "Islam", "age": 50}, + }, }, }, testUtils.Request{ @@ -79,8 +81,10 @@ func TestQueryWithUniqueCompositeIndex_WithEqualFilter_ShouldFetch(t *testing.T) }, testUtils.Request{ Request: req2, - Results: []map[string]any{ - {"name": "Islam", "age": 32}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Islam", "age": 32}, + }, }, }, testUtils.Request{ @@ -89,7 +93,9 @@ func TestQueryWithUniqueCompositeIndex_WithEqualFilter_ShouldFetch(t *testing.T) }, testUtils.Request{ Request: req3, - Results: []map[string]any{}, + Results: map[string]any{ + "User": []map[string]any{}, + }, }, }, } @@ -119,8 +125,10 @@ func TestQueryWithUniqueCompositeIndex_WithGreaterThanFilterOnFirstField_ShouldF }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Chris"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Chris"}, + }, }, }, testUtils.Request{ @@ -155,8 +163,10 @@ func TestQueryWithUniqueCompositeIndex_WithGreaterThanFilterOnSecondField_Should }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Chris"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Chris"}, + }, }, }, testUtils.Request{ @@ -191,9 +201,11 @@ func TestQueryWithUniqueCompositeIndex_WithGreaterOrEqualFilterOnFirstField_Shou }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Roy"}, - {"name": "Chris"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Roy"}, + {"name": "Chris"}, + }, }, }, testUtils.Request{ @@ -228,9 +240,11 @@ func TestQueryWithUniqueCompositeIndex_WithGreaterOrEqualFilterOnSecondField_Sho }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Chris"}, - {"name": "Roy"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Chris"}, + {"name": "Roy"}, + }, }, }, testUtils.Request{ @@ -265,8 +279,10 @@ func TestQueryWithUniqueCompositeIndex_WithLessThanFilterOnFirstField_ShouldFetc }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Bruno"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Bruno"}, + }, }, }, testUtils.Request{ @@ -301,8 +317,10 @@ func TestQueryWithUniqueCompositeIndex_WithLessThanFilterOnSecondField_ShouldFet }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Bruno"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Bruno"}, + }, }, }, testUtils.Request{ @@ -337,9 +355,11 @@ func TestQueryWithUniqueCompositeIndex_WithLessOrEqualFilterOnFirstField_ShouldF }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Shahzad"}, - {"name": "Fred"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Shahzad"}, + {"name": "Fred"}, + }, }, }, testUtils.Request{ @@ -374,9 +394,11 @@ func TestQueryWithUniqueCompositeIndex_WithLessOrEqualFilterOnSecondField_Should }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Fred"}, - {"name": "Shahzad"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Fred"}, + {"name": "Shahzad"}, + }, }, }, testUtils.Request{ @@ -411,15 +433,17 @@ func TestQueryWithUniqueCompositeIndex_WithNotEqualFilter_ShouldFetch(t *testing }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Addo"}, - {"name": "Andy"}, - {"name": "Bruno"}, - {"name": "Chris"}, - {"name": "John"}, - {"name": "Keenan"}, - {"name": "Roy"}, - {"name": "Shahzad"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Addo"}, + {"name": "Andy"}, + {"name": "Bruno"}, + {"name": "Chris"}, + {"name": "John"}, + {"name": "Keenan"}, + {"name": "Roy"}, + {"name": "Shahzad"}, + }, }, }, testUtils.Request{ @@ -492,9 +516,11 @@ func TestQueryWithUniqueCompositeIndex_WithInForFirstAndEqForRest_ShouldFetchEff }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Addo", "age": 33}, - {"name": "Andy", "age": 33}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Addo", "age": 33}, + {"name": "Andy", "age": 33}, + }, }, }, testUtils.Request{ @@ -545,9 +571,11 @@ func TestQueryWithUniqueCompositeIndex_WithInFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Andy"}, - {"name": "Fred"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Andy"}, + {"name": "Fred"}, + }, }, }, testUtils.Request{ @@ -582,10 +610,12 @@ func TestQueryWithUniqueCompositeIndex_WithNotInFilter_ShouldFetch(t *testing.T) }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Islam"}, - {"name": "Keenan"}, - {"name": "Roy"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Islam"}, + {"name": "Keenan"}, + {"name": "Roy"}, + }, }, }, testUtils.Request{ @@ -649,8 +679,10 @@ func TestQueryWithUniqueCompositeIndex_WithLikeFilter_ShouldFetch(t *testing.T) }, testUtils.Request{ Request: req1, - Results: []map[string]any{ - {"name": "Addo"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Addo"}, + }, }, }, testUtils.Request{ @@ -659,8 +691,10 @@ func TestQueryWithUniqueCompositeIndex_WithLikeFilter_ShouldFetch(t *testing.T) }, testUtils.Request{ Request: req2, - Results: []map[string]any{ - {"name": "Fred"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Fred"}, + }, }, }, testUtils.Request{ @@ -669,8 +703,10 @@ func TestQueryWithUniqueCompositeIndex_WithLikeFilter_ShouldFetch(t *testing.T) }, testUtils.Request{ Request: req3, - Results: []map[string]any{ - {"name": "Keenan"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Keenan"}, + }, }, }, testUtils.Request{ @@ -679,8 +715,10 @@ func TestQueryWithUniqueCompositeIndex_WithLikeFilter_ShouldFetch(t *testing.T) }, testUtils.Request{ Request: req4, - Results: []map[string]any{ - {"name": "Fred"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Fred"}, + }, }, }, testUtils.Request{ @@ -689,8 +727,10 @@ func TestQueryWithUniqueCompositeIndex_WithLikeFilter_ShouldFetch(t *testing.T) }, testUtils.Request{ Request: req5, - Results: []map[string]any{ - {"name": "Addo"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Addo"}, + }, }, }, testUtils.Request{ @@ -699,11 +739,15 @@ func TestQueryWithUniqueCompositeIndex_WithLikeFilter_ShouldFetch(t *testing.T) }, testUtils.Request{ Request: req6, - Results: []map[string]any{}, + Results: map[string]any{ + "User": []map[string]any{}, + }, }, testUtils.Request{ Request: req7, - Results: []map[string]any{}, + Results: map[string]any{ + "User": []map[string]any{}, + }, }, }, } @@ -732,11 +776,13 @@ func TestQueryWithUniqueCompositeIndex_WithNotLikeFilter_ShouldFetch(t *testing. }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Bruno"}, - {"name": "Islam"}, - {"name": "Keenan"}, - {"name": "Roy"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Bruno"}, + {"name": "Islam"}, + {"name": "Keenan"}, + {"name": "Roy"}, + }, }, }, testUtils.Request{ @@ -770,12 +816,14 @@ func TestQueryWithUniqueCompositeIndex_WithNotCaseInsensitiveLikeFilter_ShouldFe }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Bruno"}, - {"name": "Chris"}, - {"name": "Islam"}, - {"name": "Keenan"}, - {"name": "Roy"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Bruno"}, + {"name": "Chris"}, + {"name": "Islam"}, + {"name": "Keenan"}, + {"name": "Roy"}, + }, }, }, testUtils.Request{ @@ -852,8 +900,10 @@ func TestQueryWithUniqueCompositeIndex_WithEqualFilterOnNilValueOnFirst_ShouldFe age } }`, - Results: []map[string]any{ - {"name": nil, "age": 32}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": nil, "age": 32}, + }, }, }, }, @@ -908,9 +958,11 @@ func TestQueryWithUniqueCompositeIndex_WithMultipleNilOnFirstFieldAndNilFilter_S }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": nil, "age": 32, "email": "bob@gmail.com"}, - {"name": nil, "age": 32, "email": "cate@gmail.com"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": nil, "age": 32, "email": "bob@gmail.com"}, + {"name": nil, "age": 32, "email": "cate@gmail.com"}, + }, }, }, testUtils.Request{ @@ -968,10 +1020,12 @@ func TestQueryWithUniqueCompositeIndex_WithEqualFilterOnNilValueOnSecond_ShouldF about } }`, - Results: []map[string]any{ - { - "age": nil, - "about": "alice_nil", + Results: map[string]any{ + "User": []map[string]any{ + { + "age": nil, + "about": "alice_nil", + }, }, }, }, @@ -1036,9 +1090,11 @@ func TestQueryWithUniqueCompositeIndex_WithMultipleNilOnSecondFieldsAndNilFilter }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Bob", "age": nil, "email": "bob1@gmail.com"}, - {"name": "Bob", "age": nil, "email": "bob2@gmail.com"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Bob", "age": nil, "email": "bob1@gmail.com"}, + {"name": "Bob", "age": nil, "email": "bob2@gmail.com"}, + }, }, }, testUtils.Request{ @@ -1109,9 +1165,11 @@ func TestQueryWithUniqueCompositeIndex_WithMultipleNilOnBothFieldsAndNilFilter_S about } }`, - Results: []map[string]any{ - {"about": "nil_nil_2"}, - {"about": "nil_nil_1"}, + Results: map[string]any{ + "User": []map[string]any{ + {"about": "nil_nil_2"}, + {"about": "nil_nil_1"}, + }, }, }, testUtils.Request{ @@ -1121,10 +1179,12 @@ func TestQueryWithUniqueCompositeIndex_WithMultipleNilOnBothFieldsAndNilFilter_S about } }`, - Results: []map[string]any{ - {"about": "nil_nil_2"}, - {"about": "nil_nil_1"}, - {"about": "nil_22"}, + Results: map[string]any{ + "User": []map[string]any{ + {"about": "nil_nil_2"}, + {"about": "nil_nil_1"}, + {"about": "nil_22"}, + }, }, }, testUtils.Request{ @@ -1134,10 +1194,12 @@ func TestQueryWithUniqueCompositeIndex_WithMultipleNilOnBothFieldsAndNilFilter_S about } }`, - Results: []map[string]any{ - {"about": "bob_nil"}, - {"about": "nil_nil_2"}, - {"about": "nil_nil_1"}, + Results: map[string]any{ + "User": []map[string]any{ + {"about": "bob_nil"}, + {"about": "nil_nil_2"}, + {"about": "nil_nil_1"}, + }, }, }, }, @@ -1245,8 +1307,10 @@ func TestQueryWithUniqueCompositeIndex_AfterUpdateOnNilFields_ShouldFetch(t *tes about } }`, - Results: []map[string]any{ - {"about": "bob_nil -> nil_nil"}, + Results: map[string]any{ + "User": []map[string]any{ + {"about": "bob_nil -> nil_nil"}, + }, }, }, testUtils.Request{ @@ -1256,9 +1320,11 @@ func TestQueryWithUniqueCompositeIndex_AfterUpdateOnNilFields_ShouldFetch(t *tes about } }`, - Results: []map[string]any{ - {"about": "bob_nil -> nil_nil"}, - {"about": "nil_nil -> nil_22"}, + Results: map[string]any{ + "User": []map[string]any{ + {"about": "bob_nil -> nil_nil"}, + {"about": "nil_nil -> nil_22"}, + }, }, }, testUtils.Request{ @@ -1268,11 +1334,13 @@ func TestQueryWithUniqueCompositeIndex_AfterUpdateOnNilFields_ShouldFetch(t *tes about } }`, - Results: []map[string]any{ - {"about": "bob_22 -> bob_nil"}, - {"about": "nil_22 -> bob_nil"}, - {"about": "bob_nil -> nil_nil"}, - {"about": "nil_nil -> bob_nil"}, + Results: map[string]any{ + "User": []map[string]any{ + {"about": "bob_22 -> bob_nil"}, + {"about": "nil_22 -> bob_nil"}, + {"about": "bob_nil -> nil_nil"}, + {"about": "nil_nil -> bob_nil"}, + }, }, }, }, @@ -1327,9 +1395,11 @@ func TestQueryWithUniqueCompositeIndex_IfMiddleFieldIsNotInFilter_ShouldIgnoreVa name } }`, - Results: []map[string]any{ - { - "name": "Alan", + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Alan", + }, }, }, }, diff --git a/tests/integration/index/query_with_unique_index_only_filter_test.go b/tests/integration/index/query_with_unique_index_only_filter_test.go index f21de4630c..50bb86712d 100644 --- a/tests/integration/index/query_with_unique_index_only_filter_test.go +++ b/tests/integration/index/query_with_unique_index_only_filter_test.go @@ -36,8 +36,10 @@ func TestQueryWithUniqueIndex_WithEqualFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Islam"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Islam"}, + }, }, }, testUtils.Request{ @@ -71,8 +73,10 @@ func TestQueryWithUniqueIndex_WithGreaterThanFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Chris"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Chris"}, + }, }, }, testUtils.Request{ @@ -106,9 +110,11 @@ func TestQueryWithUniqueIndex_WithGreaterOrEqualFilter_ShouldFetch(t *testing.T) }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Keenan"}, - {"name": "Chris"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Keenan"}, + {"name": "Chris"}, + }, }, }, testUtils.Request{ @@ -142,8 +148,10 @@ func TestQueryWithUniqueIndex_WithLessThanFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Shahzad"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Shahzad"}, + }, }, }, testUtils.Request{ @@ -177,9 +185,11 @@ func TestQueryWithUniqueIndex_WithLessOrEqualFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Shahzad"}, - {"name": "Bruno"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Shahzad"}, + {"name": "Bruno"}, + }, }, }, testUtils.Request{ @@ -213,16 +223,18 @@ func TestQueryWithUniqueIndex_WithNotEqualFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Addo"}, - {"name": "Andy"}, - {"name": "Bruno"}, - {"name": "Chris"}, - {"name": "Fred"}, - {"name": "John"}, - {"name": "Keenan"}, - {"name": "Roy"}, - {"name": "Shahzad"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Addo"}, + {"name": "Andy"}, + {"name": "Bruno"}, + {"name": "Chris"}, + {"name": "Fred"}, + {"name": "John"}, + {"name": "Keenan"}, + {"name": "Roy"}, + {"name": "Shahzad"}, + }, }, }, testUtils.Request{ @@ -256,9 +268,11 @@ func TestQueryWithUniqueIndex_WithInFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Shahzad"}, - {"name": "Andy"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Shahzad"}, + {"name": "Andy"}, + }, }, }, testUtils.Request{ @@ -292,11 +306,13 @@ func TestQueryWithUniqueIndex_WithNotInFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "John"}, - {"name": "Islam"}, - {"name": "Roy"}, - {"name": "Keenan"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "John"}, + {"name": "Islam"}, + {"name": "Roy"}, + {"name": "Keenan"}, + }, }, }, testUtils.Request{ @@ -355,9 +371,11 @@ func TestQueryWithUniqueIndex_WithLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req1, - Results: []map[string]any{ - {"name": "Addo"}, - {"name": "Andy"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Addo"}, + {"name": "Andy"}, + }, }, }, testUtils.Request{ @@ -366,9 +384,11 @@ func TestQueryWithUniqueIndex_WithLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req2, - Results: []map[string]any{ - {"name": "Fred"}, - {"name": "Shahzad"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Fred"}, + {"name": "Shahzad"}, + }, }, }, testUtils.Request{ @@ -377,9 +397,11 @@ func TestQueryWithUniqueIndex_WithLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req3, - Results: []map[string]any{ - {"name": "Fred"}, - {"name": "Keenan"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Fred"}, + {"name": "Keenan"}, + }, }, }, testUtils.Request{ @@ -388,8 +410,10 @@ func TestQueryWithUniqueIndex_WithLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req4, - Results: []map[string]any{ - {"name": "Fred"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Fred"}, + }, }, }, testUtils.Request{ @@ -398,9 +422,11 @@ func TestQueryWithUniqueIndex_WithLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req5, - Results: []map[string]any{ - {"name": "Addo"}, - {"name": "Andy"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Addo"}, + {"name": "Andy"}, + }, }, }, testUtils.Request{ @@ -409,7 +435,9 @@ func TestQueryWithUniqueIndex_WithLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req6, - Results: []map[string]any{}, + Results: map[string]any{ + "User": []map[string]any{}, + }, }, testUtils.Request{ Request: makeExplainQuery(req6), @@ -442,14 +470,16 @@ func TestQueryWithUniqueIndex_WithNotLikeFilter_ShouldFetch(t *testing.T) { }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Addo"}, - {"name": "Andy"}, - {"name": "Bruno"}, - {"name": "Fred"}, - {"name": "Islam"}, - {"name": "Keenan"}, - {"name": "Roy"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Addo"}, + {"name": "Andy"}, + {"name": "Bruno"}, + {"name": "Fred"}, + {"name": "Islam"}, + {"name": "Keenan"}, + {"name": "Roy"}, + }, }, }, testUtils.Request{ @@ -483,15 +513,17 @@ func TestQueryWithUniqueIndex_WithNotCaseInsensitiveLikeFilter_ShouldFetch(t *te }, testUtils.Request{ Request: req, - Results: []map[string]any{ - {"name": "Bruno"}, - {"name": "Chris"}, - {"name": "Fred"}, - {"name": "Islam"}, - {"name": "John"}, - {"name": "Keenan"}, - {"name": "Roy"}, - {"name": "Shahzad"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Bruno"}, + {"name": "Chris"}, + {"name": "Fred"}, + {"name": "Islam"}, + {"name": "John"}, + {"name": "Keenan"}, + {"name": "Roy"}, + {"name": "Shahzad"}, + }, }, }, testUtils.Request{ @@ -529,7 +561,9 @@ func TestQueryWithUniqueIndex_IfNoMatch_ReturnEmptyResult(t *testing.T) { name } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "User": []map[string]any{}, + }, }, }, } @@ -573,8 +607,10 @@ func TestQueryWithUniqueIndex_WithEqualFilterOnNilValue_ShouldFetch(t *testing.T name } }`, - Results: []map[string]any{ - {"name": "Alice"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Alice"}, + }, }, }, }, @@ -624,8 +660,10 @@ func TestQueryWithUniqueIndex_WithEqualFilterOnZero_ShouldNotFetchNil(t *testing name } }`, - Results: []map[string]any{ - {"name": "Bob"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Bob"}, + }, }, }, }, @@ -675,9 +713,11 @@ func TestQueryWithUniqueIndex_WithNotEqualFilterOnNilValue_ShouldFetch(t *testin name } }`, - Results: []map[string]any{ - {"name": "Kate"}, - {"name": "Bob"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Kate"}, + {"name": "Bob"}, + }, }, }, }, @@ -726,9 +766,11 @@ func TestQueryWithUniqueIndex_WithMultipleNilValuesAndEqualFilter_ShouldFetch(t name } }`, - Results: []map[string]any{ - {"name": "Alice"}, - {"name": "Bob"}, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Alice"}, + {"name": "Bob"}, + }, }, }, }, diff --git a/tests/integration/issues/2566_test.go b/tests/integration/issues/2566_test.go index 696425a3b1..eecf0d20b4 100644 --- a/tests/integration/issues/2566_test.go +++ b/tests/integration/issues/2566_test.go @@ -83,11 +83,13 @@ func TestP2PUpdate_WithPNCounterSimultaneousOverflowIncrement_DoesNotReachConsit Age } }`, - Results: []map[string]any{ - { - // Node 0 overflows before subtraction, and because subtracting from infinity - // results in infinity the value remains infinate - "Age": math.Inf(1), + Results: map[string]any{ + "Users": []map[string]any{ + { + // Node 0 overflows before subtraction, and because subtracting from infinity + // results in infinity the value remains infinate + "Age": math.Inf(1), + }, }, }, }, @@ -98,11 +100,13 @@ func TestP2PUpdate_WithPNCounterSimultaneousOverflowIncrement_DoesNotReachConsit Age } }`, - Results: []map[string]any{ - { - // Node 1 subtracts before adding, meaning no overflow is achieved and the value - // remains finate - "Age": float64(1.7976931348623155e+307), + Results: map[string]any{ + "Users": []map[string]any{ + { + // Node 1 subtracts before adding, meaning no overflow is achieved and the value + // remains finate + "Age": float64(1.7976931348623155e+307), + }, }, }, }, @@ -175,11 +179,13 @@ func TestP2PUpdate_WithPNCounterSimultaneousOverflowDecrement_DoesNotReachConsit Age } }`, - Results: []map[string]any{ - { - // Node 0 overflows before addition, and because adding to infinity - // results in infinity the value remains infinate - "Age": math.Inf(-1), + Results: map[string]any{ + "Users": []map[string]any{ + { + // Node 0 overflows before addition, and because adding to infinity + // results in infinity the value remains infinate + "Age": math.Inf(-1), + }, }, }, }, @@ -190,11 +196,13 @@ func TestP2PUpdate_WithPNCounterSimultaneousOverflowDecrement_DoesNotReachConsit Age } }`, - Results: []map[string]any{ - { - // Node 1 adds before subtracting, meaning no overflow is achieved and the value - // remains finate - "Age": float64(-1.7976931348623155e+307), + Results: map[string]any{ + "Users": []map[string]any{ + { + // Node 1 adds before subtracting, meaning no overflow is achieved and the value + // remains finate + "Age": float64(-1.7976931348623155e+307), + }, }, }, }, diff --git a/tests/integration/mutation/create/crdt/pcounter_test.go b/tests/integration/mutation/create/crdt/pcounter_test.go index e54dba4ea6..724b157006 100644 --- a/tests/integration/mutation/create/crdt/pcounter_test.go +++ b/tests/integration/mutation/create/crdt/pcounter_test.go @@ -42,11 +42,13 @@ func TestPCounterCreate_IntKindWithPositiveValue_NoError(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "_docID": "bae-d8cb53d4-ac5a-5c55-8306-64df633d400d", - "name": "John", - "points": int64(10), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-d8cb53d4-ac5a-5c55-8306-64df633d400d", + "name": "John", + "points": int64(10), + }, }, }, }, diff --git a/tests/integration/mutation/create/crdt/pncounter_test.go b/tests/integration/mutation/create/crdt/pncounter_test.go index b8808ff40a..c16a0c5bb6 100644 --- a/tests/integration/mutation/create/crdt/pncounter_test.go +++ b/tests/integration/mutation/create/crdt/pncounter_test.go @@ -42,11 +42,13 @@ func TestPNCounterCreate_IntKindWithPositiveValue_NoError(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "_docID": "bae-bc5464e4-26a6-5307-b516-aada0abeb089", - "name": "John", - "points": int64(10), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-bc5464e4-26a6-5307-b516-aada0abeb089", + "name": "John", + "points": int64(10), + }, }, }, }, diff --git a/tests/integration/mutation/create/field_kinds/field_kind_json_test.go b/tests/integration/mutation/create/field_kinds/field_kind_json_test.go index 8833a74b31..cc97bd162f 100644 --- a/tests/integration/mutation/create/field_kinds/field_kind_json_test.go +++ b/tests/integration/mutation/create/field_kinds/field_kind_json_test.go @@ -36,11 +36,13 @@ func TestMutationCreate_WithJSONFieldGivenValidJSON_NoError(t *testing.T) { custom } }`, - Results: []map[string]any{ - { - "_docID": "bae-84ae4ef8-ca0c-5f32-bc85-cee97e731bc0", - "custom": "{\"tree\":\"maple\",\"age\":250}", - "name": "John", + Results: map[string]any{ + "create_Users": []map[string]any{ + { + "_docID": "bae-84ae4ef8-ca0c-5f32-bc85-cee97e731bc0", + "custom": "{\"tree\":\"maple\",\"age\":250}", + "name": "John", + }, }, }, }, diff --git a/tests/integration/mutation/create/field_kinds/one_to_many/with_alias_test.go b/tests/integration/mutation/create/field_kinds/one_to_many/with_alias_test.go index 3bddea1a4a..6fedc0c8c2 100644 --- a/tests/integration/mutation/create/field_kinds/one_to_many/with_alias_test.go +++ b/tests/integration/mutation/create/field_kinds/one_to_many/with_alias_test.go @@ -82,9 +82,11 @@ func TestMutationCreateOneToMany_AliasedRelationNameNonExistingRelationManySide_ name } }`, - Results: []map[string]any{ - { - "name": "Painted House", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + }, }, }, }, @@ -109,9 +111,11 @@ func TestMutationCreateOneToMany_AliasedRelationNameInvalidIDManySide_CreatedDoc name } }`, - Results: []map[string]any{ - { - "name": "Painted House", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + }, }, }, }, @@ -146,12 +150,14 @@ func TestMutationCreateOneToMany_AliasedRelationNameToLinkFromManySide(t *testin } } }`, - Results: []map[string]any{ - { - "name": "John Grisham", - "published": []map[string]any{ - { - "name": "Painted House", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "published": []map[string]any{ + { + "name": "Painted House", + }, }, }, }, @@ -166,11 +172,13 @@ func TestMutationCreateOneToMany_AliasedRelationNameToLinkFromManySide(t *testin } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "author": map[string]any{ - "name": "John Grisham", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, @@ -207,9 +215,11 @@ func TestMutationUpdateOneToMany_AliasRelationNameAndInternalIDBothProduceSameDo _docID } }`, - Results: []map[string]any{ - { - "_docID": bookID, // Must be same as below. + Results: map[string]any{ + "Book": []map[string]any{ + { + "_docID": bookID, // Must be same as below. + }, }, }, }, @@ -242,9 +252,11 @@ func TestMutationUpdateOneToMany_AliasRelationNameAndInternalIDBothProduceSameDo _docID } }`, - Results: []map[string]any{ - { - "_docID": bookID, // Must be same as below. + Results: map[string]any{ + "Book": []map[string]any{ + { + "_docID": bookID, // Must be same as below. + }, }, }, }, diff --git a/tests/integration/mutation/create/field_kinds/one_to_many/with_simple_test.go b/tests/integration/mutation/create/field_kinds/one_to_many/with_simple_test.go index 56efed2216..36884aa645 100644 --- a/tests/integration/mutation/create/field_kinds/one_to_many/with_simple_test.go +++ b/tests/integration/mutation/create/field_kinds/one_to_many/with_simple_test.go @@ -82,9 +82,11 @@ func TestMutationCreateOneToMany_NonExistingRelationManySide_CreatedDoc(t *testi name } }`, - Results: []map[string]any{ - { - "name": "Painted House", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + }, }, }, }, @@ -119,12 +121,14 @@ func TestMutationCreateOneToMany_RelationIDToLinkFromManySide(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "John Grisham", - "published": []map[string]any{ - { - "name": "Painted House", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "published": []map[string]any{ + { + "name": "Painted House", + }, }, }, }, @@ -139,11 +143,13 @@ func TestMutationCreateOneToMany_RelationIDToLinkFromManySide(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "author": map[string]any{ - "name": "John Grisham", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, diff --git a/tests/integration/mutation/create/field_kinds/one_to_one/with_alias_test.go b/tests/integration/mutation/create/field_kinds/one_to_one/with_alias_test.go index ef263bd47e..8c7dddb1c2 100644 --- a/tests/integration/mutation/create/field_kinds/one_to_one/with_alias_test.go +++ b/tests/integration/mutation/create/field_kinds/one_to_one/with_alias_test.go @@ -60,9 +60,11 @@ func TestMutationCreateOneToOne_UseAliasWithNonExistingRelationPrimarySide_Creat name } }`, - Results: []map[string]any{ - { - "name": "John Grisham", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + }, }, }, }, @@ -114,11 +116,13 @@ func TestMutationCreateOneToOne_UseAliasedRelationNameToLink_QueryFromPrimarySid } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "author": map[string]any{ - "name": "John Grisham", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, @@ -132,11 +136,13 @@ func TestMutationCreateOneToOne_UseAliasedRelationNameToLink_QueryFromPrimarySid } } }`, - Results: []map[string]any{ - { - "name": "John Grisham", - "published": map[string]any{ - "name": "Painted House", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "published": map[string]any{ + "name": "Painted House", + }, }, }, }, @@ -173,11 +179,13 @@ func TestMutationCreateOneToOne_UseAliasedRelationNameToLink_QueryFromSecondaryS } } }`, - Results: []map[string]any{ - { - "name": "John Grisham", - "published": map[string]any{ - "name": "Painted House", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "published": map[string]any{ + "name": "Painted House", + }, }, }, }, @@ -191,11 +199,13 @@ func TestMutationCreateOneToOne_UseAliasedRelationNameToLink_QueryFromSecondaryS } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "author": map[string]any{ - "name": "John Grisham", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, diff --git a/tests/integration/mutation/create/field_kinds/one_to_one/with_simple_test.go b/tests/integration/mutation/create/field_kinds/one_to_one/with_simple_test.go index fa890f8e70..fabced3505 100644 --- a/tests/integration/mutation/create/field_kinds/one_to_one/with_simple_test.go +++ b/tests/integration/mutation/create/field_kinds/one_to_one/with_simple_test.go @@ -60,9 +60,11 @@ func TestMutationCreateOneToOneNoChild(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John Grisham", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + }, }, }, }, @@ -115,11 +117,13 @@ func TestMutationCreateOneToOne(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "author": map[string]any{ - "name": "John Grisham", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, @@ -134,11 +138,13 @@ func TestMutationCreateOneToOne(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "John Grisham", - "published": map[string]any{ - "name": "Painted House", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "published": map[string]any{ + "name": "Painted House", + }, }, }, }, @@ -176,11 +182,13 @@ func TestMutationCreateOneToOneSecondarySide(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "John Grisham", - "published": map[string]any{ - "name": "Painted House", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "published": map[string]any{ + "name": "Painted House", + }, }, }, }, @@ -195,11 +203,13 @@ func TestMutationCreateOneToOneSecondarySide(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "author": map[string]any{ - "name": "John Grisham", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, diff --git a/tests/integration/mutation/create/field_kinds/one_to_one_to_one/with_txn_test.go b/tests/integration/mutation/create/field_kinds/one_to_one_to_one/with_txn_test.go index 3b40c19f6c..f626483375 100644 --- a/tests/integration/mutation/create/field_kinds/one_to_one_to_one/with_txn_test.go +++ b/tests/integration/mutation/create/field_kinds/one_to_one_to_one/with_txn_test.go @@ -46,9 +46,11 @@ func TestTransactionalCreationAndLinkingOfRelationalDocumentsForward(t *testing. _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", + Results: map[string]any{ + "create_Book": []map[string]any{ + { + "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", + }, }, }, }, @@ -59,9 +61,11 @@ func TestTransactionalCreationAndLinkingOfRelationalDocumentsForward(t *testing. _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-7f6a5a76-b90d-5715-a452-708ded9e7ae7", + Results: map[string]any{ + "create_Book": []map[string]any{ + { + "_docID": "bae-7f6a5a76-b90d-5715-a452-708ded9e7ae7", + }, }, }, }, @@ -78,20 +82,22 @@ func TestTransactionalCreationAndLinkingOfRelationalDocumentsForward(t *testing. } } }`, - Results: []map[string]any{ - { - "_docID": "bae-07fd000a-d023-54b9-b8f3-a4318fac8fed", - "name": "Website", - "published": map[string]any{ - "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", - "name": "Book By Website", + Results: map[string]any{ + "Publisher": []map[string]any{ + { + "_docID": "bae-07fd000a-d023-54b9-b8f3-a4318fac8fed", + "name": "Website", + "published": map[string]any{ + "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", + "name": "Book By Website", + }, }, - }, - { - "_docID": "bae-21084f46-b12a-53ab-94dd-04d075b4218c", - "name": "Online", - "published": nil, + { + "_docID": "bae-21084f46-b12a-53ab-94dd-04d075b4218c", + "name": "Online", + "published": nil, + }, }, }, }, @@ -108,18 +114,20 @@ func TestTransactionalCreationAndLinkingOfRelationalDocumentsForward(t *testing. } } }`, - Results: []map[string]any{ - { - "_docID": "bae-07fd000a-d023-54b9-b8f3-a4318fac8fed", - "name": "Website", - "published": nil, - }, - { - "_docID": "bae-21084f46-b12a-53ab-94dd-04d075b4218c", - "name": "Online", - "published": map[string]any{ - "_docID": "bae-7f6a5a76-b90d-5715-a452-708ded9e7ae7", - "name": "Book By Online", + Results: map[string]any{ + "Publisher": []map[string]any{ + { + "_docID": "bae-07fd000a-d023-54b9-b8f3-a4318fac8fed", + "name": "Website", + "published": nil, + }, + { + "_docID": "bae-21084f46-b12a-53ab-94dd-04d075b4218c", + "name": "Online", + "published": map[string]any{ + "_docID": "bae-7f6a5a76-b90d-5715-a452-708ded9e7ae7", + "name": "Book By Online", + }, }, }, }, @@ -143,21 +151,23 @@ func TestTransactionalCreationAndLinkingOfRelationalDocumentsForward(t *testing. } } }`, - Results: []map[string]any{ - { - "_docID": "bae-7f6a5a76-b90d-5715-a452-708ded9e7ae7", - "name": "Book By Online", - "publisher": map[string]any{ - "_docID": "bae-21084f46-b12a-53ab-94dd-04d075b4218c", - "name": "Online", + Results: map[string]any{ + "Book": []map[string]any{ + { + "_docID": "bae-7f6a5a76-b90d-5715-a452-708ded9e7ae7", + "name": "Book By Online", + "publisher": map[string]any{ + "_docID": "bae-21084f46-b12a-53ab-94dd-04d075b4218c", + "name": "Online", + }, }, - }, - { - "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", - "name": "Book By Website", - "publisher": map[string]any{ - "_docID": "bae-07fd000a-d023-54b9-b8f3-a4318fac8fed", - "name": "Website", + { + "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", + "name": "Book By Website", + "publisher": map[string]any{ + "_docID": "bae-07fd000a-d023-54b9-b8f3-a4318fac8fed", + "name": "Website", + }, }, }, }, @@ -196,9 +206,11 @@ func TestTransactionalCreationAndLinkingOfRelationalDocumentsBackward(t *testing _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", + Results: map[string]any{ + "create_Book": []map[string]any{ + { + "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", + }, }, }, }, @@ -209,9 +221,11 @@ func TestTransactionalCreationAndLinkingOfRelationalDocumentsBackward(t *testing _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-7f6a5a76-b90d-5715-a452-708ded9e7ae7", + Results: map[string]any{ + "create_Book": []map[string]any{ + { + "_docID": "bae-7f6a5a76-b90d-5715-a452-708ded9e7ae7", + }, }, }, }, @@ -228,13 +242,15 @@ func TestTransactionalCreationAndLinkingOfRelationalDocumentsBackward(t *testing } } }`, - Results: []map[string]any{ - { - "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", - "name": "Book By Website", - "publisher": map[string]any{ - "_docID": "bae-07fd000a-d023-54b9-b8f3-a4318fac8fed", - "name": "Website", + Results: map[string]any{ + "Book": []map[string]any{ + { + "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", + "name": "Book By Website", + "publisher": map[string]any{ + "_docID": "bae-07fd000a-d023-54b9-b8f3-a4318fac8fed", + "name": "Website", + }, }, }, }, @@ -252,13 +268,15 @@ func TestTransactionalCreationAndLinkingOfRelationalDocumentsBackward(t *testing } } }`, - Results: []map[string]any{ - { - "_docID": "bae-7f6a5a76-b90d-5715-a452-708ded9e7ae7", - "name": "Book By Online", - "publisher": map[string]any{ - "_docID": "bae-21084f46-b12a-53ab-94dd-04d075b4218c", - "name": "Online", + Results: map[string]any{ + "Book": []map[string]any{ + { + "_docID": "bae-7f6a5a76-b90d-5715-a452-708ded9e7ae7", + "name": "Book By Online", + "publisher": map[string]any{ + "_docID": "bae-21084f46-b12a-53ab-94dd-04d075b4218c", + "name": "Online", + }, }, }, }, @@ -282,22 +300,24 @@ func TestTransactionalCreationAndLinkingOfRelationalDocumentsBackward(t *testing } } }`, - Results: []map[string]any{ - { - "_docID": "bae-07fd000a-d023-54b9-b8f3-a4318fac8fed", - "name": "Website", - "published": map[string]any{ - "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", - "name": "Book By Website", + Results: map[string]any{ + "Publisher": []map[string]any{ + { + "_docID": "bae-07fd000a-d023-54b9-b8f3-a4318fac8fed", + "name": "Website", + "published": map[string]any{ + "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", + "name": "Book By Website", + }, }, - }, - { - "_docID": "bae-21084f46-b12a-53ab-94dd-04d075b4218c", - "name": "Online", - "published": map[string]any{ - "_docID": "bae-7f6a5a76-b90d-5715-a452-708ded9e7ae7", - "name": "Book By Online", + { + "_docID": "bae-21084f46-b12a-53ab-94dd-04d075b4218c", + "name": "Online", + "published": map[string]any{ + "_docID": "bae-7f6a5a76-b90d-5715-a452-708ded9e7ae7", + "name": "Book By Online", + }, }, }, }, diff --git a/tests/integration/mutation/create/simple_create_many_test.go b/tests/integration/mutation/create/simple_create_many_test.go index 5f1e425549..94e013a61a 100644 --- a/tests/integration/mutation/create/simple_create_many_test.go +++ b/tests/integration/mutation/create/simple_create_many_test.go @@ -50,16 +50,18 @@ func TestMutationCreateMany(t *testing.T) { } } `, - Results: []map[string]any{ - { - "_docID": "bae-48339725-ed14-55b1-8e63-3fda5f590725", - "name": "Islam", - "age": int64(33), - }, - { - "_docID": "bae-8c89a573-c287-5d8c-8ba6-c47c814c594d", - "name": "John", - "age": int64(27), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-48339725-ed14-55b1-8e63-3fda5f590725", + "name": "Islam", + "age": int64(33), + }, + { + "_docID": "bae-8c89a573-c287-5d8c-8ba6-c47c814c594d", + "name": "John", + "age": int64(27), + }, }, }, }, diff --git a/tests/integration/mutation/create/simple_test.go b/tests/integration/mutation/create/simple_test.go index 61280c0cc8..f8335dbe4c 100644 --- a/tests/integration/mutation/create/simple_test.go +++ b/tests/integration/mutation/create/simple_test.go @@ -51,7 +51,9 @@ func TestMutationCreate_GivenNonExistantField_Errors(t *testing.T) { } } `, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -87,11 +89,13 @@ func TestMutationCreate(t *testing.T) { } } `, - Results: []map[string]any{ - { - "_docID": "bae-8c89a573-c287-5d8c-8ba6-c47c814c594d", - "name": "John", - "age": int64(27), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-8c89a573-c287-5d8c-8ba6-c47c814c594d", + "name": "John", + "age": int64(27), + }, }, }, }, @@ -155,9 +159,11 @@ func TestMutationCreate_GivenEmptyInput(t *testing.T) { _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-332de69b-47da-5175-863f-2480107f4884", + Results: map[string]any{ + "create_Users": []map[string]any{ + { + "_docID": "bae-332de69b-47da-5175-863f-2480107f4884", + }, }, }, }, diff --git a/tests/integration/mutation/create/with_version_test.go b/tests/integration/mutation/create/with_version_test.go index 4ade869073..b19db8ee4c 100644 --- a/tests/integration/mutation/create/with_version_test.go +++ b/tests/integration/mutation/create/with_version_test.go @@ -35,11 +35,13 @@ func TestMutationCreate_ReturnsVersionCID(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "_version": []map[string]any{ - { - "cid": "bafyreia5ph2hvwebdsxe7m2f6bwuq7ngwxzqp7esiuzjihtcz2jswma6xu", + Results: map[string]any{ + "create_Users": []map[string]any{ + { + "_version": []map[string]any{ + { + "cid": "bafyreia5ph2hvwebdsxe7m2f6bwuq7ngwxzqp7esiuzjihtcz2jswma6xu", + }, }, }, }, diff --git a/tests/integration/mutation/delete/field_kinds/one_to_many/with_show_deleted_test.go b/tests/integration/mutation/delete/field_kinds/one_to_many/with_show_deleted_test.go index 8b8e7088a6..de72ebf893 100644 --- a/tests/integration/mutation/delete/field_kinds/one_to_many/with_show_deleted_test.go +++ b/tests/integration/mutation/delete/field_kinds/one_to_many/with_show_deleted_test.go @@ -65,9 +65,11 @@ func TestDeletionOfADocumentUsingSingleDocIDWithShowDeletedDocumentQuery(t *test _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-b5c56d8f-b2f5-57f9-b371-4e9e04903e91", + Results: map[string]any{ + "delete_Book": []map[string]any{ + { + "_docID": "bae-b5c56d8f-b2f5-57f9-b371-4e9e04903e91", + }, }, }, }, @@ -84,21 +86,23 @@ func TestDeletionOfADocumentUsingSingleDocIDWithShowDeletedDocumentQuery(t *test } } }`, - Results: []map[string]any{ - { - "_deleted": false, - "name": "John", - "age": int64(30), - "published": []map[string]any{ - { - "_deleted": false, - "name": "John has a chamber of secrets", - "rating": 9.9, - }, - { - "_deleted": true, - "name": "John and the philosopher are stoned", - "rating": 9.9, + Results: map[string]any{ + "Author": []map[string]any{ + { + "_deleted": false, + "name": "John", + "age": int64(30), + "published": []map[string]any{ + { + "_deleted": false, + "name": "John has a chamber of secrets", + "rating": 9.9, + }, + { + "_deleted": true, + "name": "John and the philosopher are stoned", + "rating": 9.9, + }, }, }, }, diff --git a/tests/integration/mutation/delete/field_kinds/one_to_one_to_one/with_id_test.go b/tests/integration/mutation/delete/field_kinds/one_to_one_to_one/with_id_test.go index 057f20a00b..fefcc350af 100644 --- a/tests/integration/mutation/delete/field_kinds/one_to_one_to_one/with_id_test.go +++ b/tests/integration/mutation/delete/field_kinds/one_to_one_to_one/with_id_test.go @@ -57,9 +57,11 @@ func TestRelationalDeletionOfADocumentUsingSingleKey_Success(t *testing.T) { _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-455081f4-b810-5363-ab95-50dbd2ec03d0", + Results: map[string]any{ + "delete_Author": []map[string]any{ + { + "_docID": "bae-455081f4-b810-5363-ab95-50dbd2ec03d0", + }, }, }, }, @@ -105,9 +107,11 @@ func TestRelationalDeletionOfADocumentUsingSingleKey_Success(t *testing.T) { AliasOfKey: _docID } }`, - Results: []map[string]any{ - { - "AliasOfKey": "bae-455081f4-b810-5363-ab95-50dbd2ec03d0", + Results: map[string]any{ + "delete_Author": []map[string]any{ + { + "AliasOfKey": "bae-455081f4-b810-5363-ab95-50dbd2ec03d0", + }, }, }, }, @@ -170,9 +174,11 @@ func TestRelationalDeletionOfADocumentUsingSingleKey_Success(t *testing.T) { Key: _docID } }`, - Results: []map[string]any{ - { - "Key": "bae-455081f4-b810-5363-ab95-50dbd2ec03d0", + Results: map[string]any{ + "delete_Author": []map[string]any{ + { + "Key": "bae-455081f4-b810-5363-ab95-50dbd2ec03d0", + }, }, }, }, diff --git a/tests/integration/mutation/delete/field_kinds/one_to_one_to_one/with_txn_test.go b/tests/integration/mutation/delete/field_kinds/one_to_one_to_one/with_txn_test.go index 9298f26198..d7be187d49 100644 --- a/tests/integration/mutation/delete/field_kinds/one_to_one_to_one/with_txn_test.go +++ b/tests/integration/mutation/delete/field_kinds/one_to_one_to_one/with_txn_test.go @@ -49,9 +49,11 @@ func TestTxnDeletionOfRelatedDocFromPrimarySideForwardDirection(t *testing.T) { _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", + Results: map[string]any{ + "delete_Book": []map[string]any{ + { + "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", + }, }, }, }, @@ -70,11 +72,13 @@ func TestTxnDeletionOfRelatedDocFromPrimarySideForwardDirection(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "_docID": "bae-07fd000a-d023-54b9-b8f3-a4318fac8fed", - "name": "Website", - "published": nil, + Results: map[string]any{ + "Publisher": []map[string]any{ + { + "_docID": "bae-07fd000a-d023-54b9-b8f3-a4318fac8fed", + "name": "Website", + "published": nil, + }, }, }, }, @@ -115,9 +119,11 @@ func TestTxnDeletionOfRelatedDocFromPrimarySideBackwardDirection(t *testing.T) { _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", + Results: map[string]any{ + "delete_Book": []map[string]any{ + { + "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", + }, }, }, }, @@ -136,7 +142,9 @@ func TestTxnDeletionOfRelatedDocFromPrimarySideBackwardDirection(t *testing.T) { } } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Book": []map[string]any{}, + }, }, }, } @@ -175,9 +183,11 @@ func TestATxnCanReadARecordThatIsDeletedInANonCommitedTxnForwardDirection(t *tes _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", + Results: map[string]any{ + "delete_Book": []map[string]any{ + { + "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", + }, }, }, }, @@ -194,13 +204,15 @@ func TestATxnCanReadARecordThatIsDeletedInANonCommitedTxnForwardDirection(t *tes } } }`, - Results: []map[string]any{ - { - "_docID": "bae-07fd000a-d023-54b9-b8f3-a4318fac8fed", - "name": "Website", - "published": map[string]any{ - "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", - "name": "Book By Website", + Results: map[string]any{ + "Publisher": []map[string]any{ + { + "_docID": "bae-07fd000a-d023-54b9-b8f3-a4318fac8fed", + "name": "Website", + "published": map[string]any{ + "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", + "name": "Book By Website", + }, }, }, }, @@ -220,11 +232,13 @@ func TestATxnCanReadARecordThatIsDeletedInANonCommitedTxnForwardDirection(t *tes } } }`, - Results: []map[string]any{ - { - "_docID": "bae-07fd000a-d023-54b9-b8f3-a4318fac8fed", - "name": "Website", - "published": nil, + Results: map[string]any{ + "Publisher": []map[string]any{ + { + "_docID": "bae-07fd000a-d023-54b9-b8f3-a4318fac8fed", + "name": "Website", + "published": nil, + }, }, }, }, @@ -265,9 +279,11 @@ func TestATxnCanReadARecordThatIsDeletedInANonCommitedTxnBackwardDirection(t *te _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", + Results: map[string]any{ + "delete_Book": []map[string]any{ + { + "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", + }, }, }, }, @@ -284,13 +300,15 @@ func TestATxnCanReadARecordThatIsDeletedInANonCommitedTxnBackwardDirection(t *te } } }`, - Results: []map[string]any{ - { - "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", - "name": "Book By Website", - "publisher": map[string]any{ - "_docID": "bae-07fd000a-d023-54b9-b8f3-a4318fac8fed", - "name": "Website", + Results: map[string]any{ + "Book": []map[string]any{ + { + "_docID": "bae-e7943028-5c74-5fd4-9661-0a233edcd287", + "name": "Book By Website", + "publisher": map[string]any{ + "_docID": "bae-07fd000a-d023-54b9-b8f3-a4318fac8fed", + "name": "Website", + }, }, }, }, @@ -310,7 +328,9 @@ func TestATxnCanReadARecordThatIsDeletedInANonCommitedTxnBackwardDirection(t *te } } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Book": []map[string]any{}, + }, }, }, } @@ -350,9 +370,11 @@ func TestTxnDeletionOfRelatedDocFromNonPrimarySideForwardDirection(t *testing.T) _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-21084f46-b12a-53ab-94dd-04d075b4218c", + Results: map[string]any{ + "delete_Publisher": []map[string]any{ + { + "_docID": "bae-21084f46-b12a-53ab-94dd-04d075b4218c", + }, }, }, }, @@ -371,7 +393,9 @@ func TestTxnDeletionOfRelatedDocFromNonPrimarySideForwardDirection(t *testing.T) } } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Publisher": []map[string]any{}, + }, }, }, } @@ -411,9 +435,11 @@ func TestTxnDeletionOfRelatedDocFromNonPrimarySideBackwardDirection(t *testing.T _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-21084f46-b12a-53ab-94dd-04d075b4218c", + Results: map[string]any{ + "delete_Publisher": []map[string]any{ + { + "_docID": "bae-21084f46-b12a-53ab-94dd-04d075b4218c", + }, }, }, }, @@ -432,11 +458,13 @@ func TestTxnDeletionOfRelatedDocFromNonPrimarySideBackwardDirection(t *testing.T } } }`, - Results: []map[string]any{ - { - "_docID": "bae-7f6a5a76-b90d-5715-a452-708ded9e7ae7", - "name": "Book By Online", - "publisher": nil, + Results: map[string]any{ + "Book": []map[string]any{ + { + "_docID": "bae-7f6a5a76-b90d-5715-a452-708ded9e7ae7", + "name": "Book By Online", + "publisher": nil, + }, }, }, }, diff --git a/tests/integration/mutation/delete/with_deleted_field_test.go b/tests/integration/mutation/delete/with_deleted_field_test.go index 274d224253..eb9903ed47 100644 --- a/tests/integration/mutation/delete/with_deleted_field_test.go +++ b/tests/integration/mutation/delete/with_deleted_field_test.go @@ -39,10 +39,12 @@ func TestMutationDeletion_WithDeletedField(t *testing.T) { _docID } }`, - Results: []map[string]any{ - { - "_deleted": true, - "_docID": "bae-1ef746f8-821e-586f-99b2-4cb1fb9b782f", + Results: map[string]any{ + "delete_User": []map[string]any{ + { + "_deleted": true, + "_docID": "bae-1ef746f8-821e-586f-99b2-4cb1fb9b782f", + }, }, }, }, diff --git a/tests/integration/mutation/delete/with_filter_test.go b/tests/integration/mutation/delete/with_filter_test.go index 1884d38e17..a54fb12f29 100644 --- a/tests/integration/mutation/delete/with_filter_test.go +++ b/tests/integration/mutation/delete/with_filter_test.go @@ -38,9 +38,11 @@ func TestMutationDeletion_WithFilter(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "Shahzad", + Results: map[string]any{ + "delete_User": []map[string]any{ + { + "name": "Shahzad", + }, }, }, }, @@ -86,12 +88,14 @@ func TestMutationDeletion_WithFilterMatchingMultipleDocs(t *testing.T) { age } }`, - Results: []map[string]any{ - { - "age": int64(2), - }, - { - "age": int64(1), + Results: map[string]any{ + "delete_User": []map[string]any{ + { + "age": int64(2), + }, + { + "age": int64(1), + }, }, }, }, @@ -133,15 +137,17 @@ func TestMutationDeletion_WithEmptyFilter(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", - }, - { - "name": "Shahzad", - }, - { - "name": "Fred", + Results: map[string]any{ + "delete_User": []map[string]any{ + { + "name": "John", + }, + { + "name": "Shahzad", + }, + { + "name": "Fred", + }, }, }, }, @@ -173,7 +179,9 @@ func TestMutationDeletion_WithFilterNoMatch(t *testing.T) { name } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "delete_User": []map[string]any{}, + }, }, }, } @@ -198,7 +206,9 @@ func TestMutationDeletion_WithFilterOnEmptyCollection(t *testing.T) { name } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "delete_User": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/mutation/delete/with_id_alias_test.go b/tests/integration/mutation/delete/with_id_alias_test.go index c9d259ac8b..882125c933 100644 --- a/tests/integration/mutation/delete/with_id_alias_test.go +++ b/tests/integration/mutation/delete/with_id_alias_test.go @@ -38,9 +38,11 @@ func TestMutationDeletion_WithIDAndAlias(t *testing.T) { fancyKey: _docID } }`, - Results: []map[string]any{ - { - "fancyKey": "bae-22dacd35-4560-583a-9a80-8edbf28aa85c", + Results: map[string]any{ + "delete_User": []map[string]any{ + { + "fancyKey": "bae-22dacd35-4560-583a-9a80-8edbf28aa85c", + }, }, }, }, diff --git a/tests/integration/mutation/delete/with_id_test.go b/tests/integration/mutation/delete/with_id_test.go index 774e9a8c18..6e6b8bb5b8 100644 --- a/tests/integration/mutation/delete/with_id_test.go +++ b/tests/integration/mutation/delete/with_id_test.go @@ -33,7 +33,9 @@ func TestMutationDeletion_WithIDUnknownValue(t *testing.T) { _docID } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "delete_User": []map[string]any{}, + }, }, }, } @@ -63,7 +65,9 @@ func TestMutationDeletion_WithIDUnknownValueAndUnrelatedRecordInCollection(t *te _docID } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "delete_User": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/mutation/delete/with_id_txn_test.go b/tests/integration/mutation/delete/with_id_txn_test.go index f704acea56..aa33ee447f 100644 --- a/tests/integration/mutation/delete/with_id_txn_test.go +++ b/tests/integration/mutation/delete/with_id_txn_test.go @@ -41,9 +41,11 @@ func TestMutationDeletion_WithIDAndTxn(t *testing.T) { _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-22dacd35-4560-583a-9a80-8edbf28aa85c", + Results: map[string]any{ + "delete_User": []map[string]any{ + { + "_docID": "bae-22dacd35-4560-583a-9a80-8edbf28aa85c", + }, }, }, }, @@ -54,7 +56,9 @@ func TestMutationDeletion_WithIDAndTxn(t *testing.T) { _docID } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "User": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/mutation/delete/with_ids_alias_test.go b/tests/integration/mutation/delete/with_ids_alias_test.go index b815ec703d..23fa4e2dc4 100644 --- a/tests/integration/mutation/delete/with_ids_alias_test.go +++ b/tests/integration/mutation/delete/with_ids_alias_test.go @@ -52,12 +52,14 @@ func TestMutationDeletion_WithIDsAndSelectAlias(t *testing.T) { AliasID: _docID } }`, - Results: []map[string]any{ - { - "AliasID": "bae-3eed37ed-5c7b-53ff-b125-d04fb173f6c0", - }, - { - "AliasID": "bae-959725a4-17cb-5e04-8908-98bc78fd06dd", + Results: map[string]any{ + "delete_User": []map[string]any{ + { + "AliasID": "bae-3eed37ed-5c7b-53ff-b125-d04fb173f6c0", + }, + { + "AliasID": "bae-959725a4-17cb-5e04-8908-98bc78fd06dd", + }, }, }, }, diff --git a/tests/integration/mutation/delete/with_ids_filter_test.go b/tests/integration/mutation/delete/with_ids_filter_test.go index 41f79fa859..94024a4113 100644 --- a/tests/integration/mutation/delete/with_ids_filter_test.go +++ b/tests/integration/mutation/delete/with_ids_filter_test.go @@ -38,9 +38,11 @@ func TestMutationDeletion_WithIDsAndEmptyFilter(t *testing.T) { _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-22dacd35-4560-583a-9a80-8edbf28aa85c", + Results: map[string]any{ + "delete_User": []map[string]any{ + { + "_docID": "bae-22dacd35-4560-583a-9a80-8edbf28aa85c", + }, }, }, }, diff --git a/tests/integration/mutation/delete/with_ids_test.go b/tests/integration/mutation/delete/with_ids_test.go index 4f3e462b00..1469990ce7 100644 --- a/tests/integration/mutation/delete/with_ids_test.go +++ b/tests/integration/mutation/delete/with_ids_test.go @@ -43,12 +43,14 @@ func TestMutationDeletion_WithIDs(t *testing.T) { _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-1ef746f8-821e-586f-99b2-4cb1fb9b782f", - }, - { - "_docID": "bae-22dacd35-4560-583a-9a80-8edbf28aa85c", + Results: map[string]any{ + "delete_User": []map[string]any{ + { + "_docID": "bae-1ef746f8-821e-586f-99b2-4cb1fb9b782f", + }, + { + "_docID": "bae-22dacd35-4560-583a-9a80-8edbf28aa85c", + }, }, }, }, @@ -85,7 +87,9 @@ func TestMutationDeletion_WithEmptyIDs(t *testing.T) { _docID } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "delete_User": []map[string]any{}, + }, }, testUtils.Request{ // Make sure no documents have been deleted @@ -94,12 +98,14 @@ func TestMutationDeletion_WithEmptyIDs(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", - }, - { - "name": "Shahzad", + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "John", + }, + { + "name": "Shahzad", + }, }, }, }, @@ -126,7 +132,9 @@ func TestMutationDeletion_WithIDsSingleUnknownID(t *testing.T) { _docID } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "delete_User": []map[string]any{}, + }, }, }, } @@ -151,7 +159,9 @@ func TestMutationDeletion_WithIDsMultipleUnknownID(t *testing.T) { _docID } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "delete_User": []map[string]any{}, + }, }, }, } @@ -181,9 +191,11 @@ func TestMutationDeletion_WithIDsKnownAndUnknown(t *testing.T) { _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-22dacd35-4560-583a-9a80-8edbf28aa85c", + Results: map[string]any{ + "delete_User": []map[string]any{ + { + "_docID": "bae-22dacd35-4560-583a-9a80-8edbf28aa85c", + }, }, }, }, diff --git a/tests/integration/mutation/delete/with_ids_txn_test.go b/tests/integration/mutation/delete/with_ids_txn_test.go index 53cb44c9e9..85c3624c7f 100644 --- a/tests/integration/mutation/delete/with_ids_txn_test.go +++ b/tests/integration/mutation/delete/with_ids_txn_test.go @@ -47,9 +47,11 @@ func TestMutationDeletion_WithIDsAndTxn(t *testing.T) { _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-959725a4-17cb-5e04-8908-98bc78fd06dd", + Results: map[string]any{ + "delete_User": []map[string]any{ + { + "_docID": "bae-959725a4-17cb-5e04-8908-98bc78fd06dd", + }, }, }, }, @@ -60,7 +62,9 @@ func TestMutationDeletion_WithIDsAndTxn(t *testing.T) { _docID } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "User": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/mutation/delete/with_ids_update_alias_test.go b/tests/integration/mutation/delete/with_ids_update_alias_test.go index 551b52a175..89ea5f8c06 100644 --- a/tests/integration/mutation/delete/with_ids_update_alias_test.go +++ b/tests/integration/mutation/delete/with_ids_update_alias_test.go @@ -60,12 +60,14 @@ func TestMutationDeletion_WithUpdateAndIDsAndSelectAlias(t *testing.T) { AliasID: _docID } }`, - Results: []map[string]any{ - { - "AliasID": "bae-3eed37ed-5c7b-53ff-b125-d04fb173f6c0", - }, - { - "AliasID": "bae-959725a4-17cb-5e04-8908-98bc78fd06dd", + Results: map[string]any{ + "delete_User": []map[string]any{ + { + "AliasID": "bae-3eed37ed-5c7b-53ff-b125-d04fb173f6c0", + }, + { + "AliasID": "bae-959725a4-17cb-5e04-8908-98bc78fd06dd", + }, }, }, }, diff --git a/tests/integration/mutation/mix/with_txn_test.go b/tests/integration/mutation/mix/with_txn_test.go index 5354b69eea..11ee66b73d 100644 --- a/tests/integration/mutation/mix/with_txn_test.go +++ b/tests/integration/mutation/mix/with_txn_test.go @@ -37,9 +37,11 @@ func TestMutationWithTxnDeletesUserGivenSameTransaction(t *testing.T) { _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", + Results: map[string]any{ + "create_User": []map[string]any{ + { + "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", + }, }, }, }, @@ -50,9 +52,11 @@ func TestMutationWithTxnDeletesUserGivenSameTransaction(t *testing.T) { _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", + Results: map[string]any{ + "delete_User": []map[string]any{ + { + "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", + }, }, }, }, @@ -81,9 +85,11 @@ func TestMutationWithTxnDoesNotDeletesUserGivenDifferentTransactions(t *testing. _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", + Results: map[string]any{ + "create_User": []map[string]any{ + { + "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", + }, }, }, }, @@ -94,7 +100,9 @@ func TestMutationWithTxnDoesNotDeletesUserGivenDifferentTransactions(t *testing. _docID } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "delete_User": []map[string]any{}, + }, }, testUtils.Request{ TransactionID: immutable.Some(0), @@ -105,11 +113,13 @@ func TestMutationWithTxnDoesNotDeletesUserGivenDifferentTransactions(t *testing. age } }`, - Results: []map[string]any{ - { - "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", - "name": "John", - "age": int64(27), + Results: map[string]any{ + "User": []map[string]any{ + { + "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", + "name": "John", + "age": int64(27), + }, }, }, }, @@ -122,7 +132,9 @@ func TestMutationWithTxnDoesNotDeletesUserGivenDifferentTransactions(t *testing. age } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "User": []map[string]any{}, + }, }, }, } @@ -155,9 +167,11 @@ func TestMutationWithTxnDoesUpdateUserGivenSameTransactions(t *testing.T) { _docID } }`, - Results: []map[string]any{ - { - "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", + Results: map[string]any{ + "update_User": []map[string]any{ + { + "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", + }, }, }, }, @@ -170,11 +184,13 @@ func TestMutationWithTxnDoesUpdateUserGivenSameTransactions(t *testing.T) { age } }`, - Results: []map[string]any{ - { - "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", - "name": "John", - "age": int64(28), + Results: map[string]any{ + "User": []map[string]any{ + { + "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", + "name": "John", + "age": int64(28), + }, }, }, }, @@ -211,11 +227,13 @@ func TestMutationWithTxnDoesNotUpdateUserGivenDifferentTransactions(t *testing.T age } }`, - Results: []map[string]any{ - { - "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", - "name": "John", - "age": int64(28), + Results: map[string]any{ + "update_User": []map[string]any{ + { + "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", + "name": "John", + "age": int64(28), + }, }, }, }, @@ -228,11 +246,13 @@ func TestMutationWithTxnDoesNotUpdateUserGivenDifferentTransactions(t *testing.T age } }`, - Results: []map[string]any{ - { - "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", - "name": "John", - "age": int64(27), + Results: map[string]any{ + "User": []map[string]any{ + { + "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", + "name": "John", + "age": int64(27), + }, }, }, }, @@ -270,11 +290,13 @@ func TestMutationWithTxnDoesNotAllowUpdateInSecondTransactionUser(t *testing.T) age } }`, - Results: []map[string]any{ - { - "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", - "name": "John", - "age": int64(28), + Results: map[string]any{ + "update_User": []map[string]any{ + { + "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", + "name": "John", + "age": int64(28), + }, }, }, }, @@ -287,11 +309,13 @@ func TestMutationWithTxnDoesNotAllowUpdateInSecondTransactionUser(t *testing.T) age } }`, - Results: []map[string]any{ - { - "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", - "name": "John", - "age": int64(29), + Results: map[string]any{ + "update_User": []map[string]any{ + { + "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", + "name": "John", + "age": int64(29), + }, }, }, }, @@ -311,11 +335,13 @@ func TestMutationWithTxnDoesNotAllowUpdateInSecondTransactionUser(t *testing.T) age } }`, - Results: []map[string]any{ - { - "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", - "name": "John", - "age": int64(28), + Results: map[string]any{ + "User": []map[string]any{ + { + "_docID": "bae-948fc3eb-9b68-5a8d-9c3c-8f76157002a9", + "name": "John", + "age": int64(28), + }, }, }, }, diff --git a/tests/integration/mutation/update/crdt/pcounter_test.go b/tests/integration/mutation/update/crdt/pcounter_test.go index c4ff85e8b4..784bf9f2c4 100644 --- a/tests/integration/mutation/update/crdt/pcounter_test.go +++ b/tests/integration/mutation/update/crdt/pcounter_test.go @@ -52,10 +52,12 @@ func TestPCounterUpdate_IntKindWithNegativeIncrement_ShouldError(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "name": "John", - "points": int64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "points": int64(0), + }, }, }, }, @@ -102,10 +104,12 @@ func TestPCounterUpdate_IntKindWithPositiveIncrement_ShouldIncrement(t *testing. points } }`, - Results: []map[string]any{ - { - "name": "John", - "points": int64(20), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "points": int64(20), + }, }, }, }, @@ -154,10 +158,12 @@ func TestPCounterUpdate_IntKindWithPositiveIncrementOverflow_RollsOverToMinInt64 points } }`, - Results: []map[string]any{ - { - "name": "John", - "points": int64(math.MinInt64), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "points": int64(math.MinInt64), + }, }, }, }, @@ -204,11 +210,13 @@ func TestPCounterUpdate_FloatKindWithPositiveIncrement_ShouldIncrement(t *testin points } }`, - Results: []map[string]any{ - { - "name": "John", - // Note the lack of precision of float types. - "points": 20.299999999999997, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + // Note the lack of precision of float types. + "points": 20.299999999999997, + }, }, }, }, @@ -251,10 +259,12 @@ func TestPCounterUpdate_FloatKindWithPositiveIncrementOverflow_NoOp(t *testing.T points } }`, - Results: []map[string]any{ - { - "name": "John", - "points": math.MaxFloat64, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "points": math.MaxFloat64, + }, }, }, }, diff --git a/tests/integration/mutation/update/crdt/pncounter_test.go b/tests/integration/mutation/update/crdt/pncounter_test.go index 534bd406dc..11efc0452b 100644 --- a/tests/integration/mutation/update/crdt/pncounter_test.go +++ b/tests/integration/mutation/update/crdt/pncounter_test.go @@ -57,10 +57,12 @@ func TestPNCounterUpdate_IntKindWithPositiveIncrement_ShouldIncrement(t *testing points } }`, - Results: []map[string]any{ - { - "name": "John", - "points": int64(20), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "points": int64(20), + }, }, }, }, @@ -109,10 +111,12 @@ func TestPNCounterUpdate_IntKindWithPositiveIncrementOverflow_RollsOverToMinInt6 points } }`, - Results: []map[string]any{ - { - "name": "John", - "points": int64(math.MinInt64), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "points": int64(math.MinInt64), + }, }, }, }, @@ -159,11 +163,13 @@ func TestPNCounterUpdate_FloatKindWithPositiveIncrement_ShouldIncrement(t *testi points } }`, - Results: []map[string]any{ - { - "name": "John", - // Note the lack of precision of float types. - "points": 20.299999999999997, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + // Note the lack of precision of float types. + "points": 20.299999999999997, + }, }, }, }, @@ -212,10 +218,12 @@ func TestPNCounterUpdate_FloatKindWithPositiveIncrementOverflow_PositiveInf(t *t points } }`, - Results: []map[string]any{ - { - "name": "John", - "points": math.Inf(1), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "points": math.Inf(1), + }, }, }, }, @@ -264,10 +272,12 @@ func TestPNCounterUpdate_FloatKindWithDecrementOverflow_NegativeInf(t *testing.T points } }`, - Results: []map[string]any{ - { - "name": "John", - "points": math.Inf(-1), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "points": math.Inf(-1), + }, }, }, }, @@ -309,10 +319,12 @@ func TestPNCounterUpdate_FloatKindWithPositiveIncrementInsignificantValue_DoesNo points } }`, - Results: []map[string]any{ - { - "name": "John", - "points": math.MaxFloat64 / 10, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "points": math.MaxFloat64 / 10, + }, }, }, }, diff --git a/tests/integration/mutation/update/field_kinds/array_bool_test.go b/tests/integration/mutation/update/field_kinds/array_bool_test.go index b1a5500242..4f121cbdd5 100644 --- a/tests/integration/mutation/update/field_kinds/array_bool_test.go +++ b/tests/integration/mutation/update/field_kinds/array_bool_test.go @@ -47,9 +47,11 @@ func TestMutationUpdate_WithArrayOfBooleansToNil(t *testing.T) { } } `, - Results: []map[string]any{ - { - "likedIndexes": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "likedIndexes": nil, + }, }, }, }, @@ -90,9 +92,11 @@ func TestMutationUpdate_WithArrayOfBooleansToEmpty(t *testing.T) { } } `, - Results: []map[string]any{ - { - "likedIndexes": []bool{}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "likedIndexes": []bool{}, + }, }, }, }, @@ -133,9 +137,11 @@ func TestMutationUpdate_WithArrayOfBooleansToSameSize(t *testing.T) { } } `, - Results: []map[string]any{ - { - "likedIndexes": []bool{true, false, true, false}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "likedIndexes": []bool{true, false, true, false}, + }, }, }, }, @@ -176,9 +182,11 @@ func TestMutationUpdate_WithArrayOfBooleansToSmallerSize(t *testing.T) { } } `, - Results: []map[string]any{ - { - "likedIndexes": []bool{false, true}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "likedIndexes": []bool{false, true}, + }, }, }, }, @@ -219,9 +227,11 @@ func TestMutationUpdate_WithArrayOfBooleansToLargerSize(t *testing.T) { } } `, - Results: []map[string]any{ - { - "likedIndexes": []bool{true, false, true, false, true, true}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "likedIndexes": []bool{true, false, true, false, true, true}, + }, }, }, }, diff --git a/tests/integration/mutation/update/field_kinds/array_float_test.go b/tests/integration/mutation/update/field_kinds/array_float_test.go index a1806eadf0..b62af16c41 100644 --- a/tests/integration/mutation/update/field_kinds/array_float_test.go +++ b/tests/integration/mutation/update/field_kinds/array_float_test.go @@ -47,9 +47,11 @@ func TestMutationUpdate_WithArrayOfFloatsToNil(t *testing.T) { } } `, - Results: []map[string]any{ - { - "favouriteFloats": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "favouriteFloats": nil, + }, }, }, }, @@ -90,9 +92,11 @@ func TestMutationUpdate_WithArrayOfFloatsToEmpty(t *testing.T) { } } `, - Results: []map[string]any{ - { - "favouriteFloats": []float64{}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "favouriteFloats": []float64{}, + }, }, }, }, @@ -133,9 +137,11 @@ func TestMutationUpdate_WithArrayOfFloatsToSameSize(t *testing.T) { } } `, - Results: []map[string]any{ - { - "favouriteFloats": []float64{3.1425, -0.00000000001, 1000000}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "favouriteFloats": []float64{3.1425, -0.00000000001, 1000000}, + }, }, }, }, @@ -176,9 +182,11 @@ func TestMutationUpdate_WithArrayOfFloatsToSmallerSize(t *testing.T) { } } `, - Results: []map[string]any{ - { - "favouriteFloats": []float64{3.14}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "favouriteFloats": []float64{3.14}, + }, }, }, }, @@ -219,9 +227,11 @@ func TestMutationUpdate_WithArrayOfFloatsToLargerSize(t *testing.T) { } } `, - Results: []map[string]any{ - { - "favouriteFloats": []float64{3.1425, 0.00000000001, -10, 6.626070}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "favouriteFloats": []float64{3.1425, 0.00000000001, -10, 6.626070}, + }, }, }, }, diff --git a/tests/integration/mutation/update/field_kinds/array_int_test.go b/tests/integration/mutation/update/field_kinds/array_int_test.go index 63ecfc0969..b906d17fb0 100644 --- a/tests/integration/mutation/update/field_kinds/array_int_test.go +++ b/tests/integration/mutation/update/field_kinds/array_int_test.go @@ -47,9 +47,11 @@ func TestMutationUpdate_WithArrayOfIntsToNil(t *testing.T) { } } `, - Results: []map[string]any{ - { - "favouriteIntegers": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "favouriteIntegers": nil, + }, }, }, }, @@ -90,9 +92,11 @@ func TestMutationUpdate_WithArrayOfIntsToEmpty(t *testing.T) { } } `, - Results: []map[string]any{ - { - "favouriteIntegers": []int64{}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "favouriteIntegers": []int64{}, + }, }, }, }, @@ -133,9 +137,11 @@ func TestMutationUpdate_WithArrayOfIntsToSameSizePositiveValues(t *testing.T) { } } `, - Results: []map[string]any{ - { - "favouriteIntegers": []int64{8, 5, 3, 2, 1}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "favouriteIntegers": []int64{8, 5, 3, 2, 1}, + }, }, }, }, @@ -176,9 +182,11 @@ func TestMutationUpdate_WithArrayOfIntsToSameSizeMixedValues(t *testing.T) { } } `, - Results: []map[string]any{ - { - "favouriteIntegers": []int64{-1, 2, -3, 5, -8}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "favouriteIntegers": []int64{-1, 2, -3, 5, -8}, + }, }, }, }, @@ -219,9 +227,11 @@ func TestMutationUpdate_WithArrayOfIntsToSmallerSizePositiveValues(t *testing.T) } } `, - Results: []map[string]any{ - { - "favouriteIntegers": []int64{1, 2, 3}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "favouriteIntegers": []int64{1, 2, 3}, + }, }, }, }, @@ -262,9 +272,11 @@ func TestMutationUpdate_WithArrayOfIntsToLargerSizePositiveValues(t *testing.T) } } `, - Results: []map[string]any{ - { - "favouriteIntegers": []int64{1, 2, 3, 5, 8, 13, 21}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "favouriteIntegers": []int64{1, 2, 3, 5, 8, 13, 21}, + }, }, }, }, diff --git a/tests/integration/mutation/update/field_kinds/array_nillable_bool_test.go b/tests/integration/mutation/update/field_kinds/array_nillable_bool_test.go index d069927d5e..8de0d80abc 100644 --- a/tests/integration/mutation/update/field_kinds/array_nillable_bool_test.go +++ b/tests/integration/mutation/update/field_kinds/array_nillable_bool_test.go @@ -49,14 +49,16 @@ func TestMutationUpdate_WithArrayOfNillableBooleans(t *testing.T) { } } `, - Results: []map[string]any{ - { - "likedIndexes": []immutable.Option[bool]{ - immutable.Some(true), - immutable.Some(true), - immutable.Some(false), - immutable.Some(true), - immutable.None[bool](), + Results: map[string]any{ + "Users": []map[string]any{ + { + "likedIndexes": []immutable.Option[bool]{ + immutable.Some(true), + immutable.Some(true), + immutable.Some(false), + immutable.Some(true), + immutable.None[bool](), + }, }, }, }, diff --git a/tests/integration/mutation/update/field_kinds/array_nillable_float_test.go b/tests/integration/mutation/update/field_kinds/array_nillable_float_test.go index 825461cd4c..d8838ca730 100644 --- a/tests/integration/mutation/update/field_kinds/array_nillable_float_test.go +++ b/tests/integration/mutation/update/field_kinds/array_nillable_float_test.go @@ -49,13 +49,15 @@ func TestMutationUpdate_WithArrayOfNillableFloats(t *testing.T) { } } `, - Results: []map[string]any{ - { - "favouriteFloats": []immutable.Option[float64]{ - immutable.Some(3.1425), - immutable.Some(-0.00000000001), - immutable.None[float64](), - immutable.Some[float64](10), + Results: map[string]any{ + "Users": []map[string]any{ + { + "favouriteFloats": []immutable.Option[float64]{ + immutable.Some(3.1425), + immutable.Some(-0.00000000001), + immutable.None[float64](), + immutable.Some[float64](10), + }, }, }, }, diff --git a/tests/integration/mutation/update/field_kinds/array_nillable_int_test.go b/tests/integration/mutation/update/field_kinds/array_nillable_int_test.go index 99e28d2520..639a1671ad 100644 --- a/tests/integration/mutation/update/field_kinds/array_nillable_int_test.go +++ b/tests/integration/mutation/update/field_kinds/array_nillable_int_test.go @@ -49,14 +49,16 @@ func TestMutationUpdate_WithArrayOfNillableInts(t *testing.T) { } } `, - Results: []map[string]any{ - { - "favouriteIntegers": []immutable.Option[int64]{ - immutable.None[int64](), - immutable.Some[int64](2), - immutable.Some[int64](3), - immutable.None[int64](), - immutable.Some[int64](8), + Results: map[string]any{ + "Users": []map[string]any{ + { + "favouriteIntegers": []immutable.Option[int64]{ + immutable.None[int64](), + immutable.Some[int64](2), + immutable.Some[int64](3), + immutable.None[int64](), + immutable.Some[int64](8), + }, }, }, }, diff --git a/tests/integration/mutation/update/field_kinds/array_nillable_string_test.go b/tests/integration/mutation/update/field_kinds/array_nillable_string_test.go index eea09e0157..4d4adfcf78 100644 --- a/tests/integration/mutation/update/field_kinds/array_nillable_string_test.go +++ b/tests/integration/mutation/update/field_kinds/array_nillable_string_test.go @@ -49,15 +49,17 @@ func TestMutationUpdate_WithArrayOfStringsInts(t *testing.T) { } } `, - Results: []map[string]any{ - { - "preferredStrings": []immutable.Option[string]{ - immutable.Some(""), - immutable.Some("the previous"), - immutable.None[string](), - immutable.Some("empty string"), - immutable.Some("blank string"), - immutable.Some("hitchi"), + Results: map[string]any{ + "Users": []map[string]any{ + { + "preferredStrings": []immutable.Option[string]{ + immutable.Some(""), + immutable.Some("the previous"), + immutable.None[string](), + immutable.Some("empty string"), + immutable.Some("blank string"), + immutable.Some("hitchi"), + }, }, }, }, diff --git a/tests/integration/mutation/update/field_kinds/array_string_test.go b/tests/integration/mutation/update/field_kinds/array_string_test.go index 3481fb7912..366c5d1912 100644 --- a/tests/integration/mutation/update/field_kinds/array_string_test.go +++ b/tests/integration/mutation/update/field_kinds/array_string_test.go @@ -47,9 +47,11 @@ func TestMutationUpdate_WithArrayOfStringsToNil(t *testing.T) { } } `, - Results: []map[string]any{ - { - "preferredStrings": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "preferredStrings": nil, + }, }, }, }, @@ -90,9 +92,11 @@ func TestMutationUpdate_WithArrayOfStringsToEmpty(t *testing.T) { } } `, - Results: []map[string]any{ - { - "preferredStrings": []string{}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "preferredStrings": []string{}, + }, }, }, }, @@ -133,9 +137,11 @@ func TestMutationUpdate_WithArrayOfStringsToSameSize(t *testing.T) { } } `, - Results: []map[string]any{ - { - "preferredStrings": []string{"zeroth", "the previous", "the first", "null string"}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "preferredStrings": []string{"zeroth", "the previous", "the first", "null string"}, + }, }, }, }, @@ -176,9 +182,11 @@ func TestMutationUpdate_WithArrayOfStringsToSmallerSize(t *testing.T) { } } `, - Results: []map[string]any{ - { - "preferredStrings": []string{"", "the first"}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "preferredStrings": []string{"", "the first"}, + }, }, }, }, @@ -219,15 +227,17 @@ func TestMutationUpdate_WithArrayOfStringsToLargerSize(t *testing.T) { } } `, - Results: []map[string]any{ - { - "preferredStrings": []string{ - "", - "the previous", - "the first", - "empty string", - "blank string", - "hitchi", + Results: map[string]any{ + "Users": []map[string]any{ + { + "preferredStrings": []string{ + "", + "the previous", + "the first", + "empty string", + "blank string", + "hitchi", + }, }, }, }, diff --git a/tests/integration/mutation/update/field_kinds/blob_test.go b/tests/integration/mutation/update/field_kinds/blob_test.go index 4434d49ef0..970ed781a7 100644 --- a/tests/integration/mutation/update/field_kinds/blob_test.go +++ b/tests/integration/mutation/update/field_kinds/blob_test.go @@ -47,9 +47,11 @@ func TestMutationUpdate_WithBlobField(t *testing.T) { } } `, - Results: []map[string]any{ - { - "data": "00FF", + Results: map[string]any{ + "Users": []map[string]any{ + { + "data": "00FF", + }, }, }, }, @@ -88,9 +90,11 @@ func TestMutationUpdate_IfBlobFieldSetToNull_ShouldBeNil(t *testing.T) { } } `, - Results: []map[string]any{ - { - "data": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "data": nil, + }, }, }, }, diff --git a/tests/integration/mutation/update/field_kinds/bool_test.go b/tests/integration/mutation/update/field_kinds/bool_test.go index 36301961ed..5215140203 100644 --- a/tests/integration/mutation/update/field_kinds/bool_test.go +++ b/tests/integration/mutation/update/field_kinds/bool_test.go @@ -45,9 +45,11 @@ func TestMutationUpdate_IfBoolFieldSetToNull_ShouldBeNil(t *testing.T) { } } `, - Results: []map[string]any{ - { - "valid": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "valid": nil, + }, }, }, }, diff --git a/tests/integration/mutation/update/field_kinds/date_time_test.go b/tests/integration/mutation/update/field_kinds/date_time_test.go index c0ac23c166..1eb8a412bc 100644 --- a/tests/integration/mutation/update/field_kinds/date_time_test.go +++ b/tests/integration/mutation/update/field_kinds/date_time_test.go @@ -47,9 +47,11 @@ func TestMutationUpdate_WithDateTimeField(t *testing.T) { } } `, - Results: []map[string]any{ - { - "created_at": testUtils.MustParseTime("2021-07-23T02:22:22-05:00"), + Results: map[string]any{ + "Users": []map[string]any{ + { + "created_at": testUtils.MustParseTime("2021-07-23T02:22:22-05:00"), + }, }, }, }, @@ -90,14 +92,16 @@ func TestMutationUpdate_WithDateTimeField_MultipleDocs(t *testing.T) { created_at } }`, - Results: []map[string]any{ - { - "name": "Fred", - "created_at": testUtils.MustParseTime("2031-07-23T03:23:23Z"), - }, - { - "name": "John", - "created_at": testUtils.MustParseTime("2031-07-23T03:23:23Z"), + Results: map[string]any{ + "update_Users": []map[string]any{ + { + "name": "Fred", + "created_at": testUtils.MustParseTime("2031-07-23T03:23:23Z"), + }, + { + "name": "John", + "created_at": testUtils.MustParseTime("2031-07-23T03:23:23Z"), + }, }, }, }, @@ -136,9 +140,11 @@ func TestMutationUpdate_IfDateTimeFieldSetToNull_ShouldBeNil(t *testing.T) { } } `, - Results: []map[string]any{ - { - "created_at": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "created_at": nil, + }, }, }, }, diff --git a/tests/integration/mutation/update/field_kinds/float_test.go b/tests/integration/mutation/update/field_kinds/float_test.go index bb1a9babce..9ef299db17 100644 --- a/tests/integration/mutation/update/field_kinds/float_test.go +++ b/tests/integration/mutation/update/field_kinds/float_test.go @@ -45,9 +45,11 @@ func TestMutationUpdate_IfFloatFieldSetToNull_ShouldBeNil(t *testing.T) { } } `, - Results: []map[string]any{ - { - "rate": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "rate": nil, + }, }, }, }, diff --git a/tests/integration/mutation/update/field_kinds/int_test.go b/tests/integration/mutation/update/field_kinds/int_test.go index 84a122e080..a30c321e46 100644 --- a/tests/integration/mutation/update/field_kinds/int_test.go +++ b/tests/integration/mutation/update/field_kinds/int_test.go @@ -45,9 +45,11 @@ func TestMutationUpdate_IfIntFieldSetToNull_ShouldBeNil(t *testing.T) { } } `, - Results: []map[string]any{ - { - "age": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "age": nil, + }, }, }, }, diff --git a/tests/integration/mutation/update/field_kinds/json_test.go b/tests/integration/mutation/update/field_kinds/json_test.go index c782f856a3..868e0c5a7d 100644 --- a/tests/integration/mutation/update/field_kinds/json_test.go +++ b/tests/integration/mutation/update/field_kinds/json_test.go @@ -45,9 +45,11 @@ func TestMutationUpdate_IfJSONFieldSetToNull_ShouldBeNil(t *testing.T) { } } `, - Results: []map[string]any{ - { - "custom": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "custom": nil, + }, }, }, }, diff --git a/tests/integration/mutation/update/field_kinds/one_to_many/simple_test.go b/tests/integration/mutation/update/field_kinds/one_to_many/simple_test.go index 1b515c62fd..e8ac15e4da 100644 --- a/tests/integration/mutation/update/field_kinds/one_to_many/simple_test.go +++ b/tests/integration/mutation/update/field_kinds/one_to_many/simple_test.go @@ -116,10 +116,12 @@ func TestMutationUpdateOneToMany_InvalidRelationIDToLinkFromManySide(t *testing. } } }`, - Results: []map[string]any{ - { - "name": "John Grisham", - "published": []map[string]any{}, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "published": []map[string]any{}, + }, }, }, }, @@ -132,10 +134,12 @@ func TestMutationUpdateOneToMany_InvalidRelationIDToLinkFromManySide(t *testing. } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "author": nil, // Linked to incorrect id + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author": nil, // Linked to incorrect id + }, }, }, }, @@ -246,18 +250,20 @@ func TestMutationUpdateOneToMany_RelationIDToLinkFromManySide(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "New Shahzad", - "published": []map[string]any{ - { - "name": "Painted House", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "New Shahzad", + "published": []map[string]any{ + { + "name": "Painted House", + }, }, }, - }, - { - "name": "John Grisham", - "published": []map[string]any{}, + { + "name": "John Grisham", + "published": []map[string]any{}, + }, }, }, }, @@ -270,11 +276,13 @@ func TestMutationUpdateOneToMany_RelationIDToLinkFromManySide(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "author": map[string]any{ - "name": "New Shahzad", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author": map[string]any{ + "name": "New Shahzad", + }, }, }, }, diff --git a/tests/integration/mutation/update/field_kinds/one_to_many/with_alias_test.go b/tests/integration/mutation/update/field_kinds/one_to_many/with_alias_test.go index 5f50e1732b..1f0375e6ba 100644 --- a/tests/integration/mutation/update/field_kinds/one_to_many/with_alias_test.go +++ b/tests/integration/mutation/update/field_kinds/one_to_many/with_alias_test.go @@ -110,10 +110,12 @@ func TestMutationUpdateOneToMany_InvalidAliasRelationNameToLinkFromManySide_GQL( } } }`, - Results: []map[string]any{ - { - "name": "John Grisham", - "published": []map[string]any{}, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "published": []map[string]any{}, + }, }, }, }, @@ -126,10 +128,12 @@ func TestMutationUpdateOneToMany_InvalidAliasRelationNameToLinkFromManySide_GQL( } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "author": nil, // Linked to incorrect id + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author": nil, // Linked to incorrect id + }, }, }, }, @@ -183,10 +187,12 @@ func TestMutationUpdateOneToMany_InvalidAliasRelationNameToLinkFromManySide_Coll } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "author": nil, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author": nil, + }, }, }, }, @@ -297,18 +303,20 @@ func TestMutationUpdateOneToMany_AliasRelationNameToLinkFromManySide(t *testing. } } }`, - Results: []map[string]any{ - { - "name": "New Shahzad", - "published": []map[string]any{ - { - "name": "Painted House", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "New Shahzad", + "published": []map[string]any{ + { + "name": "Painted House", + }, }, }, - }, - { - "name": "John Grisham", - "published": []map[string]any{}, + { + "name": "John Grisham", + "published": []map[string]any{}, + }, }, }, }, @@ -321,11 +329,13 @@ func TestMutationUpdateOneToMany_AliasRelationNameToLinkFromManySide(t *testing. } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "author": map[string]any{ - "name": "New Shahzad", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author": map[string]any{ + "name": "New Shahzad", + }, }, }, }, diff --git a/tests/integration/mutation/update/field_kinds/one_to_one/with_self_ref_test.go b/tests/integration/mutation/update/field_kinds/one_to_one/with_self_ref_test.go index dc49999627..841d30d80c 100644 --- a/tests/integration/mutation/update/field_kinds/one_to_one/with_self_ref_test.go +++ b/tests/integration/mutation/update/field_kinds/one_to_one/with_self_ref_test.go @@ -61,17 +61,19 @@ func TestMutationUpdateOneToOne_SelfReferencingFromPrimary(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Fred", - "boss": map[string]any{ + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Fred", + "boss": map[string]any{ + "name": "John", + }, + }, + { "name": "John", + "boss": nil, }, }, - { - "name": "John", - "boss": nil, - }, }, }, testUtils.Request{ @@ -84,15 +86,17 @@ func TestMutationUpdateOneToOne_SelfReferencingFromPrimary(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Fred", - "underling": nil, - }, - { - "name": "John", - "underling": map[string]any{ - "name": "Fred", + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Fred", + "underling": nil, + }, + { + "name": "John", + "underling": map[string]any{ + "name": "Fred", + }, }, }, }, @@ -148,15 +152,17 @@ func TestMutationUpdateOneToOne_SelfReferencingFromSecondary(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "John", - "boss": nil, - }, - { - "name": "Fred", - "boss": map[string]any{ + Results: map[string]any{ + "User": []map[string]any{ + { "name": "John", + "boss": nil, + }, + { + "name": "Fred", + "boss": map[string]any{ + "name": "John", + }, }, }, }, @@ -171,16 +177,18 @@ func TestMutationUpdateOneToOne_SelfReferencingFromSecondary(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "John", - "underling": map[string]any{ - "name": "Fred", + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "John", + "underling": map[string]any{ + "name": "Fred", + }, + }, + { + "name": "Fred", + "underling": nil, }, - }, - { - "name": "Fred", - "underling": nil, }, }, }, diff --git a/tests/integration/mutation/update/field_kinds/one_to_one/with_simple_test.go b/tests/integration/mutation/update/field_kinds/one_to_one/with_simple_test.go index c2df5a9db8..8cbbe963f3 100644 --- a/tests/integration/mutation/update/field_kinds/one_to_one/with_simple_test.go +++ b/tests/integration/mutation/update/field_kinds/one_to_one/with_simple_test.go @@ -49,9 +49,11 @@ func TestMutationUpdateOneToOneNoChild(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John Grisham", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + }, }, }, }, @@ -98,11 +100,13 @@ func TestMutationUpdateOneToOne(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "author": map[string]any{ - "name": "John Grisham", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, @@ -117,11 +121,13 @@ func TestMutationUpdateOneToOne(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "John Grisham", - "published": map[string]any{ - "name": "Painted House", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "published": map[string]any{ + "name": "Painted House", + }, }, }, }, @@ -170,11 +176,13 @@ func TestMutationUpdateOneToOneSecondarySide(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "author": map[string]any{ - "name": "John Grisham", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, @@ -189,11 +197,13 @@ func TestMutationUpdateOneToOneSecondarySide(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "John Grisham", - "published": map[string]any{ - "name": "Painted House", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "published": map[string]any{ + "name": "Painted House", + }, }, }, }, diff --git a/tests/integration/mutation/update/field_kinds/string_test.go b/tests/integration/mutation/update/field_kinds/string_test.go index 7783f9b0fd..6e665ae301 100644 --- a/tests/integration/mutation/update/field_kinds/string_test.go +++ b/tests/integration/mutation/update/field_kinds/string_test.go @@ -45,9 +45,11 @@ func TestMutationUpdate_IfStringFieldSetToNull_ShouldBeNil(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": nil, + }, }, }, }, diff --git a/tests/integration/mutation/update/underscored_schema_test.go b/tests/integration/mutation/update/underscored_schema_test.go index fa25f22d06..c73c1562e6 100644 --- a/tests/integration/mutation/update/underscored_schema_test.go +++ b/tests/integration/mutation/update/underscored_schema_test.go @@ -46,9 +46,11 @@ func TestMutationUpdateUnderscoredSchema(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "Fred", + Results: map[string]any{ + "My_User": []map[string]any{ + { + "name": "Fred", + }, }, }, }, diff --git a/tests/integration/mutation/update/with_filter_test.go b/tests/integration/mutation/update/with_filter_test.go index 1819a8ba0c..43b1faee0f 100644 --- a/tests/integration/mutation/update/with_filter_test.go +++ b/tests/integration/mutation/update/with_filter_test.go @@ -44,7 +44,9 @@ func TestMutationUpdate_WithBooleanFilter_ResultFilteredOut(t *testing.T) { } }`, // As the record no longer matches the filter it is not returned - Results: []map[string]any{}, + Results: map[string]any{ + "update_Users": []map[string]any{}, + }, }, }, } @@ -93,14 +95,16 @@ func TestMutationUpdate_WithBooleanFilter(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "name": "John", - "points": float64(59), - }, - { - "name": "Fred", - "points": float64(59), + Results: map[string]any{ + "update_Users": []map[string]any{ + { + "name": "John", + "points": float64(59), + }, + { + "name": "Fred", + "points": float64(59), + }, }, }, }, diff --git a/tests/integration/mutation/update/with_id_test.go b/tests/integration/mutation/update/with_id_test.go index 342e228052..3aa0cf9b74 100644 --- a/tests/integration/mutation/update/with_id_test.go +++ b/tests/integration/mutation/update/with_id_test.go @@ -48,10 +48,12 @@ func TestMutationUpdate_WithId(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "name": "John", - "points": float64(59), + Results: map[string]any{ + "update_Users": []map[string]any{ + { + "name": "John", + "points": float64(59), + }, }, }, }, @@ -88,7 +90,9 @@ func TestMutationUpdate_WithNonExistantId(t *testing.T) { points } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "update_Users": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/mutation/update/with_ids_test.go b/tests/integration/mutation/update/with_ids_test.go index 5b7108948f..9afa6a4d02 100644 --- a/tests/integration/mutation/update/with_ids_test.go +++ b/tests/integration/mutation/update/with_ids_test.go @@ -58,14 +58,16 @@ func TestMutationUpdate_WithIds(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "name": "John", - "points": float64(59), - }, - { - "name": "Fred", - "points": float64(59), + Results: map[string]any{ + "update_Users": []map[string]any{ + { + "name": "John", + "points": float64(59), + }, + { + "name": "Fred", + "points": float64(59), + }, }, }, }, diff --git a/tests/integration/net/one_to_many/peer/with_create_update_test.go b/tests/integration/net/one_to_many/peer/with_create_update_test.go index 1cedd82495..812b6380dc 100644 --- a/tests/integration/net/one_to_many/peer/with_create_update_test.go +++ b/tests/integration/net/one_to_many/peer/with_create_update_test.go @@ -78,12 +78,14 @@ func TestP2POneToManyPeerWithCreateUpdateLinkingSyncedDocToUnsyncedDoc(t *testin } } }`, - Results: []map[string]any{ - { - "Name": "Gulistan", - "Author_id": testUtils.NewDocIndex(0, 0), - "Author": map[string]any{ - "Name": "Saadi", + Results: map[string]any{ + "Book": []map[string]any{ + { + "Name": "Gulistan", + "Author_id": testUtils.NewDocIndex(0, 0), + "Author": map[string]any{ + "Name": "Saadi", + }, }, }, }, @@ -99,14 +101,16 @@ func TestP2POneToManyPeerWithCreateUpdateLinkingSyncedDocToUnsyncedDoc(t *testin } } }`, - Results: []map[string]any{ - { - "Name": "Gulistan", - "Author_id": testUtils.NewDocIndex(0, 0), - // "Saadi" was not synced to node 1, the update did not - // result in an error and synced to relational id even though "Saadi" - // does not exist in this node. - "Author": nil, + Results: map[string]any{ + "Book": []map[string]any{ + { + "Name": "Gulistan", + "Author_id": testUtils.NewDocIndex(0, 0), + // "Saadi" was not synced to node 1, the update did not + // result in an error and synced to relational id even though "Saadi" + // does not exist in this node. + "Author": nil, + }, }, }, }, diff --git a/tests/integration/net/one_to_many/replicator/with_create_test.go b/tests/integration/net/one_to_many/replicator/with_create_test.go index 7d2d706805..18fc1e27f0 100644 --- a/tests/integration/net/one_to_many/replicator/with_create_test.go +++ b/tests/integration/net/one_to_many/replicator/with_create_test.go @@ -68,11 +68,13 @@ func TestP2POneToManyReplicator(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "Name": "Gulistan", - "Author": map[string]any{ - "Name": "Saadi", + Results: map[string]any{ + "Book": []map[string]any{ + { + "Name": "Gulistan", + "Author": map[string]any{ + "Name": "Saadi", + }, }, }, }, diff --git a/tests/integration/net/simple/peer/crdt/pcounter_test.go b/tests/integration/net/simple/peer/crdt/pcounter_test.go index 963b7d54cd..569e4bb153 100644 --- a/tests/integration/net/simple/peer/crdt/pcounter_test.go +++ b/tests/integration/net/simple/peer/crdt/pcounter_test.go @@ -56,9 +56,11 @@ func TestP2PUpdate_WithPCounter_NoError(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "points": int64(20), + Results: map[string]any{ + "Users": []map[string]any{ + { + "points": int64(20), + }, }, }, }, @@ -111,9 +113,11 @@ func TestP2PUpdate_WithPCounterSimultaneousUpdate_NoError(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(90), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(90), + }, }, }, }, diff --git a/tests/integration/net/simple/peer/crdt/pncounter_test.go b/tests/integration/net/simple/peer/crdt/pncounter_test.go index 643ba738de..de0c67fc2c 100644 --- a/tests/integration/net/simple/peer/crdt/pncounter_test.go +++ b/tests/integration/net/simple/peer/crdt/pncounter_test.go @@ -56,9 +56,11 @@ func TestP2PUpdate_WithPNCounter_NoError(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "points": int64(20), + Results: map[string]any{ + "Users": []map[string]any{ + { + "points": int64(20), + }, }, }, }, @@ -111,9 +113,11 @@ func TestP2PUpdate_WithPNCounterSimultaneousUpdate_NoError(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(90), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(90), + }, }, }, }, diff --git a/tests/integration/net/simple/peer/subscribe/with_add_remove_test.go b/tests/integration/net/simple/peer/subscribe/with_add_remove_test.go index 26dbfdf151..0108d101bd 100644 --- a/tests/integration/net/simple/peer/subscribe/with_add_remove_test.go +++ b/tests/integration/net/simple/peer/subscribe/with_add_remove_test.go @@ -63,9 +63,11 @@ func TestP2PSubscribeAddAndRemoveSingle(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "Fred", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Fred", + }, }, }, }, @@ -125,7 +127,9 @@ func TestP2PSubscribeAddAndRemoveMultiple(t *testing.T) { name } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, testUtils.Request{ // Gillian the Giraffe has still been synced, as it was not removed from the subscription set. @@ -135,9 +139,11 @@ func TestP2PSubscribeAddAndRemoveMultiple(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "Gillian", + Results: map[string]any{ + "Giraffes": []map[string]any{ + { + "name": "Gillian", + }, }, }, }, @@ -187,9 +193,11 @@ func TestP2PSubscribeAddSingleAndRemoveErroneous(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -237,9 +245,11 @@ func TestP2PSubscribeAddSingleAndRemoveNone(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + }, }, }, }, diff --git a/tests/integration/net/simple/peer/subscribe/with_add_test.go b/tests/integration/net/simple/peer/subscribe/with_add_test.go index 04a1a3d57c..1577925763 100644 --- a/tests/integration/net/simple/peer/subscribe/with_add_test.go +++ b/tests/integration/net/simple/peer/subscribe/with_add_test.go @@ -60,12 +60,14 @@ func TestP2PSubscribeAddSingle(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + }, + // Peer sync should not sync new documents to nodes that is not subscribed + // to the P2P collection. }, - // Peer sync should not sync new documents to nodes that is not subscribed - // to the P2P collection. }, }, testUtils.Request{ @@ -75,12 +77,14 @@ func TestP2PSubscribeAddSingle(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "Fred", - }, - { - "name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Fred", + }, + { + "name": "John", + }, }, }, }, @@ -144,9 +148,11 @@ func TestP2PSubscribeAddMultiple(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -159,7 +165,9 @@ func TestP2PSubscribeAddMultiple(t *testing.T) { name } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Giraffes": []map[string]any{}, + }, }, testUtils.Request{ // Bjorn the Bear has been synced. @@ -168,9 +176,11 @@ func TestP2PSubscribeAddMultiple(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "Bjorn", + Results: map[string]any{ + "Bears": []map[string]any{ + { + "name": "Bjorn", + }, }, }, }, @@ -216,7 +226,9 @@ func TestP2PSubscribeAddSingleErroneousCollectionID(t *testing.T) { name } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -261,7 +273,9 @@ func TestP2PSubscribeAddValidAndErroneousCollectionID(t *testing.T) { name } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -309,9 +323,11 @@ func TestP2PSubscribeAddValidThenErroneousCollectionID(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -355,7 +371,9 @@ func TestP2PSubscribeAddNone(t *testing.T) { name } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/net/simple/peer/with_create_add_field_test.go b/tests/integration/net/simple/peer/with_create_add_field_test.go index 22133c78af..1f1c81e160 100644 --- a/tests/integration/net/simple/peer/with_create_add_field_test.go +++ b/tests/integration/net/simple/peer/with_create_add_field_test.go @@ -63,10 +63,12 @@ func TestP2PPeerCreateWithNewFieldSyncsDocsToOlderSchemaVersion(t *testing.T) { Email } }`, - Results: []map[string]any{ - { - "Name": "John", - "Email": "imnotyourbuddyguy@source.ca", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Email": "imnotyourbuddyguy@source.ca", + }, }, }, }, @@ -79,9 +81,11 @@ func TestP2PPeerCreateWithNewFieldSyncsDocsToOlderSchemaVersion(t *testing.T) { Name } }`, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, }, @@ -136,9 +140,11 @@ func TestP2PPeerCreateWithNewFieldSyncsDocsToNewerSchemaVersion(t *testing.T) { Name } }`, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, }, @@ -191,10 +197,12 @@ func TestP2PPeerCreateWithNewFieldSyncsDocsToUpdatedSchemaVersion(t *testing.T) Email } }`, - Results: []map[string]any{ - { - "Name": "John", - "Email": "imnotyourbuddyguy@source.ca", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Email": "imnotyourbuddyguy@source.ca", + }, }, }, }, @@ -263,10 +271,12 @@ func TestP2PPeerCreateWithNewFieldDocSyncedBeforeReceivingNodeSchemaUpdatedDoesN } } `, - Results: []map[string]any{ - { - "Name": "John", - "Email": "imnotyourbuddyguy@source.ca", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Email": "imnotyourbuddyguy@source.ca", + }, }, }, }, @@ -280,11 +290,13 @@ func TestP2PPeerCreateWithNewFieldDocSyncedBeforeReceivingNodeSchemaUpdatedDoesN } } `, - Results: []map[string]any{ - { - "Name": "John", - // The email should be returned but it is not - "Email": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + // The email should be returned but it is not + "Email": nil, + }, }, }, }, diff --git a/tests/integration/net/simple/peer/with_create_test.go b/tests/integration/net/simple/peer/with_create_test.go index e89030690d..8d67268396 100644 --- a/tests/integration/net/simple/peer/with_create_test.go +++ b/tests/integration/net/simple/peer/with_create_test.go @@ -57,12 +57,14 @@ func TestP2PCreateDoesNotSync(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(300), - }, - { - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(300), + }, + { + "Age": int64(21), + }, }, }, }, @@ -73,11 +75,13 @@ func TestP2PCreateDoesNotSync(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(300), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(300), + }, + // Peer sync should not sync new documents to nodes }, - // Peer sync should not sync new documents to nodes }, }, }, @@ -145,18 +149,20 @@ func TestP2PCreateWithP2PCollection(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(28), - }, - { - "Age": int64(30), - }, - { - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(28), + }, + { + "Age": int64(30), + }, + { + "Age": int64(21), + }, + // Peer sync should not sync new documents to nodes that is not subscribed + // to the P2P collection. }, - // Peer sync should not sync new documents to nodes that is not subscribed - // to the P2P collection. }, }, testUtils.Request{ @@ -166,18 +172,20 @@ func TestP2PCreateWithP2PCollection(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(28), - }, - { - "Age": int64(30), - }, - { - "Age": int64(21), - }, - { - "Age": int64(31), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(28), + }, + { + "Age": int64(30), + }, + { + "Age": int64(21), + }, + { + "Age": int64(31), + }, }, }, }, diff --git a/tests/integration/net/simple/peer/with_delete_test.go b/tests/integration/net/simple/peer/with_delete_test.go index 01f03e2c75..dba1c368fd 100644 --- a/tests/integration/net/simple/peer/with_delete_test.go +++ b/tests/integration/net/simple/peer/with_delete_test.go @@ -64,11 +64,13 @@ func TestP2PWithMultipleDocumentsSingleDelete(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "_deleted": false, - "Name": "Andy", - "Age": int64(74), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_deleted": false, + "Name": "Andy", + "Age": int64(74), + }, }, }, }, @@ -122,16 +124,18 @@ func TestP2PWithMultipleDocumentsSingleDeleteWithShowDeleted(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "_deleted": true, - "Name": "John", - "Age": int64(43), - }, - { - "_deleted": false, - "Name": "Andy", - "Age": int64(74), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_deleted": true, + "Name": "John", + "Age": int64(43), + }, + { + "_deleted": false, + "Name": "Andy", + "Age": int64(74), + }, }, }, }, @@ -193,16 +197,18 @@ func TestP2PWithMultipleDocumentsWithSingleUpdateBeforeConnectSingleDeleteWithSh Age } }`, - Results: []map[string]any{ - { - "_deleted": true, - "Name": "John", - "Age": int64(60), - }, - { - "_deleted": false, - "Name": "Andy", - "Age": int64(74), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_deleted": true, + "Name": "John", + "Age": int64(60), + }, + { + "_deleted": false, + "Name": "Andy", + "Age": int64(74), + }, }, }, }, @@ -272,16 +278,18 @@ func TestP2PWithMultipleDocumentsWithMultipleUpdatesBeforeConnectSingleDeleteWit Age } }`, - Results: []map[string]any{ - { - "_deleted": true, - "Name": "John", - "Age": int64(62), - }, - { - "_deleted": false, - "Name": "Andy", - "Age": int64(74), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_deleted": true, + "Name": "John", + "Age": int64(62), + }, + { + "_deleted": false, + "Name": "Andy", + "Age": int64(74), + }, }, }, }, @@ -360,16 +368,18 @@ func TestP2PWithMultipleDocumentsWithUpdateAndDeleteBeforeConnectSingleDeleteWit Age } }`, - Results: []map[string]any{ - { - "_deleted": true, - "Name": "John", - "Age": int64(62), - }, - { - "_deleted": false, - "Name": "Andy", - "Age": int64(74), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_deleted": true, + "Name": "John", + "Age": int64(62), + }, + { + "_deleted": false, + "Name": "Andy", + "Age": int64(74), + }, }, }, }, @@ -384,16 +394,18 @@ func TestP2PWithMultipleDocumentsWithUpdateAndDeleteBeforeConnectSingleDeleteWit Age } }`, - Results: []map[string]any{ - { - "_deleted": false, - "Name": "John", - "Age": int64(66), - }, - { - "_deleted": false, - "Name": "Andy", - "Age": int64(74), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_deleted": false, + "Name": "John", + "Age": int64(66), + }, + { + "_deleted": false, + "Name": "Andy", + "Age": int64(74), + }, }, }, }, diff --git a/tests/integration/net/simple/peer/with_update_add_field_test.go b/tests/integration/net/simple/peer/with_update_add_field_test.go index 88e86a75a3..c7a7d9f0f6 100644 --- a/tests/integration/net/simple/peer/with_update_add_field_test.go +++ b/tests/integration/net/simple/peer/with_update_add_field_test.go @@ -76,10 +76,12 @@ func TestP2PPeerUpdateWithNewFieldSyncsDocsToOlderSchemaVersionMultistep(t *test Email } }`, - Results: []map[string]any{ - { - "Name": "Shahzad", - "Email": "imnotyourbuddyguy@source.ca", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Shahzad", + "Email": "imnotyourbuddyguy@source.ca", + }, }, }, }, @@ -91,9 +93,11 @@ func TestP2PPeerUpdateWithNewFieldSyncsDocsToOlderSchemaVersionMultistep(t *test Name } }`, - Results: []map[string]any{ - { - "Name": "Shahzad", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Shahzad", + }, }, }, }, @@ -154,10 +158,12 @@ func TestP2PPeerUpdateWithNewFieldSyncsDocsToOlderSchemaVersion(t *testing.T) { Email } }`, - Results: []map[string]any{ - { - "Name": "Shahzad", - "Email": "imnotyourbuddyguy@source.ca", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Shahzad", + "Email": "imnotyourbuddyguy@source.ca", + }, }, }, }, @@ -168,9 +174,11 @@ func TestP2PPeerUpdateWithNewFieldSyncsDocsToOlderSchemaVersion(t *testing.T) { Name } }`, - Results: []map[string]any{ - { - "Name": "Shahzad", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Shahzad", + }, }, }, }, diff --git a/tests/integration/net/simple/peer/with_update_restart_test.go b/tests/integration/net/simple/peer/with_update_restart_test.go index 2f68870be4..92c44dd7b3 100644 --- a/tests/integration/net/simple/peer/with_update_restart_test.go +++ b/tests/integration/net/simple/peer/with_update_restart_test.go @@ -57,9 +57,11 @@ func TestP2PWithSingleDocumentSingleUpdateFromChildAndRestart(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(60), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(60), + }, }, }, }, diff --git a/tests/integration/net/simple/peer/with_update_test.go b/tests/integration/net/simple/peer/with_update_test.go index 5a04cd6034..54c7aeb3de 100644 --- a/tests/integration/net/simple/peer/with_update_test.go +++ b/tests/integration/net/simple/peer/with_update_test.go @@ -58,9 +58,11 @@ func TestP2PWithSingleDocumentSingleUpdateFromChild(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(60), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(60), + }, }, }, }, @@ -110,9 +112,11 @@ func TestP2PWithSingleDocumentSingleUpdateFromParent(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(60), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(60), + }, }, }, }, @@ -168,9 +172,11 @@ func TestP2PWithSingleDocumentUpdatePerNode(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": testUtils.AnyOf{int64(45), int64(60)}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": testUtils.AnyOf{int64(45), int64(60)}, + }, }, }, }, @@ -221,9 +227,11 @@ func TestP2PWithSingleDocumentSingleUpdateDoesNotSyncToNonPeerNode(t *testing.T) Age } }`, - Results: []map[string]any{ - { - "Age": int64(60), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(60), + }, }, }, }, @@ -234,9 +242,11 @@ func TestP2PWithSingleDocumentSingleUpdateDoesNotSyncToNonPeerNode(t *testing.T) Age } }`, - Results: []map[string]any{ - { - "Age": int64(60), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(60), + }, }, }, }, @@ -248,9 +258,11 @@ func TestP2PWithSingleDocumentSingleUpdateDoesNotSyncToNonPeerNode(t *testing.T) Age } }`, - Results: []map[string]any{ - { - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(21), + }, }, }, }, @@ -303,9 +315,11 @@ func TestP2PWithSingleDocumentSingleUpdateDoesNotSyncFromUnmappedNode(t *testing Age } }`, - Results: []map[string]any{ - { - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(21), + }, }, }, }, @@ -317,9 +331,11 @@ func TestP2PWithSingleDocumentSingleUpdateDoesNotSyncFromUnmappedNode(t *testing Age } }`, - Results: []map[string]any{ - { - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(21), + }, }, }, }, @@ -330,9 +346,11 @@ func TestP2PWithSingleDocumentSingleUpdateDoesNotSyncFromUnmappedNode(t *testing Age } }`, - Results: []map[string]any{ - { - "Age": int64(60), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(60), + }, }, }, }, @@ -410,9 +428,11 @@ func TestP2PWithMultipleDocumentUpdatesPerNode(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": testUtils.AnyOf{int64(47), int64(62)}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": testUtils.AnyOf{int64(47), int64(62)}, + }, }, }, }, @@ -473,12 +493,14 @@ func TestP2PWithSingleDocumentSingleUpdateFromChildWithP2PCollection(t *testing. Age } }`, - Results: []map[string]any{ - { - "Age": int64(21), - }, - { - "Age": int64(60), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(21), + }, + { + "Age": int64(60), + }, }, }, }, @@ -589,12 +611,14 @@ func TestP2PWithMultipleDocumentUpdatesPerNodeWithP2PCollection(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": testUtils.AnyOf{int64(47), int64(62)}, - }, - { - "Age": int64(60), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": testUtils.AnyOf{int64(47), int64(62)}, + }, + { + "Age": int64(60), + }, }, }, }, diff --git a/tests/integration/net/simple/peer_replicator/crdt/pcounter_test.go b/tests/integration/net/simple/peer_replicator/crdt/pcounter_test.go index a7b3c67a59..914f8daba3 100644 --- a/tests/integration/net/simple/peer_replicator/crdt/pcounter_test.go +++ b/tests/integration/net/simple/peer_replicator/crdt/pcounter_test.go @@ -61,12 +61,14 @@ func TestP2PPeerReplicatorWithCreate_PCounter_NoError(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "points": int64(0), - }, - { - "points": int64(3000), + Results: map[string]any{ + "Users": []map[string]any{ + { + "points": int64(0), + }, + { + "points": int64(3000), + }, }, }, }, @@ -77,9 +79,11 @@ func TestP2PPeerReplicatorWithCreate_PCounter_NoError(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "points": int64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "points": int64(0), + }, }, }, }, @@ -90,12 +94,14 @@ func TestP2PPeerReplicatorWithCreate_PCounter_NoError(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "points": int64(0), - }, - { - "points": int64(3000), + Results: map[string]any{ + "Users": []map[string]any{ + { + "points": int64(0), + }, + { + "points": int64(3000), + }, }, }, }, @@ -147,9 +153,11 @@ func TestP2PPeerReplicatorWithUpdate_PCounter_NoError(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "points": int64(20), + Results: map[string]any{ + "Users": []map[string]any{ + { + "points": int64(20), + }, }, }, }, diff --git a/tests/integration/net/simple/peer_replicator/crdt/pncounter_test.go b/tests/integration/net/simple/peer_replicator/crdt/pncounter_test.go index 40eba568ba..b990631880 100644 --- a/tests/integration/net/simple/peer_replicator/crdt/pncounter_test.go +++ b/tests/integration/net/simple/peer_replicator/crdt/pncounter_test.go @@ -61,12 +61,14 @@ func TestP2PPeerReplicatorWithCreate_PNCounter_NoError(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "points": int64(0), - }, - { - "points": int64(3000), + Results: map[string]any{ + "Users": []map[string]any{ + { + "points": int64(0), + }, + { + "points": int64(3000), + }, }, }, }, @@ -77,9 +79,11 @@ func TestP2PPeerReplicatorWithCreate_PNCounter_NoError(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "points": int64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "points": int64(0), + }, }, }, }, @@ -90,12 +94,14 @@ func TestP2PPeerReplicatorWithCreate_PNCounter_NoError(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "points": int64(0), - }, - { - "points": int64(3000), + Results: map[string]any{ + "Users": []map[string]any{ + { + "points": int64(0), + }, + { + "points": int64(3000), + }, }, }, }, @@ -147,9 +153,11 @@ func TestP2PPeerReplicatorWithUpdate_PNCounter_NoError(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "points": int64(20), + Results: map[string]any{ + "Users": []map[string]any{ + { + "points": int64(20), + }, }, }, }, diff --git a/tests/integration/net/simple/peer_replicator/with_create_test.go b/tests/integration/net/simple/peer_replicator/with_create_test.go index 3b1f299cfa..bc3ef61e78 100644 --- a/tests/integration/net/simple/peer_replicator/with_create_test.go +++ b/tests/integration/net/simple/peer_replicator/with_create_test.go @@ -61,12 +61,14 @@ func TestP2PPeerReplicatorWithCreate(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(3000), - }, - { - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(3000), + }, + { + "Age": int64(21), + }, }, }, }, @@ -77,9 +79,11 @@ func TestP2PPeerReplicatorWithCreate(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(21), + }, }, }, }, @@ -90,12 +94,14 @@ func TestP2PPeerReplicatorWithCreate(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(3000), - }, - { - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(3000), + }, + { + "Age": int64(21), + }, }, }, }, diff --git a/tests/integration/net/simple/peer_replicator/with_delete_test.go b/tests/integration/net/simple/peer_replicator/with_delete_test.go index 1d73e53da7..efb38243a7 100644 --- a/tests/integration/net/simple/peer_replicator/with_delete_test.go +++ b/tests/integration/net/simple/peer_replicator/with_delete_test.go @@ -60,11 +60,13 @@ func TestP2PPeerReplicatorWithDeleteShowDeleted(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "_deleted": true, - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_deleted": true, + "Name": "John", + "Age": int64(21), + }, }, }, }, diff --git a/tests/integration/net/simple/peer_replicator/with_update_restart_test.go b/tests/integration/net/simple/peer_replicator/with_update_restart_test.go index b908e5ae38..298b18dc13 100644 --- a/tests/integration/net/simple/peer_replicator/with_update_restart_test.go +++ b/tests/integration/net/simple/peer_replicator/with_update_restart_test.go @@ -65,9 +65,11 @@ func TestP2PPeerReplicatorWithUpdateAndRestart(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(60), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(60), + }, }, }, }, diff --git a/tests/integration/net/simple/peer_replicator/with_update_test.go b/tests/integration/net/simple/peer_replicator/with_update_test.go index 7e7e2682b5..f0eb677af3 100644 --- a/tests/integration/net/simple/peer_replicator/with_update_test.go +++ b/tests/integration/net/simple/peer_replicator/with_update_test.go @@ -60,9 +60,11 @@ func TestP2PPeerReplicatorWithUpdate(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(60), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(60), + }, }, }, }, diff --git a/tests/integration/net/simple/replicator/crdt/pcounter_test.go b/tests/integration/net/simple/replicator/crdt/pcounter_test.go index 33ea5d136d..2062b912df 100644 --- a/tests/integration/net/simple/replicator/crdt/pcounter_test.go +++ b/tests/integration/net/simple/replicator/crdt/pcounter_test.go @@ -58,9 +58,11 @@ func TestP2POneToOneReplicatorUpdate_PCounter_NoError(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "points": int64(20), + Results: map[string]any{ + "Users": []map[string]any{ + { + "points": int64(20), + }, }, }, }, diff --git a/tests/integration/net/simple/replicator/crdt/pncounter_test.go b/tests/integration/net/simple/replicator/crdt/pncounter_test.go index 186a524e4e..48d1783504 100644 --- a/tests/integration/net/simple/replicator/crdt/pncounter_test.go +++ b/tests/integration/net/simple/replicator/crdt/pncounter_test.go @@ -58,9 +58,11 @@ func TestP2POneToOneReplicatorUpdate_PNCounter_NoError(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "points": int64(20), + Results: map[string]any{ + "Users": []map[string]any{ + { + "points": int64(20), + }, }, }, }, diff --git a/tests/integration/net/simple/replicator/with_create_add_field_test.go b/tests/integration/net/simple/replicator/with_create_add_field_test.go index f73c731666..456e3bb1b8 100644 --- a/tests/integration/net/simple/replicator/with_create_add_field_test.go +++ b/tests/integration/net/simple/replicator/with_create_add_field_test.go @@ -58,9 +58,11 @@ func TestP2POneToOneReplicatorCreateWithNewFieldSyncsDocsToOlderSchemaVersion(t Name } }`, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, }, @@ -109,9 +111,11 @@ func TestP2POneToOneReplicatorCreateWithNewFieldSyncsDocsToNewerSchemaVersion(t Name } }`, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, }, @@ -161,10 +165,12 @@ func TestP2POneToOneReplicatorCreateWithNewFieldSyncsDocsToUpdatedSchemaVersion( Email } }`, - Results: []map[string]any{ - { - "Name": "John", - "Email": "imnotyourbuddyguy@source.ca", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Email": "imnotyourbuddyguy@source.ca", + }, }, }, }, diff --git a/tests/integration/net/simple/replicator/with_create_restart_test.go b/tests/integration/net/simple/replicator/with_create_restart_test.go index 92ad213dd0..a5a52d1ebc 100644 --- a/tests/integration/net/simple/replicator/with_create_restart_test.go +++ b/tests/integration/net/simple/replicator/with_create_restart_test.go @@ -51,9 +51,11 @@ func TestP2POneToOneReplicatorWithRestart(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(21), + }, }, }, }, diff --git a/tests/integration/net/simple/replicator/with_create_test.go b/tests/integration/net/simple/replicator/with_create_test.go index 08ef2baeec..1eab640b83 100644 --- a/tests/integration/net/simple/replicator/with_create_test.go +++ b/tests/integration/net/simple/replicator/with_create_test.go @@ -51,9 +51,11 @@ func TestP2POneToOneReplicator(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(21), + }, }, }, }, @@ -96,9 +98,11 @@ func TestP2POneToOneReplicatorDoesNotSyncExisting(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(21), + }, }, }, }, @@ -142,7 +146,9 @@ func TestP2POneToOneReplicatorDoesNotSyncFromTargetToSource(t *testing.T) { Age } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -190,7 +196,9 @@ func TestP2POneToOneReplicatorDoesNotSyncFromDeletedReplicator(t *testing.T) { Age } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -235,9 +243,11 @@ func TestP2POneToManyReplicator(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(21), + }, }, }, }, @@ -282,9 +292,11 @@ func TestP2POneToOneOfManyReplicator(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(21), + }, }, }, }, @@ -295,9 +307,11 @@ func TestP2POneToOneOfManyReplicator(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(21), + }, }, }, }, @@ -309,7 +323,9 @@ func TestP2POneToOneOfManyReplicator(t *testing.T) { } }`, // As node[2] was not configured, John should not be synced to it - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -357,12 +373,14 @@ func TestP2POneToOneReplicatorManyDocs(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(22), - }, - { - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(22), + }, + { + "Age": int64(21), + }, }, }, }, @@ -417,12 +435,14 @@ func TestP2POneToManyReplicatorManyDocs(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(22), - }, - { - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(22), + }, + { + "Age": int64(21), + }, }, }, }, @@ -483,14 +503,16 @@ func TestP2POneToOneReplicatorOrderIndependent(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "_docID": "bae-0b2f15e5-bfe7-5cb7-8045-471318d7dbc3", - "age": int64(21), - "name": "John", - "_version": []map[string]any{ - { - "schemaVersionId": "bafkreihhd6bqrjhl5zidwztgxzeseveplv3cj3fwtn3unjkdx7j2vr2vrq", + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-0b2f15e5-bfe7-5cb7-8045-471318d7dbc3", + "age": int64(21), + "name": "John", + "_version": []map[string]any{ + { + "schemaVersionId": "bafkreihhd6bqrjhl5zidwztgxzeseveplv3cj3fwtn3unjkdx7j2vr2vrq", + }, }, }, }, @@ -545,12 +567,14 @@ func TestP2POneToOneReplicatorOrderIndependentDirectCreate(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "_docID": "bae-0b2f15e5-bfe7-5cb7-8045-471318d7dbc3", - "_version": []map[string]any{ - { - "schemaVersionId": "bafkreihhd6bqrjhl5zidwztgxzeseveplv3cj3fwtn3unjkdx7j2vr2vrq", + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-0b2f15e5-bfe7-5cb7-8045-471318d7dbc3", + "_version": []map[string]any{ + { + "schemaVersionId": "bafkreihhd6bqrjhl5zidwztgxzeseveplv3cj3fwtn3unjkdx7j2vr2vrq", + }, }, }, }, diff --git a/tests/integration/net/simple/replicator/with_create_update_test.go b/tests/integration/net/simple/replicator/with_create_update_test.go index a8b259d46e..a47c0fd0d5 100644 --- a/tests/integration/net/simple/replicator/with_create_update_test.go +++ b/tests/integration/net/simple/replicator/with_create_update_test.go @@ -59,9 +59,11 @@ func TestP2POneToOneReplicatorWithCreateWithUpdate(t *testing.T) { Age } }`, - Results: []map[string]any{ - { - "Age": int64(60), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(60), + }, }, }, }, @@ -116,9 +118,11 @@ func TestP2POneToOneReplicatorWithCreateWithUpdateOnRecipientNode(t *testing.T) Age } }`, - Results: []map[string]any{ - { - "Age": int64(60), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(60), + }, }, }, }, @@ -180,9 +184,11 @@ func TestP2POneToOneReplicatorDoesNotUpdateDocExistingOnlyOnTarget(t *testing.T) Name } }`, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, }, diff --git a/tests/integration/net/simple/replicator/with_delete_test.go b/tests/integration/net/simple/replicator/with_delete_test.go index 89a715d356..535b22427e 100644 --- a/tests/integration/net/simple/replicator/with_delete_test.go +++ b/tests/integration/net/simple/replicator/with_delete_test.go @@ -58,11 +58,13 @@ func TestP2POneToOneReplicatorDeletesDocCreatedBeforeReplicatorConfig(t *testing Age } }`, - Results: []map[string]any{ - { - "_deleted": true, - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_deleted": true, + "Name": "John", + "Age": int64(21), + }, }, }, }, @@ -112,11 +114,13 @@ func TestP2POneToOneReplicatorDeletesDocCreatedBeforeReplicatorConfigWithNodesIn Age } }`, - Results: []map[string]any{ - { - "_deleted": true, - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_deleted": true, + "Name": "John", + "Age": int64(21), + }, }, }, }, diff --git a/tests/integration/net/simple/replicator/with_update_add_field_test.go b/tests/integration/net/simple/replicator/with_update_add_field_test.go index 52f67d324d..ae0e86d2b4 100644 --- a/tests/integration/net/simple/replicator/with_update_add_field_test.go +++ b/tests/integration/net/simple/replicator/with_update_add_field_test.go @@ -72,10 +72,12 @@ func TestP2PReplicatorUpdateWithNewFieldSyncsDocsToOlderSchemaVersionMultistep(t Email } }`, - Results: []map[string]any{ - { - "Name": "Shahzad", - "Email": "imnotyourbuddyguy@source.ca", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Shahzad", + "Email": "imnotyourbuddyguy@source.ca", + }, }, }, }, @@ -87,9 +89,11 @@ func TestP2PReplicatorUpdateWithNewFieldSyncsDocsToOlderSchemaVersionMultistep(t Name } }`, - Results: []map[string]any{ - { - "Name": "Shahzad", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Shahzad", + }, }, }, }, @@ -146,10 +150,12 @@ func TestP2PReplicatorUpdateWithNewFieldSyncsDocsToOlderSchemaVersion(t *testing Email } }`, - Results: []map[string]any{ - { - "Name": "Shahzad", - "Email": "imnotyourbuddyguy@source.ca", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Shahzad", + "Email": "imnotyourbuddyguy@source.ca", + }, }, }, }, @@ -160,9 +166,11 @@ func TestP2PReplicatorUpdateWithNewFieldSyncsDocsToOlderSchemaVersion(t *testing Name } }`, - Results: []map[string]any{ - { - "Name": "Shahzad", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Shahzad", + }, }, }, }, diff --git a/tests/integration/net/simple/replicator/with_update_test.go b/tests/integration/net/simple/replicator/with_update_test.go index 60891f54e3..32175dac3b 100644 --- a/tests/integration/net/simple/replicator/with_update_test.go +++ b/tests/integration/net/simple/replicator/with_update_test.go @@ -58,9 +58,11 @@ func TestP2POneToOneReplicatorUpdatesDocCreatedBeforeReplicatorConfig(t *testing Age } }`, - Results: []map[string]any{ - { - "Age": int64(60), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(60), + }, }, }, }, @@ -110,9 +112,11 @@ func TestP2POneToOneReplicatorUpdatesDocCreatedBeforeReplicatorConfigWithNodesIn Age } }`, - Results: []map[string]any{ - { - "Age": int64(60), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(60), + }, }, }, }, diff --git a/tests/integration/query/commits/simple_test.go b/tests/integration/query/commits/simple_test.go index dfb0fcc0ad..a1be0a7986 100644 --- a/tests/integration/query/commits/simple_test.go +++ b/tests/integration/query/commits/simple_test.go @@ -34,15 +34,17 @@ func TestQueryCommits(t *testing.T) { cid } }`, - Results: []map[string]any{ - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - }, - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - }, - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + }, + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + }, + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + }, }, }, }, @@ -77,24 +79,26 @@ func TestQueryCommitsMultipleDocs(t *testing.T) { cid } }`, - Results: []map[string]any{ - { - "cid": "bafyreihpasbgxcoxmzv5bp6euq3lbaoh5y5wjbbgfthtxqs3nppk36kebq", - }, - { - "cid": "bafyreihe3jydldbt7mvkiae6asrchdxajzkxwid6syi436nmrpcqhwt7xa", - }, - { - "cid": "bafyreihb5eo3luqoojztdmxtg3tdpvm6pc64mkyrzlefbdauker5qlnop4", - }, - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - }, - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - }, - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreihpasbgxcoxmzv5bp6euq3lbaoh5y5wjbbgfthtxqs3nppk36kebq", + }, + { + "cid": "bafyreihe3jydldbt7mvkiae6asrchdxajzkxwid6syi436nmrpcqhwt7xa", + }, + { + "cid": "bafyreihb5eo3luqoojztdmxtg3tdpvm6pc64mkyrzlefbdauker5qlnop4", + }, + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + }, + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + }, + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + }, }, }, }, @@ -123,18 +127,20 @@ func TestQueryCommitsWithSchemaVersionIDField(t *testing.T) { schemaVersionId } }`, - Results: []map[string]any{ - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "schemaVersionId": "bafkreicprhqxzlw3akyssz2v6pifwfueavp7jq2yj3dghapi3qcq6achs4", - }, - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "schemaVersionId": "bafkreicprhqxzlw3akyssz2v6pifwfueavp7jq2yj3dghapi3qcq6achs4", - }, - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "schemaVersionId": "bafkreicprhqxzlw3akyssz2v6pifwfueavp7jq2yj3dghapi3qcq6achs4", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "schemaVersionId": "bafkreicprhqxzlw3akyssz2v6pifwfueavp7jq2yj3dghapi3qcq6achs4", + }, + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "schemaVersionId": "bafkreicprhqxzlw3akyssz2v6pifwfueavp7jq2yj3dghapi3qcq6achs4", + }, + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "schemaVersionId": "bafkreicprhqxzlw3akyssz2v6pifwfueavp7jq2yj3dghapi3qcq6achs4", + }, }, }, }, @@ -163,15 +169,17 @@ func TestQueryCommitsWithFieldNameField(t *testing.T) { } } `, - Results: []map[string]any{ - { - "fieldName": "age", - }, - { - "fieldName": "name", - }, - { - "fieldName": nil, + Results: map[string]any{ + "commits": []map[string]any{ + { + "fieldName": "age", + }, + { + "fieldName": "name", + }, + { + "fieldName": nil, + }, }, }, }, @@ -205,21 +213,23 @@ func TestQueryCommitsWithFieldNameFieldAndUpdate(t *testing.T) { } } `, - Results: []map[string]any{ - { - "fieldName": "age", - }, - { - "fieldName": "age", - }, - { - "fieldName": "name", - }, - { - "fieldName": nil, - }, - { - "fieldName": nil, + Results: map[string]any{ + "commits": []map[string]any{ + { + "fieldName": "age", + }, + { + "fieldName": "age", + }, + { + "fieldName": "name", + }, + { + "fieldName": nil, + }, + { + "fieldName": nil, + }, }, }, }, @@ -248,15 +258,17 @@ func TestQueryCommitsWithFieldIDField(t *testing.T) { } } `, - Results: []map[string]any{ - { - "fieldId": "1", - }, - { - "fieldId": "2", - }, - { - "fieldId": "C", + Results: map[string]any{ + "commits": []map[string]any{ + { + "fieldId": "1", + }, + { + "fieldId": "2", + }, + { + "fieldId": "C", + }, }, }, }, @@ -290,21 +302,23 @@ func TestQueryCommitsWithFieldIDFieldWithUpdate(t *testing.T) { } } `, - Results: []map[string]any{ - { - "fieldId": "1", - }, - { - "fieldId": "1", - }, - { - "fieldId": "2", - }, - { - "fieldId": "C", - }, - { - "fieldId": "C", + Results: map[string]any{ + "commits": []map[string]any{ + { + "fieldId": "1", + }, + { + "fieldId": "1", + }, + { + "fieldId": "2", + }, + { + "fieldId": "C", + }, + { + "fieldId": "C", + }, }, }, }, @@ -347,77 +361,79 @@ func TestQuery_CommitsWithAllFieldsWithUpdate_NoError(t *testing.T) { } } `, - Results: []map[string]any{ - { - "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", - "collectionID": int64(1), - "delta": testUtils.CBORValue(22), - "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", - "fieldId": "1", - "fieldName": "age", - "height": int64(2), - "links": []map[string]any{ - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "name": "_head", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", + "collectionID": int64(1), + "delta": testUtils.CBORValue(22), + "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", + "fieldId": "1", + "fieldName": "age", + "height": int64(2), + "links": []map[string]any{ + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "name": "_head", + }, }, }, - }, - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "collectionID": int64(1), - "delta": testUtils.CBORValue(21), - "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", - "fieldId": "1", - "fieldName": "age", - "height": int64(1), - "links": []map[string]any{}, - }, - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "collectionID": int64(1), - "delta": testUtils.CBORValue("John"), - "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", - "fieldId": "2", - "fieldName": "name", - "height": int64(1), - "links": []map[string]any{}, - }, - { - "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", - "collectionID": int64(1), - "delta": nil, - "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", - "fieldId": "C", - "fieldName": nil, - "height": int64(2), - "links": []map[string]any{ - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "name": "_head", - }, - { - "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", - "name": "age", - }, + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "collectionID": int64(1), + "delta": testUtils.CBORValue(21), + "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", + "fieldId": "1", + "fieldName": "age", + "height": int64(1), + "links": []map[string]any{}, }, - }, - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "collectionID": int64(1), - "delta": nil, - "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", - "fieldId": "C", - "fieldName": nil, - "height": int64(1), - "links": []map[string]any{ - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "name": "name", + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "collectionID": int64(1), + "delta": testUtils.CBORValue("John"), + "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", + "fieldId": "2", + "fieldName": "name", + "height": int64(1), + "links": []map[string]any{}, + }, + { + "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", + "collectionID": int64(1), + "delta": nil, + "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", + "fieldId": "C", + "fieldName": nil, + "height": int64(2), + "links": []map[string]any{ + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "name": "_head", + }, + { + "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", + "name": "age", + }, }, - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "name": "age", + }, + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "collectionID": int64(1), + "delta": nil, + "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", + "fieldId": "C", + "fieldName": nil, + "height": int64(1), + "links": []map[string]any{ + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "name": "name", + }, + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "name": "age", + }, }, }, }, diff --git a/tests/integration/query/commits/with_cid_test.go b/tests/integration/query/commits/with_cid_test.go index 443577ac28..b051e2b289 100644 --- a/tests/integration/query/commits/with_cid_test.go +++ b/tests/integration/query/commits/with_cid_test.go @@ -43,9 +43,11 @@ func TestQueryCommitsWithCid(t *testing.T) { cid } }`, - Results: []map[string]any{ - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + }, }, }, }, @@ -76,9 +78,11 @@ func TestQueryCommitsWithCidForFieldCommit(t *testing.T) { cid } }`, - Results: []map[string]any{ - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + }, }, }, }, @@ -108,7 +112,9 @@ func TestQueryCommitsWithInvalidCid(t *testing.T) { delta } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "commits": []map[string]any{}, + }, }, }, } @@ -136,7 +142,9 @@ func TestQueryCommitsWithInvalidShortCid(t *testing.T) { delta } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "commits": []map[string]any{}, + }, }, }, } @@ -164,7 +172,9 @@ func TestQueryCommitsWithUnknownCid(t *testing.T) { delta } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "commits": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/query/commits/with_collectionid_group_order_test.go b/tests/integration/query/commits/with_collectionid_group_order_test.go index f39fcbd87c..ce083aedfa 100644 --- a/tests/integration/query/commits/with_collectionid_group_order_test.go +++ b/tests/integration/query/commits/with_collectionid_group_order_test.go @@ -41,12 +41,14 @@ func TestQueryCommitsWithCollectionIDGroupedAndOrderedDesc(t *testing.T) { collectionID } }`, - Results: []map[string]any{ - { - "collectionID": int64(2), - }, - { - "collectionID": int64(1), + Results: map[string]any{ + "commits": []map[string]any{ + { + "collectionID": int64(2), + }, + { + "collectionID": int64(1), + }, }, }, }, @@ -81,12 +83,14 @@ func TestQueryCommitsWithCollectionIDGroupedAndOrderedAs(t *testing.T) { collectionID } }`, - Results: []map[string]any{ - { - "collectionID": int64(1), - }, - { - "collectionID": int64(2), + Results: map[string]any{ + "commits": []map[string]any{ + { + "collectionID": int64(1), + }, + { + "collectionID": int64(2), + }, }, }, }, diff --git a/tests/integration/query/commits/with_collectionid_prop_test.go b/tests/integration/query/commits/with_collectionid_prop_test.go index 91d4d60373..261ac937c3 100644 --- a/tests/integration/query/commits/with_collectionid_prop_test.go +++ b/tests/integration/query/commits/with_collectionid_prop_test.go @@ -41,21 +41,23 @@ func TestQueryCommitsWithCollectionID(t *testing.T) { collectionID } }`, - Results: []map[string]any{ - { - "collectionID": int64(1), - }, - { - "collectionID": int64(1), - }, - { - "collectionID": int64(1), - }, - { - "collectionID": int64(2), - }, - { - "collectionID": int64(2), + Results: map[string]any{ + "commits": []map[string]any{ + { + "collectionID": int64(1), + }, + { + "collectionID": int64(1), + }, + { + "collectionID": int64(1), + }, + { + "collectionID": int64(2), + }, + { + "collectionID": int64(2), + }, }, }, }, diff --git a/tests/integration/query/commits/with_depth_test.go b/tests/integration/query/commits/with_depth_test.go index a55828115f..71d805307f 100644 --- a/tests/integration/query/commits/with_depth_test.go +++ b/tests/integration/query/commits/with_depth_test.go @@ -34,15 +34,17 @@ func TestQueryCommitsWithDepth1(t *testing.T) { cid } }`, - Results: []map[string]any{ - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - }, - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - }, - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + }, + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + }, + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + }, }, }, }, @@ -78,20 +80,22 @@ func TestQueryCommitsWithDepth1WithUpdate(t *testing.T) { height } }`, - Results: []map[string]any{ - { - // "Age" field head - "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", - "height": int64(2), - }, - { - // "Name" field head (unchanged from create) - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "height": int64(1), - }, - { - "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", - "height": int64(2), + Results: map[string]any{ + "commits": []map[string]any{ + { + // "Age" field head + "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", + "height": int64(2), + }, + { + // "Name" field head (unchanged from create) + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "height": int64(1), + }, + { + "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", + "height": int64(2), + }, }, }, }, @@ -134,31 +138,33 @@ func TestQueryCommitsWithDepth2WithUpdate(t *testing.T) { height } }`, - Results: []map[string]any{ - { - // Composite head - "cid": "bafyreibpiyrugj4gku336wp5lvcw3fgyxqpjvugm3t4z7v5h3ulwxs3x2y", - "height": int64(3), - }, - { - // Composite head -1 - "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", - "height": int64(2), - }, - { - // "Name" field head (unchanged from create) - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "height": int64(1), - }, - { - // "Age" field head - "cid": "bafyreieydjk3sqrxs5aqhsiy7ct25vu5qtbtpmzbytzee4apeidx6dq7je", - "height": int64(3), - }, - { - // "Age" field head -1 - "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", - "height": int64(2), + Results: map[string]any{ + "commits": []map[string]any{ + { + // Composite head + "cid": "bafyreibpiyrugj4gku336wp5lvcw3fgyxqpjvugm3t4z7v5h3ulwxs3x2y", + "height": int64(3), + }, + { + // Composite head -1 + "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", + "height": int64(2), + }, + { + // "Name" field head (unchanged from create) + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "height": int64(1), + }, + { + // "Age" field head + "cid": "bafyreieydjk3sqrxs5aqhsiy7ct25vu5qtbtpmzbytzee4apeidx6dq7je", + "height": int64(3), + }, + { + // "Age" field head -1 + "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", + "height": int64(2), + }, }, }, }, @@ -193,24 +199,26 @@ func TestQueryCommitsWithDepth1AndMultipleDocs(t *testing.T) { cid } }`, - Results: []map[string]any{ - { - "cid": "bafyreibzfxudkhrcsz7lsgtb637gzyegsdkehlugvb2dg76smhhnkg46dm", - }, - { - "cid": "bafyreiabiarng2rcvkfgoirnnyy3yvd7yi3c66akovkbmhivrxvdawtcna", - }, - { - "cid": "bafyreibubqh6ltxbxmtrtd5oczaekcfw5knqfyocnwkdwhpjatl7johoue", - }, - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - }, - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - }, - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreibzfxudkhrcsz7lsgtb637gzyegsdkehlugvb2dg76smhhnkg46dm", + }, + { + "cid": "bafyreiabiarng2rcvkfgoirnnyy3yvd7yi3c66akovkbmhivrxvdawtcna", + }, + { + "cid": "bafyreibubqh6ltxbxmtrtd5oczaekcfw5knqfyocnwkdwhpjatl7johoue", + }, + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + }, + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + }, + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + }, }, }, }, diff --git a/tests/integration/query/commits/with_doc_id_cid_test.go b/tests/integration/query/commits/with_doc_id_cid_test.go index 7cbdc10307..bba28526a8 100644 --- a/tests/integration/query/commits/with_doc_id_cid_test.go +++ b/tests/integration/query/commits/with_doc_id_cid_test.go @@ -37,7 +37,9 @@ func TestQueryCommitsWithDocIDAndCidForDifferentDoc(t *testing.T) { cid } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "commits": []map[string]any{}, + }, }, }, } @@ -73,7 +75,9 @@ func TestQueryCommitsWithDocIDAndCidForDifferentDocWithUpdate(t *testing.T) { cid } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "commits": []map[string]any{}, + }, }, }, } @@ -109,9 +113,11 @@ func TestQueryCommitsWithDocIDAndCidWithUpdate(t *testing.T) { cid } }`, - Results: []map[string]any{ - { - "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", + }, }, }, }, diff --git a/tests/integration/query/commits/with_doc_id_count_test.go b/tests/integration/query/commits/with_doc_id_count_test.go index d3a7ca0fbb..607822abec 100644 --- a/tests/integration/query/commits/with_doc_id_count_test.go +++ b/tests/integration/query/commits/with_doc_id_count_test.go @@ -35,18 +35,20 @@ func TestQueryCommitsWithDocIDAndLinkCount(t *testing.T) { _count(field: links) } }`, - Results: []map[string]any{ - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "_count": 0, - }, - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "_count": 0, - }, - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "_count": 2, + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "_count": 0, + }, + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "_count": 0, + }, + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "_count": 2, + }, }, }, }, diff --git a/tests/integration/query/commits/with_doc_id_field_test.go b/tests/integration/query/commits/with_doc_id_field_test.go index 84821938a0..3b36e9f9d8 100644 --- a/tests/integration/query/commits/with_doc_id_field_test.go +++ b/tests/integration/query/commits/with_doc_id_field_test.go @@ -34,7 +34,9 @@ func TestQueryCommitsWithDocIDAndUnknownField(t *testing.T) { cid } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "commits": []map[string]any{}, + }, }, }, } @@ -60,7 +62,9 @@ func TestQueryCommitsWithDocIDAndUnknownFieldId(t *testing.T) { cid } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "commits": []map[string]any{}, + }, }, }, } @@ -88,7 +92,9 @@ func TestQueryCommitsWithDocIDAndField(t *testing.T) { cid } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "commits": []map[string]any{}, + }, }, }, } @@ -116,9 +122,11 @@ func TestQueryCommitsWithDocIDAndFieldId(t *testing.T) { cid } }`, - Results: []map[string]any{ - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + }, }, }, }, @@ -148,9 +156,11 @@ func TestQueryCommitsWithDocIDAndCompositeFieldId(t *testing.T) { cid } }`, - Results: []map[string]any{ - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + }, }, }, }, diff --git a/tests/integration/query/commits/with_doc_id_group_order_test.go b/tests/integration/query/commits/with_doc_id_group_order_test.go index 5443b4e427..0314c43047 100644 --- a/tests/integration/query/commits/with_doc_id_group_order_test.go +++ b/tests/integration/query/commits/with_doc_id_group_order_test.go @@ -41,12 +41,14 @@ func TestQueryCommitsOrderedAndGroupedByDocID(t *testing.T) { docID } }`, - Results: []map[string]any{ - { - "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", - }, - { - "docID": "bae-a839588e-e2e5-5ede-bb91-ffe6871645cb", + Results: map[string]any{ + "commits": []map[string]any{ + { + "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", + }, + { + "docID": "bae-a839588e-e2e5-5ede-bb91-ffe6871645cb", + }, }, }, }, diff --git a/tests/integration/query/commits/with_doc_id_limit_offset_test.go b/tests/integration/query/commits/with_doc_id_limit_offset_test.go index 68cca30bdc..2fb095a263 100644 --- a/tests/integration/query/commits/with_doc_id_limit_offset_test.go +++ b/tests/integration/query/commits/with_doc_id_limit_offset_test.go @@ -55,12 +55,14 @@ func TestQueryCommitsWithDocIDAndLimitAndOffset(t *testing.T) { cid } }`, - Results: []map[string]any{ - { - "cid": "bafyreibpiyrugj4gku336wp5lvcw3fgyxqpjvugm3t4z7v5h3ulwxs3x2y", - }, - { - "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreibpiyrugj4gku336wp5lvcw3fgyxqpjvugm3t4z7v5h3ulwxs3x2y", + }, + { + "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", + }, }, }, }, diff --git a/tests/integration/query/commits/with_doc_id_limit_test.go b/tests/integration/query/commits/with_doc_id_limit_test.go index 090417fc64..5a569f3295 100644 --- a/tests/integration/query/commits/with_doc_id_limit_test.go +++ b/tests/integration/query/commits/with_doc_id_limit_test.go @@ -48,12 +48,14 @@ func TestQueryCommitsWithDocIDAndLimit(t *testing.T) { cid } }`, - Results: []map[string]any{ - { - "cid": "bafyreibpiyrugj4gku336wp5lvcw3fgyxqpjvugm3t4z7v5h3ulwxs3x2y", - }, - { - "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreibpiyrugj4gku336wp5lvcw3fgyxqpjvugm3t4z7v5h3ulwxs3x2y", + }, + { + "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", + }, }, }, }, diff --git a/tests/integration/query/commits/with_doc_id_order_limit_offset_test.go b/tests/integration/query/commits/with_doc_id_order_limit_offset_test.go index 4260940370..389ec5c291 100644 --- a/tests/integration/query/commits/with_doc_id_order_limit_offset_test.go +++ b/tests/integration/query/commits/with_doc_id_order_limit_offset_test.go @@ -56,14 +56,16 @@ func TestQueryCommitsWithDocIDAndOrderAndLimitAndOffset(t *testing.T) { height } }`, - Results: []map[string]any{ - { - "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", - "height": int64(2), - }, - { - "cid": "bafyreibpiyrugj4gku336wp5lvcw3fgyxqpjvugm3t4z7v5h3ulwxs3x2y", - "height": int64(3), + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", + "height": int64(2), + }, + { + "cid": "bafyreibpiyrugj4gku336wp5lvcw3fgyxqpjvugm3t4z7v5h3ulwxs3x2y", + "height": int64(3), + }, }, }, }, diff --git a/tests/integration/query/commits/with_doc_id_order_test.go b/tests/integration/query/commits/with_doc_id_order_test.go index 922c87dc7b..ba0ff67def 100644 --- a/tests/integration/query/commits/with_doc_id_order_test.go +++ b/tests/integration/query/commits/with_doc_id_order_test.go @@ -42,26 +42,28 @@ func TestQueryCommitsWithDocIDAndOrderHeightDesc(t *testing.T) { height } }`, - Results: []map[string]any{ - { - "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", - "height": int64(2), - }, - { - "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", - "height": int64(2), - }, - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "height": int64(1), - }, - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "height": int64(1), - }, - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "height": int64(1), + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", + "height": int64(2), + }, + { + "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", + "height": int64(2), + }, + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "height": int64(1), + }, + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "height": int64(1), + }, + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "height": int64(1), + }, }, }, }, @@ -97,26 +99,28 @@ func TestQueryCommitsWithDocIDAndOrderHeightAsc(t *testing.T) { height } }`, - Results: []map[string]any{ - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "height": int64(1), - }, - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "height": int64(1), - }, - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "height": int64(1), - }, - { - "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", - "height": int64(2), - }, - { - "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", - "height": int64(2), + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "height": int64(1), + }, + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "height": int64(1), + }, + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "height": int64(1), + }, + { + "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", + "height": int64(2), + }, + { + "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", + "height": int64(2), + }, }, }, }, @@ -152,26 +156,28 @@ func TestQueryCommitsWithDocIDAndOrderCidDesc(t *testing.T) { height } }`, - Results: []map[string]any{ - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "height": int64(1), - }, - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "height": int64(1), - }, - { - "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", - "height": int64(2), - }, - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "height": int64(1), - }, - { - "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", - "height": int64(2), + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "height": int64(1), + }, + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "height": int64(1), + }, + { + "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", + "height": int64(2), + }, + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "height": int64(1), + }, + { + "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", + "height": int64(2), + }, }, }, }, @@ -207,26 +213,28 @@ func TestQueryCommitsWithDocIDAndOrderCidAsc(t *testing.T) { height } }`, - Results: []map[string]any{ - { - "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", - "height": int64(2), - }, - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "height": int64(1), - }, - { - "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", - "height": int64(2), - }, - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "height": int64(1), - }, - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "height": int64(1), + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", + "height": int64(2), + }, + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "height": int64(1), + }, + { + "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", + "height": int64(2), + }, + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "height": int64(1), + }, + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "height": int64(1), + }, }, }, }, @@ -276,42 +284,44 @@ func TestQueryCommitsWithDocIDAndOrderAndMultiUpdatesCidAsc(t *testing.T) { height } }`, - Results: []map[string]any{ - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "height": int64(1), - }, - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "height": int64(1), - }, - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "height": int64(1), - }, - { - "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", - "height": int64(2), - }, - { - "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", - "height": int64(2), - }, - { - "cid": "bafyreibpiyrugj4gku336wp5lvcw3fgyxqpjvugm3t4z7v5h3ulwxs3x2y", - "height": int64(3), - }, - { - "cid": "bafyreieydjk3sqrxs5aqhsiy7ct25vu5qtbtpmzbytzee4apeidx6dq7je", - "height": int64(3), - }, - { - "cid": "bafyreic6rjkn7qsoxpboviode2l64ahg4yajsrb3p25zeooisnaxcweccu", - "height": int64(4), - }, - { - "cid": "bafyreieifkfzufdvlvni4o5pbdtuvm3w6x4fnqyelyq2owvsliiwjvddpi", - "height": int64(4), + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "height": int64(1), + }, + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "height": int64(1), + }, + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "height": int64(1), + }, + { + "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", + "height": int64(2), + }, + { + "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", + "height": int64(2), + }, + { + "cid": "bafyreibpiyrugj4gku336wp5lvcw3fgyxqpjvugm3t4z7v5h3ulwxs3x2y", + "height": int64(3), + }, + { + "cid": "bafyreieydjk3sqrxs5aqhsiy7ct25vu5qtbtpmzbytzee4apeidx6dq7je", + "height": int64(3), + }, + { + "cid": "bafyreic6rjkn7qsoxpboviode2l64ahg4yajsrb3p25zeooisnaxcweccu", + "height": int64(4), + }, + { + "cid": "bafyreieifkfzufdvlvni4o5pbdtuvm3w6x4fnqyelyq2owvsliiwjvddpi", + "height": int64(4), + }, }, }, }, diff --git a/tests/integration/query/commits/with_doc_id_prop_test.go b/tests/integration/query/commits/with_doc_id_prop_test.go index 1d370ab27a..02ad9fe50e 100644 --- a/tests/integration/query/commits/with_doc_id_prop_test.go +++ b/tests/integration/query/commits/with_doc_id_prop_test.go @@ -34,15 +34,17 @@ func TestQueryCommitsWithDocIDProperty(t *testing.T) { docID } }`, - Results: []map[string]any{ - { - "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", - }, - { - "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", - }, - { - "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", + Results: map[string]any{ + "commits": []map[string]any{ + { + "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", + }, + { + "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", + }, + { + "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", + }, }, }, }, diff --git a/tests/integration/query/commits/with_doc_id_test.go b/tests/integration/query/commits/with_doc_id_test.go index c716cd296e..26fa6136af 100644 --- a/tests/integration/query/commits/with_doc_id_test.go +++ b/tests/integration/query/commits/with_doc_id_test.go @@ -34,7 +34,9 @@ func TestQueryCommitsWithUnknownDocID(t *testing.T) { cid } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "commits": []map[string]any{}, + }, }, }, } @@ -60,15 +62,17 @@ func TestQueryCommitsWithDocID(t *testing.T) { cid } }`, - Results: []map[string]any{ - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - }, - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - }, - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + }, + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + }, + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + }, }, }, }, @@ -100,25 +104,27 @@ func TestQueryCommitsWithDocIDAndLinks(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "links": []map[string]any{}, - }, - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "links": []map[string]any{}, - }, - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "links": []map[string]any{ - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "name": "name", - }, - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "name": "age", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "links": []map[string]any{}, + }, + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "links": []map[string]any{}, + }, + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "links": []map[string]any{ + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "name": "name", + }, + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "name": "age", + }, }, }, }, @@ -156,26 +162,28 @@ func TestQueryCommitsWithDocIDAndUpdate(t *testing.T) { height } }`, - Results: []map[string]any{ - { - "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", - "height": int64(2), - }, - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "height": int64(1), - }, - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "height": int64(1), - }, - { - "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", - "height": int64(2), - }, - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "height": int64(1), + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", + "height": int64(2), + }, + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "height": int64(1), + }, + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "height": int64(1), + }, + { + "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", + "height": int64(2), + }, + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "height": int64(1), + }, }, }, }, @@ -217,47 +225,49 @@ func TestQueryCommitsWithDocIDAndUpdateAndLinks(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", - "links": []map[string]any{ - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "name": "_head", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", + "links": []map[string]any{ + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "name": "_head", + }, }, }, - }, - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "links": []map[string]any{}, - }, - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "links": []map[string]any{}, - }, - { - "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", - "links": []map[string]any{ - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "name": "_head", - }, - { - "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", - "name": "age", - }, + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "links": []map[string]any{}, }, - }, - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "links": []map[string]any{ - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "name": "name", + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "links": []map[string]any{}, + }, + { + "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", + "links": []map[string]any{ + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "name": "_head", + }, + { + "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", + "name": "age", + }, }, - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "name": "age", + }, + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "links": []map[string]any{ + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "name": "name", + }, + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "name": "age", + }, }, }, }, diff --git a/tests/integration/query/commits/with_doc_id_typename_test.go b/tests/integration/query/commits/with_doc_id_typename_test.go index a26580d113..c825933d83 100644 --- a/tests/integration/query/commits/with_doc_id_typename_test.go +++ b/tests/integration/query/commits/with_doc_id_typename_test.go @@ -35,18 +35,20 @@ func TestQueryCommitsWithDocIDWithTypeName(t *testing.T) { __typename } }`, - Results: []map[string]any{ - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "__typename": "Commit", - }, - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "__typename": "Commit", - }, - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "__typename": "Commit", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "__typename": "Commit", + }, + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "__typename": "Commit", + }, + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "__typename": "Commit", + }, }, }, }, diff --git a/tests/integration/query/commits/with_field_test.go b/tests/integration/query/commits/with_field_test.go index 48c5225ca5..43d23c462c 100644 --- a/tests/integration/query/commits/with_field_test.go +++ b/tests/integration/query/commits/with_field_test.go @@ -36,7 +36,9 @@ func TestQueryCommitsWithField(t *testing.T) { cid } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "commits": []map[string]any{}, + }, }, }, } @@ -64,9 +66,11 @@ func TestQueryCommitsWithFieldId(t *testing.T) { cid } }`, - Results: []map[string]any{ - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + }, }, }, }, @@ -96,9 +100,11 @@ func TestQueryCommitsWithCompositeFieldId(t *testing.T) { cid } }`, - Results: []map[string]any{ - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + }, }, }, }, @@ -129,10 +135,12 @@ func TestQueryCommitsWithCompositeFieldIdWithReturnedSchemaVersionID(t *testing. schemaVersionId } }`, - Results: []map[string]any{ - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "schemaVersionId": "bafkreicprhqxzlw3akyssz2v6pifwfueavp7jq2yj3dghapi3qcq6achs4", + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "schemaVersionId": "bafkreicprhqxzlw3akyssz2v6pifwfueavp7jq2yj3dghapi3qcq6achs4", + }, }, }, }, diff --git a/tests/integration/query/commits/with_group_test.go b/tests/integration/query/commits/with_group_test.go index 5405ea49c8..372097932c 100644 --- a/tests/integration/query/commits/with_group_test.go +++ b/tests/integration/query/commits/with_group_test.go @@ -41,12 +41,14 @@ func TestQueryCommitsWithGroupBy(t *testing.T) { height } }`, - Results: []map[string]any{ - { - "height": int64(2), - }, - { - "height": int64(1), + Results: map[string]any{ + "commits": []map[string]any{ + { + "height": int64(2), + }, + { + "height": int64(1), + }, }, }, }, @@ -84,29 +86,31 @@ func TestQueryCommitsWithGroupByHeightWithChild(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "height": int64(2), - "_group": []map[string]any{ - { - "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", - }, - { - "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", + Results: map[string]any{ + "commits": []map[string]any{ + { + "height": int64(2), + "_group": []map[string]any{ + { + "cid": "bafyreiay56ley5dvsptso37fsonfcrtbuphwlfhi67d2y52vzzexba6vua", + }, + { + "cid": "bafyreicsavx5oblk6asfoqyssz4ge2gf5ekfouvi7o6l7adly275op5oje", + }, }, }, - }, - { - "height": int64(1), - "_group": []map[string]any{ - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - }, - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - }, - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + { + "height": int64(1), + "_group": []map[string]any{ + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + }, + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + }, + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + }, }, }, }, @@ -140,28 +144,30 @@ func TestQueryCommitsWithGroupByCidWithChild(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "_group": []map[string]any{ - { - "height": int64(1), + Results: map[string]any{ + "commits": []map[string]any{ + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "_group": []map[string]any{ + { + "height": int64(1), + }, }, }, - }, - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "_group": []map[string]any{ - { - "height": int64(1), + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "_group": []map[string]any{ + { + "height": int64(1), + }, }, }, - }, - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "_group": []map[string]any{ - { - "height": int64(1), + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "_group": []map[string]any{ + { + "height": int64(1), + }, }, }, }, @@ -212,12 +218,14 @@ func TestQueryCommitsWithGroupByDocID(t *testing.T) { docID } }`, - Results: []map[string]any{ - { - "docID": "bae-a839588e-e2e5-5ede-bb91-ffe6871645cb", - }, - { - "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", + Results: map[string]any{ + "commits": []map[string]any{ + { + "docID": "bae-a839588e-e2e5-5ede-bb91-ffe6871645cb", + }, + { + "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", + }, }, }, }, @@ -252,15 +260,17 @@ func TestQueryCommitsWithGroupByFieldName(t *testing.T) { fieldName } }`, - Results: []map[string]any{ - { - "fieldName": "age", - }, - { - "fieldName": "name", - }, - { - "fieldName": nil, + Results: map[string]any{ + "commits": []map[string]any{ + { + "fieldName": "age", + }, + { + "fieldName": "name", + }, + { + "fieldName": nil, + }, }, }, }, @@ -298,34 +308,36 @@ func TestQueryCommitsWithGroupByFieldNameWithChild(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "fieldName": "age", - "_group": []map[string]any{ - { - "height": int64(2), - }, - { - "height": int64(1), + Results: map[string]any{ + "commits": []map[string]any{ + { + "fieldName": "age", + "_group": []map[string]any{ + { + "height": int64(2), + }, + { + "height": int64(1), + }, }, }, - }, - { - "fieldName": "name", - "_group": []map[string]any{ - { - "height": int64(1), + { + "fieldName": "name", + "_group": []map[string]any{ + { + "height": int64(1), + }, }, }, - }, - { - "fieldName": nil, - "_group": []map[string]any{ - { - "height": int64(2), - }, - { - "height": int64(1), + { + "fieldName": nil, + "_group": []map[string]any{ + { + "height": int64(2), + }, + { + "height": int64(1), + }, }, }, }, @@ -362,15 +374,17 @@ func TestQueryCommitsWithGroupByFieldID(t *testing.T) { fieldId } }`, - Results: []map[string]any{ - { - "fieldId": "1", - }, - { - "fieldId": "2", - }, - { - "fieldId": "C", + Results: map[string]any{ + "commits": []map[string]any{ + { + "fieldId": "1", + }, + { + "fieldId": "2", + }, + { + "fieldId": "C", + }, }, }, }, @@ -408,34 +422,36 @@ func TestQueryCommitsWithGroupByFieldIDWithChild(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "fieldId": "1", - "_group": []map[string]any{ - { - "height": int64(2), - }, - { - "height": int64(1), + Results: map[string]any{ + "commits": []map[string]any{ + { + "fieldId": "1", + "_group": []map[string]any{ + { + "height": int64(2), + }, + { + "height": int64(1), + }, }, }, - }, - { - "fieldId": "2", - "_group": []map[string]any{ - { - "height": int64(1), + { + "fieldId": "2", + "_group": []map[string]any{ + { + "height": int64(1), + }, }, }, - }, - { - "fieldId": "C", - "_group": []map[string]any{ - { - "height": int64(2), - }, - { - "height": int64(1), + { + "fieldId": "C", + "_group": []map[string]any{ + { + "height": int64(2), + }, + { + "height": int64(1), + }, }, }, }, diff --git a/tests/integration/query/inline_array/simple_test.go b/tests/integration/query/inline_array/simple_test.go index 16ade304fb..f266b114ba 100644 --- a/tests/integration/query/inline_array/simple_test.go +++ b/tests/integration/query/inline_array/simple_test.go @@ -36,10 +36,12 @@ func TestQueryInlineArrayWithBooleans(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "likedIndexes": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "likedIndexes": nil, + }, }, }, }, @@ -59,10 +61,12 @@ func TestQueryInlineArrayWithBooleans(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "likedIndexes": []bool{}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "likedIndexes": []bool{}, + }, }, }, }, @@ -82,10 +86,12 @@ func TestQueryInlineArrayWithBooleans(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "likedIndexes": []bool{true, true, false, true}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "likedIndexes": []bool{true, true, false, true}, + }, }, }, }, @@ -113,14 +119,16 @@ func TestQueryInlineArrayWithNillableBooleans(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "indexLikesDislikes": []immutable.Option[bool]{ - immutable.Some(true), - immutable.Some(true), - immutable.Some(false), - immutable.None[bool](), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "indexLikesDislikes": []immutable.Option[bool]{ + immutable.Some(true), + immutable.Some(true), + immutable.Some(false), + immutable.None[bool](), + }, }, }, }, @@ -146,10 +154,12 @@ func TestQueryInlineArrayWithIntegers(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "favouriteIntegers": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "favouriteIntegers": nil, + }, }, }, }, @@ -169,10 +179,12 @@ func TestQueryInlineArrayWithIntegers(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "favouriteIntegers": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "favouriteIntegers": nil, + }, }, }, }, @@ -192,10 +204,12 @@ func TestQueryInlineArrayWithIntegers(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "favouriteIntegers": []int64{}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "favouriteIntegers": []int64{}, + }, }, }, }, @@ -215,10 +229,12 @@ func TestQueryInlineArrayWithIntegers(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "favouriteIntegers": []int64{1, 2, 3, 5, 8}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "favouriteIntegers": []int64{1, 2, 3, 5, 8}, + }, }, }, }, @@ -238,10 +254,12 @@ func TestQueryInlineArrayWithIntegers(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Andy", - "favouriteIntegers": []int64{-1, -2, -3, -5, -8}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Andy", + "favouriteIntegers": []int64{-1, -2, -3, -5, -8}, + }, }, }, }, @@ -261,10 +279,12 @@ func TestQueryInlineArrayWithIntegers(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "favouriteIntegers": []int64{-1, 2, -1, 1, 0}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "favouriteIntegers": []int64{-1, 2, -1, 1, 0}, + }, }, }, }, @@ -292,15 +312,17 @@ func TestQueryInlineArrayWithNillableInts(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "testScores": []immutable.Option[int64]{ - immutable.Some[int64](-1), - immutable.None[int64](), - immutable.Some[int64](-1), - immutable.Some[int64](2), - immutable.Some[int64](0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "testScores": []immutable.Option[int64]{ + immutable.Some[int64](-1), + immutable.None[int64](), + immutable.Some[int64](-1), + immutable.Some[int64](2), + immutable.Some[int64](0), + }, }, }, }, @@ -327,10 +349,12 @@ func TestQueryInlineArrayWithFloats(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "favouriteFloats": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "favouriteFloats": nil, + }, }, }, }, @@ -350,10 +374,12 @@ func TestQueryInlineArrayWithFloats(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "favouriteFloats": []float64{}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "favouriteFloats": []float64{}, + }, }, }, }, @@ -373,10 +399,12 @@ func TestQueryInlineArrayWithFloats(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "favouriteFloats": []float64{3.1425, 0.00000000001, 10}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "favouriteFloats": []float64{3.1425, 0.00000000001, 10}, + }, }, }, }, @@ -404,14 +432,16 @@ func TestQueryInlineArrayWithNillableFloats(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "pageRatings": []immutable.Option[float64]{ - immutable.Some(3.1425), - immutable.None[float64](), - immutable.Some(-0.00000000001), - immutable.Some[float64](10), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "pageRatings": []immutable.Option[float64]{ + immutable.Some(3.1425), + immutable.None[float64](), + immutable.Some(-0.00000000001), + immutable.Some[float64](10), + }, }, }, }, @@ -438,10 +468,12 @@ func TestQueryInlineArrayWithStrings(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "preferredStrings": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "preferredStrings": nil, + }, }, }, }, @@ -461,10 +493,12 @@ func TestQueryInlineArrayWithStrings(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "preferredStrings": []string{}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "preferredStrings": []string{}, + }, }, }, }, @@ -484,10 +518,12 @@ func TestQueryInlineArrayWithStrings(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "preferredStrings": []string{"", "the previous", "the first", "empty string"}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "preferredStrings": []string{"", "the previous", "the first", "empty string"}, + }, }, }, }, @@ -515,15 +551,17 @@ func TestQueryInlineArrayWithNillableString(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "pageHeaders": []immutable.Option[string]{ - immutable.Some(""), - immutable.Some("the previous"), - immutable.Some("the first"), - immutable.Some("empty string"), - immutable.None[string](), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "pageHeaders": []immutable.Option[string]{ + immutable.Some(""), + immutable.Some("the previous"), + immutable.Some("the first"), + immutable.Some("empty string"), + immutable.None[string](), + }, }, }, }, diff --git a/tests/integration/query/inline_array/with_average_filter_test.go b/tests/integration/query/inline_array/with_average_filter_test.go index f42c40922f..cac50ea81c 100644 --- a/tests/integration/query/inline_array/with_average_filter_test.go +++ b/tests/integration/query/inline_array/with_average_filter_test.go @@ -33,10 +33,12 @@ func TestQueryInlineIntegerArrayWithAverageWithFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_avg": float64(1.5), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_avg": float64(1.5), + }, }, }, } @@ -61,10 +63,12 @@ func TestQueryInlineNillableIntegerArrayWithAverageWithFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_avg": float64(6.5), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(6.5), + }, }, }, } @@ -89,10 +93,12 @@ func TestQueryInlineFloatArrayWithAverageWithFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_avg": 3.5, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_avg": 3.5, + }, }, }, } @@ -117,10 +123,12 @@ func TestQueryInlineNillableFloatArrayWithAverageWithFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_avg": 3.5, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_avg": 3.5, + }, }, }, } diff --git a/tests/integration/query/inline_array/with_average_sum_test.go b/tests/integration/query/inline_array/with_average_sum_test.go index 56bc5da3a8..a6474d8f03 100644 --- a/tests/integration/query/inline_array/with_average_sum_test.go +++ b/tests/integration/query/inline_array/with_average_sum_test.go @@ -38,11 +38,13 @@ func TestQueryInlineIntegerArrayWithAverageAndSum(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_avg": float64(2), - "_sum": int64(8), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(2), + "_sum": int64(8), + }, }, }, } diff --git a/tests/integration/query/inline_array/with_average_test.go b/tests/integration/query/inline_array/with_average_test.go index c1e62c61bb..bd5eeec041 100644 --- a/tests/integration/query/inline_array/with_average_test.go +++ b/tests/integration/query/inline_array/with_average_test.go @@ -33,10 +33,12 @@ func TestQueryInlineIntegerArrayWithAverageAndNullArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_avg": float64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(0), + }, }, }, } @@ -61,10 +63,12 @@ func TestQueryInlineIntegerArrayWithAverageAndEmptyArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_avg": float64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(0), + }, }, }, } @@ -89,10 +93,12 @@ func TestQueryInlineIntegerArrayWithAverageAndZeroArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_avg": float64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(0), + }, }, }, } @@ -117,10 +123,12 @@ func TestQueryInlineIntegerArrayWithAverageAndPopulatedArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_avg": float64(2), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(2), + }, }, }, } @@ -145,10 +153,12 @@ func TestQueryInlineNillableIntegerArrayWithAverageAndPopulatedArray(t *testing. }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_avg": float64(4), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(4), + }, }, }, } @@ -173,10 +183,12 @@ func TestQueryInlineFloatArrayWithAverageAndNullArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_avg": float64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(0), + }, }, }, } @@ -201,10 +213,12 @@ func TestQueryInlineFloatArrayWithAverageAndEmptyArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_avg": float64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(0), + }, }, }, } @@ -229,10 +243,13 @@ func TestQueryInlineFloatArrayWithAverageAndZeroArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_avg": float64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + + "name": "John", + "_avg": float64(0), + }, }, }, } @@ -257,10 +274,12 @@ func TestQueryInlineFloatArrayWithAverageAndPopulatedArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_avg": float64(0.2), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(0.2), + }, }, }, } @@ -285,10 +304,12 @@ func TestQueryInlineNillableFloatArrayWithAverageAndPopulatedArray(t *testing.T) }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_avg": float64(0.2), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(0.2), + }, }, }, } diff --git a/tests/integration/query/inline_array/with_count_filter_test.go b/tests/integration/query/inline_array/with_count_filter_test.go index 69cd847d23..c8c81f82e2 100644 --- a/tests/integration/query/inline_array/with_count_filter_test.go +++ b/tests/integration/query/inline_array/with_count_filter_test.go @@ -33,10 +33,12 @@ func TestQueryInlineBoolArrayWithCountWithFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_count": 3, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 3, + }, }, }, } @@ -61,10 +63,12 @@ func TestQueryInlineNillableBoolArrayWithCountWithFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_count": 2, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_count": 2, + }, }, }, } @@ -89,10 +93,12 @@ func TestQueryInlineIntegerArrayWithCountWithFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_count": 2, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 2, + }, }, }, } @@ -117,10 +123,12 @@ func TestQueryInlineNillableIntegerArrayWithCountWithFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_count": 2, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 2, + }, }, }, } @@ -144,10 +152,12 @@ func TestQueryInlineIntegerArrayWithsWithCountWithAndFilterAndPopulatedArray(t * "favouriteIntegers": [-1, 2, -1, 1, 0, -2] }`)}, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_count": 4, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 4, + }, }, }, } @@ -172,10 +182,12 @@ func TestQueryInlineFloatArrayWithCountWithFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_count": 2, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 2, + }, }, }, } @@ -200,10 +212,12 @@ func TestQueryInlineNillableFloatArrayWithCountWithFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_count": 2, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 2, + }, }, }, } @@ -228,10 +242,12 @@ func TestQueryInlineStringArrayWithCountWithFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_count": 2, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 2, + }, }, }, } @@ -256,10 +272,12 @@ func TestQueryInlineNillableStringArrayWithCountWithFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_count": 2, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 2, + }, }, }, } diff --git a/tests/integration/query/inline_array/with_count_limit_offset_test.go b/tests/integration/query/inline_array/with_count_limit_offset_test.go index 59783e9587..d1e04b43ed 100644 --- a/tests/integration/query/inline_array/with_count_limit_offset_test.go +++ b/tests/integration/query/inline_array/with_count_limit_offset_test.go @@ -33,10 +33,12 @@ func TestQueryInlineIntegerArrayWithCountWithOffsetWithLimitGreaterThanLength(t }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_count": 2, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 2, + }, }, }, } @@ -61,10 +63,12 @@ func TestQueryInlineIntegerArrayWithCountWithOffsetWithLimit(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_count": 3, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 3, + }, }, }, } diff --git a/tests/integration/query/inline_array/with_count_limit_test.go b/tests/integration/query/inline_array/with_count_limit_test.go index b29c62e8e7..09354ecc8c 100644 --- a/tests/integration/query/inline_array/with_count_limit_test.go +++ b/tests/integration/query/inline_array/with_count_limit_test.go @@ -33,10 +33,12 @@ func TestQueryInlineIntegerArrayWithCountWithLimitGreaterThanLength(t *testing.T }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_count": 2, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 2, + }, }, }, } @@ -61,10 +63,12 @@ func TestQueryInlineIntegerArrayWithCountWithLimit(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_count": 3, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 3, + }, }, }, } diff --git a/tests/integration/query/inline_array/with_count_test.go b/tests/integration/query/inline_array/with_count_test.go index 18e7aaed69..40401e1cce 100644 --- a/tests/integration/query/inline_array/with_count_test.go +++ b/tests/integration/query/inline_array/with_count_test.go @@ -33,10 +33,12 @@ func TestQueryInlineIntegerArrayWithCountAndNullArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_count": 0, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_count": 0, + }, }, }, } @@ -61,10 +63,12 @@ func TestQueryInlineIntegerArrayWithCountAndEmptyArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_count": 0, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_count": 0, + }, }, }, } @@ -89,10 +93,12 @@ func TestQueryInlineIntegerArrayWithCountAndPopulatedArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_count": 5, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 5, + }, }, }, } @@ -117,10 +123,12 @@ func TestQueryInlineNillableBoolArrayWithCountAndPopulatedArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_count": 4, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_count": 4, + }, }, }, } diff --git a/tests/integration/query/inline_array/with_group_test.go b/tests/integration/query/inline_array/with_group_test.go index 8ab6eb356e..7706b9250b 100644 --- a/tests/integration/query/inline_array/with_group_test.go +++ b/tests/integration/query/inline_array/with_group_test.go @@ -39,15 +39,17 @@ func TestQueryInlineArrayWithGroupByString(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_group": []map[string]any{ - { - "favouriteIntegers": []int64{1, -2, 1, -1, 0}, - }, - { - "favouriteIntegers": []int64{-1, 2, -1, 1, 0}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_group": []map[string]any{ + { + "favouriteIntegers": []int64{1, -2, 1, -1, 0}, + }, + { + "favouriteIntegers": []int64{-1, 2, -1, 1, 0}, + }, }, }, }, @@ -84,24 +86,26 @@ func TestQueryInlineArrayWithGroupByArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "favouriteIntegers": []int64{1, 2, 3}, - "_group": []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "favouriteIntegers": []int64{1, 2, 3}, + "_group": []map[string]any{ + { + "name": "John", + }, }, }, - }, - { - "favouriteIntegers": []int64{-1, 2, -1, 1, 0}, - "_group": []map[string]any{ - { - "name": "Andy", - }, - { + { + "favouriteIntegers": []int64{-1, 2, -1, 1, 0}, + "_group": []map[string]any{ + { + "name": "Andy", + }, + { - "name": "Shahzad", + "name": "Shahzad", + }, }, }, }, diff --git a/tests/integration/query/inline_array/with_sum_filter_test.go b/tests/integration/query/inline_array/with_sum_filter_test.go index 85cd56842b..075411e06a 100644 --- a/tests/integration/query/inline_array/with_sum_filter_test.go +++ b/tests/integration/query/inline_array/with_sum_filter_test.go @@ -33,10 +33,12 @@ func TestQueryInlineIntegerArrayWithSumWithFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_sum": int64(3), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_sum": int64(3), + }, }, }, } @@ -61,10 +63,12 @@ func TestQueryInlineNillableIntegerArrayWithSumWithFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_sum": int64(3), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_sum": int64(3), + }, }, }, } @@ -89,10 +93,12 @@ func TestQueryInlineFloatArrayWithSumWithFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_sum": 3.14250000001, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_sum": 3.14250000001, + }, }, }, } @@ -117,10 +123,12 @@ func TestQueryInlineNillableFloatArrayWithSumWithFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_sum": float64(3.14250000001), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_sum": float64(3.14250000001), + }, }, }, } diff --git a/tests/integration/query/inline_array/with_sum_limit_offset_order_test.go b/tests/integration/query/inline_array/with_sum_limit_offset_order_test.go index c23f4352fe..59e4ddc7fd 100644 --- a/tests/integration/query/inline_array/with_sum_limit_offset_order_test.go +++ b/tests/integration/query/inline_array/with_sum_limit_offset_order_test.go @@ -33,11 +33,13 @@ func TestQueryInlineIntegerArrayWithSumWithOffsetWithLimitWithOrderAsc(t *testin }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - // 0 + 1 + 2 - "_sum": int64(3), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + // 0 + 1 + 2 + "_sum": int64(3), + }, }, }, } @@ -62,11 +64,13 @@ func TestQueryInlineIntegerArrayWithSumWithOffsetWithLimitWithOrderDesc(t *testi }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - // 5 + 2 + 1 - "_sum": int64(8), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + // 5 + 2 + 1 + "_sum": int64(8), + }, }, }, } @@ -91,11 +95,13 @@ func TestQueryInlineNillableIntegerArrayWithSumWithOffsetWithLimitWithOrderAsc(t }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - // 0 + 1 + 2 - "_sum": int64(3), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + // 0 + 1 + 2 + "_sum": int64(3), + }, }, }, } @@ -120,11 +126,13 @@ func TestQueryInlineNillableIntegerArrayWithSumWithOffsetWithLimitWithOrderDesc( }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - // 5 + 2 + 1 - "_sum": int64(8), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + // 5 + 2 + 1 + "_sum": int64(8), + }, }, }, } @@ -149,11 +157,13 @@ func TestQueryInlineFloatArrayWithSumWithOffsetWithLimitWithOrderAsc(t *testing. }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - // 0.577 + 2.718 + 3.1425 - "_sum": float64(6.4375), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + // 0.577 + 2.718 + 3.1425 + "_sum": float64(6.4375), + }, }, }, } @@ -178,11 +188,13 @@ func TestQueryInlineFloatArrayWithSumWithOffsetWithLimitWithOrderDesc(t *testing }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - // 6.283 + 3.1425 + 2.718 - "_sum": float64(12.1435), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + // 6.283 + 3.1425 + 2.718 + "_sum": float64(12.1435), + }, }, }, } @@ -207,11 +219,13 @@ func TestQueryInlineNillableFloatArrayWithSumWithOffsetWithLimitWithOrderAsc(t * }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - // 0.577 + 2.718 + 3.1425 - "_sum": float64(6.4375), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + // 0.577 + 2.718 + 3.1425 + "_sum": float64(6.4375), + }, }, }, } @@ -236,11 +250,13 @@ func TestQueryInlineNillableFloatArrayWithSumWithOffsetWithLimitWithOrderDesc(t }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - // 6.283 + 3.1425 + 2.718 - "_sum": float64(12.1435), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + // 6.283 + 3.1425 + 2.718 + "_sum": float64(12.1435), + }, }, }, } diff --git a/tests/integration/query/inline_array/with_sum_limit_offset_test.go b/tests/integration/query/inline_array/with_sum_limit_offset_test.go index 6e4d4ef3d7..357dbbde7e 100644 --- a/tests/integration/query/inline_array/with_sum_limit_offset_test.go +++ b/tests/integration/query/inline_array/with_sum_limit_offset_test.go @@ -33,10 +33,12 @@ func TestQueryInlineIntegerArrayWithSumWithOffsetWithLimit(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_sum": int64(7), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_sum": int64(7), + }, }, }, } diff --git a/tests/integration/query/inline_array/with_sum_limit_test.go b/tests/integration/query/inline_array/with_sum_limit_test.go index 2cf9104bbc..79ebd60f36 100644 --- a/tests/integration/query/inline_array/with_sum_limit_test.go +++ b/tests/integration/query/inline_array/with_sum_limit_test.go @@ -33,10 +33,12 @@ func TestQueryInlineIntegerArrayWithSumWithLimit(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_sum": int64(1), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_sum": int64(1), + }, }, }, } diff --git a/tests/integration/query/inline_array/with_sum_test.go b/tests/integration/query/inline_array/with_sum_test.go index 35db82a41a..28f63bb6b3 100644 --- a/tests/integration/query/inline_array/with_sum_test.go +++ b/tests/integration/query/inline_array/with_sum_test.go @@ -33,10 +33,12 @@ func TestQueryInlineIntegerArrayWithSumAndNullArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_sum": int64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_sum": int64(0), + }, }, }, } @@ -61,10 +63,12 @@ func TestQueryInlineIntegerArrayWithSumAndEmptyArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_sum": int64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_sum": int64(0), + }, }, }, } @@ -89,10 +93,12 @@ func TestQueryInlineIntegerArrayWithSumAndPopulatedArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_sum": int64(1), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_sum": int64(1), + }, }, }, } @@ -117,10 +123,12 @@ func TestQueryInlineNillableIntegerArrayWithSumAndPopulatedArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_sum": int64(2), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_sum": int64(2), + }, }, }, } @@ -145,10 +153,12 @@ func TestQueryInlineFloatArrayWithSumAndNullArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_sum": float64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_sum": float64(0), + }, }, }, } @@ -173,10 +183,12 @@ func TestQueryInlineFloatArrayWithSumAndEmptyArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_sum": float64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_sum": float64(0), + }, }, }, } @@ -201,10 +213,12 @@ func TestQueryInlineFloatArrayWithSumAndPopulatedArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John", - "_sum": float64(13.14250000001), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_sum": float64(13.14250000001), + }, }, }, } @@ -229,10 +243,12 @@ func TestQueryInlineNillableFloatArrayWithSumAndPopulatedArray(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Shahzad", - "_sum": float64(13.14250000001), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_sum": float64(13.14250000001), + }, }, }, } diff --git a/tests/integration/query/latest_commits/with_collectionid_prop_test.go b/tests/integration/query/latest_commits/with_collectionid_prop_test.go index 5509671aef..ae0758f6c2 100644 --- a/tests/integration/query/latest_commits/with_collectionid_prop_test.go +++ b/tests/integration/query/latest_commits/with_collectionid_prop_test.go @@ -41,9 +41,11 @@ func TestQueryLastCommitsWithCollectionIdProperty(t *testing.T) { collectionID } }`, - Results: []map[string]any{ - { - "collectionID": int64(1), + Results: map[string]any{ + "latestCommits": []map[string]any{ + { + "collectionID": int64(1), + }, }, }, }, @@ -53,9 +55,11 @@ func TestQueryLastCommitsWithCollectionIdProperty(t *testing.T) { collectionID } }`, - Results: []map[string]any{ - { - "collectionID": int64(2), + Results: map[string]any{ + "latestCommits": []map[string]any{ + { + "collectionID": int64(2), + }, }, }, }, diff --git a/tests/integration/query/latest_commits/with_doc_id_field_test.go b/tests/integration/query/latest_commits/with_doc_id_field_test.go index 04f0065b0a..bdaf4d5562 100644 --- a/tests/integration/query/latest_commits/with_doc_id_field_test.go +++ b/tests/integration/query/latest_commits/with_doc_id_field_test.go @@ -38,7 +38,9 @@ func TestQueryLatestCommitsWithDocIDAndFieldName(t *testing.T) { }`, }, }, - Results: []map[string]any{}, + Results: map[string]any{ + "latestCommits": []map[string]any{}, + }, } executeTestCase(t, test) @@ -66,10 +68,12 @@ func TestQueryLatestCommitsWithDocIDAndFieldId(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "links": []map[string]any{}, + Results: map[string]any{ + "latestCommits": []map[string]any{ + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "links": []map[string]any{}, + }, }, }, } @@ -99,17 +103,19 @@ func TestQueryLatestCommitsWithDocIDAndCompositeFieldId(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "links": []map[string]any{ - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "name": "name", - }, - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "name": "age", + Results: map[string]any{ + "latestCommits": []map[string]any{ + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "links": []map[string]any{ + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "name": "name", + }, + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "name": "age", + }, }, }, }, diff --git a/tests/integration/query/latest_commits/with_doc_id_prop_test.go b/tests/integration/query/latest_commits/with_doc_id_prop_test.go index 5cef0f2d06..652d321973 100644 --- a/tests/integration/query/latest_commits/with_doc_id_prop_test.go +++ b/tests/integration/query/latest_commits/with_doc_id_prop_test.go @@ -34,9 +34,11 @@ func TestQueryLastCommitsWithDocIDProperty(t *testing.T) { docID } }`, - Results: []map[string]any{ - { - "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", + Results: map[string]any{ + "latestCommits": []map[string]any{ + { + "docID": "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", + }, }, }, }, diff --git a/tests/integration/query/latest_commits/with_doc_id_test.go b/tests/integration/query/latest_commits/with_doc_id_test.go index d39becb3d3..4bd51d546d 100644 --- a/tests/integration/query/latest_commits/with_doc_id_test.go +++ b/tests/integration/query/latest_commits/with_doc_id_test.go @@ -36,17 +36,19 @@ func TestQueryLatestCommitsWithDocID(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "links": []map[string]any{ - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "name": "name", - }, - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "name": "age", + Results: map[string]any{ + "latestCommits": []map[string]any{ + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "links": []map[string]any{ + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "name": "name", + }, + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "name": "age", + }, }, }, }, @@ -73,10 +75,12 @@ func TestQueryLatestCommitsWithDocIDWithSchemaVersionIDField(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "schemaVersionId": "bafkreicprhqxzlw3akyssz2v6pifwfueavp7jq2yj3dghapi3qcq6achs4", + Results: map[string]any{ + "latestCommits": []map[string]any{ + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "schemaVersionId": "bafkreicprhqxzlw3akyssz2v6pifwfueavp7jq2yj3dghapi3qcq6achs4", + }, }, }, } diff --git a/tests/integration/query/one_to_many/simple_test.go b/tests/integration/query/one_to_many/simple_test.go index bf80618d83..44ee5f8cf5 100644 --- a/tests/integration/query/one_to_many/simple_test.go +++ b/tests/integration/query/one_to_many/simple_test.go @@ -48,13 +48,15 @@ func TestQueryOneToMany(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "name": "John Grisham", - "age": int64(65), + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "name": "John Grisham", + "age": int64(65), + }, }, }, }, @@ -106,28 +108,30 @@ func TestQueryOneToMany(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "age": int64(62), - "published": []map[string]any{ - { - "name": "Theif Lord", - "rating": 4.8, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "age": int64(62), + "published": []map[string]any{ + { + "name": "Theif Lord", + "rating": 4.8, + }, }, }, - }, - { - "name": "John Grisham", - "age": int64(65), - "published": []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, + { + "name": "John Grisham", + "age": int64(65), + "published": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + { + "name": "A Time for Mercy", + "rating": 4.5, + }, }, }, }, @@ -163,11 +167,13 @@ func TestQueryOneToManyWithNonExistantParent(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - "author": nil, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + "author": nil, + }, }, }, } diff --git a/tests/integration/query/one_to_many/with_cid_doc_id_test.go b/tests/integration/query/one_to_many/with_cid_doc_id_test.go index 3f415ab288..91f2d5782b 100644 --- a/tests/integration/query/one_to_many/with_cid_doc_id_test.go +++ b/tests/integration/query/one_to_many/with_cid_doc_id_test.go @@ -113,11 +113,13 @@ func TestQueryOneToManyWithCidAndDocID(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "author": map[string]any{ - "name": "John Grisham", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, @@ -189,12 +191,14 @@ func TestQueryOneToManyWithChildUpdateAndFirstCidAndDocID(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "author": map[string]any{ - "name": "John Grisham", - "age": int64(22), + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author": map[string]any{ + "name": "John Grisham", + "age": int64(22), + }, }, }, }, @@ -262,12 +266,14 @@ func TestQueryOneToManyWithParentUpdateAndFirstCidAndDocID(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "rating": float64(4.9), - "author": map[string]any{ - "name": "John Grisham", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": float64(4.9), + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, @@ -335,12 +341,14 @@ func TestQueryOneToManyWithParentUpdateAndLastCidAndDocID(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "rating": float64(4.5), - "author": map[string]any{ - "name": "John Grisham", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": float64(4.5), + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_count_filter_test.go b/tests/integration/query/one_to_many/with_count_filter_test.go index 4d1a590479..261e5993e9 100644 --- a/tests/integration/query/one_to_many/with_count_filter_test.go +++ b/tests/integration/query/one_to_many/with_count_filter_test.go @@ -60,14 +60,16 @@ func TestQueryOneToManyWithCountWithFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 0, - }, - { - "name": "John Grisham", - "_count": 1, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_count": 0, + }, + { + "name": "John Grisham", + "_count": 1, + }, }, }, } @@ -126,25 +128,27 @@ func TestQueryOneToManyWithCountWithFilterAndChildFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 1, - "published": []map[string]any{ - { - "name": "Theif Lord", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_count": 1, + "published": []map[string]any{ + { + "name": "Theif Lord", + }, }, }, - }, - { - "name": "John Grisham", - "_count": 2, - "published": []map[string]any{ - { - "name": "Painted House", - }, - { - "name": "A Time for Mercy", + { + "name": "John Grisham", + "_count": 2, + "published": []map[string]any{ + { + "name": "Painted House", + }, + { + "name": "A Time for Mercy", + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_count_limit_offset_test.go b/tests/integration/query/one_to_many/with_count_limit_offset_test.go index 838f67434d..eea8a504c7 100644 --- a/tests/integration/query/one_to_many/with_count_limit_offset_test.go +++ b/tests/integration/query/one_to_many/with_count_limit_offset_test.go @@ -73,21 +73,23 @@ func TestQueryOneToManyWithCountAndLimitAndOffset(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 1, - "published": []map[string]any{}, - }, - { - "name": "John Grisham", - "_count": 4, - "published": []map[string]any{ - { - "name": "Painted House", - }, - { - "name": "The Pelican Brief", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_count": 1, + "published": []map[string]any{}, + }, + { + "name": "John Grisham", + "_count": 4, + "published": []map[string]any{ + { + "name": "Painted House", + }, + { + "name": "The Pelican Brief", + }, }, }, }, @@ -149,25 +151,27 @@ func TestQueryOneToManyWithCountAndDifferentOffsets(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 0, - "published": []map[string]any{ - { - "name": "Theif Lord", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_count": 0, + "published": []map[string]any{ + { + "name": "Theif Lord", + }, }, }, - }, - { - "name": "John Grisham", - "_count": 2, - "published": []map[string]any{ - { - "name": "The Associate", - }, - { - "name": "Painted House", + { + "name": "John Grisham", + "_count": 2, + "published": []map[string]any{ + { + "name": "The Associate", + }, + { + "name": "Painted House", + }, }, }, }, @@ -221,14 +225,16 @@ func TestQueryOneToManyWithCountWithLimitWithOffset(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 0, - }, - { - "name": "John Grisham", - "_count": 1, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_count": 0, + }, + { + "name": "John Grisham", + "_count": 1, + }, }, }, } diff --git a/tests/integration/query/one_to_many/with_count_limit_test.go b/tests/integration/query/one_to_many/with_count_limit_test.go index 3badad8ef8..3f7006d074 100644 --- a/tests/integration/query/one_to_many/with_count_limit_test.go +++ b/tests/integration/query/one_to_many/with_count_limit_test.go @@ -63,22 +63,24 @@ func TestQueryOneToManyWithCountAndLimit(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 1, - "published": []map[string]any{ - { - "name": "Theif Lord", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_count": 1, + "published": []map[string]any{ + { + "name": "Theif Lord", + }, }, }, - }, - { - "name": "John Grisham", - "_count": 2, - "published": []map[string]any{ - { - "name": "Painted House", + { + "name": "John Grisham", + "_count": 2, + "published": []map[string]any{ + { + "name": "Painted House", + }, }, }, }, @@ -140,22 +142,24 @@ func TestQueryOneToManyWithCountAndDifferentLimits(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 1, - "published": []map[string]any{ - { - "name": "Theif Lord", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_count": 1, + "published": []map[string]any{ + { + "name": "Theif Lord", + }, }, }, - }, - { - "name": "John Grisham", - "_count": 2, - "published": []map[string]any{ - { - "name": "The Associate", + { + "name": "John Grisham", + "_count": 2, + "published": []map[string]any{ + { + "name": "The Associate", + }, }, }, }, @@ -209,14 +213,16 @@ func TestQueryOneToManyWithCountWithLimit(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 1, - }, - { - "name": "John Grisham", - "_count": 1, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_count": 1, + }, + { + "name": "John Grisham", + "_count": 1, + }, }, }, } diff --git a/tests/integration/query/one_to_many/with_count_test.go b/tests/integration/query/one_to_many/with_count_test.go index 0efb541d85..dba62fbf05 100644 --- a/tests/integration/query/one_to_many/with_count_test.go +++ b/tests/integration/query/one_to_many/with_count_test.go @@ -36,10 +36,12 @@ func TestQueryOneToManyWithCount(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John Grisham", - "_count": 0, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "_count": 0, + }, }, }, }, @@ -86,14 +88,16 @@ func TestQueryOneToManyWithCount(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 1, - }, - { - "name": "John Grisham", - "_count": 2, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_count": 1, + }, + { + "name": "John Grisham", + "_count": 2, + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_doc_id_test.go b/tests/integration/query/one_to_many/with_doc_id_test.go index e6e6aa9b90..b00fd0a549 100644 --- a/tests/integration/query/one_to_many/with_doc_id_test.go +++ b/tests/integration/query/one_to_many/with_doc_id_test.go @@ -52,12 +52,14 @@ func TestQueryOneToManyWithChildDocID(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John Grisham", - "published": []map[string]any{ - { - "name": "Painted House", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "published": []map[string]any{ + { + "name": "Painted House", + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_doc_ids_test.go b/tests/integration/query/one_to_many/with_doc_ids_test.go index 6e61902c79..998c926909 100644 --- a/tests/integration/query/one_to_many/with_doc_ids_test.go +++ b/tests/integration/query/one_to_many/with_doc_ids_test.go @@ -64,15 +64,17 @@ func TestQueryOneToManyWithChildDocIDs(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John Grisham", - "published": []map[string]any{ - { - "name": "The Associate", - }, - { - "name": "Painted House", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "published": []map[string]any{ + { + "name": "The Associate", + }, + { + "name": "Painted House", + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_filter_related_id_test.go b/tests/integration/query/one_to_many/with_filter_related_id_test.go index f2e456143c..6d8508e3c3 100644 --- a/tests/integration/query/one_to_many/with_filter_related_id_test.go +++ b/tests/integration/query/one_to_many/with_filter_related_id_test.go @@ -83,10 +83,12 @@ func TestQueryFromManySideWithEqFilterOnRelatedType(t *testing.T) { }`, }, }, - Results: []map[string]any{ - {"name": "The Client"}, - {"name": "Painted House"}, - {"name": "A Time for Mercy"}, + Results: map[string]any{ + "Book": []map[string]any{ + {"name": "The Client"}, + {"name": "Painted House"}, + {"name": "A Time for Mercy"}, + }, }, } @@ -160,10 +162,12 @@ func TestQueryFromManySideWithFilterOnRelatedObjectID(t *testing.T) { }`, }, }, - Results: []map[string]any{ - {"name": "The Client"}, - {"name": "Painted House"}, - {"name": "A Time for Mercy"}, + Results: map[string]any{ + "Book": []map[string]any{ + {"name": "The Client"}, + {"name": "Painted House"}, + {"name": "A Time for Mercy"}, + }, }, } @@ -242,10 +246,12 @@ func TestQueryFromManySideWithSameFiltersInDifferentWayOnRelatedType(t *testing. }`, }, }, - Results: []map[string]any{ - {"name": "The Client"}, - {"name": "Painted House"}, - {"name": "A Time for Mercy"}, + Results: map[string]any{ + "Book": []map[string]any{ + {"name": "The Client"}, + {"name": "Painted House"}, + {"name": "A Time for Mercy"}, + }, }, } @@ -319,9 +325,11 @@ func TestQueryFromSingleSideWithEqFilterOnRelatedType(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John Grisham", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + }, }, }, } diff --git a/tests/integration/query/one_to_many/with_filter_test.go b/tests/integration/query/one_to_many/with_filter_test.go index 94c971c7a8..317d89b2fd 100644 --- a/tests/integration/query/one_to_many/with_filter_test.go +++ b/tests/integration/query/one_to_many/with_filter_test.go @@ -77,18 +77,20 @@ func TestQueryOneToManyWithNumericGreaterThanFilterOnParent(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "John Grisham", - "age": int64(65), - "published": []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "age": int64(65), + "published": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + { + "name": "A Time for Mercy", + "rating": 4.5, + }, }, }, }, @@ -156,9 +158,11 @@ func TestQueryOneToManyWithNumericGreaterThanChildFilterOnParentWithUnrenderedCh name } }`, - Results: []map[string]any{ - { - "name": "John Grisham", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + }, }, }, }, @@ -229,14 +233,16 @@ func TestQueryOneToManyWithNumericGreaterThanFilterOnParentAndChild(t *testing.T } } }`, - Results: []map[string]any{ - { - "name": "John Grisham", - "age": int64(65), - "published": []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "age": int64(65), + "published": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, }, }, }, @@ -313,31 +319,33 @@ func TestQueryOneToManyWithMultipleAliasedFilteredChildren(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "age": int64(62), - "p1": []map[string]any{ - { - "name": "Theif Lord", - "rating": 4.8, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "age": int64(62), + "p1": []map[string]any{ + { + "name": "Theif Lord", + "rating": 4.8, + }, }, + "p2": []map[string]any{}, }, - "p2": []map[string]any{}, - }, - { - "name": "John Grisham", - "age": int64(65), - "p1": []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, + { + "name": "John Grisham", + "age": int64(65), + "p1": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, }, - }, - "p2": []map[string]any{ - { - "name": "A Time for Mercy", - "rating": 4.5, + "p2": []map[string]any{ + { + "name": "A Time for Mercy", + "rating": 4.5, + }, }, }, }, @@ -430,12 +438,14 @@ func TestQueryOneToManyWithCompoundOperatorInFilterAndRelation(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - }, - { - "name": "John Grisham", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + }, + { + "name": "John Grisham", + }, }, }, }, @@ -448,9 +458,11 @@ func TestQueryOneToManyWithCompoundOperatorInFilterAndRelation(t *testing.T) { name } }`, - Results: []map[string]any{{ - "name": "Cornelia Funke", - }}, + Results: map[string]any{ + "Author": []map[string]any{ + {"name": "Cornelia Funke"}, + }, + }, }, }, } @@ -535,12 +547,14 @@ func TestQueryOneToMany_WithCompoundOperatorInFilterAndRelationAndCaseInsensitiv name } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - }, - { - "name": "John Grisham", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + }, + { + "name": "John Grisham", + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_group_filter_test.go b/tests/integration/query/one_to_many/with_group_filter_test.go index 6005ef2def..38deb0cc20 100644 --- a/tests/integration/query/one_to_many/with_group_filter_test.go +++ b/tests/integration/query/one_to_many/with_group_filter_test.go @@ -88,38 +88,40 @@ func TestQueryOneToManyWithParentJoinGroupNumberAndNumberFilterOnJoin(t *testing }`, }, }, - Results: []map[string]any{ - { - "age": int64(327), - "_group": []map[string]any{ - { - "name": "Voltaire", - "published": []map[string]any{ - { - "name": "Candide", - "rating": 4.95, - }, - { - "name": "Zadig", - "rating": 4.91, + Results: map[string]any{ + "Author": []map[string]any{ + { + "age": int64(327), + "_group": []map[string]any{ + { + "name": "Voltaire", + "published": []map[string]any{ + { + "name": "Candide", + "rating": 4.95, + }, + { + "name": "Zadig", + "rating": 4.91, + }, }, }, - }, - { - "name": "Simon Pelloutier", - "published": []map[string]any{}, + { + "name": "Simon Pelloutier", + "published": []map[string]any{}, + }, }, }, - }, - { - "age": int64(65), - "_group": []map[string]any{ - { - "name": "John Grisham", - "published": []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, + { + "age": int64(65), + "_group": []map[string]any{ + { + "name": "John Grisham", + "published": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, }, }, }, @@ -206,42 +208,44 @@ func TestQueryOneToManyWithParentJoinGroupNumberAndNumberFilterOnGroup(t *testin }`, }, }, - Results: []map[string]any{ - { - "age": int64(327), - "_group": []map[string]any{ - { - "name": "Voltaire", - "published": []map[string]any{ - { - "name": "Candide", - "rating": 4.95, - }, - { - "name": "Zadig", - "rating": 4.91, + Results: map[string]any{ + "Author": []map[string]any{ + { + "age": int64(327), + "_group": []map[string]any{ + { + "name": "Voltaire", + "published": []map[string]any{ + { + "name": "Candide", + "rating": 4.95, + }, + { + "name": "Zadig", + "rating": 4.91, + }, }, }, }, }, - }, - { - "age": int64(65), - "_group": []map[string]any{ - { - "name": "John Grisham", - "published": []map[string]any{ - { - "name": "The Client", - "rating": 4.5, - }, - { - "name": "Painted House", - "rating": 4.9, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, + { + "age": int64(65), + "_group": []map[string]any{ + { + "name": "John Grisham", + "published": []map[string]any{ + { + "name": "The Client", + "rating": 4.5, + }, + { + "name": "Painted House", + "rating": 4.9, + }, + { + "name": "A Time for Mercy", + "rating": 4.5, + }, }, }, }, @@ -328,22 +332,24 @@ func TestQueryOneToManyWithParentJoinGroupNumberAndNumberFilterOnGroupAndOnGroup }`, }, }, - Results: []map[string]any{ - { - "age": int64(327), - "_group": []map[string]any{ - { - "name": "Voltaire", - "published": []map[string]any{ - { - "name": "Candide", - "rating": 4.95, + Results: map[string]any{ + "Author": []map[string]any{ + { + "age": int64(327), + "_group": []map[string]any{ + { + "name": "Voltaire", + "published": []map[string]any{ + { + "name": "Candide", + "rating": 4.95, + }, }, }, - }, - { - "name": "Simon Pelloutier", - "published": []map[string]any{}, + { + "name": "Simon Pelloutier", + "published": []map[string]any{}, + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_group_related_id_alias_test.go b/tests/integration/query/one_to_many/with_group_related_id_alias_test.go index fdd50743c4..9dde09334d 100644 --- a/tests/integration/query/one_to_many/with_group_related_id_alias_test.go +++ b/tests/integration/query/one_to_many/with_group_related_id_alias_test.go @@ -122,66 +122,68 @@ func TestQueryOneToManyWithParentGroupByOnRelatedTypeFromManySideUsingAlias(t *t } } }`, - Results: []map[string]any{ - { - "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", - "_group": []map[string]any{ - { - "name": "The Client", - "rating": 4.5, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", + Results: map[string]any{ + "Book": []map[string]any{ + { + "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", + "_group": []map[string]any{ + { + "name": "The Client", + "rating": 4.5, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, }, - }, - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, }, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", + { + "name": "A Time for Mercy", + "rating": 4.5, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, }, }, }, - }, - { - "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", - "_group": []map[string]any{ - { - "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", - "rating": 2.0, - "author": map[string]any{ - "age": int64(327), - "name": "Simon Pelloutier", + { + "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", + "_group": []map[string]any{ + { + "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", + "rating": 2.0, + "author": map[string]any{ + "age": int64(327), + "name": "Simon Pelloutier", + }, }, }, }, - }, - { - "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", - "_group": []map[string]any{ - { - "name": "Candide", - "rating": 4.95, - "author": map[string]any{ - "age": int64(327), - "name": "Voltaire", + { + "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", + "_group": []map[string]any{ + { + "name": "Candide", + "rating": 4.95, + "author": map[string]any{ + "age": int64(327), + "name": "Voltaire", + }, }, - }, - { - "name": "Zadig", - "rating": 4.91, - "author": map[string]any{ - "age": int64(327), - "name": "Voltaire", + { + "name": "Zadig", + "rating": 4.91, + "author": map[string]any{ + "age": int64(327), + "name": "Voltaire", + }, }, }, }, @@ -303,75 +305,77 @@ func TestQueryOneToManyWithParentGroupByOnRelatedTypeFromManySideUsingAliasAndRe } } }`, - Results: []map[string]any{ - { - "author": map[string]any{ - "name": "John Grisham", - "_docID": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", - }, - "_group": []map[string]any{ - { - "name": "The Client", - "rating": 4.5, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", - }, + Results: map[string]any{ + "Book": []map[string]any{ + { + "author": map[string]any{ + "name": "John Grisham", + "_docID": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", }, - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", + "_group": []map[string]any{ + { + "name": "The Client", + "rating": 4.5, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, }, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, + }, + { + "name": "A Time for Mercy", + "rating": 4.5, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, }, }, }, - }, - { - "author": map[string]any{ - "name": "Simon Pelloutier", - "_docID": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", - }, - "_group": []map[string]any{ - { - "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", - "rating": 2.0, - "author": map[string]any{ - "age": int64(327), - "name": "Simon Pelloutier", + { + "author": map[string]any{ + "name": "Simon Pelloutier", + "_docID": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", + }, + "_group": []map[string]any{ + { + "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", + "rating": 2.0, + "author": map[string]any{ + "age": int64(327), + "name": "Simon Pelloutier", + }, }, }, }, - }, - { - "author": map[string]any{ - "name": "Voltaire", - "_docID": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", - }, - "_group": []map[string]any{ - { - "name": "Candide", - "rating": 4.95, - "author": map[string]any{ - "age": int64(327), - "name": "Voltaire", - }, + { + "author": map[string]any{ + "name": "Voltaire", + "_docID": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", }, - { - "name": "Zadig", - "rating": 4.91, - "author": map[string]any{ - "age": int64(327), - "name": "Voltaire", + "_group": []map[string]any{ + { + "name": "Candide", + "rating": 4.95, + "author": map[string]any{ + "age": int64(327), + "name": "Voltaire", + }, + }, + { + "name": "Zadig", + "rating": 4.91, + "author": map[string]any{ + "age": int64(327), + "name": "Voltaire", + }, }, }, }, @@ -490,66 +494,68 @@ func TestQueryOneToManyWithParentGroupByOnRelatedTypeWithIDSelectionFromManySide } } }`, - Results: []map[string]any{ - { - "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", - "_group": []map[string]any{ - { - "name": "The Client", - "rating": 4.5, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", + Results: map[string]any{ + "Book": []map[string]any{ + { + "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", + "_group": []map[string]any{ + { + "name": "The Client", + "rating": 4.5, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, }, - }, - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, }, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", + { + "name": "A Time for Mercy", + "rating": 4.5, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, }, }, }, - }, - { - "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", - "_group": []map[string]any{ - { - "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", - "rating": 2.0, - "author": map[string]any{ - "age": int64(327), - "name": "Simon Pelloutier", + { + "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", + "_group": []map[string]any{ + { + "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", + "rating": 2.0, + "author": map[string]any{ + "age": int64(327), + "name": "Simon Pelloutier", + }, }, }, }, - }, - { - "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", - "_group": []map[string]any{ - { - "name": "Candide", - "rating": 4.95, - "author": map[string]any{ - "age": int64(327), - "name": "Voltaire", + { + "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", + "_group": []map[string]any{ + { + "name": "Candide", + "rating": 4.95, + "author": map[string]any{ + "age": int64(327), + "name": "Voltaire", + }, }, - }, - { - "name": "Zadig", - "rating": 4.91, - "author": map[string]any{ - "age": int64(327), - "name": "Voltaire", + { + "name": "Zadig", + "rating": 4.91, + "author": map[string]any{ + "age": int64(327), + "name": "Voltaire", + }, }, }, }, @@ -672,78 +678,80 @@ func TestQueryOneToManyWithParentGroupByOnRelatedTypeWithIDSelectionFromManySide } } }`, - Results: []map[string]any{ - { - "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", - "author": map[string]any{ - "name": "John Grisham", - "_docID": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", - }, - "_group": []map[string]any{ - { - "name": "The Client", - "rating": 4.5, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", - }, + Results: map[string]any{ + "Book": []map[string]any{ + { + "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", + "author": map[string]any{ + "name": "John Grisham", + "_docID": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", }, - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", + "_group": []map[string]any{ + { + "name": "The Client", + "rating": 4.5, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, }, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, + }, + { + "name": "A Time for Mercy", + "rating": 4.5, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, }, }, }, - }, - { - "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", - "author": map[string]any{ - "name": "Simon Pelloutier", - "_docID": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", - }, - "_group": []map[string]any{ - { - "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", - "rating": 2.0, - "author": map[string]any{ - "age": int64(327), - "name": "Simon Pelloutier", + { + "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", + "author": map[string]any{ + "name": "Simon Pelloutier", + "_docID": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", + }, + "_group": []map[string]any{ + { + "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", + "rating": 2.0, + "author": map[string]any{ + "age": int64(327), + "name": "Simon Pelloutier", + }, }, }, }, - }, - { - "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", - "author": map[string]any{ - "name": "Voltaire", - "_docID": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", - }, - "_group": []map[string]any{ - { - "name": "Candide", - "rating": 4.95, - "author": map[string]any{ - "age": int64(327), - "name": "Voltaire", - }, + { + "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", + "author": map[string]any{ + "name": "Voltaire", + "_docID": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", }, - { - "name": "Zadig", - "rating": 4.91, - "author": map[string]any{ - "age": int64(327), - "name": "Voltaire", + "_group": []map[string]any{ + { + "name": "Candide", + "rating": 4.95, + "author": map[string]any{ + "age": int64(327), + "name": "Voltaire", + }, + }, + { + "name": "Zadig", + "rating": 4.91, + "author": map[string]any{ + "age": int64(327), + "name": "Voltaire", + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_group_related_id_test.go b/tests/integration/query/one_to_many/with_group_related_id_test.go index 509c38fc27..da3a1cac3f 100644 --- a/tests/integration/query/one_to_many/with_group_related_id_test.go +++ b/tests/integration/query/one_to_many/with_group_related_id_test.go @@ -88,66 +88,68 @@ func TestQueryOneToManyWithParentGroupByOnRelatedTypeIDFromManySide(t *testing.T }`, }, }, - Results: []map[string]any{ - { - "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", - "_group": []map[string]any{ - { - "name": "The Client", - "rating": 4.5, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", + Results: map[string]any{ + "Book": []map[string]any{ + { + "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", + "_group": []map[string]any{ + { + "name": "The Client", + "rating": 4.5, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, }, - }, - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, }, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", + { + "name": "A Time for Mercy", + "rating": 4.5, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, }, }, }, - }, - { - "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", - "_group": []map[string]any{ - { - "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", - "rating": 2.0, - "author": map[string]any{ - "age": int64(327), - "name": "Simon Pelloutier", + { + "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", + "_group": []map[string]any{ + { + "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", + "rating": 2.0, + "author": map[string]any{ + "age": int64(327), + "name": "Simon Pelloutier", + }, }, }, }, - }, - { - "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", - "_group": []map[string]any{ - { - "name": "Candide", - "rating": 4.95, - "author": map[string]any{ - "age": int64(327), - "name": "Voltaire", + { + "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", + "_group": []map[string]any{ + { + "name": "Candide", + "rating": 4.95, + "author": map[string]any{ + "age": int64(327), + "name": "Voltaire", + }, }, - }, - { - "name": "Zadig", - "rating": 4.91, - "author": map[string]any{ - "age": int64(327), - "name": "Voltaire", + { + "name": "Zadig", + "rating": 4.91, + "author": map[string]any{ + "age": int64(327), + "name": "Voltaire", + }, }, }, }, @@ -230,66 +232,68 @@ func TestQueryOneToManyWithParentGroupByOnRelatedTypeIDWithIDSelectionFromManySi }`, }, }, - Results: []map[string]any{ - { - "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", - "_group": []map[string]any{ - { - "name": "The Client", - "rating": 4.5, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", + Results: map[string]any{ + "Book": []map[string]any{ + { + "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", + "_group": []map[string]any{ + { + "name": "The Client", + "rating": 4.5, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, }, - }, - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, }, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", + { + "name": "A Time for Mercy", + "rating": 4.5, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, }, }, }, - }, - { - "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", - "_group": []map[string]any{ - { - "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", - "rating": 2.0, - "author": map[string]any{ - "age": int64(327), - "name": "Simon Pelloutier", + { + "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", + "_group": []map[string]any{ + { + "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", + "rating": 2.0, + "author": map[string]any{ + "age": int64(327), + "name": "Simon Pelloutier", + }, }, }, }, - }, - { - "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", - "_group": []map[string]any{ - { - "name": "Candide", - "rating": 4.95, - "author": map[string]any{ - "age": int64(327), - "name": "Voltaire", + { + "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", + "_group": []map[string]any{ + { + "name": "Candide", + "rating": 4.95, + "author": map[string]any{ + "age": int64(327), + "name": "Voltaire", + }, }, - }, - { - "name": "Zadig", - "rating": 4.91, - "author": map[string]any{ - "age": int64(327), - "name": "Voltaire", + { + "name": "Zadig", + "rating": 4.91, + "author": map[string]any{ + "age": int64(327), + "name": "Voltaire", + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_group_test.go b/tests/integration/query/one_to_many/with_group_test.go index 0cb74a4492..b1fe1034f8 100644 --- a/tests/integration/query/one_to_many/with_group_test.go +++ b/tests/integration/query/one_to_many/with_group_test.go @@ -72,41 +72,43 @@ func TestQueryOneToManyWithInnerJoinGroupNumber(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "age": int64(62), - "published": []map[string]any{ - { - "rating": 4.8, - "_group": []map[string]any{ - { - "name": "Theif Lord", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "age": int64(62), + "published": []map[string]any{ + { + "rating": 4.8, + "_group": []map[string]any{ + { + "name": "Theif Lord", + }, }, }, }, }, - }, - { - "name": "John Grisham", - "age": int64(65), - "published": []map[string]any{ - { - "rating": 4.5, - "_group": []map[string]any{ - { - "name": "The Client", - }, - { - "name": "A Time for Mercy", + { + "name": "John Grisham", + "age": int64(65), + "published": []map[string]any{ + { + "rating": 4.5, + "_group": []map[string]any{ + { + "name": "The Client", + }, + { + "name": "A Time for Mercy", + }, }, }, - }, - { - "rating": 4.9, - "_group": []map[string]any{ - { - "name": "Painted House", + { + "rating": 4.9, + "_group": []map[string]any{ + { + "name": "Painted House", + }, }, }, }, @@ -192,51 +194,53 @@ func TestQueryOneToManyWithParentJoinGroupNumber(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "age": int64(327), - "_group": []map[string]any{ - { - "name": "Voltaire", - "published": []map[string]any{ - { - "name": "Candide", - "rating": 4.95, - }, - { - "name": "Zadig", - "rating": 4.91, + Results: map[string]any{ + "Author": []map[string]any{ + { + "age": int64(327), + "_group": []map[string]any{ + { + "name": "Voltaire", + "published": []map[string]any{ + { + "name": "Candide", + "rating": 4.95, + }, + { + "name": "Zadig", + "rating": 4.91, + }, }, }, - }, - { - "name": "Simon Pelloutier", - "published": []map[string]any{ - { - "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", - "rating": float64(2), + { + "name": "Simon Pelloutier", + "published": []map[string]any{ + { + "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", + "rating": float64(2), + }, }, }, }, }, - }, - { - "age": int64(65), - "_group": []map[string]any{ - { - "name": "John Grisham", - "published": []map[string]any{ - { - "name": "The Client", - "rating": 4.5, - }, - { - "name": "Painted House", - "rating": 4.9, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, + { + "age": int64(65), + "_group": []map[string]any{ + { + "name": "John Grisham", + "published": []map[string]any{ + { + "name": "The Client", + "rating": 4.5, + }, + { + "name": "Painted House", + "rating": 4.9, + }, + { + "name": "A Time for Mercy", + "rating": 4.5, + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_limit_test.go b/tests/integration/query/one_to_many/with_limit_test.go index 6b518de6e1..1cfbaf6d98 100644 --- a/tests/integration/query/one_to_many/with_limit_test.go +++ b/tests/integration/query/one_to_many/with_limit_test.go @@ -63,22 +63,24 @@ func TestQueryOneToManyWithSingleChildLimit(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "published": []map[string]any{ - { - "name": "Theif Lord", - "rating": 4.8, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "published": []map[string]any{ + { + "name": "Theif Lord", + "rating": 4.8, + }, }, }, - }, - { - "name": "John Grisham", - "published": []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, + { + "name": "John Grisham", + "published": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, }, }, }, @@ -139,38 +141,40 @@ func TestQueryOneToManyWithMultipleChildLimits(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "p1": []map[string]any{ - { - "name": "Theif Lord", - "rating": 4.8, - }, - }, - "p2": []map[string]any{ - { - "name": "Theif Lord", - "rating": 4.8, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "p1": []map[string]any{ + { + "name": "Theif Lord", + "rating": 4.8, + }, }, - }, - }, - { - "name": "John Grisham", - "p1": []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, + "p2": []map[string]any{ + { + "name": "Theif Lord", + "rating": 4.8, + }, }, }, - "p2": []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, + { + "name": "John Grisham", + "p1": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, }, - { - "name": "A Time for Mercy", - "rating": 4.5, + "p2": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + { + "name": "A Time for Mercy", + "rating": 4.5, + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_order_filter_limit_test.go b/tests/integration/query/one_to_many/with_order_filter_limit_test.go index 46c27c474e..d10fabb100 100644 --- a/tests/integration/query/one_to_many/with_order_filter_limit_test.go +++ b/tests/integration/query/one_to_many/with_order_filter_limit_test.go @@ -66,14 +66,16 @@ func TestQueryOneToManyWithNumericGreaterThanFilterOnParentAndNumericSortAscendi }`, }, }, - Results: []map[string]any{ - { - "name": "John Grisham", - "age": int64(65), - "published": []map[string]any{ - { - "name": "A Time for Mercy", - "rating": 4.5, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "age": int64(65), + "published": []map[string]any{ + { + "name": "A Time for Mercy", + "rating": 4.5, + }, }, }, }, @@ -133,14 +135,16 @@ func TestQueryOneToManyWithNumericGreaterThanFilterOnParentAndNumericSortDescend }`, }, }, - Results: []map[string]any{ - { - "name": "John Grisham", - "age": int64(65), - "published": []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "age": int64(65), + "published": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_order_filter_test.go b/tests/integration/query/one_to_many/with_order_filter_test.go index 225d25a7f4..3aec1e6a73 100644 --- a/tests/integration/query/one_to_many/with_order_filter_test.go +++ b/tests/integration/query/one_to_many/with_order_filter_test.go @@ -66,18 +66,20 @@ func TestQueryOneToManyWithNumericGreaterThanFilterOnParentAndNumericSortAscendi }`, }, }, - Results: []map[string]any{ - { - "name": "John Grisham", - "age": int64(65), - "published": []map[string]any{ - { - "name": "A Time for Mercy", - "rating": 4.5, - }, - { - "name": "Painted House", - "rating": 4.9, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "age": int64(65), + "published": []map[string]any{ + { + "name": "A Time for Mercy", + "rating": 4.5, + }, + { + "name": "Painted House", + "rating": 4.9, + }, }, }, }, @@ -135,28 +137,30 @@ func TestQueryOneToManyWithNumericGreaterThanFilterAndNumericSortDescendingOnChi }`, }, }, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "age": int64(62), - "published": []map[string]any{ - { - "name": "Theif Lord", - "rating": 4.8, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "age": int64(62), + "published": []map[string]any{ + { + "name": "Theif Lord", + "rating": 4.8, + }, }, }, - }, - { - "name": "John Grisham", - "age": int64(65), - "published": []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, + { + "name": "John Grisham", + "age": int64(65), + "published": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + { + "name": "A Time for Mercy", + "rating": 4.5, + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_related_id_test.go b/tests/integration/query/one_to_many/with_related_id_test.go index 8626ffddd9..c5955352b5 100644 --- a/tests/integration/query/one_to_many/with_related_id_test.go +++ b/tests/integration/query/one_to_many/with_related_id_test.go @@ -86,30 +86,32 @@ func TestQueryOneToManyWithRelatedTypeIDFromManySide(t *testing.T) { }, }, - Results: []map[string]any{ - { - "name": "The Client", - "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", - }, - { - "name": "Painted House", - "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", - }, - { - "name": "A Time for Mercy", - "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", - }, - { - "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", - "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", - }, - { - "name": "Candide", - "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", - }, - { - "name": "Zadig", - "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "The Client", + "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", + }, + { + "name": "Painted House", + "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", + }, + { + "name": "A Time for Mercy", + "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", + }, + { + "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", + "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", + }, + { + "name": "Candide", + "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", + }, + { + "name": "Zadig", + "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", + }, }, }, } diff --git a/tests/integration/query/one_to_many/with_same_field_name_test.go b/tests/integration/query/one_to_many/with_same_field_name_test.go index 10136ae529..fbe56099b5 100644 --- a/tests/integration/query/one_to_many/with_same_field_name_test.go +++ b/tests/integration/query/one_to_many/with_same_field_name_test.go @@ -59,11 +59,13 @@ func TestQueryOneToManyWithSameFieldName(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Painted House", - "relationship1": map[string]any{ - "name": "John Grisham", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "relationship1": map[string]any{ + "name": "John Grisham", + }, }, }, }, @@ -93,12 +95,14 @@ func TestQueryOneToManyWithSameFieldName(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John Grisham", - "relationship1": []map[string]any{ - { - "name": "Painted House", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "relationship1": []map[string]any{ + { + "name": "Painted House", + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_sum_filter_order_test.go b/tests/integration/query/one_to_many/with_sum_filter_order_test.go index 96f2c14fc1..0c2fcc0b70 100644 --- a/tests/integration/query/one_to_many/with_sum_filter_order_test.go +++ b/tests/integration/query/one_to_many/with_sum_filter_order_test.go @@ -86,18 +86,20 @@ func TestOneToManyAscOrderAndFilterOnParentWithAggSumOnSubTypeField(t *testing.T }`, }, }, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_sum": 4.8, - }, - { - "name": "John Grisham", - "_sum": 20.8, - }, - { - "name": "Not a Writer", - "_sum": 0.0, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_sum": 4.8, + }, + { + "name": "John Grisham", + "_sum": 20.8, + }, + { + "name": "Not a Writer", + "_sum": 0.0, + }, }, }, } @@ -175,18 +177,20 @@ func TestOneToManyDescOrderAndFilterOnParentWithAggSumOnSubTypeField(t *testing. }`, }, }, - Results: []map[string]any{ - { - "name": "Not a Writer", - "_sum": 0.0, - }, - { - "name": "John Grisham", - "_sum": 20.8, - }, - { - "name": "Cornelia Funke", - "_sum": 4.8, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Not a Writer", + "_sum": 0.0, + }, + { + "name": "John Grisham", + "_sum": 20.8, + }, + { + "name": "Cornelia Funke", + "_sum": 4.8, + }, }, }, } @@ -265,26 +269,28 @@ func TestOnetoManySumBySubTypeFieldAndSumBySybTypeFieldWithDescOrderingOnFieldWi }`, }, }, - Results: []map[string]any{ - { - "name": "Little Kid", - "sum1": 0.0, - "sum2": 0.0, - }, - { - "name": "Not a Writer", - "sum1": 0.0, - "sum2": 0.0, - }, - { - "name": "Cornelia Funke", - "sum1": 4.8, - "sum2": 4.8, - }, - { - "name": "John Grisham", - "sum1": 20.8, - "sum2": 4.9 + 4.5, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Little Kid", + "sum1": 0.0, + "sum2": 0.0, + }, + { + "name": "Not a Writer", + "sum1": 0.0, + "sum2": 0.0, + }, + { + "name": "Cornelia Funke", + "sum1": 4.8, + "sum2": 4.8, + }, + { + "name": "John Grisham", + "sum1": 20.8, + "sum2": 4.9 + 4.5, + }, }, }, } @@ -363,26 +369,28 @@ func TestOnetoManySumBySubTypeFieldAndSumBySybTypeFieldWithAscOrderingOnFieldWit }`, }, }, - Results: []map[string]any{ - { - "name": "Little Kid", - "sum1": 0.0, - "sum2": 0.0, - }, - { - "name": "Not a Writer", - "sum1": 0.0, - "sum2": 0.0, - }, - { - "name": "Cornelia Funke", - "sum1": 4.8, - "sum2": 4.8, - }, - { - "name": "John Grisham", - "sum1": 20.8, - "sum2": 4.0 + 3.2, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Little Kid", + "sum1": 0.0, + "sum2": 0.0, + }, + { + "name": "Not a Writer", + "sum1": 0.0, + "sum2": 0.0, + }, + { + "name": "Cornelia Funke", + "sum1": 4.8, + "sum2": 4.8, + }, + { + "name": "John Grisham", + "sum1": 20.8, + "sum2": 4.0 + 3.2, + }, }, }, } @@ -462,31 +470,33 @@ func TestOneToManyLimitAscOrderSumOfSubTypeAndLimitAscOrderFieldsOfSubtype(t *te }`, }, }, - Results: []map[string]any{ - { - "LimitOrderSum": 0.0, - "LimitOrderFields": []map[string]any{}, - }, - { - "LimitOrderSum": 0.0, - "LimitOrderFields": []map[string]any{}, - }, - { - "LimitOrderSum": 4.8, - "LimitOrderFields": []map[string]any{ - { - "name": "Theif Lord", - }, + Results: map[string]any{ + "Author": []map[string]any{ + { + "LimitOrderSum": 0.0, + "LimitOrderFields": []map[string]any{}, }, - }, - { - "LimitOrderSum": 3.2 + 4.0, - "LimitOrderFields": []map[string]any{ - { - "name": "Sooley", + { + "LimitOrderSum": 0.0, + "LimitOrderFields": []map[string]any{}, + }, + { + "LimitOrderSum": 4.8, + "LimitOrderFields": []map[string]any{ + { + "name": "Theif Lord", + }, }, - { - "name": "The Rooster Bar", + }, + { + "LimitOrderSum": 3.2 + 4.0, + "LimitOrderFields": []map[string]any{ + { + "name": "Sooley", + }, + { + "name": "The Rooster Bar", + }, }, }, }, @@ -568,31 +578,33 @@ func TestOneToManyLimitDescOrderSumOfSubTypeAndLimitAscOrderFieldsOfSubtype(t *t }`, }, }, - Results: []map[string]any{ - { - "LimitOrderSum": 0.0, - "LimitOrderFields": []map[string]any{}, - }, - { - "LimitOrderSum": 0.0, - "LimitOrderFields": []map[string]any{}, - }, - { - "LimitOrderSum": 4.8, - "LimitOrderFields": []map[string]any{ - { - "name": "Theif Lord", - }, + Results: map[string]any{ + "Author": []map[string]any{ + { + "LimitOrderSum": 0.0, + "LimitOrderFields": []map[string]any{}, }, - }, - { - "LimitOrderSum": 4.9 + 4.5, - "LimitOrderFields": []map[string]any{ - { - "name": "Painted House", + { + "LimitOrderSum": 0.0, + "LimitOrderFields": []map[string]any{}, + }, + { + "LimitOrderSum": 4.8, + "LimitOrderFields": []map[string]any{ + { + "name": "Theif Lord", + }, }, - { - "name": "A Time for Mercy", + }, + { + "LimitOrderSum": 4.9 + 4.5, + "LimitOrderFields": []map[string]any{ + { + "name": "Painted House", + }, + { + "name": "A Time for Mercy", + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_sum_limit_offset_order_test.go b/tests/integration/query/one_to_many/with_sum_limit_offset_order_test.go index e7c4606071..91aacd889c 100644 --- a/tests/integration/query/one_to_many/with_sum_limit_offset_order_test.go +++ b/tests/integration/query/one_to_many/with_sum_limit_offset_order_test.go @@ -107,16 +107,18 @@ func TestQueryOneToManyWithSumWithLimitWithOffsetWithOrderAsc(t *testing.T) { _sum(published: {field: rating, offset: 1, limit: 2, order: {name: ASC}}) } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_sum": float64(0), - }, - { - "name": "John Grisham", - // 4.9 + 3.2 - // ...00001 is float math artifact - "_sum": 8.100000000000001, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_sum": float64(0), + }, + { + "name": "John Grisham", + // 4.9 + 3.2 + // ...00001 is float math artifact + "_sum": 8.100000000000001, + }, }, }, }, @@ -217,15 +219,17 @@ func TestQueryOneToManyWithSumWithLimitWithOffsetWithOrderDesc(t *testing.T) { _sum(published: {field: rating, offset: 1, limit: 2, order: {name: DESC}}) } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_sum": float64(0), - }, - { - "name": "John Grisham", - // 4.2 + 3.2 - "_sum": 7.4, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_sum": float64(0), + }, + { + "name": "John Grisham", + // 4.2 + 3.2 + "_sum": 7.4, + }, }, }, }, @@ -327,19 +331,21 @@ func TestQueryOneToManyWithSumWithLimitWithOffsetWithOrderAscAndDesc(t *testing. desc: _sum(published: {field: rating, offset: 1, limit: 2, order: {name: DESC}}) } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "asc": float64(0), - "desc": float64(0), - }, - { - "name": "John Grisham", - // 4.9 + 3.2 - // ...00001 is float math artifact - "asc": 8.100000000000001, - // 4.2 + 3.2 - "desc": 7.4, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "asc": float64(0), + "desc": float64(0), + }, + { + "name": "John Grisham", + // 4.9 + 3.2 + // ...00001 is float math artifact + "asc": 8.100000000000001, + // 4.2 + 3.2 + "desc": 7.4, + }, }, }, }, @@ -441,18 +447,20 @@ func TestQueryOneToManyWithSumWithLimitWithOffsetWithOrderOnDifferentFields(t *t byRating: _sum(published: {field: rating, offset: 1, limit: 2, order: {rating: DESC}}) } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "byName": float64(0), - "byRating": float64(0), - }, - { - "name": "John Grisham", - // 4.2 + 3.2 - "byName": 7.4, - // 4.5 + 4.2 - "byRating": 8.7, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "byName": float64(0), + "byRating": float64(0), + }, + { + "name": "John Grisham", + // 4.2 + 3.2 + "byName": 7.4, + // 4.5 + 4.2 + "byRating": 8.7, + }, }, }, }, @@ -556,22 +564,24 @@ func TestQueryOneToManyWithSumWithLimitWithOffsetWithOrderDescAndRenderedChildre } } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_sum": float64(0), - "published": []map[string]any{}, - }, - { - "name": "John Grisham", - // 4.2 + 3.2 - "_sum": 7.4, - "published": []map[string]any{ - { - "name": "Painted House", - }, - { - "name": "Sooley", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_sum": float64(0), + "published": []map[string]any{}, + }, + { + "name": "John Grisham", + // 4.2 + 3.2 + "_sum": 7.4, + "published": []map[string]any{ + { + "name": "Painted House", + }, + { + "name": "Sooley", + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_sum_limit_offset_test.go b/tests/integration/query/one_to_many/with_sum_limit_offset_test.go index ea89759d72..3fce23bfd5 100644 --- a/tests/integration/query/one_to_many/with_sum_limit_offset_test.go +++ b/tests/integration/query/one_to_many/with_sum_limit_offset_test.go @@ -65,14 +65,16 @@ func TestQueryOneToManyWithSumWithLimitAndOffset(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_sum": float64(0), - }, - { - "name": "John Grisham", - "_sum": 9.4, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_sum": float64(0), + }, + { + "name": "John Grisham", + "_sum": 9.4, + }, }, }, } diff --git a/tests/integration/query/one_to_many/with_sum_limit_test.go b/tests/integration/query/one_to_many/with_sum_limit_test.go index f7fe551567..4ab46b65bd 100644 --- a/tests/integration/query/one_to_many/with_sum_limit_test.go +++ b/tests/integration/query/one_to_many/with_sum_limit_test.go @@ -65,15 +65,17 @@ func TestQueryOneToManyWithSumWithLimit(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_sum": 4.8, - }, - { - "name": "John Grisham", - // .00...1 is float math thing - "_sum": 9.100000000000001, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_sum": 4.8, + }, + { + "name": "John Grisham", + // .00...1 is float math thing + "_sum": 9.100000000000001, + }, }, }, } diff --git a/tests/integration/query/one_to_many/with_typename_test.go b/tests/integration/query/one_to_many/with_typename_test.go index db318066f0..da627c8625 100644 --- a/tests/integration/query/one_to_many/with_typename_test.go +++ b/tests/integration/query/one_to_many/with_typename_test.go @@ -47,13 +47,15 @@ func TestQueryOneToManyWithTypeName(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Painted House", - "__typename": "Book", - "author": map[string]any{ - "name": "John Grisham", - "__typename": "Author", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "__typename": "Book", + "author": map[string]any{ + "name": "John Grisham", + "__typename": "Author", + }, }, }, }, diff --git a/tests/integration/query/one_to_many_multiple/with_average_filter_test.go b/tests/integration/query/one_to_many_multiple/with_average_filter_test.go index 9685790830..df4b6b5f2a 100644 --- a/tests/integration/query/one_to_many_multiple/with_average_filter_test.go +++ b/tests/integration/query/one_to_many_multiple/with_average_filter_test.go @@ -122,14 +122,16 @@ func TestQueryOneToManyMultipleWithAverageOnMultipleJoinsWithAndWithoutFilter(t _avg(books: {field: score, filter: {score: {_gt: 3}}}, articles: {field: rating}) } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_avg": float64(2.3333333333333335), - }, - { - "name": "John Grisham", - "_avg": float64(3), + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_avg": float64(2.3333333333333335), + }, + { + "name": "John Grisham", + "_avg": float64(3), + }, }, }, }, @@ -245,14 +247,16 @@ func TestQueryOneToManyMultipleWithAverageOnMultipleJoinsWithFilters(t *testing. _avg(books: {field: score, filter: {score: {_gt: 3}}}, articles: {field: rating, filter: {rating: {_lt: 3}}}) } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_avg": float64(2.3333333333333335), - }, - { - "name": "John Grisham", - "_avg": float64(0), + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_avg": float64(2.3333333333333335), + }, + { + "name": "John Grisham", + "_avg": float64(0), + }, }, }, }, diff --git a/tests/integration/query/one_to_many_multiple/with_average_test.go b/tests/integration/query/one_to_many_multiple/with_average_test.go index a2af6b6a67..bf39888974 100644 --- a/tests/integration/query/one_to_many_multiple/with_average_test.go +++ b/tests/integration/query/one_to_many_multiple/with_average_test.go @@ -122,14 +122,16 @@ func TestQueryOneToManyMultipleWithAverageOnMultipleJoins(t *testing.T) { _avg(books: {field: score}, articles: {field: rating}) } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_avg": float64(2.3333333333333335), - }, - { - "name": "John Grisham", - "_avg": float64(2.25), + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_avg": float64(2.3333333333333335), + }, + { + "name": "John Grisham", + "_avg": float64(2.25), + }, }, }, }, diff --git a/tests/integration/query/one_to_many_multiple/with_count_filter_test.go b/tests/integration/query/one_to_many_multiple/with_count_filter_test.go index 9cb9409d41..5aeca2386a 100644 --- a/tests/integration/query/one_to_many_multiple/with_count_filter_test.go +++ b/tests/integration/query/one_to_many_multiple/with_count_filter_test.go @@ -122,14 +122,16 @@ func TestQueryOneToManyMultipleWithCountOnMultipleJoinsWithAndWithoutFilter(t *t _count(books: {filter: {score: {_gt: 3}}}, articles: {}) } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 3, - }, - { - "name": "John Grisham", - "_count": 1, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_count": 3, + }, + { + "name": "John Grisham", + "_count": 1, + }, }, }, }, @@ -245,14 +247,16 @@ func TestQueryOneToManyMultipleWithCountOnMultipleJoinsWithFilters(t *testing.T) _count(books: {filter: {score: {_gt: 3}}}, articles: {filter: {rating: {_lt: 3}}}) } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 3, - }, - { - "name": "John Grisham", - "_count": 0, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_count": 3, + }, + { + "name": "John Grisham", + "_count": 0, + }, }, }, }, diff --git a/tests/integration/query/one_to_many_multiple/with_count_test.go b/tests/integration/query/one_to_many_multiple/with_count_test.go index f6155ffc16..eb932c80ad 100644 --- a/tests/integration/query/one_to_many_multiple/with_count_test.go +++ b/tests/integration/query/one_to_many_multiple/with_count_test.go @@ -115,16 +115,18 @@ func TestQueryOneToManyMultipleWithCount(t *testing.T) { numberOfArticles: _count(articles: {}) } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "numberOfBooks": 1, - "numberOfArticles": 2, - }, - { - "name": "John Grisham", - "numberOfBooks": 2, - "numberOfArticles": 1, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "numberOfBooks": 1, + "numberOfArticles": 2, + }, + { + "name": "John Grisham", + "numberOfBooks": 2, + "numberOfArticles": 1, + }, }, }, }, @@ -240,14 +242,16 @@ func TestQueryOneToManyMultipleWithCountOnMultipleJoins(t *testing.T) { _count(books: {}, articles: {}) } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 3, - }, - { - "name": "John Grisham", - "_count": 4, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_count": 3, + }, + { + "name": "John Grisham", + "_count": 4, + }, }, }, }, diff --git a/tests/integration/query/one_to_many_multiple/with_multiple_filter_test.go b/tests/integration/query/one_to_many_multiple/with_multiple_filter_test.go index a30f2f78a1..99bc3b2801 100644 --- a/tests/integration/query/one_to_many_multiple/with_multiple_filter_test.go +++ b/tests/integration/query/one_to_many_multiple/with_multiple_filter_test.go @@ -121,9 +121,11 @@ func TestQueryOneToManyMultipleWithMultipleManyFilters(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John Grisham", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + }, }, }, }, diff --git a/tests/integration/query/one_to_many_multiple/with_sum_filter_test.go b/tests/integration/query/one_to_many_multiple/with_sum_filter_test.go index f5f278a1f2..a35dce9aca 100644 --- a/tests/integration/query/one_to_many_multiple/with_sum_filter_test.go +++ b/tests/integration/query/one_to_many_multiple/with_sum_filter_test.go @@ -122,14 +122,16 @@ func TestQueryOneToManyMultipleWithSumOnMultipleJoinsWithAndWithoutFilter(t *tes _sum(books: {field: score, filter: {score: {_gt: 3}}}, articles: {field: rating}) } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_sum": int64(7), - }, - { - "name": "John Grisham", - "_sum": int64(3), + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_sum": int64(7), + }, + { + "name": "John Grisham", + "_sum": int64(3), + }, }, }, }, @@ -245,14 +247,16 @@ func TestQueryOneToManyMultipleWithSumOnMultipleJoinsWithFilters(t *testing.T) { _sum(books: {field: score, filter: {score: {_gt: 3}}}, articles: {field: rating, filter: {rating: {_lt: 3}}}) } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_sum": int64(7), - }, - { - "name": "John Grisham", - "_sum": int64(0), + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_sum": int64(7), + }, + { + "name": "John Grisham", + "_sum": int64(0), + }, }, }, }, diff --git a/tests/integration/query/one_to_many_multiple/with_sum_test.go b/tests/integration/query/one_to_many_multiple/with_sum_test.go index a1f9176722..b7f1e9d5d1 100644 --- a/tests/integration/query/one_to_many_multiple/with_sum_test.go +++ b/tests/integration/query/one_to_many_multiple/with_sum_test.go @@ -122,14 +122,16 @@ func TestQueryOneToManyMultipleWithSumOnMultipleJoins(t *testing.T) { _sum(books: {field: score}, articles: {field: rating}) } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "_sum": int64(7), - }, - { - "name": "John Grisham", - "_sum": int64(9), + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_sum": int64(7), + }, + { + "name": "John Grisham", + "_sum": int64(9), + }, }, }, }, diff --git a/tests/integration/query/one_to_many_to_many/joins_test.go b/tests/integration/query/one_to_many_to_many/joins_test.go index 1143eb1ba9..7fe84162e1 100644 --- a/tests/integration/query/one_to_many_to_many/joins_test.go +++ b/tests/integration/query/one_to_many_to_many/joins_test.go @@ -185,78 +185,80 @@ func TestOneToManyToManyJoinsAreLinkedProperly(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "_docID": testUtils.NewDocIndex(0, 2), - "book": []map[string]any{}, - "name": "Not a Writer", - }, - { - "name": "Cornelia Funke", - "_docID": testUtils.NewDocIndex(0, 1), - "book": []map[string]any{ - { - "_docID": testUtils.NewDocIndex(1, 0), - "name": "The Rooster Bar", - "publisher": []map[string]any{ - { - "_docID": testUtils.NewDocIndex(2, 0), - "name": "Only Publisher of The Rooster Bar", + Results: map[string]any{ + "Author": []map[string]any{ + { + "_docID": testUtils.NewDocIndex(0, 2), + "book": []map[string]any{}, + "name": "Not a Writer", + }, + { + "name": "Cornelia Funke", + "_docID": testUtils.NewDocIndex(0, 1), + "book": []map[string]any{ + { + "_docID": testUtils.NewDocIndex(1, 0), + "name": "The Rooster Bar", + "publisher": []map[string]any{ + { + "_docID": testUtils.NewDocIndex(2, 0), + "name": "Only Publisher of The Rooster Bar", + }, }, }, }, }, - }, - { - "name": "John Grisham", - "_docID": testUtils.NewDocIndex(0, 0), - "book": []map[string]any{ - { - "_docID": testUtils.NewDocIndex(1, 1), - "name": "Theif Lord", - "publisher": []map[string]any{ - { - "_docID": testUtils.NewDocIndex(2, 1), - "name": "Only Publisher of Theif Lord", + { + "name": "John Grisham", + "_docID": testUtils.NewDocIndex(0, 0), + "book": []map[string]any{ + { + "_docID": testUtils.NewDocIndex(1, 1), + "name": "Theif Lord", + "publisher": []map[string]any{ + { + "_docID": testUtils.NewDocIndex(2, 1), + "name": "Only Publisher of Theif Lord", + }, }, }, - }, - { - "_docID": testUtils.NewDocIndex(1, 2), - "name": "The Associate", - "publisher": []map[string]any{}, - }, - { - "_docID": testUtils.NewDocIndex(1, 3), - "name": "Painted House", - "publisher": []map[string]any{ - { - "_docID": testUtils.NewDocIndex(2, 2), - "name": "Only Publisher of Painted House", - }, + { + "_docID": testUtils.NewDocIndex(1, 2), + "name": "The Associate", + "publisher": []map[string]any{}, }, - }, - { - "_docID": testUtils.NewDocIndex(1, 4), - "name": "A Time for Mercy", - "publisher": []map[string]any{ - { - "_docID": testUtils.NewDocIndex(2, 3), - "name": "Only Publisher of A Time for Mercy", + { + "_docID": testUtils.NewDocIndex(1, 3), + "name": "Painted House", + "publisher": []map[string]any{ + { + "_docID": testUtils.NewDocIndex(2, 2), + "name": "Only Publisher of Painted House", + }, }, }, - }, - { - "_docID": testUtils.NewDocIndex(1, 5), - "name": "Sooley", - "publisher": []map[string]any{ - { - "_docID": testUtils.NewDocIndex(2, 5), - "name": "Second of Two Publishers of Sooley", + { + "_docID": testUtils.NewDocIndex(1, 4), + "name": "A Time for Mercy", + "publisher": []map[string]any{ + { + "_docID": testUtils.NewDocIndex(2, 3), + "name": "Only Publisher of A Time for Mercy", + }, }, - { - "_docID": testUtils.NewDocIndex(2, 4), - "name": "First of Two Publishers of Sooley", + }, + { + "_docID": testUtils.NewDocIndex(1, 5), + "name": "Sooley", + "publisher": []map[string]any{ + { + "_docID": testUtils.NewDocIndex(2, 5), + "name": "Second of Two Publishers of Sooley", + }, + { + "_docID": testUtils.NewDocIndex(2, 4), + "name": "First of Two Publishers of Sooley", + }, }, }, }, diff --git a/tests/integration/query/one_to_many_to_one/joins_test.go b/tests/integration/query/one_to_many_to_one/joins_test.go index 9cd6432112..1699096357 100644 --- a/tests/integration/query/one_to_many_to_one/joins_test.go +++ b/tests/integration/query/one_to_many_to_one/joins_test.go @@ -165,65 +165,67 @@ func TestOneToManyToOneJoinsAreLinkedProperly(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "_docID": "bae-489b4e01-4764-56f6-913f-b3c92dffcaa3", - "book": []map[string]any{}, - "name": "Not a Writer", - }, - { - "name": "John Grisham", - "_docID": "bae-7aabc9d2-fbbc-5911-b0d0-b49a2a1d0e84", - "book": []map[string]any{ - { - "_docID": "bae-1d0dcbed-300a-567a-9b48-c23cd026d165", - "name": "A Time for Mercy", - "publisher": map[string]any{ - "_docID": "bae-2bad7de3-0f1a-56c0-b499-a552debef4b8", - "name": "Only Publisher of A Time for Mercy", + Results: map[string]any{ + "Author": []map[string]any{ + { + "_docID": "bae-489b4e01-4764-56f6-913f-b3c92dffcaa3", + "book": []map[string]any{}, + "name": "Not a Writer", + }, + { + "name": "John Grisham", + "_docID": "bae-7aabc9d2-fbbc-5911-b0d0-b49a2a1d0e84", + "book": []map[string]any{ + { + "_docID": "bae-1d0dcbed-300a-567a-9b48-c23cd026d165", + "name": "A Time for Mercy", + "publisher": map[string]any{ + "_docID": "bae-2bad7de3-0f1a-56c0-b499-a552debef4b8", + "name": "Only Publisher of A Time for Mercy", + }, }, - }, - { - "_docID": "bae-374998e0-e84d-5f6b-9e87-5edaaa2d9c7d", - "name": "The Associate", - "publisher": nil, - }, - { - "_docID": "bae-7697f14d-7b32-5884-8677-344e183c14bf", - "name": "Theif Lord", - "publisher": map[string]any{ - "_docID": "bae-d43823c0-0bb6-58a9-a098-1826dffa4e4a", - "name": "Only Publisher of Theif Lord", + { + "_docID": "bae-374998e0-e84d-5f6b-9e87-5edaaa2d9c7d", + "name": "The Associate", + "publisher": nil, }, - }, - { - "_docID": "bae-aef1d940-5ac1-5924-a87f-63ac40758b22", - "name": "Painted House", - "publisher": map[string]any{ - "_docID": "bae-a104397b-7804-5cd0-93e5-c3986b4e5e71", - "name": "Only Publisher of Painted House", + { + "_docID": "bae-7697f14d-7b32-5884-8677-344e183c14bf", + "name": "Theif Lord", + "publisher": map[string]any{ + "_docID": "bae-d43823c0-0bb6-58a9-a098-1826dffa4e4a", + "name": "Only Publisher of Theif Lord", + }, }, - }, - { - "_docID": "bae-ee6b8339-8a9e-58a9-9a0d-dbd8d44fa149", - "name": "Sooley", - "publisher": map[string]any{ - "_docID": "bae-efeca601-cce1-5289-b392-85fa5b7bc0f7", - "name": "Only Publisher of Sooley", + { + "_docID": "bae-aef1d940-5ac1-5924-a87f-63ac40758b22", + "name": "Painted House", + "publisher": map[string]any{ + "_docID": "bae-a104397b-7804-5cd0-93e5-c3986b4e5e71", + "name": "Only Publisher of Painted House", + }, + }, + { + "_docID": "bae-ee6b8339-8a9e-58a9-9a0d-dbd8d44fa149", + "name": "Sooley", + "publisher": map[string]any{ + "_docID": "bae-efeca601-cce1-5289-b392-85fa5b7bc0f7", + "name": "Only Publisher of Sooley", + }, }, }, }, - }, - { - "name": "Cornelia Funke", - "_docID": "bae-fb2a1852-3951-5ce9-a3bf-6825202f201b", - "book": []map[string]any{ - { - "_docID": "bae-1867d7cb-01b3-572f-a993-1c3f22f46526", - "name": "The Rooster Bar", - "publisher": map[string]any{ - "_docID": "bae-09af7e39-8596-584f-8825-cb430c4156b3", - "name": "Only Publisher of The Rooster Bar", + { + "name": "Cornelia Funke", + "_docID": "bae-fb2a1852-3951-5ce9-a3bf-6825202f201b", + "book": []map[string]any{ + { + "_docID": "bae-1867d7cb-01b3-572f-a993-1c3f22f46526", + "name": "The Rooster Bar", + "publisher": map[string]any{ + "_docID": "bae-09af7e39-8596-584f-8825-cb430c4156b3", + "name": "Only Publisher of The Rooster Bar", + }, }, }, }, diff --git a/tests/integration/query/one_to_many_to_one/simple_test.go b/tests/integration/query/one_to_many_to_one/simple_test.go index d1551300da..da6206c1e7 100644 --- a/tests/integration/query/one_to_many_to_one/simple_test.go +++ b/tests/integration/query/one_to_many_to_one/simple_test.go @@ -108,30 +108,32 @@ func TestQueryOneToOneRelations(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "The Rooster Bar", - "author": map[string]any{ - "name": "Cornelia Funke", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "The Rooster Bar", + "author": map[string]any{ + "name": "Cornelia Funke", + }, + "publisher": map[string]any{ + "name": "Only Publisher of The Rooster Bar", + }, }, - "publisher": map[string]any{ - "name": "Only Publisher of The Rooster Bar", + { + "name": "The Associate", + "author": map[string]any{ + "name": "John Grisham", + }, + "publisher": nil, }, - }, - { - "name": "The Associate", - "author": map[string]any{ - "name": "John Grisham", - }, - "publisher": nil, - }, - { - "name": "Theif Lord", - "author": map[string]any{ - "name": "John Grisham", - }, - "publisher": map[string]any{ - "name": "Only Publisher of Theif Lord", + { + "name": "Theif Lord", + "author": map[string]any{ + "name": "John Grisham", + }, + "publisher": map[string]any{ + "name": "Only Publisher of Theif Lord", + }, }, }, }, diff --git a/tests/integration/query/one_to_many_to_one/with_filter_test.go b/tests/integration/query/one_to_many_to_one/with_filter_test.go index bd56f7bc39..147f71f790 100644 --- a/tests/integration/query/one_to_many_to_one/with_filter_test.go +++ b/tests/integration/query/one_to_many_to_one/with_filter_test.go @@ -106,13 +106,15 @@ func TestQueryComplexWithDeepFilterOnRenderedChildren(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "book": []map[string]any{ - { - "publisher": map[string]any{ - "yearOpened": int64(2022), + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "book": []map[string]any{ + { + "publisher": map[string]any{ + "yearOpened": int64(2022), + }, }, }, }, @@ -139,23 +141,25 @@ func TestOneToManyToOneWithSumOfDeepFilterSubTypeOfBothDescAndAsc(t *testing.T) s2: _sum(book: {field: rating, filter: {publisher: {yearOpened: {_ge: 2020}}}}) } }`, - Results: []map[string]any{ - { - "name": "Not a Writer", - "s1": 0.0, - "s2": 0.0, - }, - { - "name": "John Grisham", - // 'Theif Lord' (4.8 rating) 2020, then 'A Time for Mercy' 2013 (4.5 rating). - "s1": 4.5, - // 'The Associate' as it has no Publisher (4.2 rating), then 'Painted House' 1995 (4.9 rating). - "s2": 4.8, - }, - { - "name": "Cornelia Funke", - "s1": 0.0, - "s2": 4.0, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Not a Writer", + "s1": 0.0, + "s2": 0.0, + }, + { + "name": "John Grisham", + // 'Theif Lord' (4.8 rating) 2020, then 'A Time for Mercy' 2013 (4.5 rating). + "s1": 4.5, + // 'The Associate' as it has no Publisher (4.2 rating), then 'Painted House' 1995 (4.9 rating). + "s2": 4.8, + }, + { + "name": "Cornelia Funke", + "s1": 0.0, + "s2": 4.0, + }, }, }, }, @@ -181,27 +185,29 @@ func TestOneToManyToOneWithSumOfDeepFilterSubTypeAndDeepOrderBySubtypeOppositeDi } } }`, - Results: []map[string]any{ - { - "name": "Not a Writer", - "s1": 0.0, - "books2020": []map[string]any{}, - }, - { - "name": "John Grisham", - "s1": 4.5, - "books2020": []map[string]any{ - { - "name": "Theif Lord", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Not a Writer", + "s1": 0.0, + "books2020": []map[string]any{}, + }, + { + "name": "John Grisham", + "s1": 4.5, + "books2020": []map[string]any{ + { + "name": "Theif Lord", + }, }, }, - }, - { - "name": "Cornelia Funke", - "s1": 0.0, - "books2020": []map[string]any{ - { - "name": "The Rooster Bar", + { + "name": "Cornelia Funke", + "s1": 0.0, + "books2020": []map[string]any{ + { + "name": "The Rooster Bar", + }, }, }, }, @@ -231,50 +237,52 @@ func TestOneToManyToOneWithTwoLevelDeepFilter(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "book": []map[string]any{ - { - "name": "A Time for Mercy", - "publisher": map[string]any{ - "yearOpened": int64(2013), + Results: map[string]any{ + "Author": []map[string]any{ + { + "book": []map[string]any{ + { + "name": "A Time for Mercy", + "publisher": map[string]any{ + "yearOpened": int64(2013), + }, }, - }, - { - "name": "The Associate", - "publisher": nil, - }, - { - "name": "Theif Lord", - "publisher": map[string]any{ - "yearOpened": int64(2020), + { + "name": "The Associate", + "publisher": nil, }, - }, - { - "name": "Painted House", - "publisher": map[string]any{ - "yearOpened": int64(1995), + { + "name": "Theif Lord", + "publisher": map[string]any{ + "yearOpened": int64(2020), + }, }, - }, - { - "name": "Sooley", - "publisher": map[string]any{ - "yearOpened": int64(1999), + { + "name": "Painted House", + "publisher": map[string]any{ + "yearOpened": int64(1995), + }, + }, + { + "name": "Sooley", + "publisher": map[string]any{ + "yearOpened": int64(1999), + }, }, }, + "name": "John Grisham", }, - "name": "John Grisham", - }, - { - "book": []map[string]any{ - { - "name": "The Rooster Bar", - "publisher": map[string]any{ - "yearOpened": int64(2022), + { + "book": []map[string]any{ + { + "name": "The Rooster Bar", + "publisher": map[string]any{ + "yearOpened": int64(2022), + }, }, }, + "name": "Cornelia Funke", }, - "name": "Cornelia Funke", }, }, }, @@ -327,12 +335,14 @@ func TestOneToManyToOneWithCompoundOperatorInFilterAndRelation(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John Tolkien", - }, - { - "name": "Cornelia Funke", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Tolkien", + }, + { + "name": "Cornelia Funke", + }, }, }, }, @@ -349,9 +359,11 @@ func TestOneToManyToOneWithCompoundOperatorInFilterAndRelation(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John Grisham", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + }, }, }, }, @@ -388,12 +400,16 @@ func TestOneToManyToOneWithCompoundOperatorInSubFilterAndRelation(t *testing.T) } } }`, - Results: []map[string]any{{ - "name": "John Grisham", - "book": []map[string]any{{ - "name": "Sooley", - }}, - }}, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "book": []map[string]any{{ + "name": "Sooley", + }}, + }, + }, + }, }, }, } diff --git a/tests/integration/query/one_to_many_to_one/with_order_limit_test.go b/tests/integration/query/one_to_many_to_one/with_order_limit_test.go index 1ec7c0296e..196dd3bdf6 100644 --- a/tests/integration/query/one_to_many_to_one/with_order_limit_test.go +++ b/tests/integration/query/one_to_many_to_one/with_order_limit_test.go @@ -34,35 +34,37 @@ func TestOneToManyToOneDeepOrderBySubTypeOfBothDescAndAsc(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Not a Writer", - "NewestPublishersBook": []map[string]any{}, - "OldestPublishersBook": []map[string]any{}, - }, - { - "name": "John Grisham", - "NewestPublishersBook": []map[string]any{ - { - "name": "Theif Lord", - }, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Not a Writer", + "NewestPublishersBook": []map[string]any{}, + "OldestPublishersBook": []map[string]any{}, }, - "OldestPublishersBook": []map[string]any{ - { - "name": "The Associate", // oldest because has no Publisher. + { + "name": "John Grisham", + "NewestPublishersBook": []map[string]any{ + { + "name": "Theif Lord", + }, }, - }, - }, - { - "name": "Cornelia Funke", - "NewestPublishersBook": []map[string]any{ - { - "name": "The Rooster Bar", + "OldestPublishersBook": []map[string]any{ + { + "name": "The Associate", // oldest because has no Publisher. + }, }, }, - "OldestPublishersBook": []map[string]any{ - { - "name": "The Rooster Bar", + { + "name": "Cornelia Funke", + "NewestPublishersBook": []map[string]any{ + { + "name": "The Rooster Bar", + }, + }, + "OldestPublishersBook": []map[string]any{ + { + "name": "The Rooster Bar", + }, }, }, }, diff --git a/tests/integration/query/one_to_many_to_one/with_order_test.go b/tests/integration/query/one_to_many_to_one/with_order_test.go index 91fccbe8d6..5036faf6d9 100644 --- a/tests/integration/query/one_to_many_to_one/with_order_test.go +++ b/tests/integration/query/one_to_many_to_one/with_order_test.go @@ -33,50 +33,52 @@ func TestMultipleOrderByWithDepthGreaterThanOne(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Sooley", - "rating": 3.2, - "publisher": map[string]any{ - "name": "Only Publisher of Sooley", - "yearOpened": int64(1999), + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Sooley", + "rating": 3.2, + "publisher": map[string]any{ + "name": "Only Publisher of Sooley", + "yearOpened": int64(1999), + }, }, - }, - { - "name": "The Rooster Bar", - "rating": 4.0, - "publisher": map[string]any{ - "name": "Only Publisher of The Rooster Bar", - "yearOpened": int64(2022), + { + "name": "The Rooster Bar", + "rating": 4.0, + "publisher": map[string]any{ + "name": "Only Publisher of The Rooster Bar", + "yearOpened": int64(2022), + }, }, - }, - { - "name": "The Associate", - "rating": 4.2, - "publisher": nil, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, - "publisher": map[string]any{ - "name": "Only Publisher of A Time for Mercy", - "yearOpened": int64(2013), + { + "name": "The Associate", + "rating": 4.2, + "publisher": nil, }, - }, - { - "name": "Theif Lord", - "rating": 4.8, - "publisher": map[string]any{ - "name": "Only Publisher of Theif Lord", - "yearOpened": int64(2020), + { + "name": "A Time for Mercy", + "rating": 4.5, + "publisher": map[string]any{ + "name": "Only Publisher of A Time for Mercy", + "yearOpened": int64(2013), + }, }, - }, - { - "name": "Painted House", - "rating": 4.9, - "publisher": map[string]any{ - "name": "Only Publisher of Painted House", - "yearOpened": int64(1995), + { + "name": "Theif Lord", + "rating": 4.8, + "publisher": map[string]any{ + "name": "Only Publisher of Theif Lord", + "yearOpened": int64(2020), + }, + }, + { + "name": "Painted House", + "rating": 4.9, + "publisher": map[string]any{ + "name": "Only Publisher of Painted House", + "yearOpened": int64(1995), + }, }, }, }, @@ -104,51 +106,53 @@ func TestMultipleOrderByWithDepthGreaterThanOneOrderSwitched(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "The Rooster Bar", - "rating": 4.0, - "publisher": map[string]any{ - "name": "Only Publisher of The Rooster Bar", - "yearOpened": int64(2022), + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "The Rooster Bar", + "rating": 4.0, + "publisher": map[string]any{ + "name": "Only Publisher of The Rooster Bar", + "yearOpened": int64(2022), + }, }, - }, - { - "name": "Theif Lord", - "rating": 4.8, - "publisher": map[string]any{ - "name": "Only Publisher of Theif Lord", - "yearOpened": int64(2020), + { + "name": "Theif Lord", + "rating": 4.8, + "publisher": map[string]any{ + "name": "Only Publisher of Theif Lord", + "yearOpened": int64(2020), + }, }, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, - "publisher": map[string]any{ - "name": "Only Publisher of A Time for Mercy", - "yearOpened": int64(2013), + { + "name": "A Time for Mercy", + "rating": 4.5, + "publisher": map[string]any{ + "name": "Only Publisher of A Time for Mercy", + "yearOpened": int64(2013), + }, }, - }, - { - "name": "Sooley", - "rating": 3.2, - "publisher": map[string]any{ - "name": "Only Publisher of Sooley", - "yearOpened": int64(1999), + { + "name": "Sooley", + "rating": 3.2, + "publisher": map[string]any{ + "name": "Only Publisher of Sooley", + "yearOpened": int64(1999), + }, }, - }, - { - "name": "Painted House", - "rating": 4.9, - "publisher": map[string]any{ - "name": "Only Publisher of Painted House", - "yearOpened": int64(1995), + { + "name": "Painted House", + "rating": 4.9, + "publisher": map[string]any{ + "name": "Only Publisher of Painted House", + "yearOpened": int64(1995), + }, + }, + { + "name": "The Associate", + "rating": 4.2, + "publisher": nil, }, - }, - { - "name": "The Associate", - "rating": 4.2, - "publisher": nil, }, }, }, diff --git a/tests/integration/query/one_to_many_to_one/with_sum_order_limit_test.go b/tests/integration/query/one_to_many_to_one/with_sum_order_limit_test.go index 28379253b4..93e3040460 100644 --- a/tests/integration/query/one_to_many_to_one/with_sum_order_limit_test.go +++ b/tests/integration/query/one_to_many_to_one/with_sum_order_limit_test.go @@ -32,30 +32,32 @@ func TestOneToManyToOneWithSumOfDeepOrderBySubTypeAndDeepOrderBySubtypeDescDirec } } }`, - Results: []map[string]any{ - { - "name": "Not a Writer", - "s1": 0.0, - "NewestPublishersBook": []map[string]any{}, - }, - { - "name": "John Grisham", - "s1": 4.8 + 4.5, // Because in descending order years for John are [2020, 2013]. - "NewestPublishersBook": []map[string]any{ - { - "name": "Theif Lord", - }, - { - "name": "A Time for Mercy", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Not a Writer", + "s1": 0.0, + "NewestPublishersBook": []map[string]any{}, + }, + { + "name": "John Grisham", + "s1": 4.8 + 4.5, // Because in descending order years for John are [2020, 2013]. + "NewestPublishersBook": []map[string]any{ + { + "name": "Theif Lord", + }, + { + "name": "A Time for Mercy", + }, }, }, - }, - { - "name": "Cornelia Funke", - "s1": 4.0, - "NewestPublishersBook": []map[string]any{ - { - "name": "The Rooster Bar", + { + "name": "Cornelia Funke", + "s1": 4.0, + "NewestPublishersBook": []map[string]any{ + { + "name": "The Rooster Bar", + }, }, }, }, @@ -82,32 +84,34 @@ func TestOneToManyToOneWithSumOfDeepOrderBySubTypeAndDeepOrderBySubtypeAscDirect } } }`, - Results: []map[string]any{ - { - "name": "Not a Writer", - "s1": 0.0, - "NewestPublishersBook": []map[string]any{}, - }, - { - "name": "John Grisham", - // Because in ascending order years for John are: - // 'The Associate' as it has no Publisher (4.2 rating), then 'Painted House' 1995 (4.9 rating). - "s1": float64(4.2) + float64(4.9), - "NewestPublishersBook": []map[string]any{ - { - "name": "The Associate", - }, - { - "name": "Painted House", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Not a Writer", + "s1": 0.0, + "NewestPublishersBook": []map[string]any{}, + }, + { + "name": "John Grisham", + // Because in ascending order years for John are: + // 'The Associate' as it has no Publisher (4.2 rating), then 'Painted House' 1995 (4.9 rating). + "s1": float64(4.2) + float64(4.9), + "NewestPublishersBook": []map[string]any{ + { + "name": "The Associate", + }, + { + "name": "Painted House", + }, }, }, - }, - { - "name": "Cornelia Funke", - "s1": 4.0, - "NewestPublishersBook": []map[string]any{ - { - "name": "The Rooster Bar", + { + "name": "Cornelia Funke", + "s1": 4.0, + "NewestPublishersBook": []map[string]any{ + { + "name": "The Rooster Bar", + }, }, }, }, @@ -133,23 +137,25 @@ func TestOneToManyToOneWithSumOfDeepOrderBySubTypeOfBothDescAndAsc(t *testing.T) s2: _sum(book: {field: rating, order: {publisher: {yearOpened: ASC}}, limit: 2}) } }`, - Results: []map[string]any{ - { - "name": "Not a Writer", - "s1": 0.0, - "s2": 0.0, - }, - { - "name": "John Grisham", - // 'Theif Lord' (4.8 rating) 2020, then 'A Time for Mercy' 2013 (4.5 rating). - "s1": 4.8 + 4.5, - // 'The Associate' as it has no Publisher (4.2 rating), then 'Painted House' 1995 (4.9 rating). - "s2": float64(4.2) + float64(4.9), - }, - { - "name": "Cornelia Funke", - "s1": 4.0, - "s2": 4.0, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Not a Writer", + "s1": 0.0, + "s2": 0.0, + }, + { + "name": "John Grisham", + // 'Theif Lord' (4.8 rating) 2020, then 'A Time for Mercy' 2013 (4.5 rating). + "s1": 4.8 + 4.5, + // 'The Associate' as it has no Publisher (4.2 rating), then 'Painted House' 1995 (4.9 rating). + "s2": float64(4.2) + float64(4.9), + }, + { + "name": "Cornelia Funke", + "s1": 4.0, + "s2": 4.0, + }, }, }, }, @@ -175,31 +181,33 @@ func TestOneToManyToOneWithSumOfDeepOrderBySubTypeAndDeepOrderBySubtypeOppositeD } } }`, - Results: []map[string]any{ - { - "name": "Not a Writer", - "s1": 0.0, - "OldestPublishersBook": []map[string]any{}, - }, - { - "name": "John Grisham", - // 'Theif Lord' (4.8 rating) 2020, then 'A Time for Mercy' 2013 (4.5 rating). - "s1": 4.8 + 4.5, - "OldestPublishersBook": []map[string]any{ - { - "name": "The Associate", - }, - { - "name": "Painted House", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Not a Writer", + "s1": 0.0, + "OldestPublishersBook": []map[string]any{}, + }, + { + "name": "John Grisham", + // 'Theif Lord' (4.8 rating) 2020, then 'A Time for Mercy' 2013 (4.5 rating). + "s1": 4.8 + 4.5, + "OldestPublishersBook": []map[string]any{ + { + "name": "The Associate", + }, + { + "name": "Painted House", + }, }, }, - }, - { - "name": "Cornelia Funke", - "s1": 4.0, - "OldestPublishersBook": []map[string]any{ - { - "name": "The Rooster Bar", + { + "name": "Cornelia Funke", + "s1": 4.0, + "OldestPublishersBook": []map[string]any{ + { + "name": "The Rooster Bar", + }, }, }, }, diff --git a/tests/integration/query/one_to_many_to_one/with_sum_test.go b/tests/integration/query/one_to_many_to_one/with_sum_test.go index 192784144e..b140f94978 100644 --- a/tests/integration/query/one_to_many_to_one/with_sum_test.go +++ b/tests/integration/query/one_to_many_to_one/with_sum_test.go @@ -95,16 +95,18 @@ func TestQueryWithSumOnInlineAndSumOnOneToManyField(t *testing.T) { TotalRating: _sum(book: {field: rating}) } }`, - Results: []map[string]any{ - { - "name": "John Grisham", - "ThisMakesNoSenseToSumButHey": int64(-1 + 2 + -1 + 1 + 0), - "TotalRating": float64(4.8 + 4.2), - }, - { - "name": "Cornelia Funke", - "ThisMakesNoSenseToSumButHey": int64(0), - "TotalRating": float64(4), + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "ThisMakesNoSenseToSumButHey": int64(-1 + 2 + -1 + 1 + 0), + "TotalRating": float64(4.8 + 4.2), + }, + { + "name": "Cornelia Funke", + "ThisMakesNoSenseToSumButHey": int64(0), + "TotalRating": float64(4), + }, }, }, }, diff --git a/tests/integration/query/one_to_one/simple_test.go b/tests/integration/query/one_to_one/simple_test.go index f0eb5f1f4e..2ebad49df6 100644 --- a/tests/integration/query/one_to_one/simple_test.go +++ b/tests/integration/query/one_to_one/simple_test.go @@ -48,13 +48,15 @@ func TestQueryOneToOne(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "name": "John Grisham", - "age": int64(65), + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "name": "John Grisham", + "age": int64(65), + }, }, }, }, @@ -89,13 +91,15 @@ func TestQueryOneToOne(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John Grisham", - "age": int64(65), - "published": map[string]any{ - "name": "Painted House", - "rating": 4.9, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "age": int64(65), + "published": map[string]any{ + "name": "Painted House", + "rating": 4.9, + }, }, }, }, @@ -168,17 +172,19 @@ func TestQueryOneToOneWithMultipleRecords(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Go Guide for Rust developers", - "author": map[string]any{ - "name": "Andrew Lone", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Go Guide for Rust developers", + "author": map[string]any{ + "name": "Andrew Lone", + }, }, - }, - { - "name": "Painted House", - "author": map[string]any{ - "name": "John Grisham", + { + "name": "Painted House", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, @@ -244,17 +250,19 @@ func TestQueryOneToOneWithMultipleRecordsSecondaryDirection(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "published": map[string]any{ - "name": "Theif Lord", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "published": map[string]any{ + "name": "Theif Lord", + }, }, - }, - { - "name": "John Grisham", - "published": map[string]any{ - "name": "Painted House", + { + "name": "John Grisham", + "published": map[string]any{ + "name": "Painted House", + }, }, }, }, @@ -284,10 +292,12 @@ func TestQueryOneToOneWithNilChild(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "John Grisham", - "published": nil, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "published": nil, + }, }, }, } @@ -314,10 +324,12 @@ func TestQueryOneToOneWithNilParent(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Painted House", - "author": nil, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author": nil, + }, }, }, } @@ -362,10 +374,12 @@ func TestQueryOneToOne_WithRelationIDFromPrimarySide(t *testing.T) { published_id } }`, - Results: []map[string]any{ - { - "name": "John Grisham", - "published_id": "bae-514f04b1-b218-5b8c-89ee-538f150a32b5", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "published_id": "bae-514f04b1-b218-5b8c-89ee-538f150a32b5", + }, }, }, }, @@ -412,10 +426,12 @@ func TestQueryOneToOne_WithRelationIDFromSecondarySide(t *testing.T) { author_id } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "author_id": "bae-420e72a6-e0c6-5a06-a958-2cc7adb7b3d0", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author_id": "bae-420e72a6-e0c6-5a06-a958-2cc7adb7b3d0", + }, }, }, }, diff --git a/tests/integration/query/one_to_one/with_clashing_id_field_test.go b/tests/integration/query/one_to_one/with_clashing_id_field_test.go index 368ea364a4..077416084f 100644 --- a/tests/integration/query/one_to_one/with_clashing_id_field_test.go +++ b/tests/integration/query/one_to_one/with_clashing_id_field_test.go @@ -59,12 +59,14 @@ func TestQueryOneToOneWithClashingIdFieldOnSecondary(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "author_id": "bae-1a0405fa-e17d-5b0f-8fe2-eb966938df1c", - "author": map[string]any{ - "name": "John Grisham", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author_id": "bae-1a0405fa-e17d-5b0f-8fe2-eb966938df1c", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, diff --git a/tests/integration/query/one_to_one/with_count_filter_test.go b/tests/integration/query/one_to_one/with_count_filter_test.go index 9748bb7ca8..aa38267af4 100644 --- a/tests/integration/query/one_to_one/with_count_filter_test.go +++ b/tests/integration/query/one_to_one/with_count_filter_test.go @@ -94,10 +94,8 @@ func TestQueryOneToOneWithCountWithCompoundOrFilterThatIncludesRelation(t *testi {_not: {author: {age: {_gt: 30}}} } ]}}) }`, - Results: []map[string]any{ - { - "_count": int(2), - }, + Results: map[string]any{ + "_count": int(2), }, }, }, diff --git a/tests/integration/query/one_to_one/with_filter_order_test.go b/tests/integration/query/one_to_one/with_filter_order_test.go index 7ec7d88362..24682d4fb4 100644 --- a/tests/integration/query/one_to_one/with_filter_order_test.go +++ b/tests/integration/query/one_to_one/with_filter_order_test.go @@ -60,14 +60,16 @@ func TestOnetoOneSubTypeDscOrderByQueryWithFilterHavinghNoSubTypeSelections(t *t }`, }, }, - Results: []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - }, - { - "name": "Theif Lord", - "rating": 4.8, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + { + "name": "Theif Lord", + "rating": 4.8, + }, }, }, } @@ -119,14 +121,16 @@ func TestOnetoOneSubTypeAscOrderByQueryWithFilterHavinghNoSubTypeSelections(t *t }`, }, }, - Results: []map[string]any{ - { - "name": "Theif Lord", - "rating": 4.8, - }, - { - "name": "Painted House", - "rating": 4.9, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Theif Lord", + "rating": 4.8, + }, + { + "name": "Painted House", + "rating": 4.9, + }, }, }, } diff --git a/tests/integration/query/one_to_one/with_filter_test.go b/tests/integration/query/one_to_one/with_filter_test.go index c9ae69f637..c3db221349 100644 --- a/tests/integration/query/one_to_one/with_filter_test.go +++ b/tests/integration/query/one_to_one/with_filter_test.go @@ -50,13 +50,15 @@ func TestQueryOneToOneWithNumericFilterOnParent(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "name": "John Grisham", - "age": int64(65), + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "name": "John Grisham", + "age": int64(65), + }, }, }, }, @@ -103,13 +105,15 @@ func TestQueryOneToOneWithStringFilterOnChild(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "name": "John Grisham", - "age": int64(65), + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "name": "John Grisham", + "age": int64(65), + }, }, }, }, @@ -156,13 +160,15 @@ func TestQueryOneToOneWithBooleanFilterOnChild(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "name": "John Grisham", - "age": int64(65), + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "name": "John Grisham", + "age": int64(65), + }, }, }, }, @@ -223,13 +229,15 @@ func TestQueryOneToOneWithFilterThroughChildBackToParent(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "name": "John Grisham", - "age": int64(65), + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "name": "John Grisham", + "age": int64(65), + }, }, }, }, @@ -270,10 +278,14 @@ func TestQueryOneToOneWithBooleanFilterOnChildWithNoSubTypeSelection(t *testing. rating } }`, - Results: []map[string]any{{ - "name": "Painted House", - "rating": 4.9, - }}, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + }, + }, }, }, } @@ -346,10 +358,14 @@ func TestQueryOneToOneWithCompoundAndFilterThatIncludesRelation(t *testing.T) { rating } }`, - Results: []map[string]any{{ - "name": "Painted House", - "rating": 4.9, - }}, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + }, + }, }, }, } @@ -443,12 +459,14 @@ func TestQueryOneToOneWithCompoundOrFilterThatIncludesRelation(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "Some Book", - }, - { - "name": "Some Other Book", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Some Book", + }, + { + "name": "Some Other Book", + }, }, }, }, @@ -461,12 +479,14 @@ func TestQueryOneToOneWithCompoundOrFilterThatIncludesRelation(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "Yet Another Book", - }, - { - "name": "Painted House", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Yet Another Book", + }, + { + "name": "Painted House", + }, }, }, }, @@ -541,14 +561,16 @@ func TestQueryOneToOne_WithCompoundFiltersThatIncludesRelation_ShouldReturnResul rating } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - }, - { - "name": "Some Other Book", - "rating": 3.0, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + { + "name": "Some Other Book", + "rating": 3.0, + }, }, }, }, @@ -562,10 +584,12 @@ func TestQueryOneToOne_WithCompoundFiltersThatIncludesRelation_ShouldReturnResul rating } }`, - Results: []map[string]any{ - { - "name": "Some Book", - "rating": 4.0, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Some Book", + "rating": 4.0, + }, }, }, }, @@ -580,14 +604,16 @@ func TestQueryOneToOne_WithCompoundFiltersThatIncludesRelation_ShouldReturnResul rating } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - }, - { - "name": "Some Other Book", - "rating": 3.0, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + { + "name": "Some Other Book", + "rating": 3.0, + }, }, }, }, diff --git a/tests/integration/query/one_to_one/with_group_related_id_alias_test.go b/tests/integration/query/one_to_one/with_group_related_id_alias_test.go index 1f98f6604b..9def4654f4 100644 --- a/tests/integration/query/one_to_one/with_group_related_id_alias_test.go +++ b/tests/integration/query/one_to_one/with_group_related_id_alias_test.go @@ -71,26 +71,28 @@ func TestQueryOneToOneWithGroupRelatedIDAlias(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "author_id": "bae-077b5e8d-5a86-5ae7-a321-ac7e423bb260", - "author": map[string]any{ - "name": "John Grisham", - }, - "_group": []map[string]any{ - { - "name": "Painted House", + Results: map[string]any{ + "Book": []map[string]any{ + { + "author_id": "bae-077b5e8d-5a86-5ae7-a321-ac7e423bb260", + "author": map[string]any{ + "name": "John Grisham", + }, + "_group": []map[string]any{ + { + "name": "Painted House", + }, }, }, - }, - { - "author_id": "bae-b11e00fc-340f-558b-909d-2ab94601570b", - "author": map[string]any{ - "name": "Andrew Lone", - }, - "_group": []map[string]any{ - { - "name": "Go Guide for Rust developers", + { + "author_id": "bae-b11e00fc-340f-558b-909d-2ab94601570b", + "author": map[string]any{ + "name": "Andrew Lone", + }, + "_group": []map[string]any{ + { + "name": "Go Guide for Rust developers", + }, }, }, }, @@ -151,12 +153,14 @@ func TestQueryOneToOneWithGroupRelatedIDAliasFromSecondaryWithoutInnerGroup(t *t author_id } }`, - Results: []map[string]any{ - { - "author_id": "bae-3c308f94-dc9e-5262-b0ce-ef4e8e545820", - }, - { - "author_id": "bae-420e72a6-e0c6-5a06-a958-2cc7adb7b3d0", + Results: map[string]any{ + "Book": []map[string]any{ + { + "author_id": "bae-3c308f94-dc9e-5262-b0ce-ef4e8e545820", + }, + { + "author_id": "bae-420e72a6-e0c6-5a06-a958-2cc7adb7b3d0", + }, }, }, }, @@ -218,17 +222,19 @@ func TestQueryOneToOneWithGroupRelatedIDAliasFromSecondaryWithoutInnerGroupWithJ } } }`, - Results: []map[string]any{ - { - "author_id": "bae-3c308f94-dc9e-5262-b0ce-ef4e8e545820", - "author": map[string]any{ - "name": "Andrew Lone", + Results: map[string]any{ + "Book": []map[string]any{ + { + "author_id": "bae-3c308f94-dc9e-5262-b0ce-ef4e8e545820", + "author": map[string]any{ + "name": "Andrew Lone", + }, }, - }, - { - "author_id": "bae-420e72a6-e0c6-5a06-a958-2cc7adb7b3d0", - "author": map[string]any{ - "name": "John Grisham", + { + "author_id": "bae-420e72a6-e0c6-5a06-a958-2cc7adb7b3d0", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, @@ -291,20 +297,22 @@ func TestQueryOneToOneWithGroupRelatedIDAliasFromSecondaryWithInnerGroup(t *test } } }`, - Results: []map[string]any{ - { - "author_id": "bae-3c308f94-dc9e-5262-b0ce-ef4e8e545820", - "_group": []map[string]any{ - { - "name": "Go Guide for Rust developers", + Results: map[string]any{ + "Book": []map[string]any{ + { + "author_id": "bae-3c308f94-dc9e-5262-b0ce-ef4e8e545820", + "_group": []map[string]any{ + { + "name": "Go Guide for Rust developers", + }, }, }, - }, - { - "author_id": "bae-420e72a6-e0c6-5a06-a958-2cc7adb7b3d0", - "_group": []map[string]any{ - { - "name": "Painted House", + { + "author_id": "bae-420e72a6-e0c6-5a06-a958-2cc7adb7b3d0", + "_group": []map[string]any{ + { + "name": "Painted House", + }, }, }, }, @@ -371,26 +379,28 @@ func TestQueryOneToOneWithGroupRelatedIDAliasFromSecondaryWithInnerGroupWithJoin } } }`, - Results: []map[string]any{ - { - "author_id": "bae-3c308f94-dc9e-5262-b0ce-ef4e8e545820", - "author": map[string]any{ - "name": "Andrew Lone", - }, - "_group": []map[string]any{ - { - "name": "Go Guide for Rust developers", + Results: map[string]any{ + "Book": []map[string]any{ + { + "author_id": "bae-3c308f94-dc9e-5262-b0ce-ef4e8e545820", + "author": map[string]any{ + "name": "Andrew Lone", + }, + "_group": []map[string]any{ + { + "name": "Go Guide for Rust developers", + }, }, }, - }, - { - "author_id": "bae-420e72a6-e0c6-5a06-a958-2cc7adb7b3d0", - "author": map[string]any{ - "name": "John Grisham", - }, - "_group": []map[string]any{ - { - "name": "Painted House", + { + "author_id": "bae-420e72a6-e0c6-5a06-a958-2cc7adb7b3d0", + "author": map[string]any{ + "name": "John Grisham", + }, + "_group": []map[string]any{ + { + "name": "Painted House", + }, }, }, }, diff --git a/tests/integration/query/one_to_one/with_group_related_id_test.go b/tests/integration/query/one_to_one/with_group_related_id_test.go index d3b9867886..7607965203 100644 --- a/tests/integration/query/one_to_one/with_group_related_id_test.go +++ b/tests/integration/query/one_to_one/with_group_related_id_test.go @@ -68,20 +68,22 @@ func TestQueryOneToOneWithGroupRelatedID(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "author_id": "bae-077b5e8d-5a86-5ae7-a321-ac7e423bb260", - "_group": []map[string]any{ - { - "name": "Painted House", + Results: map[string]any{ + "Book": []map[string]any{ + { + "author_id": "bae-077b5e8d-5a86-5ae7-a321-ac7e423bb260", + "_group": []map[string]any{ + { + "name": "Painted House", + }, }, }, - }, - { - "author_id": "bae-cfee1ed9-ede8-5b80-a6fa-78c727a076ac", - "_group": []map[string]any{ - { - "name": "Go Guide for Rust developers", + { + "author_id": "bae-cfee1ed9-ede8-5b80-a6fa-78c727a076ac", + "_group": []map[string]any{ + { + "name": "Go Guide for Rust developers", + }, }, }, }, @@ -142,12 +144,14 @@ func TestQueryOneToOneWithGroupRelatedIDFromSecondaryWithoutGroup(t *testing.T) author_id } }`, - Results: []map[string]any{ - { - "author_id": "bae-3c308f94-dc9e-5262-b0ce-ef4e8e545820", - }, - { - "author_id": "bae-420e72a6-e0c6-5a06-a958-2cc7adb7b3d0", + Results: map[string]any{ + "Book": []map[string]any{ + { + "author_id": "bae-3c308f94-dc9e-5262-b0ce-ef4e8e545820", + }, + { + "author_id": "bae-420e72a6-e0c6-5a06-a958-2cc7adb7b3d0", + }, }, }, }, @@ -209,17 +213,19 @@ func TestQueryOneToOneWithGroupRelatedIDFromSecondaryWithoutGroupWithJoin(t *tes } } }`, - Results: []map[string]any{ - { - "author_id": "bae-3c308f94-dc9e-5262-b0ce-ef4e8e545820", - "author": map[string]any{ - "name": "Andrew Lone", + Results: map[string]any{ + "Book": []map[string]any{ + { + "author_id": "bae-3c308f94-dc9e-5262-b0ce-ef4e8e545820", + "author": map[string]any{ + "name": "Andrew Lone", + }, }, - }, - { - "author_id": "bae-420e72a6-e0c6-5a06-a958-2cc7adb7b3d0", - "author": map[string]any{ - "name": "John Grisham", + { + "author_id": "bae-420e72a6-e0c6-5a06-a958-2cc7adb7b3d0", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, @@ -282,20 +288,22 @@ func TestQueryOneToOneWithGroupRelatedIDFromSecondaryWithGroup(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "author_id": "bae-bb4d6e89-e8b4-5eec-bfeb-6f7aa4840950", - "_group": []map[string]any{ - { - "name": "Go Guide for Rust developers", + Results: map[string]any{ + "Book": []map[string]any{ + { + "author_id": "bae-bb4d6e89-e8b4-5eec-bfeb-6f7aa4840950", + "_group": []map[string]any{ + { + "name": "Go Guide for Rust developers", + }, }, }, - }, - { - "author_id": "bae-420e72a6-e0c6-5a06-a958-2cc7adb7b3d0", - "_group": []map[string]any{ - { - "name": "Painted House", + { + "author_id": "bae-420e72a6-e0c6-5a06-a958-2cc7adb7b3d0", + "_group": []map[string]any{ + { + "name": "Painted House", + }, }, }, }, @@ -362,26 +370,28 @@ func TestQueryOneToOneWithGroupRelatedIDFromSecondaryWithGroupWithJoin(t *testin } } }`, - Results: []map[string]any{ - { - "author_id": "bae-3c308f94-dc9e-5262-b0ce-ef4e8e545820", - "author": map[string]any{ - "name": "Andrew Lone", - }, - "_group": []map[string]any{ - { - "name": "Go Guide for Rust developers", + Results: map[string]any{ + "Book": []map[string]any{ + { + "author_id": "bae-3c308f94-dc9e-5262-b0ce-ef4e8e545820", + "author": map[string]any{ + "name": "Andrew Lone", + }, + "_group": []map[string]any{ + { + "name": "Go Guide for Rust developers", + }, }, }, - }, - { - "author_id": "bae-420e72a6-e0c6-5a06-a958-2cc7adb7b3d0", - "author": map[string]any{ - "name": "John Grisham", - }, - "_group": []map[string]any{ - { - "name": "Painted House", + { + "author_id": "bae-420e72a6-e0c6-5a06-a958-2cc7adb7b3d0", + "author": map[string]any{ + "name": "John Grisham", + }, + "_group": []map[string]any{ + { + "name": "Painted House", + }, }, }, }, diff --git a/tests/integration/query/one_to_one/with_order_test.go b/tests/integration/query/one_to_one/with_order_test.go index bdf5d6d1e3..9a2ca8c4c9 100644 --- a/tests/integration/query/one_to_one/with_order_test.go +++ b/tests/integration/query/one_to_one/with_order_test.go @@ -61,21 +61,23 @@ func TestQueryOneToOneWithChildBooleanOrderDescending(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "name": "John Grisham", - "age": int64(65), + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "name": "John Grisham", + "age": int64(65), + }, }, - }, - { - "name": "Theif Lord", - "rating": 4.8, - "author": map[string]any{ - "name": "Cornelia Funke", - "age": int64(62), + { + "name": "Theif Lord", + "rating": 4.8, + "author": map[string]any{ + "name": "Cornelia Funke", + "age": int64(62), + }, }, }, }, @@ -129,21 +131,23 @@ func TestQueryOneToOneWithChildBooleanOrderAscending(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "name": "Theif Lord", - "rating": 4.8, - "author": map[string]any{ - "name": "Cornelia Funke", - "age": int64(62), + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Theif Lord", + "rating": 4.8, + "author": map[string]any{ + "name": "Cornelia Funke", + "age": int64(62), + }, }, - }, - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "name": "John Grisham", - "age": int64(65), + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "name": "John Grisham", + "age": int64(65), + }, }, }, }, @@ -193,14 +197,16 @@ func TestQueryOneToOneWithChildIntOrderDescendingWithNoSubTypeFieldsSelected(t * }`, }, }, - Results: []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - }, - { - "name": "Theif Lord", - "rating": 4.8, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + { + "name": "Theif Lord", + "rating": 4.8, + }, }, }, } @@ -249,14 +255,16 @@ func TestQueryOneToOneWithChildIntOrderAscendingWithNoSubTypeFieldsSelected(t *t }`, }, }, - Results: []map[string]any{ - { - "name": "Theif Lord", - "rating": 4.8, - }, - { - "name": "Painted House", - "rating": 4.9, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Theif Lord", + "rating": 4.8, + }, + { + "name": "Painted House", + "rating": 4.9, + }, }, }, } diff --git a/tests/integration/query/one_to_one_multiple/simple_test.go b/tests/integration/query/one_to_one_multiple/simple_test.go index f7988a1940..66b823138a 100644 --- a/tests/integration/query/one_to_one_multiple/simple_test.go +++ b/tests/integration/query/one_to_one_multiple/simple_test.go @@ -91,23 +91,25 @@ func TestQueryOneToOneMultiple_FromPrimary(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "publisher": map[string]any{ - "name": "Old Publisher", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "publisher": map[string]any{ + "name": "Old Publisher", + }, + "author": map[string]any{ + "name": "John Grisham", + }, }, - "author": map[string]any{ - "name": "John Grisham", - }, - }, - { - "name": "Theif Lord", - "publisher": map[string]any{ - "name": "New Publisher", - }, - "author": map[string]any{ - "name": "Cornelia Funke", + { + "name": "Theif Lord", + "publisher": map[string]any{ + "name": "New Publisher", + }, + "author": map[string]any{ + "name": "Cornelia Funke", + }, }, }, }, @@ -193,23 +195,25 @@ func TestQueryOneToOneMultiple_FromMixedPrimaryAndSecondary(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Theif Lord", - "publisher": map[string]any{ - "name": "New Publisher", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Theif Lord", + "publisher": map[string]any{ + "name": "New Publisher", + }, + "author": map[string]any{ + "name": "Cornelia Funke", + }, }, - "author": map[string]any{ - "name": "Cornelia Funke", - }, - }, - { - "name": "Painted House", - "publisher": map[string]any{ - "name": "Old Publisher", - }, - "author": map[string]any{ - "name": "John Grisham", + { + "name": "Painted House", + "publisher": map[string]any{ + "name": "Old Publisher", + }, + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, @@ -295,23 +299,25 @@ func TestQueryOneToOneMultiple_FromSecondary(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "publisher": map[string]any{ - "name": "Old Publisher", - }, - "author": map[string]any{ - "name": "John Grisham", - }, - }, - { - "name": "Theif Lord", - "publisher": map[string]any{ - "name": "New Publisher", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "publisher": map[string]any{ + "name": "Old Publisher", + }, + "author": map[string]any{ + "name": "John Grisham", + }, }, - "author": map[string]any{ - "name": "Cornelia Funke", + { + "name": "Theif Lord", + "publisher": map[string]any{ + "name": "New Publisher", + }, + "author": map[string]any{ + "name": "Cornelia Funke", + }, }, }, }, diff --git a/tests/integration/query/one_to_one_to_many/simple_test.go b/tests/integration/query/one_to_one_to_many/simple_test.go index cee2d465cf..3e65193cc7 100644 --- a/tests/integration/query/one_to_one_to_many/simple_test.go +++ b/tests/integration/query/one_to_one_to_many/simple_test.go @@ -71,13 +71,15 @@ func TestQueryOneToOneToMany(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Observation1", - "observable": map[string]any{ - "name": "Observable1", - "indicator": map[string]any{ - "name": "Indicator1", + Results: map[string]any{ + "Observation": []map[string]any{ + { + "name": "Observation1", + "observable": map[string]any{ + "name": "Observable1", + "indicator": map[string]any{ + "name": "Indicator1", + }, }, }, }, @@ -144,14 +146,16 @@ func TestQueryOneToOneToManyFromSecondaryOnOneToMany(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Indicator1", - "observable": map[string]any{ - "name": "Observable1", - "observations": []map[string]any{ - { - "name": "Observation1", + Results: map[string]any{ + "Indicator": []map[string]any{ + { + "name": "Indicator1", + "observable": map[string]any{ + "name": "Observable1", + "observations": []map[string]any{ + { + "name": "Observation1", + }, }, }, }, @@ -219,13 +223,15 @@ func TestQueryOneToOneToManyFromSecondaryOnOneToOne(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Observation1", - "observable": map[string]any{ - "name": "Observable1", - "indicator": map[string]any{ - "name": "Indicator1", + Results: map[string]any{ + "Observation": []map[string]any{ + { + "name": "Observation1", + "observable": map[string]any{ + "name": "Observable1", + "indicator": map[string]any{ + "name": "Indicator1", + }, }, }, }, @@ -292,14 +298,16 @@ func TestQueryOneToOneToManyFromSecondary(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Indicator1", - "observable": map[string]any{ - "name": "Observable1", - "observations": []map[string]any{ - { - "name": "Observation1", + Results: map[string]any{ + "Indicator": []map[string]any{ + { + "name": "Indicator1", + "observable": map[string]any{ + "name": "Observable1", + "observations": []map[string]any{ + { + "name": "Observation1", + }, }, }, }, diff --git a/tests/integration/query/one_to_one_to_one/simple_test.go b/tests/integration/query/one_to_one_to_one/simple_test.go index e788ddc732..bb054c4380 100644 --- a/tests/integration/query/one_to_one_to_one/simple_test.go +++ b/tests/integration/query/one_to_one_to_one/simple_test.go @@ -91,22 +91,24 @@ func TestQueryOneToOneToOne(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "New Publisher", - "printed": map[string]any{ - "name": "Theif Lord", - "author": map[string]any{ - "name": "Cornelia Funke", + Results: map[string]any{ + "Publisher": []map[string]any{ + { + "name": "New Publisher", + "printed": map[string]any{ + "name": "Theif Lord", + "author": map[string]any{ + "name": "Cornelia Funke", + }, }, }, - }, - { - "name": "Old Publisher", - "printed": map[string]any{ - "name": "Painted House", - "author": map[string]any{ - "name": "John Grisham", + { + "name": "Old Publisher", + "printed": map[string]any{ + "name": "Painted House", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, @@ -193,22 +195,24 @@ func TestQueryOneToOneToOneSecondaryThenPrimary(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "New Publisher", - "printed": map[string]any{ - "name": "Theif Lord", - "author": map[string]any{ - "name": "Cornelia Funke", + Results: map[string]any{ + "Publisher": []map[string]any{ + { + "name": "New Publisher", + "printed": map[string]any{ + "name": "Theif Lord", + "author": map[string]any{ + "name": "Cornelia Funke", + }, }, }, - }, - { - "name": "Old Publisher", - "printed": map[string]any{ - "name": "Painted House", - "author": map[string]any{ - "name": "John Grisham", + { + "name": "Old Publisher", + "printed": map[string]any{ + "name": "Painted House", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, @@ -295,22 +299,24 @@ func TestQueryOneToOneToOnePrimaryThenSecondary(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "New Publisher", - "printed": map[string]any{ - "name": "Theif Lord", - "author": map[string]any{ - "name": "Cornelia Funke", + Results: map[string]any{ + "Publisher": []map[string]any{ + { + "name": "New Publisher", + "printed": map[string]any{ + "name": "Theif Lord", + "author": map[string]any{ + "name": "Cornelia Funke", + }, }, }, - }, - { - "name": "Old Publisher", - "printed": map[string]any{ - "name": "Painted House", - "author": map[string]any{ - "name": "John Grisham", + { + "name": "Old Publisher", + "printed": map[string]any{ + "name": "Painted House", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, @@ -397,22 +403,24 @@ func TestQueryOneToOneToOneSecondary(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "New Publisher", - "printed": map[string]any{ - "name": "Theif Lord", - "author": map[string]any{ - "name": "Cornelia Funke", + Results: map[string]any{ + "Publisher": []map[string]any{ + { + "name": "New Publisher", + "printed": map[string]any{ + "name": "Theif Lord", + "author": map[string]any{ + "name": "Cornelia Funke", + }, }, }, - }, - { - "name": "Old Publisher", - "printed": map[string]any{ - "name": "Painted House", - "author": map[string]any{ - "name": "John Grisham", + { + "name": "Old Publisher", + "printed": map[string]any{ + "name": "Painted House", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, diff --git a/tests/integration/query/one_to_one_to_one/with_order_test.go b/tests/integration/query/one_to_one_to_one/with_order_test.go index 899f890f74..4c241cc281 100644 --- a/tests/integration/query/one_to_one_to_one/with_order_test.go +++ b/tests/integration/query/one_to_one_to_one/with_order_test.go @@ -91,22 +91,24 @@ func TestQueryOneToOneToOneWithNestedOrder(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "New Publisher", - "printed": map[string]any{ - "name": "Theif Lord", - "author": map[string]any{ - "name": "Cornelia Funke", + Results: map[string]any{ + "Publisher": []map[string]any{ + { + "name": "New Publisher", + "printed": map[string]any{ + "name": "Theif Lord", + "author": map[string]any{ + "name": "Cornelia Funke", + }, }, }, - }, - { - "name": "Old Publisher", - "printed": map[string]any{ - "name": "Painted House", - "author": map[string]any{ - "name": "John Grisham", + { + "name": "Old Publisher", + "printed": map[string]any{ + "name": "Painted House", + "author": map[string]any{ + "name": "John Grisham", + }, }, }, }, diff --git a/tests/integration/query/one_to_two_many/simple_test.go b/tests/integration/query/one_to_two_many/simple_test.go index 58a677d6fa..47e946b6e4 100644 --- a/tests/integration/query/one_to_two_many/simple_test.go +++ b/tests/integration/query/one_to_two_many/simple_test.go @@ -95,38 +95,40 @@ func TestQueryOneToTwoManyWithNilUnnamedRelationship_FromOneSide(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "name": "John Grisham", - }, - "reviewedBy": map[string]any{ - "name": "Cornelia Funke", - "age": int64(62), - }, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, - "author": map[string]any{ - "name": "John Grisham", - }, - "reviewedBy": map[string]any{ - "name": "Cornelia Funke", - "age": int64(62), + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "name": "John Grisham", + }, + "reviewedBy": map[string]any{ + "name": "Cornelia Funke", + "age": int64(62), + }, }, - }, - { - "name": "Theif Lord", - "rating": 4.8, - "author": map[string]any{ - "name": "Cornelia Funke", + { + "name": "A Time for Mercy", + "rating": 4.5, + "author": map[string]any{ + "name": "John Grisham", + }, + "reviewedBy": map[string]any{ + "name": "Cornelia Funke", + "age": int64(62), + }, }, - "reviewedBy": map[string]any{ - "name": "John Grisham", - "age": int64(65), + { + "name": "Theif Lord", + "rating": 4.8, + "author": map[string]any{ + "name": "Cornelia Funke", + }, + "reviewedBy": map[string]any{ + "name": "John Grisham", + "age": int64(65), + }, }, }, }, @@ -216,41 +218,43 @@ func TestQueryOneToTwoManyWithNilUnnamedRelationship_FromManySide(t *testing.T) } } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "age": int64(62), - "reviewed": []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, - }, - }, - "written": []map[string]any{ - { - "name": "Theif Lord", + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "age": int64(62), + "reviewed": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + { + "name": "A Time for Mercy", + "rating": 4.5, + }, }, - }, - }, - { - "name": "John Grisham", - "age": int64(65), - "reviewed": []map[string]any{ - { - "name": "Theif Lord", - "rating": 4.8, + "written": []map[string]any{ + { + "name": "Theif Lord", + }, }, }, - "written": []map[string]any{ - { - "name": "Painted House", + { + "name": "John Grisham", + "age": int64(65), + "reviewed": []map[string]any{ + { + "name": "Theif Lord", + "rating": 4.8, + }, }, - { - "name": "A Time for Mercy", + "written": []map[string]any{ + { + "name": "Painted House", + }, + { + "name": "A Time for Mercy", + }, }, }, }, @@ -369,50 +373,52 @@ func TestQueryOneToTwoManyWithNamedAndUnnamedRelationships(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "name": "John Grisham", - }, - "reviewedBy": map[string]any{ - "name": "Cornelia Funke", - "age": int64(62), - }, - "price": map[string]any{ - "currency": "GBP", - "value": 12.99, - }, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, - "author": map[string]any{ - "name": "John Grisham", - }, - "reviewedBy": map[string]any{ - "name": "Cornelia Funke", - "age": int64(62), - }, - "price": map[string]any{ - "currency": "SEK", - "value": float64(129), - }, - }, - { - "name": "Theif Lord", - "rating": 4.8, - "author": map[string]any{ - "name": "Cornelia Funke", + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "name": "John Grisham", + }, + "reviewedBy": map[string]any{ + "name": "Cornelia Funke", + "age": int64(62), + }, + "price": map[string]any{ + "currency": "GBP", + "value": 12.99, + }, }, - "reviewedBy": map[string]any{ - "name": "John Grisham", - "age": int64(65), + { + "name": "A Time for Mercy", + "rating": 4.5, + "author": map[string]any{ + "name": "John Grisham", + }, + "reviewedBy": map[string]any{ + "name": "Cornelia Funke", + "age": int64(62), + }, + "price": map[string]any{ + "currency": "SEK", + "value": float64(129), + }, }, - "price": map[string]any{ - "currency": "GBP", - "value": 12.99, + { + "name": "Theif Lord", + "rating": 4.8, + "author": map[string]any{ + "name": "Cornelia Funke", + }, + "reviewedBy": map[string]any{ + "name": "John Grisham", + "age": int64(65), + }, + "price": map[string]any{ + "currency": "GBP", + "value": 12.99, + }, }, }, }, @@ -529,49 +535,51 @@ func TestQueryOneToTwoManyWithNamedAndUnnamedRelationships_FromManySide(t *testi } } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "age": int64(62), - "reviewed": []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, - }, - }, - "written": []map[string]any{ - { - "name": "Theif Lord", - "price": map[string]any{ - "value": 12.99, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "age": int64(62), + "reviewed": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + { + "name": "A Time for Mercy", + "rating": 4.5, }, }, - }, - }, - { - "name": "John Grisham", - "age": int64(65), - "reviewed": []map[string]any{ - { - "name": "Theif Lord", - "rating": 4.8, + "written": []map[string]any{ + { + "name": "Theif Lord", + "price": map[string]any{ + "value": 12.99, + }, + }, }, }, - "written": []map[string]any{ - { - "name": "Painted House", - "price": map[string]any{ - "value": 12.99, + { + "name": "John Grisham", + "age": int64(65), + "reviewed": []map[string]any{ + { + "name": "Theif Lord", + "rating": 4.8, }, }, - { - "name": "A Time for Mercy", - "price": map[string]any{ - "value": float64(129), + "written": []map[string]any{ + { + "name": "Painted House", + "price": map[string]any{ + "value": 12.99, + }, + }, + { + "name": "A Time for Mercy", + "price": map[string]any{ + "value": float64(129), + }, }, }, }, diff --git a/tests/integration/query/one_to_two_many/with_order_test.go b/tests/integration/query/one_to_two_many/with_order_test.go index d84aa4e869..fd58bdb3d6 100644 --- a/tests/integration/query/one_to_two_many/with_order_test.go +++ b/tests/integration/query/one_to_two_many/with_order_test.go @@ -95,39 +95,41 @@ func TestQueryOneToTwoManyWithOrder(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Cornelia Funke", - "reviewed": []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "reviewed": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, }, - }, - "written": []map[string]any{ - { - "name": "Theif Lord", - }, - }, - }, - { - "name": "John Grisham", - "reviewed": []map[string]any{ - { - "name": "Theif Lord", - "rating": 4.8, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, + "written": []map[string]any{ + { + "name": "Theif Lord", + }, }, }, - "written": []map[string]any{ - { - "name": "A Time for Mercy", + { + "name": "John Grisham", + "reviewed": []map[string]any{ + { + "name": "Theif Lord", + "rating": 4.8, + }, + { + "name": "A Time for Mercy", + "rating": 4.5, + }, }, - { - "name": "Painted House", + "written": []map[string]any{ + { + "name": "A Time for Mercy", + }, + { + "name": "Painted House", + }, }, }, }, diff --git a/tests/integration/query/simple/simple_test.go b/tests/integration/query/simple/simple_test.go index 5872998e81..fce69f1412 100644 --- a/tests/integration/query/simple/simple_test.go +++ b/tests/integration/query/simple/simple_test.go @@ -34,11 +34,13 @@ func TestQuerySimple(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "_docID": "bae-d4303725-7db9-53d2-b324-f3ee44020e52", - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-d4303725-7db9-53d2-b324-f3ee44020e52", + "Name": "John", + "Age": int64(21), + }, }, }, } @@ -63,10 +65,12 @@ func TestQuerySimpleWithAlias(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "username": "John", - "age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "username": "John", + "age": int64(21), + }, }, }, } @@ -95,14 +99,16 @@ func TestQuerySimpleWithMultipleRows(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Bob", - "Age": int64(27), - }, - { - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + "Age": int64(27), + }, + { + "Name": "John", + "Age": int64(21), + }, }, }, } @@ -144,13 +150,15 @@ func TestQuerySimpleWithSomeDefaultValues(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Email": nil, - "Age": nil, - "HeightM": nil, - "Verified": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Email": nil, + "Age": nil, + "HeightM": nil, + "Verified": nil, + }, }, }, } @@ -175,13 +183,15 @@ func TestQuerySimpleWithDefaultValue(t *testing.T) { `{ }`, }, }, - Results: []map[string]any{ - { - "Name": nil, - "Email": nil, - "Age": nil, - "HeightM": nil, - "Verified": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": nil, + "Email": nil, + "Age": nil, + "HeightM": nil, + "Verified": nil, + }, }, }, } diff --git a/tests/integration/query/simple/with_average_filter_test.go b/tests/integration/query/simple/with_average_filter_test.go index 8711c56e6b..48bf59ab89 100644 --- a/tests/integration/query/simple/with_average_filter_test.go +++ b/tests/integration/query/simple/with_average_filter_test.go @@ -38,10 +38,8 @@ func TestQuerySimpleWithAverageWithFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "_avg": float64(31), - }, + Results: map[string]any{ + "_avg": float64(31), }, } @@ -73,10 +71,8 @@ func TestQuerySimpleWithAverageWithDateTimeFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "_avg": float64(31), - }, + Results: map[string]any{ + "_avg": float64(31), }, } diff --git a/tests/integration/query/simple/with_average_test.go b/tests/integration/query/simple/with_average_test.go index bd7ddbe6d5..1237c21cb6 100644 --- a/tests/integration/query/simple/with_average_test.go +++ b/tests/integration/query/simple/with_average_test.go @@ -46,10 +46,8 @@ func TestQuerySimpleWithAverageOnEmptyCollection(t *testing.T) { Request: `query { _avg(Users: {field: Age}) }`, - Results: []map[string]any{ - { - "_avg": float64(0), - }, + Results: map[string]any{ + "_avg": float64(0), }, } @@ -74,10 +72,8 @@ func TestQuerySimpleWithAverage(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "_avg": float64(29), - }, + Results: map[string]any{ + "_avg": float64(29), }, } diff --git a/tests/integration/query/simple/with_cid_doc_id_test.go b/tests/integration/query/simple/with_cid_doc_id_test.go index 34dbbd5512..4cb1614ddc 100644 --- a/tests/integration/query/simple/with_cid_doc_id_test.go +++ b/tests/integration/query/simple/with_cid_doc_id_test.go @@ -99,9 +99,11 @@ func TestQuerySimpleWithCidAndDocID(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -141,9 +143,11 @@ func TestQuerySimpleWithUpdateAndFirstCidAndDocID(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -183,9 +187,11 @@ func TestQuerySimpleWithUpdateAndLastCidAndDocID(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "Johnn", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Johnn", + }, }, }, }, @@ -230,9 +236,11 @@ func TestQuerySimpleWithUpdateAndMiddleCidAndDocID(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "Johnn", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Johnn", + }, }, }, }, @@ -275,12 +283,14 @@ func TestQuerySimpleWithUpdateAndFirstCidAndDocIDAndSchemaVersion(t *testing.T) } } }`, - Results: []map[string]any{ - { - "name": "John", - "_version": []map[string]any{ - { - "schemaVersionId": "bafkreia3o3cetvcnnxyu5spucimoos77ifungfmacxdkva4zah2is3aooe", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_version": []map[string]any{ + { + "schemaVersionId": "bafkreia3o3cetvcnnxyu5spucimoos77ifungfmacxdkva4zah2is3aooe", + }, }, }, }, @@ -331,10 +341,12 @@ func TestCidAndDocIDQuery_ContainsPNCounterWithIntKind_NoError(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "name": "John", - "points": int64(10), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "points": int64(10), + }, }, }, }, @@ -383,10 +395,12 @@ func TestCidAndDocIDQuery_ContainsPNCounterWithFloatKind_NoError(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "name": "John", - "points": 10.2, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "points": 10.2, + }, }, }, }, @@ -430,10 +444,12 @@ func TestCidAndDocIDQuery_ContainsPCounterWithIntKind_NoError(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "name": "John", - "points": int64(10), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "points": int64(10), + }, }, }, }, @@ -477,10 +493,12 @@ func TestCidAndDocIDQuery_ContainsPCounterWithFloatKind_NoError(t *testing.T) { points } }`, - Results: []map[string]any{ - { - "name": "John", - "points": 10.2, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "points": 10.2, + }, }, }, }, diff --git a/tests/integration/query/simple/with_count_filter_test.go b/tests/integration/query/simple/with_count_filter_test.go index 4724815a9c..8bf9182bfe 100644 --- a/tests/integration/query/simple/with_count_filter_test.go +++ b/tests/integration/query/simple/with_count_filter_test.go @@ -38,10 +38,8 @@ func TestQuerySimpleWithCountWithFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "_count": 2, - }, + Results: map[string]any{ + "_count": 2, }, } @@ -73,10 +71,8 @@ func TestQuerySimpleWithCountWithDateTimeFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "_count": 2, - }, + Results: map[string]any{ + "_count": 2, }, } diff --git a/tests/integration/query/simple/with_count_test.go b/tests/integration/query/simple/with_count_test.go index 47cb153c85..338d6847b6 100644 --- a/tests/integration/query/simple/with_count_test.go +++ b/tests/integration/query/simple/with_count_test.go @@ -34,10 +34,8 @@ func TestQuerySimpleWithCountOnEmptyCollection(t *testing.T) { Request: `query { _count(Users: {}) }`, - Results: []map[string]any{ - { - "_count": 0, - }, + Results: map[string]any{ + "_count": 0, }, } @@ -62,10 +60,8 @@ func TestQuerySimpleWithCount(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "_count": 2, - }, + Results: map[string]any{ + "_count": 2, }, } diff --git a/tests/integration/query/simple/with_deleted_field_test.go b/tests/integration/query/simple/with_deleted_field_test.go index cc302e29b7..383c2b49b5 100644 --- a/tests/integration/query/simple/with_deleted_field_test.go +++ b/tests/integration/query/simple/with_deleted_field_test.go @@ -49,14 +49,16 @@ func TestQuerySimple_WithDeletedField(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "_deleted": true, - "name": "John", - }, - { - "_deleted": true, - "name": "Andy", + Results: map[string]any{ + "User": []map[string]any{ + { + "_deleted": true, + "name": "John", + }, + { + "_deleted": true, + "name": "Andy", + }, }, }, }, diff --git a/tests/integration/query/simple/with_doc_id_filter_test.go b/tests/integration/query/simple/with_doc_id_filter_test.go index 7c1e886787..91bf2ef9cb 100644 --- a/tests/integration/query/simple/with_doc_id_filter_test.go +++ b/tests/integration/query/simple/with_doc_id_filter_test.go @@ -37,10 +37,12 @@ func TestQuerySimpleWithDocIDFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, }, }, } diff --git a/tests/integration/query/simple/with_doc_id_test.go b/tests/integration/query/simple/with_doc_id_test.go index 7d5e7c0206..5f0b6fb316 100644 --- a/tests/integration/query/simple/with_doc_id_test.go +++ b/tests/integration/query/simple/with_doc_id_test.go @@ -34,10 +34,12 @@ func TestQuerySimpleWithDocIDFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, }, }, }, @@ -57,7 +59,9 @@ func TestQuerySimpleWithDocIDFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, { Description: "Simple query with basic filter (by docID arg), partial results", @@ -79,10 +83,12 @@ func TestQuerySimpleWithDocIDFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, }, }, }, diff --git a/tests/integration/query/simple/with_doc_ids_test.go b/tests/integration/query/simple/with_doc_ids_test.go index 1dc61bb610..285a84f87e 100644 --- a/tests/integration/query/simple/with_doc_ids_test.go +++ b/tests/integration/query/simple/with_doc_ids_test.go @@ -34,10 +34,12 @@ func TestQuerySimpleWithDocIDsFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, }, }, }, @@ -57,7 +59,9 @@ func TestQuerySimpleWithDocIDsFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, { Description: "Simple query with basic filter (duplicate ID by docIDs arg), partial results", @@ -79,10 +83,12 @@ func TestQuerySimpleWithDocIDsFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, }, }, }, @@ -110,14 +116,16 @@ func TestQuerySimpleWithDocIDsFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Jim", - "Age": int64(27), - }, - { - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Jim", + "Age": int64(27), + }, + { + "Name": "John", + "Age": int64(21), + }, }, }, }, @@ -145,7 +153,9 @@ func TestQuerySimpleReturnsNothinGivenEmptyDocIDsFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, } executeTestCase(t, test) diff --git a/tests/integration/query/simple/with_filter/with_and_test.go b/tests/integration/query/simple/with_filter/with_and_test.go index bbcbeb38b9..4bac7cf5af 100644 --- a/tests/integration/query/simple/with_filter/with_and_test.go +++ b/tests/integration/query/simple/with_filter/with_and_test.go @@ -45,14 +45,16 @@ func TestQuerySimpleWithIntGreaterThanAndIntLessThanFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Bob", - "Age": int64(32), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Bob", + "Age": int64(32), + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_eq_blob_test.go b/tests/integration/query/simple/with_filter/with_eq_blob_test.go index 76a804f98a..25d7fb9840 100644 --- a/tests/integration/query/simple/with_filter/with_eq_blob_test.go +++ b/tests/integration/query/simple/with_filter/with_eq_blob_test.go @@ -45,7 +45,11 @@ func TestQuerySimple_WithEqOpOnBlobField_ShouldFilter(t *testing.T) { name } }`, - Results: []map[string]any{{"name": "John"}}, + Results: map[string]any{ + "Users": []map[string]any{ + {"name": "John"}, + }, + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_eq_datetime_test.go b/tests/integration/query/simple/with_filter/with_eq_datetime_test.go index bf4518749a..0f72bd05ab 100644 --- a/tests/integration/query/simple/with_filter/with_eq_datetime_test.go +++ b/tests/integration/query/simple/with_filter/with_eq_datetime_test.go @@ -40,11 +40,13 @@ func TestQuerySimpleWithDateTimeEqualsFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Age": int64(21), - "CreatedAt": testUtils.MustParseTime("2017-07-23T03:46:56-05:00"), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + "CreatedAt": testUtils.MustParseTime("2017-07-23T03:46:56-05:00"), + }, }, }, } @@ -80,11 +82,13 @@ func TestQuerySimpleWithDateTimeEqualsNilFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Fred", - "Age": int64(44), - "CreatedAt": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Fred", + "Age": int64(44), + "CreatedAt": nil, + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_eq_float_test.go b/tests/integration/query/simple/with_filter/with_eq_float_test.go index 2e5f677e7b..340236f580 100644 --- a/tests/integration/query/simple/with_filter/with_eq_float_test.go +++ b/tests/integration/query/simple/with_filter/with_eq_float_test.go @@ -37,10 +37,12 @@ func TestQuerySimpleWithFloatEqualsFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "HeightM": float64(2.1), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "HeightM": float64(2.1), + }, }, }, } @@ -72,10 +74,12 @@ func TestQuerySimpleWithFloatEqualsNilFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Fred", - "HeightM": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Fred", + "HeightM": nil, + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_eq_int_test.go b/tests/integration/query/simple/with_filter/with_eq_int_test.go index 067c2d2198..576f2fa38e 100644 --- a/tests/integration/query/simple/with_filter/with_eq_int_test.go +++ b/tests/integration/query/simple/with_filter/with_eq_int_test.go @@ -37,10 +37,12 @@ func TestQuerySimpleWithIntEqualsFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, }, }, } @@ -72,10 +74,12 @@ func TestQuerySimpleWithIntEqualsNilFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Fred", - "Age": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Fred", + "Age": nil, + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_eq_json_test.go b/tests/integration/query/simple/with_filter/with_eq_json_test.go index d0d9e93369..da0c03ed4b 100644 --- a/tests/integration/query/simple/with_filter/with_eq_json_test.go +++ b/tests/integration/query/simple/with_filter/with_eq_json_test.go @@ -46,7 +46,11 @@ func TestQuerySimple_WithEqOpOnJSONField_ShouldFilter(t *testing.T) { name } }`, - Results: []map[string]any{{"name": "Andy"}}, + Results: map[string]any{ + "Users": []map[string]any{ + {"name": "Andy"}, + }, + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_eq_string_test.go b/tests/integration/query/simple/with_filter/with_eq_string_test.go index 18b03bee58..bc9d249877 100644 --- a/tests/integration/query/simple/with_filter/with_eq_string_test.go +++ b/tests/integration/query/simple/with_filter/with_eq_string_test.go @@ -37,10 +37,12 @@ func TestQuerySimpleWithStringFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, }, }, } @@ -72,10 +74,12 @@ func TestQuerySimpleWithStringEqualsNilFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": nil, - "Age": int64(60), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": nil, + "Age": int64(60), + }, }, }, } @@ -104,9 +108,11 @@ func TestQuerySimpleWithStringFilterBlockAndSelect(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, }, @@ -129,9 +135,11 @@ func TestQuerySimpleWithStringFilterBlockAndSelect(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(21), + }, }, }, }, @@ -151,7 +159,9 @@ func TestQuerySimpleWithStringFilterBlockAndSelect(t *testing.T) { }`, }, }, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, } diff --git a/tests/integration/query/simple/with_filter/with_ge_datetime_test.go b/tests/integration/query/simple/with_filter/with_ge_datetime_test.go index 69eddcd9c4..a21a120c44 100644 --- a/tests/integration/query/simple/with_filter/with_ge_datetime_test.go +++ b/tests/integration/query/simple/with_filter/with_ge_datetime_test.go @@ -38,9 +38,11 @@ func TestQuerySimpleWithDateTimeGEFilterBlockWithEqualValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, } @@ -70,9 +72,11 @@ func TestQuerySimpleWithDateTimeGEFilterBlockWithGreaterValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, } @@ -102,7 +106,9 @@ func TestQuerySimpleWithDateTimeGEFilterBlockWithLesserValue(t *testing.T) { }`, }, }, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, } executeTestCase(t, test) @@ -127,12 +133,14 @@ func TestQuerySimpleWithDateTimeGEFilterBlockWithNilValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Bob", - }, - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_ge_float_test.go b/tests/integration/query/simple/with_filter/with_ge_float_test.go index 3983f08718..be0a6d9c12 100644 --- a/tests/integration/query/simple/with_filter/with_ge_float_test.go +++ b/tests/integration/query/simple/with_filter/with_ge_float_test.go @@ -36,9 +36,11 @@ func TestQuerySimpleWithHeightMGEFilterBlockWithEqualValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, } @@ -66,9 +68,11 @@ func TestQuerySimpleWithHeightMGEFilterBlockWithLesserValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, } @@ -96,9 +100,11 @@ func TestQuerySimpleWithHeightMGEFilterBlockWithLesserIntValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, } @@ -125,12 +131,14 @@ func TestQuerySimpleWithHeightMGEFilterBlockWithNilValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - }, - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + { + "Name": "Bob", + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_ge_int_test.go b/tests/integration/query/simple/with_filter/with_ge_int_test.go index e780bef687..5a07a18b01 100644 --- a/tests/integration/query/simple/with_filter/with_ge_int_test.go +++ b/tests/integration/query/simple/with_filter/with_ge_int_test.go @@ -36,9 +36,11 @@ func TestQuerySimpleWithIntGEFilterBlockWithEqualValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, }, }, } @@ -66,9 +68,11 @@ func TestQuerySimpleWithIntGEFilterBlockWithGreaterValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, }, }, } @@ -95,12 +99,14 @@ func TestQuerySimpleWithIntGEFilterBlockWithNilValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Bob", - }, - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_gt_datetime_test.go b/tests/integration/query/simple/with_filter/with_gt_datetime_test.go index 468dcf07e5..e12a74a36f 100644 --- a/tests/integration/query/simple/with_filter/with_gt_datetime_test.go +++ b/tests/integration/query/simple/with_filter/with_gt_datetime_test.go @@ -38,9 +38,11 @@ func TestQuerySimpleWithDateTimeGTFilterBlockWithEqualValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, } @@ -70,9 +72,11 @@ func TestQuerySimpleWithDateTimeGTFilterBlockWithGreaterValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, } @@ -102,7 +106,9 @@ func TestQuerySimpleWithDateTimeGTFilterBlockWithLesserValue(t *testing.T) { }`, }, }, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, } executeTestCase(t, test) @@ -127,9 +133,11 @@ func TestQuerySimpleWithDateTimeGTFilterBlockWithNilValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_gt_float_test.go b/tests/integration/query/simple/with_filter/with_gt_float_test.go index fea3cc968a..da72d4df51 100644 --- a/tests/integration/query/simple/with_filter/with_gt_float_test.go +++ b/tests/integration/query/simple/with_filter/with_gt_float_test.go @@ -37,9 +37,11 @@ func TestQuerySimpleWithFloatGreaterThanFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, }, @@ -62,7 +64,9 @@ func TestQuerySimpleWithFloatGreaterThanFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, { Description: "Simple query with basic float greater than filter, multiple results", @@ -83,12 +87,14 @@ func TestQuerySimpleWithFloatGreaterThanFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - }, - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + { + "Name": "Bob", + }, }, }, }, @@ -119,9 +125,11 @@ func TestQuerySimpleWithFloatGreaterThanFilterBlockWithIntFilterValue(t *testing }`, }, }, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, } @@ -148,9 +156,11 @@ func TestQuerySimpleWithFloatGreaterThanFilterBlockWithNullFilterValue(t *testin }`, }, }, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_gt_int_test.go b/tests/integration/query/simple/with_filter/with_gt_int_test.go index d832114cac..3cbdf82250 100644 --- a/tests/integration/query/simple/with_filter/with_gt_int_test.go +++ b/tests/integration/query/simple/with_filter/with_gt_int_test.go @@ -38,10 +38,12 @@ func TestQuerySimpleWithIntGreaterThanFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, }, }, }, @@ -65,7 +67,9 @@ func TestQuerySimpleWithIntGreaterThanFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, { Description: "Simple query with basic filter(age), multiple results", @@ -87,14 +91,16 @@ func TestQuerySimpleWithIntGreaterThanFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Bob", - "Age": int64(32), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Bob", + "Age": int64(32), + }, }, }, }, @@ -124,9 +130,11 @@ func TestQuerySimpleWithIntGreaterThanFilterBlockWithNullFilterValue(t *testing. }`, }, }, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_in_blob_test.go b/tests/integration/query/simple/with_filter/with_in_blob_test.go index a168a297ac..64a8b17888 100644 --- a/tests/integration/query/simple/with_filter/with_in_blob_test.go +++ b/tests/integration/query/simple/with_filter/with_in_blob_test.go @@ -45,7 +45,11 @@ func TestQuerySimple_WithInOpOnBlobField_ShouldFilter(t *testing.T) { name } }`, - Results: []map[string]any{{"name": "John"}}, + Results: map[string]any{ + "Users": []map[string]any{ + {"name": "John"}, + }, + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_in_json_test.go b/tests/integration/query/simple/with_filter/with_in_json_test.go index cb4fcdc7da..b9bab035f4 100644 --- a/tests/integration/query/simple/with_filter/with_in_json_test.go +++ b/tests/integration/query/simple/with_filter/with_in_json_test.go @@ -46,7 +46,11 @@ func TestQuerySimple_WithInOpOnJSONField_ShouldFilter(t *testing.T) { name } }`, - Results: []map[string]any{{"name": "Andy"}}, + Results: map[string]any{ + "Users": []map[string]any{ + {"name": "Andy"}, + }, + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_in_test.go b/tests/integration/query/simple/with_filter/with_in_test.go index 75867469d9..887a4ccbdb 100644 --- a/tests/integration/query/simple/with_filter/with_in_test.go +++ b/tests/integration/query/simple/with_filter/with_in_test.go @@ -45,14 +45,16 @@ func TestQuerySimpleWithIntInFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Carlo", - "Age": int64(55), - }, - { - "Name": "Alice", - "Age": int64(19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "Age": int64(55), + }, + { + "Name": "Alice", + "Age": int64(19), + }, }, }, } @@ -88,12 +90,14 @@ func TestQuerySimpleWithIntInFilterOnFloat(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Carlo", - }, - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + }, + { + "Name": "John", + }, }, }, } @@ -133,18 +137,20 @@ func TestQuerySimpleWithIntInFilterWithNullValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Fred", - "Age": nil, - }, - { - "Name": "Carlo", - "Age": int64(55), - }, - { - "Name": "Alice", - "Age": int64(19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Fred", + "Age": nil, + }, + { + "Name": "Carlo", + "Age": int64(55), + }, + { + "Name": "Alice", + "Age": int64(19), + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_le_datetime_test.go b/tests/integration/query/simple/with_filter/with_le_datetime_test.go index 051a97de43..3e1dc9ff96 100644 --- a/tests/integration/query/simple/with_filter/with_le_datetime_test.go +++ b/tests/integration/query/simple/with_filter/with_le_datetime_test.go @@ -38,9 +38,11 @@ func TestQuerySimpleWithDateTimeLEFilterBlockWithEqualValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, } @@ -70,9 +72,11 @@ func TestQuerySimpleWithDateTimeLEFilterBlockWithGreaterValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, } @@ -101,9 +105,11 @@ func TestQuerySimpleWithDateTimeLEFilterBlockWithNullValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_le_float_test.go b/tests/integration/query/simple/with_filter/with_le_float_test.go index 45be20cb44..f5d2e7e3fc 100644 --- a/tests/integration/query/simple/with_filter/with_le_float_test.go +++ b/tests/integration/query/simple/with_filter/with_le_float_test.go @@ -36,9 +36,11 @@ func TestQuerySimpleWithFloatLEFilterBlockWithEqualValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, }, }, } @@ -66,9 +68,11 @@ func TestQuerySimpleWithFloatLEFilterBlockWithGreaterValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, }, }, } @@ -96,9 +100,11 @@ func TestQuerySimpleWithFloatLEFilterBlockWithGreaterIntValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, }, }, } @@ -125,9 +131,11 @@ func TestQuerySimpleWithFloatLEFilterBlockWithNullValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_le_int_test.go b/tests/integration/query/simple/with_filter/with_le_int_test.go index 2d9f543b12..1dd363c25e 100644 --- a/tests/integration/query/simple/with_filter/with_le_int_test.go +++ b/tests/integration/query/simple/with_filter/with_le_int_test.go @@ -36,9 +36,11 @@ func TestQuerySimpleWithIntLEFilterBlockWithEqualValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, } @@ -66,9 +68,11 @@ func TestQuerySimpleWithIntLEFilterBlockWithGreaterValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, } @@ -95,9 +99,11 @@ func TestQuerySimpleWithIntLEFilterBlockWithNullValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_like_blob_test.go b/tests/integration/query/simple/with_filter/with_like_blob_test.go index bc51930f06..84e1ed3825 100644 --- a/tests/integration/query/simple/with_filter/with_like_blob_test.go +++ b/tests/integration/query/simple/with_filter/with_like_blob_test.go @@ -45,7 +45,11 @@ func TestQuerySimple_WithLikeOpOnBlobField_ShouldFilter(t *testing.T) { name } }`, - Results: []map[string]any{{"name": "John"}}, + Results: map[string]any{ + "Users": []map[string]any{ + {"name": "John"}, + }, + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_like_json_test.go b/tests/integration/query/simple/with_filter/with_like_json_test.go index ed092dd502..f77041ada0 100644 --- a/tests/integration/query/simple/with_filter/with_like_json_test.go +++ b/tests/integration/query/simple/with_filter/with_like_json_test.go @@ -45,7 +45,11 @@ func TestQuerySimple_WithLikeOpOnJSONField_ShouldFilter(t *testing.T) { name } }`, - Results: []map[string]any{{"name": "Andy"}}, + Results: map[string]any{ + "Users": []map[string]any{ + {"name": "Andy"}, + }, + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_like_string_test.go b/tests/integration/query/simple/with_filter/with_like_string_test.go index ff6ddf1fa2..9aa5ede34b 100644 --- a/tests/integration/query/simple/with_filter/with_like_string_test.go +++ b/tests/integration/query/simple/with_filter/with_like_string_test.go @@ -36,9 +36,11 @@ func TestQuerySimpleWithLikeStringContainsFilterBlockContainsString(t *testing.T }`, }, }, - Results: []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, }, }, } @@ -66,9 +68,11 @@ func TestQuerySimple_WithCaseInsensitiveLike_ShouldMatchString(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, }, }, } @@ -96,9 +100,11 @@ func TestQuerySimpleWithLikeStringContainsFilterBlockAsPrefixString(t *testing.T }`, }, }, - Results: []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, }, }, } @@ -126,9 +132,11 @@ func TestQuerySimple_WithCaseInsensitiveLikeString_ShouldMatchPrefixString(t *te }`, }, }, - Results: []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, }, }, } @@ -156,9 +164,11 @@ func TestQuerySimpleWithLikeStringContainsFilterBlockAsSuffixString(t *testing.T }`, }, }, - Results: []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, }, }, } @@ -186,9 +196,11 @@ func TestQuerySimple_WithCaseInsensitiveLikeString_ShouldMatchSuffixString(t *te }`, }, }, - Results: []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, }, }, } @@ -216,9 +228,11 @@ func TestQuerySimpleWithLikeStringContainsFilterBlockExactString(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, }, }, } @@ -246,9 +260,11 @@ func TestQuerySimple_WithCaseInsensitiveLikeString_ShouldMatchExactString(t *tes }`, }, }, - Results: []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, }, }, } @@ -276,12 +292,14 @@ func TestQuerySimpleWithLikeStringContainsFilterBlockContainsStringMuplitpleResu }`, }, }, - Results: []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", - }, - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, }, }, } @@ -309,9 +327,11 @@ func TestQuerySimpleWithLikeStringContainsFilterBlockHasStartAndEnd(t *testing.T }`, }, }, - Results: []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, }, }, } @@ -339,7 +359,9 @@ func TestQuerySimpleWithLikeStringContainsFilterBlockHasBoth(t *testing.T) { }`, }, }, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, } executeTestCase(t, test) @@ -365,9 +387,11 @@ func TestQuerySimpleWithLikeStringContainsFilterBlockHasEither(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, }, }, } @@ -398,9 +422,11 @@ func TestQuerySimpleWithLikeStringContainsFilterBlockPropNotSet(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_lt_datetime_test.go b/tests/integration/query/simple/with_filter/with_lt_datetime_test.go index 0d17607891..da6f60354e 100644 --- a/tests/integration/query/simple/with_filter/with_lt_datetime_test.go +++ b/tests/integration/query/simple/with_filter/with_lt_datetime_test.go @@ -38,9 +38,11 @@ func TestQuerySimpleWithDateTimeLTFilterBlockWithGreaterValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, } @@ -69,7 +71,9 @@ func TestQuerySimpleWithDateTimeLTFilterBlockWithNullValue(t *testing.T) { }`, }, }, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, } executeTestCase(t, test) diff --git a/tests/integration/query/simple/with_filter/with_lt_float_test.go b/tests/integration/query/simple/with_filter/with_lt_float_test.go index ef7b601fcd..84e3c6122a 100644 --- a/tests/integration/query/simple/with_filter/with_lt_float_test.go +++ b/tests/integration/query/simple/with_filter/with_lt_float_test.go @@ -36,9 +36,11 @@ func TestQuerySimpleWithFloatLessThanFilterBlockWithGreaterValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, }, }, } @@ -66,9 +68,11 @@ func TestQuerySimpleWithFloatLessThanFilterBlockWithGreaterIntValue(t *testing.T }`, }, }, - Results: []map[string]any{ - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, }, }, } @@ -96,7 +100,9 @@ func TestQuerySimpleWithFloatLessThanFilterBlockWithNullValue(t *testing.T) { }`, }, }, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, } executeTestCase(t, test) diff --git a/tests/integration/query/simple/with_filter/with_lt_int_test.go b/tests/integration/query/simple/with_filter/with_lt_int_test.go index d26ecdc5a4..12bf972938 100644 --- a/tests/integration/query/simple/with_filter/with_lt_int_test.go +++ b/tests/integration/query/simple/with_filter/with_lt_int_test.go @@ -36,9 +36,11 @@ func TestQuerySimpleWithIntLessThanFilterBlockWithGreaterValue(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, }, }, } @@ -65,7 +67,9 @@ func TestQuerySimpleWithIntLessThanFilterBlockWithNullValue(t *testing.T) { }`, }, }, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, } executeTestCase(t, test) diff --git a/tests/integration/query/simple/with_filter/with_ne_bool_test.go b/tests/integration/query/simple/with_filter/with_ne_bool_test.go index 4b68d73592..1f25203e89 100644 --- a/tests/integration/query/simple/with_filter/with_ne_bool_test.go +++ b/tests/integration/query/simple/with_filter/with_ne_bool_test.go @@ -39,12 +39,14 @@ func TestQuerySimpleWithBoolNotEqualsTrueFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Fred", - }, - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Fred", + }, + { + "Name": "Bob", + }, }, }, } @@ -75,12 +77,14 @@ func TestQuerySimpleWithBoolNotEqualsNilFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - }, - { - "Name": "Fred", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + { + "Name": "Fred", + }, }, }, } @@ -111,12 +115,14 @@ func TestQuerySimpleWithBoolNotEqualsFalseFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - }, - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + { + "Name": "Bob", + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_ne_datetime_test.go b/tests/integration/query/simple/with_filter/with_ne_datetime_test.go index 11acb8629c..f6423ed95c 100644 --- a/tests/integration/query/simple/with_filter/with_ne_datetime_test.go +++ b/tests/integration/query/simple/with_filter/with_ne_datetime_test.go @@ -38,9 +38,11 @@ func TestQuerySimpleWithDateTimeNotEqualsFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, }, }, } @@ -74,12 +76,14 @@ func TestQuerySimpleWithDateTimeNotEqualsNilFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Bob", - }, - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_ne_float_test.go b/tests/integration/query/simple/with_filter/with_ne_float_test.go index fc742547c6..6e8e04175f 100644 --- a/tests/integration/query/simple/with_filter/with_ne_float_test.go +++ b/tests/integration/query/simple/with_filter/with_ne_float_test.go @@ -36,9 +36,11 @@ func TestQuerySimpleWithFloatNotEqualsFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, }, }, } @@ -69,12 +71,14 @@ func TestQuerySimpleWithFloatNotEqualsNilFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - }, - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + { + "Name": "Bob", + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_ne_int_test.go b/tests/integration/query/simple/with_filter/with_ne_int_test.go index 7f61063eed..543af47d31 100644 --- a/tests/integration/query/simple/with_filter/with_ne_int_test.go +++ b/tests/integration/query/simple/with_filter/with_ne_int_test.go @@ -36,9 +36,11 @@ func TestQuerySimpleWithIntNotEqualsFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, }, }, } @@ -69,12 +71,14 @@ func TestQuerySimpleWithIntNotEqualsNilFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - }, - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + { + "Name": "Bob", + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_ne_string_test.go b/tests/integration/query/simple/with_filter/with_ne_string_test.go index b052e89e89..141e9b6d78 100644 --- a/tests/integration/query/simple/with_filter/with_ne_string_test.go +++ b/tests/integration/query/simple/with_filter/with_ne_string_test.go @@ -36,9 +36,11 @@ func TestQuerySimpleWithStringNotEqualsFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + }, }, }, } @@ -69,12 +71,14 @@ func TestQuerySimpleWithStringNotEqualsNilFilterBlock(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Age": int64(21), - }, - { - "Age": int64(32), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(21), + }, + { + "Age": int64(32), + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_nin_test.go b/tests/integration/query/simple/with_filter/with_nin_test.go index 9993847c0e..bd0f1b7333 100644 --- a/tests/integration/query/simple/with_filter/with_nin_test.go +++ b/tests/integration/query/simple/with_filter/with_nin_test.go @@ -47,12 +47,14 @@ func TestQuerySimpleWithNotInFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - }, - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + { + "Name": "Bob", + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_nlike_string_test.go b/tests/integration/query/simple/with_filter/with_nlike_string_test.go index 14526d39e2..7c07b785ae 100644 --- a/tests/integration/query/simple/with_filter/with_nlike_string_test.go +++ b/tests/integration/query/simple/with_filter/with_nlike_string_test.go @@ -36,9 +36,11 @@ func TestQuerySimpleWithNotLikeStringContainsFilterBlockContainsString(t *testin }`, }, }, - Results: []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, }, }, } @@ -66,9 +68,11 @@ func TestQuerySimple_WithNotCaseInsensitiveLikeString_ShouldMatchString(t *testi }`, }, }, - Results: []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, }, }, } @@ -96,9 +100,11 @@ func TestQuerySimpleWithNotLikeStringContainsFilterBlockAsPrefixString(t *testin }`, }, }, - Results: []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, }, }, } @@ -126,9 +132,11 @@ func TestQuerySimple_WithNotCaseInsensitiveLikeString_ShouldMatchPrefixString(t }`, }, }, - Results: []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, }, }, } @@ -156,9 +164,11 @@ func TestQuerySimpleWithNotLikeStringContainsFilterBlockAsSuffixString(t *testin }`, }, }, - Results: []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, }, }, } @@ -186,9 +196,11 @@ func TestQuerySimple_WithNotCaseInsensitiveLikeString_ShouldMatchSuffixString(t }`, }, }, - Results: []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, }, }, } @@ -216,9 +228,11 @@ func TestQuerySimpleWithNotLikeStringContainsFilterBlockExactString(t *testing.T }`, }, }, - Results: []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, }, }, } @@ -246,9 +260,11 @@ func TestQuerySimple_WithNotCaseInsensitiveLikeString_MatchExactString(t *testin }`, }, }, - Results: []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, }, }, } @@ -276,7 +292,9 @@ func TestQuerySimpleWithNotLikeStringContainsFilterBlockContainsStringMuplitpleR }`, }, }, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, } executeTestCase(t, test) @@ -302,9 +320,11 @@ func TestQuerySimpleWithNotLikeStringContainsFilterBlockHasStartAndEnd(t *testin }`, }, }, - Results: []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, }, }, } @@ -332,9 +352,11 @@ func TestQuerySimpleWithNotLikeStringContainsFilterBlockHasBoth(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, }, }, } @@ -362,12 +384,14 @@ func TestQuerySimpleWithNotLikeStringContainsFilterBlockHasEither(t *testing.T) }`, }, }, - Results: []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", - }, - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, }, }, } @@ -398,12 +422,14 @@ func TestQuerySimpleWithNotLikeStringContainsFilterBlockPropNotSet(t *testing.T) }`, }, }, - Results: []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", - }, - { - "Name": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, + { + "Name": nil, + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_not_test.go b/tests/integration/query/simple/with_filter/with_not_test.go index 14fef0d155..6e9ffcc0da 100644 --- a/tests/integration/query/simple/with_filter/with_not_test.go +++ b/tests/integration/query/simple/with_filter/with_not_test.go @@ -45,18 +45,20 @@ func TestQuerySimple_WithNotEqualToXFilter_NoError(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Bob", - "Age": int64(32), - }, - { - "Name": "Alice", - "Age": int64(19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Bob", + "Age": int64(32), + }, + { + "Name": "Alice", + "Age": int64(19), + }, }, }, } @@ -93,10 +95,12 @@ func TestQuerySimple_WithNotAndComparisonXFilter_NoError(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Alice", - "Age": int64(19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Alice", + "Age": int64(19), + }, }, }, } @@ -133,14 +137,16 @@ func TestQuerySimple_WithNotEqualToXorYFilter_NoError(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Bob", - "Age": int64(32), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Bob", + "Age": int64(32), + }, }, }, } @@ -177,7 +183,9 @@ func TestQuerySimple_WithEmptyNotFilter_ReturnError(t *testing.T) { }`, }, }, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, } executeTestCase(t, test) @@ -216,22 +224,24 @@ func TestQuerySimple_WithNotEqualToXAndNotYFilter_NoError(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Bob", - "Age": int64(32), - }, - { - "Name": "Carlo", - "Age": int64(55), - }, - { - "Name": "Alice", - "Age": int64(19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Bob", + "Age": int64(32), + }, + { + "Name": "Carlo", + "Age": int64(55), + }, + { + "Name": "Alice", + "Age": int64(19), + }, }, }, } diff --git a/tests/integration/query/simple/with_filter/with_or_test.go b/tests/integration/query/simple/with_filter/with_or_test.go index 2c1ea68e94..6a913730c2 100644 --- a/tests/integration/query/simple/with_filter/with_or_test.go +++ b/tests/integration/query/simple/with_filter/with_or_test.go @@ -45,14 +45,16 @@ func TestQuerySimpleWithIntEqualToXOrYFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Carlo", - "Age": int64(55), - }, - { - "Name": "Alice", - "Age": int64(19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "Age": int64(55), + }, + { + "Name": "Alice", + "Age": int64(19), + }, }, }, } diff --git a/tests/integration/query/simple/with_group_average_count_test.go b/tests/integration/query/simple/with_group_average_count_test.go index b5f13fce1b..837b12d11c 100644 --- a/tests/integration/query/simple/with_group_average_count_test.go +++ b/tests/integration/query/simple/with_group_average_count_test.go @@ -47,16 +47,18 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerAverageA }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_avg": float64(35), - "_count": int(2), - }, - { - "Name": "Alice", - "_avg": float64(-19), - "_count": int(1), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(35), + "_count": int(2), + }, + { + "Name": "Alice", + "_avg": float64(-19), + "_count": int(1), + }, }, }, } diff --git a/tests/integration/query/simple/with_group_average_filter_test.go b/tests/integration/query/simple/with_group_average_filter_test.go index fa68f2d0e9..6f17370301 100644 --- a/tests/integration/query/simple/with_group_average_filter_test.go +++ b/tests/integration/query/simple/with_group_average_filter_test.go @@ -41,14 +41,16 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildAverageWithFilt }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_avg": float64(33), - }, - { - "Name": "Alice", - "_avg": float64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(33), + }, + { + "Name": "Alice", + "_avg": float64(0), + }, }, }, } @@ -84,25 +86,27 @@ func TestQuerySimpleWithGroupByStringWithRenderedGroupAndChildAverageWithFilter( }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_avg": float64(33), - "_group": []map[string]any{ - { - "Age": int64(34), - }, - { - "Age": int64(32), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(33), + "_group": []map[string]any{ + { + "Age": int64(34), + }, + { + "Age": int64(32), + }, }, }, - }, - { - "Name": "Alice", - "_avg": float64(0), - "_group": []map[string]any{ - { - "Age": int64(19), + { + "Name": "Alice", + "_avg": float64(0), + "_group": []map[string]any{ + { + "Age": int64(19), + }, }, }, }, @@ -143,25 +147,27 @@ func TestQuerySimpleWithGroupByStringWithRenderedGroupAndChildAverageWithDateTim }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_avg": float64(33), - "_group": []map[string]any{ - { - "Age": int64(32), - }, - { - "Age": int64(34), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(33), + "_group": []map[string]any{ + { + "Age": int64(32), + }, + { + "Age": int64(34), + }, }, }, - }, - { - "Name": "Alice", - "_avg": float64(0), - "_group": []map[string]any{ - { - "Age": int64(19), + { + "Name": "Alice", + "_avg": float64(0), + "_group": []map[string]any{ + { + "Age": int64(19), + }, }, }, }, @@ -199,20 +205,22 @@ func TestQuerySimpleWithGroupByStringWithRenderedGroupWithFilterAndChildAverageW }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_avg": float64(34), - "_group": []map[string]any{ - { - "Age": int64(34), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(34), + "_group": []map[string]any{ + { + "Age": int64(34), + }, }, }, - }, - { - "Name": "Alice", - "_avg": float64(0), - "_group": []map[string]any{}, + { + "Name": "Alice", + "_avg": float64(0), + "_group": []map[string]any{}, + }, }, }, } @@ -251,20 +259,22 @@ func TestQuerySimpleWithGroupByStringWithRenderedGroupWithFilterAndChildAverageW }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_avg": float64(34), - "_group": []map[string]any{ - { - "Age": int64(34), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(34), + "_group": []map[string]any{ + { + "Age": int64(34), + }, }, }, - }, - { - "Name": "Alice", - "_avg": float64(0), - "_group": []map[string]any{}, + { + "Name": "Alice", + "_avg": float64(0), + "_group": []map[string]any{}, + }, }, }, } @@ -300,22 +310,24 @@ func TestQuerySimpleWithGroupByStringWithRenderedGroupWithFilterAndChildAverageW }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_avg": float64(34), - "_group": []map[string]any{ - { - "Age": int64(32), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(34), + "_group": []map[string]any{ + { + "Age": int64(32), + }, }, }, - }, - { - "Name": "Alice", - "_avg": float64(0), - "_group": []map[string]any{ - { - "Age": int64(19), + { + "Name": "Alice", + "_avg": float64(0), + "_group": []map[string]any{ + { + "Age": int64(19), + }, }, }, }, @@ -351,16 +363,18 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildAveragesWithDif }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "A1": float64(33), - "A2": float64(0), - }, - { - "Name": "Alice", - "A1": float64(0), - "A2": float64(19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "A1": float64(33), + "A2": float64(0), + }, + { + "Name": "Alice", + "A1": float64(0), + "A2": float64(19), + }, }, }, } @@ -401,14 +415,16 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildAverageWithFilt }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_avg": float64(31), - }, - { - "Name": "Alice", - "_avg": float64(19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(31), + }, + { + "Name": "Alice", + "_avg": float64(19), + }, }, }, } diff --git a/tests/integration/query/simple/with_group_average_limit_offset_test.go b/tests/integration/query/simple/with_group_average_limit_offset_test.go index 935ca5cb78..110dcc8bfd 100644 --- a/tests/integration/query/simple/with_group_average_limit_offset_test.go +++ b/tests/integration/query/simple/with_group_average_limit_offset_test.go @@ -46,14 +46,16 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerAverageW }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_avg": float64(35), - }, - { - "Name": "Alice", - "_avg": float64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(35), + }, + { + "Name": "Alice", + "_avg": float64(0), + }, }, }, } diff --git a/tests/integration/query/simple/with_group_average_limit_test.go b/tests/integration/query/simple/with_group_average_limit_test.go index bb28de8793..ca5b1b0d81 100644 --- a/tests/integration/query/simple/with_group_average_limit_test.go +++ b/tests/integration/query/simple/with_group_average_limit_test.go @@ -46,14 +46,16 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerAverageW }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_avg": float64(33), - }, - { - "Name": "Alice", - "_avg": float64(-19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(33), + }, + { + "Name": "Alice", + "_avg": float64(-19), + }, }, }, } diff --git a/tests/integration/query/simple/with_group_average_sum_test.go b/tests/integration/query/simple/with_group_average_sum_test.go index 4a1851df67..4e00607986 100644 --- a/tests/integration/query/simple/with_group_average_sum_test.go +++ b/tests/integration/query/simple/with_group_average_sum_test.go @@ -58,38 +58,40 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndSumOfCountOfInt(t * }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_sum": float64(62.5), - "_group": []map[string]any{ - { - "Verified": true, - "_avg": float64(28.5), - }, - { - "Verified": false, - "_avg": float64(34), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_sum": float64(62.5), + "_group": []map[string]any{ + { + "Verified": true, + "_avg": float64(28.5), + }, + { + "Verified": false, + "_avg": float64(34), + }, }, }, - }, - { - "Name": "Carlo", - "_sum": float64(55), - "_group": []map[string]any{ - { - "Verified": true, - "_avg": float64(55), + { + "Name": "Carlo", + "_sum": float64(55), + "_group": []map[string]any{ + { + "Verified": true, + "_avg": float64(55), + }, }, }, - }, - { - "Name": "Alice", - "_sum": float64(19), - "_group": []map[string]any{ - { - "Verified": false, - "_avg": float64(19), + { + "Name": "Alice", + "_sum": float64(19), + "_group": []map[string]any{ + { + "Verified": false, + "_avg": float64(19), + }, }, }, }, @@ -130,16 +132,18 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerAverageA }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_avg": float64(35), - "_sum": int64(70), - }, - { - "Name": "Alice", - "_avg": float64(-19), - "_sum": int64(-19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(35), + "_sum": int64(70), + }, + { + "Name": "Alice", + "_avg": float64(-19), + "_sum": int64(-19), + }, }, }, } diff --git a/tests/integration/query/simple/with_group_average_test.go b/tests/integration/query/simple/with_group_average_test.go index 91aacd3c8a..9afbef7a3e 100644 --- a/tests/integration/query/simple/with_group_average_test.go +++ b/tests/integration/query/simple/with_group_average_test.go @@ -48,7 +48,9 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerAverageO _avg(_group: {field: Age}) } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, } executeTestCase(t, test) @@ -80,14 +82,16 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerAverage( }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_avg": float64(35), - }, - { - "Name": "Alice", - "_avg": float64(-19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(35), + }, + { + "Name": "Alice", + "_avg": float64(-19), + }, }, }, } @@ -120,14 +124,16 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildNilAverage(t *t }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_avg": float64(32), - }, - { - "Name": "Alice", - "_avg": float64(19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(32), + }, + { + "Name": "Alice", + "_avg": float64(19), + }, }, }, } @@ -177,38 +183,40 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndAverageOfAverageOfI }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_avg": float64(31.25), - "_group": []map[string]any{ - { - "Verified": true, - "_avg": float64(28.5), - }, - { - "Verified": false, - "_avg": float64(34), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(31.25), + "_group": []map[string]any{ + { + "Verified": true, + "_avg": float64(28.5), + }, + { + "Verified": false, + "_avg": float64(34), + }, }, }, - }, - { - "Name": "Carlo", - "_avg": float64(55), - "_group": []map[string]any{ - { - "Verified": true, - "_avg": float64(55), + { + "Name": "Carlo", + "_avg": float64(55), + "_group": []map[string]any{ + { + "Verified": true, + "_avg": float64(55), + }, }, }, - }, - { - "Name": "Alice", - "_avg": float64(19), - "_group": []map[string]any{ - { - "Verified": false, - "_avg": float64(19), + { + "Name": "Alice", + "_avg": float64(19), + "_group": []map[string]any{ + { + "Verified": false, + "_avg": float64(19), + }, }, }, }, @@ -242,14 +250,16 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildEmptyFloatAvera }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_avg": float64(1.855), - }, - { - "Name": "Alice", - "_avg": float64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(1.855), + }, + { + "Name": "Alice", + "_avg": float64(0), + }, }, }, } @@ -282,14 +292,16 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildFloatAverage(t }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_avg": float64(1.855), - }, - { - "Name": "Alice", - "_avg": float64(2.04), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(1.855), + }, + { + "Name": "Alice", + "_avg": float64(2.04), + }, }, }, } @@ -339,38 +351,40 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndAverageOfAverageOfF }`, }, }, - Results: []map[string]any{ - { - "Name": "Alice", - "_avg": float64(2.04), - "_group": []map[string]any{ - { - "Verified": false, - "_avg": float64(2.04), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Alice", + "_avg": float64(2.04), + "_group": []map[string]any{ + { + "Verified": false, + "_avg": float64(2.04), + }, }, }, - }, - { - "Name": "John", - "_avg": float64(1.9675000000000002), - "_group": []map[string]any{ - { - "Verified": true, - "_avg": float64(1.715), - }, - { - "Verified": false, - "_avg": float64(2.22), + { + "Name": "John", + "_avg": float64(1.9675000000000002), + "_group": []map[string]any{ + { + "Verified": true, + "_avg": float64(1.715), + }, + { + "Verified": false, + "_avg": float64(2.22), + }, }, }, - }, - { - "Name": "Carlo", - "_avg": float64(1.74), - "_group": []map[string]any{ - { - "Verified": true, - "_avg": float64(1.74), + { + "Name": "Carlo", + "_avg": float64(1.74), + "_group": []map[string]any{ + { + "Verified": true, + "_avg": float64(1.74), + }, }, }, }, @@ -431,64 +445,66 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndAverageOfAverageOfA }`, }, }, - Results: []map[string]any{ - { - "Name": "Carlo", - "_avg": float64(1.74), - "_group": []map[string]any{ - { - "Verified": true, - "_avg": float64(1.74), - "_group": []map[string]any{ - { - "Age": int64(55), - "_avg": float64(1.74), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "_avg": float64(1.74), + "_group": []map[string]any{ + { + "Verified": true, + "_avg": float64(1.74), + "_group": []map[string]any{ + { + "Age": int64(55), + "_avg": float64(1.74), + }, }, }, }, }, - }, - { - "Name": "Alice", - "_avg": float64(2.04), - "_group": []map[string]any{ - { - "Verified": false, - "_avg": float64(2.04), - "_group": []map[string]any{ - { - "Age": int64(19), - "_avg": float64(2.04), + { + "Name": "Alice", + "_avg": float64(2.04), + "_group": []map[string]any{ + { + "Verified": false, + "_avg": float64(2.04), + "_group": []map[string]any{ + { + "Age": int64(19), + "_avg": float64(2.04), + }, }, }, }, }, - }, - { - "Name": "John", - "_avg": float64(1.9675000000000002), - "_group": []map[string]any{ - { - "Verified": true, - "_avg": float64(1.715), - "_group": []map[string]any{ - { - "Age": int64(32), - "_avg": float64(1.61), - }, - { - "Age": int64(25), - "_avg": float64(1.82), + { + "Name": "John", + "_avg": float64(1.9675000000000002), + "_group": []map[string]any{ + { + "Verified": true, + "_avg": float64(1.715), + "_group": []map[string]any{ + { + "Age": int64(32), + "_avg": float64(1.61), + }, + { + "Age": int64(25), + "_avg": float64(1.82), + }, }, }, - }, - { - "Verified": false, - "_avg": float64(2.22), - "_group": []map[string]any{ - { - "Age": int64(34), - "_avg": float64(2.22), + { + "Verified": false, + "_avg": float64(2.22), + "_group": []map[string]any{ + { + "Age": int64(34), + "_avg": float64(2.22), + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_count_filter_test.go b/tests/integration/query/simple/with_group_count_filter_test.go index 18a60bedf9..9d2950b4e5 100644 --- a/tests/integration/query/simple/with_group_count_filter_test.go +++ b/tests/integration/query/simple/with_group_count_filter_test.go @@ -41,14 +41,16 @@ func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildCountWithFilter }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "_count": 2, - }, - { - "Age": int64(19), - "_count": 0, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_count": 2, + }, + { + "Age": int64(19), + "_count": 0, + }, }, }, } @@ -84,25 +86,27 @@ func TestQuerySimpleWithGroupByNumberWithRenderedGroupAndChildCountWithFilter(t }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "_count": 2, - "_group": []map[string]any{ - { - "Name": "Bob", - }, - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_count": 2, + "_group": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, }, }, - }, - { - "Age": int64(19), - "_count": 0, - "_group": []map[string]any{ - { - "Name": "Alice", + { + "Age": int64(19), + "_count": 0, + "_group": []map[string]any{ + { + "Name": "Alice", + }, }, }, }, @@ -140,20 +144,22 @@ func TestQuerySimpleWithGroupByNumberWithRenderedGroupWithFilterAndChildCountWit }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "_count": 1, - "_group": []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_count": 1, + "_group": []map[string]any{ + { + "Name": "John", + }, }, }, - }, - { - "Age": int64(19), - "_count": 0, - "_group": []map[string]any{}, + { + "Age": int64(19), + "_count": 0, + "_group": []map[string]any{}, + }, }, }, } @@ -189,20 +195,22 @@ func TestQuerySimpleWithGroupByNumberWithRenderedGroupWithFilterAndChildCountWit }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "_count": 2, - "_group": []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_count": 2, + "_group": []map[string]any{ + { + "Name": "John", + }, }, }, - }, - { - "Age": int64(19), - "_count": 0, - "_group": []map[string]any{}, + { + "Age": int64(19), + "_count": 0, + "_group": []map[string]any{}, + }, }, }, } @@ -236,16 +244,18 @@ func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildCountsWithDiffe }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "C1": 2, - "C2": 0, - }, - { - "Age": int64(19), - "C1": 0, - "C2": 1, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "C1": 2, + "C2": 0, + }, + { + "Age": int64(19), + "C1": 0, + "C2": 1, + }, }, }, } diff --git a/tests/integration/query/simple/with_group_count_limit_offset_test.go b/tests/integration/query/simple/with_group_count_limit_offset_test.go index 015f76c30c..4fe00f25b9 100644 --- a/tests/integration/query/simple/with_group_count_limit_offset_test.go +++ b/tests/integration/query/simple/with_group_count_limit_offset_test.go @@ -41,14 +41,16 @@ func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildCountWithLimitA }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "_count": 1, - }, - { - "Age": int64(19), - "_count": 0, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_count": 1, + }, + { + "Age": int64(19), + "_count": 0, + }, }, }, } @@ -88,25 +90,27 @@ func TestQuerySimpleWithGroupByNumberWithRenderedGroupWithLimitAndChildCountWith }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "_count": 1, - "_group": []map[string]any{ - { - "Name": "Bob", - }, - { - "Name": "Shahzad", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_count": 1, + "_group": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "Shahzad", + }, }, }, - }, - { - "Age": int64(19), - "_count": 0, - "_group": []map[string]any{ - { - "Name": "Alice", + { + "Age": int64(19), + "_count": 0, + "_group": []map[string]any{ + { + "Name": "Alice", + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_count_limit_test.go b/tests/integration/query/simple/with_group_count_limit_test.go index 1870e07bc2..7deae49208 100644 --- a/tests/integration/query/simple/with_group_count_limit_test.go +++ b/tests/integration/query/simple/with_group_count_limit_test.go @@ -41,14 +41,16 @@ func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildCountWithLimit( }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "_count": 1, - }, - { - "Age": int64(19), - "_count": 1, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_count": 1, + }, + { + "Age": int64(19), + "_count": 1, + }, }, }, } @@ -88,25 +90,27 @@ func TestQuerySimpleWithGroupByNumberWithRenderedGroupWithLimitAndChildCountWith }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "_count": 1, - "_group": []map[string]any{ - { - "Name": "Bob", - }, - { - "Name": "Shahzad", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_count": 1, + "_group": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "Shahzad", + }, }, }, - }, - { - "Age": int64(19), - "_count": 1, - "_group": []map[string]any{ - { - "Name": "Alice", + { + "Age": int64(19), + "_count": 1, + "_group": []map[string]any{ + { + "Name": "Alice", + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_count_sum_test.go b/tests/integration/query/simple/with_group_count_sum_test.go index aab55c4002..7e26628591 100644 --- a/tests/integration/query/simple/with_group_count_sum_test.go +++ b/tests/integration/query/simple/with_group_count_sum_test.go @@ -58,38 +58,40 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndSumOfCount(t *testi }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_sum": int64(3), - "_group": []map[string]any{ - { - "Verified": true, - "_count": int(2), - }, - { - "Verified": false, - "_count": int(1), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_sum": int64(3), + "_group": []map[string]any{ + { + "Verified": true, + "_count": int(2), + }, + { + "Verified": false, + "_count": int(1), + }, }, }, - }, - { - "Name": "Carlo", - "_sum": int64(1), - "_group": []map[string]any{ - { - "Verified": true, - "_count": int(1), + { + "Name": "Carlo", + "_sum": int64(1), + "_group": []map[string]any{ + { + "Verified": true, + "_count": int(1), + }, }, }, - }, - { - "Name": "Alice", - "_sum": int64(1), - "_group": []map[string]any{ - { - "Verified": false, - "_count": int(1), + { + "Name": "Alice", + "_sum": int64(1), + "_group": []map[string]any{ + { + "Verified": false, + "_count": int(1), + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_count_test.go b/tests/integration/query/simple/with_group_count_test.go index 6f3fda8320..4f979f3dcb 100644 --- a/tests/integration/query/simple/with_group_count_test.go +++ b/tests/integration/query/simple/with_group_count_test.go @@ -90,14 +90,16 @@ func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildCount(t *testin }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "_count": 2, - }, - { - "Age": int64(19), - "_count": 1, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_count": 2, + }, + { + "Age": int64(19), + "_count": 1, + }, }, }, } @@ -114,7 +116,9 @@ func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildCountOnEmptyCol _count(_group: {}) } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, } executeTestCase(t, test) @@ -148,25 +152,27 @@ func TestQuerySimpleWithGroupByNumberWithRenderedGroupAndChildCount(t *testing.T }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "_count": 2, - "_group": []map[string]any{ - { - "Name": "Bob", - }, - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_count": 2, + "_group": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, }, }, - }, - { - "Age": int64(19), - "_count": 1, - "_group": []map[string]any{ - { - "Name": "Alice", + { + "Age": int64(19), + "_count": 1, + "_group": []map[string]any{ + { + "Name": "Alice", + }, }, }, }, @@ -232,14 +238,16 @@ func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndAliasesChildCount(t }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "Count": 2, - }, - { - "Age": int64(19), - "Count": 1, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "Count": 2, + }, + { + "Age": int64(19), + "Count": 1, + }, }, }, } @@ -275,16 +283,18 @@ func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndDuplicatedAliasedChi }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "Count1": 2, - "Count2": 2, - }, - { - "Age": int64(19), - "Count1": 1, - "Count2": 1, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "Count1": 2, + "Count2": 2, + }, + { + "Age": int64(19), + "Count1": 1, + "Count2": 1, + }, }, }, } diff --git a/tests/integration/query/simple/with_group_doc_id_test.go b/tests/integration/query/simple/with_group_doc_id_test.go index f476b3c617..9529f7e3bd 100644 --- a/tests/integration/query/simple/with_group_doc_id_test.go +++ b/tests/integration/query/simple/with_group_doc_id_test.go @@ -44,18 +44,20 @@ func TestQuerySimpleWithGroupByWithGroupWithDocID(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Age": int64(21), - "_group": []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(21), + "_group": []map[string]any{ + { + "Name": "John", + }, }, }, - }, - { - "Age": int64(32), - "_group": []map[string]any{}, + { + "Age": int64(32), + "_group": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/query/simple/with_group_doc_ids_test.go b/tests/integration/query/simple/with_group_doc_ids_test.go index 72aa527b66..cafbb21481 100644 --- a/tests/integration/query/simple/with_group_doc_ids_test.go +++ b/tests/integration/query/simple/with_group_doc_ids_test.go @@ -49,21 +49,23 @@ func TestQuerySimpleWithGroupByWithGroupWithDocIDs(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Age": int64(21), - "_group": []map[string]any{ - { - "Name": "Fred", - }, - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(21), + "_group": []map[string]any{ + { + "Name": "Fred", + }, + { + "Name": "John", + }, }, }, - }, - { - "Age": int64(32), - "_group": []map[string]any{}, + { + "Age": int64(32), + "_group": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/query/simple/with_group_filter_test.go b/tests/integration/query/simple/with_group_filter_test.go index 919d4c311b..3e3b5f32fe 100644 --- a/tests/integration/query/simple/with_group_filter_test.go +++ b/tests/integration/query/simple/with_group_filter_test.go @@ -47,26 +47,28 @@ func TestQuerySimpleWithGroupByStringWithGroupNumberFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Carlo", - "_group": []map[string]any{ - { - "Age": int64(55), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "_group": []map[string]any{ + { + "Age": int64(55), + }, }, }, - }, - { - "Name": "John", - "_group": []map[string]any{ - { - "Age": int64(32), + { + "Name": "John", + "_group": []map[string]any{ + { + "Age": int64(32), + }, }, }, - }, - { - "Name": "Alice", - "_group": []map[string]any{}, + { + "Name": "Alice", + "_group": []map[string]any{}, + }, }, }, } @@ -105,20 +107,22 @@ func TestQuerySimpleWithGroupByStringWithGroupNumberWithParentFilter(t *testing. }`, }, }, - Results: []map[string]any{ - { - "Name": "Carlo", - "_group": []map[string]any{ - { - "Age": int64(55), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "_group": []map[string]any{ + { + "Age": int64(55), + }, }, }, - }, - { - "Name": "John", - "_group": []map[string]any{ - { - "Age": int64(32), + { + "Name": "John", + "_group": []map[string]any{ + { + "Age": int64(32), + }, }, }, }, @@ -156,12 +160,14 @@ func TestQuerySimpleWithGroupByStringWithUnrenderedGroupNumberWithParentFilter(t }`, }, }, - Results: []map[string]any{ - { - "Name": "Carlo", - }, - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + }, + { + "Name": "John", + }, }, }, } @@ -214,35 +220,37 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanThenInnerNumberFilterT }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_group": []map[string]any{ - { - "Verified": true, - "_group": []map[string]any{}, - }, - { - "Verified": false, - "_group": []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_group": []map[string]any{ + { + "Verified": true, + "_group": []map[string]any{}, + }, + { + "Verified": false, + "_group": []map[string]any{}, + }, }, }, - }, - { - "Name": "Carlo", - "_group": []map[string]any{ - { - "Verified": true, - "_group": []map[string]any{}, + { + "Name": "Carlo", + "_group": []map[string]any{ + { + "Verified": true, + "_group": []map[string]any{}, + }, }, }, - }, - { - "Name": "Alice", - "_group": []map[string]any{ - { - "Verified": false, - "_group": []map[string]any{}, + { + "Name": "Alice", + "_group": []map[string]any{ + { + "Verified": false, + "_group": []map[string]any{}, + }, }, }, }, @@ -286,35 +294,37 @@ func TestQuerySimpleWithGroupByStringWithMultipleGroupNumberFilter(t *testing.T) }`, }, }, - Results: []map[string]any{ - { - "Name": "Carlo", - "G1": []map[string]any{ - { - "Age": int64(55), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "G1": []map[string]any{ + { + "Age": int64(55), + }, }, + "G2": []map[string]any{}, }, - "G2": []map[string]any{}, - }, - { - "Name": "John", - "G1": []map[string]any{ - { - "Age": int64(32), + { + "Name": "John", + "G1": []map[string]any{ + { + "Age": int64(32), + }, }, - }, - "G2": []map[string]any{ - { - "Age": int64(25), + "G2": []map[string]any{ + { + "Age": int64(25), + }, }, }, - }, - { - "Name": "Alice", - "G1": []map[string]any{}, - "G2": []map[string]any{ - { - "Age": int64(19), + { + "Name": "Alice", + "G1": []map[string]any{}, + "G2": []map[string]any{ + { + "Age": int64(19), + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_limit_offset_test.go b/tests/integration/query/simple/with_group_limit_offset_test.go index 0fea317d5a..ea4c2afc81 100644 --- a/tests/integration/query/simple/with_group_limit_offset_test.go +++ b/tests/integration/query/simple/with_group_limit_offset_test.go @@ -43,18 +43,20 @@ func TestQuerySimpleWithGroupByNumberWithGroupLimitAndOffset(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "_group": []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_group": []map[string]any{ + { + "Name": "John", + }, }, }, - }, - { - "Age": int64(19), - "_group": []map[string]any{}, + { + "Age": int64(19), + "_group": []map[string]any{}, + }, }, }, } @@ -89,10 +91,12 @@ func TestQuerySimpleWithGroupByNumberWithLimitAndOffsetAndWithGroupLimitAndOffse }`, }, }, - Results: []map[string]any{ - { - "Age": int64(19), - "_group": []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(19), + "_group": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/query/simple/with_group_limit_test.go b/tests/integration/query/simple/with_group_limit_test.go index b5b53c3b81..2b7ac5d205 100644 --- a/tests/integration/query/simple/with_group_limit_test.go +++ b/tests/integration/query/simple/with_group_limit_test.go @@ -43,20 +43,22 @@ func TestQuerySimpleWithGroupByNumberWithGroupLimit(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "_group": []map[string]any{ - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_group": []map[string]any{ + { + "Name": "Bob", + }, }, }, - }, - { - "Age": int64(19), - "_group": []map[string]any{ - { - "Name": "Alice", + { + "Age": int64(19), + "_group": []map[string]any{ + { + "Name": "Alice", + }, }, }, }, @@ -96,33 +98,35 @@ func TestQuerySimpleWithGroupByNumberWithMultipleGroupsWithDifferentLimits(t *te }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "G1": []map[string]any{ - { - "Name": "Bob", - }, - }, - "G2": []map[string]any{ - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "G1": []map[string]any{ + { + "Name": "Bob", + }, }, - { - "Name": "John", + "G2": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, }, }, - }, - { - "Age": int64(19), - "G1": []map[string]any{ - { - "Name": "Alice", + { + "Age": int64(19), + "G1": []map[string]any{ + { + "Name": "Alice", + }, }, - }, - "G2": []map[string]any{ - { - "Name": "Alice", + "G2": []map[string]any{ + { + "Name": "Alice", + }, }, }, }, @@ -159,15 +163,17 @@ func TestQuerySimpleWithGroupByNumberWithLimitAndGroupWithHigherLimit(t *testing }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "_group": []map[string]any{ - { - "Name": "Bob", - }, - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_group": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, }, }, }, @@ -208,20 +214,22 @@ func TestQuerySimpleWithGroupByNumberWithLimitAndGroupWithLowerLimit(t *testing. }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "_group": []map[string]any{ - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_group": []map[string]any{ + { + "Name": "Bob", + }, }, }, - }, - { - "Age": int64(42), - "_group": []map[string]any{ - { - "Name": "Alice", + { + "Age": int64(42), + "_group": []map[string]any{ + { + "Name": "Alice", + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_order_test.go b/tests/integration/query/simple/with_group_order_test.go index 29d7014b03..b1ace46918 100644 --- a/tests/integration/query/simple/with_group_order_test.go +++ b/tests/integration/query/simple/with_group_order_test.go @@ -47,31 +47,33 @@ func TestQuerySimpleWithGroupByStringWithGroupNumberWithGroupOrder(t *testing.T) }`, }, }, - Results: []map[string]any{ - { - "Name": "Carlo", - "_group": []map[string]any{ - { - "Age": int64(55), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "_group": []map[string]any{ + { + "Age": int64(55), + }, }, }, - }, - { - "Name": "Alice", - "_group": []map[string]any{ - { - "Age": int64(19), + { + "Name": "Alice", + "_group": []map[string]any{ + { + "Age": int64(19), + }, }, }, - }, - { - "Name": "John", - "_group": []map[string]any{ - { - "Age": int64(25), - }, - { - "Age": int64(32), + { + "Name": "John", + "_group": []map[string]any{ + { + "Age": int64(25), + }, + { + "Age": int64(32), + }, }, }, }, @@ -112,31 +114,33 @@ func TestQuerySimpleWithGroupByStringWithGroupNumberWithGroupOrderDescending(t * }`, }, }, - Results: []map[string]any{ - { - "Name": "Carlo", - "_group": []map[string]any{ - { - "Age": int64(55), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "_group": []map[string]any{ + { + "Age": int64(55), + }, }, }, - }, - { - "Name": "John", - "_group": []map[string]any{ - { - "Age": int64(32), - }, - { - "Age": int64(25), + { + "Name": "John", + "_group": []map[string]any{ + { + "Age": int64(32), + }, + { + "Age": int64(25), + }, }, }, - }, - { - "Name": "Alice", - "_group": []map[string]any{ - { - "Age": int64(19), + { + "Name": "Alice", + "_group": []map[string]any{ + { + "Age": int64(19), + }, }, }, }, @@ -177,31 +181,33 @@ func TestQuerySimpleWithGroupByStringAndOrderDescendingWithGroupNumberWithGroupO }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_group": []map[string]any{ - { - "Age": int64(25), - }, - { - "Age": int64(32), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_group": []map[string]any{ + { + "Age": int64(25), + }, + { + "Age": int64(32), + }, }, }, - }, - { - "Name": "Carlo", - "_group": []map[string]any{ - { - "Age": int64(55), + { + "Name": "Carlo", + "_group": []map[string]any{ + { + "Age": int64(55), + }, }, }, - }, - { - "Name": "Alice", - "_group": []map[string]any{ - { - "Age": int64(19), + { + "Name": "Alice", + "_group": []map[string]any{ + { + "Age": int64(19), + }, }, }, }, @@ -254,52 +260,54 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanThenInnerOrderDescendi }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_group": []map[string]any{ - { - "Verified": true, - "_group": []map[string]any{ - { - "Age": int64(32), - }, - { - "Age": int64(25), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_group": []map[string]any{ + { + "Verified": true, + "_group": []map[string]any{ + { + "Age": int64(32), + }, + { + "Age": int64(25), + }, }, }, - }, - { - "Verified": false, - "_group": []map[string]any{ - { - "Age": int64(34), + { + "Verified": false, + "_group": []map[string]any{ + { + "Age": int64(34), + }, }, }, }, }, - }, - { - "Name": "Carlo", - "_group": []map[string]any{ - { - "Verified": true, - "_group": []map[string]any{ - { - "Age": int64(55), + { + "Name": "Carlo", + "_group": []map[string]any{ + { + "Verified": true, + "_group": []map[string]any{ + { + "Age": int64(55), + }, }, }, }, }, - }, - { - "Name": "Alice", - "_group": []map[string]any{ - { - "Verified": false, - "_group": []map[string]any{ - { - "Age": int64(19), + { + "Name": "Alice", + "_group": []map[string]any{ + { + "Verified": false, + "_group": []map[string]any{ + { + "Age": int64(19), + }, }, }, }, @@ -356,52 +364,54 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndOrderAscendingThenI }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_group": []map[string]any{ - { - "Verified": false, - "_group": []map[string]any{ - { - "Age": int64(34), - }, - { - "Age": int64(25), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_group": []map[string]any{ + { + "Verified": false, + "_group": []map[string]any{ + { + "Age": int64(34), + }, + { + "Age": int64(25), + }, }, }, - }, - { - "Verified": true, - "_group": []map[string]any{ - { - "Age": int64(32), + { + "Verified": true, + "_group": []map[string]any{ + { + "Age": int64(32), + }, }, }, }, }, - }, - { - "Name": "Alice", - "_group": []map[string]any{ - { - "Verified": false, - "_group": []map[string]any{ - { - "Age": int64(19), + { + "Name": "Alice", + "_group": []map[string]any{ + { + "Verified": false, + "_group": []map[string]any{ + { + "Age": int64(19), + }, }, }, }, }, - }, - { - "Name": "Carlo", - "_group": []map[string]any{ - { - "Verified": true, - "_group": []map[string]any{ - { - "Age": int64(55), + { + "Name": "Carlo", + "_group": []map[string]any{ + { + "Verified": true, + "_group": []map[string]any{ + { + "Age": int64(55), + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_sum_filter_test.go b/tests/integration/query/simple/with_group_sum_filter_test.go index 15d6a89acb..cf9f8e3a0b 100644 --- a/tests/integration/query/simple/with_group_sum_filter_test.go +++ b/tests/integration/query/simple/with_group_sum_filter_test.go @@ -41,14 +41,16 @@ func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildSumWithFilter(t }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "_sum": int64(64), - }, - { - "Age": int64(19), - "_sum": int64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_sum": int64(64), + }, + { + "Age": int64(19), + "_sum": int64(0), + }, }, }, } @@ -84,25 +86,27 @@ func TestQuerySimpleWithGroupByNumberWithRenderedGroupAndChildSumWithFilter(t *t }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "_sum": int64(64), - "_group": []map[string]any{ - { - "Name": "Bob", - }, - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_sum": int64(64), + "_group": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, }, }, - }, - { - "Age": int64(19), - "_sum": int64(0), - "_group": []map[string]any{ - { - "Name": "Alice", + { + "Age": int64(19), + "_sum": int64(0), + "_group": []map[string]any{ + { + "Name": "Alice", + }, }, }, }, @@ -140,20 +144,22 @@ func TestQuerySimpleWithGroupByNumberWithRenderedGroupWithFilterAndChildSumWithM }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "_sum": int64(32), - "_group": []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_sum": int64(32), + "_group": []map[string]any{ + { + "Name": "John", + }, }, }, - }, - { - "Age": int64(19), - "_sum": int64(0), - "_group": []map[string]any{}, + { + "Age": int64(19), + "_sum": int64(0), + "_group": []map[string]any{}, + }, }, }, } @@ -189,20 +195,22 @@ func TestQuerySimpleWithGroupByNumberWithRenderedGroupWithFilterAndChildSumWithD }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "_sum": int64(64), - "_group": []map[string]any{ - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_sum": int64(64), + "_group": []map[string]any{ + { + "Name": "John", + }, }, }, - }, - { - "Age": int64(19), - "_sum": int64(0), - "_group": []map[string]any{}, + { + "Age": int64(19), + "_sum": int64(0), + "_group": []map[string]any{}, + }, }, }, } @@ -236,16 +244,18 @@ func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildSumsWithDiffere }`, }, }, - Results: []map[string]any{ - { - "Age": int64(32), - "S1": int64(64), - "S2": int64(0), - }, - { - "Age": int64(19), - "S1": int64(0), - "S2": int64(19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "S1": int64(64), + "S2": int64(0), + }, + { + "Age": int64(19), + "S1": int64(0), + "S2": int64(19), + }, }, }, } diff --git a/tests/integration/query/simple/with_group_sum_limit_offset_test.go b/tests/integration/query/simple/with_group_sum_limit_offset_test.go index 8f09e1a0e6..7ba181b3c5 100644 --- a/tests/integration/query/simple/with_group_sum_limit_offset_test.go +++ b/tests/integration/query/simple/with_group_sum_limit_offset_test.go @@ -46,14 +46,16 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerSumWithL }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_sum": int64(70), - }, - { - "Name": "Alice", - "_sum": int64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_sum": int64(70), + }, + { + "Name": "Alice", + "_sum": int64(0), + }, }, }, } diff --git a/tests/integration/query/simple/with_group_sum_limit_test.go b/tests/integration/query/simple/with_group_sum_limit_test.go index 3d40ccd66c..eda7ea131b 100644 --- a/tests/integration/query/simple/with_group_sum_limit_test.go +++ b/tests/integration/query/simple/with_group_sum_limit_test.go @@ -46,14 +46,16 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerSumWithL }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_sum": int64(66), - }, - { - "Name": "Alice", - "_sum": int64(-19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_sum": int64(66), + }, + { + "Name": "Alice", + "_sum": int64(-19), + }, }, }, } diff --git a/tests/integration/query/simple/with_group_sum_test.go b/tests/integration/query/simple/with_group_sum_test.go index 8fd0ce6fb1..03bfb3e2de 100644 --- a/tests/integration/query/simple/with_group_sum_test.go +++ b/tests/integration/query/simple/with_group_sum_test.go @@ -48,7 +48,9 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerSumOnEmp _sum(_group: {field: Age}) } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, } executeTestCase(t, test) @@ -80,14 +82,16 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerSum(t *t }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_sum": int64(70), - }, - { - "Name": "Alice", - "_sum": int64(-19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_sum": int64(70), + }, + { + "Name": "Alice", + "_sum": int64(-19), + }, }, }, } @@ -120,14 +124,16 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildNilSum(t *testi }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_sum": int64(32), - }, - { - "Name": "Alice", - "_sum": int64(19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_sum": int64(32), + }, + { + "Name": "Alice", + "_sum": int64(19), + }, }, }, } @@ -177,38 +183,40 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndSumOfSumOfInt(t *te }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_sum": int64(91), - "_group": []map[string]any{ - { - "Verified": true, - "_sum": int64(57), - }, - { - "Verified": false, - "_sum": int64(34), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_sum": int64(91), + "_group": []map[string]any{ + { + "Verified": true, + "_sum": int64(57), + }, + { + "Verified": false, + "_sum": int64(34), + }, }, }, - }, - { - "Name": "Carlo", - "_sum": int64(55), - "_group": []map[string]any{ - { - "Verified": true, - "_sum": int64(55), + { + "Name": "Carlo", + "_sum": int64(55), + "_group": []map[string]any{ + { + "Verified": true, + "_sum": int64(55), + }, }, }, - }, - { - "Name": "Alice", - "_sum": int64(19), - "_group": []map[string]any{ - { - "Verified": false, - "_sum": int64(19), + { + "Name": "Alice", + "_sum": int64(19), + "_group": []map[string]any{ + { + "Verified": false, + "_sum": int64(19), + }, }, }, }, @@ -242,14 +250,16 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildEmptyFloatSum(t }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_sum": float64(3.71), - }, - { - "Name": "Alice", - "_sum": float64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_sum": float64(3.71), + }, + { + "Name": "Alice", + "_sum": float64(0), + }, }, }, } @@ -282,14 +292,16 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildFloatSum(t *tes }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_sum": float64(3.71), - }, - { - "Name": "Alice", - "_sum": float64(2.04), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_sum": float64(3.71), + }, + { + "Name": "Alice", + "_sum": float64(2.04), + }, }, }, } @@ -339,38 +351,40 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndSumOfSumOfFloat(t * }`, }, }, - Results: []map[string]any{ - { - "Name": "Alice", - "_sum": float64(2.04), - "_group": []map[string]any{ - { - "Verified": false, - "_sum": float64(2.04), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Alice", + "_sum": float64(2.04), + "_group": []map[string]any{ + { + "Verified": false, + "_sum": float64(2.04), + }, }, }, - }, - { - "Name": "John", - "_sum": float64(5.65), - "_group": []map[string]any{ - { - "Verified": true, - "_sum": float64(3.43), - }, - { - "Verified": false, - "_sum": float64(2.22), + { + "Name": "John", + "_sum": float64(5.65), + "_group": []map[string]any{ + { + "Verified": true, + "_sum": float64(3.43), + }, + { + "Verified": false, + "_sum": float64(2.22), + }, }, }, - }, - { - "Name": "Carlo", - "_sum": float64(1.74), - "_group": []map[string]any{ - { - "Verified": true, - "_sum": float64(1.74), + { + "Name": "Carlo", + "_sum": float64(1.74), + "_group": []map[string]any{ + { + "Verified": true, + "_sum": float64(1.74), + }, }, }, }, @@ -431,64 +445,66 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndSumOfSumOfSumOfFloa }`, }, }, - Results: []map[string]any{ - { - "Name": "Carlo", - "_sum": float64(1.74), - "_group": []map[string]any{ - { - "Verified": true, - "_sum": float64(1.74), - "_group": []map[string]any{ - { - "Age": int64(55), - "_sum": float64(1.74), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "_sum": float64(1.74), + "_group": []map[string]any{ + { + "Verified": true, + "_sum": float64(1.74), + "_group": []map[string]any{ + { + "Age": int64(55), + "_sum": float64(1.74), + }, }, }, }, }, - }, - { - "Name": "Alice", - "_sum": float64(2.04), - "_group": []map[string]any{ - { - "Verified": false, - "_sum": float64(2.04), - "_group": []map[string]any{ - { - "Age": int64(19), - "_sum": float64(2.04), + { + "Name": "Alice", + "_sum": float64(2.04), + "_group": []map[string]any{ + { + "Verified": false, + "_sum": float64(2.04), + "_group": []map[string]any{ + { + "Age": int64(19), + "_sum": float64(2.04), + }, }, }, }, }, - }, - { - "Name": "John", - "_sum": float64(5.65), - "_group": []map[string]any{ - { - "Verified": true, - "_sum": float64(3.43), - "_group": []map[string]any{ - { - "Age": int64(32), - "_sum": float64(1.61), - }, - { - "Age": int64(25), - "_sum": float64(1.82), + { + "Name": "John", + "_sum": float64(5.65), + "_group": []map[string]any{ + { + "Verified": true, + "_sum": float64(3.43), + "_group": []map[string]any{ + { + "Age": int64(32), + "_sum": float64(1.61), + }, + { + "Age": int64(25), + "_sum": float64(1.82), + }, }, }, - }, - { - "Verified": false, - "_sum": float64(2.22), - "_group": []map[string]any{ - { - "Age": int64(34), - "_sum": float64(2.22), + { + "Verified": false, + "_sum": float64(2.22), + "_group": []map[string]any{ + { + "Age": int64(34), + "_sum": float64(2.22), + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_test.go b/tests/integration/query/simple/with_group_test.go index a12ecd0668..7b71ebf90f 100644 --- a/tests/integration/query/simple/with_group_test.go +++ b/tests/integration/query/simple/with_group_test.go @@ -38,14 +38,16 @@ func TestQuerySimpleWithGroupByEmpty(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "_group": []map[string]any{ - { - "Name": "Bob", - }, - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "_group": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, }, }, }, @@ -83,15 +85,17 @@ func TestQuerySimpleWithGroupByNumber(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Age": int64(55), - }, - { - "Age": int64(32), - }, - { - "Age": int64(19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(55), + }, + { + "Age": int64(32), + }, + { + "Age": int64(19), + }, }, }, } @@ -127,15 +131,17 @@ func TestQuerySimpleWithGroupByDateTime(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "CreatedAt": testUtils.MustParseTime("2011-07-23T03:46:56-05:00"), - }, - { - "CreatedAt": testUtils.MustParseTime("2013-07-23T03:46:56-05:00"), - }, - { - "CreatedAt": testUtils.MustParseTime("2012-07-23T03:46:56-05:00"), + Results: map[string]any{ + "Users": []map[string]any{ + { + "CreatedAt": testUtils.MustParseTime("2011-07-23T03:46:56-05:00"), + }, + { + "CreatedAt": testUtils.MustParseTime("2013-07-23T03:46:56-05:00"), + }, + { + "CreatedAt": testUtils.MustParseTime("2012-07-23T03:46:56-05:00"), + }, }, }, } @@ -174,31 +180,33 @@ func TestQuerySimpleWithGroupByNumberWithGroupString(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Age": int64(55), - "_group": []map[string]any{ - { - "Name": "Carlo", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(55), + "_group": []map[string]any{ + { + "Name": "Carlo", + }, }, }, - }, - { - "Age": int64(32), - "_group": []map[string]any{ - { - "Name": "Bob", - }, - { - "Name": "John", + { + "Age": int64(32), + "_group": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, }, }, - }, - { - "Age": int64(19), - "_group": []map[string]any{ - { - "Name": "Alice", + { + "Age": int64(19), + "_group": []map[string]any{ + { + "Name": "Alice", + }, }, }, }, @@ -239,31 +247,33 @@ func TestQuerySimpleWithGroupByWithoutGroupedFieldSelectedWithInnerGroup(t *test }`, }, }, - Results: []map[string]any{ - { - "Name": "Carlo", - "_group": []map[string]any{ - { - "Age": int64(55), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "_group": []map[string]any{ + { + "Age": int64(55), + }, }, }, - }, - { - "Name": "John", - "_group": []map[string]any{ - { - "Age": int64(25), - }, - { - "Age": int64(32), + { + "Name": "John", + "_group": []map[string]any{ + { + "Age": int64(25), + }, + { + "Age": int64(32), + }, }, }, - }, - { - "Name": "Alice", - "_group": []map[string]any{ - { - "Age": int64(19), + { + "Name": "Alice", + "_group": []map[string]any{ + { + "Age": int64(19), + }, }, }, }, @@ -304,31 +314,33 @@ func TestQuerySimpleWithGroupByString(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Carlo", - "_group": []map[string]any{ - { - "Age": int64(55), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "_group": []map[string]any{ + { + "Age": int64(55), + }, }, }, - }, - { - "Name": "John", - "_group": []map[string]any{ - { - "Age": int64(25), - }, - { - "Age": int64(32), + { + "Name": "John", + "_group": []map[string]any{ + { + "Age": int64(25), + }, + { + "Age": int64(32), + }, }, }, - }, - { - "Name": "Alice", - "_group": []map[string]any{ - { - "Age": int64(19), + { + "Name": "Alice", + "_group": []map[string]any{ + { + "Age": int64(19), + }, }, }, }, @@ -381,52 +393,54 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBoolean(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_group": []map[string]any{ - { - "Verified": true, - "_group": []map[string]any{ - { - "Age": int64(25), - }, - { - "Age": int64(32), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_group": []map[string]any{ + { + "Verified": true, + "_group": []map[string]any{ + { + "Age": int64(25), + }, + { + "Age": int64(32), + }, }, }, - }, - { - "Verified": false, - "_group": []map[string]any{ - { - "Age": int64(34), + { + "Verified": false, + "_group": []map[string]any{ + { + "Age": int64(34), + }, }, }, }, }, - }, - { - "Name": "Carlo", - "_group": []map[string]any{ - { - "Verified": true, - "_group": []map[string]any{ - { - "Age": int64(55), + { + "Name": "Carlo", + "_group": []map[string]any{ + { + "Verified": true, + "_group": []map[string]any{ + { + "Age": int64(55), + }, }, }, }, }, - }, - { - "Name": "Alice", - "_group": []map[string]any{ - { - "Verified": false, - "_group": []map[string]any{ - { - "Age": int64(19), + { + "Name": "Alice", + "_group": []map[string]any{ + { + "Verified": false, + "_group": []map[string]any{ + { + "Age": int64(19), + }, }, }, }, @@ -479,43 +493,45 @@ func TestQuerySimpleWithGroupByStringThenBoolean(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Verified": true, - "_group": []map[string]any{ - { - "Age": int64(25), - }, - { - "Age": int64(32), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Verified": true, + "_group": []map[string]any{ + { + "Age": int64(25), + }, + { + "Age": int64(32), + }, }, }, - }, - { - "Name": "John", - "Verified": false, - "_group": []map[string]any{ - { - "Age": int64(34), + { + "Name": "John", + "Verified": false, + "_group": []map[string]any{ + { + "Age": int64(34), + }, }, }, - }, - { - "Name": "Carlo", - "Verified": true, - "_group": []map[string]any{ - { - "Age": int64(55), + { + "Name": "Carlo", + "Verified": true, + "_group": []map[string]any{ + { + "Age": int64(55), + }, }, }, - }, - { - "Name": "Alice", - "Verified": false, - "_group": []map[string]any{ - { - "Age": int64(19), + { + "Name": "Alice", + "Verified": false, + "_group": []map[string]any{ + { + "Age": int64(19), + }, }, }, }, @@ -566,43 +582,45 @@ func TestQuerySimpleWithGroupByBooleanThenNumber(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Verified": true, - "_group": []map[string]any{ - { - "Age": int64(25), - }, - { - "Age": int64(32), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Verified": true, + "_group": []map[string]any{ + { + "Age": int64(25), + }, + { + "Age": int64(32), + }, }, }, - }, - { - "Name": "John", - "Verified": false, - "_group": []map[string]any{ - { - "Age": int64(34), + { + "Name": "John", + "Verified": false, + "_group": []map[string]any{ + { + "Age": int64(34), + }, }, }, - }, - { - "Name": "Carlo", - "Verified": true, - "_group": []map[string]any{ - { - "Age": int64(55), + { + "Name": "Carlo", + "Verified": true, + "_group": []map[string]any{ + { + "Age": int64(55), + }, }, }, - }, - { - "Name": "Alice", - "Verified": false, - "_group": []map[string]any{ - { - "Age": int64(19), + { + "Name": "Alice", + "Verified": false, + "_group": []map[string]any{ + { + "Age": int64(19), + }, }, }, }, @@ -634,12 +652,14 @@ func TestQuerySimpleWithGroupByNumberOnUndefined(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Age": nil, - }, - { - "Age": int64(32), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": nil, + }, + { + "Age": int64(32), + }, }, }, } @@ -672,23 +692,25 @@ func TestQuerySimpleWithGroupByNumberOnUndefinedWithChildren(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Age": nil, - "_group": []map[string]any{ - { - "Name": "Alice", - }, - { - "Name": "Bob", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": nil, + "_group": []map[string]any{ + { + "Name": "Alice", + }, + { + "Name": "Bob", + }, }, }, - }, - { - "Age": int64(32), - "_group": []map[string]any{ - { - "Name": "John", + { + "Age": int64(32), + "_group": []map[string]any{ + { + "Name": "John", + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_typename_test.go b/tests/integration/query/simple/with_group_typename_test.go index 7da1001c74..d8179fc755 100644 --- a/tests/integration/query/simple/with_group_typename_test.go +++ b/tests/integration/query/simple/with_group_typename_test.go @@ -32,10 +32,12 @@ func TestQuerySimpleWithGroupByWithTypeName(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "__typename": "Users", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "__typename": "Users", + }, }, }, } @@ -61,12 +63,14 @@ func TestQuerySimpleWithGroupByWithChildTypeName(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_group": []map[string]any{ - { - "__typename": "Users", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_group": []map[string]any{ + { + "__typename": "Users", + }, }, }, }, diff --git a/tests/integration/query/simple/with_limit_offset_test.go b/tests/integration/query/simple/with_limit_offset_test.go index 21e02f049c..458fc91cc9 100644 --- a/tests/integration/query/simple/with_limit_offset_test.go +++ b/tests/integration/query/simple/with_limit_offset_test.go @@ -36,12 +36,14 @@ func TestQuerySimpleWithLimit0(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Bob", - }, - { - "Name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, }, }, } @@ -71,10 +73,12 @@ func TestQuerySimpleWithLimit(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Bob", - "Age": int64(32), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + "Age": int64(32), + }, }, }, }, @@ -106,14 +110,16 @@ func TestQuerySimpleWithLimit(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Carlo", - "Age": int64(55), - }, - { - "Name": "Bob", - "Age": int64(32), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "Age": int64(55), + }, + { + "Name": "Bob", + "Age": int64(32), + }, }, }, }, @@ -146,10 +152,12 @@ func TestQuerySimpleWithLimitAndOffset(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, }, }, }, @@ -181,14 +189,16 @@ func TestQuerySimpleWithLimitAndOffset(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Alice", - "Age": int64(19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Alice", + "Age": int64(19), + }, }, }, }, @@ -221,10 +231,12 @@ func TestQuerySimpleWithOffset(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, }, }, }, @@ -260,18 +272,20 @@ func TestQuerySimpleWithOffset(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Melynda", - "Age": int64(30), - }, - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Alice", - "Age": int64(19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Melynda", + "Age": int64(30), + }, + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Alice", + "Age": int64(19), + }, }, }, }, diff --git a/tests/integration/query/simple/with_multiple_types_test.go b/tests/integration/query/simple/with_multiple_types_test.go index e46b03db28..6a8eb6dcfa 100644 --- a/tests/integration/query/simple/with_multiple_types_test.go +++ b/tests/integration/query/simple/with_multiple_types_test.go @@ -70,9 +70,11 @@ func TestSimple_WithSevenDummyTypesBefore(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -131,9 +133,11 @@ func TestSimple_WithEightDummyTypesBefore(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -195,9 +199,11 @@ func TestSimple_WithEightDummyTypesBeforeInSplitDeclaration(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -256,9 +262,11 @@ func TestSimple_WithEightDummyTypesAfter(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -318,9 +326,11 @@ func TestSimple_WithSevenDummyTypesBeforeAndOneAfter(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "John", + }, }, }, }, diff --git a/tests/integration/query/simple/with_operation_alias_test.go b/tests/integration/query/simple/with_operation_alias_test.go new file mode 100644 index 0000000000..5a1130c523 --- /dev/null +++ b/tests/integration/query/simple/with_operation_alias_test.go @@ -0,0 +1,49 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package simple + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestQuerySimpleWithOperationAlias(t *testing.T) { + test := testUtils.RequestTestCase{ + Description: "Simple query with operation alias", + Request: `query { + allUsers: Users { + _docID + Name + Age + } + }`, + Docs: map[int][]string{ + 0: { + `{ + "Name": "John", + "Age": 21 + }`, + }, + }, + Results: map[string]any{ + "allUsers": []map[string]any{ + { + "_docID": "bae-d4303725-7db9-53d2-b324-f3ee44020e52", + "Name": "John", + "Age": int64(21), + }, + }, + }, + } + + executeTestCase(t, test) +} diff --git a/tests/integration/query/simple/with_order_filter_test.go b/tests/integration/query/simple/with_order_filter_test.go index d65a197f2c..cbee236ca2 100644 --- a/tests/integration/query/simple/with_order_filter_test.go +++ b/tests/integration/query/simple/with_order_filter_test.go @@ -45,14 +45,16 @@ func TestQuerySimpleWithNumericGreaterThanFilterAndNumericOrderDescending(t *tes }`, }, }, - Results: []map[string]any{ - { - "Name": "Carlo", - "Age": int64(55), - }, - { - "Name": "Bob", - "Age": int64(32), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "Age": int64(55), + }, + { + "Name": "Bob", + "Age": int64(32), + }, }, }, } diff --git a/tests/integration/query/simple/with_order_test.go b/tests/integration/query/simple/with_order_test.go index 1bd56574f9..003b9a0a52 100644 --- a/tests/integration/query/simple/with_order_test.go +++ b/tests/integration/query/simple/with_order_test.go @@ -41,18 +41,20 @@ func TestQuerySimpleWithEmptyOrder(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Carlo", - "Age": int64(55), - }, - { - "Name": "Bob", - "Age": int64(32), - }, - { - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "Age": int64(55), + }, + { + "Name": "Bob", + "Age": int64(32), + }, + { + "Name": "John", + "Age": int64(21), + }, }, }, } @@ -89,22 +91,24 @@ func TestQuerySimpleWithNumericOrderAscending(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Alice", - "Age": int64(19), - }, - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Bob", - "Age": int64(32), - }, - { - "Name": "Carlo", - "Age": int64(55), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Alice", + "Age": int64(19), + }, + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Bob", + "Age": int64(32), + }, + { + "Name": "Carlo", + "Age": int64(55), + }, }, }, } @@ -145,22 +149,24 @@ func TestQuerySimpleWithDateTimeOrderAscending(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Alice", - "Age": int64(19), - }, - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Bob", - "Age": int64(32), - }, - { - "Name": "Carlo", - "Age": int64(55), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Alice", + "Age": int64(19), + }, + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Bob", + "Age": int64(32), + }, + { + "Name": "Carlo", + "Age": int64(55), + }, }, }, } @@ -197,22 +203,24 @@ func TestQuerySimpleWithNumericOrderDescending(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Carlo", - "Age": int64(55), - }, - { - "Name": "Bob", - "Age": int64(32), - }, - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Alice", - "Age": int64(19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "Age": int64(55), + }, + { + "Name": "Bob", + "Age": int64(32), + }, + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Alice", + "Age": int64(19), + }, }, }, } @@ -253,22 +261,24 @@ func TestQuerySimpleWithDateTimeOrderDescending(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "Carlo", - "Age": int64(55), - }, - { - "Name": "Bob", - "Age": int64(32), - }, - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Alice", - "Age": int64(19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "Age": int64(55), + }, + { + "Name": "Bob", + "Age": int64(32), + }, + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Alice", + "Age": int64(19), + }, }, }, } @@ -310,26 +320,28 @@ func TestQuerySimpleWithNumericOrderDescendingAndBooleanOrderAscending(t *testin }`, }, }, - Results: []map[string]any{ - { - "Name": "Carlo", - "Age": int64(55), - "Verified": true, - }, - { - "Name": "Bob", - "Age": int64(21), - "Verified": false, - }, - { - "Name": "John", - "Age": int64(21), - "Verified": true, - }, - { - "Name": "Alice", - "Age": int64(19), - "Verified": false, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "Age": int64(55), + "Verified": true, + }, + { + "Name": "Bob", + "Age": int64(21), + "Verified": false, + }, + { + "Name": "John", + "Age": int64(21), + "Verified": true, + }, + { + "Name": "Alice", + "Age": int64(19), + "Verified": false, + }, }, }, } diff --git a/tests/integration/query/simple/with_restart_test.go b/tests/integration/query/simple/with_restart_test.go index 0991f55c23..5d225bfad8 100644 --- a/tests/integration/query/simple/with_restart_test.go +++ b/tests/integration/query/simple/with_restart_test.go @@ -43,10 +43,12 @@ func TestQuerySimpleWithRestart(t *testing.T) { age } }`, - Results: []map[string]any{ - { - "name": "Shahzad", - "age": int64(30), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "age": int64(30), + }, }, }, }, diff --git a/tests/integration/query/simple/with_sum_filter_test.go b/tests/integration/query/simple/with_sum_filter_test.go index d02990ecea..1c1515a769 100644 --- a/tests/integration/query/simple/with_sum_filter_test.go +++ b/tests/integration/query/simple/with_sum_filter_test.go @@ -38,10 +38,8 @@ func TestQuerySimpleWithSumWithFilter(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "_sum": int64(62), - }, + Results: map[string]any{ + "_sum": int64(62), }, } diff --git a/tests/integration/query/simple/with_sum_test.go b/tests/integration/query/simple/with_sum_test.go index 812faf6995..34dde00e15 100644 --- a/tests/integration/query/simple/with_sum_test.go +++ b/tests/integration/query/simple/with_sum_test.go @@ -46,10 +46,8 @@ func TestQuerySimpleWithSumOnEmptyCollection(t *testing.T) { Request: `query { _sum(Users: {field: Age}) }`, - Results: []map[string]any{ - { - "_sum": int64(0), - }, + Results: map[string]any{ + "_sum": int64(0), }, } @@ -74,10 +72,8 @@ func TestQuerySimpleWithSum(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "_sum": int64(51), - }, + Results: map[string]any{ + "_sum": int64(51), }, } diff --git a/tests/integration/query/simple/with_typename_test.go b/tests/integration/query/simple/with_typename_test.go index fb7a5e0bb8..8f44ee60c0 100644 --- a/tests/integration/query/simple/with_typename_test.go +++ b/tests/integration/query/simple/with_typename_test.go @@ -32,10 +32,12 @@ func TestQuerySimpleWithTypeName(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "__typename": "Users", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "__typename": "Users", + }, }, }, } @@ -60,11 +62,13 @@ func TestQuerySimpleWithAliasedTypeName(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "__typename": "Users", - "t1": "Users", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "__typename": "Users", + "t1": "Users", + }, }, }, } diff --git a/tests/integration/query/simple/with_version_test.go b/tests/integration/query/simple/with_version_test.go index 732c1b6f1a..aaf2092e61 100644 --- a/tests/integration/query/simple/with_version_test.go +++ b/tests/integration/query/simple/with_version_test.go @@ -40,21 +40,23 @@ func TestQuerySimpleWithEmbeddedLatestCommit(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Age": int64(21), - "_version": []map[string]any{ - { - "cid": "bafyreiby7drdzfsg4wwo7f6vkdqhurbe74s4lhayn3k3226zvkgwjd2fbu", - "links": []map[string]any{ - { - "cid": "bafyreid4sasigytiflrh3rupyevo6wy43b6mlfi4jwkjjwvohgjcd3oscu", - "name": "Age", - }, - { - "cid": "bafyreieg3p2kpyxwiowskvb3pp35nedzawmapjuib7glrvszcgmv6z37fm", - "name": "Name", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + "_version": []map[string]any{ + { + "cid": "bafyreiby7drdzfsg4wwo7f6vkdqhurbe74s4lhayn3k3226zvkgwjd2fbu", + "links": []map[string]any{ + { + "cid": "bafyreid4sasigytiflrh3rupyevo6wy43b6mlfi4jwkjjwvohgjcd3oscu", + "name": "Age", + }, + { + "cid": "bafyreieg3p2kpyxwiowskvb3pp35nedzawmapjuib7glrvszcgmv6z37fm", + "name": "Name", + }, }, }, }, @@ -85,12 +87,14 @@ func TestQuerySimpleWithEmbeddedLatestCommitWithSchemaVersionID(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_version": []map[string]any{ - { - "schemaVersionId": "bafkreigqmcqzkbg3elpe24vfza4rjle2r6cxu7ihzvg56aov57crhaebry", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_version": []map[string]any{ + { + "schemaVersionId": "bafkreigqmcqzkbg3elpe24vfza4rjle2r6cxu7ihzvg56aov57crhaebry", + }, }, }, }, @@ -122,13 +126,15 @@ func TestQuerySimpleWithEmbeddedLatestCommitWithDocID(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "_docID": docID, - "_version": []map[string]any{ - { - "docID": docID, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_docID": docID, + "_version": []map[string]any{ + { + "docID": docID, + }, }, }, }, @@ -165,29 +171,31 @@ func TestQuerySimpleWithMultipleAliasedEmbeddedLatestCommit(t *testing.T) { }`, }, }, - Results: []map[string]any{ - { - "Name": "John", - "Age": int64(21), - "_version": []map[string]any{ - { - "cid": "bafyreiby7drdzfsg4wwo7f6vkdqhurbe74s4lhayn3k3226zvkgwjd2fbu", - "L1": []map[string]any{ - { - "cid": "bafyreid4sasigytiflrh3rupyevo6wy43b6mlfi4jwkjjwvohgjcd3oscu", - "name": "Age", - }, - { - "cid": "bafyreieg3p2kpyxwiowskvb3pp35nedzawmapjuib7glrvszcgmv6z37fm", - "name": "Name", - }, - }, - "L2": []map[string]any{ - { - "name": "Age", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + "_version": []map[string]any{ + { + "cid": "bafyreiby7drdzfsg4wwo7f6vkdqhurbe74s4lhayn3k3226zvkgwjd2fbu", + "L1": []map[string]any{ + { + "cid": "bafyreid4sasigytiflrh3rupyevo6wy43b6mlfi4jwkjjwvohgjcd3oscu", + "name": "Age", + }, + { + "cid": "bafyreieg3p2kpyxwiowskvb3pp35nedzawmapjuib7glrvszcgmv6z37fm", + "name": "Name", + }, }, - { - "name": "Name", + "L2": []map[string]any{ + { + "name": "Age", + }, + { + "name": "Name", + }, }, }, }, @@ -236,30 +244,32 @@ func TestQuery_WithAllCommitFields_NoError(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "Name": "John", - "_docID": docID, - "_version": []map[string]any{ - { - "cid": "bafyreiby7drdzfsg4wwo7f6vkdqhurbe74s4lhayn3k3226zvkgwjd2fbu", - "collectionID": int64(1), - "delta": nil, - "docID": "bae-d4303725-7db9-53d2-b324-f3ee44020e52", - "fieldId": "C", - "fieldName": nil, - "height": int64(1), - "links": []map[string]any{ - { - "cid": "bafyreid4sasigytiflrh3rupyevo6wy43b6mlfi4jwkjjwvohgjcd3oscu", - "name": "Age", - }, - { - "cid": "bafyreieg3p2kpyxwiowskvb3pp35nedzawmapjuib7glrvszcgmv6z37fm", - "name": "Name", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_docID": docID, + "_version": []map[string]any{ + { + "cid": "bafyreiby7drdzfsg4wwo7f6vkdqhurbe74s4lhayn3k3226zvkgwjd2fbu", + "collectionID": int64(1), + "delta": nil, + "docID": "bae-d4303725-7db9-53d2-b324-f3ee44020e52", + "fieldId": "C", + "fieldName": nil, + "height": int64(1), + "links": []map[string]any{ + { + "cid": "bafyreid4sasigytiflrh3rupyevo6wy43b6mlfi4jwkjjwvohgjcd3oscu", + "name": "Age", + }, + { + "cid": "bafyreieg3p2kpyxwiowskvb3pp35nedzawmapjuib7glrvszcgmv6z37fm", + "name": "Name", + }, }, + "schemaVersionId": "bafkreigqmcqzkbg3elpe24vfza4rjle2r6cxu7ihzvg56aov57crhaebry", }, - "schemaVersionId": "bafkreigqmcqzkbg3elpe24vfza4rjle2r6cxu7ihzvg56aov57crhaebry", }, }, }, @@ -314,51 +324,53 @@ func TestQuery_WithAllCommitFieldsWithUpdate_NoError(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "Name": "John", - "Age": int64(22), - "_docID": docID, - "_version": []map[string]any{ - { - "cid": "bafyreigfstknvmsl77pg443lqqf2g64y7hr575tts5c4nxuzk3dynffkem", - "collectionID": int64(1), - "delta": nil, - "docID": docID, - "fieldId": "C", - "fieldName": nil, - "height": int64(2), - "links": []map[string]any{ - { - "cid": "bafyreiby7drdzfsg4wwo7f6vkdqhurbe74s4lhayn3k3226zvkgwjd2fbu", - "name": "_head", - }, - { - "cid": "bafyreiapjg22e47sanhjtqgu453mvmxcfcl4ksrcoctyfl6nfsh3xwfcvm", - "name": "Age", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(22), + "_docID": docID, + "_version": []map[string]any{ + { + "cid": "bafyreigfstknvmsl77pg443lqqf2g64y7hr575tts5c4nxuzk3dynffkem", + "collectionID": int64(1), + "delta": nil, + "docID": docID, + "fieldId": "C", + "fieldName": nil, + "height": int64(2), + "links": []map[string]any{ + { + "cid": "bafyreiby7drdzfsg4wwo7f6vkdqhurbe74s4lhayn3k3226zvkgwjd2fbu", + "name": "_head", + }, + { + "cid": "bafyreiapjg22e47sanhjtqgu453mvmxcfcl4ksrcoctyfl6nfsh3xwfcvm", + "name": "Age", + }, }, + "schemaVersionId": "bafkreigqmcqzkbg3elpe24vfza4rjle2r6cxu7ihzvg56aov57crhaebry", }, - "schemaVersionId": "bafkreigqmcqzkbg3elpe24vfza4rjle2r6cxu7ihzvg56aov57crhaebry", - }, - { - "cid": "bafyreiby7drdzfsg4wwo7f6vkdqhurbe74s4lhayn3k3226zvkgwjd2fbu", - "collectionID": int64(1), - "delta": nil, - "docID": docID, - "fieldId": "C", - "fieldName": nil, - "height": int64(1), - "links": []map[string]any{ - { - "cid": "bafyreid4sasigytiflrh3rupyevo6wy43b6mlfi4jwkjjwvohgjcd3oscu", - "name": "Age", - }, - { - "cid": "bafyreieg3p2kpyxwiowskvb3pp35nedzawmapjuib7glrvszcgmv6z37fm", - "name": "Name", + { + "cid": "bafyreiby7drdzfsg4wwo7f6vkdqhurbe74s4lhayn3k3226zvkgwjd2fbu", + "collectionID": int64(1), + "delta": nil, + "docID": docID, + "fieldId": "C", + "fieldName": nil, + "height": int64(1), + "links": []map[string]any{ + { + "cid": "bafyreid4sasigytiflrh3rupyevo6wy43b6mlfi4jwkjjwvohgjcd3oscu", + "name": "Age", + }, + { + "cid": "bafyreieg3p2kpyxwiowskvb3pp35nedzawmapjuib7glrvszcgmv6z37fm", + "name": "Name", + }, }, + "schemaVersionId": "bafkreigqmcqzkbg3elpe24vfza4rjle2r6cxu7ihzvg56aov57crhaebry", }, - "schemaVersionId": "bafkreigqmcqzkbg3elpe24vfza4rjle2r6cxu7ihzvg56aov57crhaebry", }, }, }, diff --git a/tests/integration/schema/migrations/query/simple_test.go b/tests/integration/schema/migrations/query/simple_test.go index 4e0ca20f2b..584933946e 100644 --- a/tests/integration/schema/migrations/query/simple_test.go +++ b/tests/integration/schema/migrations/query/simple_test.go @@ -67,10 +67,12 @@ func TestSchemaMigrationQuery(t *testing.T) { verified } }`, - Results: []map[string]any{ - { - "name": "John", - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "verified": true, + }, }, }, }, @@ -137,18 +139,20 @@ func TestSchemaMigrationQueryMultipleDocs(t *testing.T) { verified } }`, - Results: []map[string]any{ - { - "name": "Islam", - "verified": true, - }, - { - "name": "Fred", - "verified": true, - }, - { - "name": "Shahzad", - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Islam", + "verified": true, + }, + { + "name": "Fred", + "verified": true, + }, + { + "name": "Shahzad", + "verified": true, + }, }, }, }, @@ -207,10 +211,12 @@ func TestSchemaMigrationQueryWithMigrationRegisteredBeforeSchemaPatch(t *testing verified } }`, - Results: []map[string]any{ - { - "name": "John", - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "verified": true, + }, }, }, }, @@ -277,11 +283,13 @@ func TestSchemaMigrationQueryMigratesToIntermediaryVersion(t *testing.T) { email } }`, - Results: []map[string]any{ - { - "name": "John", - "verified": true, - "email": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "verified": true, + "email": nil, + }, }, }, }, @@ -348,11 +356,13 @@ func TestSchemaMigrationQueryMigratesFromIntermediaryVersion(t *testing.T) { email } }`, - Results: []map[string]any{ - { - "name": "John", - "verified": true, - "email": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "verified": true, + "email": nil, + }, }, }, }, @@ -434,11 +444,13 @@ func TestSchemaMigrationQueryMigratesAcrossMultipleVersions(t *testing.T) { email } }`, - Results: []map[string]any{ - { - "name": "John", - "verified": true, - "email": "ilovewasm@source.com", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "verified": true, + "email": "ilovewasm@source.com", + }, }, }, }, @@ -520,11 +532,13 @@ func TestSchemaMigrationQueryMigratesAcrossMultipleVersionsBeforePatches(t *test email } }`, - Results: []map[string]any{ - { - "name": "John", - "verified": true, - "email": "ilovewasm@source.com", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "verified": true, + "email": "ilovewasm@source.com", + }, }, }, }, @@ -607,11 +621,13 @@ func TestSchemaMigrationQueryMigratesAcrossMultipleVersionsBeforePatchesWrongOrd email } }`, - Results: []map[string]any{ - { - "name": "John", - "verified": true, - "email": "ilovewasm@source.com", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "verified": true, + "email": "ilovewasm@source.com", + }, }, }, }, @@ -674,10 +690,12 @@ func TestSchemaMigrationQueryWithUnknownSchemaMigration(t *testing.T) { verified } }`, - Results: []map[string]any{ - { - "name": "John", - "verified": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "verified": nil, + }, }, }, }, @@ -736,9 +754,11 @@ func TestSchemaMigrationQueryMigrationMutatesExistingScalarField(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "Fred", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Fred", + }, }, }, }, @@ -797,9 +817,11 @@ func TestSchemaMigrationQueryMigrationMutatesExistingInlineArrayField(t *testing mobile } }`, - Results: []map[string]any{ - { - "mobile": []int64{847, 723, 2012}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "mobile": []int64{847, 723, 2012}, + }, }, }, }, @@ -857,10 +879,12 @@ func TestSchemaMigrationQueryMigrationRemovesExistingField(t *testing.T) { age } }`, - Results: []map[string]any{ - { - "name": "John", - "age": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "age": nil, + }, }, }, }, @@ -918,9 +942,11 @@ func TestSchemaMigrationQueryMigrationPreservesExistingFieldWhenFieldNotRequeste name } }`, - Results: []map[string]any{ - { - "name": "Fred", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Fred", + }, }, }, }, @@ -931,10 +957,12 @@ func TestSchemaMigrationQueryMigrationPreservesExistingFieldWhenFieldNotRequeste age } }`, - Results: []map[string]any{ - { - "name": "Fred", - "age": int64(40), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Fred", + "age": int64(40), + }, }, }, }, @@ -993,10 +1021,12 @@ func TestSchemaMigrationQueryMigrationCopiesExistingFieldWhenSrcFieldNotRequeste yearsLived } }`, - Results: []map[string]any{ - { - "name": "John", - "yearsLived": int64(40), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "yearsLived": int64(40), + }, }, }, }, @@ -1054,9 +1084,11 @@ func TestSchemaMigrationQueryMigrationCopiesExistingFieldWhenSrcAndDstFieldNotRe name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -1068,11 +1100,13 @@ func TestSchemaMigrationQueryMigrationCopiesExistingFieldWhenSrcAndDstFieldNotRe yearsLived } }`, - Results: []map[string]any{ - { - "name": "John", - "age": int64(40), - "yearsLived": int64(40), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "age": int64(40), + "yearsLived": int64(40), + }, }, }, }, diff --git a/tests/integration/schema/migrations/query/with_doc_id_test.go b/tests/integration/schema/migrations/query/with_doc_id_test.go index 2bd34a6fd4..bb28b90ac8 100644 --- a/tests/integration/schema/migrations/query/with_doc_id_test.go +++ b/tests/integration/schema/migrations/query/with_doc_id_test.go @@ -74,10 +74,12 @@ func TestSchemaMigrationQueryByDocID(t *testing.T) { verified } }`, - Results: []map[string]any{ - { - "name": "Shahzad", - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "verified": true, + }, }, }, }, @@ -180,10 +182,12 @@ func TestSchemaMigrationQueryMultipleQueriesByDocID(t *testing.T) { verified } }`, - Results: []map[string]any{ - { - "name": "Shahzad", - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "verified": true, + }, }, }, }, @@ -194,10 +198,12 @@ func TestSchemaMigrationQueryMultipleQueriesByDocID(t *testing.T) { verified } }`, - Results: []map[string]any{ - { - "name": "Fred", - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Fred", + "verified": true, + }, }, }, }, @@ -208,10 +214,12 @@ func TestSchemaMigrationQueryMultipleQueriesByDocID(t *testing.T) { verified } }`, - Results: []map[string]any{ - { - "name": "Chris", - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Chris", + "verified": true, + }, }, }, }, @@ -222,10 +230,12 @@ func TestSchemaMigrationQueryMultipleQueriesByDocID(t *testing.T) { verified } }`, - Results: []map[string]any{ - { - "name": "John", - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "verified": true, + }, }, }, }, @@ -236,10 +246,12 @@ func TestSchemaMigrationQueryMultipleQueriesByDocID(t *testing.T) { verified } }`, - Results: []map[string]any{ - { - "name": "Islam", - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Islam", + "verified": true, + }, }, }, }, @@ -250,10 +262,12 @@ func TestSchemaMigrationQueryMultipleQueriesByDocID(t *testing.T) { verified } }`, - Results: []map[string]any{ - { - "name": "Dave", - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Dave", + "verified": true, + }, }, }, }, diff --git a/tests/integration/schema/migrations/query/with_inverse_test.go b/tests/integration/schema/migrations/query/with_inverse_test.go index 11c83c5fd4..3324637d7d 100644 --- a/tests/integration/schema/migrations/query/with_inverse_test.go +++ b/tests/integration/schema/migrations/query/with_inverse_test.go @@ -99,11 +99,13 @@ func TestSchemaMigrationQueryInversesAcrossMultipleVersions(t *testing.T) { height } }`, - Results: []map[string]any{ - { - "name": "John", - "age": nil, - "height": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "age": nil, + "height": nil, + }, }, }, }, diff --git a/tests/integration/schema/migrations/query/with_p2p_schema_branch_test.go b/tests/integration/schema/migrations/query/with_p2p_schema_branch_test.go index d7dc9f10dd..a1f207f3a8 100644 --- a/tests/integration/schema/migrations/query/with_p2p_schema_branch_test.go +++ b/tests/integration/schema/migrations/query/with_p2p_schema_branch_test.go @@ -102,10 +102,12 @@ func TestSchemaMigrationQueryWithP2PReplicatedDocOnOtherSchemaBranch(t *testing. verified } }`, - Results: []map[string]any{ - { - "name": "John", - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "verified": true, + }, }, }, }, @@ -121,13 +123,15 @@ func TestSchemaMigrationQueryWithP2PReplicatedDocOnOtherSchemaBranch(t *testing. } } `, - Results: []map[string]any{ - { - // name has been cleared by the inverse of the migration from version 1 to 2 - "name": nil, - // phone has been set by the migration from version 1 to 3 - "phone": "1234567890", - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + // name has been cleared by the inverse of the migration from version 1 to 2 + "name": nil, + // phone has been set by the migration from version 1 to 3 + "phone": "1234567890", + "verified": true, + }, }, }, }, diff --git a/tests/integration/schema/migrations/query/with_p2p_test.go b/tests/integration/schema/migrations/query/with_p2p_test.go index 39adf5a5a8..b320bb28f4 100644 --- a/tests/integration/schema/migrations/query/with_p2p_test.go +++ b/tests/integration/schema/migrations/query/with_p2p_test.go @@ -82,9 +82,11 @@ func TestSchemaMigrationQueryWithP2PReplicatedDocAtOlderSchemaVersion(t *testing name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -97,11 +99,13 @@ func TestSchemaMigrationQueryWithP2PReplicatedDocAtOlderSchemaVersion(t *testing verified } }`, - Results: []map[string]any{ - { - "name": "John", - // John has been migrated up to the newer schema version on node 1 - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + // John has been migrated up to the newer schema version on node 1 + "verified": true, + }, }, }, }, @@ -199,9 +203,11 @@ func TestSchemaMigrationQueryWithP2PReplicatedDocAtMuchOlderSchemaVersion(t *tes name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -214,11 +220,13 @@ func TestSchemaMigrationQueryWithP2PReplicatedDocAtMuchOlderSchemaVersion(t *tes verified } }`, - Results: []map[string]any{ - { - "name": "Fred", - // John has been migrated up to the newer schema version on node 1 - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Fred", + // John has been migrated up to the newer schema version on node 1 + "verified": true, + }, }, }, }, @@ -290,10 +298,12 @@ func TestSchemaMigrationQueryWithP2PReplicatedDocAtNewerSchemaVersion(t *testing verified } }`, - Results: []map[string]any{ - { - "name": "John", - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "verified": true, + }, }, }, }, @@ -306,12 +316,14 @@ func TestSchemaMigrationQueryWithP2PReplicatedDocAtNewerSchemaVersion(t *testing verified } }`, - Results: []map[string]any{ - { - "name": "John", - // John has been migrated down to the older schema version on node 1 - // clearing the verified field - "verified": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + // John has been migrated down to the older schema version on node 1 + // clearing the verified field + "verified": nil, + }, }, }, }, @@ -389,9 +401,11 @@ func TestSchemaMigrationQueryWithP2PReplicatedDocAtMuchNewerSchemaVersionWithSch name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + }, }, }, }, diff --git a/tests/integration/schema/migrations/query/with_restart_test.go b/tests/integration/schema/migrations/query/with_restart_test.go index 4f2c0f4ec7..e468249e60 100644 --- a/tests/integration/schema/migrations/query/with_restart_test.go +++ b/tests/integration/schema/migrations/query/with_restart_test.go @@ -68,10 +68,12 @@ func TestSchemaMigrationQueryWithRestart(t *testing.T) { verified } }`, - Results: []map[string]any{ - { - "name": "John", - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "verified": true, + }, }, }, }, @@ -129,10 +131,12 @@ func TestSchemaMigrationQueryWithRestartAndMigrationBeforeSchemaPatch(t *testing verified } }`, - Results: []map[string]any{ - { - "name": "John", - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "verified": true, + }, }, }, }, diff --git a/tests/integration/schema/migrations/query/with_schema_branch_test.go b/tests/integration/schema/migrations/query/with_schema_branch_test.go index 0ed9e68aca..d3bf7b2960 100644 --- a/tests/integration/schema/migrations/query/with_schema_branch_test.go +++ b/tests/integration/schema/migrations/query/with_schema_branch_test.go @@ -92,12 +92,14 @@ func TestSchemaMigrationQuery_WithBranchingSchema(t *testing.T) { } } `, - Results: []map[string]any{ - { - // name has been cleared by the inverse of the migration from version 1 to 2 - "name": nil, - // phone has been set by the migration from version 1 to 3 - "phone": "1234567890", + Results: map[string]any{ + "Users": []map[string]any{ + { + // name has been cleared by the inverse of the migration from version 1 to 2 + "name": nil, + // phone has been set by the migration from version 1 to 3 + "phone": "1234567890", + }, }, }, }, diff --git a/tests/integration/schema/migrations/query/with_set_default_test.go b/tests/integration/schema/migrations/query/with_set_default_test.go index 170a861d89..22865d3173 100644 --- a/tests/integration/schema/migrations/query/with_set_default_test.go +++ b/tests/integration/schema/migrations/query/with_set_default_test.go @@ -69,10 +69,12 @@ func TestSchemaMigrationQuery_WithSetDefaultToLatest_AppliesForwardMigration(t * verified } }`, - Results: []map[string]any{ - { - "name": "John", - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "verified": true, + }, }, }, }, @@ -143,11 +145,13 @@ func TestSchemaMigrationQuery_WithSetDefaultToOriginal_AppliesInverseMigration(t verified } }`, - Results: []map[string]any{ - { - "name": "John", - // The inverse lens migration has been applied, clearing the verified field - "verified": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + // The inverse lens migration has been applied, clearing the verified field + "verified": nil, + }, }, }, }, @@ -215,11 +219,13 @@ func TestSchemaMigrationQuery_WithSetDefaultToOriginalVersionThatDocWasCreatedAt verified } }`, - Results: []map[string]any{ - { - "name": "John", - // The inverse lens migration has not been applied, the document is returned as it was defined - "verified": false, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + // The inverse lens migration has not been applied, the document is returned as it was defined + "verified": false, + }, }, }, }, diff --git a/tests/integration/schema/migrations/query/with_txn_test.go b/tests/integration/schema/migrations/query/with_txn_test.go index 79d2d9e825..3dc5044720 100644 --- a/tests/integration/schema/migrations/query/with_txn_test.go +++ b/tests/integration/schema/migrations/query/with_txn_test.go @@ -70,10 +70,12 @@ func TestSchemaMigrationQueryWithTxn(t *testing.T) { verified } }`, - Results: []map[string]any{ - { - "name": "John", - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "verified": true, + }, }, }, }, @@ -135,10 +137,12 @@ func TestSchemaMigrationQueryWithTxnAndCommit(t *testing.T) { verified } }`, - Results: []map[string]any{ - { - "name": "John", - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "verified": true, + }, }, }, }, diff --git a/tests/integration/schema/migrations/query/with_update_test.go b/tests/integration/schema/migrations/query/with_update_test.go index bbeabcd062..ce9132ba85 100644 --- a/tests/integration/schema/migrations/query/with_update_test.go +++ b/tests/integration/schema/migrations/query/with_update_test.go @@ -67,12 +67,14 @@ func TestSchemaMigrationQueryWithUpdateRequest(t *testing.T) { verified } }`, - Results: []map[string]any{ - { - "name": "Johnnnn", - // We need to assert that the migration has been run within the context - // of the update - "verified": true, + Results: map[string]any{ + "update_Users": []map[string]any{ + { + "name": "Johnnnn", + // We need to assert that the migration has been run within the context + // of the update + "verified": true, + }, }, }, }, @@ -83,12 +85,14 @@ func TestSchemaMigrationQueryWithUpdateRequest(t *testing.T) { verified } }`, - Results: []map[string]any{ - { - "name": "Johnnnn", - // We need to assert that the effects of the migration executed within the - // update have been persisted - "verified": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Johnnnn", + // We need to assert that the effects of the migration executed within the + // update have been persisted + "verified": true, + }, }, }, }, @@ -151,12 +155,14 @@ func TestSchemaMigrationQueryWithMigrationRegisteredAfterUpdate(t *testing.T) { verified } }`, - Results: []map[string]any{ - { - "name": "Johnnnn", - // As the document was updated before the migration was registered - // the migration will not have been run - "verified": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Johnnnn", + // As the document was updated before the migration was registered + // the migration will not have been run + "verified": nil, + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/crdt/lww_test.go b/tests/integration/schema/updates/add/field/crdt/lww_test.go index 5d75d4db6e..44444f5aa3 100644 --- a/tests/integration/schema/updates/add/field/crdt/lww_test.go +++ b/tests/integration/schema/updates/add/field/crdt/lww_test.go @@ -41,7 +41,9 @@ func TestSchemaUpdatesAddFieldCRDTLWW(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/schema/updates/add/field/crdt/none_test.go b/tests/integration/schema/updates/add/field/crdt/none_test.go index c49faa3904..002320115f 100644 --- a/tests/integration/schema/updates/add/field/crdt/none_test.go +++ b/tests/integration/schema/updates/add/field/crdt/none_test.go @@ -41,7 +41,9 @@ func TestSchemaUpdatesAddFieldCRDTDefault(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -73,7 +75,9 @@ func TestSchemaUpdatesAddFieldCRDTNone(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/schema/updates/add/field/crdt/pcounter_test.go b/tests/integration/schema/updates/add/field/crdt/pcounter_test.go index b7edfe7269..0614311fe2 100644 --- a/tests/integration/schema/updates/add/field/crdt/pcounter_test.go +++ b/tests/integration/schema/updates/add/field/crdt/pcounter_test.go @@ -41,7 +41,9 @@ func TestSchemaUpdates_AddFieldCRDTPCounter_NoError(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/schema/updates/add/field/crdt/pncounter_test.go b/tests/integration/schema/updates/add/field/crdt/pncounter_test.go index e4be1c1df8..788f0aff65 100644 --- a/tests/integration/schema/updates/add/field/crdt/pncounter_test.go +++ b/tests/integration/schema/updates/add/field/crdt/pncounter_test.go @@ -41,7 +41,9 @@ func TestSchemaUpdates_AddFieldCRDTPNCounter_NoError(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/schema/updates/add/field/create_test.go b/tests/integration/schema/updates/add/field/create_test.go index 32f10b1a60..85ded26b12 100644 --- a/tests/integration/schema/updates/add/field/create_test.go +++ b/tests/integration/schema/updates/add/field/create_test.go @@ -48,11 +48,13 @@ func TestSchemaUpdatesAddFieldWithCreate(t *testing.T) { email } }`, - Results: []map[string]any{ - { - "_docID": "bae-6845cfdf-cb0f-56a3-be3a-b5a67be5fbdc", - "name": "John", - "email": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-6845cfdf-cb0f-56a3-be3a-b5a67be5fbdc", + "name": "John", + "email": nil, + }, }, }, }, @@ -102,14 +104,16 @@ func TestSchemaUpdatesAddFieldWithCreateAfterSchemaUpdate(t *testing.T) { email } }`, - Results: []map[string]any{ - { - "name": "Shahzad", - "email": "sqlizded@yahoo.ca", - }, - { - "name": "John", - "email": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "email": "sqlizded@yahoo.ca", + }, + { + "name": "John", + "email": nil, + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/create_update_test.go b/tests/integration/schema/updates/add/field/create_update_test.go index 53b892e0ae..12d8523460 100644 --- a/tests/integration/schema/updates/add/field/create_update_test.go +++ b/tests/integration/schema/updates/add/field/create_update_test.go @@ -47,12 +47,14 @@ func TestSchemaUpdatesAddFieldWithCreateWithUpdateAfterSchemaUpdateAndVersionJoi } } }`, - Results: []map[string]any{ - { - "name": "John", - "_version": []map[string]any{ - { - "schemaVersionId": initialSchemaVersionID, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_version": []map[string]any{ + { + "schemaVersionId": initialSchemaVersionID, + }, }, }, }, @@ -82,18 +84,20 @@ func TestSchemaUpdatesAddFieldWithCreateWithUpdateAfterSchemaUpdateAndVersionJoi } } }`, - Results: []map[string]any{ - { - "name": "John", - "email": "ih8oraclelicensing@netscape.net", - "_version": []map[string]any{ - { - // Update commit - "schemaVersionId": updatedSchemaVersionID, - }, - { - // Create commit - "schemaVersionId": initialSchemaVersionID, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "email": "ih8oraclelicensing@netscape.net", + "_version": []map[string]any{ + { + // Update commit + "schemaVersionId": updatedSchemaVersionID, + }, + { + // Create commit + "schemaVersionId": initialSchemaVersionID, + }, }, }, }, @@ -144,14 +148,16 @@ func TestSchemaUpdatesAddFieldWithCreateWithUpdateAfterSchemaUpdateAndCommitQuer schemaVersionId } }`, - Results: []map[string]any{ - { - // Update commit - "schemaVersionId": updatedSchemaVersionID, - }, - { - // Create commit - "schemaVersionId": initialSchemaVersionID, + Results: map[string]any{ + "commits": []map[string]any{ + { + // Update commit + "schemaVersionId": updatedSchemaVersionID, + }, + { + // Create commit + "schemaVersionId": initialSchemaVersionID, + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/kind/blob_test.go b/tests/integration/schema/updates/add/field/kind/blob_test.go index badbdc56fe..c4bd3c1d2e 100644 --- a/tests/integration/schema/updates/add/field/kind/blob_test.go +++ b/tests/integration/schema/updates/add/field/kind/blob_test.go @@ -41,7 +41,9 @@ func TestSchemaUpdatesAddFieldKindBlob(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -80,10 +82,12 @@ func TestSchemaUpdatesAddFieldKindBlobWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": "00ff", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": "00ff", + }, }, }, }, @@ -124,10 +128,12 @@ func TestSchemaUpdatesAddFieldKindBlobSubstitutionWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": "00ff", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": "00ff", + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/kind/bool_array_test.go b/tests/integration/schema/updates/add/field/kind/bool_array_test.go index 64df51a18c..7f1664a30d 100644 --- a/tests/integration/schema/updates/add/field/kind/bool_array_test.go +++ b/tests/integration/schema/updates/add/field/kind/bool_array_test.go @@ -41,7 +41,9 @@ func TestSchemaUpdatesAddFieldKindBoolArray(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -80,10 +82,12 @@ func TestSchemaUpdatesAddFieldKindBoolArrayWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": []bool{true, false, true}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": []bool{true, false, true}, + }, }, }, }, @@ -124,10 +128,12 @@ func TestSchemaUpdatesAddFieldKindBoolArraySubstitutionWithCreate(t *testing.T) foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": []bool{true, false, true}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": []bool{true, false, true}, + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/kind/bool_nil_array_test.go b/tests/integration/schema/updates/add/field/kind/bool_nil_array_test.go index 899d0cba36..b6de79d1f9 100644 --- a/tests/integration/schema/updates/add/field/kind/bool_nil_array_test.go +++ b/tests/integration/schema/updates/add/field/kind/bool_nil_array_test.go @@ -43,7 +43,9 @@ func TestSchemaUpdatesAddFieldKindNillableBoolArray(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -82,10 +84,12 @@ func TestSchemaUpdatesAddFieldKindNillableBoolArrayWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": []immutable.Option[bool]{immutable.Some(true), immutable.Some(false), immutable.None[bool]()}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": []immutable.Option[bool]{immutable.Some(true), immutable.Some(false), immutable.None[bool]()}, + }, }, }, }, @@ -126,10 +130,12 @@ func TestSchemaUpdatesAddFieldKindNillableBoolArraySubstitutionWithCreate(t *tes foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": []immutable.Option[bool]{immutable.Some(true), immutable.Some(false), immutable.None[bool]()}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": []immutable.Option[bool]{immutable.Some(true), immutable.Some(false), immutable.None[bool]()}, + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/kind/bool_test.go b/tests/integration/schema/updates/add/field/kind/bool_test.go index c77d187dbb..a06f111237 100644 --- a/tests/integration/schema/updates/add/field/kind/bool_test.go +++ b/tests/integration/schema/updates/add/field/kind/bool_test.go @@ -41,7 +41,9 @@ func TestSchemaUpdatesAddFieldKindBool(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -80,10 +82,12 @@ func TestSchemaUpdatesAddFieldKindBoolWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": true, + }, }, }, }, @@ -124,10 +128,12 @@ func TestSchemaUpdatesAddFieldKindBoolSubstitutionWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": true, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": true, + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/kind/datetime_test.go b/tests/integration/schema/updates/add/field/kind/datetime_test.go index a9ee10a2de..662ae96919 100644 --- a/tests/integration/schema/updates/add/field/kind/datetime_test.go +++ b/tests/integration/schema/updates/add/field/kind/datetime_test.go @@ -41,7 +41,9 @@ func TestSchemaUpdatesAddFieldKindDateTime(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -80,10 +82,12 @@ func TestSchemaUpdatesAddFieldKindDateTimeWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": testUtils.MustParseTime("2017-07-23T03:46:56-05:00"), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": testUtils.MustParseTime("2017-07-23T03:46:56-05:00"), + }, }, }, }, @@ -124,10 +128,12 @@ func TestSchemaUpdatesAddFieldKindDateTimeSubstitutionWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": testUtils.MustParseTime("2017-07-23T03:46:56-05:00"), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": testUtils.MustParseTime("2017-07-23T03:46:56-05:00"), + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/kind/doc_id_test.go b/tests/integration/schema/updates/add/field/kind/doc_id_test.go index edac43150f..be62192a1f 100644 --- a/tests/integration/schema/updates/add/field/kind/doc_id_test.go +++ b/tests/integration/schema/updates/add/field/kind/doc_id_test.go @@ -41,7 +41,9 @@ func TestSchemaUpdatesAddFieldKindDocID(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -80,10 +82,12 @@ func TestSchemaUpdatesAddFieldKindDocIDWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": "nhgfdsfd", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": "nhgfdsfd", + }, }, }, }, @@ -124,10 +128,12 @@ func TestSchemaUpdatesAddFieldKindDocIDSubstitutionWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": "nhgfdsfd", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": "nhgfdsfd", + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/kind/float_array_test.go b/tests/integration/schema/updates/add/field/kind/float_array_test.go index dcf9fd3d42..76d4c2fa67 100644 --- a/tests/integration/schema/updates/add/field/kind/float_array_test.go +++ b/tests/integration/schema/updates/add/field/kind/float_array_test.go @@ -41,7 +41,9 @@ func TestSchemaUpdatesAddFieldKindFloatArray(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -80,10 +82,12 @@ func TestSchemaUpdatesAddFieldKindFloatArrayWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": []float64{3.1, -8.1, 0}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": []float64{3.1, -8.1, 0}, + }, }, }, }, @@ -124,10 +128,12 @@ func TestSchemaUpdatesAddFieldKindFloatArraySubstitutionWithCreate(t *testing.T) foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": []float64{3.1, -8.1, 0}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": []float64{3.1, -8.1, 0}, + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/kind/float_nil_array_test.go b/tests/integration/schema/updates/add/field/kind/float_nil_array_test.go index 9dd4209a38..721dfcc3db 100644 --- a/tests/integration/schema/updates/add/field/kind/float_nil_array_test.go +++ b/tests/integration/schema/updates/add/field/kind/float_nil_array_test.go @@ -43,7 +43,9 @@ func TestSchemaUpdatesAddFieldKindNillableFloatArray(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -82,13 +84,15 @@ func TestSchemaUpdatesAddFieldKindNillableFloatArrayWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": []immutable.Option[float64]{ - immutable.Some(3.14), - immutable.Some(-5.77), - immutable.None[float64](), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": []immutable.Option[float64]{ + immutable.Some(3.14), + immutable.Some(-5.77), + immutable.None[float64](), + }, }, }, }, @@ -130,13 +134,15 @@ func TestSchemaUpdatesAddFieldKindNillableFloatArraySubstitutionWithCreate(t *te foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": []immutable.Option[float64]{ - immutable.Some(3.14), - immutable.Some(-5.77), - immutable.None[float64](), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": []immutable.Option[float64]{ + immutable.Some(3.14), + immutable.Some(-5.77), + immutable.None[float64](), + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/kind/float_test.go b/tests/integration/schema/updates/add/field/kind/float_test.go index b145d4c148..12c97bb107 100644 --- a/tests/integration/schema/updates/add/field/kind/float_test.go +++ b/tests/integration/schema/updates/add/field/kind/float_test.go @@ -41,7 +41,9 @@ func TestSchemaUpdatesAddFieldKindFloat(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -80,10 +82,12 @@ func TestSchemaUpdatesAddFieldKindFloatWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": float64(3), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": float64(3), + }, }, }, }, @@ -124,10 +128,12 @@ func TestSchemaUpdatesAddFieldKindFloatSubstitutionWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": float64(3), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": float64(3), + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/kind/foreign_object_test.go b/tests/integration/schema/updates/add/field/kind/foreign_object_test.go index 9b18500446..6b544d6713 100644 --- a/tests/integration/schema/updates/add/field/kind/foreign_object_test.go +++ b/tests/integration/schema/updates/add/field/kind/foreign_object_test.go @@ -163,15 +163,17 @@ func TestSchemaUpdatesAddFieldKindForeignObject_Succeeds(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": nil, - }, - { - "name": "Keenan", - "foo": map[string]any{ + Results: map[string]any{ + "Users": []map[string]any{ + { "name": "John", + "foo": nil, + }, + { + "name": "Keenan", + "foo": map[string]any{ + "name": "John", + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/kind/int_array_test.go b/tests/integration/schema/updates/add/field/kind/int_array_test.go index 9a6d9e69af..5d9d8a8342 100644 --- a/tests/integration/schema/updates/add/field/kind/int_array_test.go +++ b/tests/integration/schema/updates/add/field/kind/int_array_test.go @@ -41,7 +41,9 @@ func TestSchemaUpdatesAddFieldKindIntArray(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -80,10 +82,12 @@ func TestSchemaUpdatesAddFieldKindIntArrayWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": []int64{3, 5, 8}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": []int64{3, 5, 8}, + }, }, }, }, @@ -124,10 +128,12 @@ func TestSchemaUpdatesAddFieldKindIntArraySubstitutionWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": []int64{3, 5, 8}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": []int64{3, 5, 8}, + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/kind/int_nil_array_test.go b/tests/integration/schema/updates/add/field/kind/int_nil_array_test.go index 0de26958bb..30e05f38ac 100644 --- a/tests/integration/schema/updates/add/field/kind/int_nil_array_test.go +++ b/tests/integration/schema/updates/add/field/kind/int_nil_array_test.go @@ -43,7 +43,9 @@ func TestSchemaUpdatesAddFieldKindNillableIntArray(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -82,13 +84,15 @@ func TestSchemaUpdatesAddFieldKindNillableIntArrayWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": []immutable.Option[int64]{ - immutable.Some[int64](3), - immutable.Some[int64](-5), - immutable.None[int64](), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": []immutable.Option[int64]{ + immutable.Some[int64](3), + immutable.Some[int64](-5), + immutable.None[int64](), + }, }, }, }, @@ -130,13 +134,15 @@ func TestSchemaUpdatesAddFieldKindNillableIntArraySubstitutionWithCreate(t *test foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": []immutable.Option[int64]{ - immutable.Some[int64](3), - immutable.Some[int64](-5), - immutable.None[int64](), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": []immutable.Option[int64]{ + immutable.Some[int64](3), + immutable.Some[int64](-5), + immutable.None[int64](), + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/kind/int_test.go b/tests/integration/schema/updates/add/field/kind/int_test.go index 70b3294a84..0cf0011b87 100644 --- a/tests/integration/schema/updates/add/field/kind/int_test.go +++ b/tests/integration/schema/updates/add/field/kind/int_test.go @@ -41,7 +41,9 @@ func TestSchemaUpdatesAddFieldKindInt(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -80,10 +82,12 @@ func TestSchemaUpdatesAddFieldKindIntWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": int64(3), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": int64(3), + }, }, }, }, @@ -124,10 +128,12 @@ func TestSchemaUpdatesAddFieldKindIntSubstitutionWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": int64(3), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": int64(3), + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/kind/json_test.go b/tests/integration/schema/updates/add/field/kind/json_test.go index 37e2886a58..371e12d074 100644 --- a/tests/integration/schema/updates/add/field/kind/json_test.go +++ b/tests/integration/schema/updates/add/field/kind/json_test.go @@ -41,7 +41,9 @@ func TestSchemaUpdatesAddFieldKindJSON(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -80,10 +82,12 @@ func TestSchemaUpdatesAddFieldKindJSONWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": "{}", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": "{}", + }, }, }, }, @@ -124,10 +128,12 @@ func TestSchemaUpdatesAddFieldKindJSONSubstitutionWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": "{}", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": "{}", + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/kind/string_array_test.go b/tests/integration/schema/updates/add/field/kind/string_array_test.go index b035162aed..4da57d15e1 100644 --- a/tests/integration/schema/updates/add/field/kind/string_array_test.go +++ b/tests/integration/schema/updates/add/field/kind/string_array_test.go @@ -41,7 +41,9 @@ func TestSchemaUpdatesAddFieldKindStringArray(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -80,10 +82,12 @@ func TestSchemaUpdatesAddFieldKindStringArrayWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": []string{"bar", "pub", "inn", "out", "hokey", "cokey", "pepsi", "beer", "bar", "pub", "..."}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": []string{"bar", "pub", "inn", "out", "hokey", "cokey", "pepsi", "beer", "bar", "pub", "..."}, + }, }, }, }, @@ -124,10 +128,12 @@ func TestSchemaUpdatesAddFieldKindStringArraySubstitutionWithCreate(t *testing.T foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": []string{"bar", "pub", "inn", "out", "hokey", "cokey", "pepsi", "beer", "bar", "pub", "..."}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": []string{"bar", "pub", "inn", "out", "hokey", "cokey", "pepsi", "beer", "bar", "pub", "..."}, + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/kind/string_nil_array_test.go b/tests/integration/schema/updates/add/field/kind/string_nil_array_test.go index 9fc750cc80..0cec4880a9 100644 --- a/tests/integration/schema/updates/add/field/kind/string_nil_array_test.go +++ b/tests/integration/schema/updates/add/field/kind/string_nil_array_test.go @@ -43,7 +43,9 @@ func TestSchemaUpdatesAddFieldKindNillableStringArray(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -82,13 +84,15 @@ func TestSchemaUpdatesAddFieldKindNillableStringArrayWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": []immutable.Option[string]{ - immutable.Some("hello"), - immutable.Some("پدر سگ"), - immutable.None[string](), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": []immutable.Option[string]{ + immutable.Some("hello"), + immutable.Some("پدر سگ"), + immutable.None[string](), + }, }, }, }, @@ -130,13 +134,15 @@ func TestSchemaUpdatesAddFieldKindNillableStringArraySubstitutionWithCreate(t *t foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": []immutable.Option[string]{ - immutable.Some("hello"), - immutable.Some("پدر سگ"), - immutable.None[string](), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": []immutable.Option[string]{ + immutable.Some("hello"), + immutable.Some("پدر سگ"), + immutable.None[string](), + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/kind/string_test.go b/tests/integration/schema/updates/add/field/kind/string_test.go index 336c2fe6de..dadb59d09f 100644 --- a/tests/integration/schema/updates/add/field/kind/string_test.go +++ b/tests/integration/schema/updates/add/field/kind/string_test.go @@ -41,7 +41,9 @@ func TestSchemaUpdatesAddFieldKindString(t *testing.T) { foo } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -80,10 +82,12 @@ func TestSchemaUpdatesAddFieldKindStringWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": "bar", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": "bar", + }, }, }, }, @@ -124,10 +128,12 @@ func TestSchemaUpdatesAddFieldKindStringSubstitutionWithCreate(t *testing.T) { foo } }`, - Results: []map[string]any{ - { - "name": "John", - "foo": "bar", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "foo": "bar", + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/simple_test.go b/tests/integration/schema/updates/add/field/simple_test.go index d315791dfa..a958bea6a4 100644 --- a/tests/integration/schema/updates/add/field/simple_test.go +++ b/tests/integration/schema/updates/add/field/simple_test.go @@ -47,7 +47,9 @@ func TestSchemaUpdatesAddFieldSimple(t *testing.T) { email } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, testUtils.GetSchema{ VersionID: immutable.Some(schemaVersion2ID), @@ -195,7 +197,9 @@ func TestSchemaUpdatesAddFieldSimpleErrorsAddingToUnknownCollection(t *testing.T name } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -229,7 +233,9 @@ func TestSchemaUpdatesAddFieldMultipleInPatch(t *testing.T) { city } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -269,7 +275,9 @@ func TestSchemaUpdatesAddFieldMultiplePatches(t *testing.T) { city } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -338,7 +346,9 @@ func TestSchemaUpdatesAddFieldMultipleInPatchPartialSuccess(t *testing.T) { name } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/schema/updates/add/field/with_filter_test.go b/tests/integration/schema/updates/add/field/with_filter_test.go index 6161d9a237..a1b4679a66 100644 --- a/tests/integration/schema/updates/add/field/with_filter_test.go +++ b/tests/integration/schema/updates/add/field/with_filter_test.go @@ -40,7 +40,9 @@ func TestSchemaUpdatesAddFieldSimpleWithFilter(t *testing.T) { name } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -80,9 +82,11 @@ func TestSchemaUpdatesAddFieldSimpleWithFilterOnPopulatedDatabase(t *testing.T) name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + }, }, }, }, diff --git a/tests/integration/schema/updates/add/field/with_index_sub_test.go b/tests/integration/schema/updates/add/field/with_index_sub_test.go index 274e3aac2b..3ddb4a1b9f 100644 --- a/tests/integration/schema/updates/add/field/with_index_sub_test.go +++ b/tests/integration/schema/updates/add/field/with_index_sub_test.go @@ -41,7 +41,9 @@ func TestSchemaUpdatesAddFieldSimple_FieldIndexedByName(t *testing.T) { email } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -73,7 +75,9 @@ func TestSchemaUpdatesAddFieldSimple_FieldIndexedByNameWithSameNameDefinedInValu email } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -130,7 +134,9 @@ func TestSchemaUpdatesAddFieldSimple_FieldIndexedByNameMultipleTimes(t *testing. email } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/schema/updates/add/field/with_index_test.go b/tests/integration/schema/updates/add/field/with_index_test.go index 52815789f8..e7981495f7 100644 --- a/tests/integration/schema/updates/add/field/with_index_test.go +++ b/tests/integration/schema/updates/add/field/with_index_test.go @@ -43,7 +43,9 @@ func TestSchemaUpdatesAddFieldSimple_WithExistingIndex(t *testing.T) { email } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/schema/updates/add/simple_test.go b/tests/integration/schema/updates/add/simple_test.go index 65d04a7af6..18fbcdf138 100644 --- a/tests/integration/schema/updates/add/simple_test.go +++ b/tests/integration/schema/updates/add/simple_test.go @@ -41,7 +41,9 @@ func TestSchemaUpdatesAddSimpleErrorsAddingSchema(t *testing.T) { name } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -121,7 +123,9 @@ func TestSchemaUpdatesAddSimpleErrorsAddingUnsupportedCollectionProp(t *testing. name } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -153,7 +157,9 @@ func TestSchemaUpdatesAddSimpleErrorsAddingUnsupportedSchemaProp(t *testing.T) { name } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/schema/updates/copy/field/simple_test.go b/tests/integration/schema/updates/copy/field/simple_test.go index 5baf640ab8..1e380fbd7c 100644 --- a/tests/integration/schema/updates/copy/field/simple_test.go +++ b/tests/integration/schema/updates/copy/field/simple_test.go @@ -43,7 +43,9 @@ func TestSchemaUpdatesCopyFieldErrors(t *testing.T) { email } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -80,7 +82,9 @@ func TestSchemaUpdatesCopyFieldWithAndReplaceName(t *testing.T) { fax } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } @@ -124,11 +128,13 @@ func TestSchemaUpdatesCopyFieldWithReplaceNameAndKindSubstitution(t *testing.T) age } }`, - Results: []map[string]any{ - { - "name": "John", - // It is important to test this with data, to ensure the type has been substituted correctly - "age": int64(3), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + // It is important to test this with data, to ensure the type has been substituted correctly + "age": int64(3), + }, }, }, }, diff --git a/tests/integration/schema/updates/move/simple_test.go b/tests/integration/schema/updates/move/simple_test.go index 9898430e0f..1053438aa7 100644 --- a/tests/integration/schema/updates/move/simple_test.go +++ b/tests/integration/schema/updates/move/simple_test.go @@ -58,9 +58,11 @@ func TestSchemaUpdatesMoveCollectionDoesNothing(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "Johnnn", + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Johnnn", + }, }, }, }, @@ -71,14 +73,16 @@ func TestSchemaUpdatesMoveCollectionDoesNothing(t *testing.T) { schemaVersionId } }`, - Results: []map[string]any{ - { - // Update commit - "schemaVersionId": schemaVersionID, - }, - { - // Create commit - "schemaVersionId": schemaVersionID, + Results: map[string]any{ + "commits": []map[string]any{ + { + // Update commit + "schemaVersionId": schemaVersionID, + }, + { + // Create commit + "schemaVersionId": schemaVersionID, + }, }, }, }, diff --git a/tests/integration/schema/updates/remove/simple_test.go b/tests/integration/schema/updates/remove/simple_test.go index d0343484e5..6628ccde86 100644 --- a/tests/integration/schema/updates/remove/simple_test.go +++ b/tests/integration/schema/updates/remove/simple_test.go @@ -93,7 +93,9 @@ func TestSchemaUpdatesRemoveSchemaVersionIDErrors(t *testing.T) { email } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/schema/updates/test/add_field_test.go b/tests/integration/schema/updates/test/add_field_test.go index 31eec344f2..f75acc7795 100644 --- a/tests/integration/schema/updates/test/add_field_test.go +++ b/tests/integration/schema/updates/test/add_field_test.go @@ -42,7 +42,9 @@ func TestSchemaUpdatesTestAddField(t *testing.T) { email } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/schema/updates/with_schema_branch_test.go b/tests/integration/schema/updates/with_schema_branch_test.go index 58759f3edd..312cb34d2a 100644 --- a/tests/integration/schema/updates/with_schema_branch_test.go +++ b/tests/integration/schema/updates/with_schema_branch_test.go @@ -98,7 +98,9 @@ func TestSchemaUpdates_WithBranchingSchema(t *testing.T) { phone } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, testUtils.GetSchema{ // The third schema version is present in the system, with the phone field @@ -220,7 +222,9 @@ func TestSchemaUpdates_WithPatchOnBranchedSchema(t *testing.T) { discordName } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, testUtils.GetSchema{ // The fourth schema version is present in the system, with the phone and discordName field @@ -351,7 +355,9 @@ func TestSchemaUpdates_WithBranchingSchemaAndSetActiveSchemaToOtherBranch(t *tes } }`, // The email field is queriable - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, testUtils.Request{ Request: `query { @@ -458,7 +464,9 @@ func TestSchemaUpdates_WithBranchingSchemaAndSetActiveSchemaToOtherBranchThenPat discordName } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, testUtils.GetSchema{ // The fourth schema version is present in the system, with the email and discordName field diff --git a/tests/integration/schema/with_update_set_default_test.go b/tests/integration/schema/with_update_set_default_test.go index 22f05a4d73..3cc2a7cf9a 100644 --- a/tests/integration/schema/with_update_set_default_test.go +++ b/tests/integration/schema/with_update_set_default_test.go @@ -138,7 +138,9 @@ func TestSchema_WithUpdateAndSetDefaultVersionToNew_AllowsQueryingOfNewField(t * email } }`, - Results: []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, } diff --git a/tests/integration/subscription/subscription_test.go b/tests/integration/subscription/subscription_test.go index dc7a91d7c6..1a844f6e16 100644 --- a/tests/integration/subscription/subscription_test.go +++ b/tests/integration/subscription/subscription_test.go @@ -28,19 +28,23 @@ func TestSubscriptionWithCreateMutations(t *testing.T) { age } }`, - Results: [][]map[string]any{ + Results: []map[string]any{ { - { - "_docID": "bae-b3ce089b-f543-5984-be9f-ad7d08969f4e", - "age": int64(27), - "name": "John", + "User": []map[string]any{ + { + "_docID": "bae-b3ce089b-f543-5984-be9f-ad7d08969f4e", + "age": int64(27), + "name": "John", + }, }, }, { - { - "_docID": "bae-bc20b854-10b3-5408-b28c-f273ddda9434", - "age": int64(31), - "name": "Addo", + "User": []map[string]any{ + { + "_docID": "bae-bc20b854-10b3-5408-b28c-f273ddda9434", + "age": int64(31), + "name": "Addo", + }, }, }, }, @@ -51,9 +55,11 @@ func TestSubscriptionWithCreateMutations(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "create_User": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -63,9 +69,11 @@ func TestSubscriptionWithCreateMutations(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "Addo", + Results: map[string]any{ + "create_User": []map[string]any{ + { + "name": "Addo", + }, }, }, }, @@ -86,11 +94,13 @@ func TestSubscriptionWithFilterAndOneCreateMutation(t *testing.T) { age } }`, - Results: [][]map[string]any{ + Results: []map[string]any{ { - { - "age": int64(27), - "name": "John", + "User": []map[string]any{ + { + "age": int64(27), + "name": "John", + }, }, }, }, @@ -101,9 +111,11 @@ func TestSubscriptionWithFilterAndOneCreateMutation(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "create_User": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -125,7 +137,7 @@ func TestSubscriptionWithFilterAndOneCreateMutationOutsideFilter(t *testing.T) { age } }`, - Results: [][]map[string]any{}, + Results: []map[string]any{}, }, testUtils.Request{ Request: `mutation { @@ -133,9 +145,11 @@ func TestSubscriptionWithFilterAndOneCreateMutationOutsideFilter(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "create_User": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -156,11 +170,13 @@ func TestSubscriptionWithFilterAndCreateMutations(t *testing.T) { age } }`, - Results: [][]map[string]any{ + Results: []map[string]any{ { - { - "age": int64(27), - "name": "John", + "User": []map[string]any{ + { + "age": int64(27), + "name": "John", + }, }, }, }, @@ -171,9 +187,11 @@ func TestSubscriptionWithFilterAndCreateMutations(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "create_User": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -183,9 +201,11 @@ func TestSubscriptionWithFilterAndCreateMutations(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "Addo", + Results: map[string]any{ + "create_User": []map[string]any{ + { + "name": "Addo", + }, }, }, }, @@ -225,12 +245,14 @@ func TestSubscriptionWithUpdateMutations(t *testing.T) { points } }`, - Results: [][]map[string]any{ + Results: []map[string]any{ { - { - "age": int64(27), - "name": "John", - "points": float64(45), + "User": []map[string]any{ + { + "age": int64(27), + "name": "John", + "points": float64(45), + }, }, }, }, @@ -241,9 +263,11 @@ func TestSubscriptionWithUpdateMutations(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "update_User": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -283,19 +307,23 @@ func TestSubscriptionWithUpdateAllMutations(t *testing.T) { points } }`, - Results: [][]map[string]any{ + Results: []map[string]any{ { - { - "age": int64(31), - "name": "Addo", - "points": float64(55), + "User": []map[string]any{ + { + "age": int64(31), + "name": "Addo", + "points": float64(55), + }, }, }, { - { - "age": int64(27), - "name": "John", - "points": float64(55), + "User": []map[string]any{ + { + "age": int64(27), + "name": "John", + "points": float64(55), + }, }, }, }, @@ -306,12 +334,14 @@ func TestSubscriptionWithUpdateAllMutations(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "Addo", - }, - { - "name": "John", + Results: map[string]any{ + "update_User": []map[string]any{ + { + "name": "Addo", + }, + { + "name": "John", + }, }, }, }, diff --git a/tests/integration/test_case.go b/tests/integration/test_case.go index a384318dd2..689b8cb815 100644 --- a/tests/integration/test_case.go +++ b/tests/integration/test_case.go @@ -487,13 +487,13 @@ type GetIndexes struct { // assertions. type ResultAsserter interface { // Assert will be called with the test and the result of the request. - Assert(t testing.TB, result []map[string]any) + Assert(t testing.TB, result map[string]any) } // ResultAsserterFunc is a function that can be used to implement the ResultAsserter -type ResultAsserterFunc func(testing.TB, []map[string]any) (bool, string) +type ResultAsserterFunc func(testing.TB, map[string]any) (bool, string) -func (f ResultAsserterFunc) Assert(t testing.TB, result []map[string]any) { +func (f ResultAsserterFunc) Assert(t testing.TB, result map[string]any) { f(t, result) } @@ -536,7 +536,7 @@ type Request struct { Request string // The expected (data) results of the issued request. - Results []map[string]any + Results map[string]any // Asserter is an optional custom result asserter. Asserter ResultAsserter @@ -616,7 +616,7 @@ type SubscriptionRequest struct { Request string // The expected (data) results yielded through the subscription across its lifetime. - Results [][]map[string]any + Results []map[string]any // Any error expected from the action. Optional. // diff --git a/tests/integration/utils.go b/tests/integration/utils.go index b530f45920..14f20b494d 100644 --- a/tests/integration/utils.go +++ b/tests/integration/utils.go @@ -22,7 +22,7 @@ type RequestTestCase struct { // of docs in stringified JSON format Docs map[int][]string - Results []map[string]any + Results map[string]any // The expected content of an expected error ExpectedError string diff --git a/tests/integration/utils2.go b/tests/integration/utils2.go index a9bd8aa4c3..f26ee4ed5b 100644 --- a/tests/integration/utils2.go +++ b/tests/integration/utils2.go @@ -1272,15 +1272,8 @@ func createDocViaGQL( strings.Join(action.EncryptedFields, ", ") + "]" } - req := fmt.Sprintf( - `mutation { - create_%s(%s) { - _docID - } - }`, - collection.Name().Value(), - params, - ) + key := fmt.Sprintf("create_%s", collection.Name().Value()) + req := fmt.Sprintf(`mutation { %s(%s) { _docID } }`, key, params) txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) ctx := db.SetContextIdentity(db.SetContextTxn(s.ctx, txn), getIdentity(s, nodeIndex, action.Identity)) @@ -1290,13 +1283,11 @@ func createDocViaGQL( return nil, result.GQL.Errors[0] } - resultantDocs, ok := result.GQL.Data.([]map[string]any) - if !ok || len(resultantDocs) == 0 { - return nil, nil - } + resultData := result.GQL.Data.(map[string]any) + resultDocs := ConvertToArrayOfMaps(s.t, resultData[key]) - docIDs := make([]client.DocID, len(resultantDocs)) - for i, docMap := range resultantDocs { + docIDs := make([]client.DocID, len(resultDocs)) + for i, docMap := range resultDocs { docIDString := docMap[request.DocIDFieldName].(string) docID, err := client.NewDocIDFromString(docIDString) require.NoError(s.t, err) @@ -1842,7 +1833,7 @@ type docFieldKey struct { func assertRequestResults( s *state, result *client.GQLResult, - expectedResults []map[string]any, + expectedResults map[string]any, expectedError string, asserter ResultAsserter, nodeID int, @@ -1858,16 +1849,51 @@ func assertRequestResults( } // Note: if result.Data == nil this panics (the panic seems useful while testing). - resultantData := result.Data.([]map[string]any) + resultantData := result.Data.(map[string]any) + log.InfoContext(s.ctx, "", corelog.Any("RequestResults", result.Data)) if asserter != nil { asserter.Assert(s.t, resultantData) return true } - log.InfoContext(s.ctx, "", corelog.Any("RequestResults", result.Data)) + // merge all keys so we can check for missing values + keys := make(map[string]struct{}) + for key := range resultantData { + keys[key] = struct{}{} + } + for key := range expectedResults { + keys[key] = struct{}{} + } + + for key := range keys { + expect, ok := expectedResults[key] + require.True(s.t, ok, "expected key not found: %s", key) + + actual, ok := resultantData[key] + require.True(s.t, ok, "result key not found: %s", key) + + expectDocs, ok := expect.([]map[string]any) + if ok { + actualDocs := ConvertToArrayOfMaps(s.t, actual) + assertRequestResultDocs( + s, + nodeID, + expectDocs, + actualDocs, + anyOfByField) + } else { + assertResultsEqual( + s.t, + s.clientType, + expect, + actual, + fmt.Sprintf("node: %v, key: %v", nodeID, key), + ) + } + } - return assertRequestResultDocs(s, nodeID, expectedResults, resultantData, anyOfByField) + return false } func assertRequestResultDocs( @@ -1914,7 +1940,7 @@ func assertRequestResultDocs( fmt.Sprintf("node: %v, doc: %v", nodeID, actualDocIndex), ) case []map[string]any: - actualValueMap := convertToArrayOfMaps(s.t, actualValue) + actualValueMap := ConvertToArrayOfMaps(s.t, actualValue) assertRequestResultDocs( s, @@ -1939,7 +1965,7 @@ func assertRequestResultDocs( return false } -func convertToArrayOfMaps(t testing.TB, value any) []map[string]any { +func ConvertToArrayOfMaps(t testing.TB, value any) []map[string]any { valueArrayMap, ok := value.([]map[string]any) if ok { return valueArrayMap diff --git a/tests/integration/view/one_to_many/simple_test.go b/tests/integration/view/one_to_many/simple_test.go index 9c846b6ba0..2f66c6ee50 100644 --- a/tests/integration/view/one_to_many/simple_test.go +++ b/tests/integration/view/one_to_many/simple_test.go @@ -73,12 +73,14 @@ func TestView_OneToMany(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Harper Lee", - "books": []map[string]any{ - { - "name": "To Kill a Mockingbird", + Results: map[string]any{ + "AuthorView": []map[string]any{ + { + "name": "Harper Lee", + "books": []map[string]any{ + { + "name": "To Kill a Mockingbird", + }, }, }, }, @@ -291,9 +293,11 @@ func TestView_OneToManyWithRelationInQueryButNotInSDL(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "Harper Lee", + Results: map[string]any{ + "AuthorView": []map[string]any{ + { + "name": "Harper Lee", + }, }, }, }, @@ -439,12 +443,14 @@ func TestView_OneToManyWithDoubleSidedRelation_Errors(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "name": "Harper Lee", - "books": []map[string]any{ - { - "name": "To Kill a Mockingbird", + Results: map[string]any{ + "AuthorViewView": []map[string]any{ + { + "name": "Harper Lee", + "books": []map[string]any{ + { + "name": "To Kill a Mockingbird", + }, }, }, }, diff --git a/tests/integration/view/one_to_many/with_alias_test.go b/tests/integration/view/one_to_many/with_alias_test.go index bfd6e443d9..29101fbc63 100644 --- a/tests/integration/view/one_to_many/with_alias_test.go +++ b/tests/integration/view/one_to_many/with_alias_test.go @@ -73,12 +73,14 @@ func TestView_OneToManyWithAliasOnOuter(t *testing.T) { } } }`, - Results: []map[string]any{ - { - "fullName": "Harper Lee", - "books": []map[string]any{ - { - "name": "To Kill a Mockingbird", + Results: map[string]any{ + "AuthorView": []map[string]any{ + { + "fullName": "Harper Lee", + "books": []map[string]any{ + { + "name": "To Kill a Mockingbird", + }, }, }, }, @@ -149,12 +151,14 @@ func TestView_OneToManyWithAliasOnInner(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "Harper Lee", - "books": []map[string]any{ - { - "fullName": "To Kill a Mockingbird", + Results: map[string]any{ + "AuthorView": []map[string]any{ + { + "name": "Harper Lee", + "books": []map[string]any{ + { + "fullName": "To Kill a Mockingbird", + }, }, }, }, diff --git a/tests/integration/view/one_to_many/with_count_test.go b/tests/integration/view/one_to_many/with_count_test.go index 2fa06d9aec..a679c53f6b 100644 --- a/tests/integration/view/one_to_many/with_count_test.go +++ b/tests/integration/view/one_to_many/with_count_test.go @@ -143,10 +143,12 @@ func TestView_OneToManyWithAliasedCount(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "Harper Lee", - "numberOfBooks": 2, + Results: map[string]any{ + "AuthorView": []map[string]any{ + { + "name": "Harper Lee", + "numberOfBooks": 2, + }, }, }, }, @@ -199,9 +201,11 @@ func TestView_OneToManyWithCountInQueryButNotSDL(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "Harper Lee", + Results: map[string]any{ + "AuthorView": []map[string]any{ + { + "name": "Harper Lee", + }, }, }, }, diff --git a/tests/integration/view/one_to_many/with_transform_test.go b/tests/integration/view/one_to_many/with_transform_test.go index 13ef4f19c6..f0ceeee197 100644 --- a/tests/integration/view/one_to_many/with_transform_test.go +++ b/tests/integration/view/one_to_many/with_transform_test.go @@ -92,12 +92,14 @@ func TestView_OneToManyWithTransformOnOuter(t *testing.T) { } } `, - Results: []map[string]any{ - { - "fullName": "Ferdowsi", - "books": []any{ - map[string]any{ - "name": "Shahnameh", + Results: map[string]any{ + "AuthorView": []map[string]any{ + { + "fullName": "Ferdowsi", + "books": []any{ + map[string]any{ + "name": "Shahnameh", + }, }, }, }, @@ -171,15 +173,17 @@ func TestView_OneToManyWithTransformAddingInnerDocs(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "Ferdowsi", - "books": []any{ - map[string]any{ - "name": "The Tragedy of Sohrab and Rostam", - }, - map[string]any{ - "name": "The Legend of Seyavash", + Results: map[string]any{ + "AuthorView": []map[string]any{ + { + "name": "Ferdowsi", + "books": []any{ + map[string]any{ + "name": "The Tragedy of Sohrab and Rostam", + }, + map[string]any{ + "name": "The Legend of Seyavash", + }, }, }, }, diff --git a/tests/integration/view/one_to_one/identical_schema_test.go b/tests/integration/view/one_to_one/identical_schema_test.go index ec83cd81cc..aab5cedbbf 100644 --- a/tests/integration/view/one_to_one/identical_schema_test.go +++ b/tests/integration/view/one_to_one/identical_schema_test.go @@ -77,11 +77,13 @@ func TestView_OneToOneSameSchema(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "Left hand 1", - "heldBy": map[string]any{ - "name": "Right hand 1", + Results: map[string]any{ + "HandView": []map[string]any{ + { + "name": "Left hand 1", + "heldBy": map[string]any{ + "name": "Right hand 1", + }, }, }, }, diff --git a/tests/integration/view/one_to_one/with_transform_test.go b/tests/integration/view/one_to_one/with_transform_test.go index d4270b454d..8fcee174f3 100644 --- a/tests/integration/view/one_to_one/with_transform_test.go +++ b/tests/integration/view/one_to_one/with_transform_test.go @@ -92,11 +92,13 @@ func TestView_OneToOneWithTransformOnOuter(t *testing.T) { } } `, - Results: []map[string]any{ - { - "fullName": "Ferdowsi", - "book": map[string]any{ - "name": "Shahnameh", + Results: map[string]any{ + "AuthorView": []map[string]any{ + { + "fullName": "Ferdowsi", + "book": map[string]any{ + "name": "Shahnameh", + }, }, }, }, diff --git a/tests/integration/view/simple/simple_test.go b/tests/integration/view/simple/simple_test.go index df9ef60379..df811a528f 100644 --- a/tests/integration/view/simple/simple_test.go +++ b/tests/integration/view/simple/simple_test.go @@ -50,9 +50,11 @@ func TestView_Simple(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "UserView": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -101,12 +103,14 @@ func TestView_SimpleMultipleDocs(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", - }, - { - "name": "Fred", + Results: map[string]any{ + "UserView": []map[string]any{ + { + "name": "John", + }, + { + "name": "Fred", + }, }, }, }, @@ -198,9 +202,11 @@ func TestView_SimpleWithExtraFieldInViewSDL(t *testing.T) { name } }`, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "UserView": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -249,9 +255,11 @@ func TestView_SimpleWithExtraFieldInViewQuery(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "UserView": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -309,9 +317,11 @@ func TestView_SimpleViewOfView(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "UserViewView": []map[string]any{ + { + "name": "John", + }, }, }, }, diff --git a/tests/integration/view/simple/with_alias_test.go b/tests/integration/view/simple/with_alias_test.go index 0fd7e29db9..b7818e25be 100644 --- a/tests/integration/view/simple/with_alias_test.go +++ b/tests/integration/view/simple/with_alias_test.go @@ -52,9 +52,11 @@ func TestView_SimpleWithAlias(t *testing.T) { } } `, - Results: []map[string]any{ - { - "fullname": "John", + Results: map[string]any{ + "UserView": []map[string]any{ + { + "fullname": "John", + }, }, }, }, diff --git a/tests/integration/view/simple/with_filter_test.go b/tests/integration/view/simple/with_filter_test.go index a600a84729..58dfadc926 100644 --- a/tests/integration/view/simple/with_filter_test.go +++ b/tests/integration/view/simple/with_filter_test.go @@ -57,9 +57,11 @@ func TestView_SimpleWithFilter(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "John", + Results: map[string]any{ + "UserView": []map[string]any{ + { + "name": "John", + }, }, }, }, @@ -122,10 +124,12 @@ func TestView_SimpleWithFilterOnViewAndQuery(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "John", - "age": 31, + Results: map[string]any{ + "UserView": []map[string]any{ + { + "name": "John", + "age": 31, + }, }, }, }, diff --git a/tests/integration/view/simple/with_transform_test.go b/tests/integration/view/simple/with_transform_test.go index b6d903a286..118d0b3991 100644 --- a/tests/integration/view/simple/with_transform_test.go +++ b/tests/integration/view/simple/with_transform_test.go @@ -76,12 +76,14 @@ func TestView_SimpleWithTransform(t *testing.T) { } } `, - Results: []map[string]any{ - { - "fullName": "John", - }, - { - "fullName": "Fred", + Results: map[string]any{ + "UserView": []map[string]any{ + { + "fullName": "John", + }, + { + "fullName": "Fred", + }, }, }, }, @@ -157,14 +159,16 @@ func TestView_SimpleWithMultipleTransforms(t *testing.T) { } } `, - Results: []map[string]any{ - { - "fullName": "John", - "age": 23, - }, - { - "fullName": "Fred", - "age": 23, + Results: map[string]any{ + "UserView": []map[string]any{ + { + "fullName": "John", + "age": 23, + }, + { + "fullName": "Fred", + "age": 23, + }, }, }, }, @@ -227,15 +231,17 @@ func TestView_SimpleWithTransformReturningMoreDocsThanInput(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "Fred", - }, - { - "name": "Shahzad", - }, - { - "name": "John", + Results: map[string]any{ + "UserView": []map[string]any{ + { + "name": "Fred", + }, + { + "name": "Shahzad", + }, + { + "name": "John", + }, }, }, }, @@ -307,12 +313,14 @@ func TestView_SimpleWithTransformReturningFewerDocsThanInput(t *testing.T) { } } `, - Results: []map[string]any{ - { - "name": "John", - }, - { - "name": "Shahzad", + Results: map[string]any{ + "UserView": []map[string]any{ + { + "name": "John", + }, + { + "name": "Shahzad", + }, }, }, }, From 6ad8f18ff81b6ff6937f51fcc9a05a50cd69fd88 Mon Sep 17 00:00:00 2001 From: Keenan Nemetz Date: Tue, 30 Jul 2024 14:07:00 -0700 Subject: [PATCH 26/41] fix: Create mutation introspection (#2881) ## Relevant issue(s) Resolves #2868 ## Description This PR fixes the create mutation return type. ## Tasks - [x] I made sure the code is well commented, particularly hard-to-understand areas. - [x] I made sure the repository-held documentation is changed accordingly. - [x] I made sure the pull request title adheres to the conventional commit style (the subset used in the project can be found in [tools/configs/chglog/config.yml](tools/configs/chglog/config.yml)). - [x] I made sure to discuss its limitations such as threats to validity, vulnerability to mistake and misuse, robustness to invalidation of assumptions, resource requirements, ... ## How has this been tested? manually tested in playground Specify the platform(s) on which this was tested: - MacOS --- internal/request/graphql/schema/descriptions.go | 2 +- internal/request/graphql/schema/generate.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/request/graphql/schema/descriptions.go b/internal/request/graphql/schema/descriptions.go index 526e41470e..9fe841c466 100644 --- a/internal/request/graphql/schema/descriptions.go +++ b/internal/request/graphql/schema/descriptions.go @@ -102,7 +102,7 @@ An optional value that specifies as to whether deleted documents may be returned. This argument will propagate down through any child selects/joins. ` createDocumentDescription string = ` -Creates a single document of this type using the data provided. +Creates one or more documents of this type using the data provided. ` updateDocumentsDescription string = ` Updates documents in this collection using the data provided. Only documents diff --git a/internal/request/graphql/schema/generate.go b/internal/request/graphql/schema/generate.go index 22524391fd..4d86a97204 100644 --- a/internal/request/graphql/schema/generate.go +++ b/internal/request/graphql/schema/generate.go @@ -1057,7 +1057,7 @@ func (g *Generator) GenerateMutationInputForGQLType(obj *gql.Object) ([]*gql.Fie create := &gql.Field{ Name: "create_" + obj.Name(), Description: createDocumentDescription, - Type: obj, + Type: gql.NewList(obj), Args: gql.FieldConfigArgument{ request.Input: schemaTypes.NewArgConfig(mutationInput, "Create a "+obj.Name()+" document"), request.Inputs: schemaTypes.NewArgConfig(gql.NewList(gql.NewNonNull(mutationInput)), From 18b3c818b74c7d84217e74cd18cc06247f05e18e Mon Sep 17 00:00:00 2001 From: Keenan Nemetz Date: Mon, 5 Aug 2024 15:19:03 -0700 Subject: [PATCH 27/41] refactor(i): RequestTestCase actions (#2884) ## Relevant issue(s) Resolves #2883 ## Description This PR refactors all `RequestTestCase` actions to use the newer test framework. ## Tasks - [x] I made sure the code is well commented, particularly hard-to-understand areas. - [x] I made sure the repository-held documentation is changed accordingly. - [x] I made sure the pull request title adheres to the conventional commit style (the subset used in the project can be found in [tools/configs/chglog/config.yml](tools/configs/chglog/config.yml)). - [x] I made sure to discuss its limitations such as threats to validity, vulnerability to mistake and misuse, robustness to invalidation of assumptions, resource requirements, ... ## How has this been tested? `make test` Specify the platform(s) on which this was tested: - MacOS --- .../query/inline_array/simple_test.go | 622 ++--- tests/integration/query/inline_array/utils.go | 17 +- .../inline_array/with_average_filter_test.go | 128 +- .../inline_array/with_average_sum_test.go | 34 +- .../query/inline_array/with_average_test.go | 320 +-- .../inline_array/with_count_filter_test.go | 287 ++- .../with_count_limit_offset_test.go | 64 +- .../inline_array/with_count_limit_test.go | 64 +- .../query/inline_array/with_count_test.go | 128 +- .../query/inline_array/with_group_test.go | 116 +- .../inline_array/with_sum_filter_test.go | 128 +- .../with_sum_limit_offset_order_test.go | 272 +- .../with_sum_limit_offset_test.go | 32 +- .../query/inline_array/with_sum_limit_test.go | 32 +- .../query/inline_array/with_sum_test.go | 256 +- .../query/latest_commits/simple_test.go | 20 +- .../integration/query/latest_commits/utils.go | 35 +- .../with_collectionid_prop_test.go | 11 +- .../latest_commits/with_doc_id_field_test.go | 100 +- .../latest_commits/with_doc_id_prop_test.go | 9 +- .../query/latest_commits/with_doc_id_test.go | 76 +- .../query/latest_commits/with_field_test.go | 40 +- .../query/one_to_many/simple_test.go | 198 +- tests/integration/query/one_to_many/utils.go | 17 +- .../one_to_many/with_count_filter_test.go | 161 +- .../with_count_limit_offset_test.go | 260 +- .../one_to_many/with_count_limit_test.go | 240 +- .../query/one_to_many/with_count_test.go | 101 +- .../query/one_to_many/with_doc_id_test.go | 57 +- .../query/one_to_many/with_doc_ids_test.go | 75 +- .../with_filter_related_id_test.go | 404 +-- .../one_to_many/with_group_filter_test.go | 381 +-- .../with_group_related_id_alias_test.go | 148 +- .../one_to_many/with_group_related_id_test.go | 548 ++-- .../query/one_to_many/with_group_test.go | 315 ++- .../query/one_to_many/with_limit_test.go | 206 +- .../with_order_filter_limit_test.go | 146 +- .../one_to_many/with_order_filter_test.go | 178 +- .../query/one_to_many/with_related_id_test.go | 200 +- .../one_to_many/with_same_field_name_test.go | 120 +- .../one_to_many/with_sum_filter_order_test.go | 682 +++-- .../one_to_many/with_sum_limit_offset_test.go | 72 +- .../query/one_to_many/with_sum_limit_test.go | 74 +- .../query/one_to_many/with_typename_test.go | 56 +- .../query/one_to_one/simple_test.go | 187 +- tests/integration/query/one_to_one/utils.go | 17 +- .../one_to_one/with_filter_order_test.go | 140 +- .../query/one_to_one/with_order_test.go | 300 +-- tests/integration/query/simple/simple_test.go | 194 +- tests/integration/query/simple/utils.go | 17 +- .../query/simple/with_average_filter_test.go | 60 +- .../query/simple/with_average_test.go | 58 +- .../integration/query/simple/with_cid_test.go | 20 +- .../query/simple/with_count_filter_test.go | 60 +- .../query/simple/with_count_test.go | 48 +- .../query/simple/with_doc_id_filter_test.go | 38 +- .../query/simple/with_doc_id_test.go | 90 +- .../query/simple/with_doc_ids_test.go | 162 +- .../query/simple/with_filter/utils.go | 17 +- .../query/simple/with_filter/with_and_test.go | 54 +- .../with_filter/with_eq_datetime_test.go | 88 +- .../simple/with_filter/with_eq_float_test.go | 80 +- .../simple/with_filter/with_eq_int_test.go | 80 +- .../simple/with_filter/with_eq_string_test.go | 168 +- .../with_filter/with_ge_datetime_test.go | 138 +- .../simple/with_filter/with_ge_float_test.go | 142 +- .../simple/with_filter/with_ge_int_test.go | 108 +- .../with_filter/with_gt_datetime_test.go | 132 +- .../simple/with_filter/with_gt_float_test.go | 168 +- .../simple/with_filter/with_gt_int_test.go | 146 +- .../query/simple/with_filter/with_in_test.go | 168 +- .../with_filter/with_le_datetime_test.go | 102 +- .../simple/with_filter/with_le_float_test.go | 136 +- .../simple/with_filter/with_le_int_test.go | 102 +- .../with_filter/with_like_string_test.go | 448 ++-- .../with_filter/with_lt_datetime_test.go | 64 +- .../simple/with_filter/with_lt_float_test.go | 98 +- .../simple/with_filter/with_lt_int_test.go | 64 +- .../simple/with_filter/with_ne_bool_test.go | 132 +- .../with_filter/with_ne_datetime_test.go | 78 +- .../simple/with_filter/with_ne_float_test.go | 78 +- .../simple/with_filter/with_ne_int_test.go | 78 +- .../simple/with_filter/with_ne_string_test.go | 78 +- .../query/simple/with_filter/with_nin_test.go | 52 +- .../with_filter/with_nlike_string_test.go | 454 ++-- .../query/simple/with_filter/with_not_test.go | 276 +- .../query/simple/with_filter/with_or_test.go | 54 +- .../simple/with_group_average_count_test.go | 57 +- .../simple/with_group_average_filter_test.go | 498 ++-- .../with_group_average_limit_offset_test.go | 55 +- .../simple/with_group_average_limit_test.go | 54 +- .../simple/with_group_average_sum_test.go | 160 +- .../query/simple/with_group_average_test.go | 668 ++--- .../simple/with_group_count_filter_test.go | 302 ++- .../with_group_count_limit_offset_test.go | 126 +- .../simple/with_group_count_limit_test.go | 126 +- .../query/simple/with_group_count_sum_test.go | 104 +- .../query/simple/with_group_count_test.go | 312 ++- .../query/simple/with_group_doc_id_test.go | 57 +- .../query/simple/with_group_doc_ids_test.go | 64 +- .../query/simple/with_group_filter_test.go | 380 +-- .../simple/with_group_limit_offset_test.go | 102 +- .../query/simple/with_group_limit_test.go | 270 +- .../query/simple/with_group_order_test.go | 466 ++-- .../simple/with_group_sum_filter_test.go | 302 ++- .../with_group_sum_limit_offset_test.go | 54 +- .../query/simple/with_group_sum_limit_test.go | 54 +- .../query/simple/with_group_sum_test.go | 580 +++-- .../query/simple/with_group_test.go | 847 ++++--- .../query/simple/with_group_typename_test.go | 62 +- .../query/simple/with_limit_offset_test.go | 322 ++- .../query/simple/with_operation_alias_test.go | 34 +- .../query/simple/with_order_filter_test.go | 54 +- .../query/simple/with_order_test.go | 418 +-- .../query/simple/with_sum_filter_test.go | 30 +- .../integration/query/simple/with_sum_test.go | 58 +- .../query/simple/with_typename_test.go | 62 +- .../query/simple/with_version_test.go | 186 +- tests/integration/utils.go | 2245 ++++++++++++++++- tests/integration/utils2.go | 2242 ---------------- 120 files changed, 13064 insertions(+), 10891 deletions(-) delete mode 100644 tests/integration/utils2.go diff --git a/tests/integration/query/inline_array/simple_test.go b/tests/integration/query/inline_array/simple_test.go index f266b114ba..7b2435e5fe 100644 --- a/tests/integration/query/inline_array/simple_test.go +++ b/tests/integration/query/inline_array/simple_test.go @@ -19,78 +19,84 @@ import ( ) func TestQueryInlineArrayWithBooleans(t *testing.T) { - tests := []testUtils.RequestTestCase{ + tests := []testUtils.TestCase{ { Description: "Simple inline array with no filter, nil boolean array", - Request: `query { - Users { - name - likedIndexes - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "name": "John", "likedIndexes": null }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "likedIndexes": nil, + testUtils.Request{ + Request: `query { + Users { + name + likedIndexes + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "likedIndexes": nil, + }, + }, }, }, }, }, { Description: "Simple inline array with no filter, empty boolean array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "likedIndexes": [] + }`, + }, + testUtils.Request{ + Request: `query { Users { name likedIndexes } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "likedIndexes": [] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "likedIndexes": []bool{}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "likedIndexes": []bool{}, + }, + }, }, }, }, }, { Description: "Simple inline array with no filter, booleans", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "likedIndexes": [true, true, false, true] + }`, + }, + testUtils.Request{ + Request: `query { Users { name likedIndexes } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "likedIndexes": [true, true, false, true] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "likedIndexes": []bool{true, true, false, true}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "likedIndexes": []bool{true, true, false, true}, + }, + }, }, }, }, @@ -103,31 +109,33 @@ func TestQueryInlineArrayWithBooleans(t *testing.T) { } func TestQueryInlineArrayWithNillableBooleans(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, booleans", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "indexLikesDislikes": [true, true, false, null] + }`, + }, + testUtils.Request{ + Request: `query { Users { name indexLikesDislikes } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "indexLikesDislikes": [true, true, false, null] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "indexLikesDislikes": []immutable.Option[bool]{ - immutable.Some(true), - immutable.Some(true), - immutable.Some(false), - immutable.None[bool](), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "indexLikesDislikes": []immutable.Option[bool]{ + immutable.Some(true), + immutable.Some(true), + immutable.Some(false), + immutable.None[bool](), + }, + }, }, }, }, @@ -138,152 +146,164 @@ func TestQueryInlineArrayWithNillableBooleans(t *testing.T) { } func TestQueryInlineArrayWithIntegers(t *testing.T) { - tests := []testUtils.RequestTestCase{ + tests := []testUtils.TestCase{ { Description: "Simple inline array with no filter, default integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John" + }`, + }, + testUtils.Request{ + Request: `query { Users { name favouriteIntegers } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John" - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "favouriteIntegers": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "favouriteIntegers": nil, + }, + }, }, }, }, }, { Description: "Simple inline array with no filter, nil integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteIntegers": null + }`, + }, + testUtils.Request{ + Request: `query { Users { name favouriteIntegers } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteIntegers": null - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "favouriteIntegers": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "favouriteIntegers": nil, + }, + }, }, }, }, }, { Description: "Simple inline array with no filter, empty integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteIntegers": [] + }`, + }, + testUtils.Request{ + Request: `query { Users { name favouriteIntegers } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteIntegers": [] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "favouriteIntegers": []int64{}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "favouriteIntegers": []int64{}, + }, + }, }, }, }, }, { Description: "Simple inline array with no filter, positive integers", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteIntegers": [1, 2, 3, 5, 8] + }`, + }, + testUtils.Request{ + Request: `query { Users { name favouriteIntegers } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteIntegers": [1, 2, 3, 5, 8] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "favouriteIntegers": []int64{1, 2, 3, 5, 8}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "favouriteIntegers": []int64{1, 2, 3, 5, 8}, + }, + }, }, }, }, }, { Description: "Simple inline array with no filter, negative integers", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Andy", + "favouriteIntegers": [-1, -2, -3, -5, -8] + }`, + }, + testUtils.Request{ + Request: `query { Users { name favouriteIntegers } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Andy", - "favouriteIntegers": [-1, -2, -3, -5, -8] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Andy", - "favouriteIntegers": []int64{-1, -2, -3, -5, -8}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Andy", + "favouriteIntegers": []int64{-1, -2, -3, -5, -8}, + }, + }, }, }, }, }, { Description: "Simple inline array with no filter, mixed integers", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "favouriteIntegers": [-1, 2, -1, 1, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users { name favouriteIntegers } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "favouriteIntegers": [-1, 2, -1, 1, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "favouriteIntegers": []int64{-1, 2, -1, 1, 0}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "favouriteIntegers": []int64{-1, 2, -1, 1, 0}, + }, + }, }, }, }, @@ -296,32 +316,34 @@ func TestQueryInlineArrayWithIntegers(t *testing.T) { } func TestQueryInlineArrayWithNillableInts(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, nillable ints", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "testScores": [-1, null, -1, 2, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users { name testScores } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "testScores": [-1, null, -1, 2, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "testScores": []immutable.Option[int64]{ - immutable.Some[int64](-1), - immutable.None[int64](), - immutable.Some[int64](-1), - immutable.Some[int64](2), - immutable.Some[int64](0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "testScores": []immutable.Option[int64]{ + immutable.Some[int64](-1), + immutable.None[int64](), + immutable.Some[int64](-1), + immutable.Some[int64](2), + immutable.Some[int64](0), + }, + }, }, }, }, @@ -332,78 +354,84 @@ func TestQueryInlineArrayWithNillableInts(t *testing.T) { } func TestQueryInlineArrayWithFloats(t *testing.T) { - tests := []testUtils.RequestTestCase{ + tests := []testUtils.TestCase{ { Description: "Simple inline array with no filter, nil float array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteFloats": null + }`, + }, + testUtils.Request{ + Request: `query { Users { name favouriteFloats } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteFloats": null - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "favouriteFloats": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "favouriteFloats": nil, + }, + }, }, }, }, }, { Description: "Simple inline array with no filter, empty float array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteFloats": [] + }`, + }, + testUtils.Request{ + Request: `query { Users { name favouriteFloats } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteFloats": [] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "favouriteFloats": []float64{}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "favouriteFloats": []float64{}, + }, + }, }, }, }, }, { Description: "Simple inline array with no filter, positive floats", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteFloats": [3.1425, 0.00000000001, 10] + }`, + }, + testUtils.Request{ + Request: `query { Users { name favouriteFloats } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteFloats": [3.1425, 0.00000000001, 10] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "favouriteFloats": []float64{3.1425, 0.00000000001, 10}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "favouriteFloats": []float64{3.1425, 0.00000000001, 10}, + }, + }, }, }, }, @@ -416,31 +444,33 @@ func TestQueryInlineArrayWithFloats(t *testing.T) { } func TestQueryInlineArrayWithNillableFloats(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, nillable floats", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "pageRatings": [3.1425, null, -0.00000000001, 10] + }`, + }, + testUtils.Request{ + Request: `query { Users { name pageRatings } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "pageRatings": [3.1425, null, -0.00000000001, 10] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "pageRatings": []immutable.Option[float64]{ - immutable.Some(3.1425), - immutable.None[float64](), - immutable.Some(-0.00000000001), - immutable.Some[float64](10), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "pageRatings": []immutable.Option[float64]{ + immutable.Some(3.1425), + immutable.None[float64](), + immutable.Some(-0.00000000001), + immutable.Some[float64](10), + }, + }, }, }, }, @@ -451,78 +481,84 @@ func TestQueryInlineArrayWithNillableFloats(t *testing.T) { } func TestQueryInlineArrayWithStrings(t *testing.T) { - tests := []testUtils.RequestTestCase{ + tests := []testUtils.TestCase{ { Description: "Simple inline array with no filter, nil string array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "preferredStrings": null + }`, + }, + testUtils.Request{ + Request: `query { Users { name preferredStrings } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "preferredStrings": null - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "preferredStrings": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "preferredStrings": nil, + }, + }, }, }, }, }, { Description: "Simple inline array with no filter, empty string array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "preferredStrings": [] + }`, + }, + testUtils.Request{ + Request: `query { Users { name preferredStrings } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "preferredStrings": [] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "preferredStrings": []string{}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "preferredStrings": []string{}, + }, + }, }, }, }, }, { Description: "Simple inline array with no filter, strings", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "preferredStrings": ["", "the previous", "the first", "empty string"] + }`, + }, + testUtils.Request{ + Request: `query { Users { name preferredStrings } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "preferredStrings": ["", "the previous", "the first", "empty string"] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "preferredStrings": []string{"", "the previous", "the first", "empty string"}, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "preferredStrings": []string{"", "the previous", "the first", "empty string"}, + }, + }, }, }, }, @@ -535,32 +571,34 @@ func TestQueryInlineArrayWithStrings(t *testing.T) { } func TestQueryInlineArrayWithNillableString(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, nillable strings", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "pageHeaders": ["", "the previous", "the first", "empty string", null] + }`, + }, + testUtils.Request{ + Request: `query { Users { name pageHeaders } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "pageHeaders": ["", "the previous", "the first", "empty string", null] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "pageHeaders": []immutable.Option[string]{ - immutable.Some(""), - immutable.Some("the previous"), - immutable.Some("the first"), - immutable.Some("empty string"), - immutable.None[string](), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "pageHeaders": []immutable.Option[string]{ + immutable.Some(""), + immutable.Some("the previous"), + immutable.Some("the first"), + immutable.Some("empty string"), + immutable.None[string](), + }, + }, }, }, }, diff --git a/tests/integration/query/inline_array/utils.go b/tests/integration/query/inline_array/utils.go index 924cc45577..90f359b6d2 100644 --- a/tests/integration/query/inline_array/utils.go +++ b/tests/integration/query/inline_array/utils.go @@ -30,6 +30,19 @@ var userCollectionGQLSchema = (` } `) -func executeTestCase(t *testing.T, test testUtils.RequestTestCase) { - testUtils.ExecuteRequestTestCase(t, userCollectionGQLSchema, []string{"Users"}, test) +func executeTestCase(t *testing.T, test testUtils.TestCase) { + testUtils.ExecuteTestCase( + t, + testUtils.TestCase{ + Description: test.Description, + Actions: append( + []any{ + testUtils.SchemaUpdate{ + Schema: userCollectionGQLSchema, + }, + }, + test.Actions..., + ), + }, + ) } diff --git a/tests/integration/query/inline_array/with_average_filter_test.go b/tests/integration/query/inline_array/with_average_filter_test.go index cac50ea81c..f89b7e7835 100644 --- a/tests/integration/query/inline_array/with_average_filter_test.go +++ b/tests/integration/query/inline_array/with_average_filter_test.go @@ -17,27 +17,29 @@ import ( ) func TestQueryInlineIntegerArrayWithAverageWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, filtered average of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "favouriteIntegers": [-1, 2, -1, 1, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _avg(favouriteIntegers: {filter: {_gt: 0}}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "favouriteIntegers": [-1, 2, -1, 1, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_avg": float64(1.5), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_avg": float64(1.5), + }, + }, }, }, }, @@ -47,27 +49,29 @@ func TestQueryInlineIntegerArrayWithAverageWithFilter(t *testing.T) { } func TestQueryInlineNillableIntegerArrayWithAverageWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with filter, average of populated nillable integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "testScores": [-1, null, 13, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _avg(testScores: {filter: {_gt: -1}}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "testScores": [-1, null, 13, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "_avg": float64(6.5), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(6.5), + }, + }, }, }, }, @@ -77,27 +81,29 @@ func TestQueryInlineNillableIntegerArrayWithAverageWithFilter(t *testing.T) { } func TestQueryInlineFloatArrayWithAverageWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, filtered average of float array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "favouriteFloats": [3.4, 3.6, 10] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _avg(favouriteFloats: {filter: {_lt: 9}}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "favouriteFloats": [3.4, 3.6, 10] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_avg": 3.5, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_avg": 3.5, + }, + }, }, }, }, @@ -107,27 +113,29 @@ func TestQueryInlineFloatArrayWithAverageWithFilter(t *testing.T) { } func TestQueryInlineNillableFloatArrayWithAverageWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, filtered average of nillable float array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "pageRatings": [3.4, 3.6, 10, null] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _avg(pageRatings: {filter: {_lt: 9}}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "pageRatings": [3.4, 3.6, 10, null] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_avg": 3.5, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_avg": 3.5, + }, + }, }, }, }, diff --git a/tests/integration/query/inline_array/with_average_sum_test.go b/tests/integration/query/inline_array/with_average_sum_test.go index a6474d8f03..b9d2098c9f 100644 --- a/tests/integration/query/inline_array/with_average_sum_test.go +++ b/tests/integration/query/inline_array/with_average_sum_test.go @@ -21,29 +21,31 @@ import ( // verify that that code path is taken, but it does verfiy that the correct result // is returned to the consumer in case the more efficient code path is taken. func TestQueryInlineIntegerArrayWithAverageAndSum(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, average and sum of populated integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteIntegers": [-1, 0, 9, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users(groupBy: [name]) { name _avg(favouriteIntegers: {}) _sum(favouriteIntegers: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteIntegers": [-1, 0, 9, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "_avg": float64(2), - "_sum": int64(8), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(2), + "_sum": int64(8), + }, + }, }, }, }, diff --git a/tests/integration/query/inline_array/with_average_test.go b/tests/integration/query/inline_array/with_average_test.go index bd5eeec041..376d6efd5b 100644 --- a/tests/integration/query/inline_array/with_average_test.go +++ b/tests/integration/query/inline_array/with_average_test.go @@ -17,27 +17,29 @@ import ( ) func TestQueryInlineIntegerArrayWithAverageAndNullArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, average of nil integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteIntegers": null + }`, + }, + testUtils.Request{ + Request: `query { Users { name _avg(favouriteIntegers: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteIntegers": null - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "_avg": float64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(0), + }, + }, }, }, }, @@ -47,27 +49,29 @@ func TestQueryInlineIntegerArrayWithAverageAndNullArray(t *testing.T) { } func TestQueryInlineIntegerArrayWithAverageAndEmptyArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, average of empty integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteIntegers": [] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _avg(favouriteIntegers: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteIntegers": [] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "_avg": float64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(0), + }, + }, }, }, }, @@ -77,27 +81,29 @@ func TestQueryInlineIntegerArrayWithAverageAndEmptyArray(t *testing.T) { } func TestQueryInlineIntegerArrayWithAverageAndZeroArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, average of zero integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteIntegers": [0, 0, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _avg(favouriteIntegers: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteIntegers": [0, 0, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "_avg": float64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(0), + }, + }, }, }, }, @@ -107,27 +113,29 @@ func TestQueryInlineIntegerArrayWithAverageAndZeroArray(t *testing.T) { } func TestQueryInlineIntegerArrayWithAverageAndPopulatedArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, average of populated integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteIntegers": [-1, 0, 9, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _avg(favouriteIntegers: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteIntegers": [-1, 0, 9, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "_avg": float64(2), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(2), + }, + }, }, }, }, @@ -137,27 +145,29 @@ func TestQueryInlineIntegerArrayWithAverageAndPopulatedArray(t *testing.T) { } func TestQueryInlineNillableIntegerArrayWithAverageAndPopulatedArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, average of populated nillable integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "testScores": [-1, null, 13, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _avg(testScores: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "testScores": [-1, null, 13, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "_avg": float64(4), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(4), + }, + }, }, }, }, @@ -167,27 +177,29 @@ func TestQueryInlineNillableIntegerArrayWithAverageAndPopulatedArray(t *testing. } func TestQueryInlineFloatArrayWithAverageAndNullArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, average of nil float array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteFloats": null + }`, + }, + testUtils.Request{ + Request: `query { Users { name _avg(favouriteFloats: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteFloats": null - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "_avg": float64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(0), + }, + }, }, }, }, @@ -197,27 +209,29 @@ func TestQueryInlineFloatArrayWithAverageAndNullArray(t *testing.T) { } func TestQueryInlineFloatArrayWithAverageAndEmptyArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, average of empty float array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteFloats": [] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _avg(favouriteFloats: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteFloats": [] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "_avg": float64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(0), + }, + }, }, }, }, @@ -227,28 +241,30 @@ func TestQueryInlineFloatArrayWithAverageAndEmptyArray(t *testing.T) { } func TestQueryInlineFloatArrayWithAverageAndZeroArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, average of zero float array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteFloats": [0, 0, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _avg(favouriteFloats: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteFloats": [0, 0, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { + Results: map[string]any{ + "Users": []map[string]any{ + { - "name": "John", - "_avg": float64(0), + "name": "John", + "_avg": float64(0), + }, + }, }, }, }, @@ -258,27 +274,29 @@ func TestQueryInlineFloatArrayWithAverageAndZeroArray(t *testing.T) { } func TestQueryInlineFloatArrayWithAverageAndPopulatedArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, average of populated float array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteFloats": [-0.1, 0, 0.9, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _avg(favouriteFloats: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteFloats": [-0.1, 0, 0.9, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "_avg": float64(0.2), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(0.2), + }, + }, }, }, }, @@ -288,27 +306,29 @@ func TestQueryInlineFloatArrayWithAverageAndPopulatedArray(t *testing.T) { } func TestQueryInlineNillableFloatArrayWithAverageAndPopulatedArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, average of populated nillable float array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "pageRatings": [-0.1, 0, 0.9, 0, null] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _avg(pageRatings: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "pageRatings": [-0.1, 0, 0.9, 0, null] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "_avg": float64(0.2), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_avg": float64(0.2), + }, + }, }, }, }, diff --git a/tests/integration/query/inline_array/with_count_filter_test.go b/tests/integration/query/inline_array/with_count_filter_test.go index c8c81f82e2..c35fd6f1c0 100644 --- a/tests/integration/query/inline_array/with_count_filter_test.go +++ b/tests/integration/query/inline_array/with_count_filter_test.go @@ -17,27 +17,29 @@ import ( ) func TestQueryInlineBoolArrayWithCountWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, filtered count of bool array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "likedIndexes": [true, true, false, true] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _count(likedIndexes: {filter: {_eq: true}}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "likedIndexes": [true, true, false, true] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_count": 3, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 3, + }, + }, }, }, }, @@ -47,27 +49,29 @@ func TestQueryInlineBoolArrayWithCountWithFilter(t *testing.T) { } func TestQueryInlineNillableBoolArrayWithCountWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with filter, count of nillable bool array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "indexLikesDislikes": [true, true, false, null] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _count(indexLikesDislikes: {filter: {_eq: true}}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "indexLikesDislikes": [true, true, false, null] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "_count": 2, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_count": 2, + }, + }, }, }, }, @@ -77,27 +81,29 @@ func TestQueryInlineNillableBoolArrayWithCountWithFilter(t *testing.T) { } func TestQueryInlineIntegerArrayWithCountWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, filtered count of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "favouriteIntegers": [-1, 2, -1, 1, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _count(favouriteIntegers: {filter: {_gt: 0}}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "favouriteIntegers": [-1, 2, -1, 1, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_count": 2, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 2, + }, + }, }, }, }, @@ -107,27 +113,29 @@ func TestQueryInlineIntegerArrayWithCountWithFilter(t *testing.T) { } func TestQueryInlineNillableIntegerArrayWithCountWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, filtered count of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "testScores": [-1, 2, 1, null, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _count(testScores: {filter: {_gt: 0}}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "testScores": [-1, 2, 1, null, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_count": 2, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 2, + }, + }, }, }, }, @@ -137,26 +145,29 @@ func TestQueryInlineNillableIntegerArrayWithCountWithFilter(t *testing.T) { } func TestQueryInlineIntegerArrayWithsWithCountWithAndFilterAndPopulatedArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, filtered count of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "favouriteIntegers": [-1, 2, -1, 1, 0, -2] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _count(favouriteIntegers: {filter: {_and: [{_gt: -2}, {_lt: 2}]}}) } }`, - Docs: map[int][]string{ - 0: { - (`{ - "name": "Shahzad", - "favouriteIntegers": [-1, 2, -1, 1, 0, -2] - }`)}, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_count": 4, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 4, + }, + }, }, }, }, @@ -166,27 +177,29 @@ func TestQueryInlineIntegerArrayWithsWithCountWithAndFilterAndPopulatedArray(t * } func TestQueryInlineFloatArrayWithCountWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, filtered count of float array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "favouriteFloats": [3.1425, 0.00000000001, 10] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _count(favouriteFloats: {filter: {_lt: 9}}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "favouriteFloats": [3.1425, 0.00000000001, 10] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_count": 2, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 2, + }, + }, }, }, }, @@ -196,27 +209,29 @@ func TestQueryInlineFloatArrayWithCountWithFilter(t *testing.T) { } func TestQueryInlineNillableFloatArrayWithCountWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, filtered count of nillable float array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "pageRatings": [3.1425, 0.00000000001, 10, null] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _count(pageRatings: {filter: {_lt: 9}}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "pageRatings": [3.1425, 0.00000000001, 10, null] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_count": 2, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 2, + }, + }, }, }, }, @@ -226,27 +241,29 @@ func TestQueryInlineNillableFloatArrayWithCountWithFilter(t *testing.T) { } func TestQueryInlineStringArrayWithCountWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, filtered count of string array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "preferredStrings": ["", "the previous", "the first", "empty string"] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _count(preferredStrings: {filter: {_in: ["", "the first"]}}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "preferredStrings": ["", "the previous", "the first", "empty string"] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_count": 2, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 2, + }, + }, }, }, }, @@ -256,27 +273,29 @@ func TestQueryInlineStringArrayWithCountWithFilter(t *testing.T) { } func TestQueryInlineNillableStringArrayWithCountWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, filtered count of string array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "pageHeaders": ["", "the previous", null, "empty string"] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _count(pageHeaders: {filter: {_in: ["", "the first", "empty string"]}}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "pageHeaders": ["", "the previous", null, "empty string"] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_count": 2, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 2, + }, + }, }, }, }, diff --git a/tests/integration/query/inline_array/with_count_limit_offset_test.go b/tests/integration/query/inline_array/with_count_limit_offset_test.go index d1e04b43ed..ebf3ee52b6 100644 --- a/tests/integration/query/inline_array/with_count_limit_offset_test.go +++ b/tests/integration/query/inline_array/with_count_limit_offset_test.go @@ -17,27 +17,29 @@ import ( ) func TestQueryInlineIntegerArrayWithCountWithOffsetWithLimitGreaterThanLength(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, offsetted limited count of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "favouriteIntegers": [-1, 2, 3] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _count(favouriteIntegers: {offset: 1, limit: 3}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "favouriteIntegers": [-1, 2, 3] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_count": 2, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 2, + }, + }, }, }, }, @@ -47,27 +49,29 @@ func TestQueryInlineIntegerArrayWithCountWithOffsetWithLimitGreaterThanLength(t } func TestQueryInlineIntegerArrayWithCountWithOffsetWithLimit(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, offsetted limited count of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "favouriteIntegers": [-1, 2, -1, 1, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _count(favouriteIntegers: {offset: 1, limit: 3}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "favouriteIntegers": [-1, 2, -1, 1, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_count": 3, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 3, + }, + }, }, }, }, diff --git a/tests/integration/query/inline_array/with_count_limit_test.go b/tests/integration/query/inline_array/with_count_limit_test.go index 09354ecc8c..11aab3e99a 100644 --- a/tests/integration/query/inline_array/with_count_limit_test.go +++ b/tests/integration/query/inline_array/with_count_limit_test.go @@ -17,27 +17,29 @@ import ( ) func TestQueryInlineIntegerArrayWithCountWithLimitGreaterThanLength(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, limited count of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "favouriteIntegers": [-1, 2] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _count(favouriteIntegers: {limit: 3}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "favouriteIntegers": [-1, 2] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_count": 2, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 2, + }, + }, }, }, }, @@ -47,27 +49,29 @@ func TestQueryInlineIntegerArrayWithCountWithLimitGreaterThanLength(t *testing.T } func TestQueryInlineIntegerArrayWithCountWithLimit(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, limited count of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "favouriteIntegers": [-1, 2, -1, 1, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _count(favouriteIntegers: {limit: 3}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "favouriteIntegers": [-1, 2, -1, 1, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_count": 3, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 3, + }, + }, }, }, }, diff --git a/tests/integration/query/inline_array/with_count_test.go b/tests/integration/query/inline_array/with_count_test.go index 40401e1cce..d0c13d2886 100644 --- a/tests/integration/query/inline_array/with_count_test.go +++ b/tests/integration/query/inline_array/with_count_test.go @@ -17,27 +17,29 @@ import ( ) func TestQueryInlineIntegerArrayWithCountAndNullArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, count of nil integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteIntegers": null + }`, + }, + testUtils.Request{ + Request: `query { Users { name _count(favouriteIntegers: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteIntegers": null - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "_count": 0, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_count": 0, + }, + }, }, }, }, @@ -47,27 +49,29 @@ func TestQueryInlineIntegerArrayWithCountAndNullArray(t *testing.T) { } func TestQueryInlineIntegerArrayWithCountAndEmptyArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, count of empty integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteIntegers": [] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _count(favouriteIntegers: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteIntegers": [] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "_count": 0, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_count": 0, + }, + }, }, }, }, @@ -77,27 +81,29 @@ func TestQueryInlineIntegerArrayWithCountAndEmptyArray(t *testing.T) { } func TestQueryInlineIntegerArrayWithCountAndPopulatedArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, count of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "favouriteIntegers": [-1, 2, -1, 1, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _count(favouriteIntegers: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "favouriteIntegers": [-1, 2, -1, 1, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_count": 5, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_count": 5, + }, + }, }, }, }, @@ -107,27 +113,29 @@ func TestQueryInlineIntegerArrayWithCountAndPopulatedArray(t *testing.T) { } func TestQueryInlineNillableBoolArrayWithCountAndPopulatedArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, count of nillable bool array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "indexLikesDislikes": [true, true, false, null] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _count(indexLikesDislikes: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "indexLikesDislikes": [true, true, false, null] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "_count": 4, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_count": 4, + }, + }, }, }, }, diff --git a/tests/integration/query/inline_array/with_group_test.go b/tests/integration/query/inline_array/with_group_test.go index 7706b9250b..f893a54171 100644 --- a/tests/integration/query/inline_array/with_group_test.go +++ b/tests/integration/query/inline_array/with_group_test.go @@ -17,38 +17,42 @@ import ( ) func TestQueryInlineArrayWithGroupByString(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, mixed integers, group by string", - Request: `query { - Users (groupBy: [name]) { - name - _group { - favouriteIntegers - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "name": "Shahzad", "favouriteIntegers": [-1, 2, -1, 1, 0] }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "name": "Shahzad", "favouriteIntegers": [1, -2, 1, -1, 0] }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_group": []map[string]any{ - { - "favouriteIntegers": []int64{1, -2, 1, -1, 0}, - }, + testUtils.Request{ + Request: `query { + Users (groupBy: [name]) { + name + _group { + favouriteIntegers + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "favouriteIntegers": []int64{-1, 2, -1, 1, 0}, + "name": "Shahzad", + "_group": []map[string]any{ + { + "favouriteIntegers": []int64{1, -2, 1, -1, 0}, + }, + { + "favouriteIntegers": []int64{-1, 2, -1, 1, 0}, + }, + }, }, }, }, @@ -60,51 +64,57 @@ func TestQueryInlineArrayWithGroupByString(t *testing.T) { } func TestQueryInlineArrayWithGroupByArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, mixed integers, group by array", - Request: `query { - Users (groupBy: [favouriteIntegers]) { - favouriteIntegers - _group { - name - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "name": "Andy", "favouriteIntegers": [-1, 2, -1, 1, 0] }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "name": "Shahzad", "favouriteIntegers": [-1, 2, -1, 1, 0] }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "name": "John", "favouriteIntegers": [1, 2, 3] }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "favouriteIntegers": []int64{1, 2, 3}, - "_group": []map[string]any{ - { - "name": "John", - }, - }, - }, - { - "favouriteIntegers": []int64{-1, 2, -1, 1, 0}, - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users (groupBy: [favouriteIntegers]) { + favouriteIntegers + _group { + name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "name": "Andy", + "favouriteIntegers": []int64{1, 2, 3}, + "_group": []map[string]any{ + { + "name": "John", + }, + }, }, { + "favouriteIntegers": []int64{-1, 2, -1, 1, 0}, + "_group": []map[string]any{ + { + "name": "Andy", + }, + { - "name": "Shahzad", + "name": "Shahzad", + }, + }, }, }, }, diff --git a/tests/integration/query/inline_array/with_sum_filter_test.go b/tests/integration/query/inline_array/with_sum_filter_test.go index 075411e06a..c43a961002 100644 --- a/tests/integration/query/inline_array/with_sum_filter_test.go +++ b/tests/integration/query/inline_array/with_sum_filter_test.go @@ -17,27 +17,29 @@ import ( ) func TestQueryInlineIntegerArrayWithSumWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, filtered sum of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "favouriteIntegers": [-1, 2, -1, 1, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(favouriteIntegers: {filter: {_gt: 0}}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "favouriteIntegers": [-1, 2, -1, 1, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_sum": int64(3), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_sum": int64(3), + }, + }, }, }, }, @@ -47,27 +49,29 @@ func TestQueryInlineIntegerArrayWithSumWithFilter(t *testing.T) { } func TestQueryInlineNillableIntegerArrayWithSumWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with filter, sum of nillable integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "testScores": [-1, 2, null, 1, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(testScores: {filter: {_gt: 0}}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "testScores": [-1, 2, null, 1, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_sum": int64(3), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_sum": int64(3), + }, + }, }, }, }, @@ -77,27 +81,29 @@ func TestQueryInlineNillableIntegerArrayWithSumWithFilter(t *testing.T) { } func TestQueryInlineFloatArrayWithSumWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, filtered sum of float array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "favouriteFloats": [3.1425, 0.00000000001, 10] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(favouriteFloats: {filter: {_lt: 9}}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "favouriteFloats": [3.1425, 0.00000000001, 10] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_sum": 3.14250000001, + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_sum": 3.14250000001, + }, + }, }, }, }, @@ -107,27 +113,29 @@ func TestQueryInlineFloatArrayWithSumWithFilter(t *testing.T) { } func TestQueryInlineNillableFloatArrayWithSumWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with filter, sum of nillable float array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "pageRatings": [3.1425, 0.00000000001, 10, null] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(pageRatings: {filter: {_lt: 9}}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "pageRatings": [3.1425, 0.00000000001, 10, null] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_sum": float64(3.14250000001), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_sum": float64(3.14250000001), + }, + }, }, }, }, diff --git a/tests/integration/query/inline_array/with_sum_limit_offset_order_test.go b/tests/integration/query/inline_array/with_sum_limit_offset_order_test.go index 59e4ddc7fd..502fd4683f 100644 --- a/tests/integration/query/inline_array/with_sum_limit_offset_order_test.go +++ b/tests/integration/query/inline_array/with_sum_limit_offset_order_test.go @@ -17,28 +17,30 @@ import ( ) func TestQueryInlineIntegerArrayWithSumWithOffsetWithLimitWithOrderAsc(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, ordered offsetted limited sum of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "favouriteIntegers": [-1, 2, 5, 1, 0, 7] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(favouriteIntegers: {offset: 1, limit: 3, order: ASC}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "favouriteIntegers": [-1, 2, 5, 1, 0, 7] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - // 0 + 1 + 2 - "_sum": int64(3), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + // 0 + 1 + 2 + "_sum": int64(3), + }, + }, }, }, }, @@ -48,28 +50,30 @@ func TestQueryInlineIntegerArrayWithSumWithOffsetWithLimitWithOrderAsc(t *testin } func TestQueryInlineIntegerArrayWithSumWithOffsetWithLimitWithOrderDesc(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, ordered offsetted limited sum of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "favouriteIntegers": [-1, 2, 5, 1, 0, 7] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(favouriteIntegers: {offset: 1, limit: 3, order: DESC}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "favouriteIntegers": [-1, 2, 5, 1, 0, 7] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - // 5 + 2 + 1 - "_sum": int64(8), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + // 5 + 2 + 1 + "_sum": int64(8), + }, + }, }, }, }, @@ -79,28 +83,30 @@ func TestQueryInlineIntegerArrayWithSumWithOffsetWithLimitWithOrderDesc(t *testi } func TestQueryInlineNillableIntegerArrayWithSumWithOffsetWithLimitWithOrderAsc(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, ordered offsetted limited sum of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "testScores": [2, null, 5, 1, 0, 7] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(testScores: {offset: 1, limit: 3, order: ASC}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "testScores": [2, null, 5, 1, 0, 7] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - // 0 + 1 + 2 - "_sum": int64(3), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + // 0 + 1 + 2 + "_sum": int64(3), + }, + }, }, }, }, @@ -110,28 +116,30 @@ func TestQueryInlineNillableIntegerArrayWithSumWithOffsetWithLimitWithOrderAsc(t } func TestQueryInlineNillableIntegerArrayWithSumWithOffsetWithLimitWithOrderDesc(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, ordered offsetted limited sum of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "testScores": [null, 2, 5, 1, 0, 7] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(testScores: {offset: 1, limit: 3, order: DESC}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "testScores": [null, 2, 5, 1, 0, 7] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - // 5 + 2 + 1 - "_sum": int64(8), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + // 5 + 2 + 1 + "_sum": int64(8), + }, + }, }, }, }, @@ -141,28 +149,30 @@ func TestQueryInlineNillableIntegerArrayWithSumWithOffsetWithLimitWithOrderDesc( } func TestQueryInlineFloatArrayWithSumWithOffsetWithLimitWithOrderAsc(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, ordered offsetted limited sum of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "favouriteFloats": [3.1425, 0.00000000001, 10, 2.718, 0.577, 6.283] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(favouriteFloats: {offset: 1, limit: 3, order: ASC}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "favouriteFloats": [3.1425, 0.00000000001, 10, 2.718, 0.577, 6.283] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - // 0.577 + 2.718 + 3.1425 - "_sum": float64(6.4375), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + // 0.577 + 2.718 + 3.1425 + "_sum": float64(6.4375), + }, + }, }, }, }, @@ -172,28 +182,30 @@ func TestQueryInlineFloatArrayWithSumWithOffsetWithLimitWithOrderAsc(t *testing. } func TestQueryInlineFloatArrayWithSumWithOffsetWithLimitWithOrderDesc(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, ordered offsetted limited sum of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "favouriteFloats": [3.1425, 0.00000000001, 10, 2.718, 0.577, 6.283] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(favouriteFloats: {offset: 1, limit: 3, order: DESC}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "favouriteFloats": [3.1425, 0.00000000001, 10, 2.718, 0.577, 6.283] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - // 6.283 + 3.1425 + 2.718 - "_sum": float64(12.1435), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + // 6.283 + 3.1425 + 2.718 + "_sum": float64(12.1435), + }, + }, }, }, }, @@ -203,28 +215,30 @@ func TestQueryInlineFloatArrayWithSumWithOffsetWithLimitWithOrderDesc(t *testing } func TestQueryInlineNillableFloatArrayWithSumWithOffsetWithLimitWithOrderAsc(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, ordered offsetted limited sum of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "pageRatings": [3.1425, null, 10, 2.718, 0.577, 6.283] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(pageRatings: {offset: 1, limit: 3, order: ASC}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "pageRatings": [3.1425, null, 10, 2.718, 0.577, 6.283] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - // 0.577 + 2.718 + 3.1425 - "_sum": float64(6.4375), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + // 0.577 + 2.718 + 3.1425 + "_sum": float64(6.4375), + }, + }, }, }, }, @@ -234,28 +248,30 @@ func TestQueryInlineNillableFloatArrayWithSumWithOffsetWithLimitWithOrderAsc(t * } func TestQueryInlineNillableFloatArrayWithSumWithOffsetWithLimitWithOrderDesc(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, ordered offsetted limited sum of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "pageRatings": [3.1425, null, 10, 2.718, 0.577, 6.283] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(pageRatings: {offset: 1, limit: 3, order: DESC}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "pageRatings": [3.1425, null, 10, 2.718, 0.577, 6.283] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - // 6.283 + 3.1425 + 2.718 - "_sum": float64(12.1435), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + // 6.283 + 3.1425 + 2.718 + "_sum": float64(12.1435), + }, + }, }, }, }, diff --git a/tests/integration/query/inline_array/with_sum_limit_offset_test.go b/tests/integration/query/inline_array/with_sum_limit_offset_test.go index 357dbbde7e..621417ffc3 100644 --- a/tests/integration/query/inline_array/with_sum_limit_offset_test.go +++ b/tests/integration/query/inline_array/with_sum_limit_offset_test.go @@ -17,27 +17,29 @@ import ( ) func TestQueryInlineIntegerArrayWithSumWithOffsetWithLimit(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, offsetted limited sum of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "favouriteIntegers": [-1, 2, 5, 1, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(favouriteIntegers: {offset: 1, limit: 2}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "favouriteIntegers": [-1, 2, 5, 1, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_sum": int64(7), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_sum": int64(7), + }, + }, }, }, }, diff --git a/tests/integration/query/inline_array/with_sum_limit_test.go b/tests/integration/query/inline_array/with_sum_limit_test.go index 79ebd60f36..171c389823 100644 --- a/tests/integration/query/inline_array/with_sum_limit_test.go +++ b/tests/integration/query/inline_array/with_sum_limit_test.go @@ -17,27 +17,29 @@ import ( ) func TestQueryInlineIntegerArrayWithSumWithLimit(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array, limited sum of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "favouriteIntegers": [-1, 2, -1, 1, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(favouriteIntegers: {limit: 2}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "favouriteIntegers": [-1, 2, -1, 1, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_sum": int64(1), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_sum": int64(1), + }, + }, }, }, }, diff --git a/tests/integration/query/inline_array/with_sum_test.go b/tests/integration/query/inline_array/with_sum_test.go index 28f63bb6b3..d65fde5d7b 100644 --- a/tests/integration/query/inline_array/with_sum_test.go +++ b/tests/integration/query/inline_array/with_sum_test.go @@ -17,27 +17,29 @@ import ( ) func TestQueryInlineIntegerArrayWithSumAndNullArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, sum of nil integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteIntegers": null + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(favouriteIntegers: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteIntegers": null - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "_sum": int64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_sum": int64(0), + }, + }, }, }, }, @@ -47,27 +49,29 @@ func TestQueryInlineIntegerArrayWithSumAndNullArray(t *testing.T) { } func TestQueryInlineIntegerArrayWithSumAndEmptyArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, sum of empty integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteIntegers": [] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(favouriteIntegers: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteIntegers": [] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "_sum": int64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_sum": int64(0), + }, + }, }, }, }, @@ -77,27 +81,29 @@ func TestQueryInlineIntegerArrayWithSumAndEmptyArray(t *testing.T) { } func TestQueryInlineIntegerArrayWithSumAndPopulatedArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, sum of integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "favouriteIntegers": [-1, 2, -1, 1, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(favouriteIntegers: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "favouriteIntegers": [-1, 2, -1, 1, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_sum": int64(1), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_sum": int64(1), + }, + }, }, }, }, @@ -107,27 +113,29 @@ func TestQueryInlineIntegerArrayWithSumAndPopulatedArray(t *testing.T) { } func TestQueryInlineNillableIntegerArrayWithSumAndPopulatedArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, sum of nillable integer array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "testScores": [-1, 2, null, 1, 0] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(testScores: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "testScores": [-1, 2, null, 1, 0] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_sum": int64(2), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_sum": int64(2), + }, + }, }, }, }, @@ -137,27 +145,29 @@ func TestQueryInlineNillableIntegerArrayWithSumAndPopulatedArray(t *testing.T) { } func TestQueryInlineFloatArrayWithSumAndNullArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, sum of nil float array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteFloats": null + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(favouriteFloats: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteFloats": null - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "_sum": float64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_sum": float64(0), + }, + }, }, }, }, @@ -167,27 +177,29 @@ func TestQueryInlineFloatArrayWithSumAndNullArray(t *testing.T) { } func TestQueryInlineFloatArrayWithSumAndEmptyArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, sum of empty float array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteFloats": [] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(favouriteFloats: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteFloats": [] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "_sum": float64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_sum": float64(0), + }, + }, }, }, }, @@ -197,27 +209,29 @@ func TestQueryInlineFloatArrayWithSumAndEmptyArray(t *testing.T) { } func TestQueryInlineFloatArrayWithSumAndPopulatedArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, sum of float array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "favouriteFloats": [3.1425, 0.00000000001, 10] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(favouriteFloats: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "favouriteFloats": [3.1425, 0.00000000001, 10] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "John", - "_sum": float64(13.14250000001), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "John", + "_sum": float64(13.14250000001), + }, + }, }, }, }, @@ -227,27 +241,29 @@ func TestQueryInlineFloatArrayWithSumAndPopulatedArray(t *testing.T) { } func TestQueryInlineNillableFloatArrayWithSumAndPopulatedArray(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple inline array with no filter, sum of nillable float array", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "Shahzad", + "pageRatings": [3.1425, 0.00000000001, 10, null] + }`, + }, + testUtils.Request{ + Request: `query { Users { name _sum(pageRatings: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "Shahzad", - "pageRatings": [3.1425, 0.00000000001, 10, null] - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "name": "Shahzad", - "_sum": float64(13.14250000001), + Results: map[string]any{ + "Users": []map[string]any{ + { + "name": "Shahzad", + "_sum": float64(13.14250000001), + }, + }, }, }, }, diff --git a/tests/integration/query/latest_commits/simple_test.go b/tests/integration/query/latest_commits/simple_test.go index e31ee22da8..e71772d90d 100644 --- a/tests/integration/query/latest_commits/simple_test.go +++ b/tests/integration/query/latest_commits/simple_test.go @@ -19,9 +19,17 @@ import ( // This test is for documentation reasons only. This is not // desired behaviour (should return all latest commits). func TestQueryLatestCommits(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple latest commits query", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "age": 21 + }`, + }, + testUtils.Request{ + Request: `query { latestCommits { cid links { @@ -30,15 +38,9 @@ func TestQueryLatestCommits(t *testing.T) { } } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "age": 21 - }`, + ExpectedError: "Field \"latestCommits\" argument \"docID\" of type \"ID!\" is required but not provided.", }, }, - ExpectedError: "Field \"latestCommits\" argument \"docID\" of type \"ID!\" is required but not provided.", } executeTestCase(t, test) diff --git a/tests/integration/query/latest_commits/utils.go b/tests/integration/query/latest_commits/utils.go index 8c6b344f7e..b4ef3a8fbb 100644 --- a/tests/integration/query/latest_commits/utils.go +++ b/tests/integration/query/latest_commits/utils.go @@ -24,24 +24,19 @@ var userCollectionGQLSchema = (` } `) -const companiesCollectionGQLSchema = (` - type Companies { - name: String - } -`) - -func updateUserCollectionSchema() testUtils.SchemaUpdate { - return testUtils.SchemaUpdate{ - Schema: userCollectionGQLSchema, - } -} - -func updateCompaniesCollectionSchema() testUtils.SchemaUpdate { - return testUtils.SchemaUpdate{ - Schema: companiesCollectionGQLSchema, - } -} - -func executeTestCase(t *testing.T, test testUtils.RequestTestCase) { - testUtils.ExecuteRequestTestCase(t, userCollectionGQLSchema, []string{"Users"}, test) +func executeTestCase(t *testing.T, test testUtils.TestCase) { + testUtils.ExecuteTestCase( + t, + testUtils.TestCase{ + Description: test.Description, + Actions: append( + []any{ + testUtils.SchemaUpdate{ + Schema: userCollectionGQLSchema, + }, + }, + test.Actions..., + ), + }, + ) } diff --git a/tests/integration/query/latest_commits/with_collectionid_prop_test.go b/tests/integration/query/latest_commits/with_collectionid_prop_test.go index ae0758f6c2..70d4296bbe 100644 --- a/tests/integration/query/latest_commits/with_collectionid_prop_test.go +++ b/tests/integration/query/latest_commits/with_collectionid_prop_test.go @@ -20,8 +20,13 @@ func TestQueryLastCommitsWithCollectionIdProperty(t *testing.T) { test := testUtils.TestCase{ Description: "Simple latest commits query with collectionID property", Actions: []any{ - updateUserCollectionSchema(), - updateCompaniesCollectionSchema(), + testUtils.SchemaUpdate{ + Schema: ` + type Companies { + name: String + } + `, + }, testUtils.CreateDoc{ CollectionID: 0, Doc: `{ @@ -66,5 +71,5 @@ func TestQueryLastCommitsWithCollectionIdProperty(t *testing.T) { }, } - testUtils.ExecuteTestCase(t, test) + executeTestCase(t, test) } diff --git a/tests/integration/query/latest_commits/with_doc_id_field_test.go b/tests/integration/query/latest_commits/with_doc_id_field_test.go index bdaf4d5562..e96c2d2604 100644 --- a/tests/integration/query/latest_commits/with_doc_id_field_test.go +++ b/tests/integration/query/latest_commits/with_doc_id_field_test.go @@ -19,9 +19,17 @@ import ( // This test is for documentation reasons only. This is not // desired behaviour (it looks totally broken to me). func TestQueryLatestCommitsWithDocIDAndFieldName(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple latest commits query with docID and field name", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "age": 21 + }`, + }, + testUtils.Request{ + Request: `query { latestCommits(docID: "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", fieldId: "age") { cid links { @@ -30,17 +38,11 @@ func TestQueryLatestCommitsWithDocIDAndFieldName(t *testing.T) { } } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "age": 21 - }`, + Results: map[string]any{ + "latestCommits": []map[string]any{}, + }, }, }, - Results: map[string]any{ - "latestCommits": []map[string]any{}, - }, } executeTestCase(t, test) @@ -49,9 +51,17 @@ func TestQueryLatestCommitsWithDocIDAndFieldName(t *testing.T) { // This test is for documentation reasons only. This is not // desired behaviour (Users should not be specifying field ids). func TestQueryLatestCommitsWithDocIDAndFieldId(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple latest commits query with docID and field id", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "age": 21 + }`, + }, + testUtils.Request{ + Request: `query { latestCommits(docID: "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", fieldId: "1") { cid links { @@ -60,19 +70,13 @@ func TestQueryLatestCommitsWithDocIDAndFieldId(t *testing.T) { } } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "age": 21 - }`, - }, - }, - Results: map[string]any{ - "latestCommits": []map[string]any{ - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "links": []map[string]any{}, + Results: map[string]any{ + "latestCommits": []map[string]any{ + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "links": []map[string]any{}, + }, + }, }, }, }, @@ -84,9 +88,17 @@ func TestQueryLatestCommitsWithDocIDAndFieldId(t *testing.T) { // This test is for documentation reasons only. This is not // desired behaviour (Users should not be specifying field ids). func TestQueryLatestCommitsWithDocIDAndCompositeFieldId(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple latest commits query with docID and composite field id", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "age": 21 + }`, + }, + testUtils.Request{ + Request: `query { latestCommits(docID: "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3", fieldId: "C") { cid links { @@ -95,26 +107,20 @@ func TestQueryLatestCommitsWithDocIDAndCompositeFieldId(t *testing.T) { } } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "age": 21 - }`, - }, - }, - Results: map[string]any{ - "latestCommits": []map[string]any{ - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "links": []map[string]any{ - { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "name": "name", - }, + Results: map[string]any{ + "latestCommits": []map[string]any{ { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "name": "age", + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "links": []map[string]any{ + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "name": "name", + }, + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "name": "age", + }, + }, }, }, }, diff --git a/tests/integration/query/latest_commits/with_doc_id_prop_test.go b/tests/integration/query/latest_commits/with_doc_id_prop_test.go index 652d321973..9b978d89c0 100644 --- a/tests/integration/query/latest_commits/with_doc_id_prop_test.go +++ b/tests/integration/query/latest_commits/with_doc_id_prop_test.go @@ -20,13 +20,12 @@ func TestQueryLastCommitsWithDocIDProperty(t *testing.T) { test := testUtils.TestCase{ Description: "Simple latest commits query with docID property", Actions: []any{ - updateUserCollectionSchema(), testUtils.CreateDoc{ CollectionID: 0, Doc: `{ - "name": "John", - "age": 21 - }`, + "name": "John", + "age": 21 + }`, }, testUtils.Request{ Request: `query { @@ -45,5 +44,5 @@ func TestQueryLastCommitsWithDocIDProperty(t *testing.T) { }, } - testUtils.ExecuteTestCase(t, test) + executeTestCase(t, test) } diff --git a/tests/integration/query/latest_commits/with_doc_id_test.go b/tests/integration/query/latest_commits/with_doc_id_test.go index 4bd51d546d..9db8206b2e 100644 --- a/tests/integration/query/latest_commits/with_doc_id_test.go +++ b/tests/integration/query/latest_commits/with_doc_id_test.go @@ -17,9 +17,17 @@ import ( ) func TestQueryLatestCommitsWithDocID(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple latest commits query with docID", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "age": 21 + }`, + }, + testUtils.Request{ + Request: `query { latestCommits(docID: "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3") { cid links { @@ -28,26 +36,20 @@ func TestQueryLatestCommitsWithDocID(t *testing.T) { } } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "age": 21 - }`, - }, - }, - Results: map[string]any{ - "latestCommits": []map[string]any{ - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "links": []map[string]any{ + Results: map[string]any{ + "latestCommits": []map[string]any{ { - "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", - "name": "name", - }, - { - "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", - "name": "age", + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "links": []map[string]any{ + { + "cid": "bafyreic2sba5sffkfnt32wfeoaw4qsqozjb5acwwtouxuzllb3aymjwute", + "name": "name", + }, + { + "cid": "bafyreifzyy7bmpx2eywj4lznxzrzrvh6vrz6l7bhthkpexdq3wtho3vz6i", + "name": "age", + }, + }, }, }, }, @@ -59,27 +61,29 @@ func TestQueryLatestCommitsWithDocID(t *testing.T) { } func TestQueryLatestCommitsWithDocIDWithSchemaVersionIDField(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple latest commits query with docID and schema versiion id field", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "age": 21 + }`, + }, + testUtils.Request{ + Request: `query { latestCommits(docID: "bae-c9fb0fa4-1195-589c-aa54-e68333fb90b3") { cid schemaVersionId } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "age": 21 - }`, - }, - }, - Results: map[string]any{ - "latestCommits": []map[string]any{ - { - "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", - "schemaVersionId": "bafkreicprhqxzlw3akyssz2v6pifwfueavp7jq2yj3dghapi3qcq6achs4", + Results: map[string]any{ + "latestCommits": []map[string]any{ + { + "cid": "bafyreihv7jqe32wsuff5vwzlp7izoo6pqg6kgqf5edknp3mqm3344gu35q", + "schemaVersionId": "bafkreicprhqxzlw3akyssz2v6pifwfueavp7jq2yj3dghapi3qcq6achs4", + }, + }, }, }, }, diff --git a/tests/integration/query/latest_commits/with_field_test.go b/tests/integration/query/latest_commits/with_field_test.go index 67ae607c47..2440e7b4af 100644 --- a/tests/integration/query/latest_commits/with_field_test.go +++ b/tests/integration/query/latest_commits/with_field_test.go @@ -20,9 +20,17 @@ import ( // desired behaviour (should return all latest commits for given // field in the collection). func TestQueryLatestCommitsWithField(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple latest commits query with field", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "age": 21 + }`, + }, + testUtils.Request{ + Request: `query { latestCommits (fieldId: "Age") { cid links { @@ -31,15 +39,9 @@ func TestQueryLatestCommitsWithField(t *testing.T) { } } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "age": 21 - }`, + ExpectedError: "Field \"latestCommits\" argument \"docID\" of type \"ID!\" is required but not provided.", }, }, - ExpectedError: "Field \"latestCommits\" argument \"docID\" of type \"ID!\" is required but not provided.", } executeTestCase(t, test) @@ -49,9 +51,17 @@ func TestQueryLatestCommitsWithField(t *testing.T) { // desired behaviour (should return all latest commits for given // field in the collection). func TestQueryLatestCommitsWithFieldId(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple latest commits query with field", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "age": 21 + }`, + }, + testUtils.Request{ + Request: `query { latestCommits (fieldId: "1") { cid links { @@ -60,15 +70,9 @@ func TestQueryLatestCommitsWithFieldId(t *testing.T) { } } }`, - Docs: map[int][]string{ - 0: { - `{ - "name": "John", - "age": 21 - }`, + ExpectedError: "Field \"latestCommits\" argument \"docID\" of type \"ID!\" is required but not provided.", }, }, - ExpectedError: "Field \"latestCommits\" argument \"docID\" of type \"ID!\" is required but not provided.", } executeTestCase(t, test) diff --git a/tests/integration/query/one_to_many/simple_test.go b/tests/integration/query/one_to_many/simple_test.go index 44ee5f8cf5..6c0a73c7e8 100644 --- a/tests/integration/query/one_to_many/simple_test.go +++ b/tests/integration/query/one_to_many/simple_test.go @@ -17,45 +17,47 @@ import ( ) func TestQueryOneToMany(t *testing.T) { - tests := []testUtils.RequestTestCase{ + tests := []testUtils.TestCase{ { Description: "One-to-many relation query from one side", - Request: `query { - Book { - name - rating - author { - name - age - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, }, - //authors - 1: { // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, }, - }, - Results: map[string]any{ - "Book": []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "name": "John Grisham", - "age": int64(65), + testUtils.Request{ + Request: `query { + Book { + name + rating + author { + name + age + } + } + }`, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "name": "John Grisham", + "age": int64(65), + }, + }, }, }, }, @@ -63,74 +65,83 @@ func TestQueryOneToMany(t *testing.T) { }, { Description: "One-to-many relation query from many side", - Request: `query { - Author { - name - age - published { - name - rating - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" - }`, - `{ + }`, + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "Cornelia Funke", - "age": int64(62), - "published": []map[string]any{ - { - "name": "Theif Lord", - "rating": 4.8, - }, - }, - }, - { - "name": "John Grisham", - "age": int64(65), - "published": []map[string]any{ + testUtils.Request{ + Request: `query { + Author { + name + age + published { + name + rating + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "Painted House", - "rating": 4.9, + "name": "Cornelia Funke", + "age": int64(62), + "published": []map[string]any{ + { + "name": "Theif Lord", + "rating": 4.8, + }, + }, }, { - "name": "A Time for Mercy", - "rating": 4.5, + "name": "John Grisham", + "age": int64(65), + "published": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + { + "name": "A Time for Mercy", + "rating": 4.5, + }, + }, }, }, }, @@ -145,34 +156,35 @@ func TestQueryOneToMany(t *testing.T) { } func TestQueryOneToManyWithNonExistantParent(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from one side with non-existant parent", - Request: `query { - Book { - name - rating - author { - name - age - } - } - }`, - Docs: map[int][]string{ - //books - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, }, - }, - Results: map[string]any{ - "Book": []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - "author": nil, + testUtils.Request{ + Request: `query { + Book { + name + rating + author { + name + age + } + } + }`, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + "author": nil, + }, + }, }, }, }, diff --git a/tests/integration/query/one_to_many/utils.go b/tests/integration/query/one_to_many/utils.go index d1e25df661..df37e5990c 100644 --- a/tests/integration/query/one_to_many/utils.go +++ b/tests/integration/query/one_to_many/utils.go @@ -31,6 +31,19 @@ var bookAuthorGQLSchema = (` } `) -func executeTestCase(t *testing.T, test testUtils.RequestTestCase) { - testUtils.ExecuteRequestTestCase(t, bookAuthorGQLSchema, []string{"Book", "Author"}, test) +func executeTestCase(t *testing.T, test testUtils.TestCase) { + testUtils.ExecuteTestCase( + t, + testUtils.TestCase{ + Description: test.Description, + Actions: append( + []any{ + testUtils.SchemaUpdate{ + Schema: bookAuthorGQLSchema, + }, + }, + test.Actions..., + ), + }, + ) } diff --git a/tests/integration/query/one_to_many/with_count_filter_test.go b/tests/integration/query/one_to_many/with_count_filter_test.go index 261e5993e9..74d4cd6e29 100644 --- a/tests/integration/query/one_to_many/with_count_filter_test.go +++ b/tests/integration/query/one_to_many/with_count_filter_test.go @@ -17,58 +17,67 @@ import ( ) func TestQueryOneToManyWithCountWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from many side with count with filter", - Request: `query { - Author { - name - _count(published: {filter: {rating: {_gt: 4.8}}}) - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 0, - }, - { - "name": "John Grisham", - "_count": 1, + testUtils.Request{ + Request: `query { + Author { + name + _count(published: {filter: {rating: {_gt: 4.8}}}) + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_count": 0, + }, + { + "name": "John Grisham", + "_count": 1, + }, + }, }, }, }, @@ -78,76 +87,88 @@ func TestQueryOneToManyWithCountWithFilter(t *testing.T) { } func TestQueryOneToManyWithCountWithFilterAndChildFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from many side with count with filter", - Request: `query { - Author { - name - _count(published: {filter: {rating: {_ne: null}}}) - published(filter: {rating: {_ne: null}}){ - name - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Associate", "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 1, - "published": []map[string]any{ - { - "name": "Theif Lord", - }, - }, - }, - { - "name": "John Grisham", - "_count": 2, - "published": []map[string]any{ + testUtils.Request{ + Request: `query { + Author { + name + _count(published: {filter: {rating: {_ne: null}}}) + published(filter: {rating: {_ne: null}}){ + name + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "Painted House", + "name": "Cornelia Funke", + "_count": 1, + "published": []map[string]any{ + { + "name": "Theif Lord", + }, + }, }, { - "name": "A Time for Mercy", + "name": "John Grisham", + "_count": 2, + "published": []map[string]any{ + { + "name": "Painted House", + }, + { + "name": "A Time for Mercy", + }, + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_count_limit_offset_test.go b/tests/integration/query/one_to_many/with_count_limit_offset_test.go index eea8a504c7..ee0dc26e61 100644 --- a/tests/integration/query/one_to_many/with_count_limit_offset_test.go +++ b/tests/integration/query/one_to_many/with_count_limit_offset_test.go @@ -17,78 +17,93 @@ import ( ) func TestQueryOneToManyWithCountAndLimitAndOffset(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from many side with count and limit and offset", - Request: `query { - Author { - name - _count(published: {}) - published(limit: 2, offset: 1) { - name - } - } - }`, - Docs: map[int][]string{ - //books - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" - }`, - `{ + }`, + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Firm", "rating": 4.1, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" - }`, - `{ + }`, + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Pelican Brief", "rating": 4.0, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" - }`, - `{ + }`, + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 1, - "published": []map[string]any{}, - }, - { - "name": "John Grisham", - "_count": 4, - "published": []map[string]any{ + testUtils.Request{ + Request: `query { + Author { + name + _count(published: {}) + published(limit: 2, offset: 1) { + name + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "Painted House", + "name": "Cornelia Funke", + "_count": 1, + "published": []map[string]any{}, }, { - "name": "The Pelican Brief", + "name": "John Grisham", + "_count": 4, + "published": []map[string]any{ + { + "name": "Painted House", + }, + { + "name": "The Pelican Brief", + }, + }, }, }, }, @@ -100,77 +115,89 @@ func TestQueryOneToManyWithCountAndLimitAndOffset(t *testing.T) { } func TestQueryOneToManyWithCountAndDifferentOffsets(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from many side with count and limit and offset", - Request: `query { - Author { - name - _count(published: {offset: 1, limit: 2}) - published(limit: 2) { - name - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Associate", "rating": 4.2, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 0, - "published": []map[string]any{ - { - "name": "Theif Lord", - }, - }, - }, - { - "name": "John Grisham", - "_count": 2, - "published": []map[string]any{ + testUtils.Request{ + Request: `query { + Author { + name + _count(published: {offset: 1, limit: 2}) + published(limit: 2) { + name + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "The Associate", + "name": "Cornelia Funke", + "_count": 0, + "published": []map[string]any{ + { + "name": "Theif Lord", + }, + }, }, { - "name": "Painted House", + "name": "John Grisham", + "_count": 2, + "published": []map[string]any{ + { + "name": "The Associate", + }, + { + "name": "Painted House", + }, + }, }, }, }, @@ -182,58 +209,67 @@ func TestQueryOneToManyWithCountAndDifferentOffsets(t *testing.T) { } func TestQueryOneToManyWithCountWithLimitWithOffset(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from many side with count with limit with offset", - Request: `query { - Author { - name - _count(published: {offset: 1, limit: 1}) - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" - }`, - `{ + }`, + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 0, - }, - { - "name": "John Grisham", - "_count": 1, + testUtils.Request{ + Request: `query { + Author { + name + _count(published: {offset: 1, limit: 1}) + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_count": 0, + }, + { + "name": "John Grisham", + "_count": 1, + }, + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_count_limit_test.go b/tests/integration/query/one_to_many/with_count_limit_test.go index 3f7006d074..0b1cdaae96 100644 --- a/tests/integration/query/one_to_many/with_count_limit_test.go +++ b/tests/integration/query/one_to_many/with_count_limit_test.go @@ -17,69 +17,78 @@ import ( ) func TestQueryOneToManyWithCountAndLimit(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from many side with count and limit", - Request: `query { - Author { - name - _count(published: {}) - published(limit: 1) { - name - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" - }`, - `{ + }`, + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 1, - "published": []map[string]any{ + testUtils.Request{ + Request: `query { + Author { + name + _count(published: {}) + published(limit: 1) { + name + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "Theif Lord", + "name": "Cornelia Funke", + "_count": 1, + "published": []map[string]any{ + { + "name": "Theif Lord", + }, + }, }, - }, - }, - { - "name": "John Grisham", - "_count": 2, - "published": []map[string]any{ { - "name": "Painted House", + "name": "John Grisham", + "_count": 2, + "published": []map[string]any{ + { + "name": "Painted House", + }, + }, }, }, }, @@ -91,74 +100,86 @@ func TestQueryOneToManyWithCountAndLimit(t *testing.T) { } func TestQueryOneToManyWithCountAndDifferentLimits(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from many side with count and limit", - Request: `query { - Author { - name - _count(published: {limit: 2}) - published(limit: 1) { - name - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Associate", "rating": 4.2, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 1, - "published": []map[string]any{ + testUtils.Request{ + Request: `query { + Author { + name + _count(published: {limit: 2}) + published(limit: 1) { + name + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "Theif Lord", + "name": "Cornelia Funke", + "_count": 1, + "published": []map[string]any{ + { + "name": "Theif Lord", + }, + }, }, - }, - }, - { - "name": "John Grisham", - "_count": 2, - "published": []map[string]any{ { - "name": "The Associate", + "name": "John Grisham", + "_count": 2, + "published": []map[string]any{ + { + "name": "The Associate", + }, + }, }, }, }, @@ -170,58 +191,67 @@ func TestQueryOneToManyWithCountAndDifferentLimits(t *testing.T) { } func TestQueryOneToManyWithCountWithLimit(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from many side with count with limit", - Request: `query { - Author { - name - _count(published: {limit: 1}) - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 1, - }, - { - "name": "John Grisham", - "_count": 1, + testUtils.Request{ + Request: `query { + Author { + name + _count(published: {limit: 1}) + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_count": 1, + }, + { + "name": "John Grisham", + "_count": 1, + }, + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_count_test.go b/tests/integration/query/one_to_many/with_count_test.go index dba62fbf05..2b4e8a5fbe 100644 --- a/tests/integration/query/one_to_many/with_count_test.go +++ b/tests/integration/query/one_to_many/with_count_test.go @@ -17,86 +17,97 @@ import ( ) func TestQueryOneToManyWithCount(t *testing.T) { - tests := []testUtils.RequestTestCase{ + tests := []testUtils.TestCase{ { Description: "One-to-many relation query from many side with count, no child records", - Request: `query { - Author { - name - _count(published: {}) - } - }`, - Docs: map[int][]string{ - //authors - 1: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "John Grisham", - "_count": 0, + testUtils.Request{ + Request: `query { + Author { + name + _count(published: {}) + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "_count": 0, + }, + }, }, }, }, }, { Description: "One-to-many relation query from many side with count", - Request: `query { - Author { - name - _count(published: {}) - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "Cornelia Funke", - "_count": 1, - }, - { - "name": "John Grisham", - "_count": 2, + testUtils.Request{ + Request: `query { + Author { + name + _count(published: {}) + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_count": 1, + }, + { + "name": "John Grisham", + "_count": 2, + }, + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_doc_id_test.go b/tests/integration/query/one_to_many/with_doc_id_test.go index b00fd0a549..86551c5934 100644 --- a/tests/integration/query/one_to_many/with_doc_id_test.go +++ b/tests/integration/query/one_to_many/with_doc_id_test.go @@ -17,48 +17,53 @@ import ( ) func TestQueryOneToManyWithChildDocID(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from one side with child docID", - Request: `query { - Author { - name - published ( - docID: "bae-5366ba09-54e8-5381-8169-a770aa9282ae" - ) { - name - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-5366ba09-54e8-5381-8169-a770aa9282ae - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, }, - //authors - 1: { // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "John Grisham", - "published": []map[string]any{ + testUtils.Request{ + Request: `query { + Author { + name + published ( + docID: "bae-5366ba09-54e8-5381-8169-a770aa9282ae" + ) { + name + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "Painted House", + "name": "John Grisham", + "published": []map[string]any{ + { + "name": "Painted House", + }, + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_doc_ids_test.go b/tests/integration/query/one_to_many/with_doc_ids_test.go index 998c926909..b704cd0ddd 100644 --- a/tests/integration/query/one_to_many/with_doc_ids_test.go +++ b/tests/integration/query/one_to_many/with_doc_ids_test.go @@ -17,63 +17,72 @@ import ( ) func TestQueryOneToManyWithChildDocIDs(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from one side with child docIDs", - Request: `query { - Author { - name - published ( - docIDs: ["bae-5366ba09-54e8-5381-8169-a770aa9282ae", "bae-1ccf3043-d760-543e-be1b-6691fa6aa7a8"] - ) { - name - } - } - }`, - Docs: map[int][]string{ - //books - 0: { - // bae-5366ba09-54e8-5381-8169-a770aa9282ae - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - // bae-1ccf3043-d760-543e-be1b-6691fa6aa7a8 - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Associate", "rating": 4.2, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Firm", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, }, - //authors - 1: { // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "John Grisham", - "published": []map[string]any{ - { - "name": "The Associate", - }, + testUtils.Request{ + Request: `query { + Author { + name + published ( + docIDs: ["bae-5366ba09-54e8-5381-8169-a770aa9282ae", "bae-1ccf3043-d760-543e-be1b-6691fa6aa7a8"] + ) { + name + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "Painted House", + "name": "John Grisham", + "published": []map[string]any{ + { + "name": "The Associate", + }, + { + "name": "Painted House", + }, + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_filter_related_id_test.go b/tests/integration/query/one_to_many/with_filter_related_id_test.go index 6d8508e3c3..4f9bffaffb 100644 --- a/tests/integration/query/one_to_many/with_filter_related_id_test.go +++ b/tests/integration/query/one_to_many/with_filter_related_id_test.go @@ -17,77 +17,94 @@ import ( ) func TestQueryFromManySideWithEqFilterOnRelatedType(t *testing.T) { - test := testUtils.RequestTestCase{ - + test := testUtils.TestCase{ Description: "One-to-many query from many side with _eq filter on related field type.", - - Request: `query { - Book(filter: {author: {_docID: {_eq: "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b"}}}) { - name - } - }`, - - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Client", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Candide", "rating": 4.95, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Zadig", "rating": 4.91, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", "rating": 2, "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Voltaire", "age": 327, "verified": true }`, - // bae-34a9bd41-1f0d-5748-8446-48fc36ef2614 - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Simon Pelloutier", "age": 327, "verified": true }`, }, - }, - Results: map[string]any{ - "Book": []map[string]any{ - {"name": "The Client"}, - {"name": "Painted House"}, - {"name": "A Time for Mercy"}, + testUtils.Request{ + Request: `query { + Book(filter: {author: {_docID: {_eq: "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b"}}}) { + name + } + }`, + Results: map[string]any{ + "Book": []map[string]any{ + {"name": "The Client"}, + {"name": "Painted House"}, + {"name": "A Time for Mercy"}, + }, + }, }, }, } @@ -96,77 +113,94 @@ func TestQueryFromManySideWithEqFilterOnRelatedType(t *testing.T) { } func TestQueryFromManySideWithFilterOnRelatedObjectID(t *testing.T) { - test := testUtils.RequestTestCase{ - + test := testUtils.TestCase{ Description: "One-to-many query from many side with filter on related field.", - - Request: `query { - Book(filter: {author_id: {_eq: "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b"}}) { - name - } - }`, - - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Client", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Candide", "rating": 4.95, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Zadig", "rating": 4.91, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", "rating": 2, "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Voltaire", "age": 327, "verified": true }`, - // bae-34a9bd41-1f0d-5748-8446-48fc36ef2614 - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Simon Pelloutier", "age": 327, "verified": true }`, }, - }, - Results: map[string]any{ - "Book": []map[string]any{ - {"name": "The Client"}, - {"name": "Painted House"}, - {"name": "A Time for Mercy"}, + testUtils.Request{ + Request: `query { + Book(filter: {author_id: {_eq: "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b"}}) { + name + } + }`, + Results: map[string]any{ + "Book": []map[string]any{ + {"name": "The Client"}, + {"name": "Painted House"}, + {"name": "A Time for Mercy"}, + }, + }, }, }, } @@ -175,82 +209,99 @@ func TestQueryFromManySideWithFilterOnRelatedObjectID(t *testing.T) { } func TestQueryFromManySideWithSameFiltersInDifferentWayOnRelatedType(t *testing.T) { - test := testUtils.RequestTestCase{ - + test := testUtils.TestCase{ Description: "One-to-many query from many side with same filters in different way on related type.", - - Request: `query { - Book( - filter: { - author: {_docID: {_eq: "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b"}}, - author_id: {_eq: "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b"} - } - ) { - name - } - }`, - - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Client", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Candide", "rating": 4.95, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Zadig", "rating": 4.91, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", "rating": 2, "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Voltaire", "age": 327, "verified": true }`, - // bae-34a9bd41-1f0d-5748-8446-48fc36ef2614 - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Simon Pelloutier", "age": 327, "verified": true }`, }, - }, - Results: map[string]any{ - "Book": []map[string]any{ - {"name": "The Client"}, - {"name": "Painted House"}, - {"name": "A Time for Mercy"}, + testUtils.Request{ + Request: `query { + Book( + filter: { + author: {_docID: {_eq: "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b"}}, + author_id: {_eq: "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b"} + } + ) { + name + } + }`, + Results: map[string]any{ + "Book": []map[string]any{ + {"name": "The Client"}, + {"name": "Painted House"}, + {"name": "A Time for Mercy"}, + }, + }, }, }, } @@ -259,76 +310,93 @@ func TestQueryFromManySideWithSameFiltersInDifferentWayOnRelatedType(t *testing. } func TestQueryFromSingleSideWithEqFilterOnRelatedType(t *testing.T) { - test := testUtils.RequestTestCase{ - + test := testUtils.TestCase{ Description: "One-to-many query from single side with _eq filter on related field type.", - - Request: `query { - Author(filter: {published: {_docID: {_eq: "bae-96c9de0f-2903-5589-9604-b42882afde8c"}}}) { - name - } - }`, - - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Client", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Candide", "rating": 4.95, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Zadig", "rating": 4.91, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", "rating": 2, "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Voltaire", "age": 327, "verified": true }`, - // bae-34a9bd41-1f0d-5748-8446-48fc36ef2614 - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Simon Pelloutier", "age": 327, "verified": true }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "John Grisham", + testUtils.Request{ + Request: `query { + Author(filter: {published: {_docID: {_eq: "bae-96c9de0f-2903-5589-9604-b42882afde8c"}}}) { + name + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + }, + }, }, }, }, @@ -338,74 +406,90 @@ func TestQueryFromSingleSideWithEqFilterOnRelatedType(t *testing.T) { } func TestQueryFromSingleSideWithFilterOnRelatedObjectID_Error(t *testing.T) { - test := testUtils.RequestTestCase{ - + test := testUtils.TestCase{ Description: "One-to-many query from single side with filter on related field.", - - Request: `query { - Author(filter: {published_id: {_eq: "bae-5366ba09-54e8-5381-8169-a770aa9282ae"}}) { - name - } - }`, - - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Client", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Candide", "rating": 4.95, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Zadig", "rating": 4.91, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", "rating": 2, "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Voltaire", "age": 327, "verified": true }`, - // bae-34a9bd41-1f0d-5748-8446-48fc36ef2614 - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Simon Pelloutier", "age": 327, "verified": true }`, }, + testUtils.Request{ + Request: `query { + Author(filter: {published_id: {_eq: "bae-5366ba09-54e8-5381-8169-a770aa9282ae"}}) { + name + } + }`, + ExpectedError: "Argument \"filter\" has invalid value {published_id: {_eq: \"bae-5366ba09-54e8-5381-8169-a770aa9282ae\"}}.\nIn field \"published_id\": Unknown field.", + }, }, - - ExpectedError: "Argument \"filter\" has invalid value {published_id: {_eq: \"bae-5366ba09-54e8-5381-8169-a770aa9282ae\"}}.\nIn field \"published_id\": Unknown field.", } executeTestCase(t, test) diff --git a/tests/integration/query/one_to_many/with_group_filter_test.go b/tests/integration/query/one_to_many/with_group_filter_test.go index 38deb0cc20..5071b963cf 100644 --- a/tests/integration/query/one_to_many/with_group_filter_test.go +++ b/tests/integration/query/one_to_many/with_group_filter_test.go @@ -17,110 +17,131 @@ import ( ) func TestQueryOneToManyWithParentJoinGroupNumberAndNumberFilterOnJoin(t *testing.T) { - tests := []testUtils.RequestTestCase{ + tests := []testUtils.TestCase{ { Description: "One-to-many relation query from many side with parent level group and filter on join", - Request: `query { - Author (groupBy: [age]) { - age - _group { - name - published (filter: {rating: {_gt: 4.6}}) { - name - rating - } - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Client", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Candide", "rating": 4.95, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Zadig", "rating": 4.91, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", "rating": 2, "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Voltaire", "age": 327, "verified": true }`, - // bae-34a9bd41-1f0d-5748-8446-48fc36ef2614 - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Simon Pelloutier", "age": 327, "verified": true }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "age": int64(327), - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Author (groupBy: [age]) { + age + _group { + name + published (filter: {rating: {_gt: 4.6}}) { + name + rating + } + } + } + }`, + + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "Voltaire", - "published": []map[string]any{ + "age": int64(327), + "_group": []map[string]any{ { - "name": "Candide", - "rating": 4.95, + "name": "Voltaire", + "published": []map[string]any{ + { + "name": "Candide", + "rating": 4.95, + }, + { + "name": "Zadig", + "rating": 4.91, + }, + }, }, { - "name": "Zadig", - "rating": 4.91, + "name": "Simon Pelloutier", + "published": []map[string]any{}, }, }, }, { - "name": "Simon Pelloutier", - "published": []map[string]any{}, - }, - }, - }, - { - "age": int64(65), - "_group": []map[string]any{ - { - "name": "John Grisham", - "published": []map[string]any{ + "age": int64(65), + "_group": []map[string]any{ { - "name": "Painted House", - "rating": 4.9, + "name": "John Grisham", + "published": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + }, }, }, }, @@ -137,114 +158,134 @@ func TestQueryOneToManyWithParentJoinGroupNumberAndNumberFilterOnJoin(t *testing } func TestQueryOneToManyWithParentJoinGroupNumberAndNumberFilterOnGroup(t *testing.T) { - tests := []testUtils.RequestTestCase{ + tests := []testUtils.TestCase{ { Description: "One-to-many relation query from many side with parent level group and group filter", - Request: `query { - Author (groupBy: [age]) { - age - _group (filter: {published: {rating: {_gt: 4.6}}}) { - name - published { - name - rating - } - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Client", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Candide", "rating": 4.95, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Zadig", "rating": 4.91, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", "rating": 2, "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Voltaire", "age": 327, "verified": true }`, - // bae-34a9bd41-1f0d-5748-8446-48fc36ef2614 - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Simon Pelloutier", "age": 327, "verified": true }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "age": int64(327), - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Author (groupBy: [age]) { + age + _group (filter: {published: {rating: {_gt: 4.6}}}) { + name + published { + name + rating + } + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "Voltaire", - "published": []map[string]any{ - { - "name": "Candide", - "rating": 4.95, - }, + "age": int64(327), + "_group": []map[string]any{ { - "name": "Zadig", - "rating": 4.91, + "name": "Voltaire", + "published": []map[string]any{ + { + "name": "Candide", + "rating": 4.95, + }, + { + "name": "Zadig", + "rating": 4.91, + }, + }, }, }, }, - }, - }, - { - "age": int64(65), - "_group": []map[string]any{ { - "name": "John Grisham", - "published": []map[string]any{ + "age": int64(65), + "_group": []map[string]any{ { - "name": "The Client", - "rating": 4.5, - }, - { - "name": "Painted House", - "rating": 4.9, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, + "name": "John Grisham", + "published": []map[string]any{ + { + "name": "The Client", + "rating": 4.5, + }, + { + "name": "Painted House", + "rating": 4.9, + }, + { + "name": "A Time for Mercy", + "rating": 4.5, + }, + }, }, }, }, @@ -261,95 +302,115 @@ func TestQueryOneToManyWithParentJoinGroupNumberAndNumberFilterOnGroup(t *testin } func TestQueryOneToManyWithParentJoinGroupNumberAndNumberFilterOnGroupAndOnGroupJoin(t *testing.T) { - tests := []testUtils.RequestTestCase{ + tests := []testUtils.TestCase{ { Description: "One-to-many relation query from many side with parent level group and filters", - Request: `query { - Author (groupBy: [age], filter: {age: {_gt: 300}}) { - age - _group { - name - published (filter: {rating: {_gt: 4.91}}){ - name - rating - } - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Client", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Candide", "rating": 4.95, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Zadig", "rating": 4.91, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", "rating": 2, "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Voltaire", "age": 327, "verified": true }`, - // bae-34a9bd41-1f0d-5748-8446-48fc36ef2614 - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Simon Pelloutier", "age": 327, "verified": true }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "age": int64(327), - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Author (groupBy: [age], filter: {age: {_gt: 300}}) { + age + _group { + name + published (filter: {rating: {_gt: 4.91}}){ + name + rating + } + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "Voltaire", - "published": []map[string]any{ + "age": int64(327), + "_group": []map[string]any{ + { + "name": "Voltaire", + "published": []map[string]any{ + { + "name": "Candide", + "rating": 4.95, + }, + }, + }, { - "name": "Candide", - "rating": 4.95, + "name": "Simon Pelloutier", + "published": []map[string]any{}, }, }, }, - { - "name": "Simon Pelloutier", - "published": []map[string]any{}, - }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_group_related_id_alias_test.go b/tests/integration/query/one_to_many/with_group_related_id_alias_test.go index 9dde09334d..2847b0da2c 100644 --- a/tests/integration/query/one_to_many/with_group_related_id_alias_test.go +++ b/tests/integration/query/one_to_many/with_group_related_id_alias_test.go @@ -765,147 +765,185 @@ func TestQueryOneToManyWithParentGroupByOnRelatedTypeWithIDSelectionFromManySide } func TestQueryOneToManyWithParentGroupByOnRelatedTypeFromSingleSideUsingAlias(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many query with groupBy on related id field alias (from single side).", - Request: `query { - Author(groupBy: [published]) { - _group { - name - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Client", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Candide", "rating": 4.95, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Zadig", "rating": 4.91, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", "rating": 2, "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Voltaire", "age": 327, "verified": true }`, - // bae-34a9bd41-1f0d-5748-8446-48fc36ef2614 - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Simon Pelloutier", "age": 327, "verified": true }`, }, + testUtils.Request{ + Request: `query { + Author(groupBy: [published]) { + _group { + name + } + } + }`, + ExpectedError: "invalid field value to groupBy. Field: published", + }, }, - - ExpectedError: "invalid field value to groupBy. Field: published", } executeTestCase(t, test) } func TestQueryOneToManyWithParentGroupByOnRelatedTypeWithIDSelectionFromSingleSideUsingAlias(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many query with groupBy on related id field alias, with id selection (from single side).", - Request: `query { - Author(groupBy: [published]) { - published_id - _group { - name - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Client", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Candide", "rating": 4.95, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Zadig", "rating": 4.91, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", "rating": 2, "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Voltaire", "age": 327, "verified": true }`, - // bae-34a9bd41-1f0d-5748-8446-48fc36ef2614 - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Simon Pelloutier", "age": 327, "verified": true }`, }, + testUtils.Request{ + Request: `query { + Author(groupBy: [published]) { + published_id + _group { + name + } + } + }`, + ExpectedError: "Cannot query field \"published_id\" on type \"Author\". ", + }, }, - - ExpectedError: "Cannot query field \"published_id\" on type \"Author\". ", } executeTestCase(t, test) diff --git a/tests/integration/query/one_to_many/with_group_related_id_test.go b/tests/integration/query/one_to_many/with_group_related_id_test.go index da3a1cac3f..86d391a2f6 100644 --- a/tests/integration/query/one_to_many/with_group_related_id_test.go +++ b/tests/integration/query/one_to_many/with_group_related_id_test.go @@ -17,138 +17,158 @@ import ( ) func TestQueryOneToManyWithParentGroupByOnRelatedTypeIDFromManySide(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many query with groupBy on related id (from many side).", - Request: `query { - Book(groupBy: [author_id]) { - author_id - _group { - name - rating - author { - name - age - } - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Client", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Candide", "rating": 4.95, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Zadig", "rating": 4.91, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", "rating": 2, "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Voltaire", "age": 327, "verified": true }`, - // bae-34a9bd41-1f0d-5748-8446-48fc36ef2614 - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Simon Pelloutier", "age": 327, "verified": true }`, }, - }, - Results: map[string]any{ - "Book": []map[string]any{ - { - "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", - "_group": []map[string]any{ - { - "name": "The Client", - "rating": 4.5, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", - }, - }, - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", - }, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", - }, - }, - }, - }, - { - "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Book(groupBy: [author_id]) { + author_id + _group { + name + rating + author { + name + age + } + } + } + }`, + Results: map[string]any{ + "Book": []map[string]any{ { - "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", - "rating": 2.0, - "author": map[string]any{ - "age": int64(327), - "name": "Simon Pelloutier", + "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", + "_group": []map[string]any{ + { + "name": "The Client", + "rating": 4.5, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, + }, + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, + }, + { + "name": "A Time for Mercy", + "rating": 4.5, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, + }, }, }, - }, - }, - { - "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", - "_group": []map[string]any{ { - "name": "Candide", - "rating": 4.95, - "author": map[string]any{ - "age": int64(327), - "name": "Voltaire", + "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", + "_group": []map[string]any{ + { + "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", + "rating": 2.0, + "author": map[string]any{ + "age": int64(327), + "name": "Simon Pelloutier", + }, + }, }, }, { - "name": "Zadig", - "rating": 4.91, - "author": map[string]any{ - "age": int64(327), - "name": "Voltaire", + "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", + "_group": []map[string]any{ + { + "name": "Candide", + "rating": 4.95, + "author": map[string]any{ + "age": int64(327), + "name": "Voltaire", + }, + }, + { + "name": "Zadig", + "rating": 4.91, + "author": map[string]any{ + "age": int64(327), + "name": "Voltaire", + }, + }, }, }, }, @@ -161,138 +181,158 @@ func TestQueryOneToManyWithParentGroupByOnRelatedTypeIDFromManySide(t *testing.T } func TestQueryOneToManyWithParentGroupByOnRelatedTypeIDWithIDSelectionFromManySide(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many query with groupBy on related id, with id selection (from many side).", - Request: `query { - Book(groupBy: [author_id]) { - author_id - _group { - name - rating - author { - name - age - } - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Client", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Candide", "rating": 4.95, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Zadig", "rating": 4.91, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", "rating": 2, "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Voltaire", "age": 327, "verified": true }`, - // bae-34a9bd41-1f0d-5748-8446-48fc36ef2614 - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Simon Pelloutier", "age": 327, "verified": true }`, }, - }, - Results: map[string]any{ - "Book": []map[string]any{ - { - "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", - "_group": []map[string]any{ - { - "name": "The Client", - "rating": 4.5, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", - }, - }, - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", - }, - }, - { - "name": "A Time for Mercy", - "rating": 4.5, - "author": map[string]any{ - "age": int64(65), - "name": "John Grisham", - }, - }, - }, - }, - { - "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Book(groupBy: [author_id]) { + author_id + _group { + name + rating + author { + name + age + } + } + } + }`, + Results: map[string]any{ + "Book": []map[string]any{ { - "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", - "rating": 2.0, - "author": map[string]any{ - "age": int64(327), - "name": "Simon Pelloutier", + "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", + "_group": []map[string]any{ + { + "name": "The Client", + "rating": 4.5, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, + }, + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, + }, + { + "name": "A Time for Mercy", + "rating": 4.5, + "author": map[string]any{ + "age": int64(65), + "name": "John Grisham", + }, + }, }, }, - }, - }, - { - "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", - "_group": []map[string]any{ { - "name": "Candide", - "rating": 4.95, - "author": map[string]any{ - "age": int64(327), - "name": "Voltaire", + "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", + "_group": []map[string]any{ + { + "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", + "rating": 2.0, + "author": map[string]any{ + "age": int64(327), + "name": "Simon Pelloutier", + }, + }, }, }, { - "name": "Zadig", - "rating": 4.91, - "author": map[string]any{ - "age": int64(327), - "name": "Voltaire", + "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", + "_group": []map[string]any{ + { + "name": "Candide", + "rating": 4.95, + "author": map[string]any{ + "age": int64(327), + "name": "Voltaire", + }, + }, + { + "name": "Zadig", + "rating": 4.91, + "author": map[string]any{ + "age": int64(327), + "name": "Voltaire", + }, + }, }, }, }, @@ -305,155 +345,193 @@ func TestQueryOneToManyWithParentGroupByOnRelatedTypeIDWithIDSelectionFromManySi } func TestQueryOneToManyWithParentGroupByOnRelatedTypeFromSingleSide(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many query with groupBy on related id (from single side).", - Request: `query { - Author(groupBy: [published_id]) { - _group { - name - published { - name - rating - } - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Client", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Candide", "rating": 4.95, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Zadig", "rating": 4.91, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", "rating": 2, "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Voltaire", "age": 327, "verified": true }`, - // bae-34a9bd41-1f0d-5748-8446-48fc36ef2614 - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Simon Pelloutier", "age": 327, "verified": true }`, }, + testUtils.Request{ + Request: `query { + Author(groupBy: [published_id]) { + _group { + name + published { + name + rating + } + } + } + }`, + ExpectedError: "Argument \"groupBy\" has invalid value [published_id].\nIn element #1: Expected type \"AuthorField\", found published_id.", + }, }, - - ExpectedError: "Argument \"groupBy\" has invalid value [published_id].\nIn element #1: Expected type \"AuthorField\", found published_id.", } executeTestCase(t, test) } func TestQueryOneToManyWithParentGroupByOnRelatedTypeWithIDSelectionFromSingleSide(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many query with groupBy on related id, with id selection (from single side).", - Request: `query { - Author(groupBy: [published_id]) { - published_id - _group { - name - published { - name - rating - } - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Client", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Candide", "rating": 4.95, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Zadig", "rating": 4.91, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", "rating": 2, "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Voltaire", "age": 327, "verified": true }`, - // bae-34a9bd41-1f0d-5748-8446-48fc36ef2614 - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Simon Pelloutier", "age": 327, "verified": true }`, }, + testUtils.Request{ + Request: `query { + Author(groupBy: [published_id]) { + published_id + _group { + name + published { + name + rating + } + } + } + }`, + ExpectedError: "Argument \"groupBy\" has invalid value [published_id].\nIn element #1: Expected type \"AuthorField\", found published_id.", + }, }, - - ExpectedError: "Argument \"groupBy\" has invalid value [published_id].\nIn element #1: Expected type \"AuthorField\", found published_id.", } executeTestCase(t, test) diff --git a/tests/integration/query/one_to_many/with_group_test.go b/tests/integration/query/one_to_many/with_group_test.go index b1fe1034f8..421c785dbe 100644 --- a/tests/integration/query/one_to_many/with_group_test.go +++ b/tests/integration/query/one_to_many/with_group_test.go @@ -17,97 +17,109 @@ import ( ) func TestQueryOneToManyWithInnerJoinGroupNumber(t *testing.T) { - tests := []testUtils.RequestTestCase{ + tests := []testUtils.TestCase{ { Description: "One-to-many relation query from many side with group inside of join", - Request: `query { - Author { - name - age - published (groupBy: [rating]){ - rating - _group { - name - } - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Client", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "Cornelia Funke", - "age": int64(62), - "published": []map[string]any{ + testUtils.Request{ + Request: `query { + Author { + name + age + published (groupBy: [rating]){ + rating + _group { + name + } + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ { - "rating": 4.8, - "_group": []map[string]any{ + "name": "Cornelia Funke", + "age": int64(62), + "published": []map[string]any{ { - "name": "Theif Lord", + "rating": 4.8, + "_group": []map[string]any{ + { + "name": "Theif Lord", + }, + }, }, }, }, - }, - }, - { - "name": "John Grisham", - "age": int64(65), - "published": []map[string]any{ { - "rating": 4.5, - "_group": []map[string]any{ + "name": "John Grisham", + "age": int64(65), + "published": []map[string]any{ { - "name": "The Client", + "rating": 4.5, + "_group": []map[string]any{ + { + "name": "The Client", + }, + { + "name": "A Time for Mercy", + }, + }, }, { - "name": "A Time for Mercy", - }, - }, - }, - { - "rating": 4.9, - "_group": []map[string]any{ - { - "name": "Painted House", + "rating": 4.9, + "_group": []map[string]any{ + { + "name": "Painted House", + }, + }, }, }, }, @@ -124,122 +136,142 @@ func TestQueryOneToManyWithInnerJoinGroupNumber(t *testing.T) { } func TestQueryOneToManyWithParentJoinGroupNumber(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from many side with parent level group", - Request: `query { - Author (groupBy: [age]) { - age - _group { - name - published { - name - rating - } - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Client", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Candide", "rating": 4.95, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Zadig", "rating": 4.91, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ - "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", - "rating": 2, - "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614" - }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ + "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", + "rating": 2, + "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614" + }`, + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Voltaire", "age": 327, "verified": true }`, - // bae-34a9bd41-1f0d-5748-8446-48fc36ef2614 - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Simon Pelloutier", "age": 327, "verified": true }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "age": int64(327), - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Author (groupBy: [age]) { + age + _group { + name + published { + name + rating + } + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "Voltaire", - "published": []map[string]any{ + "age": int64(327), + "_group": []map[string]any{ { - "name": "Candide", - "rating": 4.95, + "name": "Voltaire", + "published": []map[string]any{ + { + "name": "Candide", + "rating": 4.95, + }, + { + "name": "Zadig", + "rating": 4.91, + }, + }, }, { - "name": "Zadig", - "rating": 4.91, - }, - }, - }, - { - "name": "Simon Pelloutier", - "published": []map[string]any{ - { - "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", - "rating": float64(2), + "name": "Simon Pelloutier", + "published": []map[string]any{ + { + "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", + "rating": float64(2), + }, + }, }, }, }, - }, - }, - { - "age": int64(65), - "_group": []map[string]any{ { - "name": "John Grisham", - "published": []map[string]any{ - { - "name": "The Client", - "rating": 4.5, - }, - { - "name": "Painted House", - "rating": 4.9, - }, + "age": int64(65), + "_group": []map[string]any{ { - "name": "A Time for Mercy", - "rating": 4.5, + "name": "John Grisham", + "published": []map[string]any{ + { + "name": "The Client", + "rating": 4.5, + }, + { + "name": "Painted House", + "rating": 4.9, + }, + { + "name": "A Time for Mercy", + "rating": 4.5, + }, + }, }, }, }, @@ -253,23 +285,26 @@ func TestQueryOneToManyWithParentJoinGroupNumber(t *testing.T) { } func TestQueryOneToManyWithInnerJoinGroupNumberWithNonGroupFieldsSelected(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from many side with group inside of join and invalid field", - Request: `query { - Author { - name - age - published (groupBy: [rating]){ - rating - name - _group { + Actions: []any{ + testUtils.Request{ + Request: `query { + Author { name + age + published (groupBy: [rating]){ + rating + name + _group { + name + } + } } - } - } - }`, - Docs: map[int][]string{}, - ExpectedError: "cannot select a non-group-by field at group-level", + }`, + ExpectedError: "cannot select a non-group-by field at group-level", + }, + }, } executeTestCase(t, test) diff --git a/tests/integration/query/one_to_many/with_limit_test.go b/tests/integration/query/one_to_many/with_limit_test.go index 1cfbaf6d98..8badd8f742 100644 --- a/tests/integration/query/one_to_many/with_limit_test.go +++ b/tests/integration/query/one_to_many/with_limit_test.go @@ -17,69 +17,78 @@ import ( ) func TestQueryOneToManyWithSingleChildLimit(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from many side with limit", - Request: `query { - Author { - name - published (limit: 1) { - name - rating - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "Cornelia Funke", - "published": []map[string]any{ + testUtils.Request{ + Request: `query { + Author { + name + published (limit: 1) { + name + rating + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "Theif Lord", - "rating": 4.8, + "name": "Cornelia Funke", + "published": []map[string]any{ + { + "name": "Theif Lord", + "rating": 4.8, + }, + }, }, - }, - }, - { - "name": "John Grisham", - "published": []map[string]any{ { - "name": "Painted House", - "rating": 4.9, + "name": "John Grisham", + "published": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + }, }, }, }, @@ -91,89 +100,98 @@ func TestQueryOneToManyWithSingleChildLimit(t *testing.T) { } func TestQueryOneToManyWithMultipleChildLimits(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from many side with limit", - Request: `query { - Author { - name - p1: published (limit: 1) { - name - rating - } - p2: published (limit: 2) { - name - rating - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "Cornelia Funke", - "p1": []map[string]any{ - { - "name": "Theif Lord", - "rating": 4.8, - }, - }, - "p2": []map[string]any{ - { - "name": "Theif Lord", - "rating": 4.8, - }, - }, - }, - { - "name": "John Grisham", - "p1": []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - }, - }, - "p2": []map[string]any{ + testUtils.Request{ + Request: `query { + Author { + name + p1: published (limit: 1) { + name + rating + } + p2: published (limit: 2) { + name + rating + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "Painted House", - "rating": 4.9, + "name": "Cornelia Funke", + "p1": []map[string]any{ + { + "name": "Theif Lord", + "rating": 4.8, + }, + }, + "p2": []map[string]any{ + { + "name": "Theif Lord", + "rating": 4.8, + }, + }, }, { - "name": "A Time for Mercy", - "rating": 4.5, + "name": "John Grisham", + "p1": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + }, + "p2": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + { + "name": "A Time for Mercy", + "rating": 4.5, + }, + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_order_filter_limit_test.go b/tests/integration/query/one_to_many/with_order_filter_limit_test.go index d10fabb100..f1602985d1 100644 --- a/tests/integration/query/one_to_many/with_order_filter_limit_test.go +++ b/tests/integration/query/one_to_many/with_order_filter_limit_test.go @@ -19,62 +19,71 @@ import ( func TestQueryOneToManyWithNumericGreaterThanFilterOnParentAndNumericSortAscendingAndLimitOnChild( t *testing.T, ) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from the many side, asc. order & limit on sub", - Request: `query { - Author(filter: {age: {_gt: 63}}) { - name - age - published(order: {rating: ASC}, limit: 1) { - name - rating - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "John Grisham", - "age": int64(65), - "published": []map[string]any{ + testUtils.Request{ + Request: `query { + Author(filter: {age: {_gt: 63}}) { + name + age + published(order: {rating: ASC}, limit: 1) { + name + rating + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "A Time for Mercy", - "rating": 4.5, + "name": "John Grisham", + "age": int64(65), + "published": []map[string]any{ + { + "name": "A Time for Mercy", + "rating": 4.5, + }, + }, }, }, }, @@ -88,62 +97,71 @@ func TestQueryOneToManyWithNumericGreaterThanFilterOnParentAndNumericSortAscendi func TestQueryOneToManyWithNumericGreaterThanFilterOnParentAndNumericSortDescendingAndLimitOnChild( t *testing.T, ) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from the many side, desc. order & limit on sub", - Request: `query { - Author(filter: {age: {_gt: 63}}) { - name - age - published(order: {rating: DESC}, limit: 1) { - name - rating - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "John Grisham", - "age": int64(65), - "published": []map[string]any{ + testUtils.Request{ + Request: `query { + Author(filter: {age: {_gt: 63}}) { + name + age + published(order: {rating: DESC}, limit: 1) { + name + rating + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "Painted House", - "rating": 4.9, + "name": "John Grisham", + "age": int64(65), + "published": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_order_filter_test.go b/tests/integration/query/one_to_many/with_order_filter_test.go index 3aec1e6a73..42ec0f85d5 100644 --- a/tests/integration/query/one_to_many/with_order_filter_test.go +++ b/tests/integration/query/one_to_many/with_order_filter_test.go @@ -19,66 +19,75 @@ import ( func TestQueryOneToManyWithNumericGreaterThanFilterOnParentAndNumericSortAscendingOnChild( t *testing.T, ) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from the many side, order on sub", - Request: `query { - Author(filter: {age: {_gt: 63}}) { - name - age - published(order: {rating: ASC}) { - name - rating - } - } - }`, - Docs: map[int][]string{ - //books - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "John Grisham", - "age": int64(65), - "published": []map[string]any{ - { - "name": "A Time for Mercy", - "rating": 4.5, - }, + testUtils.Request{ + Request: `query { + Author(filter: {age: {_gt: 63}}) { + name + age + published(order: {rating: ASC}) { + name + rating + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "Painted House", - "rating": 4.9, + "name": "John Grisham", + "age": int64(65), + "published": []map[string]any{ + { + "name": "A Time for Mercy", + "rating": 4.5, + }, + { + "name": "Painted House", + "rating": 4.9, + }, + }, }, }, }, @@ -90,76 +99,85 @@ func TestQueryOneToManyWithNumericGreaterThanFilterOnParentAndNumericSortAscendi } func TestQueryOneToManyWithNumericGreaterThanFilterAndNumericSortDescendingOnChild(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from the many side, filter on sub from root", - Request: `query { - Author(filter: {published: {rating: {_gt: 4.1}}}) { - name - age - published(order: {rating: DESC}) { - name - rating - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "Cornelia Funke", - "age": int64(62), - "published": []map[string]any{ - { - "name": "Theif Lord", - "rating": 4.8, - }, - }, - }, - { - "name": "John Grisham", - "age": int64(65), - "published": []map[string]any{ + testUtils.Request{ + Request: `query { + Author(filter: {published: {rating: {_gt: 4.1}}}) { + name + age + published(order: {rating: DESC}) { + name + rating + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "Painted House", - "rating": 4.9, + "name": "Cornelia Funke", + "age": int64(62), + "published": []map[string]any{ + { + "name": "Theif Lord", + "rating": 4.8, + }, + }, }, { - "name": "A Time for Mercy", - "rating": 4.5, + "name": "John Grisham", + "age": int64(65), + "published": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + { + "name": "A Time for Mercy", + "rating": 4.5, + }, + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_related_id_test.go b/tests/integration/query/one_to_many/with_related_id_test.go index c5955352b5..906719c532 100644 --- a/tests/integration/query/one_to_many/with_related_id_test.go +++ b/tests/integration/query/one_to_many/with_related_id_test.go @@ -17,100 +17,115 @@ import ( ) func TestQueryOneToManyWithRelatedTypeIDFromManySide(t *testing.T) { - test := testUtils.RequestTestCase{ - + test := testUtils.TestCase{ Description: "One-to-many query with related id (from many side).", - - Request: `query { - Book { - name - author_id - } - }`, - - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Client", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Candide", "rating": 4.95, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Zadig", "rating": 4.91, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", "rating": 2, "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614" }`, }, - - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Voltaire", "age": 327, "verified": true }`, - // bae-34a9bd41-1f0d-5748-8446-48fc36ef2614 - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Simon Pelloutier", "age": 327, "verified": true }`, }, - }, - - Results: map[string]any{ - "Book": []map[string]any{ - { - "name": "The Client", - "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", - }, - { - "name": "Painted House", - "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", - }, - { - "name": "A Time for Mercy", - "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", - }, - { - "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", - "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", - }, - { - "name": "Candide", - "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", - }, - { - "name": "Zadig", - "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", + testUtils.Request{ + Request: `query { + Book { + name + author_id + } + }`, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "The Client", + "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", + }, + { + "name": "Painted House", + "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", + }, + { + "name": "A Time for Mercy", + "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b", + }, + { + "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", + "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614", + }, + { + "name": "Candide", + "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", + }, + { + "name": "Zadig", + "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c", + }, + }, }, }, }, @@ -120,76 +135,91 @@ func TestQueryOneToManyWithRelatedTypeIDFromManySide(t *testing.T) { } func TestQueryOneToManyWithRelatedTypeIDFromSingleSide(t *testing.T) { - test := testUtils.RequestTestCase{ - + test := testUtils.TestCase{ Description: "One-to-many query with related id (from single side).", - - Request: `query { - Author { - name - author_id - } - }`, - - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Client", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Candide", "rating": 4.95, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Zadig", "rating": 4.91, "author_id": "bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Histoiare des Celtes et particulierement des Gaulois et des Germains depuis les temps fabuleux jusqua la prise de Roze par les Gaulois", "rating": 2, "author_id": "bae-34a9bd41-1f0d-5748-8446-48fc36ef2614" }`, }, - - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-1594d2aa-d63c-51d2-8e5e-06ee0c9e2e8c - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Voltaire", "age": 327, "verified": true }`, - // bae-34a9bd41-1f0d-5748-8446-48fc36ef2614 - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Simon Pelloutier", "age": 327, "verified": true }`, }, + testUtils.Request{ + Request: `query { + Author { + name + author_id + } + }`, + ExpectedError: "Cannot query field \"author_id\" on type \"Author\".", + }, }, - - ExpectedError: "Cannot query field \"author_id\" on type \"Author\".", } executeTestCase(t, test) diff --git a/tests/integration/query/one_to_many/with_same_field_name_test.go b/tests/integration/query/one_to_many/with_same_field_name_test.go index fbe56099b5..c16774ac25 100644 --- a/tests/integration/query/one_to_many/with_same_field_name_test.go +++ b/tests/integration/query/one_to_many/with_same_field_name_test.go @@ -17,10 +17,10 @@ import ( ) var sameFieldNameGQLSchema = (` - type Book { - name: String - relationship1: Author - } + type Book { + name: String + relationship1: Author + } type Author { name: String @@ -28,43 +28,58 @@ var sameFieldNameGQLSchema = (` } `) -func executeSameFieldNameTestCase(t *testing.T, test testUtils.RequestTestCase) { - testUtils.ExecuteRequestTestCase(t, sameFieldNameGQLSchema, []string{"Book", "Author"}, test) +func executeSameFieldNameTestCase(t *testing.T, test testUtils.TestCase) { + testUtils.ExecuteTestCase( + t, + testUtils.TestCase{ + Description: test.Description, + Actions: append( + []any{ + testUtils.SchemaUpdate{ + Schema: sameFieldNameGQLSchema, + }, + }, + test.Actions..., + ), + }, + ) } func TestQueryOneToManyWithSameFieldName(t *testing.T) { - tests := []testUtils.RequestTestCase{ + tests := []testUtils.TestCase{ { Description: "One-to-many relation query from one side, same field name", - Request: `query { - Book { - name - relationship1 { - name - } - } - }`, - Docs: map[int][]string{ - //books - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "relationship1_id": "bae-ee5973cf-73c3-558f-8aec-8b590b8e77cf" }`, }, - //authors - 1: { // bae-ee5973cf-73c3-558f-8aec-8b590b8e77cf - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham" }`, }, - }, - Results: map[string]any{ - "Book": []map[string]any{ - { - "name": "Painted House", - "relationship1": map[string]any{ - "name": "John Grisham", + testUtils.Request{ + Request: `query { + Book { + name + relationship1 { + name + } + } + }`, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "relationship1": map[string]any{ + "name": "John Grisham", + }, + }, }, }, }, @@ -72,36 +87,39 @@ func TestQueryOneToManyWithSameFieldName(t *testing.T) { }, { Description: "One-to-many relation query from many side, same field name", - Request: `query { - Author { - name - relationship1 { - name - } - } - }`, - Docs: map[int][]string{ - //books - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "relationship1_id": "bae-ee5973cf-73c3-558f-8aec-8b590b8e77cf" }`, }, - //authors - 1: { // bae-ee5973cf-73c3-558f-8aec-8b590b8e77cf - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham" }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "John Grisham", - "relationship1": []map[string]any{ + testUtils.Request{ + Request: `query { + Author { + name + relationship1 { + name + } + } + }`, + + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "Painted House", + "name": "John Grisham", + "relationship1": []map[string]any{ + { + "name": "Painted House", + }, + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_sum_filter_order_test.go b/tests/integration/query/one_to_many/with_sum_filter_order_test.go index 0c2fcc0b70..46d36c82d8 100644 --- a/tests/integration/query/one_to_many/with_sum_filter_order_test.go +++ b/tests/integration/query/one_to_many/with_sum_filter_order_test.go @@ -17,88 +17,111 @@ import ( ) func TestOneToManyAscOrderAndFilterOnParentWithAggSumOnSubTypeField(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "1-N ascending order & filter on parent, with sum on on subtype field.", - Request: `query { - Author(order: {age: ASC}, filter: {age: {_gt: 8}}) { - name - _sum(published: {field: rating}) - } - }`, - - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Associate", "rating": 4.2, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Sooley", "rating": 3.2, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Rooster Bar", "rating": 4, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Little Kid", "age": 6, "verified": true }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Not a Writer", "age": 85, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "Cornelia Funke", - "_sum": 4.8, - }, - { - "name": "John Grisham", - "_sum": 20.8, - }, - { - "name": "Not a Writer", - "_sum": 0.0, + testUtils.Request{ + Request: `query { + Author(order: {age: ASC}, filter: {age: {_gt: 8}}) { + name + _sum(published: {field: rating}) + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_sum": 4.8, + }, + { + "name": "John Grisham", + "_sum": 20.8, + }, + { + "name": "Not a Writer", + "_sum": 0.0, + }, + }, }, }, }, @@ -108,88 +131,111 @@ func TestOneToManyAscOrderAndFilterOnParentWithAggSumOnSubTypeField(t *testing.T } func TestOneToManyDescOrderAndFilterOnParentWithAggSumOnSubTypeField(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "1-N descending order & filter on parent, with sum on on subtype field.", - Request: `query { - Author(order: {age: DESC}, filter: {age: {_gt: 8}}) { - name - _sum(published: {field: rating}) - } - }`, - - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Associate", "rating": 4.2, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Sooley", "rating": 3.2, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Rooster Bar", "rating": 4, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Little Kid", "age": 6, "verified": true }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Not a Writer", "age": 85, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "Not a Writer", - "_sum": 0.0, - }, - { - "name": "John Grisham", - "_sum": 20.8, - }, - { - "name": "Cornelia Funke", - "_sum": 4.8, + testUtils.Request{ + Request: `query { + Author(order: {age: DESC}, filter: {age: {_gt: 8}}) { + name + _sum(published: {field: rating}) + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Not a Writer", + "_sum": 0.0, + }, + { + "name": "John Grisham", + "_sum": 20.8, + }, + { + "name": "Cornelia Funke", + "_sum": 4.8, + }, + }, }, }, }, @@ -199,97 +245,120 @@ func TestOneToManyDescOrderAndFilterOnParentWithAggSumOnSubTypeField(t *testing. } func TestOnetoManySumBySubTypeFieldAndSumBySybTypeFieldWithDescOrderingOnFieldWithLimit(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "1-N sum subtype and sum subtype with desc. order on field with limit.", - Request: `query { - Author { - name - sum1: _sum(published: {field: rating}) - sum2: _sum(published: {field: rating, limit: 2, order: {rating: DESC}}) - } - }`, - - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Associate", "rating": 4.2, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Sooley", "rating": 3.2, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Rooster Bar", "rating": 4, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Little Kid", "age": 6, "verified": true }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Not a Writer", "age": 85, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "Little Kid", - "sum1": 0.0, - "sum2": 0.0, - }, - { - "name": "Not a Writer", - "sum1": 0.0, - "sum2": 0.0, - }, - { - "name": "Cornelia Funke", - "sum1": 4.8, - "sum2": 4.8, - }, - { - "name": "John Grisham", - "sum1": 20.8, - "sum2": 4.9 + 4.5, + testUtils.Request{ + Request: `query { + Author { + name + sum1: _sum(published: {field: rating}) + sum2: _sum(published: {field: rating, limit: 2, order: {rating: DESC}}) + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Little Kid", + "sum1": 0.0, + "sum2": 0.0, + }, + { + "name": "Not a Writer", + "sum1": 0.0, + "sum2": 0.0, + }, + { + "name": "Cornelia Funke", + "sum1": 4.8, + "sum2": 4.8, + }, + { + "name": "John Grisham", + "sum1": 20.8, + "sum2": 4.9 + 4.5, + }, + }, }, }, }, @@ -299,97 +368,120 @@ func TestOnetoManySumBySubTypeFieldAndSumBySybTypeFieldWithDescOrderingOnFieldWi } func TestOnetoManySumBySubTypeFieldAndSumBySybTypeFieldWithAscOrderingOnFieldWithLimit(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "1-N sum subtype and sum subtype with asc. order on field with limit.", - Request: `query { - Author { - name - sum1: _sum(published: {field: rating}) - sum2: _sum(published: {field: rating, limit: 2, order: {rating: ASC}}) - } - }`, - - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Associate", "rating": 4.2, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Sooley", "rating": 3.2, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Rooster Bar", "rating": 4, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Little Kid", "age": 6, "verified": true }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Not a Writer", "age": 85, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "Little Kid", - "sum1": 0.0, - "sum2": 0.0, - }, - { - "name": "Not a Writer", - "sum1": 0.0, - "sum2": 0.0, - }, - { - "name": "Cornelia Funke", - "sum1": 4.8, - "sum2": 4.8, - }, - { - "name": "John Grisham", - "sum1": 20.8, - "sum2": 4.0 + 3.2, + testUtils.Request{ + Request: `query { + Author { + name + sum1: _sum(published: {field: rating}) + sum2: _sum(published: {field: rating, limit: 2, order: {rating: ASC}}) + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Little Kid", + "sum1": 0.0, + "sum2": 0.0, + }, + { + "name": "Not a Writer", + "sum1": 0.0, + "sum2": 0.0, + }, + { + "name": "Cornelia Funke", + "sum1": 4.8, + "sum2": 4.8, + }, + { + "name": "John Grisham", + "sum1": 20.8, + "sum2": 4.0 + 3.2, + }, + }, }, }, }, @@ -399,103 +491,126 @@ func TestOnetoManySumBySubTypeFieldAndSumBySybTypeFieldWithAscOrderingOnFieldWit } func TestOneToManyLimitAscOrderSumOfSubTypeAndLimitAscOrderFieldsOfSubtype(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "1-N sum of subtype float field with limit and asc. order, and non-sum query of same subtype fields.", - Request: `query { - Author { - LimitOrderSum: _sum(published: {field: rating, limit: 2, order: {rating: ASC}}) - LimitOrderFields: published(order: {rating: ASC}, limit: 2) { - name - } - } - }`, - - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Associate", "rating": 4.2, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Sooley", "rating": 3.2, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Rooster Bar", "rating": 4, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Little Kid", "age": 6, "verified": true }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Not a Writer", "age": 85, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "LimitOrderSum": 0.0, - "LimitOrderFields": []map[string]any{}, - }, - { - "LimitOrderSum": 0.0, - "LimitOrderFields": []map[string]any{}, - }, - { - "LimitOrderSum": 4.8, - "LimitOrderFields": []map[string]any{ + testUtils.Request{ + Request: `query { + Author { + LimitOrderSum: _sum(published: {field: rating, limit: 2, order: {rating: ASC}}) + LimitOrderFields: published(order: {rating: ASC}, limit: 2) { + name + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "Theif Lord", + "LimitOrderSum": 0.0, + "LimitOrderFields": []map[string]any{}, + }, + { + "LimitOrderSum": 0.0, + "LimitOrderFields": []map[string]any{}, }, - }, - }, - { - "LimitOrderSum": 3.2 + 4.0, - "LimitOrderFields": []map[string]any{ { - "name": "Sooley", + "LimitOrderSum": 4.8, + "LimitOrderFields": []map[string]any{ + { + "name": "Theif Lord", + }, + }, }, { - "name": "The Rooster Bar", + "LimitOrderSum": 3.2 + 4.0, + "LimitOrderFields": []map[string]any{ + { + "name": "Sooley", + }, + { + "name": "The Rooster Bar", + }, + }, }, }, }, @@ -507,103 +622,126 @@ func TestOneToManyLimitAscOrderSumOfSubTypeAndLimitAscOrderFieldsOfSubtype(t *te } func TestOneToManyLimitDescOrderSumOfSubTypeAndLimitAscOrderFieldsOfSubtype(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "1-N sum of subtype float field with limit and desc. order, and non-sum query of same subtype fields.", - Request: `query { - Author { - LimitOrderSum: _sum(published: {field: rating, limit: 2, order: {rating: DESC}}) - LimitOrderFields: published(order: {rating: DESC}, limit: 2) { - name - } - } - }`, - - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Associate", "rating": 4.2, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Sooley", "rating": 3.2, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Rooster Bar", "rating": 4, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Little Kid", "age": 6, "verified": true }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Not a Writer", "age": 85, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "LimitOrderSum": 0.0, - "LimitOrderFields": []map[string]any{}, - }, - { - "LimitOrderSum": 0.0, - "LimitOrderFields": []map[string]any{}, - }, - { - "LimitOrderSum": 4.8, - "LimitOrderFields": []map[string]any{ + testUtils.Request{ + Request: `query { + Author { + LimitOrderSum: _sum(published: {field: rating, limit: 2, order: {rating: DESC}}) + LimitOrderFields: published(order: {rating: DESC}, limit: 2) { + name + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ { - "name": "Theif Lord", + "LimitOrderSum": 0.0, + "LimitOrderFields": []map[string]any{}, + }, + { + "LimitOrderSum": 0.0, + "LimitOrderFields": []map[string]any{}, }, - }, - }, - { - "LimitOrderSum": 4.9 + 4.5, - "LimitOrderFields": []map[string]any{ { - "name": "Painted House", + "LimitOrderSum": 4.8, + "LimitOrderFields": []map[string]any{ + { + "name": "Theif Lord", + }, + }, }, { - "name": "A Time for Mercy", + "LimitOrderSum": 4.9 + 4.5, + "LimitOrderFields": []map[string]any{ + { + "name": "Painted House", + }, + { + "name": "A Time for Mercy", + }, + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_sum_limit_offset_test.go b/tests/integration/query/one_to_many/with_sum_limit_offset_test.go index 3fce23bfd5..420deeca19 100644 --- a/tests/integration/query/one_to_many/with_sum_limit_offset_test.go +++ b/tests/integration/query/one_to_many/with_sum_limit_offset_test.go @@ -17,63 +17,75 @@ import ( ) func TestQueryOneToManyWithSumWithLimitAndOffset(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from many side with sum with limit and offset", - Request: `query { - Author { - name - _sum(published: {field: rating, offset: 1, limit: 2}) - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Associate", "rating": 4.2, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "Cornelia Funke", - "_sum": float64(0), - }, - { - "name": "John Grisham", - "_sum": 9.4, + testUtils.Request{ + Request: `query { + Author { + name + _sum(published: {field: rating, offset: 1, limit: 2}) + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_sum": float64(0), + }, + { + "name": "John Grisham", + "_sum": 9.4, + }, + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_sum_limit_test.go b/tests/integration/query/one_to_many/with_sum_limit_test.go index 4ab46b65bd..b3cfba74b0 100644 --- a/tests/integration/query/one_to_many/with_sum_limit_test.go +++ b/tests/integration/query/one_to_many/with_sum_limit_test.go @@ -17,64 +17,76 @@ import ( ) func TestQueryOneToManyWithSumWithLimit(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from many side with sum with limit", - Request: `query { - Author { - name - _sum(published: {field: rating, limit: 2}) - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "A Time for Mercy", "rating": 4.5, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "The Associate", "rating": 4.2, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8, "author_id": "bae-72e8c691-9f20-55e7-9228-8af1cf54cace" }`, }, - //authors - 1: { - // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, - // bae-72e8c691-9f20-55e7-9228-8af1cf54cace - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "Cornelia Funke", - "_sum": 4.8, - }, - { - "name": "John Grisham", - // .00...1 is float math thing - "_sum": 9.100000000000001, + testUtils.Request{ + Request: `query { + Author { + name + _sum(published: {field: rating, limit: 2}) + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "Cornelia Funke", + "_sum": 4.8, + }, + { + "name": "John Grisham", + // .00...1 is float math thing + "_sum": 9.100000000000001, + }, + }, }, }, }, diff --git a/tests/integration/query/one_to_many/with_typename_test.go b/tests/integration/query/one_to_many/with_typename_test.go index da627c8625..b4852b2d4e 100644 --- a/tests/integration/query/one_to_many/with_typename_test.go +++ b/tests/integration/query/one_to_many/with_typename_test.go @@ -17,44 +17,46 @@ import ( ) func TestQueryOneToManyWithTypeName(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-many relation query from one side with typename", - Request: `query { - Book { - name - __typename - author { - name - __typename - } - } - }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9, "author_id": "bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b" }`, }, - //authors - 1: { // bae-e1ea288f-09fa-55fa-b0b5-0ac8941ea35b - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true }`, }, - }, - Results: map[string]any{ - "Book": []map[string]any{ - { - "name": "Painted House", - "__typename": "Book", - "author": map[string]any{ - "name": "John Grisham", - "__typename": "Author", + testUtils.Request{ + Request: `query { + Book { + name + __typename + author { + name + __typename + } + } + }`, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "__typename": "Book", + "author": map[string]any{ + "name": "John Grisham", + "__typename": "Author", + }, + }, }, }, }, diff --git a/tests/integration/query/one_to_one/simple_test.go b/tests/integration/query/one_to_one/simple_test.go index 2ebad49df6..4433c3ff9c 100644 --- a/tests/integration/query/one_to_one/simple_test.go +++ b/tests/integration/query/one_to_one/simple_test.go @@ -17,10 +17,28 @@ import ( ) func TestQueryOneToOne(t *testing.T) { - tests := []testUtils.RequestTestCase{ + tests := []testUtils.TestCase{ { Description: "One-to-one relation query with no filter", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ + "name": "Painted House", + "rating": 4.9 + }`, + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ + "name": "John Grisham", + "age": 65, + "verified": true, + "published_id": "bae-be6d8024-4953-5a92-84b4-f042d25230c6" + }`, + }, + testUtils.Request{ + Request: `query { Book { name rating @@ -30,40 +48,42 @@ func TestQueryOneToOne(t *testing.T) { } } }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "name": "John Grisham", + "age": int64(65), + }, + }, + }, + }, + }, + }, + }, + { + Description: "One-to-one relation secondary direction, no filter", + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9 }`, }, - //authors - 1: { // bae-7aabc9d2-fbbc-5911-b0d0-b49a2a1d0e84 - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true, "published_id": "bae-be6d8024-4953-5a92-84b4-f042d25230c6" }`, }, - }, - Results: map[string]any{ - "Book": []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "name": "John Grisham", - "age": int64(65), - }, - }, - }, - }, - }, - { - Description: "One-to-one relation secondary direction, no filter", - Request: `query { + testUtils.Request{ + Request: `query { Author { name age @@ -73,32 +93,16 @@ func TestQueryOneToOne(t *testing.T) { } } }`, - Docs: map[int][]string{ - //books - 0: { // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ - "name": "Painted House", - "rating": 4.9 - }`, - }, - //authors - 1: { // bae-7aabc9d2-fbbc-5911-b0d0-b49a2a1d0e84 - `{ - "name": "John Grisham", - "age": 65, - "verified": true, - "published_id": "bae-be6d8024-4953-5a92-84b4-f042d25230c6" - }`, - }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "John Grisham", - "age": int64(65), - "published": map[string]any{ - "name": "Painted House", - "rating": 4.9, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "age": int64(65), + "published": map[string]any{ + "name": "Painted House", + "rating": 4.9, + }, + }, }, }, }, @@ -274,29 +278,31 @@ func TestQueryOneToOneWithMultipleRecordsSecondaryDirection(t *testing.T) { } func TestQueryOneToOneWithNilChild(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-one relation primary direction, nil child", - Request: `query { - Author { - name - published { - name - } - } - }`, - Docs: map[int][]string{ - //authors - 1: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham" }`, }, - }, - Results: map[string]any{ - "Author": []map[string]any{ - { - "name": "John Grisham", - "published": nil, + testUtils.Request{ + Request: `query { + Author { + name + published { + name + } + } + }`, + Results: map[string]any{ + "Author": []map[string]any{ + { + "name": "John Grisham", + "published": nil, + }, + }, }, }, }, @@ -306,29 +312,30 @@ func TestQueryOneToOneWithNilChild(t *testing.T) { } func TestQueryOneToOneWithNilParent(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-one relation primary direction, nil parent", - Request: `query { - Book { - name - author { - name - } - } - }`, - Docs: map[int][]string{ - //books - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "name": "Painted House" }`, }, - }, - Results: map[string]any{ - "Book": []map[string]any{ - { - "name": "Painted House", - "author": nil, + testUtils.Request{ + Request: `query { + Book { + name + author { + name + } + } + }`, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "author": nil, + }, + }, }, }, }, diff --git a/tests/integration/query/one_to_one/utils.go b/tests/integration/query/one_to_one/utils.go index 64aa7590fb..0778ce4b0a 100644 --- a/tests/integration/query/one_to_one/utils.go +++ b/tests/integration/query/one_to_one/utils.go @@ -31,6 +31,19 @@ var bookAuthorGQLSchema = ` } ` -func executeTestCase(t *testing.T, test testUtils.RequestTestCase) { - testUtils.ExecuteRequestTestCase(t, bookAuthorGQLSchema, []string{"Book", "Author"}, test) +func executeTestCase(t *testing.T, test testUtils.TestCase) { + testUtils.ExecuteTestCase( + t, + testUtils.TestCase{ + Description: test.Description, + Actions: append( + []any{ + testUtils.SchemaUpdate{ + Schema: bookAuthorGQLSchema, + }, + }, + test.Actions..., + ), + }, + ) } diff --git a/tests/integration/query/one_to_one/with_filter_order_test.go b/tests/integration/query/one_to_one/with_filter_order_test.go index 24682d4fb4..90682b31e3 100644 --- a/tests/integration/query/one_to_one/with_filter_order_test.go +++ b/tests/integration/query/one_to_one/with_filter_order_test.go @@ -17,58 +17,62 @@ import ( ) func TestOnetoOneSubTypeDscOrderByQueryWithFilterHavinghNoSubTypeSelections(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-one subtype descending order query with filter, no subtype child fields selected.", - Request: `query { - Book( - filter: {author: {age: {_gt: 5}}}, - order: {author: {age: DESC}} - ){ - name - rating - } - }`, - Docs: map[int][]string{ - //books - 0: { - // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9 }`, - // bae-26a28d23-ae5b-5257-91b7-d4f2c6abef7b - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8 }`, }, - //authors - 1: { - // "bae-3bfe0092-e31f-5ebe-a3ba-fa18fac448a6" - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true, "published_id": "bae-be6d8024-4953-5a92-84b4-f042d25230c6" }`, - // "bae-08519989-280d-5a4d-90b2-915ea06df3c4" - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false, "published_id": "bae-26a28d23-ae5b-5257-91b7-d4f2c6abef7b" }`, }, - }, - Results: map[string]any{ - "Book": []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - }, - { - "name": "Theif Lord", - "rating": 4.8, + testUtils.Request{ + Request: `query { + Book( + filter: {author: {age: {_gt: 5}}}, + order: {author: {age: DESC}} + ){ + name + rating + } + }`, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + { + "name": "Theif Lord", + "rating": 4.8, + }, + }, }, }, }, @@ -78,58 +82,62 @@ func TestOnetoOneSubTypeDscOrderByQueryWithFilterHavinghNoSubTypeSelections(t *t } func TestOnetoOneSubTypeAscOrderByQueryWithFilterHavinghNoSubTypeSelections(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-one subtype ascending order query with filter, no subtype child fields selected.", - Request: `query { - Book( - filter: {author: {age: {_gt: 5}}}, - order: {author: {age: ASC}} - ){ - name - rating - } - }`, - Docs: map[int][]string{ - //books - 0: { - // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9 }`, - // bae-26a28d23-ae5b-5257-91b7-d4f2c6abef7b - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8 }`, }, - //authors - 1: { - // "bae-3bfe0092-e31f-5ebe-a3ba-fa18fac448a6" - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true, "published_id": "bae-be6d8024-4953-5a92-84b4-f042d25230c6" }`, - // "bae-08519989-280d-5a4d-90b2-915ea06df3c4" - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false, "published_id": "bae-26a28d23-ae5b-5257-91b7-d4f2c6abef7b" }`, }, - }, - Results: map[string]any{ - "Book": []map[string]any{ - { - "name": "Theif Lord", - "rating": 4.8, - }, - { - "name": "Painted House", - "rating": 4.9, + testUtils.Request{ + Request: `query { + Book( + filter: {author: {age: {_gt: 5}}}, + order: {author: {age: ASC}} + ){ + name + rating + } + }`, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Theif Lord", + "rating": 4.8, + }, + { + "name": "Painted House", + "rating": 4.9, + }, + }, }, }, }, diff --git a/tests/integration/query/one_to_one/with_order_test.go b/tests/integration/query/one_to_one/with_order_test.go index 9a2ca8c4c9..3475ebfc63 100644 --- a/tests/integration/query/one_to_one/with_order_test.go +++ b/tests/integration/query/one_to_one/with_order_test.go @@ -17,66 +17,70 @@ import ( ) func TestQueryOneToOneWithChildBooleanOrderDescending(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-one relation query with simple descending order by sub type", - Request: `query { - Book(order: {author: {verified: DESC}}) { - name - rating - author { - name - age - } - } - }`, - Docs: map[int][]string{ - //books - 0: { - // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9 }`, - // bae-26a28d23-ae5b-5257-91b7-d4f2c6abef7b - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8 }`, }, - //authors - 1: { - // bae-7aabc9d2-fbbc-5911-b0d0-b49a2a1d0e84 - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true, "published_id": "bae-be6d8024-4953-5a92-84b4-f042d25230c6" }`, - // bae-b769708d-f552-5c3d-a402-ccfd7ac7fb04 - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false, "published_id": "bae-26a28d23-ae5b-5257-91b7-d4f2c6abef7b" }`, }, - }, - Results: map[string]any{ - "Book": []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "name": "John Grisham", - "age": int64(65), - }, - }, - { - "name": "Theif Lord", - "rating": 4.8, - "author": map[string]any{ - "name": "Cornelia Funke", - "age": int64(62), + testUtils.Request{ + Request: `query { + Book(order: {author: {verified: DESC}}) { + name + rating + author { + name + age + } + } + }`, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "name": "John Grisham", + "age": int64(65), + }, + }, + { + "name": "Theif Lord", + "rating": 4.8, + "author": map[string]any{ + "name": "Cornelia Funke", + "age": int64(62), + }, + }, }, }, }, @@ -87,66 +91,70 @@ func TestQueryOneToOneWithChildBooleanOrderDescending(t *testing.T) { } func TestQueryOneToOneWithChildBooleanOrderAscending(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "One-to-one relation query with simple ascending order by sub type", - Request: `query { - Book(order: {author: {verified: ASC}}) { - name - rating - author { - name - age - } - } - }`, - Docs: map[int][]string{ - //books - 0: { - // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9 }`, - // bae-26a28d23-ae5b-5257-91b7-d4f2c6abef7b - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8 }`, }, - //authors - 1: { - // bae-7aabc9d2-fbbc-5911-b0d0-b49a2a1d0e84 - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true, "published_id": "bae-be6d8024-4953-5a92-84b4-f042d25230c6" }`, - // bae-b769708d-f552-5c3d-a402-ccfd7ac7fb04 - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false, "published_id": "bae-26a28d23-ae5b-5257-91b7-d4f2c6abef7b" }`, }, - }, - Results: map[string]any{ - "Book": []map[string]any{ - { - "name": "Theif Lord", - "rating": 4.8, - "author": map[string]any{ - "name": "Cornelia Funke", - "age": int64(62), - }, - }, - { - "name": "Painted House", - "rating": 4.9, - "author": map[string]any{ - "name": "John Grisham", - "age": int64(65), + testUtils.Request{ + Request: `query { + Book(order: {author: {verified: ASC}}) { + name + rating + author { + name + age + } + } + }`, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Theif Lord", + "rating": 4.8, + "author": map[string]any{ + "name": "Cornelia Funke", + "age": int64(62), + }, + }, + { + "name": "Painted House", + "rating": 4.9, + "author": map[string]any{ + "name": "John Grisham", + "age": int64(65), + }, + }, }, }, }, @@ -157,55 +165,59 @@ func TestQueryOneToOneWithChildBooleanOrderAscending(t *testing.T) { } func TestQueryOneToOneWithChildIntOrderDescendingWithNoSubTypeFieldsSelected(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Relation query with descending order by sub-type's int field, but only parent fields are selected.", - Request: `query { - Book(order: {author: {age: DESC}}) { - name - rating - } - }`, - Docs: map[int][]string{ - //books - 0: { - // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9 }`, - // bae-26a28d23-ae5b-5257-91b7-d4f2c6abef7b - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8 }`, }, - //authors - 1: { - // "bae-3bfe0092-e31f-5ebe-a3ba-fa18fac448a6" - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true, "published_id": "bae-be6d8024-4953-5a92-84b4-f042d25230c6" }`, - // "bae-08519989-280d-5a4d-90b2-915ea06df3c4" - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false, "published_id": "bae-26a28d23-ae5b-5257-91b7-d4f2c6abef7b" }`, }, - }, - Results: map[string]any{ - "Book": []map[string]any{ - { - "name": "Painted House", - "rating": 4.9, - }, - { - "name": "Theif Lord", - "rating": 4.8, + testUtils.Request{ + Request: `query { + Book(order: {author: {age: DESC}}) { + name + rating + } + }`, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Painted House", + "rating": 4.9, + }, + { + "name": "Theif Lord", + "rating": 4.8, + }, + }, }, }, }, @@ -215,55 +227,59 @@ func TestQueryOneToOneWithChildIntOrderDescendingWithNoSubTypeFieldsSelected(t * } func TestQueryOneToOneWithChildIntOrderAscendingWithNoSubTypeFieldsSelected(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Relation query with ascending order by sub-type's int field, but only parent fields are selected.", - Request: `query { - Book(order: {author: {age: ASC}}) { - name - rating - } - }`, - Docs: map[int][]string{ - //books - 0: { - // bae-be6d8024-4953-5a92-84b4-f042d25230c6 - `{ + Actions: []any{ + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Painted House", "rating": 4.9 }`, - // bae-26a28d23-ae5b-5257-91b7-d4f2c6abef7b - `{ + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: `{ "name": "Theif Lord", "rating": 4.8 }`, }, - //authors - 1: { - // "bae-3bfe0092-e31f-5ebe-a3ba-fa18fac448a6" - `{ + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "John Grisham", "age": 65, "verified": true, "published_id": "bae-be6d8024-4953-5a92-84b4-f042d25230c6" }`, - // "bae-08519989-280d-5a4d-90b2-915ea06df3c4" - `{ + }, + testUtils.CreateDoc{ + CollectionID: 1, + Doc: `{ "name": "Cornelia Funke", "age": 62, "verified": false, "published_id": "bae-26a28d23-ae5b-5257-91b7-d4f2c6abef7b" }`, }, - }, - Results: map[string]any{ - "Book": []map[string]any{ - { - "name": "Theif Lord", - "rating": 4.8, - }, - { - "name": "Painted House", - "rating": 4.9, + testUtils.Request{ + Request: `query { + Book(order: {author: {age: ASC}}) { + name + rating + } + }`, + Results: map[string]any{ + "Book": []map[string]any{ + { + "name": "Theif Lord", + "rating": 4.8, + }, + { + "name": "Painted House", + "rating": 4.9, + }, + }, }, }, }, diff --git a/tests/integration/query/simple/simple_test.go b/tests/integration/query/simple/simple_test.go index fce69f1412..eff5b09d65 100644 --- a/tests/integration/query/simple/simple_test.go +++ b/tests/integration/query/simple/simple_test.go @@ -17,29 +17,31 @@ import ( ) func TestQuerySimple(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with no filter", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 21 + }`, + }, + testUtils.Request{ + Request: `query { Users { _docID Name Age } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 21 - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "_docID": "bae-d4303725-7db9-53d2-b324-f3ee44020e52", - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "_docID": "bae-d4303725-7db9-53d2-b324-f3ee44020e52", + "Name": "John", + "Age": int64(21), + }, + }, }, }, }, @@ -49,27 +51,29 @@ func TestQuerySimple(t *testing.T) { } func TestQuerySimpleWithAlias(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with alias, no filter", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 21 + }`, + }, + testUtils.Request{ + Request: `query { Users { username: Name age: Age } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 21 - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "username": "John", - "age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "username": "John", + "age": int64(21), + }, + }, }, }, }, @@ -79,35 +83,39 @@ func TestQuerySimpleWithAlias(t *testing.T) { } func TestQuerySimpleWithMultipleRows(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with no filter, multiple rows", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 21 + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "Name": "Bob", + "Age": 27 + }`, + }, + testUtils.Request{ + Request: `query { Users { Name Age } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 21 - }`, - `{ - "Name": "Bob", - "Age": 27 - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Bob", - "Age": int64(27), - }, - { - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + "Age": int64(27), + }, + { + "Name": "John", + "Age": int64(21), + }, + }, }, }, }, @@ -117,24 +125,35 @@ func TestQuerySimpleWithMultipleRows(t *testing.T) { } func TestQuerySimpleWithUndefinedField(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query for undefined field", - Request: `query { + Actions: []any{ + testUtils.Request{ + Request: `query { Users { Name ThisFieldDoesNotExists } }`, - ExpectedError: "Cannot query field \"ThisFieldDoesNotExists\" on type \"Users\".", + ExpectedError: "Cannot query field \"ThisFieldDoesNotExists\" on type \"Users\".", + }, + }, } executeTestCase(t, test) } func TestQuerySimpleWithSomeDefaultValues(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with some default-value fields", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John" + }`, + }, + testUtils.Request{ + Request: `query { Users { Name Email @@ -143,21 +162,16 @@ func TestQuerySimpleWithSomeDefaultValues(t *testing.T) { Verified } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John" - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Email": nil, - "Age": nil, - "HeightM": nil, - "Verified": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Email": nil, + "Age": nil, + "HeightM": nil, + "Verified": nil, + }, + }, }, }, }, @@ -167,9 +181,14 @@ func TestQuerySimpleWithSomeDefaultValues(t *testing.T) { } func TestQuerySimpleWithDefaultValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with default-value fields", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ }`, + }, + testUtils.Request{ + Request: `query { Users { Name Email @@ -178,19 +197,16 @@ func TestQuerySimpleWithDefaultValue(t *testing.T) { Verified } }`, - Docs: map[int][]string{ - 0: { - `{ }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": nil, - "Email": nil, - "Age": nil, - "HeightM": nil, - "Verified": nil, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": nil, + "Email": nil, + "Age": nil, + "HeightM": nil, + "Verified": nil, + }, + }, }, }, }, diff --git a/tests/integration/query/simple/utils.go b/tests/integration/query/simple/utils.go index 0343eca82c..0f2258e30e 100644 --- a/tests/integration/query/simple/utils.go +++ b/tests/integration/query/simple/utils.go @@ -27,6 +27,19 @@ var userCollectionGQLSchema = (` } `) -func executeTestCase(t *testing.T, test testUtils.RequestTestCase) { - testUtils.ExecuteRequestTestCase(t, userCollectionGQLSchema, []string{"Users"}, test) +func executeTestCase(t *testing.T, test testUtils.TestCase) { + testUtils.ExecuteTestCase( + t, + testUtils.TestCase{ + Description: test.Description, + Actions: append( + []any{ + testUtils.SchemaUpdate{ + Schema: userCollectionGQLSchema, + }, + }, + test.Actions..., + ), + }, + ) } diff --git a/tests/integration/query/simple/with_average_filter_test.go b/tests/integration/query/simple/with_average_filter_test.go index 48bf59ab89..0886d8f8f0 100644 --- a/tests/integration/query/simple/with_average_filter_test.go +++ b/tests/integration/query/simple/with_average_filter_test.go @@ -17,29 +17,35 @@ import ( ) func TestQuerySimpleWithAverageWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query, average with filter", - Request: `query { - _avg(Users: {field: Age, filter: {Age: {_gt: 26}}}) - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 30 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 32 }`, }, - }, - Results: map[string]any{ - "_avg": float64(31), + testUtils.Request{ + Request: `query { + _avg(Users: {field: Age, filter: {Age: {_gt: 26}}}) + }`, + Results: map[string]any{ + "_avg": float64(31), + }, + }, }, } @@ -47,32 +53,38 @@ func TestQuerySimpleWithAverageWithFilter(t *testing.T) { } func TestQuerySimpleWithAverageWithDateTimeFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query, average with datetime filter", - Request: `query { - _avg(Users: {field: Age, filter: {CreatedAt: {_gt: "2017-07-23T03:46:56-05:00"}}}) - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21, "CreatedAt": "2017-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 30, "CreatedAt": "2018-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 32, "CreatedAt": "2019-07-23T03:46:56-05:00" }`, }, - }, - Results: map[string]any{ - "_avg": float64(31), + testUtils.Request{ + Request: `query { + _avg(Users: {field: Age, filter: {CreatedAt: {_gt: "2017-07-23T03:46:56-05:00"}}}) + }`, + Results: map[string]any{ + "_avg": float64(31), + }, + }, }, } diff --git a/tests/integration/query/simple/with_average_test.go b/tests/integration/query/simple/with_average_test.go index 1237c21cb6..36aedd1ee8 100644 --- a/tests/integration/query/simple/with_average_test.go +++ b/tests/integration/query/simple/with_average_test.go @@ -17,37 +17,49 @@ import ( ) func TestQuerySimpleWithAverageOnUndefinedObject(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query, average on undefined object", - Request: `query { + Actions: []any{ + testUtils.Request{ + Request: `query { _avg }`, - ExpectedError: "aggregate must be provided with a property to aggregate", + ExpectedError: "aggregate must be provided with a property to aggregate", + }, + }, } executeTestCase(t, test) } func TestQuerySimpleWithAverageOnUndefinedField(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query, average on undefined field", - Request: `query { + Actions: []any{ + testUtils.Request{ + Request: `query { _avg(Users: {}) }`, - ExpectedError: "Argument \"Users\" has invalid value {}.\nIn field \"field\": Expected \"UsersNumericFieldsArg!\", found null.", + ExpectedError: "Argument \"Users\" has invalid value {}.\nIn field \"field\": Expected \"UsersNumericFieldsArg!\", found null.", + }, + }, } executeTestCase(t, test) } func TestQuerySimpleWithAverageOnEmptyCollection(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query, average on empty", - Request: `query { + Actions: []any{ + testUtils.Request{ + Request: `query { _avg(Users: {field: Age}) }`, - Results: map[string]any{ - "_avg": float64(0), + Results: map[string]any{ + "_avg": float64(0), + }, + }, }, } @@ -55,25 +67,29 @@ func TestQuerySimpleWithAverageOnEmptyCollection(t *testing.T) { } func TestQuerySimpleWithAverage(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query, average", - Request: `query { - _avg(Users: {field: Age}) - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 28 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 30 }`, }, - }, - Results: map[string]any{ - "_avg": float64(29), + testUtils.Request{ + Request: `query { + _avg(Users: {field: Age}) + }`, + Results: map[string]any{ + "_avg": float64(29), + }, + }, }, } diff --git a/tests/integration/query/simple/with_cid_test.go b/tests/integration/query/simple/with_cid_test.go index 044748a9b3..baa8b09402 100644 --- a/tests/integration/query/simple/with_cid_test.go +++ b/tests/integration/query/simple/with_cid_test.go @@ -17,22 +17,24 @@ import ( ) func TestQuerySimpleWithInvalidCid(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with cid", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 21 + }`, + }, + testUtils.Request{ + Request: `query { Users (cid: "any non-nil string value - this will be ignored") { Name } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 21 - }`, + ExpectedError: "invalid cid: selected encoding not supported", }, }, - ExpectedError: "invalid cid: selected encoding not supported", } executeTestCase(t, test) diff --git a/tests/integration/query/simple/with_count_filter_test.go b/tests/integration/query/simple/with_count_filter_test.go index 8bf9182bfe..d9055ab05e 100644 --- a/tests/integration/query/simple/with_count_filter_test.go +++ b/tests/integration/query/simple/with_count_filter_test.go @@ -17,29 +17,35 @@ import ( ) func TestQuerySimpleWithCountWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query, count with filter", - Request: `query { - _count(Users: {filter: {Age: {_gt: 26}}}) - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 30 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 32 }`, }, - }, - Results: map[string]any{ - "_count": 2, + testUtils.Request{ + Request: `query { + _count(Users: {filter: {Age: {_gt: 26}}}) + }`, + Results: map[string]any{ + "_count": 2, + }, + }, }, } @@ -47,32 +53,38 @@ func TestQuerySimpleWithCountWithFilter(t *testing.T) { } func TestQuerySimpleWithCountWithDateTimeFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query, count with datetime filter", - Request: `query { - _count(Users: {filter: {CreatedAt: {_gt: "2017-08-23T03:46:56-05:00"}}}) - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21, "CreatedAt": "2017-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 30, "CreatedAt": "2017-09-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 32, "CreatedAt": "2017-10-23T03:46:56-05:00" }`, }, - }, - Results: map[string]any{ - "_count": 2, + testUtils.Request{ + Request: `query { + _count(Users: {filter: {CreatedAt: {_gt: "2017-08-23T03:46:56-05:00"}}}) + }`, + Results: map[string]any{ + "_count": 2, + }, + }, }, } diff --git a/tests/integration/query/simple/with_count_test.go b/tests/integration/query/simple/with_count_test.go index 338d6847b6..20068e0672 100644 --- a/tests/integration/query/simple/with_count_test.go +++ b/tests/integration/query/simple/with_count_test.go @@ -17,25 +17,33 @@ import ( ) func TestQuerySimpleWithCountOnUndefined(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query, count on undefined", - Request: `query { + Actions: []any{ + testUtils.Request{ + Request: `query { _count }`, - ExpectedError: "aggregate must be provided with a property to aggregate", + ExpectedError: "aggregate must be provided with a property to aggregate", + }, + }, } executeTestCase(t, test) } func TestQuerySimpleWithCountOnEmptyCollection(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query, count on empty", - Request: `query { + Actions: []any{ + testUtils.Request{ + Request: `query { _count(Users: {}) }`, - Results: map[string]any{ - "_count": 0, + Results: map[string]any{ + "_count": 0, + }, + }, }, } @@ -43,25 +51,29 @@ func TestQuerySimpleWithCountOnEmptyCollection(t *testing.T) { } func TestQuerySimpleWithCount(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query, count", - Request: `query { - _count(Users: {}) - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 30 }`, }, - }, - Results: map[string]any{ - "_count": 2, + testUtils.Request{ + Request: `query { + _count(Users: {}) + }`, + Results: map[string]any{ + "_count": 2, + }, + }, }, } diff --git a/tests/integration/query/simple/with_doc_id_filter_test.go b/tests/integration/query/simple/with_doc_id_filter_test.go index 91bf2ef9cb..d54c9480df 100644 --- a/tests/integration/query/simple/with_doc_id_filter_test.go +++ b/tests/integration/query/simple/with_doc_id_filter_test.go @@ -17,31 +17,35 @@ import ( ) func TestQuerySimpleWithDocIDFilterBlock(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic filter (docID by filter block)", - Request: `query { - Users(filter: {_docID: {_eq: "bae-d4303725-7db9-53d2-b324-f3ee44020e52"}}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Age": int64(21), + testUtils.Request{ + Request: `query { + Users(filter: {_docID: {_eq: "bae-d4303725-7db9-53d2-b324-f3ee44020e52"}}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_doc_id_test.go b/tests/integration/query/simple/with_doc_id_test.go index 5f0b6fb316..a698da5ccf 100644 --- a/tests/integration/query/simple/with_doc_id_test.go +++ b/tests/integration/query/simple/with_doc_id_test.go @@ -17,77 +17,85 @@ import ( ) func TestQuerySimpleWithDocIDFilter(t *testing.T) { - tests := []testUtils.RequestTestCase{ + tests := []testUtils.TestCase{ { Description: "Simple query with basic filter (by docID arg)", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 21 + }`, + }, + testUtils.Request{ + Request: `query { Users(docID: "bae-d4303725-7db9-53d2-b324-f3ee44020e52") { Name Age } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 21 - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + }, }, }, }, }, { Description: "Simple query with basic filter (by docID arg), no results", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 21 + }`, + }, + testUtils.Request{ + Request: `query { Users(docID: "bae-52b9170d-b77a-5887-b877-cbdbb99b009g") { Name Age } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 21 - }`, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, - Results: map[string]any{ - "Users": []map[string]any{}, - }, }, { Description: "Simple query with basic filter (by docID arg), partial results", - Request: `query { - Users(docID: "bae-d4303725-7db9-53d2-b324-f3ee44020e52") { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Age": int64(21), + testUtils.Request{ + Request: `query { + Users(docID: "bae-d4303725-7db9-53d2-b324-f3ee44020e52") { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_doc_ids_test.go b/tests/integration/query/simple/with_doc_ids_test.go index 285a84f87e..4b2aa16ce0 100644 --- a/tests/integration/query/simple/with_doc_ids_test.go +++ b/tests/integration/query/simple/with_doc_ids_test.go @@ -17,114 +17,128 @@ import ( ) func TestQuerySimpleWithDocIDsFilter(t *testing.T) { - tests := []testUtils.RequestTestCase{ + tests := []testUtils.TestCase{ { Description: "Simple query with basic filter (single ID by docIDs arg)", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 21 + }`, + }, + testUtils.Request{ + Request: `query { Users(docIDs: ["bae-d4303725-7db9-53d2-b324-f3ee44020e52"]) { Name Age } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 21 - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + }, }, }, }, }, { Description: "Simple query with basic filter (single ID by docIDs arg), no results", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 21 + }`, + }, + testUtils.Request{ + Request: `query { Users(docIDs: ["bae-52b9170d-b77a-5887-b877-cbdbb99b009g"]) { Name Age } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 21 - }`, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, - Results: map[string]any{ - "Users": []map[string]any{}, - }, }, { Description: "Simple query with basic filter (duplicate ID by docIDs arg), partial results", - Request: `query { - Users(docIDs: ["bae-d4303725-7db9-53d2-b324-f3ee44020e52", "bae-d4303725-7db9-53d2-b324-f3ee44020e52"]) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Age": int64(21), + testUtils.Request{ + Request: `query { + Users(docIDs: ["bae-d4303725-7db9-53d2-b324-f3ee44020e52", "bae-d4303725-7db9-53d2-b324-f3ee44020e52"]) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + }, }, }, }, }, { Description: "Simple query with basic filter (multiple ID by docIDs arg), partial results", - Request: `query { - Users(docIDs: ["bae-d4303725-7db9-53d2-b324-f3ee44020e52", "bae-428c6d76-3491-520b-ad1f-a218f4dad787"]) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Jim", "Age": 27 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Jim", - "Age": int64(27), - }, - { - "Name": "John", - "Age": int64(21), + testUtils.Request{ + Request: `query { + Users(docIDs: ["bae-d4303725-7db9-53d2-b324-f3ee44020e52", "bae-428c6d76-3491-520b-ad1f-a218f4dad787"]) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Jim", + "Age": int64(27), + }, + { + "Name": "John", + "Age": int64(21), + }, + }, }, }, }, @@ -137,25 +151,27 @@ func TestQuerySimpleWithDocIDsFilter(t *testing.T) { } func TestQuerySimpleReturnsNothinGivenEmptyDocIDsFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with empty docIDs arg", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 21 + }`, + }, + testUtils.Request{ + Request: `query { Users(docIDs: []) { Name Age } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 21 - }`, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, - Results: map[string]any{ - "Users": []map[string]any{}, - }, } executeTestCase(t, test) diff --git a/tests/integration/query/simple/with_filter/utils.go b/tests/integration/query/simple/with_filter/utils.go index 28d84e61dd..4e4375096b 100644 --- a/tests/integration/query/simple/with_filter/utils.go +++ b/tests/integration/query/simple/with_filter/utils.go @@ -26,6 +26,19 @@ var userCollectionGQLSchema = (` } `) -func executeTestCase(t *testing.T, test testUtils.RequestTestCase) { - testUtils.ExecuteRequestTestCase(t, userCollectionGQLSchema, []string{"Users"}, test) +func executeTestCase(t *testing.T, test testUtils.TestCase) { + testUtils.ExecuteTestCase( + t, + testUtils.TestCase{ + Description: test.Description, + Actions: append( + []any{ + testUtils.SchemaUpdate{ + Schema: userCollectionGQLSchema, + }, + }, + test.Actions..., + ), + }, + ) } diff --git a/tests/integration/query/simple/with_filter/with_and_test.go b/tests/integration/query/simple/with_filter/with_and_test.go index 4bac7cf5af..81ccbeb35f 100644 --- a/tests/integration/query/simple/with_filter/with_and_test.go +++ b/tests/integration/query/simple/with_filter/with_and_test.go @@ -17,43 +17,51 @@ import ( ) func TestQuerySimpleWithIntGreaterThanAndIntLessThanFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with logical compound filter (and)", - Request: `query { - Users(filter: {_and: [{Age: {_gt: 20}}, {Age: {_lt: 50}}]}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Bob", - "Age": int64(32), + testUtils.Request{ + Request: `query { + Users(filter: {_and: [{Age: {_gt: 20}}, {Age: {_lt: 50}}]}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Bob", + "Age": int64(32), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_eq_datetime_test.go b/tests/integration/query/simple/with_filter/with_eq_datetime_test.go index 0f72bd05ab..dbf6152244 100644 --- a/tests/integration/query/simple/with_filter/with_eq_datetime_test.go +++ b/tests/integration/query/simple/with_filter/with_eq_datetime_test.go @@ -17,35 +17,39 @@ import ( ) func TestQuerySimpleWithDateTimeEqualsFilterBlock(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic filter(age)", - Request: `query { - Users(filter: {CreatedAt: {_eq: "2017-07-23T03:46:56-05:00"}}) { - Name - Age - CreatedAt - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21, "CreatedAt": "2017-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32, "CreatedAt": "2016-07-23T03:46:56-05:00" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Age": int64(21), - "CreatedAt": testUtils.MustParseTime("2017-07-23T03:46:56-05:00"), + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_eq: "2017-07-23T03:46:56-05:00"}}) { + Name + Age + CreatedAt + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + "CreatedAt": testUtils.MustParseTime("2017-07-23T03:46:56-05:00"), + }, + }, }, }, }, @@ -55,39 +59,45 @@ func TestQuerySimpleWithDateTimeEqualsFilterBlock(t *testing.T) { } func TestQuerySimpleWithDateTimeEqualsNilFilterBlock(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic filter(age)", - Request: `query { - Users(filter: {CreatedAt: {_eq: null}}) { - Name - Age - CreatedAt - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21, "CreatedAt": "2017-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32, "CreatedAt": "2016-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Fred", "Age": 44 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Fred", - "Age": int64(44), - "CreatedAt": nil, + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_eq: null}}) { + Name + Age + CreatedAt + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Fred", + "Age": int64(44), + "CreatedAt": nil, + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_eq_float_test.go b/tests/integration/query/simple/with_filter/with_eq_float_test.go index 340236f580..99f3de859f 100644 --- a/tests/integration/query/simple/with_filter/with_eq_float_test.go +++ b/tests/integration/query/simple/with_filter/with_eq_float_test.go @@ -17,31 +17,35 @@ import ( ) func TestQuerySimpleWithFloatEqualsFilterBlock(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic float filter", - Request: `query { - Users(filter: {HeightM: {_eq: 2.1}}) { - Name - HeightM - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "HeightM": float64(2.1), + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_eq: 2.1}}) { + Name + HeightM + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "HeightM": float64(2.1), + }, + }, }, }, }, @@ -51,34 +55,40 @@ func TestQuerySimpleWithFloatEqualsFilterBlock(t *testing.T) { } func TestQuerySimpleWithFloatEqualsNilFilterBlock(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic float nil filter", - Request: `query { - Users(filter: {HeightM: {_eq: null}}) { - Name - HeightM - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "HeightM": 1.82 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Fred" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Fred", - "HeightM": nil, + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_eq: null}}) { + Name + HeightM + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Fred", + "HeightM": nil, + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_eq_int_test.go b/tests/integration/query/simple/with_filter/with_eq_int_test.go index 576f2fa38e..4871f22e86 100644 --- a/tests/integration/query/simple/with_filter/with_eq_int_test.go +++ b/tests/integration/query/simple/with_filter/with_eq_int_test.go @@ -17,31 +17,35 @@ import ( ) func TestQuerySimpleWithIntEqualsFilterBlock(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic filter(age)", - Request: `query { - Users(filter: {Age: {_eq: 21}}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Age": int64(21), + testUtils.Request{ + Request: `query { + Users(filter: {Age: {_eq: 21}}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + }, }, }, }, @@ -51,34 +55,40 @@ func TestQuerySimpleWithIntEqualsFilterBlock(t *testing.T) { } func TestQuerySimpleWithIntEqualsNilFilterBlock(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic int nil filter", - Request: `query { - Users(filter: {Age: {_eq: null}}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Fred" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Fred", - "Age": nil, + testUtils.Request{ + Request: `query { + Users(filter: {Age: {_eq: null}}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Fred", + "Age": nil, + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_eq_string_test.go b/tests/integration/query/simple/with_filter/with_eq_string_test.go index bc9d249877..11deb874dc 100644 --- a/tests/integration/query/simple/with_filter/with_eq_string_test.go +++ b/tests/integration/query/simple/with_filter/with_eq_string_test.go @@ -17,31 +17,35 @@ import ( ) func TestQuerySimpleWithStringFilterBlock(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic filter (Name)", - Request: `query { - Users(filter: {Name: {_eq: "John"}}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Age": int64(21), + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_eq: "John"}}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + }, }, }, }, @@ -51,34 +55,40 @@ func TestQuerySimpleWithStringFilterBlock(t *testing.T) { } func TestQuerySimpleWithStringEqualsNilFilterBlock(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic string nil filter", - Request: `query { - Users(filter: {Name: {_eq: null}}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Age": 60 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": nil, - "Age": int64(60), + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_eq: null}}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": nil, + "Age": int64(60), + }, + }, }, }, }, @@ -88,80 +98,90 @@ func TestQuerySimpleWithStringEqualsNilFilterBlock(t *testing.T) { } func TestQuerySimpleWithStringFilterBlockAndSelect(t *testing.T) { - tests := []testUtils.RequestTestCase{ + tests := []testUtils.TestCase{ { Description: "Simple query with basic filter and selection", - Request: `query { - Users(filter: {Name: {_eq: "John"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_eq: "John"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + }, }, }, }, }, { Description: "Simple query with basic filter and selection (diff from filter)", - Request: `query { - Users(filter: {Name: {_eq: "John"}}) { - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(21), + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_eq: "John"}}) { + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(21), + }, + }, }, }, }, }, { Description: "Simple query with basic filter(name), no results", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 21 + }`, + }, + testUtils.Request{ + Request: `query { Users(filter: {Name: {_eq: "Bob"}}) { Name Age } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 21 - }`, + Results: map[string]any{ + "Users": []map[string]any{}, + }, }, }, - Results: map[string]any{ - "Users": []map[string]any{}, - }, }, } diff --git a/tests/integration/query/simple/with_filter/with_ge_datetime_test.go b/tests/integration/query/simple/with_filter/with_ge_datetime_test.go index a21a120c44..5c2aacaa00 100644 --- a/tests/integration/query/simple/with_filter/with_ge_datetime_test.go +++ b/tests/integration/query/simple/with_filter/with_ge_datetime_test.go @@ -17,31 +17,35 @@ import ( ) func TestQuerySimpleWithDateTimeGEFilterBlockWithEqualValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic ge int filter with equal value", - Request: `query { - Users(filter: {CreatedAt: {_ge: "2017-07-23T03:46:56-05:00"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21, "CreatedAt": "2017-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32, "CreatedAt": "2010-07-23T03:46:56-05:00" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_ge: "2017-07-23T03:46:56-05:00"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + }, }, }, }, @@ -51,31 +55,35 @@ func TestQuerySimpleWithDateTimeGEFilterBlockWithEqualValue(t *testing.T) { } func TestQuerySimpleWithDateTimeGEFilterBlockWithGreaterValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic ge int filter with equal value", - Request: `query { - Users(filter: {CreatedAt: {_ge: "2017-07-22T03:46:56-05:00"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21, "CreatedAt": "2017-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32, "CreatedAt": "2010-07-23T03:46:56-05:00" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_ge: "2017-07-22T03:46:56-05:00"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + }, }, }, }, @@ -85,29 +93,33 @@ func TestQuerySimpleWithDateTimeGEFilterBlockWithGreaterValue(t *testing.T) { } func TestQuerySimpleWithDateTimeGEFilterBlockWithLesserValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic ge int filter with equal value", - Request: `query { - Users(filter: {CreatedAt: {_ge: "2017-07-25T03:46:56-05:00"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21, "CreatedAt": "2017-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32, "CreatedAt": "2010-07-23T03:46:56-05:00" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{}, + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_ge: "2017-07-25T03:46:56-05:00"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{}, + }, + }, }, } @@ -115,31 +127,35 @@ func TestQuerySimpleWithDateTimeGEFilterBlockWithLesserValue(t *testing.T) { } func TestQuerySimpleWithDateTimeGEFilterBlockWithNilValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic ge nil filter", - Request: `query { - Users(filter: {CreatedAt: {_ge: null}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "CreatedAt": "2010-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Bob", - }, - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_ge: null}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_ge_float_test.go b/tests/integration/query/simple/with_filter/with_ge_float_test.go index be0a6d9c12..9ea5559972 100644 --- a/tests/integration/query/simple/with_filter/with_ge_float_test.go +++ b/tests/integration/query/simple/with_filter/with_ge_float_test.go @@ -17,29 +17,33 @@ import ( ) func TestQuerySimpleWithHeightMGEFilterBlockWithEqualValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic ge int filter with equal value", - Request: `query { - Users(filter: {HeightM: {_ge: 2.1}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_ge: 2.1}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + }, }, }, }, @@ -49,29 +53,33 @@ func TestQuerySimpleWithHeightMGEFilterBlockWithEqualValue(t *testing.T) { } func TestQuerySimpleWithHeightMGEFilterBlockWithLesserValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic ge int filter with lesser value", - Request: `query { - Users(filter: {HeightM: {_ge: 2.0999999999999}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_ge: 2.0999999999999}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + }, }, }, }, @@ -81,29 +89,33 @@ func TestQuerySimpleWithHeightMGEFilterBlockWithLesserValue(t *testing.T) { } func TestQuerySimpleWithHeightMGEFilterBlockWithLesserIntValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic ge int filter with lesser int value", - Request: `query { - Users(filter: {HeightM: {_ge: 2}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_ge: 2}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + }, }, }, }, @@ -113,31 +125,35 @@ func TestQuerySimpleWithHeightMGEFilterBlockWithLesserIntValue(t *testing.T) { } func TestQuerySimpleWithHeightMGEFilterBlockWithNilValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic ge float nil filter", - Request: `query { - Users(filter: {HeightM: {_ge: null}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - }, - { - "Name": "Bob", + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_ge: null}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + { + "Name": "Bob", + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_ge_int_test.go b/tests/integration/query/simple/with_filter/with_ge_int_test.go index 5a07a18b01..1c2b629960 100644 --- a/tests/integration/query/simple/with_filter/with_ge_int_test.go +++ b/tests/integration/query/simple/with_filter/with_ge_int_test.go @@ -17,29 +17,33 @@ import ( ) func TestQuerySimpleWithIntGEFilterBlockWithEqualValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic ge int filter with equal value", - Request: `query { - Users(filter: {Age: {_ge: 32}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Bob", + testUtils.Request{ + Request: `query { + Users(filter: {Age: {_ge: 32}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + }, }, }, }, @@ -49,29 +53,33 @@ func TestQuerySimpleWithIntGEFilterBlockWithEqualValue(t *testing.T) { } func TestQuerySimpleWithIntGEFilterBlockWithGreaterValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic ge int filter with greater value", - Request: `query { - Users(filter: {Age: {_ge: 31}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Bob", + testUtils.Request{ + Request: `query { + Users(filter: {Age: {_ge: 31}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + }, }, }, }, @@ -81,31 +89,35 @@ func TestQuerySimpleWithIntGEFilterBlockWithGreaterValue(t *testing.T) { } func TestQuerySimpleWithIntGEFilterBlockWithNilValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic ge nil filter", - Request: `query { - Users(filter: {Age: {_ge: null}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Bob", - }, - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {Age: {_ge: null}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_gt_datetime_test.go b/tests/integration/query/simple/with_filter/with_gt_datetime_test.go index e12a74a36f..67ee8a05a0 100644 --- a/tests/integration/query/simple/with_filter/with_gt_datetime_test.go +++ b/tests/integration/query/simple/with_filter/with_gt_datetime_test.go @@ -17,31 +17,35 @@ import ( ) func TestQuerySimpleWithDateTimeGTFilterBlockWithEqualValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic gt datetime filter with equal value", - Request: `query { - Users(filter: {CreatedAt: {_gt: "2017-07-20T03:46:56-05:00"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21, "CreatedAt": "2017-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32, "CreatedAt": "2010-07-23T03:46:56-05:00" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_gt: "2017-07-20T03:46:56-05:00"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + }, }, }, }, @@ -51,31 +55,35 @@ func TestQuerySimpleWithDateTimeGTFilterBlockWithEqualValue(t *testing.T) { } func TestQuerySimpleWithDateTimeGTFilterBlockWithGreaterValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic gt DateTime filter with equal value", - Request: `query { - Users(filter: {CreatedAt: {_gt: "2017-07-22T03:46:56-05:00"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21, "CreatedAt": "2017-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32, "CreatedAt": "2010-07-23T03:46:56-05:00" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_gt: "2017-07-22T03:46:56-05:00"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + }, }, }, }, @@ -85,29 +93,33 @@ func TestQuerySimpleWithDateTimeGTFilterBlockWithGreaterValue(t *testing.T) { } func TestQuerySimpleWithDateTimeGTFilterBlockWithLesserValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic gt datetime filter with lesser value", - Request: `query { - Users(filter: {CreatedAt: {_gt: "2017-07-25T03:46:56-05:00"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21, "CreatedAt": "2017-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32, "CreatedAt": "2010-07-23T03:46:56-05:00" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{}, + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_gt: "2017-07-25T03:46:56-05:00"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{}, + }, + }, }, } @@ -115,28 +127,32 @@ func TestQuerySimpleWithDateTimeGTFilterBlockWithLesserValue(t *testing.T) { } func TestQuerySimpleWithDateTimeGTFilterBlockWithNilValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic gt datetime nil filter", - Request: `query { - Users(filter: {CreatedAt: {_gt: null}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "CreatedAt": "2010-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_gt: null}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_gt_float_test.go b/tests/integration/query/simple/with_filter/with_gt_float_test.go index da72d4df51..a362223488 100644 --- a/tests/integration/query/simple/with_filter/with_gt_float_test.go +++ b/tests/integration/query/simple/with_filter/with_gt_float_test.go @@ -17,83 +17,95 @@ import ( ) func TestQuerySimpleWithFloatGreaterThanFilterBlock(t *testing.T) { - tests := []testUtils.RequestTestCase{ + tests := []testUtils.TestCase{ { Description: "Simple query with basic float greater than filter", - Request: `query { - Users(filter: {HeightM: {_gt: 2.0999999999999}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_gt: 2.0999999999999}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + }, }, }, }, }, { Description: "Simple query with basic float greater than filter, no results", - Request: `query { - Users(filter: {HeightM: {_gt: 40}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{}, + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_gt: 40}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{}, + }, + }, }, }, { Description: "Simple query with basic float greater than filter, multiple results", - Request: `query { - Users(filter: {HeightM: {_gt: 1.8199999999999}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - }, - { - "Name": "Bob", + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_gt: 1.8199999999999}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + { + "Name": "Bob", + }, + }, }, }, }, @@ -106,29 +118,33 @@ func TestQuerySimpleWithFloatGreaterThanFilterBlock(t *testing.T) { } func TestQuerySimpleWithFloatGreaterThanFilterBlockWithIntFilterValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic float greater than filter, with int filter value", - Request: `query { - Users(filter: {HeightM: {_gt: 2}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_gt: 2}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + }, }, }, }, @@ -138,28 +154,32 @@ func TestQuerySimpleWithFloatGreaterThanFilterBlockWithIntFilterValue(t *testing } func TestQuerySimpleWithFloatGreaterThanFilterBlockWithNullFilterValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic float greater than filter, with null filter value", - Request: `query { - Users(filter: {HeightM: {_gt: null}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_gt: null}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_gt_int_test.go b/tests/integration/query/simple/with_filter/with_gt_int_test.go index 3cbdf82250..3069131e97 100644 --- a/tests/integration/query/simple/with_filter/with_gt_int_test.go +++ b/tests/integration/query/simple/with_filter/with_gt_int_test.go @@ -17,89 +17,101 @@ import ( ) func TestQuerySimpleWithIntGreaterThanFilterBlock(t *testing.T) { - tests := []testUtils.RequestTestCase{ + tests := []testUtils.TestCase{ { Description: "Simple query with basic filter(age), greater than", - Request: `query { - Users(filter: {Age: {_gt: 20}}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Age": int64(21), + testUtils.Request{ + Request: `query { + Users(filter: {Age: {_gt: 20}}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + }, }, }, }, }, { Description: "Simple query with basic filter(age), no results", - Request: `query { - Users(filter: {Age: {_gt: 40}}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{}, - }, - }, - { - Description: "Simple query with basic filter(age), multiple results", - Request: `query { - Users(filter: {Age: {_gt: 20}}) { + testUtils.Request{ + Request: `query { + Users(filter: {Age: {_gt: 40}}) { Name Age } }`, - Docs: map[int][]string{ - 0: { - `{ + Results: map[string]any{ + "Users": []map[string]any{}, + }, + }, + }, + }, + { + Description: "Simple query with basic filter(age), multiple results", + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Bob", - "Age": int64(32), + testUtils.Request{ + Request: `query { + Users(filter: {Age: {_gt: 20}}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Bob", + "Age": int64(32), + }, + }, }, }, }, @@ -112,28 +124,32 @@ func TestQuerySimpleWithIntGreaterThanFilterBlock(t *testing.T) { } func TestQuerySimpleWithIntGreaterThanFilterBlockWithNullFilterValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic int greater than filter, with null filter value", - Request: `query { - Users(filter: {Age: {_gt: null}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {Age: {_gt: null}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_in_test.go b/tests/integration/query/simple/with_filter/with_in_test.go index 887a4ccbdb..5afca0c170 100644 --- a/tests/integration/query/simple/with_filter/with_in_test.go +++ b/tests/integration/query/simple/with_filter/with_in_test.go @@ -17,43 +17,51 @@ import ( ) func TestQuerySimpleWithIntInFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with special filter (or)", - Request: `query { - Users(filter: {Age: {_in: [19, 40, 55]}}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Carlo", - "Age": int64(55), - }, - { - "Name": "Alice", - "Age": int64(19), + testUtils.Request{ + Request: `query { + Users(filter: {Age: {_in: [19, 40, 55]}}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "Age": int64(55), + }, + { + "Name": "Alice", + "Age": int64(19), + }, + }, }, }, }, @@ -63,40 +71,48 @@ func TestQuerySimpleWithIntInFilter(t *testing.T) { } func TestQuerySimpleWithIntInFilterOnFloat(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with _in filter on float", - Request: `query { - Users(filter: {HeightM: {_in: [21, 21.2]}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 21.0 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "HeightM": 21.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "HeightM": 21.2 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "HeightM": 21.3 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Carlo", - }, - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_in: [21, 21.2]}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + }, + { + "Name": "John", + }, + }, }, }, }, @@ -106,50 +122,60 @@ func TestQuerySimpleWithIntInFilterOnFloat(t *testing.T) { } func TestQuerySimpleWithIntInFilterWithNullValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with special filter (or)", - Request: `query { - Users(filter: {Age: {_in: [19, 40, 55, null]}}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Fred" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Fred", - "Age": nil, - }, - { - "Name": "Carlo", - "Age": int64(55), - }, - { - "Name": "Alice", - "Age": int64(19), + testUtils.Request{ + Request: `query { + Users(filter: {Age: {_in: [19, 40, 55, null]}}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Fred", + "Age": nil, + }, + { + "Name": "Carlo", + "Age": int64(55), + }, + { + "Name": "Alice", + "Age": int64(19), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_le_datetime_test.go b/tests/integration/query/simple/with_filter/with_le_datetime_test.go index 3e1dc9ff96..6ffbbbac69 100644 --- a/tests/integration/query/simple/with_filter/with_le_datetime_test.go +++ b/tests/integration/query/simple/with_filter/with_le_datetime_test.go @@ -17,31 +17,35 @@ import ( ) func TestQuerySimpleWithDateTimeLEFilterBlockWithEqualValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic le DateTime filter with equal value", - Request: `query { - Users(filter: {CreatedAt: {_le: "2017-07-23T03:46:56-05:00"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21, "CreatedAt": "2017-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32, "CreatedAt": "2019-07-23T03:46:56-05:00" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_le: "2017-07-23T03:46:56-05:00"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + }, }, }, }, @@ -51,31 +55,35 @@ func TestQuerySimpleWithDateTimeLEFilterBlockWithEqualValue(t *testing.T) { } func TestQuerySimpleWithDateTimeLEFilterBlockWithGreaterValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic le DateTime filter with greater value", - Request: `query { - Users(filter: {CreatedAt: {_le: "2018-07-23T03:46:56-05:00"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21, "CreatedAt": "2017-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32, "CreatedAt": "2019-07-23T03:46:56-05:00" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_le: "2018-07-23T03:46:56-05:00"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + }, }, }, }, @@ -85,30 +93,34 @@ func TestQuerySimpleWithDateTimeLEFilterBlockWithGreaterValue(t *testing.T) { } func TestQuerySimpleWithDateTimeLEFilterBlockWithNullValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic le DateTime filter with null value", - Request: `query { - Users(filter: {CreatedAt: {_le: null}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21, "CreatedAt": "2017-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Bob", + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_le: null}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_le_float_test.go b/tests/integration/query/simple/with_filter/with_le_float_test.go index f5d2e7e3fc..ecd162b222 100644 --- a/tests/integration/query/simple/with_filter/with_le_float_test.go +++ b/tests/integration/query/simple/with_filter/with_le_float_test.go @@ -17,29 +17,33 @@ import ( ) func TestQuerySimpleWithFloatLEFilterBlockWithEqualValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic le float filter with equal value", - Request: `query { - Users(filter: {HeightM: {_le: 1.82}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Bob", + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_le: 1.82}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + }, }, }, }, @@ -49,29 +53,33 @@ func TestQuerySimpleWithFloatLEFilterBlockWithEqualValue(t *testing.T) { } func TestQuerySimpleWithFloatLEFilterBlockWithGreaterValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic le float filter with greater value", - Request: `query { - Users(filter: {HeightM: {_le: 1.820000000001}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Bob", + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_le: 1.820000000001}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + }, }, }, }, @@ -81,29 +89,33 @@ func TestQuerySimpleWithFloatLEFilterBlockWithGreaterValue(t *testing.T) { } func TestQuerySimpleWithFloatLEFilterBlockWithGreaterIntValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic le float filter with greater int value", - Request: `query { - Users(filter: {HeightM: {_le: 2}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Bob", + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_le: 2}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + }, }, }, }, @@ -113,28 +125,32 @@ func TestQuerySimpleWithFloatLEFilterBlockWithGreaterIntValue(t *testing.T) { } func TestQuerySimpleWithFloatLEFilterBlockWithNullValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic le float filter with null value", - Request: `query { - Users(filter: {HeightM: {_le: null}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Bob", + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_le: null}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_le_int_test.go b/tests/integration/query/simple/with_filter/with_le_int_test.go index 1dd363c25e..12275bd90e 100644 --- a/tests/integration/query/simple/with_filter/with_le_int_test.go +++ b/tests/integration/query/simple/with_filter/with_le_int_test.go @@ -17,29 +17,33 @@ import ( ) func TestQuerySimpleWithIntLEFilterBlockWithEqualValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic le int filter with equal value", - Request: `query { - Users(filter: {Age: {_le: 21}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {Age: {_le: 21}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + }, }, }, }, @@ -49,29 +53,33 @@ func TestQuerySimpleWithIntLEFilterBlockWithEqualValue(t *testing.T) { } func TestQuerySimpleWithIntLEFilterBlockWithGreaterValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic le int filter with greater value", - Request: `query { - Users(filter: {Age: {_le: 22}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {Age: {_le: 22}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + }, }, }, }, @@ -81,28 +89,32 @@ func TestQuerySimpleWithIntLEFilterBlockWithGreaterValue(t *testing.T) { } func TestQuerySimpleWithIntLEFilterBlockWithNullValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic le int filter with null value", - Request: `query { - Users(filter: {Age: {_le: null}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Bob", + testUtils.Request{ + Request: `query { + Users(filter: {Age: {_le: null}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_like_string_test.go b/tests/integration/query/simple/with_filter/with_like_string_test.go index 9aa5ede34b..dce0c381f1 100644 --- a/tests/integration/query/simple/with_filter/with_like_string_test.go +++ b/tests/integration/query/simple/with_filter/with_like_string_test.go @@ -17,29 +17,33 @@ import ( ) func TestQuerySimpleWithLikeStringContainsFilterBlockContainsString(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic like-string filter contains string", - Request: `query { - Users(filter: {Name: {_like: "%Stormborn%"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_like: "%Stormborn%"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, + }, }, }, }, @@ -49,29 +53,33 @@ func TestQuerySimpleWithLikeStringContainsFilterBlockContainsString(t *testing.T } func TestQuerySimple_WithCaseInsensitiveLike_ShouldMatchString(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic case insensitive like-string filter contains string", - Request: `query { - Users(filter: {Name: {_ilike: "%stormborn%"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_ilike: "%stormborn%"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, + }, }, }, }, @@ -81,29 +89,33 @@ func TestQuerySimple_WithCaseInsensitiveLike_ShouldMatchString(t *testing.T) { } func TestQuerySimpleWithLikeStringContainsFilterBlockAsPrefixString(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic like-string filter with string as prefix", - Request: `query { - Users(filter: {Name: {_like: "Viserys%"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_like: "Viserys%"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, + }, }, }, }, @@ -113,29 +125,33 @@ func TestQuerySimpleWithLikeStringContainsFilterBlockAsPrefixString(t *testing.T } func TestQuerySimple_WithCaseInsensitiveLikeString_ShouldMatchPrefixString(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic case insensitive like-string filter with string as prefix", - Request: `query { - Users(filter: {Name: {_ilike: "viserys%"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_ilike: "viserys%"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, + }, }, }, }, @@ -145,29 +161,33 @@ func TestQuerySimple_WithCaseInsensitiveLikeString_ShouldMatchPrefixString(t *te } func TestQuerySimpleWithLikeStringContainsFilterBlockAsSuffixString(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic like-string filter with string as suffix", - Request: `query { - Users(filter: {Name: {_like: "%Andals"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_like: "%Andals"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, + }, }, }, }, @@ -177,29 +197,33 @@ func TestQuerySimpleWithLikeStringContainsFilterBlockAsSuffixString(t *testing.T } func TestQuerySimple_WithCaseInsensitiveLikeString_ShouldMatchSuffixString(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic case insensitive like-string filter with string as suffix", - Request: `query { - Users(filter: {Name: {_ilike: "%andals"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_ilike: "%andals"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, + }, }, }, }, @@ -209,29 +233,33 @@ func TestQuerySimple_WithCaseInsensitiveLikeString_ShouldMatchSuffixString(t *te } func TestQuerySimpleWithLikeStringContainsFilterBlockExactString(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic like-string filter with string as suffix", - Request: `query { - Users(filter: {Name: {_like: "Daenerys Stormborn of House Targaryen, the First of Her Name"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_like: "Daenerys Stormborn of House Targaryen, the First of Her Name"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, + }, }, }, }, @@ -241,29 +269,33 @@ func TestQuerySimpleWithLikeStringContainsFilterBlockExactString(t *testing.T) { } func TestQuerySimple_WithCaseInsensitiveLikeString_ShouldMatchExactString(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic like-string filter with string as suffix", - Request: `query { - Users(filter: {Name: {_ilike: "daenerys stormborn of house targaryen, the first of her name"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_ilike: "daenerys stormborn of house targaryen, the first of her name"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, + }, }, }, }, @@ -273,32 +305,36 @@ func TestQuerySimple_WithCaseInsensitiveLikeString_ShouldMatchExactString(t *tes } func TestQuerySimpleWithLikeStringContainsFilterBlockContainsStringMuplitpleResults(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic like-string filter with contains string multiple results", - Request: `query { - Users(filter: {Name: {_like: "%Targaryen%"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", - }, - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_like: "%Targaryen%"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, + }, }, }, }, @@ -308,29 +344,33 @@ func TestQuerySimpleWithLikeStringContainsFilterBlockContainsStringMuplitpleResu } func TestQuerySimpleWithLikeStringContainsFilterBlockHasStartAndEnd(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic like-string filter with string as start and end", - Request: `query { - Users(filter: {Name: {_like: "Daenerys%Name"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_like: "Daenerys%Name"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, + }, }, }, }, @@ -340,27 +380,31 @@ func TestQuerySimpleWithLikeStringContainsFilterBlockHasStartAndEnd(t *testing.T } func TestQuerySimpleWithLikeStringContainsFilterBlockHasBoth(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic like-string filter with none of the strings", - Request: `query { - Users(filter: {_and: [{Name: {_like: "%Baratheon%"}}, {Name: {_like: "%Stormborn%"}}]}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{}, + testUtils.Request{ + Request: `query { + Users(filter: {_and: [{Name: {_like: "%Baratheon%"}}, {Name: {_like: "%Stormborn%"}}]}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{}, + }, + }, }, } @@ -368,29 +412,33 @@ func TestQuerySimpleWithLikeStringContainsFilterBlockHasBoth(t *testing.T) { } func TestQuerySimpleWithLikeStringContainsFilterBlockHasEither(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic like-string filter with either strings", - Request: `query { - Users(filter: {_or: [{Name: {_like: "%Baratheon%"}}, {Name: {_like: "%Stormborn%"}}]}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + testUtils.Request{ + Request: `query { + Users(filter: {_or: [{Name: {_like: "%Baratheon%"}}, {Name: {_like: "%Stormborn%"}}]}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, + }, }, }, }, @@ -400,32 +448,38 @@ func TestQuerySimpleWithLikeStringContainsFilterBlockHasEither(t *testing.T) { } func TestQuerySimpleWithLikeStringContainsFilterBlockPropNotSet(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic like-string filter with either strings", - Request: `query { - Users(filter: {Name: {_like: "%King%"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "HeightM": 1.92 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_like: "%King%"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_lt_datetime_test.go b/tests/integration/query/simple/with_filter/with_lt_datetime_test.go index da6f60354e..a2230b3b20 100644 --- a/tests/integration/query/simple/with_filter/with_lt_datetime_test.go +++ b/tests/integration/query/simple/with_filter/with_lt_datetime_test.go @@ -17,31 +17,35 @@ import ( ) func TestQuerySimpleWithDateTimeLTFilterBlockWithGreaterValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic lt DateTime filter with equal value", - Request: `query { - Users(filter: {CreatedAt: {_lt: "2017-07-25T03:46:56-05:00"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21, "CreatedAt": "2017-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32, "CreatedAt": "2019-07-23T03:46:56-05:00" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_lt: "2017-07-25T03:46:56-05:00"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + }, }, }, }, @@ -51,28 +55,32 @@ func TestQuerySimpleWithDateTimeLTFilterBlockWithGreaterValue(t *testing.T) { } func TestQuerySimpleWithDateTimeLTFilterBlockWithNullValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic lt DateTime filter with null value", - Request: `query { - Users(filter: {CreatedAt: {_lt: null}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21, "CreatedAt": "2017-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{}, + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_lt: null}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{}, + }, + }, }, } diff --git a/tests/integration/query/simple/with_filter/with_lt_float_test.go b/tests/integration/query/simple/with_filter/with_lt_float_test.go index 84e3c6122a..3c255b7def 100644 --- a/tests/integration/query/simple/with_filter/with_lt_float_test.go +++ b/tests/integration/query/simple/with_filter/with_lt_float_test.go @@ -17,29 +17,33 @@ import ( ) func TestQuerySimpleWithFloatLessThanFilterBlockWithGreaterValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic lt float filter with greater value", - Request: `query { - Users(filter: {HeightM: {_lt: 1.820000000001}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Bob", + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_lt: 1.820000000001}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + }, }, }, }, @@ -49,29 +53,33 @@ func TestQuerySimpleWithFloatLessThanFilterBlockWithGreaterValue(t *testing.T) { } func TestQuerySimpleWithFloatLessThanFilterBlockWithGreaterIntValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic lt float filter with greater int value", - Request: `query { - Users(filter: {HeightM: {_lt: 2}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Bob", + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_lt: 2}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + }, }, }, }, @@ -81,27 +89,31 @@ func TestQuerySimpleWithFloatLessThanFilterBlockWithGreaterIntValue(t *testing.T } func TestQuerySimpleWithFloatLessThanFilterBlockWithNullValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic lt float filter with null value", - Request: `query { - Users(filter: {HeightM: {_lt: null}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{}, + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_lt: null}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{}, + }, + }, }, } diff --git a/tests/integration/query/simple/with_filter/with_lt_int_test.go b/tests/integration/query/simple/with_filter/with_lt_int_test.go index 12bf972938..b5a0c85cb5 100644 --- a/tests/integration/query/simple/with_filter/with_lt_int_test.go +++ b/tests/integration/query/simple/with_filter/with_lt_int_test.go @@ -17,29 +17,33 @@ import ( ) func TestQuerySimpleWithIntLessThanFilterBlockWithGreaterValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic lt int filter with greater value", - Request: `query { - Users(filter: {Age: {_lt: 22}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {Age: {_lt: 22}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + }, }, }, }, @@ -49,26 +53,30 @@ func TestQuerySimpleWithIntLessThanFilterBlockWithGreaterValue(t *testing.T) { } func TestQuerySimpleWithIntLessThanFilterBlockWithNullValue(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic lt int filter with null value", - Request: `query { - Users(filter: {Age: {_lt: null}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{}, + testUtils.Request{ + Request: `query { + Users(filter: {Age: {_lt: null}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{}, + }, + }, }, } diff --git a/tests/integration/query/simple/with_filter/with_ne_bool_test.go b/tests/integration/query/simple/with_filter/with_ne_bool_test.go index 1f25203e89..d1acd27ad2 100644 --- a/tests/integration/query/simple/with_filter/with_ne_bool_test.go +++ b/tests/integration/query/simple/with_filter/with_ne_bool_test.go @@ -17,35 +17,41 @@ import ( ) func TestQuerySimpleWithBoolNotEqualsTrueFilterBlock(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with ne true filter", - Request: `query { - Users(filter: {Verified: {_ne: true}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Fred", "Verified": false }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Fred", - }, - { - "Name": "Bob", + testUtils.Request{ + Request: `query { + Users(filter: {Verified: {_ne: true}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Fred", + }, + { + "Name": "Bob", + }, + }, }, }, }, @@ -55,35 +61,41 @@ func TestQuerySimpleWithBoolNotEqualsTrueFilterBlock(t *testing.T) { } func TestQuerySimpleWithBoolNotEqualsNilFilterBlock(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with ne nil filter", - Request: `query { - Users(filter: {Verified: {_ne: null}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Fred", "Verified": false }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - }, - { - "Name": "Fred", + testUtils.Request{ + Request: `query { + Users(filter: {Verified: {_ne: null}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + { + "Name": "Fred", + }, + }, }, }, }, @@ -93,35 +105,41 @@ func TestQuerySimpleWithBoolNotEqualsNilFilterBlock(t *testing.T) { } func TestQuerySimpleWithBoolNotEqualsFalseFilterBlock(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with ne false filter", - Request: `query { - Users(filter: {Verified: {_ne: false}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Fred", "Verified": false }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - }, - { - "Name": "Bob", + testUtils.Request{ + Request: `query { + Users(filter: {Verified: {_ne: false}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + { + "Name": "Bob", + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_ne_datetime_test.go b/tests/integration/query/simple/with_filter/with_ne_datetime_test.go index f6423ed95c..5320a9c7eb 100644 --- a/tests/integration/query/simple/with_filter/with_ne_datetime_test.go +++ b/tests/integration/query/simple/with_filter/with_ne_datetime_test.go @@ -17,31 +17,35 @@ import ( ) func TestQuerySimpleWithDateTimeNotEqualsFilterBlock(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with ne DateTime filter", - Request: `query { - Users(filter: {CreatedAt: {_ne: "2017-07-23T03:46:56-05:00"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21, "CreatedAt": "2017-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32, "CreatedAt": "2011-07-23T03:46:56-05:00" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Bob", + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_ne: "2017-07-23T03:46:56-05:00"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + }, }, }, }, @@ -51,38 +55,44 @@ func TestQuerySimpleWithDateTimeNotEqualsFilterBlock(t *testing.T) { } func TestQuerySimpleWithDateTimeNotEqualsNilFilterBlock(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with ne DateTime nil filter", - Request: `query { - Users(filter: {CreatedAt: {_ne: null}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21, "CreatedAt": "2017-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32, "CreatedAt": "2011-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Fred", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Bob", - }, - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_ne: null}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_ne_float_test.go b/tests/integration/query/simple/with_filter/with_ne_float_test.go index 6e8e04175f..58b2985013 100644 --- a/tests/integration/query/simple/with_filter/with_ne_float_test.go +++ b/tests/integration/query/simple/with_filter/with_ne_float_test.go @@ -17,29 +17,33 @@ import ( ) func TestQuerySimpleWithFloatNotEqualsFilterBlock(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with ne float filter", - Request: `query { - Users(filter: {HeightM: {_ne: 2.1}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "HeightM": 3.2 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Bob", + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_ne: 2.1}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + }, }, }, }, @@ -49,35 +53,41 @@ func TestQuerySimpleWithFloatNotEqualsFilterBlock(t *testing.T) { } func TestQuerySimpleWithFloatNotEqualsNilFilterBlock(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with ne float nil filter", - Request: `query { - Users(filter: {HeightM: {_ne: null}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.1 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "HeightM": 3.2 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Fred" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - }, - { - "Name": "Bob", + testUtils.Request{ + Request: `query { + Users(filter: {HeightM: {_ne: null}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + { + "Name": "Bob", + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_ne_int_test.go b/tests/integration/query/simple/with_filter/with_ne_int_test.go index 543af47d31..173f7fb461 100644 --- a/tests/integration/query/simple/with_filter/with_ne_int_test.go +++ b/tests/integration/query/simple/with_filter/with_ne_int_test.go @@ -17,29 +17,33 @@ import ( ) func TestQuerySimpleWithIntNotEqualsFilterBlock(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with ne int filter", - Request: `query { - Users(filter: {Age: {_ne: 21}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Bob", + testUtils.Request{ + Request: `query { + Users(filter: {Age: {_ne: 21}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + }, }, }, }, @@ -49,35 +53,41 @@ func TestQuerySimpleWithIntNotEqualsFilterBlock(t *testing.T) { } func TestQuerySimpleWithIntNotEqualsNilFilterBlock(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with ne int nil filter", - Request: `query { - Users(filter: {Age: {_ne: null}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Fred" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - }, - { - "Name": "Bob", + testUtils.Request{ + Request: `query { + Users(filter: {Age: {_ne: null}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + { + "Name": "Bob", + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_ne_string_test.go b/tests/integration/query/simple/with_filter/with_ne_string_test.go index 141e9b6d78..d72e60f927 100644 --- a/tests/integration/query/simple/with_filter/with_ne_string_test.go +++ b/tests/integration/query/simple/with_filter/with_ne_string_test.go @@ -17,29 +17,33 @@ import ( ) func TestQuerySimpleWithStringNotEqualsFilterBlock(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with ne string filter", - Request: `query { - Users(filter: {Name: {_ne: "John"}}) { - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_ne: "John"}}) { + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + }, + }, }, }, }, @@ -49,35 +53,41 @@ func TestQuerySimpleWithStringNotEqualsFilterBlock(t *testing.T) { } func TestQuerySimpleWithStringNotEqualsNilFilterBlock(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with ne string nil filter", - Request: `query { - Users(filter: {Name: {_ne: null}}) { - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Age": 36 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(21), - }, - { - "Age": int64(32), + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_ne: null}}) { + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(21), + }, + { + "Age": int64(32), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_nin_test.go b/tests/integration/query/simple/with_filter/with_nin_test.go index bd0f1b7333..7f961bf537 100644 --- a/tests/integration/query/simple/with_filter/with_nin_test.go +++ b/tests/integration/query/simple/with_filter/with_nin_test.go @@ -17,43 +17,53 @@ import ( ) func TestQuerySimpleWithNotInFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with not-in filter", - Request: `query { - Users(filter: {Age: {_nin: [19, 40, 55, null]}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Fred" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - }, - { - "Name": "Bob", + testUtils.Request{ + Request: `query { + Users(filter: {Age: {_nin: [19, 40, 55, null]}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + }, + { + "Name": "Bob", + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_nlike_string_test.go b/tests/integration/query/simple/with_filter/with_nlike_string_test.go index 7c07b785ae..f6d3165d30 100644 --- a/tests/integration/query/simple/with_filter/with_nlike_string_test.go +++ b/tests/integration/query/simple/with_filter/with_nlike_string_test.go @@ -17,29 +17,33 @@ import ( ) func TestQuerySimpleWithNotLikeStringContainsFilterBlockContainsString(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic not like-string filter contains string", - Request: `query { - Users(filter: {Name: {_nlike: "%Stormborn%"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_nlike: "%Stormborn%"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, + }, }, }, }, @@ -49,29 +53,33 @@ func TestQuerySimpleWithNotLikeStringContainsFilterBlockContainsString(t *testin } func TestQuerySimple_WithNotCaseInsensitiveLikeString_ShouldMatchString(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic not case insensitive like-string filter contains string", - Request: `query { - Users(filter: {Name: {_nilike: "%stormborn%"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_nilike: "%stormborn%"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, + }, }, }, }, @@ -81,29 +89,33 @@ func TestQuerySimple_WithNotCaseInsensitiveLikeString_ShouldMatchString(t *testi } func TestQuerySimpleWithNotLikeStringContainsFilterBlockAsPrefixString(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic not like-string filter with string as prefix", - Request: `query { - Users(filter: {Name: {_nlike: "Viserys%"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_nlike: "Viserys%"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, + }, }, }, }, @@ -113,29 +125,33 @@ func TestQuerySimpleWithNotLikeStringContainsFilterBlockAsPrefixString(t *testin } func TestQuerySimple_WithNotCaseInsensitiveLikeString_ShouldMatchPrefixString(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic not case insensitive like-string filter with string as prefix", - Request: `query { - Users(filter: {Name: {_nilike: "viserys%"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_nilike: "viserys%"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, + }, }, }, }, @@ -145,29 +161,33 @@ func TestQuerySimple_WithNotCaseInsensitiveLikeString_ShouldMatchPrefixString(t } func TestQuerySimpleWithNotLikeStringContainsFilterBlockAsSuffixString(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic not like-string filter with string as suffix", - Request: `query { - Users(filter: {Name: {_nlike: "%Andals"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_nlike: "%Andals"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, + }, }, }, }, @@ -177,29 +197,33 @@ func TestQuerySimpleWithNotLikeStringContainsFilterBlockAsSuffixString(t *testin } func TestQuerySimple_WithNotCaseInsensitiveLikeString_ShouldMatchSuffixString(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic not like-string filter with string as suffix", - Request: `query { - Users(filter: {Name: {_nilike: "%andals"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_nilike: "%andals"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, + }, }, }, }, @@ -209,29 +233,33 @@ func TestQuerySimple_WithNotCaseInsensitiveLikeString_ShouldMatchSuffixString(t } func TestQuerySimpleWithNotLikeStringContainsFilterBlockExactString(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic not like-string filter with string as suffix", - Request: `query { - Users(filter: {Name: {_nlike: "Daenerys Stormborn of House Targaryen, the First of Her Name"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_nlike: "Daenerys Stormborn of House Targaryen, the First of Her Name"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, + }, }, }, }, @@ -241,29 +269,33 @@ func TestQuerySimpleWithNotLikeStringContainsFilterBlockExactString(t *testing.T } func TestQuerySimple_WithNotCaseInsensitiveLikeString_MatchExactString(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic not case insensitive like-string filter with string as suffix", - Request: `query { - Users(filter: {Name: {_nilike: "daenerys stormborn of house targaryen, the first of her name"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_nilike: "daenerys stormborn of house targaryen, the first of her name"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, + }, }, }, }, @@ -273,27 +305,31 @@ func TestQuerySimple_WithNotCaseInsensitiveLikeString_MatchExactString(t *testin } func TestQuerySimpleWithNotLikeStringContainsFilterBlockContainsStringMuplitpleResults(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic not like-string filter with contains string multiple results", - Request: `query { - Users(filter: {Name: {_nlike: "%Targaryen%"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{}, + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_nlike: "%Targaryen%"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{}, + }, + }, }, } @@ -301,29 +337,33 @@ func TestQuerySimpleWithNotLikeStringContainsFilterBlockContainsStringMuplitpleR } func TestQuerySimpleWithNotLikeStringContainsFilterBlockHasStartAndEnd(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic not like-string filter with string as start and end", - Request: `query { - Users(filter: {Name: {_nlike: "Daenerys%Name"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_nlike: "Daenerys%Name"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, + }, }, }, }, @@ -333,29 +373,33 @@ func TestQuerySimpleWithNotLikeStringContainsFilterBlockHasStartAndEnd(t *testin } func TestQuerySimpleWithNotLikeStringContainsFilterBlockHasBoth(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic not like-string filter with none of the strings", - Request: `query { - Users(filter: {_and: [{Name: {_nlike: "%Baratheon%"}}, {Name: {_nlike: "%Stormborn%"}}]}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", + testUtils.Request{ + Request: `query { + Users(filter: {_and: [{Name: {_nlike: "%Baratheon%"}}, {Name: {_nlike: "%Stormborn%"}}]}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, + }, }, }, }, @@ -365,32 +409,36 @@ func TestQuerySimpleWithNotLikeStringContainsFilterBlockHasBoth(t *testing.T) { } func TestQuerySimpleWithNotLikeStringContainsFilterBlockHasEither(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic not like-string filter with either strings", - Request: `query { - Users(filter: {_or: [{Name: {_nlike: "%Baratheon%"}}, {Name: {_nlike: "%Stormborn%"}}]}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Viserys I Targaryen, King of the Andals", - }, - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + testUtils.Request{ + Request: `query { + Users(filter: {_or: [{Name: {_nlike: "%Baratheon%"}}, {Name: {_nlike: "%Stormborn%"}}]}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Viserys I Targaryen, King of the Andals", + }, + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, + }, }, }, }, @@ -400,35 +448,41 @@ func TestQuerySimpleWithNotLikeStringContainsFilterBlockHasEither(t *testing.T) } func TestQuerySimpleWithNotLikeStringContainsFilterBlockPropNotSet(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic not like-string filter with either strings", - Request: `query { - Users(filter: {Name: {_nlike: "%King%"}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", "HeightM": 1.65 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Viserys I Targaryen, King of the Andals", "HeightM": 1.82 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "HeightM": 1.92 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", - }, - { - "Name": nil, + testUtils.Request{ + Request: `query { + Users(filter: {Name: {_nlike: "%King%"}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Daenerys Stormborn of House Targaryen, the First of Her Name", + }, + { + "Name": nil, + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_not_test.go b/tests/integration/query/simple/with_filter/with_not_test.go index 6e9ffcc0da..15071e9c14 100644 --- a/tests/integration/query/simple/with_filter/with_not_test.go +++ b/tests/integration/query/simple/with_filter/with_not_test.go @@ -17,47 +17,55 @@ import ( ) func TestQuerySimple_WithNotEqualToXFilter_NoError(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with logical compound filter (not)", - Request: `query { - Users(filter: {_not: {Age: {_eq: 55}}}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Bob", - "Age": int64(32), - }, - { - "Name": "Alice", - "Age": int64(19), + testUtils.Request{ + Request: `query { + Users(filter: {_not: {Age: {_eq: 55}}}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Bob", + "Age": int64(32), + }, + { + "Name": "Alice", + "Age": int64(19), + }, + }, }, }, }, @@ -67,39 +75,47 @@ func TestQuerySimple_WithNotEqualToXFilter_NoError(t *testing.T) { } func TestQuerySimple_WithNotAndComparisonXFilter_NoError(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with _not filter with _gt condition)", - Request: `query { - Users(filter: {_not: {Age: {_gt: 20}}}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Alice", - "Age": int64(19), + testUtils.Request{ + Request: `query { + Users(filter: {_not: {Age: {_gt: 20}}}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Alice", + "Age": int64(19), + }, + }, }, }, }, @@ -109,43 +125,51 @@ func TestQuerySimple_WithNotAndComparisonXFilter_NoError(t *testing.T) { } func TestQuerySimple_WithNotEqualToXorYFilter_NoError(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with logical compound filter (not)", - Request: `query { - Users(filter: {_not: {_or: [{Age: {_eq: 55}}, {Name: {_eq: "Alice"}}]}}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Bob", - "Age": int64(32), + testUtils.Request{ + Request: `query { + Users(filter: {_not: {_or: [{Age: {_eq: 55}}, {Name: {_eq: "Alice"}}]}}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Bob", + "Age": int64(32), + }, + }, }, }, }, @@ -155,36 +179,44 @@ func TestQuerySimple_WithNotEqualToXorYFilter_NoError(t *testing.T) { } func TestQuerySimple_WithEmptyNotFilter_ReturnError(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with empty logical compound filter (not) returns empty result set", - Request: `query { - Users(filter: {_not: {}}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{}, + testUtils.Request{ + Request: `query { + Users(filter: {_not: {}}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{}, + }, + }, }, } @@ -192,55 +224,65 @@ func TestQuerySimple_WithEmptyNotFilter_ReturnError(t *testing.T) { } func TestQuerySimple_WithNotEqualToXAndNotYFilter_NoError(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with logical compound filter (not)", - Request: `query { - Users(filter: {_not: {Age: {_eq: 55}, _not: {Name: {_eq: "Carlo"}}}}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Frank", "Age": 55 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Bob", - "Age": int64(32), - }, - { - "Name": "Carlo", - "Age": int64(55), - }, - { - "Name": "Alice", - "Age": int64(19), + testUtils.Request{ + Request: `query { + Users(filter: {_not: {Age: {_eq: 55}, _not: {Name: {_eq: "Carlo"}}}}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Bob", + "Age": int64(32), + }, + { + "Name": "Carlo", + "Age": int64(55), + }, + { + "Name": "Alice", + "Age": int64(19), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_filter/with_or_test.go b/tests/integration/query/simple/with_filter/with_or_test.go index 6a913730c2..fe63d7cc62 100644 --- a/tests/integration/query/simple/with_filter/with_or_test.go +++ b/tests/integration/query/simple/with_filter/with_or_test.go @@ -17,43 +17,51 @@ import ( ) func TestQuerySimpleWithIntEqualToXOrYFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with logical compound filter (or)", - Request: `query { - Users(filter: {_or: [{Age: {_eq: 55}}, {Age: {_eq: 19}}]}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Carlo", - "Age": int64(55), - }, - { - "Name": "Alice", - "Age": int64(19), + testUtils.Request{ + Request: `query { + Users(filter: {_or: [{Age: {_eq: 55}}, {Age: {_eq: 19}}]}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "Age": int64(55), + }, + { + "Name": "Alice", + "Age": int64(19), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_average_count_test.go b/tests/integration/query/simple/with_group_average_count_test.go index 837b12d11c..771259d115 100644 --- a/tests/integration/query/simple/with_group_average_count_test.go +++ b/tests/integration/query/simple/with_group_average_count_test.go @@ -21,43 +21,48 @@ import ( // verify that that code path is taken, but it does verfiy that the correct result // is returned to the consumer in case the more efficient code path is taken. func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerAverageAndCount(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, average and sum on non-rendered group integer value", - Request: `query { - Users(groupBy: [Name]) { - Name - _avg(_group: {field: Age}) - _count(_group: {}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 38 }`, - // It is important to test negative values here, due to the auto-typing of numbers - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": -19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_avg": float64(35), - "_count": int(2), - }, - { - "Name": "Alice", - "_avg": float64(-19), - "_count": int(1), + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _avg(_group: {field: Age}) + _count(_group: {}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(35), + "_count": int(2), + }, + { + "Name": "Alice", + "_avg": float64(-19), + "_count": int(1), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_average_filter_test.go b/tests/integration/query/simple/with_group_average_filter_test.go index 6f17370301..d5c145c15f 100644 --- a/tests/integration/query/simple/with_group_average_filter_test.go +++ b/tests/integration/query/simple/with_group_average_filter_test.go @@ -17,39 +17,45 @@ import ( ) func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildAverageWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, no children, average on non-rendered, unfiltered group", - Request: `query { - Users(groupBy: [Name]) { - Name - _avg(_group: {field: Age, filter: {Age: {_gt: 26}}}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 34 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_avg": float64(33), - }, - { - "Name": "Alice", - "_avg": float64(0), + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _avg(_group: {field: Age, filter: {Age: {_gt: 26}}}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(33), + }, + { + "Name": "Alice", + "_avg": float64(0), + }, + }, }, }, }, @@ -59,53 +65,59 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildAverageWithFilt } func TestQuerySimpleWithGroupByStringWithRenderedGroupAndChildAverageWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, no children, average on rendered, unfiltered group", - Request: `query { - Users(groupBy: [Name]) { - Name - _avg(_group: {field: Age, filter: {Age: {_gt: 26}}}) - _group { - Age - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 34 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_avg": float64(33), - "_group": []map[string]any{ - { - "Age": int64(34), - }, + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _avg(_group: {field: Age, filter: {Age: {_gt: 26}}}) + _group { + Age + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Age": int64(32), + "Name": "John", + "_avg": float64(33), + "_group": []map[string]any{ + { + "Age": int64(34), + }, + { + "Age": int64(32), + }, + }, }, - }, - }, - { - "Name": "Alice", - "_avg": float64(0), - "_group": []map[string]any{ { - "Age": int64(19), + "Name": "Alice", + "_avg": float64(0), + "_group": []map[string]any{ + { + "Age": int64(19), + }, + }, }, }, }, @@ -117,56 +129,62 @@ func TestQuerySimpleWithGroupByStringWithRenderedGroupAndChildAverageWithFilter( } func TestQuerySimpleWithGroupByStringWithRenderedGroupAndChildAverageWithDateTimeFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, no children, average on rendered, unfiltered group", - Request: `query { - Users(groupBy: [Name]) { - Name - _avg(_group: {field: Age, filter: {CreatedAt: {_gt: "2017-07-23T03:46:56-05:00"}}}) - _group { - Age - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 34, "CreatedAt": "2019-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32, "CreatedAt": "2018-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19, "CreatedAt": "2011-07-23T03:46:56-05:00" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_avg": float64(33), - "_group": []map[string]any{ - { - "Age": int64(32), - }, + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _avg(_group: {field: Age, filter: {CreatedAt: {_gt: "2017-07-23T03:46:56-05:00"}}}) + _group { + Age + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Age": int64(34), + "Name": "John", + "_avg": float64(33), + "_group": []map[string]any{ + { + "Age": int64(32), + }, + { + "Age": int64(34), + }, + }, }, - }, - }, - { - "Name": "Alice", - "_avg": float64(0), - "_group": []map[string]any{ { - "Age": int64(19), + "Name": "Alice", + "_avg": float64(0), + "_group": []map[string]any{ + { + "Age": int64(19), + }, + }, }, }, }, @@ -178,49 +196,55 @@ func TestQuerySimpleWithGroupByStringWithRenderedGroupAndChildAverageWithDateTim } func TestQuerySimpleWithGroupByStringWithRenderedGroupWithFilterAndChildAverageWithMatchingFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, no children, average on rendered, matching filtered group", - Request: `query { - Users(groupBy: [Name]) { - Name - _avg(_group: {field: Age, filter: {Age: {_gt: 33}}}) - _group(filter: {Age: {_gt: 33}}) { - Age - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 34 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_avg": float64(34), - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _avg(_group: {field: Age, filter: {Age: {_gt: 33}}}) + _group(filter: {Age: {_gt: 33}}) { + Age + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(34), + "_group": []map[string]any{ + { + "Age": int64(34), + }, + }, + }, { - "Age": int64(34), + "Name": "Alice", + "_avg": float64(0), + "_group": []map[string]any{}, }, }, }, - { - "Name": "Alice", - "_avg": float64(0), - "_group": []map[string]any{}, - }, }, }, } @@ -229,52 +253,58 @@ func TestQuerySimpleWithGroupByStringWithRenderedGroupWithFilterAndChildAverageW } func TestQuerySimpleWithGroupByStringWithRenderedGroupWithFilterAndChildAverageWithMatchingDateTimeFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, no children, average on rendered, matching datetime filtered group", - Request: `query { - Users(groupBy: [Name]) { - Name - _avg(_group: {field: Age, filter: {CreatedAt: {_gt: "2016-07-23T03:46:56-05:00"}}}) - _group(filter: {CreatedAt: {_gt: "2016-07-23T03:46:56-05:00"}}) { - Age - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 34, "CreatedAt": "2017-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32, "CreatedAt": "2011-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19, "CreatedAt": "2010-07-23T03:46:56-05:00" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_avg": float64(34), - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _avg(_group: {field: Age, filter: {CreatedAt: {_gt: "2016-07-23T03:46:56-05:00"}}}) + _group(filter: {CreatedAt: {_gt: "2016-07-23T03:46:56-05:00"}}) { + Age + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Age": int64(34), + "Name": "John", + "_avg": float64(34), + "_group": []map[string]any{ + { + "Age": int64(34), + }, + }, + }, + { + "Name": "Alice", + "_avg": float64(0), + "_group": []map[string]any{}, }, }, }, - { - "Name": "Alice", - "_avg": float64(0), - "_group": []map[string]any{}, - }, }, }, } @@ -283,50 +313,56 @@ func TestQuerySimpleWithGroupByStringWithRenderedGroupWithFilterAndChildAverageW } func TestQuerySimpleWithGroupByStringWithRenderedGroupWithFilterAndChildAverageWithDifferentFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, no children, average on non-rendered, different filtered group", - Request: `query { - Users(groupBy: [Name]) { - Name - _avg(_group: {field: Age, filter: {Age: {_gt: 33}}}) - _group(filter: {Age: {_lt: 33}}) { - Age - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 34 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_avg": float64(34), - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _avg(_group: {field: Age, filter: {Age: {_gt: 33}}}) + _group(filter: {Age: {_lt: 33}}) { + Age + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Age": int64(32), + "Name": "John", + "_avg": float64(34), + "_group": []map[string]any{ + { + "Age": int64(32), + }, + }, }, - }, - }, - { - "Name": "Alice", - "_avg": float64(0), - "_group": []map[string]any{ { - "Age": int64(19), + "Name": "Alice", + "_avg": float64(0), + "_group": []map[string]any{ + { + "Age": int64(19), + }, + }, }, }, }, @@ -338,42 +374,48 @@ func TestQuerySimpleWithGroupByStringWithRenderedGroupWithFilterAndChildAverageW } func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildAveragesWithDifferentFilters(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, no children, average on non-rendered, unfiltered group", - Request: `query { - Users(groupBy: [Name]) { - Name - A1: _avg(_group: {field: Age, filter: {Age: {_gt: 26}}}) - A2: _avg(_group: {field: Age, filter: {Age: {_lt: 26}}}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 34 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "A1": float64(33), - "A2": float64(0), - }, - { - "Name": "Alice", - "A1": float64(0), - "A2": float64(19), + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + A1: _avg(_group: {field: Age, filter: {Age: {_gt: 26}}}) + A2: _avg(_group: {field: Age, filter: {Age: {_lt: 26}}}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "A1": float64(33), + "A2": float64(0), + }, + { + "Name": "Alice", + "A1": float64(0), + "A2": float64(19), + }, + }, }, }, }, @@ -384,46 +426,56 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildAveragesWithDif func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildAverageWithFilterAndNilItem(t *testing.T) { // This test checks that the appended/internal nil filter does not clash with the consumer-defined filter - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, no children, average with filter on non-rendered, unfiltered group", - Request: `query { - Users(groupBy: [Name]) { - Name - _avg(_group: {field: Age, filter: {Age: {_lt: 33}}}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 34 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 30 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_avg": float64(31), - }, - { - "Name": "Alice", - "_avg": float64(19), + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _avg(_group: {field: Age, filter: {Age: {_lt: 33}}}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(31), + }, + { + "Name": "Alice", + "_avg": float64(19), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_average_limit_offset_test.go b/tests/integration/query/simple/with_group_average_limit_offset_test.go index 110dcc8bfd..0d7ba5d7e1 100644 --- a/tests/integration/query/simple/with_group_average_limit_offset_test.go +++ b/tests/integration/query/simple/with_group_average_limit_offset_test.go @@ -17,44 +17,51 @@ import ( ) func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerAverageWithLimitAndOffset(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, limited average on non-rendered group integer value", - Request: `query { - Users(groupBy: [Name]) { - Name - _avg(_group: {field: Age, offset: 1, limit: 2}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 38 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 28 }`, - // It is important to test negative values here, due to the auto-typing of numbers - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": -19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_avg": float64(35), - }, - { - "Name": "Alice", - "_avg": float64(0), + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _avg(_group: {field: Age, offset: 1, limit: 2}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(35), + }, + { + "Name": "Alice", + "_avg": float64(0), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_average_limit_test.go b/tests/integration/query/simple/with_group_average_limit_test.go index ca5b1b0d81..415e2eee5b 100644 --- a/tests/integration/query/simple/with_group_average_limit_test.go +++ b/tests/integration/query/simple/with_group_average_limit_test.go @@ -17,44 +17,52 @@ import ( ) func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerAverageWithLimit(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, limited average on non-rendered group integer value", - Request: `query { - Users(groupBy: [Name]) { - Name - _avg(_group: {field: Age, limit: 2}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 38 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 28 }`, + }, + testUtils.CreateDoc{ // It is important to test negative values here, due to the auto-typing of numbers - `{ + Doc: `{ "Name": "Alice", "Age": -19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_avg": float64(33), - }, - { - "Name": "Alice", - "_avg": float64(-19), + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _avg(_group: {field: Age, limit: 2}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(33), + }, + { + "Name": "Alice", + "_avg": float64(-19), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_average_sum_test.go b/tests/integration/query/simple/with_group_average_sum_test.go index 4e00607986..e16aab05e7 100644 --- a/tests/integration/query/simple/with_group_average_sum_test.go +++ b/tests/integration/query/simple/with_group_average_sum_test.go @@ -17,80 +17,90 @@ import ( ) func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndSumOfCountOfInt(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, with child group by boolean, and sum of average on int", - Request: `query { - Users(groupBy: [Name]) { - Name - _sum(_group: {field: _avg}) - _group (groupBy: [Verified]){ - Verified - _avg(_group: {field: Age}) - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 25, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 34, "Verified": false }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19, "Verified": false }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_sum": float64(62.5), - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _sum(_group: {field: _avg}) + _group (groupBy: [Verified]){ + Verified + _avg(_group: {field: Age}) + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Verified": true, - "_avg": float64(28.5), + "Name": "John", + "_sum": float64(62.5), + "_group": []map[string]any{ + { + "Verified": true, + "_avg": float64(28.5), + }, + { + "Verified": false, + "_avg": float64(34), + }, + }, }, { - "Verified": false, - "_avg": float64(34), + "Name": "Carlo", + "_sum": float64(55), + "_group": []map[string]any{ + { + "Verified": true, + "_avg": float64(55), + }, + }, }, - }, - }, - { - "Name": "Carlo", - "_sum": float64(55), - "_group": []map[string]any{ { - "Verified": true, - "_avg": float64(55), - }, - }, - }, - { - "Name": "Alice", - "_sum": float64(19), - "_group": []map[string]any{ - { - "Verified": false, - "_avg": float64(19), + "Name": "Alice", + "_sum": float64(19), + "_group": []map[string]any{ + { + "Verified": false, + "_avg": float64(19), + }, + }, }, }, }, @@ -106,43 +116,49 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndSumOfCountOfInt(t * // verify that that code path is taken, but it does verfiy that the correct result // is returned to the consumer in case the more efficient code path is taken. func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerAverageAndSum(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, average and sum on non-rendered group integer value", - Request: `query { - Users(groupBy: [Name]) { - Name - _avg(_group: {field: Age}) - _sum(_group: {field: Age}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 38 }`, + }, + testUtils.CreateDoc{ // It is important to test negative values here, due to the auto-typing of numbers - `{ + Doc: `{ "Name": "Alice", "Age": -19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_avg": float64(35), - "_sum": int64(70), - }, - { - "Name": "Alice", - "_avg": float64(-19), - "_sum": int64(-19), + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _avg(_group: {field: Age}) + _sum(_group: {field: Age}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(35), + "_sum": int64(70), + }, + { + "Name": "Alice", + "_avg": float64(-19), + "_sum": int64(-19), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_average_test.go b/tests/integration/query/simple/with_group_average_test.go index 9afbef7a3e..a346ee61fa 100644 --- a/tests/integration/query/simple/with_group_average_test.go +++ b/tests/integration/query/simple/with_group_average_test.go @@ -17,39 +17,45 @@ import ( ) func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndAverageOfUndefined(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with average on unspecified field", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 32 + }`, + }, + testUtils.Request{ + Request: `query { Users (groupBy: [Name]) { Name _avg } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 32 - }`, + ExpectedError: "aggregate must be provided with a property to aggregate", }, }, - ExpectedError: "aggregate must be provided with a property to aggregate", } executeTestCase(t, test) } func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerAverageOnEmptyCollection(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, average on non-rendered group, empty collection", - Request: `query { + Actions: []any{ + testUtils.Request{ + Request: `query { Users(groupBy: [Age]) { Age _avg(_group: {field: Age}) } }`, - Results: map[string]any{ - "Users": []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, + }, }, } @@ -57,40 +63,46 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerAverageO } func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerAverage(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, average on non-rendered group integer value", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 32 + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 38 + }`, + }, + testUtils.CreateDoc{ + // It is important to test negative values here, due to the auto-typing of numbers + Doc: `{ + "Name": "Alice", + "Age": -19 + }`, + }, + testUtils.Request{ + Request: `query { Users(groupBy: [Name]) { Name _avg(_group: {field: Age}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 32 - }`, - `{ - "Name": "John", - "Age": 38 - }`, - // It is important to test negative values here, due to the auto-typing of numbers - `{ - "Name": "Alice", - "Age": -19 - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_avg": float64(35), - }, - { - "Name": "Alice", - "_avg": float64(-19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(35), + }, + { + "Name": "Alice", + "_avg": float64(-19), + }, + }, }, }, }, @@ -100,39 +112,45 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerAverage( } func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildNilAverage(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, average on non-rendered group nil and integer values", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 32 + }`, + }, + testUtils.CreateDoc{ + // Age is undefined here and must be ignored + Doc: `{ + "Name": "John" + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "Name": "Alice", + "Age": 19 + }`, + }, + testUtils.Request{ + Request: `query { Users(groupBy: [Name]) { Name _avg(_group: {field: Age}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 32 - }`, - // Age is undefined here and must be ignored - `{ - "Name": "John" - }`, - `{ - "Name": "Alice", - "Age": 19 - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_avg": float64(32), - }, - { - "Name": "Alice", - "_avg": float64(19), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(32), + }, + { + "Name": "Alice", + "_avg": float64(19), + }, + }, }, }, }, @@ -142,9 +160,46 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildNilAverage(t *t } func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndAverageOfAverageOfInt(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, with child group by boolean, and average of average on int", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 25, + "Verified": true + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 32, + "Verified": true + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 34, + "Verified": false + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "Name": "Carlo", + "Age": 55, + "Verified": true + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "Name": "Alice", + "Age": 19, + "Verified": false + }`, + }, + testUtils.Request{ + Request: `query { Users(groupBy: [Name]) { Name _avg(_group: {field: _avg}) @@ -154,68 +209,41 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndAverageOfAverageOfI } } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 25, - "Verified": true - }`, - `{ - "Name": "John", - "Age": 32, - "Verified": true - }`, - `{ - "Name": "John", - "Age": 34, - "Verified": false - }`, - `{ - "Name": "Carlo", - "Age": 55, - "Verified": true - }`, - `{ - "Name": "Alice", - "Age": 19, - "Verified": false - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_avg": float64(31.25), - "_group": []map[string]any{ - { - "Verified": true, - "_avg": float64(28.5), - }, + Results: map[string]any{ + "Users": []map[string]any{ { - "Verified": false, - "_avg": float64(34), + "Name": "John", + "_avg": float64(31.25), + "_group": []map[string]any{ + { + "Verified": true, + "_avg": float64(28.5), + }, + { + "Verified": false, + "_avg": float64(34), + }, + }, }, - }, - }, - { - "Name": "Carlo", - "_avg": float64(55), - "_group": []map[string]any{ { - "Verified": true, - "_avg": float64(55), + "Name": "Carlo", + "_avg": float64(55), + "_group": []map[string]any{ + { + "Verified": true, + "_avg": float64(55), + }, + }, }, - }, - }, - { - "Name": "Alice", - "_avg": float64(19), - "_group": []map[string]any{ { - "Verified": false, - "_avg": float64(19), + "Name": "Alice", + "_avg": float64(19), + "_group": []map[string]any{ + { + "Verified": false, + "_avg": float64(19), + }, + }, }, }, }, @@ -227,38 +255,44 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndAverageOfAverageOfI } func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildEmptyFloatAverage(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, average on non-rendered group float (default) value", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "HeightM": 1.82 + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "HeightM": 1.89 + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "Name": "Alice" + }`, + }, + testUtils.Request{ + Request: `query { Users(groupBy: [Name]) { Name _avg(_group: {field: HeightM}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "HeightM": 1.82 - }`, - `{ - "Name": "John", - "HeightM": 1.89 - }`, - `{ - "Name": "Alice" - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_avg": float64(1.855), - }, - { - "Name": "Alice", - "_avg": float64(0), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(1.855), + }, + { + "Name": "Alice", + "_avg": float64(0), + }, + }, }, }, }, @@ -268,39 +302,45 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildEmptyFloatAvera } func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildFloatAverage(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, average on non-rendered group float value", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "HeightM": 1.82 + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "HeightM": 1.89 + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "Name": "Alice", + "HeightM": 2.04 + }`, + }, + testUtils.Request{ + Request: `query { Users(groupBy: [Name]) { Name _avg(_group: {field: HeightM}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "HeightM": 1.82 - }`, - `{ - "Name": "John", - "HeightM": 1.89 - }`, - `{ - "Name": "Alice", - "HeightM": 2.04 - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_avg": float64(1.855), - }, - { - "Name": "Alice", - "_avg": float64(2.04), + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_avg": float64(1.855), + }, + { + "Name": "Alice", + "_avg": float64(2.04), + }, + }, }, }, }, @@ -310,9 +350,46 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildFloatAverage(t } func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndAverageOfAverageOfFloat(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, with child group by boolean, and average of average on float", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "HeightM": 1.82, + "Verified": true + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "HeightM": 1.61, + "Verified": true + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "HeightM": 2.22, + "Verified": false + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "Name": "Carlo", + "HeightM": 1.74, + "Verified": true + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "Name": "Alice", + "HeightM": 2.04, + "Verified": false + }`, + }, + testUtils.Request{ + Request: `query { Users(groupBy: [Name]) { Name _avg(_group: {field: _avg}) @@ -322,68 +399,41 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndAverageOfAverageOfF } } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "HeightM": 1.82, - "Verified": true - }`, - `{ - "Name": "John", - "HeightM": 1.61, - "Verified": true - }`, - `{ - "Name": "John", - "HeightM": 2.22, - "Verified": false - }`, - `{ - "Name": "Carlo", - "HeightM": 1.74, - "Verified": true - }`, - `{ - "Name": "Alice", - "HeightM": 2.04, - "Verified": false - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Alice", - "_avg": float64(2.04), - "_group": []map[string]any{ - { - "Verified": false, - "_avg": float64(2.04), - }, - }, - }, - { - "Name": "John", - "_avg": float64(1.9675000000000002), - "_group": []map[string]any{ + Results: map[string]any{ + "Users": []map[string]any{ { - "Verified": true, - "_avg": float64(1.715), + "Name": "Alice", + "_avg": float64(2.04), + "_group": []map[string]any{ + { + "Verified": false, + "_avg": float64(2.04), + }, + }, }, { - "Verified": false, - "_avg": float64(2.22), + "Name": "John", + "_avg": float64(1.9675000000000002), + "_group": []map[string]any{ + { + "Verified": true, + "_avg": float64(1.715), + }, + { + "Verified": false, + "_avg": float64(2.22), + }, + }, }, - }, - }, - { - "Name": "Carlo", - "_avg": float64(1.74), - "_group": []map[string]any{ { - "Verified": true, - "_avg": float64(1.74), + "Name": "Carlo", + "_avg": float64(1.74), + "_group": []map[string]any{ + { + "Verified": true, + "_avg": float64(1.74), + }, + }, }, }, }, @@ -395,115 +445,125 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndAverageOfAverageOfF } func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndAverageOfAverageOfAverageOfFloat(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, with child group by boolean, and average of average of average of float", - Request: `query { - Users(groupBy: [Name]) { - Name - _avg(_group: {field: _avg}) - _group (groupBy: [Verified]){ - Verified - _avg(_group: {field: HeightM}) - _group (groupBy: [Age]){ - Age - _avg(_group: {field: HeightM}) - } - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 1.82, "Age": 25, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 1.61, "Age": 32, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.22, "Age": 34, "Verified": false }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "HeightM": 1.74, "Age": 55, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "HeightM": 2.04, "Age": 19, "Verified": false }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Carlo", - "_avg": float64(1.74), - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _avg(_group: {field: _avg}) + _group (groupBy: [Verified]){ + Verified + _avg(_group: {field: HeightM}) + _group (groupBy: [Age]){ + Age + _avg(_group: {field: HeightM}) + } + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Verified": true, - "_avg": float64(1.74), + "Name": "Carlo", + "_avg": float64(1.74), "_group": []map[string]any{ { - "Age": int64(55), - "_avg": float64(1.74), + "Verified": true, + "_avg": float64(1.74), + "_group": []map[string]any{ + { + "Age": int64(55), + "_avg": float64(1.74), + }, + }, }, }, }, - }, - }, - { - "Name": "Alice", - "_avg": float64(2.04), - "_group": []map[string]any{ { - "Verified": false, - "_avg": float64(2.04), + "Name": "Alice", + "_avg": float64(2.04), "_group": []map[string]any{ { - "Age": int64(19), - "_avg": float64(2.04), + "Verified": false, + "_avg": float64(2.04), + "_group": []map[string]any{ + { + "Age": int64(19), + "_avg": float64(2.04), + }, + }, }, }, }, - }, - }, - { - "Name": "John", - "_avg": float64(1.9675000000000002), - "_group": []map[string]any{ { - "Verified": true, - "_avg": float64(1.715), + "Name": "John", + "_avg": float64(1.9675000000000002), "_group": []map[string]any{ { - "Age": int64(32), - "_avg": float64(1.61), - }, - { - "Age": int64(25), - "_avg": float64(1.82), + "Verified": true, + "_avg": float64(1.715), + "_group": []map[string]any{ + { + "Age": int64(32), + "_avg": float64(1.61), + }, + { + "Age": int64(25), + "_avg": float64(1.82), + }, + }, }, - }, - }, - { - "Verified": false, - "_avg": float64(2.22), - "_group": []map[string]any{ { - "Age": int64(34), - "_avg": float64(2.22), + "Verified": false, + "_avg": float64(2.22), + "_group": []map[string]any{ + { + "Age": int64(34), + "_avg": float64(2.22), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_count_filter_test.go b/tests/integration/query/simple/with_group_count_filter_test.go index 9d2950b4e5..4544755898 100644 --- a/tests/integration/query/simple/with_group_count_filter_test.go +++ b/tests/integration/query/simple/with_group_count_filter_test.go @@ -17,39 +17,45 @@ import ( ) func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildCountWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, count on non-rendered, unfiltered group", - Request: `query { - Users(groupBy: [Age]) { - Age - _count(_group: {filter: {Age: {_gt: 26}}}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "_count": 2, - }, - { - "Age": int64(19), - "_count": 0, + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _count(_group: {filter: {Age: {_gt: 26}}}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_count": 2, + }, + { + "Age": int64(19), + "_count": 0, + }, + }, }, }, }, @@ -59,53 +65,59 @@ func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildCountWithFilter } func TestQuerySimpleWithGroupByNumberWithRenderedGroupAndChildCountWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, count on non-rendered, filtered group", - Request: `query { - Users(groupBy: [Age]) { - Age - _count(_group: {filter: {Age: {_gt: 26}}}) - _group { - Name - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "_count": 2, - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _count(_group: {filter: {Age: {_gt: 26}}}) + _group { + Name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Name": "Bob", + "Age": int64(32), + "_count": 2, + "_group": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, + }, }, { - "Name": "John", - }, - }, - }, - { - "Age": int64(19), - "_count": 0, - "_group": []map[string]any{ - { - "Name": "Alice", + "Age": int64(19), + "_count": 0, + "_group": []map[string]any{ + { + "Name": "Alice", + }, + }, }, }, }, @@ -117,49 +129,55 @@ func TestQuerySimpleWithGroupByNumberWithRenderedGroupAndChildCountWithFilter(t } func TestQuerySimpleWithGroupByNumberWithRenderedGroupWithFilterAndChildCountWithMatchingFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, count on non-rendered, matching filtered group", - Request: `query { - Users(groupBy: [Age]) { - Age - _count(_group: {filter: {Name: {_eq: "John"}}}) - _group(filter: {Name: {_eq: "John"}}) { - Name - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "_count": 1, - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _count(_group: {filter: {Name: {_eq: "John"}}}) + _group(filter: {Name: {_eq: "John"}}) { + Name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Name": "John", + "Age": int64(32), + "_count": 1, + "_group": []map[string]any{ + { + "Name": "John", + }, + }, + }, + { + "Age": int64(19), + "_count": 0, + "_group": []map[string]any{}, }, }, }, - { - "Age": int64(19), - "_count": 0, - "_group": []map[string]any{}, - }, }, }, } @@ -168,49 +186,55 @@ func TestQuerySimpleWithGroupByNumberWithRenderedGroupWithFilterAndChildCountWit } func TestQuerySimpleWithGroupByNumberWithRenderedGroupWithFilterAndChildCountWithDifferentFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, count on non-rendered, different group filter", - Request: `query { - Users(groupBy: [Age]) { - Age - _count(_group: {filter: {Age: {_gt: 26}}}) - _group(filter: {Name: {_eq: "John"}}) { - Name - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "_count": 2, - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _count(_group: {filter: {Age: {_gt: 26}}}) + _group(filter: {Name: {_eq: "John"}}) { + Name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_count": 2, + "_group": []map[string]any{ + { + "Name": "John", + }, + }, + }, { - "Name": "John", + "Age": int64(19), + "_count": 0, + "_group": []map[string]any{}, }, }, }, - { - "Age": int64(19), - "_count": 0, - "_group": []map[string]any{}, - }, }, }, } @@ -219,42 +243,48 @@ func TestQuerySimpleWithGroupByNumberWithRenderedGroupWithFilterAndChildCountWit } func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildCountsWithDifferentFilters(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, multiple counts on non-rendered, unfiltered group", - Request: `query { - Users(groupBy: [Age]) { - Age - C1: _count(_group: {filter: {Age: {_gt: 26}}}) - C2: _count(_group: {filter: {Age: {_lt: 26}}}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "C1": 2, - "C2": 0, - }, - { - "Age": int64(19), - "C1": 0, - "C2": 1, + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + C1: _count(_group: {filter: {Age: {_gt: 26}}}) + C2: _count(_group: {filter: {Age: {_lt: 26}}}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "C1": 2, + "C2": 0, + }, + { + "Age": int64(19), + "C1": 0, + "C2": 1, + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_count_limit_offset_test.go b/tests/integration/query/simple/with_group_count_limit_offset_test.go index 4fe00f25b9..365cabc886 100644 --- a/tests/integration/query/simple/with_group_count_limit_offset_test.go +++ b/tests/integration/query/simple/with_group_count_limit_offset_test.go @@ -17,39 +17,45 @@ import ( ) func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildCountWithLimitAndOffset(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, count with limit and offset on non-rendered group", - Request: `query { - Users(groupBy: [Age]) { - Age - _count(_group: {offset: 1, limit: 1}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "_count": 1, - }, - { - "Age": int64(19), - "_count": 0, + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _count(_group: {offset: 1, limit: 1}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_count": 1, + }, + { + "Age": int64(19), + "_count": 0, + }, + }, }, }, }, @@ -59,57 +65,65 @@ func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildCountWithLimitA } func TestQuerySimpleWithGroupByNumberWithRenderedGroupWithLimitAndChildCountWithLimitAndOffset(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, child limit, count with limit and offset on rendered group", - Request: `query { - Users(groupBy: [Age]) { - Age - _count(_group: {offset: 1, limit: 1}) - _group (limit: 2) { - Name - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Shahzad", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "_count": 1, - "_group": []map[string]any{ - { - "Name": "Bob", - }, + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _count(_group: {offset: 1, limit: 1}) + _group (limit: 2) { + Name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Name": "Shahzad", + "Age": int64(32), + "_count": 1, + "_group": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "Shahzad", + }, + }, }, - }, - }, - { - "Age": int64(19), - "_count": 0, - "_group": []map[string]any{ { - "Name": "Alice", + "Age": int64(19), + "_count": 0, + "_group": []map[string]any{ + { + "Name": "Alice", + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_count_limit_test.go b/tests/integration/query/simple/with_group_count_limit_test.go index 7deae49208..d31639c6fc 100644 --- a/tests/integration/query/simple/with_group_count_limit_test.go +++ b/tests/integration/query/simple/with_group_count_limit_test.go @@ -17,39 +17,45 @@ import ( ) func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildCountWithLimit(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, count with limit on non-rendered group", - Request: `query { - Users(groupBy: [Age]) { - Age - _count(_group: {limit: 1}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "_count": 1, - }, - { - "Age": int64(19), - "_count": 1, + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _count(_group: {limit: 1}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_count": 1, + }, + { + "Age": int64(19), + "_count": 1, + }, + }, }, }, }, @@ -59,57 +65,65 @@ func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildCountWithLimit( } func TestQuerySimpleWithGroupByNumberWithRenderedGroupWithLimitAndChildCountWithLimit(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, child limit, count with limit on rendered group", - Request: `query { - Users(groupBy: [Age]) { - Age - _count(_group: {limit: 1}) - _group (limit: 2) { - Name - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Shahzad", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "_count": 1, - "_group": []map[string]any{ - { - "Name": "Bob", - }, + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _count(_group: {limit: 1}) + _group (limit: 2) { + Name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Name": "Shahzad", + "Age": int64(32), + "_count": 1, + "_group": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "Shahzad", + }, + }, }, - }, - }, - { - "Age": int64(19), - "_count": 1, - "_group": []map[string]any{ { - "Name": "Alice", + "Age": int64(19), + "_count": 1, + "_group": []map[string]any{ + { + "Name": "Alice", + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_count_sum_test.go b/tests/integration/query/simple/with_group_count_sum_test.go index 7e26628591..9fe06c9c79 100644 --- a/tests/integration/query/simple/with_group_count_sum_test.go +++ b/tests/integration/query/simple/with_group_count_sum_test.go @@ -17,80 +17,90 @@ import ( ) func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndSumOfCount(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, with child group by boolean, and sum of count", - Request: `query { - Users(groupBy: [Name]) { - Name - _sum(_group: {field: _count}) - _group (groupBy: [Verified]){ - Verified - _count(_group: {}) - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 25, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 34, "Verified": false }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19, "Verified": false }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_sum": int64(3), - "_group": []map[string]any{ - { - "Verified": true, - "_count": int(2), - }, + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _sum(_group: {field: _count}) + _group (groupBy: [Verified]){ + Verified + _count(_group: {}) + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Verified": false, - "_count": int(1), + "Name": "John", + "_sum": int64(3), + "_group": []map[string]any{ + { + "Verified": true, + "_count": int(2), + }, + { + "Verified": false, + "_count": int(1), + }, + }, }, - }, - }, - { - "Name": "Carlo", - "_sum": int64(1), - "_group": []map[string]any{ { - "Verified": true, - "_count": int(1), + "Name": "Carlo", + "_sum": int64(1), + "_group": []map[string]any{ + { + "Verified": true, + "_count": int(1), + }, + }, }, - }, - }, - { - "Name": "Alice", - "_sum": int64(1), - "_group": []map[string]any{ { - "Verified": false, - "_count": int(1), + "Name": "Alice", + "_sum": int64(1), + "_group": []map[string]any{ + { + "Verified": false, + "_count": int(1), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_count_test.go b/tests/integration/query/simple/with_group_count_test.go index 4f979f3dcb..f41b1e1d99 100644 --- a/tests/integration/query/simple/with_group_count_test.go +++ b/tests/integration/query/simple/with_group_count_test.go @@ -17,32 +17,42 @@ import ( ) func TestQuerySimpleWithoutGroupByWithCountOnGroup(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query without group by, no children, count on non-existant group", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 32 + }`, + }, + testUtils.Request{ + Request: `query { Users { Age _count(_group: {}) } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 32 - }`, + ExpectedError: "_group may only be referenced when within a groupBy request", }, }, - ExpectedError: "_group may only be referenced when within a groupBy request", } executeTestCase(t, test) } func TestQuerySimpleWithGroupByNumberWithCountOnInnerNonExistantGroup(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query without group by, no children, count on inner non-existant group", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 32 + }`, + }, + testUtils.Request{ + Request: `query { Users(groupBy: [Age]) { Age _group { @@ -51,54 +61,54 @@ func TestQuerySimpleWithGroupByNumberWithCountOnInnerNonExistantGroup(t *testing } } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 32 - }`, + ExpectedError: "_group may only be referenced when within a groupBy request", }, }, - ExpectedError: "_group may only be referenced when within a groupBy request", } executeTestCase(t, test) } func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildCount(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, count on non-rendered group", - Request: `query { - Users(groupBy: [Age]) { - Age - _count(_group: {}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "_count": 2, - }, - { - "Age": int64(19), - "_count": 1, + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _count(_group: {}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_count": 2, + }, + { + "Age": int64(19), + "_count": 1, + }, + }, }, }, }, @@ -108,16 +118,20 @@ func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildCount(t *testin } func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildCountOnEmptyCollection(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, count on non-rendered group, empty collection", - Request: `query { + Actions: []any{ + testUtils.Request{ + Request: `query { Users(groupBy: [Age]) { Age _count(_group: {}) } }`, - Results: map[string]any{ - "Users": []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, + }, }, } @@ -125,53 +139,59 @@ func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildCountOnEmptyCol } func TestQuerySimpleWithGroupByNumberWithRenderedGroupAndChildCount(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, count on rendered group", - Request: `query { - Users(groupBy: [Age]) { - Age - _count(_group: {}) - _group { - Name - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "_count": 2, - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _count(_group: {}) + _group { + Name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Name": "Bob", + "Age": int64(32), + "_count": 2, + "_group": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, + }, }, { - "Name": "John", - }, - }, - }, - { - "Age": int64(19), - "_count": 1, - "_group": []map[string]any{ - { - "Name": "Alice", + "Age": int64(19), + "_count": 1, + "_group": []map[string]any{ + { + "Name": "Alice", + }, + }, }, }, }, @@ -183,70 +203,82 @@ func TestQuerySimpleWithGroupByNumberWithRenderedGroupAndChildCount(t *testing.T } func TestQuerySimpleWithGroupByNumberWithUndefinedField(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, count on undefined field", - Request: `query { - Users(groupBy: [Age]) { - Age - _count - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _count + } + }`, + ExpectedError: "aggregate must be provided with a property to aggregate", + }, }, - ExpectedError: "aggregate must be provided with a property to aggregate", } executeTestCase(t, test) } func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndAliasesChildCount(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, aliased count on non-rendered group", - Request: `query { - Users(groupBy: [Age]) { - Age - Count: _count(_group: {}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "Count": 2, - }, - { - "Age": int64(19), - "Count": 1, + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + Count: _count(_group: {}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "Count": 2, + }, + { + "Age": int64(19), + "Count": 1, + }, + }, }, }, }, @@ -258,42 +290,48 @@ func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndAliasesChildCount(t func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndDuplicatedAliasedChildCounts( t *testing.T, ) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, duplicated aliased count on non-rendered group", - Request: `query { - Users(groupBy: [Age]) { - Age - Count1: _count(_group: {}) - Count2: _count(_group: {}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "Count1": 2, - "Count2": 2, - }, - { - "Age": int64(19), - "Count1": 1, - "Count2": 1, + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + Count1: _count(_group: {}) + Count2: _count(_group: {}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "Count1": 2, + "Count2": 2, + }, + { + "Age": int64(19), + "Count1": 1, + "Count2": 1, + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_doc_id_test.go b/tests/integration/query/simple/with_group_doc_id_test.go index 9529f7e3bd..336a64e351 100644 --- a/tests/integration/query/simple/with_group_doc_id_test.go +++ b/tests/integration/query/simple/with_group_doc_id_test.go @@ -17,47 +17,52 @@ import ( ) func TestQuerySimpleWithGroupByWithGroupWithDocID(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with docID filter on _group", - Request: `query { - Users(groupBy: [Age]) { - Age - _group(docID: "bae-d4303725-7db9-53d2-b324-f3ee44020e52") { - Name - } - } - }`, - Docs: map[int][]string{ - 0: { - // bae-d4303725-7db9-53d2-b324-f3ee44020e52 - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Fred", "Age": 21 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(21), - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _group(docID: "bae-d4303725-7db9-53d2-b324-f3ee44020e52") { + Name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Name": "John", + "Age": int64(21), + "_group": []map[string]any{ + { + "Name": "John", + }, + }, + }, + { + "Age": int64(32), + "_group": []map[string]any{}, }, }, }, - { - "Age": int64(32), - "_group": []map[string]any{}, - }, }, }, } diff --git a/tests/integration/query/simple/with_group_doc_ids_test.go b/tests/integration/query/simple/with_group_doc_ids_test.go index cafbb21481..5798bd387f 100644 --- a/tests/integration/query/simple/with_group_doc_ids_test.go +++ b/tests/integration/query/simple/with_group_doc_ids_test.go @@ -17,55 +17,61 @@ import ( ) func TestQuerySimpleWithGroupByWithGroupWithDocIDs(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with docIDs filter on _group", - Request: `query { - Users(groupBy: [Age]) { - Age - _group(docIDs: ["bae-d4303725-7db9-53d2-b324-f3ee44020e52", "bae-19b16890-5f24-5e5b-8822-ed2a97ebcc24"]) { - Name - } - } - }`, - Docs: map[int][]string{ - 0: { - // bae-d4303725-7db9-53d2-b324-f3ee44020e52 - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - // bae-19b16890-5f24-5e5b-8822-ed2a97ebcc24 - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Fred", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Shahzad", "Age": 21 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(21), - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _group(docIDs: ["bae-d4303725-7db9-53d2-b324-f3ee44020e52", "bae-19b16890-5f24-5e5b-8822-ed2a97ebcc24"]) { + Name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Name": "Fred", + "Age": int64(21), + "_group": []map[string]any{ + { + "Name": "Fred", + }, + { + "Name": "John", + }, + }, }, { - "Name": "John", + "Age": int64(32), + "_group": []map[string]any{}, }, }, }, - { - "Age": int64(32), - "_group": []map[string]any{}, - }, }, }, } diff --git a/tests/integration/query/simple/with_group_filter_test.go b/tests/integration/query/simple/with_group_filter_test.go index 3e3b5f32fe..3d9ecf4c36 100644 --- a/tests/integration/query/simple/with_group_filter_test.go +++ b/tests/integration/query/simple/with_group_filter_test.go @@ -17,58 +17,66 @@ import ( ) func TestQuerySimpleWithGroupByStringWithGroupNumberFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by with child filter", - Request: `query { - Users(groupBy: [Name]) { - Name - _group (filter: {Age: {_gt: 26}}){ - Age - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 25 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Carlo", - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _group (filter: {Age: {_gt: 26}}){ + Age + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Age": int64(55), + "Name": "Carlo", + "_group": []map[string]any{ + { + "Age": int64(55), + }, + }, }, - }, - }, - { - "Name": "John", - "_group": []map[string]any{ { - "Age": int64(32), + "Name": "John", + "_group": []map[string]any{ + { + "Age": int64(32), + }, + }, + }, + { + "Name": "Alice", + "_group": []map[string]any{}, }, }, }, - { - "Name": "Alice", - "_group": []map[string]any{}, - }, }, }, } @@ -77,51 +85,59 @@ func TestQuerySimpleWithGroupByStringWithGroupNumberFilter(t *testing.T) { } func TestQuerySimpleWithGroupByStringWithGroupNumberWithParentFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by with number filter", - Request: `query { - Users(groupBy: [Name], filter: {Age: {_gt: 26}}) { - Name - _group { - Age - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 25 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Carlo", - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Name], filter: {Age: {_gt: 26}}) { + Name + _group { + Age + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Age": int64(55), + "Name": "Carlo", + "_group": []map[string]any{ + { + "Age": int64(55), + }, + }, }, - }, - }, - { - "Name": "John", - "_group": []map[string]any{ { - "Age": int64(32), + "Name": "John", + "_group": []map[string]any{ + { + "Age": int64(32), + }, + }, }, }, }, @@ -133,40 +149,48 @@ func TestQuerySimpleWithGroupByStringWithGroupNumberWithParentFilter(t *testing. } func TestQuerySimpleWithGroupByStringWithUnrenderedGroupNumberWithParentFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by with number filter", - Request: `query { - Users(groupBy: [Name], filter: {Age: {_gt: 26}}) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 25 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Carlo", - }, - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(groupBy: [Name], filter: {Age: {_gt: 26}}) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + }, + { + "Name": "John", + }, + }, }, }, }, @@ -178,78 +202,88 @@ func TestQuerySimpleWithGroupByStringWithUnrenderedGroupNumberWithParentFilter(t func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanThenInnerNumberFilterThatExcludesAll( t *testing.T, ) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, with child group by boolean, with child number filter that excludes all records", - Request: `query { - Users(groupBy: [Name]) { - Name - _group (groupBy: [Verified]){ - Verified - _group (filter: {Age: {_gt: 260}}) { - Age - } - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 25, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 34, "Verified": false }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19, "Verified": false }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_group": []map[string]any{ - { - "Verified": true, - "_group": []map[string]any{}, - }, + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _group (groupBy: [Verified]){ + Verified + _group (filter: {Age: {_gt: 260}}) { + Age + } + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Verified": false, - "_group": []map[string]any{}, + "Name": "John", + "_group": []map[string]any{ + { + "Verified": true, + "_group": []map[string]any{}, + }, + { + "Verified": false, + "_group": []map[string]any{}, + }, + }, }, - }, - }, - { - "Name": "Carlo", - "_group": []map[string]any{ { - "Verified": true, - "_group": []map[string]any{}, + "Name": "Carlo", + "_group": []map[string]any{ + { + "Verified": true, + "_group": []map[string]any{}, + }, + }, }, - }, - }, - { - "Name": "Alice", - "_group": []map[string]any{ { - "Verified": false, - "_group": []map[string]any{}, + "Name": "Alice", + "_group": []map[string]any{ + { + "Verified": false, + "_group": []map[string]any{}, + }, + }, }, }, }, @@ -261,69 +295,77 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanThenInnerNumberFilterT } func TestQuerySimpleWithGroupByStringWithMultipleGroupNumberFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by with child filter", - Request: `query { - Users(groupBy: [Name]) { - Name - G1: _group (filter: {Age: {_gt: 26}}){ - Age - } - G2: _group (filter: {Age: {_lt: 26}}){ - Age - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 25 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Carlo", - "G1": []map[string]any{ - { - "Age": int64(55), - }, - }, - "G2": []map[string]any{}, - }, - { - "Name": "John", - "G1": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + G1: _group (filter: {Age: {_gt: 26}}){ + Age + } + G2: _group (filter: {Age: {_lt: 26}}){ + Age + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Age": int64(32), + "Name": "Carlo", + "G1": []map[string]any{ + { + "Age": int64(55), + }, + }, + "G2": []map[string]any{}, }, - }, - "G2": []map[string]any{ { - "Age": int64(25), + "Name": "John", + "G1": []map[string]any{ + { + "Age": int64(32), + }, + }, + "G2": []map[string]any{ + { + "Age": int64(25), + }, + }, }, - }, - }, - { - "Name": "Alice", - "G1": []map[string]any{}, - "G2": []map[string]any{ { - "Age": int64(19), + "Name": "Alice", + "G1": []map[string]any{}, + "G2": []map[string]any{ + { + "Age": int64(19), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_limit_offset_test.go b/tests/integration/query/simple/with_group_limit_offset_test.go index ea4c2afc81..7c45c50559 100644 --- a/tests/integration/query/simple/with_group_limit_offset_test.go +++ b/tests/integration/query/simple/with_group_limit_offset_test.go @@ -17,46 +17,52 @@ import ( ) func TestQuerySimpleWithGroupByNumberWithGroupLimitAndOffset(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, rendered, limited and offset group", - Request: `query { - Users(groupBy: [Age]) { - Age - _group(limit: 1, offset: 1) { - Name - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _group(limit: 1, offset: 1) { + Name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Name": "John", + "Age": int64(32), + "_group": []map[string]any{ + { + "Name": "John", + }, + }, + }, + { + "Age": int64(19), + "_group": []map[string]any{}, }, }, }, - { - "Age": int64(19), - "_group": []map[string]any{}, - }, }, }, } @@ -65,37 +71,43 @@ func TestQuerySimpleWithGroupByNumberWithGroupLimitAndOffset(t *testing.T) { } func TestQuerySimpleWithGroupByNumberWithLimitAndOffsetAndWithGroupLimitAndOffset(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number with limit and offset, no children, rendered, limited and offset group", - Request: `query { - Users(groupBy: [Age], limit: 1, offset: 1) { - Age - _group(limit: 1, offset: 1) { - Name - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(19), - "_group": []map[string]any{}, + testUtils.Request{ + Request: `query { + Users(groupBy: [Age], limit: 1, offset: 1) { + Age + _group(limit: 1, offset: 1) { + Name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(19), + "_group": []map[string]any{}, + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_limit_test.go b/tests/integration/query/simple/with_group_limit_test.go index 2b7ac5d205..2f13f9dd3f 100644 --- a/tests/integration/query/simple/with_group_limit_test.go +++ b/tests/integration/query/simple/with_group_limit_test.go @@ -17,47 +17,53 @@ import ( ) func TestQuerySimpleWithGroupByNumberWithGroupLimit(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, rendered, limited group", - Request: `query { - Users(groupBy: [Age]) { - Age - _group(limit: 1) { - Name - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _group(limit: 1) { + Name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Name": "Bob", + "Age": int64(32), + "_group": []map[string]any{ + { + "Name": "Bob", + }, + }, }, - }, - }, - { - "Age": int64(19), - "_group": []map[string]any{ { - "Name": "Alice", + "Age": int64(19), + "_group": []map[string]any{ + { + "Name": "Alice", + }, + }, }, }, }, @@ -69,63 +75,69 @@ func TestQuerySimpleWithGroupByNumberWithGroupLimit(t *testing.T) { } func TestQuerySimpleWithGroupByNumberWithMultipleGroupsWithDifferentLimits(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, multiple rendered, limited groups", - Request: `query { - Users(groupBy: [Age]) { - Age - G1: _group(limit: 1) { - Name - } - G2: _group(limit: 2) { - Name - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "G1": []map[string]any{ - { - "Name": "Bob", - }, - }, - "G2": []map[string]any{ - { - "Name": "Bob", - }, - { - "Name": "John", - }, - }, - }, - { - "Age": int64(19), - "G1": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + G1: _group(limit: 1) { + Name + } + G2: _group(limit: 2) { + Name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Name": "Alice", + "Age": int64(32), + "G1": []map[string]any{ + { + "Name": "Bob", + }, + }, + "G2": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, + }, }, - }, - "G2": []map[string]any{ { - "Name": "Alice", + "Age": int64(19), + "G1": []map[string]any{ + { + "Name": "Alice", + }, + }, + "G2": []map[string]any{ + { + "Name": "Alice", + }, + }, }, }, }, @@ -137,42 +149,48 @@ func TestQuerySimpleWithGroupByNumberWithMultipleGroupsWithDifferentLimits(t *te } func TestQuerySimpleWithGroupByNumberWithLimitAndGroupWithHigherLimit(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number and limit, no children, rendered, limited group", - Request: `query { - Users(groupBy: [Age], limit: 1) { - Age - _group(limit: 2) { - Name - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "_group": []map[string]any{ - { - "Name": "Bob", - }, + testUtils.Request{ + Request: `query { + Users(groupBy: [Age], limit: 1) { + Age + _group(limit: 2) { + Name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Name": "John", + "Age": int64(32), + "_group": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, + }, }, }, }, @@ -184,51 +202,59 @@ func TestQuerySimpleWithGroupByNumberWithLimitAndGroupWithHigherLimit(t *testing } func TestQuerySimpleWithGroupByNumberWithLimitAndGroupWithLowerLimit(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number and limit, no children, rendered, limited group", - Request: `query { - Users(groupBy: [Age], limit: 2) { - Age - _group(limit: 1) { - Name - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 42 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Age], limit: 2) { + Age + _group(limit: 1) { + Name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Name": "Bob", + "Age": int64(32), + "_group": []map[string]any{ + { + "Name": "Bob", + }, + }, }, - }, - }, - { - "Age": int64(42), - "_group": []map[string]any{ { - "Name": "Alice", + "Age": int64(42), + "_group": []map[string]any{ + { + "Name": "Alice", + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_order_test.go b/tests/integration/query/simple/with_group_order_test.go index b1ace46918..7e8a2cbf17 100644 --- a/tests/integration/query/simple/with_group_order_test.go +++ b/tests/integration/query/simple/with_group_order_test.go @@ -17,62 +17,70 @@ import ( ) func TestQuerySimpleWithGroupByStringWithGroupNumberWithGroupOrder(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, and child order ascending", - Request: `query { - Users(groupBy: [Name]) { - Name - _group (order: {Age: ASC}){ - Age - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 25 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Carlo", - "_group": []map[string]any{ - { - "Age": int64(55), - }, - }, - }, - { - "Name": "Alice", - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _group (order: {Age: ASC}){ + Age + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Age": int64(19), + "Name": "Carlo", + "_group": []map[string]any{ + { + "Age": int64(55), + }, + }, }, - }, - }, - { - "Name": "John", - "_group": []map[string]any{ { - "Age": int64(25), + "Name": "Alice", + "_group": []map[string]any{ + { + "Age": int64(19), + }, + }, }, { - "Age": int64(32), + "Name": "John", + "_group": []map[string]any{ + { + "Age": int64(25), + }, + { + "Age": int64(32), + }, + }, }, }, }, @@ -84,62 +92,70 @@ func TestQuerySimpleWithGroupByStringWithGroupNumberWithGroupOrder(t *testing.T) } func TestQuerySimpleWithGroupByStringWithGroupNumberWithGroupOrderDescending(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, and child order descending", - Request: `query { - Users(groupBy: [Name]) { - Name - _group (order: {Age: DESC}){ - Age - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 25 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Carlo", - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _group (order: {Age: DESC}){ + Age + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Age": int64(55), + "Name": "Carlo", + "_group": []map[string]any{ + { + "Age": int64(55), + }, + }, }, - }, - }, - { - "Name": "John", - "_group": []map[string]any{ { - "Age": int64(32), + "Name": "John", + "_group": []map[string]any{ + { + "Age": int64(32), + }, + { + "Age": int64(25), + }, + }, }, { - "Age": int64(25), - }, - }, - }, - { - "Name": "Alice", - "_group": []map[string]any{ - { - "Age": int64(19), + "Name": "Alice", + "_group": []map[string]any{ + { + "Age": int64(19), + }, + }, }, }, }, @@ -151,62 +167,70 @@ func TestQuerySimpleWithGroupByStringWithGroupNumberWithGroupOrderDescending(t * } func TestQuerySimpleWithGroupByStringAndOrderDescendingWithGroupNumberWithGroupOrder(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, and child order ascending", - Request: `query { - Users(groupBy: [Name], order: {Name: DESC}) { - Name - _group (order: {Age: ASC}){ - Age - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 25 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_group": []map[string]any{ - { - "Age": int64(25), - }, + testUtils.Request{ + Request: `query { + Users(groupBy: [Name], order: {Name: DESC}) { + Name + _group (order: {Age: ASC}){ + Age + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Age": int64(32), + "Name": "John", + "_group": []map[string]any{ + { + "Age": int64(25), + }, + { + "Age": int64(32), + }, + }, }, - }, - }, - { - "Name": "Carlo", - "_group": []map[string]any{ { - "Age": int64(55), + "Name": "Carlo", + "_group": []map[string]any{ + { + "Age": int64(55), + }, + }, }, - }, - }, - { - "Name": "Alice", - "_group": []map[string]any{ { - "Age": int64(19), + "Name": "Alice", + "_group": []map[string]any{ + { + "Age": int64(19), + }, + }, }, }, }, @@ -218,95 +242,105 @@ func TestQuerySimpleWithGroupByStringAndOrderDescendingWithGroupNumberWithGroupO } func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanThenInnerOrderDescending(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, with child group by boolean, with child order desc", - Request: `query { - Users(groupBy: [Name]) { - Name - _group (groupBy: [Verified]){ - Verified - _group (order: {Age: DESC}) { - Age - } - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 25, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 34, "Verified": false }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19, "Verified": false }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _group (groupBy: [Verified]){ + Verified + _group (order: {Age: DESC}) { + Age + } + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Verified": true, + "Name": "John", "_group": []map[string]any{ { - "Age": int64(32), + "Verified": true, + "_group": []map[string]any{ + { + "Age": int64(32), + }, + { + "Age": int64(25), + }, + }, }, { - "Age": int64(25), + "Verified": false, + "_group": []map[string]any{ + { + "Age": int64(34), + }, + }, }, }, }, { - "Verified": false, + "Name": "Carlo", "_group": []map[string]any{ { - "Age": int64(34), + "Verified": true, + "_group": []map[string]any{ + { + "Age": int64(55), + }, + }, }, }, }, - }, - }, - { - "Name": "Carlo", - "_group": []map[string]any{ - { - "Verified": true, - "_group": []map[string]any{ - { - "Age": int64(55), - }, - }, - }, - }, - }, - { - "Name": "Alice", - "_group": []map[string]any{ { - "Verified": false, + "Name": "Alice", "_group": []map[string]any{ { - "Age": int64(19), + "Verified": false, + "_group": []map[string]any{ + { + "Age": int64(19), + }, + }, }, }, }, @@ -322,95 +356,105 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanThenInnerOrderDescendi func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndOrderAscendingThenInnerOrderDescending( t *testing.T, ) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, with child group by boolean, with child order desc", - Request: `query { - Users(groupBy: [Name]) { - Name - _group (groupBy: [Verified], order: {Verified: ASC}){ - Verified - _group (order: {Age: DESC}) { - Age - } - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 25, "Verified": false }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 34, "Verified": false }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19, "Verified": false }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _group (groupBy: [Verified], order: {Verified: ASC}){ + Verified + _group (order: {Age: DESC}) { + Age + } + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Verified": false, + "Name": "John", "_group": []map[string]any{ { - "Age": int64(34), + "Verified": false, + "_group": []map[string]any{ + { + "Age": int64(34), + }, + { + "Age": int64(25), + }, + }, }, { - "Age": int64(25), + "Verified": true, + "_group": []map[string]any{ + { + "Age": int64(32), + }, + }, }, }, }, { - "Verified": true, + "Name": "Alice", "_group": []map[string]any{ { - "Age": int64(32), + "Verified": false, + "_group": []map[string]any{ + { + "Age": int64(19), + }, + }, }, }, }, - }, - }, - { - "Name": "Alice", - "_group": []map[string]any{ { - "Verified": false, + "Name": "Carlo", "_group": []map[string]any{ { - "Age": int64(19), - }, - }, - }, - }, - }, - { - "Name": "Carlo", - "_group": []map[string]any{ - { - "Verified": true, - "_group": []map[string]any{ - { - "Age": int64(55), + "Verified": true, + "_group": []map[string]any{ + { + "Age": int64(55), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_sum_filter_test.go b/tests/integration/query/simple/with_group_sum_filter_test.go index cf9f8e3a0b..7ba39a1fda 100644 --- a/tests/integration/query/simple/with_group_sum_filter_test.go +++ b/tests/integration/query/simple/with_group_sum_filter_test.go @@ -17,39 +17,45 @@ import ( ) func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildSumWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, sum on non-rendered, unfiltered group", - Request: `query { - Users(groupBy: [Age]) { - Age - _sum(_group: {field: Age, filter: {Age: {_gt: 26}}}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "_sum": int64(64), - }, - { - "Age": int64(19), - "_sum": int64(0), + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _sum(_group: {field: Age, filter: {Age: {_gt: 26}}}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_sum": int64(64), + }, + { + "Age": int64(19), + "_sum": int64(0), + }, + }, }, }, }, @@ -59,53 +65,59 @@ func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildSumWithFilter(t } func TestQuerySimpleWithGroupByNumberWithRenderedGroupAndChildSumWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, sum on rendered, unfiltered group", - Request: `query { - Users(groupBy: [Age]) { - Age - _sum(_group: {field: Age, filter: {Age: {_gt: 26}}}) - _group { - Name - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "_sum": int64(64), - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _sum(_group: {field: Age, filter: {Age: {_gt: 26}}}) + _group { + Name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Name": "Bob", + "Age": int64(32), + "_sum": int64(64), + "_group": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, + }, }, { - "Name": "John", - }, - }, - }, - { - "Age": int64(19), - "_sum": int64(0), - "_group": []map[string]any{ - { - "Name": "Alice", + "Age": int64(19), + "_sum": int64(0), + "_group": []map[string]any{ + { + "Name": "Alice", + }, + }, }, }, }, @@ -117,49 +129,55 @@ func TestQuerySimpleWithGroupByNumberWithRenderedGroupAndChildSumWithFilter(t *t } func TestQuerySimpleWithGroupByNumberWithRenderedGroupWithFilterAndChildSumWithMatchingFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, sum on rendered, matching filtered group", - Request: `query { - Users(groupBy: [Age]) { - Age - _sum(_group: {field: Age, filter: {Name: {_eq: "John"}}}) - _group(filter: {Name: {_eq: "John"}}) { - Name - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "_sum": int64(32), - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _sum(_group: {field: Age, filter: {Name: {_eq: "John"}}}) + _group(filter: {Name: {_eq: "John"}}) { + Name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Name": "John", + "Age": int64(32), + "_sum": int64(32), + "_group": []map[string]any{ + { + "Name": "John", + }, + }, + }, + { + "Age": int64(19), + "_sum": int64(0), + "_group": []map[string]any{}, }, }, }, - { - "Age": int64(19), - "_sum": int64(0), - "_group": []map[string]any{}, - }, }, }, } @@ -168,49 +186,55 @@ func TestQuerySimpleWithGroupByNumberWithRenderedGroupWithFilterAndChildSumWithM } func TestQuerySimpleWithGroupByNumberWithRenderedGroupWithFilterAndChildSumWithDifferentFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, sum on non-rendered, different filtered group", - Request: `query { - Users(groupBy: [Age]) { - Age - _sum(_group: {field: Age, filter: {Age: {_gt: 26}}}) - _group(filter: {Name: {_eq: "John"}}) { - Name - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "_sum": int64(64), - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _sum(_group: {field: Age, filter: {Age: {_gt: 26}}}) + _group(filter: {Name: {_eq: "John"}}) { + Name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "_sum": int64(64), + "_group": []map[string]any{ + { + "Name": "John", + }, + }, + }, { - "Name": "John", + "Age": int64(19), + "_sum": int64(0), + "_group": []map[string]any{}, }, }, }, - { - "Age": int64(19), - "_sum": int64(0), - "_group": []map[string]any{}, - }, }, }, } @@ -219,42 +243,48 @@ func TestQuerySimpleWithGroupByNumberWithRenderedGroupWithFilterAndChildSumWithD } func TestQuerySimpleWithGroupByNumberWithoutRenderedGroupAndChildSumsWithDifferentFilters(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, sum on non-rendered, unfiltered group", - Request: `query { - Users(groupBy: [Age]) { - Age - S1: _sum(_group: {field: Age, filter: {Age: {_gt: 26}}}) - S2: _sum(_group: {field: Age, filter: {Age: {_lt: 26}}}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(32), - "S1": int64(64), - "S2": int64(0), - }, - { - "Age": int64(19), - "S1": int64(0), - "S2": int64(19), + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + S1: _sum(_group: {field: Age, filter: {Age: {_gt: 26}}}) + S2: _sum(_group: {field: Age, filter: {Age: {_lt: 26}}}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(32), + "S1": int64(64), + "S2": int64(0), + }, + { + "Age": int64(19), + "S1": int64(0), + "S2": int64(19), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_sum_limit_offset_test.go b/tests/integration/query/simple/with_group_sum_limit_offset_test.go index 7ba181b3c5..2222b62966 100644 --- a/tests/integration/query/simple/with_group_sum_limit_offset_test.go +++ b/tests/integration/query/simple/with_group_sum_limit_offset_test.go @@ -17,44 +17,52 @@ import ( ) func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerSumWithLimitAndOffset(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, offsetted limited sum on non-rendered group integer value", - Request: `query { - Users(groupBy: [Name]) { - Name - _sum(_group: {field: Age, offset: 1, limit: 2}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 38 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 28 }`, + }, + testUtils.CreateDoc{ // It is important to test negative values here, due to the auto-typing of numbers - `{ + Doc: `{ "Name": "Alice", "Age": -19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_sum": int64(70), - }, - { - "Name": "Alice", - "_sum": int64(0), + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _sum(_group: {field: Age, offset: 1, limit: 2}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_sum": int64(70), + }, + { + "Name": "Alice", + "_sum": int64(0), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_sum_limit_test.go b/tests/integration/query/simple/with_group_sum_limit_test.go index eda7ea131b..631a7914a2 100644 --- a/tests/integration/query/simple/with_group_sum_limit_test.go +++ b/tests/integration/query/simple/with_group_sum_limit_test.go @@ -17,44 +17,52 @@ import ( ) func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerSumWithLimit(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, limited sum on non-rendered group integer value", - Request: `query { - Users(groupBy: [Name]) { - Name - _sum(_group: {field: Age, limit: 2}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 38 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 28 }`, + }, + testUtils.CreateDoc{ // It is important to test negative values here, due to the auto-typing of numbers - `{ + Doc: `{ "Name": "Alice", "Age": -19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_sum": int64(66), - }, - { - "Name": "Alice", - "_sum": int64(-19), + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _sum(_group: {field: Age, limit: 2}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_sum": int64(66), + }, + { + "Name": "Alice", + "_sum": int64(-19), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_sum_test.go b/tests/integration/query/simple/with_group_sum_test.go index 03bfb3e2de..a6a70b6b69 100644 --- a/tests/integration/query/simple/with_group_sum_test.go +++ b/tests/integration/query/simple/with_group_sum_test.go @@ -17,39 +17,45 @@ import ( ) func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndSumOfUndefined(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with sum on unspecified field", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 32 + }`, + }, + testUtils.Request{ + Request: `query { Users (groupBy: [Name]) { Name _sum } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 32 - }`, + ExpectedError: "aggregate must be provided with a property to aggregate", }, }, - ExpectedError: "aggregate must be provided with a property to aggregate", } executeTestCase(t, test) } func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerSumOnEmptyCollection(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, sum on non-rendered group, empty collection", - Request: `query { + Actions: []any{ + testUtils.Request{ + Request: `query { Users(groupBy: [Age]) { Age _sum(_group: {field: Age}) } }`, - Results: map[string]any{ - "Users": []map[string]any{}, + Results: map[string]any{ + "Users": []map[string]any{}, + }, + }, }, } @@ -57,40 +63,46 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerSumOnEmp } func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerSum(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, sum on non-rendered group integer value", - Request: `query { - Users(groupBy: [Name]) { - Name - _sum(_group: {field: Age}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 38 }`, + }, + testUtils.CreateDoc{ // It is important to test negative values here, due to the auto-typing of numbers - `{ + Doc: `{ "Name": "Alice", "Age": -19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_sum": int64(70), - }, - { - "Name": "Alice", - "_sum": int64(-19), + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _sum(_group: {field: Age}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_sum": int64(70), + }, + { + "Name": "Alice", + "_sum": int64(-19), + }, + }, }, }, }, @@ -100,39 +112,45 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildIntegerSum(t *t } func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildNilSum(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, sum on non-rendered group nil and integer values", - Request: `query { - Users(groupBy: [Name]) { - Name - _sum(_group: {field: Age}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, + }, + testUtils.CreateDoc{ // Age is undefined here - `{ + Doc: `{ "Name": "John" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_sum": int64(32), - }, - { - "Name": "Alice", - "_sum": int64(19), + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _sum(_group: {field: Age}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_sum": int64(32), + }, + { + "Name": "Alice", + "_sum": int64(19), + }, + }, }, }, }, @@ -142,80 +160,90 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildNilSum(t *testi } func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndSumOfSumOfInt(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, with child group by boolean, and sum of sum on int", - Request: `query { - Users(groupBy: [Name]) { - Name - _sum(_group: {field: _sum}) - _group (groupBy: [Verified]){ - Verified - _sum(_group: {field: Age}) - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 25, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 34, "Verified": false }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19, "Verified": false }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_sum": int64(91), - "_group": []map[string]any{ - { - "Verified": true, - "_sum": int64(57), - }, + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _sum(_group: {field: _sum}) + _group (groupBy: [Verified]){ + Verified + _sum(_group: {field: Age}) + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Verified": false, - "_sum": int64(34), + "Name": "John", + "_sum": int64(91), + "_group": []map[string]any{ + { + "Verified": true, + "_sum": int64(57), + }, + { + "Verified": false, + "_sum": int64(34), + }, + }, }, - }, - }, - { - "Name": "Carlo", - "_sum": int64(55), - "_group": []map[string]any{ { - "Verified": true, - "_sum": int64(55), + "Name": "Carlo", + "_sum": int64(55), + "_group": []map[string]any{ + { + "Verified": true, + "_sum": int64(55), + }, + }, }, - }, - }, - { - "Name": "Alice", - "_sum": int64(19), - "_group": []map[string]any{ { - "Verified": false, - "_sum": int64(19), + "Name": "Alice", + "_sum": int64(19), + "_group": []map[string]any{ + { + "Verified": false, + "_sum": int64(19), + }, + }, }, }, }, @@ -227,38 +255,44 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndSumOfSumOfInt(t *te } func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildEmptyFloatSum(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, sum on non-rendered group float (default) value", - Request: `query { - Users(groupBy: [Name]) { - Name - _sum(_group: {field: HeightM}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 1.82 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 1.89 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_sum": float64(3.71), - }, - { - "Name": "Alice", - "_sum": float64(0), + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _sum(_group: {field: HeightM}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_sum": float64(3.71), + }, + { + "Name": "Alice", + "_sum": float64(0), + }, + }, }, }, }, @@ -268,39 +302,45 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildEmptyFloatSum(t } func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildFloatSum(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, sum on non-rendered group float value", - Request: `query { - Users(groupBy: [Name]) { - Name - _sum(_group: {field: HeightM}) - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 1.82 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 1.89 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "HeightM": 2.04 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_sum": float64(3.71), - }, - { - "Name": "Alice", - "_sum": float64(2.04), + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _sum(_group: {field: HeightM}) + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "_sum": float64(3.71), + }, + { + "Name": "Alice", + "_sum": float64(2.04), + }, + }, }, }, }, @@ -310,80 +350,90 @@ func TestQuerySimpleWithGroupByStringWithoutRenderedGroupAndChildFloatSum(t *tes } func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndSumOfSumOfFloat(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, with child group by boolean, and sum of sum on float", - Request: `query { - Users(groupBy: [Name]) { - Name - _sum(_group: {field: _sum}) - _group (groupBy: [Verified]){ - Verified - _sum(_group: {field: HeightM}) - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 1.82, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 1.61, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.22, "Verified": false }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "HeightM": 1.74, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "HeightM": 2.04, "Verified": false }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Alice", - "_sum": float64(2.04), - "_group": []map[string]any{ - { - "Verified": false, - "_sum": float64(2.04), - }, - }, - }, - { - "Name": "John", - "_sum": float64(5.65), - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _sum(_group: {field: _sum}) + _group (groupBy: [Verified]){ + Verified + _sum(_group: {field: HeightM}) + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Verified": true, - "_sum": float64(3.43), + "Name": "Alice", + "_sum": float64(2.04), + "_group": []map[string]any{ + { + "Verified": false, + "_sum": float64(2.04), + }, + }, }, { - "Verified": false, - "_sum": float64(2.22), + "Name": "John", + "_sum": float64(5.65), + "_group": []map[string]any{ + { + "Verified": true, + "_sum": float64(3.43), + }, + { + "Verified": false, + "_sum": float64(2.22), + }, + }, }, - }, - }, - { - "Name": "Carlo", - "_sum": float64(1.74), - "_group": []map[string]any{ { - "Verified": true, - "_sum": float64(1.74), + "Name": "Carlo", + "_sum": float64(1.74), + "_group": []map[string]any{ + { + "Verified": true, + "_sum": float64(1.74), + }, + }, }, }, }, @@ -395,115 +445,125 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndSumOfSumOfFloat(t * } func TestQuerySimpleWithGroupByStringWithInnerGroupBooleanAndSumOfSumOfSumOfFloat(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, with child group by boolean, and sum of sum of sum of float", - Request: `query { - Users(groupBy: [Name]) { - Name - _sum(_group: {field: _sum}) - _group (groupBy: [Verified]){ - Verified - _sum(_group: {field: HeightM}) - _group (groupBy: [Age]){ - Age - _sum(_group: {field: HeightM}) - } - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 1.82, "Age": 25, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 1.61, "Age": 32, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "HeightM": 2.22, "Age": 34, "Verified": false }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "HeightM": 1.74, "Age": 55, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "HeightM": 2.04, "Age": 19, "Verified": false }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Carlo", - "_sum": float64(1.74), - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _sum(_group: {field: _sum}) + _group (groupBy: [Verified]){ + Verified + _sum(_group: {field: HeightM}) + _group (groupBy: [Age]){ + Age + _sum(_group: {field: HeightM}) + } + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Verified": true, - "_sum": float64(1.74), + "Name": "Carlo", + "_sum": float64(1.74), "_group": []map[string]any{ { - "Age": int64(55), - "_sum": float64(1.74), + "Verified": true, + "_sum": float64(1.74), + "_group": []map[string]any{ + { + "Age": int64(55), + "_sum": float64(1.74), + }, + }, }, }, }, - }, - }, - { - "Name": "Alice", - "_sum": float64(2.04), - "_group": []map[string]any{ { - "Verified": false, - "_sum": float64(2.04), + "Name": "Alice", + "_sum": float64(2.04), "_group": []map[string]any{ { - "Age": int64(19), - "_sum": float64(2.04), + "Verified": false, + "_sum": float64(2.04), + "_group": []map[string]any{ + { + "Age": int64(19), + "_sum": float64(2.04), + }, + }, }, }, }, - }, - }, - { - "Name": "John", - "_sum": float64(5.65), - "_group": []map[string]any{ { - "Verified": true, - "_sum": float64(3.43), + "Name": "John", + "_sum": float64(5.65), "_group": []map[string]any{ { - "Age": int64(32), - "_sum": float64(1.61), - }, - { - "Age": int64(25), - "_sum": float64(1.82), + "Verified": true, + "_sum": float64(3.43), + "_group": []map[string]any{ + { + "Age": int64(32), + "_sum": float64(1.61), + }, + { + "Age": int64(25), + "_sum": float64(1.82), + }, + }, }, - }, - }, - { - "Verified": false, - "_sum": float64(2.22), - "_group": []map[string]any{ { - "Age": int64(34), - "_sum": float64(2.22), + "Verified": false, + "_sum": float64(2.22), + "_group": []map[string]any{ + { + "Age": int64(34), + "_sum": float64(2.22), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_group_test.go b/tests/integration/query/simple/with_group_test.go index 7b71ebf90f..ddb141afab 100644 --- a/tests/integration/query/simple/with_group_test.go +++ b/tests/integration/query/simple/with_group_test.go @@ -17,36 +17,40 @@ import ( ) func TestQuerySimpleWithGroupByEmpty(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by empty set, children", - Request: `query { - Users(groupBy: []) { - _group { - Name - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "_group": []map[string]any{ - { - "Name": "Bob", - }, + testUtils.Request{ + Request: `query { + Users(groupBy: []) { + _group { + Name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Name": "John", + "_group": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, + }, }, }, }, @@ -58,43 +62,51 @@ func TestQuerySimpleWithGroupByEmpty(t *testing.T) { } func TestQuerySimpleWithGroupByNumber(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children", - Request: `query { - Users(groupBy: [Age]) { - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(55), - }, - { - "Age": int64(32), - }, - { - "Age": int64(19), + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": int64(55), + }, + { + "Age": int64(32), + }, + { + "Age": int64(19), + }, + }, }, }, }, @@ -104,43 +116,51 @@ func TestQuerySimpleWithGroupByNumber(t *testing.T) { } func TestQuerySimpleWithGroupByDateTime(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children", - Request: `query { - Users(groupBy: [CreatedAt]) { - CreatedAt - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "CreatedAt": "2011-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "CreatedAt": "2011-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "CreatedAt": "2012-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "CreatedAt": "2013-07-23T03:46:56-05:00" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "CreatedAt": testUtils.MustParseTime("2011-07-23T03:46:56-05:00"), - }, - { - "CreatedAt": testUtils.MustParseTime("2013-07-23T03:46:56-05:00"), - }, - { - "CreatedAt": testUtils.MustParseTime("2012-07-23T03:46:56-05:00"), + testUtils.Request{ + Request: `query { + Users(groupBy: [CreatedAt]) { + CreatedAt + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "CreatedAt": testUtils.MustParseTime("2011-07-23T03:46:56-05:00"), + }, + { + "CreatedAt": testUtils.MustParseTime("2013-07-23T03:46:56-05:00"), + }, + { + "CreatedAt": testUtils.MustParseTime("2012-07-23T03:46:56-05:00"), + }, + }, }, }, }, @@ -150,62 +170,70 @@ func TestQuerySimpleWithGroupByDateTime(t *testing.T) { } func TestQuerySimpleWithGroupByNumberWithGroupString(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, child string", - Request: `query { - Users(groupBy: [Age]) { - Age - _group { - Name - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": int64(55), - "_group": []map[string]any{ - { - "Name": "Carlo", - }, - }, - }, - { - "Age": int64(32), - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _group { + Name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Name": "Bob", + "Age": int64(55), + "_group": []map[string]any{ + { + "Name": "Carlo", + }, + }, }, { - "Name": "John", + "Age": int64(32), + "_group": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, + }, }, - }, - }, - { - "Age": int64(19), - "_group": []map[string]any{ { - "Name": "Alice", + "Age": int64(19), + "_group": []map[string]any{ + { + "Name": "Alice", + }, + }, }, }, }, @@ -217,62 +245,70 @@ func TestQuerySimpleWithGroupByNumberWithGroupString(t *testing.T) { } func TestQuerySimpleWithGroupByWithoutGroupedFieldSelectedWithInnerGroup(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with groupBy without selecting field grouped by, with inner _group.", - Request: `query { - Users(groupBy: [Name]) { - Name - _group { - Age - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 25 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Carlo", - "_group": []map[string]any{ - { - "Age": int64(55), - }, - }, - }, - { - "Name": "John", - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _group { + Age + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Age": int64(25), + "Name": "Carlo", + "_group": []map[string]any{ + { + "Age": int64(55), + }, + }, }, { - "Age": int64(32), + "Name": "John", + "_group": []map[string]any{ + { + "Age": int64(25), + }, + { + "Age": int64(32), + }, + }, }, - }, - }, - { - "Name": "Alice", - "_group": []map[string]any{ { - "Age": int64(19), + "Name": "Alice", + "_group": []map[string]any{ + { + "Age": int64(19), + }, + }, }, }, }, @@ -284,62 +320,70 @@ func TestQuerySimpleWithGroupByWithoutGroupedFieldSelectedWithInnerGroup(t *test } func TestQuerySimpleWithGroupByString(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string", - Request: `query { - Users(groupBy: [Name]) { - Name - _group { - Age - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 25 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Carlo", - "_group": []map[string]any{ - { - "Age": int64(55), - }, - }, - }, - { - "Name": "John", - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _group { + Age + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Age": int64(25), + "Name": "Carlo", + "_group": []map[string]any{ + { + "Age": int64(55), + }, + }, }, { - "Age": int64(32), + "Name": "John", + "_group": []map[string]any{ + { + "Age": int64(25), + }, + { + "Age": int64(32), + }, + }, }, - }, - }, - { - "Name": "Alice", - "_group": []map[string]any{ { - "Age": int64(19), + "Name": "Alice", + "_group": []map[string]any{ + { + "Age": int64(19), + }, + }, }, }, }, @@ -351,95 +395,105 @@ func TestQuerySimpleWithGroupByString(t *testing.T) { } func TestQuerySimpleWithGroupByStringWithInnerGroupBoolean(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string, with child group by boolean", - Request: `query { - Users(groupBy: [Name]) { - Name - _group (groupBy: [Verified]){ - Verified - _group { - Age - } - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 25, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 34, "Verified": false }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19, "Verified": false }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_group": []map[string]any{ + testUtils.Request{ + Request: `query { + Users(groupBy: [Name]) { + Name + _group (groupBy: [Verified]){ + Verified + _group { + Age + } + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Verified": true, + "Name": "John", "_group": []map[string]any{ { - "Age": int64(25), + "Verified": true, + "_group": []map[string]any{ + { + "Age": int64(25), + }, + { + "Age": int64(32), + }, + }, }, { - "Age": int64(32), + "Verified": false, + "_group": []map[string]any{ + { + "Age": int64(34), + }, + }, }, }, }, { - "Verified": false, - "_group": []map[string]any{ - { - "Age": int64(34), - }, - }, - }, - }, - }, - { - "Name": "Carlo", - "_group": []map[string]any{ - { - "Verified": true, + "Name": "Carlo", "_group": []map[string]any{ { - "Age": int64(55), + "Verified": true, + "_group": []map[string]any{ + { + "Age": int64(55), + }, + }, }, }, }, - }, - }, - { - "Name": "Alice", - "_group": []map[string]any{ { - "Verified": false, + "Name": "Alice", "_group": []map[string]any{ { - "Age": int64(19), + "Verified": false, + "_group": []map[string]any{ + { + "Age": int64(19), + }, + }, }, }, }, @@ -453,84 +507,94 @@ func TestQuerySimpleWithGroupByStringWithInnerGroupBoolean(t *testing.T) { } func TestQuerySimpleWithGroupByStringThenBoolean(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by string then by boolean", - Request: `query { - Users(groupBy: [Name, Verified]) { - Name - Verified - _group { - Age - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 25, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 34, "Verified": false }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19, "Verified": false }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Verified": true, - "_group": []map[string]any{ - { - "Age": int64(25), - }, + testUtils.Request{ + Request: `query { + Users(groupBy: [Name, Verified]) { + Name + Verified + _group { + Age + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Age": int64(32), + "Name": "John", + "Verified": true, + "_group": []map[string]any{ + { + "Age": int64(25), + }, + { + "Age": int64(32), + }, + }, }, - }, - }, - { - "Name": "John", - "Verified": false, - "_group": []map[string]any{ { - "Age": int64(34), + "Name": "John", + "Verified": false, + "_group": []map[string]any{ + { + "Age": int64(34), + }, + }, }, - }, - }, - { - "Name": "Carlo", - "Verified": true, - "_group": []map[string]any{ { - "Age": int64(55), + "Name": "Carlo", + "Verified": true, + "_group": []map[string]any{ + { + "Age": int64(55), + }, + }, }, - }, - }, - { - "Name": "Alice", - "Verified": false, - "_group": []map[string]any{ { - "Age": int64(19), + "Name": "Alice", + "Verified": false, + "_group": []map[string]any{ + { + "Age": int64(19), + }, + }, }, }, }, @@ -542,84 +606,94 @@ func TestQuerySimpleWithGroupByStringThenBoolean(t *testing.T) { } func TestQuerySimpleWithGroupByBooleanThenNumber(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by boolean then by string", - Request: `query { - Users(groupBy: [Verified, Name]) { - Name - Verified - _group { - Age - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 25, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 34, "Verified": false }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19, "Verified": false }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Verified": true, - "_group": []map[string]any{ - { - "Age": int64(25), - }, + testUtils.Request{ + Request: `query { + Users(groupBy: [Verified, Name]) { + Name + Verified + _group { + Age + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Age": int64(32), + "Name": "John", + "Verified": true, + "_group": []map[string]any{ + { + "Age": int64(25), + }, + { + "Age": int64(32), + }, + }, }, - }, - }, - { - "Name": "John", - "Verified": false, - "_group": []map[string]any{ { - "Age": int64(34), + "Name": "John", + "Verified": false, + "_group": []map[string]any{ + { + "Age": int64(34), + }, + }, }, - }, - }, - { - "Name": "Carlo", - "Verified": true, - "_group": []map[string]any{ { - "Age": int64(55), + "Name": "Carlo", + "Verified": true, + "_group": []map[string]any{ + { + "Age": int64(55), + }, + }, }, - }, - }, - { - "Name": "Alice", - "Verified": false, - "_group": []map[string]any{ { - "Age": int64(19), + "Name": "Alice", + "Verified": false, + "_group": []map[string]any{ + { + "Age": int64(19), + }, + }, }, }, }, @@ -631,34 +705,40 @@ func TestQuerySimpleWithGroupByBooleanThenNumber(t *testing.T) { } func TestQuerySimpleWithGroupByNumberOnUndefined(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children, undefined group value", - Request: `query { - Users(groupBy: [Age]) { - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": nil, - }, - { - "Age": int64(32), + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Age": nil, + }, + { + "Age": int64(32), + }, + }, }, }, }, @@ -668,48 +748,54 @@ func TestQuerySimpleWithGroupByNumberOnUndefined(t *testing.T) { } func TestQuerySimpleWithGroupByNumberOnUndefinedWithChildren(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, with children, undefined group value", - Request: `query { - Users(groupBy: [Age]) { - Age - _group { - Name - } - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Age": nil, - "_group": []map[string]any{ - { - "Name": "Alice", - }, + testUtils.Request{ + Request: `query { + Users(groupBy: [Age]) { + Age + _group { + Name + } + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ { - "Name": "Bob", + "Age": nil, + "_group": []map[string]any{ + { + "Name": "Alice", + }, + { + "Name": "Bob", + }, + }, }, - }, - }, - { - "Age": int64(32), - "_group": []map[string]any{ { - "Name": "John", + "Age": int64(32), + "_group": []map[string]any{ + { + "Name": "John", + }, + }, }, }, }, @@ -721,16 +807,19 @@ func TestQuerySimpleWithGroupByNumberOnUndefinedWithChildren(t *testing.T) { } func TestQuerySimpleErrorsWithNonGroupFieldsSelected(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with group by number, no children", - Request: `query { + Actions: []any{ + testUtils.Request{ + Request: `query { Users(groupBy: [Age]) { Age Name } }`, - Docs: map[int][]string{}, - ExpectedError: "cannot select a non-group-by field at group-level", + ExpectedError: "cannot select a non-group-by field at group-level", + }, + }, } executeTestCase(t, test) diff --git a/tests/integration/query/simple/with_group_typename_test.go b/tests/integration/query/simple/with_group_typename_test.go index d8179fc755..96078cf195 100644 --- a/tests/integration/query/simple/with_group_typename_test.go +++ b/tests/integration/query/simple/with_group_typename_test.go @@ -17,26 +17,28 @@ import ( ) func TestQuerySimpleWithGroupByWithTypeName(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query group by and parent typename", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John" + }`, + }, + testUtils.Request{ + Request: `query { Users(groupBy: [Name]) { Name __typename } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John" - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "__typename": "Users", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "__typename": "Users", + }, + }, }, }, }, @@ -46,9 +48,16 @@ func TestQuerySimpleWithGroupByWithTypeName(t *testing.T) { } func TestQuerySimpleWithGroupByWithChildTypeName(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query group by and child typename", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John" + }`, + }, + testUtils.Request{ + Request: `query { Users(groupBy: [Name]) { Name _group { @@ -56,20 +65,15 @@ func TestQuerySimpleWithGroupByWithChildTypeName(t *testing.T) { } } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John" - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_group": []map[string]any{ + Results: map[string]any{ + "Users": []map[string]any{ { - "__typename": "Users", + "Name": "John", + "_group": []map[string]any{ + { + "__typename": "Users", + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_limit_offset_test.go b/tests/integration/query/simple/with_limit_offset_test.go index 458fc91cc9..aea6cb5b18 100644 --- a/tests/integration/query/simple/with_limit_offset_test.go +++ b/tests/integration/query/simple/with_limit_offset_test.go @@ -17,32 +17,36 @@ import ( ) func TestQuerySimpleWithLimit0(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with limit 0", - Request: `query { - Users(limit: 0) { - Name - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Bob", - }, - { - "Name": "John", + testUtils.Request{ + Request: `query { + Users(limit: 0) { + Name + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + }, + { + "Name": "John", + }, + }, }, }, }, @@ -52,73 +56,85 @@ func TestQuerySimpleWithLimit0(t *testing.T) { } func TestQuerySimpleWithLimit(t *testing.T) { - tests := []testUtils.RequestTestCase{ + tests := []testUtils.TestCase{ { Description: "Simple query with basic limit", - Request: `query { - Users(limit: 1) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Bob", - "Age": int64(32), + testUtils.Request{ + Request: `query { + Users(limit: 1) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + "Age": int64(32), + }, + }, }, }, }, }, { Description: "Simple query with basic limit, more rows", - Request: `query { - Users(limit: 2) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Carlo", - "Age": int64(55), - }, - { - "Name": "Bob", - "Age": int64(32), + testUtils.Request{ + Request: `query { + Users(limit: 2) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "Age": int64(55), + }, + { + "Name": "Bob", + "Age": int64(32), + }, + }, }, }, }, @@ -131,73 +147,85 @@ func TestQuerySimpleWithLimit(t *testing.T) { } func TestQuerySimpleWithLimitAndOffset(t *testing.T) { - tests := []testUtils.RequestTestCase{ + tests := []testUtils.TestCase{ { Description: "Simple query with basic limit & offset", - Request: `query { - Users(limit: 1, offset: 1) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Age": int64(21), + testUtils.Request{ + Request: `query { + Users(limit: 1, offset: 1) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + }, }, }, }, }, { Description: "Simple query with basic limit & offset, more rows", - Request: `query { - Users(limit: 2, offset: 2) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Alice", - "Age": int64(19), + testUtils.Request{ + Request: `query { + Users(limit: 2, offset: 2) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Alice", + "Age": int64(19), + }, + }, }, }, }, @@ -210,81 +238,95 @@ func TestQuerySimpleWithLimitAndOffset(t *testing.T) { } func TestQuerySimpleWithOffset(t *testing.T) { - tests := []testUtils.RequestTestCase{ + tests := []testUtils.TestCase{ { Description: "Simple query with offset only", - Request: `query { - Users(offset: 1) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Age": int64(21), + testUtils.Request{ + Request: `query { + Users(offset: 1) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + }, + }, }, }, }, }, { Description: "Simple query with offset only, more rows", - Request: `query { - Users(offset: 2) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Melynda", "Age": 30 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Melynda", - "Age": int64(30), - }, - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Alice", - "Age": int64(19), + testUtils.Request{ + Request: `query { + Users(offset: 2) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Melynda", + "Age": int64(30), + }, + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Alice", + "Age": int64(19), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_operation_alias_test.go b/tests/integration/query/simple/with_operation_alias_test.go index 5a1130c523..f8ee75b402 100644 --- a/tests/integration/query/simple/with_operation_alias_test.go +++ b/tests/integration/query/simple/with_operation_alias_test.go @@ -17,29 +17,31 @@ import ( ) func TestQuerySimpleWithOperationAlias(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with operation alias", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 21 + }`, + }, + testUtils.Request{ + Request: `query { allUsers: Users { _docID Name Age } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 21 - }`, - }, - }, - Results: map[string]any{ - "allUsers": []map[string]any{ - { - "_docID": "bae-d4303725-7db9-53d2-b324-f3ee44020e52", - "Name": "John", - "Age": int64(21), + Results: map[string]any{ + "allUsers": []map[string]any{ + { + "_docID": "bae-d4303725-7db9-53d2-b324-f3ee44020e52", + "Name": "John", + "Age": int64(21), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_order_filter_test.go b/tests/integration/query/simple/with_order_filter_test.go index cbee236ca2..c51ee88bd0 100644 --- a/tests/integration/query/simple/with_order_filter_test.go +++ b/tests/integration/query/simple/with_order_filter_test.go @@ -17,43 +17,51 @@ import ( ) func TestQuerySimpleWithNumericGreaterThanFilterAndNumericOrderDescending(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with order & filter", - Request: `query { - Users(filter: {Age: {_gt: 30}}, order: {Age: DESC}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Carlo", - "Age": int64(55), - }, - { - "Name": "Bob", - "Age": int64(32), + testUtils.Request{ + Request: `query { + Users(filter: {Age: {_gt: 30}}, order: {Age: DESC}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "Age": int64(55), + }, + { + "Name": "Bob", + "Age": int64(32), + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_order_test.go b/tests/integration/query/simple/with_order_test.go index 003b9a0a52..000e3ee391 100644 --- a/tests/integration/query/simple/with_order_test.go +++ b/tests/integration/query/simple/with_order_test.go @@ -17,43 +17,49 @@ import ( ) func TestQuerySimpleWithEmptyOrder(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with empty order", - Request: `query { - Users(order: {}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Carlo", - "Age": int64(55), - }, - { - "Name": "Bob", - "Age": int64(32), - }, - { - "Name": "John", - "Age": int64(21), + testUtils.Request{ + Request: `query { + Users(order: {}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "Age": int64(55), + }, + { + "Name": "Bob", + "Age": int64(32), + }, + { + "Name": "John", + "Age": int64(21), + }, + }, }, }, }, @@ -63,51 +69,59 @@ func TestQuerySimpleWithEmptyOrder(t *testing.T) { } func TestQuerySimpleWithNumericOrderAscending(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic order ASC", - Request: `query { - Users(order: {Age: ASC}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Alice", - "Age": int64(19), - }, - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Bob", - "Age": int64(32), - }, - { - "Name": "Carlo", - "Age": int64(55), + testUtils.Request{ + Request: `query { + Users(order: {Age: ASC}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Alice", + "Age": int64(19), + }, + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Bob", + "Age": int64(32), + }, + { + "Name": "Carlo", + "Age": int64(55), + }, + }, }, }, }, @@ -117,55 +131,63 @@ func TestQuerySimpleWithNumericOrderAscending(t *testing.T) { } func TestQuerySimpleWithDateTimeOrderAscending(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic order ASC", - Request: `query { - Users(order: {CreatedAt: ASC}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21, "CreatedAt": "2021-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32, "CreatedAt": "2032-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55, "CreatedAt": "2055-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19, "CreatedAt": "2019-07-23T03:46:56-05:00" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Alice", - "Age": int64(19), - }, - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Bob", - "Age": int64(32), - }, - { - "Name": "Carlo", - "Age": int64(55), + testUtils.Request{ + Request: `query { + Users(order: {CreatedAt: ASC}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Alice", + "Age": int64(19), + }, + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Bob", + "Age": int64(32), + }, + { + "Name": "Carlo", + "Age": int64(55), + }, + }, }, }, }, @@ -175,51 +197,59 @@ func TestQuerySimpleWithDateTimeOrderAscending(t *testing.T) { } func TestQuerySimpleWithNumericOrderDescending(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic order DESC", - Request: `query { - Users(order: {Age: DESC}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19 }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Carlo", - "Age": int64(55), - }, - { - "Name": "Bob", - "Age": int64(32), - }, - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Alice", - "Age": int64(19), + testUtils.Request{ + Request: `query { + Users(order: {Age: DESC}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "Age": int64(55), + }, + { + "Name": "Bob", + "Age": int64(32), + }, + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Alice", + "Age": int64(19), + }, + }, }, }, }, @@ -229,55 +259,63 @@ func TestQuerySimpleWithNumericOrderDescending(t *testing.T) { } func TestQuerySimpleWithDateTimeOrderDescending(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with basic order DESC", - Request: `query { - Users(order: {CreatedAt: DESC}) { - Name - Age - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21, "CreatedAt": "2021-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 32, "CreatedAt": "2032-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55, "CreatedAt": "2055-07-23T03:46:56-05:00" }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19, "CreatedAt": "2019-07-23T03:46:56-05:00" }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Carlo", - "Age": int64(55), - }, - { - "Name": "Bob", - "Age": int64(32), - }, - { - "Name": "John", - "Age": int64(21), - }, - { - "Name": "Alice", - "Age": int64(19), + testUtils.Request{ + Request: `query { + Users(order: {CreatedAt: DESC}) { + Name + Age + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "Age": int64(55), + }, + { + "Name": "Bob", + "Age": int64(32), + }, + { + "Name": "John", + "Age": int64(21), + }, + { + "Name": "Alice", + "Age": int64(19), + }, + }, }, }, }, @@ -287,60 +325,68 @@ func TestQuerySimpleWithDateTimeOrderDescending(t *testing.T) { } func TestQuerySimpleWithNumericOrderDescendingAndBooleanOrderAscending(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with compound order", - Request: `query { - Users(order: {Age: DESC, Verified: ASC}) { - Name - Age - Verified - } - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 21, "Verified": false }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Carlo", "Age": 55, "Verified": true }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 19, "Verified": false }`, }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "Carlo", - "Age": int64(55), - "Verified": true, - }, - { - "Name": "Bob", - "Age": int64(21), - "Verified": false, - }, - { - "Name": "John", - "Age": int64(21), - "Verified": true, - }, - { - "Name": "Alice", - "Age": int64(19), - "Verified": false, + testUtils.Request{ + Request: `query { + Users(order: {Age: DESC, Verified: ASC}) { + Name + Age + Verified + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Carlo", + "Age": int64(55), + "Verified": true, + }, + { + "Name": "Bob", + "Age": int64(21), + "Verified": false, + }, + { + "Name": "John", + "Age": int64(21), + "Verified": true, + }, + { + "Name": "Alice", + "Age": int64(19), + "Verified": false, + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_sum_filter_test.go b/tests/integration/query/simple/with_sum_filter_test.go index 1c1515a769..8a947fdb54 100644 --- a/tests/integration/query/simple/with_sum_filter_test.go +++ b/tests/integration/query/simple/with_sum_filter_test.go @@ -17,29 +17,35 @@ import ( ) func TestQuerySimpleWithSumWithFilter(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query, sum with filter", - Request: `query { - _sum(Users: {field: Age, filter: {Age: {_gt: 26}}}) - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 30 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Alice", "Age": 32 }`, }, - }, - Results: map[string]any{ - "_sum": int64(62), + testUtils.Request{ + Request: `query { + _sum(Users: {field: Age, filter: {Age: {_gt: 26}}}) + }`, + Results: map[string]any{ + "_sum": int64(62), + }, + }, }, } diff --git a/tests/integration/query/simple/with_sum_test.go b/tests/integration/query/simple/with_sum_test.go index 34dde00e15..65da7d2ea3 100644 --- a/tests/integration/query/simple/with_sum_test.go +++ b/tests/integration/query/simple/with_sum_test.go @@ -17,37 +17,49 @@ import ( ) func TestQuerySimpleWithSumOnUndefinedObject(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query, sum on undefined object", - Request: `query { + Actions: []any{ + testUtils.Request{ + Request: `query { _sum }`, - ExpectedError: "aggregate must be provided with a property to aggregate", + ExpectedError: "aggregate must be provided with a property to aggregate", + }, + }, } executeTestCase(t, test) } func TestQuerySimpleWithSumOnUndefinedField(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query, sum on undefined field", - Request: `query { + Actions: []any{ + testUtils.Request{ + Request: `query { _sum(Users: {}) }`, - ExpectedError: "Argument \"Users\" has invalid value {}.\nIn field \"field\": Expected \"UsersNumericFieldsArg!\", found null.", + ExpectedError: "Argument \"Users\" has invalid value {}.\nIn field \"field\": Expected \"UsersNumericFieldsArg!\", found null.", + }, + }, } executeTestCase(t, test) } func TestQuerySimpleWithSumOnEmptyCollection(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query, sum on empty", - Request: `query { + Actions: []any{ + testUtils.Request{ + Request: `query { _sum(Users: {field: Age}) }`, - Results: map[string]any{ - "_sum": int64(0), + Results: map[string]any{ + "_sum": int64(0), + }, + }, }, } @@ -55,25 +67,29 @@ func TestQuerySimpleWithSumOnEmptyCollection(t *testing.T) { } func TestQuerySimpleWithSum(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query, sum", - Request: `query { - _sum(Users: {field: Age}) - }`, - Docs: map[int][]string{ - 0: { - `{ + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ "Name": "John", "Age": 21 }`, - `{ + }, + testUtils.CreateDoc{ + Doc: `{ "Name": "Bob", "Age": 30 }`, }, - }, - Results: map[string]any{ - "_sum": int64(51), + testUtils.Request{ + Request: `query { + _sum(Users: {field: Age}) + }`, + Results: map[string]any{ + "_sum": int64(51), + }, + }, }, } diff --git a/tests/integration/query/simple/with_typename_test.go b/tests/integration/query/simple/with_typename_test.go index 8f44ee60c0..8bf44d0fb7 100644 --- a/tests/integration/query/simple/with_typename_test.go +++ b/tests/integration/query/simple/with_typename_test.go @@ -17,26 +17,28 @@ import ( ) func TestQuerySimpleWithTypeName(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with typename", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John" + }`, + }, + testUtils.Request{ + Request: `query { Users { Name __typename } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John" - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "__typename": "Users", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "__typename": "Users", + }, + }, }, }, }, @@ -46,28 +48,30 @@ func TestQuerySimpleWithTypeName(t *testing.T) { } func TestQuerySimpleWithAliasedTypeName(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Simple query with aliased typename", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John" + }`, + }, + testUtils.Request{ + Request: `query { Users { Name __typename t1: __typename } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John" - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "__typename": "Users", - "t1": "Users", + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "__typename": "Users", + "t1": "Users", + }, + }, }, }, }, diff --git a/tests/integration/query/simple/with_version_test.go b/tests/integration/query/simple/with_version_test.go index aaf2092e61..d0eda9db43 100644 --- a/tests/integration/query/simple/with_version_test.go +++ b/tests/integration/query/simple/with_version_test.go @@ -17,9 +17,17 @@ import ( ) func TestQuerySimpleWithEmbeddedLatestCommit(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Embedded latest commits query within object query", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 21 + }`, + }, + testUtils.Request{ + Request: `query { Users { Name Age @@ -32,30 +40,24 @@ func TestQuerySimpleWithEmbeddedLatestCommit(t *testing.T) { } } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 21 - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Age": int64(21), - "_version": []map[string]any{ + Results: map[string]any{ + "Users": []map[string]any{ { - "cid": "bafyreiby7drdzfsg4wwo7f6vkdqhurbe74s4lhayn3k3226zvkgwjd2fbu", - "links": []map[string]any{ - { - "cid": "bafyreid4sasigytiflrh3rupyevo6wy43b6mlfi4jwkjjwvohgjcd3oscu", - "name": "Age", - }, + "Name": "John", + "Age": int64(21), + "_version": []map[string]any{ { - "cid": "bafyreieg3p2kpyxwiowskvb3pp35nedzawmapjuib7glrvszcgmv6z37fm", - "name": "Name", + "cid": "bafyreiby7drdzfsg4wwo7f6vkdqhurbe74s4lhayn3k3226zvkgwjd2fbu", + "links": []map[string]any{ + { + "cid": "bafyreid4sasigytiflrh3rupyevo6wy43b6mlfi4jwkjjwvohgjcd3oscu", + "name": "Age", + }, + { + "cid": "bafyreieg3p2kpyxwiowskvb3pp35nedzawmapjuib7glrvszcgmv6z37fm", + "name": "Name", + }, + }, }, }, }, @@ -69,9 +71,17 @@ func TestQuerySimpleWithEmbeddedLatestCommit(t *testing.T) { } func TestQuerySimpleWithEmbeddedLatestCommitWithSchemaVersionID(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Embedded commits query within object query with schema version id", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 21 + }`, + }, + testUtils.Request{ + Request: `query { Users { Name _version { @@ -79,21 +89,15 @@ func TestQuerySimpleWithEmbeddedLatestCommitWithSchemaVersionID(t *testing.T) { } } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 21 - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_version": []map[string]any{ + Results: map[string]any{ + "Users": []map[string]any{ { - "schemaVersionId": "bafkreigqmcqzkbg3elpe24vfza4rjle2r6cxu7ihzvg56aov57crhaebry", + "Name": "John", + "_version": []map[string]any{ + { + "schemaVersionId": "bafkreigqmcqzkbg3elpe24vfza4rjle2r6cxu7ihzvg56aov57crhaebry", + }, + }, }, }, }, @@ -107,9 +111,17 @@ func TestQuerySimpleWithEmbeddedLatestCommitWithSchemaVersionID(t *testing.T) { func TestQuerySimpleWithEmbeddedLatestCommitWithDocID(t *testing.T) { const docID = "bae-d4303725-7db9-53d2-b324-f3ee44020e52" - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Embedded commits query within object query with document ID", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 21 + }`, + }, + testUtils.Request{ + Request: `query { Users { Name _docID @@ -118,22 +130,16 @@ func TestQuerySimpleWithEmbeddedLatestCommitWithDocID(t *testing.T) { } } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 21 - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "_docID": docID, - "_version": []map[string]any{ + Results: map[string]any{ + "Users": []map[string]any{ { - "docID": docID, + "Name": "John", + "_docID": docID, + "_version": []map[string]any{ + { + "docID": docID, + }, + }, }, }, }, @@ -145,9 +151,17 @@ func TestQuerySimpleWithEmbeddedLatestCommitWithDocID(t *testing.T) { } func TestQuerySimpleWithMultipleAliasedEmbeddedLatestCommit(t *testing.T) { - test := testUtils.RequestTestCase{ + test := testUtils.TestCase{ Description: "Embedded, aliased, latest commits query within object query", - Request: `query { + Actions: []any{ + testUtils.CreateDoc{ + Doc: `{ + "Name": "John", + "Age": 21 + }`, + }, + testUtils.Request{ + Request: `query { Users { Name Age @@ -163,38 +177,32 @@ func TestQuerySimpleWithMultipleAliasedEmbeddedLatestCommit(t *testing.T) { } } }`, - Docs: map[int][]string{ - 0: { - `{ - "Name": "John", - "Age": 21 - }`, - }, - }, - Results: map[string]any{ - "Users": []map[string]any{ - { - "Name": "John", - "Age": int64(21), - "_version": []map[string]any{ + Results: map[string]any{ + "Users": []map[string]any{ { - "cid": "bafyreiby7drdzfsg4wwo7f6vkdqhurbe74s4lhayn3k3226zvkgwjd2fbu", - "L1": []map[string]any{ - { - "cid": "bafyreid4sasigytiflrh3rupyevo6wy43b6mlfi4jwkjjwvohgjcd3oscu", - "name": "Age", - }, - { - "cid": "bafyreieg3p2kpyxwiowskvb3pp35nedzawmapjuib7glrvszcgmv6z37fm", - "name": "Name", - }, - }, - "L2": []map[string]any{ - { - "name": "Age", - }, + "Name": "John", + "Age": int64(21), + "_version": []map[string]any{ { - "name": "Name", + "cid": "bafyreiby7drdzfsg4wwo7f6vkdqhurbe74s4lhayn3k3226zvkgwjd2fbu", + "L1": []map[string]any{ + { + "cid": "bafyreid4sasigytiflrh3rupyevo6wy43b6mlfi4jwkjjwvohgjcd3oscu", + "name": "Age", + }, + { + "cid": "bafyreieg3p2kpyxwiowskvb3pp35nedzawmapjuib7glrvszcgmv6z37fm", + "name": "Name", + }, + }, + "L2": []map[string]any{ + { + "name": "Age", + }, + { + "name": "Name", + }, + }, }, }, }, diff --git a/tests/integration/utils.go b/tests/integration/utils.go index 14f20b494d..f26ee4ed5b 100644 --- a/tests/integration/utils.go +++ b/tests/integration/utils.go @@ -11,63 +11,2232 @@ package tests import ( + "context" + "encoding/json" + "fmt" + "os" + "reflect" + "strconv" + "strings" "testing" + "time" + + "github.com/bxcodec/faker/support/slice" + "github.com/fxamacker/cbor/v2" + "github.com/sourcenetwork/corelog" + "github.com/sourcenetwork/immutable" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/sourcenetwork/defradb/client" + "github.com/sourcenetwork/defradb/client/request" + "github.com/sourcenetwork/defradb/crypto" + "github.com/sourcenetwork/defradb/datastore" + "github.com/sourcenetwork/defradb/errors" + "github.com/sourcenetwork/defradb/internal/db" + "github.com/sourcenetwork/defradb/internal/encryption" + "github.com/sourcenetwork/defradb/internal/request/graphql" + "github.com/sourcenetwork/defradb/net" + changeDetector "github.com/sourcenetwork/defradb/tests/change_detector" + "github.com/sourcenetwork/defradb/tests/clients" + "github.com/sourcenetwork/defradb/tests/gen" + "github.com/sourcenetwork/defradb/tests/predefined" +) + +const ( + mutationTypeEnvName = "DEFRA_MUTATION_TYPE" + skipNetworkTestsEnvName = "DEFRA_SKIP_NETWORK_TESTS" +) + +// The MutationType that tests will run using. +// +// For example if set to [CollectionSaveMutationType], all supporting +// actions (such as [UpdateDoc]) will execute via [Collection.Save]. +// +// Defaults to CollectionSaveMutationType. +type MutationType string + +const ( + // CollectionSaveMutationType will cause all supporting actions + // to run their mutations via [Collection.Save]. + CollectionSaveMutationType MutationType = "collection-save" + + // CollectionNamedMutationType will cause all supporting actions + // to run their mutations via their corresponding named [Collection] + // call. + // + // For example, CreateDoc will call [Collection.Create], and + // UpdateDoc will call [Collection.Update]. + CollectionNamedMutationType MutationType = "collection-named" + + // GQLRequestMutationType will cause all supporting actions to + // run their mutations using GQL requests, typically these will + // include a `id` parameter to target the specified document. + GQLRequestMutationType MutationType = "gql" +) + +var ( + log = corelog.NewLogger("tests.integration") + mutationType MutationType + // skipNetworkTests will skip any tests that involve network actions + skipNetworkTests = false ) -type RequestTestCase struct { - Description string - Request string +const ( + // subscriptionTimeout is the maximum time to wait for subscription results to be returned. + subscriptionTimeout = 1 * time.Second + // Instantiating lenses is expensive, and our tests do not benefit from a large number of them, + // so we explicitly set it to a low value. + lensPoolSize = 2 +) + +const testJSONFile = "/test.json" + +func init() { + // We use environment variables instead of flags `go test ./...` throws for all packages + // that don't have the flag defined + if value, ok := os.LookupEnv(mutationTypeEnvName); ok { + mutationType = MutationType(value) + } else { + // Default to testing mutations via Collection.Save - it should be simpler and + // faster. We assume this is desirable when not explicitly testing any particular + // mutation type. + mutationType = CollectionSaveMutationType + } + if value, ok := os.LookupEnv(skipNetworkTestsEnvName); ok { + skipNetworkTests, _ = strconv.ParseBool(value) + } +} + +// AssertPanic asserts that the code inside the specified PanicTestFunc panics. +// +// This function is not supported by either the change detector, or the http-client. +// Calling this within either of them will result in the test being skipped. +// +// Usage: AssertPanic(t, func() { executeTestCase(t, test) }) +func AssertPanic(t *testing.T, f assert.PanicTestFunc) bool { + if changeDetector.Enabled { + // The `assert.Panics` call will falsely fail if this test is executed during + // a detect changes test run. + t.Skip("Assert panic with the change detector is not currently supported.") + } + + if httpClient || cliClient { + // The http / cli client will return an error instead of panicing at the moment. + t.Skip("Assert panic with the http client is not currently supported.") + } + + return assert.Panics(t, f, "expected a panic, but none found.") +} + +// ExecuteTestCase executes the given TestCase against the configured database +// instances. +// +// Will also attempt to detect incompatible changes in the persisted data if +// configured to do so (the CI will do so, but disabled by default as it is slow). +func ExecuteTestCase( + t testing.TB, + testCase TestCase, +) { + flattenActions(&testCase) + collectionNames := getCollectionNames(testCase) + changeDetector.PreTestChecks(t, collectionNames) + skipIfMutationTypeUnsupported(t, testCase.SupportedMutationTypes) + skipIfACPTypeUnsupported(t, testCase.SupportedACPTypes) + skipIfNetworkTest(t, testCase.Actions) + + var clients []ClientType + if httpClient { + clients = append(clients, HTTPClientType) + } + if goClient { + clients = append(clients, GoClientType) + } + if cliClient { + clients = append(clients, CLIClientType) + } + + var databases []DatabaseType + if badgerInMemory { + databases = append(databases, badgerIMType) + } + if badgerFile { + databases = append(databases, badgerFileType) + } + if inMemoryStore { + databases = append(databases, defraIMType) + } + + // Assert that these are not empty to protect against accidental mis-configurations, + // otherwise an empty set would silently pass all the tests. + require.NotEmpty(t, databases) + require.NotEmpty(t, clients) + + clients = skipIfClientTypeUnsupported(t, clients, testCase.SupportedClientTypes) + + ctx := context.Background() + for _, ct := range clients { + for _, dbt := range databases { + executeTestCase(ctx, t, collectionNames, testCase, dbt, ct) + } + } +} + +func executeTestCase( + ctx context.Context, + t testing.TB, + collectionNames []string, + testCase TestCase, + dbt DatabaseType, + clientType ClientType, +) { + log.InfoContext( + ctx, + testCase.Description, + corelog.Any("database", dbt), + corelog.Any("client", clientType), + corelog.Any("mutationType", mutationType), + corelog.String("databaseDir", databaseDir), + corelog.Bool("badgerEncryption", badgerEncryption), + corelog.Bool("skipNetworkTests", skipNetworkTests), + corelog.Bool("changeDetector.Enabled", changeDetector.Enabled), + corelog.Bool("changeDetector.SetupOnly", changeDetector.SetupOnly), + corelog.String("changeDetector.SourceBranch", changeDetector.SourceBranch), + corelog.String("changeDetector.TargetBranch", changeDetector.TargetBranch), + corelog.String("changeDetector.Repository", changeDetector.Repository), + ) + + startActionIndex, endActionIndex := getActionRange(t, testCase) + + s := newState(ctx, t, testCase, dbt, clientType, collectionNames) + setStartingNodes(s) + + // It is very important that the databases are always closed, otherwise resources will leak + // as tests run. This is particularly important for file based datastores. + defer closeNodes(s) + + // Documents and Collections may already exist in the database if actions have been split + // by the change detector so we should fetch them here at the start too (if they exist). + // collections are by node (index), as they are specific to nodes. + refreshCollections(s) + refreshDocuments(s, startActionIndex) + refreshIndexes(s) + + for i := startActionIndex; i <= endActionIndex; i++ { + performAction(s, i, testCase.Actions[i]) + } + + // Notify any active subscriptions that all requests have been sent. + close(s.allActionsDone) + + for _, resultsChan := range s.subscriptionResultsChans { + select { + case subscriptionAssert := <-resultsChan: + // We want to assert back in the main thread so failures get recorded properly + subscriptionAssert() + + // a safety in case the stream hangs - we don't want the tests to run forever. + case <-time.After(subscriptionTimeout): + assert.Fail(t, "timeout occurred while waiting for data stream", testCase.Description) + } + } +} + +func performAction( + s *state, + actionIndex int, + act any, +) { + switch action := act.(type) { + case ConfigureNode: + configureNode(s, action) + + case Restart: + restartNodes(s) + + case ConnectPeers: + connectPeers(s, action) + + case ConfigureReplicator: + configureReplicator(s, action) + + case DeleteReplicator: + deleteReplicator(s, action) + + case SubscribeToCollection: + subscribeToCollection(s, action) + + case UnsubscribeToCollection: + unsubscribeToCollection(s, action) + + case GetAllP2PCollections: + getAllP2PCollections(s, action) + + case SchemaUpdate: + updateSchema(s, action) + + case SchemaPatch: + patchSchema(s, action) + + case PatchCollection: + patchCollection(s, action) + + case GetSchema: + getSchema(s, action) + + case GetCollections: + getCollections(s, action) + + case SetActiveSchemaVersion: + setActiveSchemaVersion(s, action) + + case CreateView: + createView(s, action) + + case ConfigureMigration: + configureMigration(s, action) + + case AddPolicy: + addPolicyACP(s, action) + + case CreateDoc: + createDoc(s, action) + + case DeleteDoc: + deleteDoc(s, action) + + case UpdateDoc: + updateDoc(s, action) + + case UpdateWithFilter: + updateWithFilter(s, action) + + case CreateIndex: + createIndex(s, action) + + case DropIndex: + dropIndex(s, action) + + case GetIndexes: + getIndexes(s, action) + + case BackupExport: + backupExport(s, action) + + case BackupImport: + backupImport(s, action) + + case TransactionCommit: + commitTransaction(s, action) + + case SubscriptionRequest: + executeSubscriptionRequest(s, action) + + case Request: + executeRequest(s, action) + + case ExplainRequest: + executeExplainRequest(s, action) + + case IntrospectionRequest: + assertIntrospectionResults(s, action) + + case ClientIntrospectionRequest: + assertClientIntrospectionResults(s, action) + + case WaitForSync: + waitForMergeEvents(s) + + case Benchmark: + benchmarkAction(s, actionIndex, action) + + case GenerateDocs: + generateDocs(s, action) + + case CreatePredefinedDocs: + generatePredefinedDocs(s, action) + + case SetupComplete: + // no-op, just continue. + + default: + s.t.Fatalf("Unknown action type %T", action) + } +} + +func createGenerateDocs(s *state, docs []gen.GeneratedDoc, nodeID immutable.Option[int]) { + nameToInd := make(map[string]int) + for i, name := range s.collectionNames { + nameToInd[name] = i + } + for _, doc := range docs { + docJSON, err := doc.Doc.String() + if err != nil { + s.t.Fatalf("Failed to generate docs %s", err) + } + createDoc(s, CreateDoc{CollectionID: nameToInd[doc.Col.Description.Name.Value()], Doc: docJSON, NodeID: nodeID}) + } +} + +func generateDocs(s *state, action GenerateDocs) { + collections := getNodeCollections(action.NodeID, s.collections) + defs := make([]client.CollectionDefinition, 0, len(collections[0])) + for _, col := range collections[0] { + if len(action.ForCollections) == 0 || slice.Contains(action.ForCollections, col.Name().Value()) { + defs = append(defs, col.Definition()) + } + } + docs, err := gen.AutoGenerate(defs, action.Options...) + if err != nil { + s.t.Fatalf("Failed to generate docs %s", err) + } + createGenerateDocs(s, docs, action.NodeID) +} + +func generatePredefinedDocs(s *state, action CreatePredefinedDocs) { + collections := getNodeCollections(action.NodeID, s.collections) + defs := make([]client.CollectionDefinition, 0, len(collections[0])) + for _, col := range collections[0] { + defs = append(defs, col.Definition()) + } + docs, err := predefined.Create(defs, action.Docs) + if err != nil { + s.t.Fatalf("Failed to generate docs %s", err) + } + createGenerateDocs(s, docs, action.NodeID) +} + +func benchmarkAction( + s *state, + actionIndex int, + bench Benchmark, +) { + if s.dbt == defraIMType { + // Benchmarking makes no sense for test in-memory storage + return + } + if len(bench.FocusClients) > 0 { + isFound := false + for _, clientType := range bench.FocusClients { + if s.clientType == clientType { + isFound = true + break + } + } + if !isFound { + return + } + } + + runBench := func(benchCase any) time.Duration { + startTime := time.Now() + for i := 0; i < bench.Reps; i++ { + performAction(s, actionIndex, benchCase) + } + return time.Since(startTime) + } + + s.isBench = true + defer func() { s.isBench = false }() + + baseElapsedTime := runBench(bench.BaseCase) + optimizedElapsedTime := runBench(bench.OptimizedCase) + + factoredBaseTime := int64(float64(baseElapsedTime) / bench.Factor) + assert.Greater(s.t, factoredBaseTime, optimizedElapsedTime, + "Optimized case should be faster at least by factor of %.2f than the base case. Base: %d, Optimized: %d (μs)", + bench.Factor, optimizedElapsedTime.Microseconds(), baseElapsedTime.Microseconds()) +} + +// getCollectionNames gets an ordered, unique set of collection names across all nodes +// from the action set within the given test case. +// +// It preserves the order in which they are declared, and shares indexes across all nodes, so +// if a second node adds a collection of a name that was previously declared in another node +// the new node will respect the index originally assigned. This allows collections to be +// referenced across multiple nodes by a consistent, predictable index - allowing a single +// action to target the same collection across multiple nodes. +// +// WARNING: This will not work with schemas ending in `type`, e.g. `user_type` +func getCollectionNames(testCase TestCase) []string { + nextIndex := 0 + collectionIndexByName := map[string]int{} + + for _, a := range testCase.Actions { + switch action := a.(type) { + case SchemaUpdate: + if action.ExpectedError != "" { + // If an error is expected then no collections should result from this action + continue + } + + nextIndex = getCollectionNamesFromSchema(collectionIndexByName, action.Schema, nextIndex) + } + } + + collectionNames := make([]string, len(collectionIndexByName)) + for name, index := range collectionIndexByName { + collectionNames[index] = name + } + + return collectionNames +} + +func getCollectionNamesFromSchema(result map[string]int, schema string, nextIndex int) int { + // WARNING: This will not work with schemas ending in `type`, e.g. `user_type` + splitByType := strings.Split(schema, "type ") + // Skip the first, as that preceeds `type ` if `type ` is present, + // else there are no types. + for i := 1; i < len(splitByType); i++ { + wipSplit := strings.TrimLeft(splitByType[i], " ") + indexOfLastChar := strings.IndexAny(wipSplit, " {") + if indexOfLastChar <= 0 { + // This should never happen + continue + } + + collectionName := wipSplit[:indexOfLastChar] + if _, ok := result[collectionName]; ok { + // Collection name has already been added, possibly via another node + continue + } + + result[collectionName] = nextIndex + nextIndex++ + } + return nextIndex +} + +// closeNodes closes all the given nodes, ensuring that resources are properly released. +func closeNodes( + s *state, +) { + for _, node := range s.nodes { + node.Close() + } +} + +// getNodes gets the set of applicable nodes for the given nodeID. +// +// If nodeID has a value it will return that node only, otherwise all nodes will be returned. +func getNodes(nodeID immutable.Option[int], nodes []clients.Client) []clients.Client { + if !nodeID.HasValue() { + return nodes + } + + return []clients.Client{nodes[nodeID.Value()]} +} + +// getNodeCollections gets the set of applicable collections for the given nodeID. +// +// If nodeID has a value it will return collections for that node only, otherwise all collections across all +// nodes will be returned. +func getNodeCollections(nodeID immutable.Option[int], collections [][]client.Collection) [][]client.Collection { + if !nodeID.HasValue() { + return collections + } + + return [][]client.Collection{collections[nodeID.Value()]} +} + +func calculateLenForFlattenedActions(testCase *TestCase) int { + newLen := 0 + for _, a := range testCase.Actions { + actionGroup := reflect.ValueOf(a) + switch actionGroup.Kind() { + case reflect.Array, reflect.Slice: + newLen += actionGroup.Len() + default: + newLen++ + } + } + return newLen +} + +func flattenActions(testCase *TestCase) { + newLen := calculateLenForFlattenedActions(testCase) + if newLen == len(testCase.Actions) { + return + } + newActions := make([]any, 0, newLen) + + for _, a := range testCase.Actions { + actionGroup := reflect.ValueOf(a) + switch actionGroup.Kind() { + case reflect.Array, reflect.Slice: + for i := 0; i < actionGroup.Len(); i++ { + newActions = append( + newActions, + actionGroup.Index(i).Interface(), + ) + } + default: + newActions = append(newActions, a) + } + } + testCase.Actions = newActions +} + +// getActionRange returns the index of the first action to be run, and the last. +// +// Not all processes will run all actions - if this is a change detector run they +// will be split. +// +// If a SetupComplete action is provided, the actions will be split there, if not +// they will be split at the first non SchemaUpdate/CreateDoc/UpdateDoc action. +func getActionRange(t testing.TB, testCase TestCase) (int, int) { + startIndex := 0 + endIndex := len(testCase.Actions) - 1 + + if !changeDetector.Enabled { + return startIndex, endIndex + } + + setupCompleteIndex := -1 + firstNonSetupIndex := -1 + +ActionLoop: + for i := range testCase.Actions { + switch testCase.Actions[i].(type) { + case SetupComplete: + setupCompleteIndex = i + // We don't care about anything else if this has been explicitly provided + break ActionLoop + + case SchemaUpdate, CreateDoc, UpdateDoc, Restart: + continue + + default: + firstNonSetupIndex = i + break ActionLoop + } + } + + if changeDetector.SetupOnly { + if setupCompleteIndex > -1 { + endIndex = setupCompleteIndex + } else if firstNonSetupIndex > -1 { + // -1 to exclude this index + endIndex = firstNonSetupIndex - 1 + } + } else { + if setupCompleteIndex > -1 { + // +1 to exclude the SetupComplete action + startIndex = setupCompleteIndex + 1 + } else if firstNonSetupIndex > -1 { + // We must not set this to -1 :) + startIndex = firstNonSetupIndex + } else { + // if we don't have any non-mutation actions and the change detector is enabled + // skip this test as we will not gain anything from running (change detector would + // run an idential profile to a normal test run) + t.Skipf("no actions to execute") + } + } + + return startIndex, endIndex +} + +// setStartingNodes adds a set of initial Defra nodes for the test to execute against. +// +// If a node(s) has been explicitly configured via a `ConfigureNode` action then no new +// nodes will be added. +func setStartingNodes( + s *state, +) { + hasExplicitNode := false + for _, action := range s.testCase.Actions { + switch action.(type) { + case ConfigureNode: + hasExplicitNode = true + } + } + + // If nodes have not been explicitly configured via actions, setup a default one. + if !hasExplicitNode { + node, path, err := setupNode(s) + require.Nil(s.t, err) + + c, err := setupClient(s, node) + require.Nil(s.t, err) + + eventState, err := newEventState(c.Events()) + require.NoError(s.t, err) + + s.nodes = append(s.nodes, c) + s.nodeEvents = append(s.nodeEvents, eventState) + s.nodeP2P = append(s.nodeP2P, newP2PState()) + s.dbPaths = append(s.dbPaths, path) + } +} + +func restartNodes( + s *state, +) { + if s.dbt == badgerIMType || s.dbt == defraIMType { + return + } + closeNodes(s) + + // We need to restart the nodes in reverse order, to avoid dial backoff issues. + for i := len(s.nodes) - 1; i >= 0; i-- { + originalPath := databaseDir + databaseDir = s.dbPaths[i] + node, _, err := setupNode(s) + require.Nil(s.t, err) + databaseDir = originalPath + + if len(s.nodeConfigs) == 0 { + // If there are no explicit node configuration actions the node will be + // basic (i.e. no P2P stuff) and can be yielded now. + c, err := setupClient(s, node) + require.NoError(s.t, err) + s.nodes[i] = c + + eventState, err := newEventState(c.Events()) + require.NoError(s.t, err) + s.nodeEvents[i] = eventState + continue + } + + // We need to make sure the node is configured with its old address, otherwise + // a new one may be selected and reconnnection to it will fail. + var addresses []string + for _, addr := range s.nodeAddresses[i].Addrs { + addresses = append(addresses, addr.String()) + } + + nodeOpts := s.nodeConfigs[i] + nodeOpts = append(nodeOpts, net.WithListenAddresses(addresses...)) + + p, err := net.NewPeer(s.ctx, node.DB.Rootstore(), node.DB.Blockstore(), node.DB.Events(), nodeOpts...) + require.NoError(s.t, err) + + if err := p.Start(); err != nil { + p.Close() + require.NoError(s.t, err) + } + node.Peer = p + + c, err := setupClient(s, node) + require.NoError(s.t, err) + s.nodes[i] = c + + eventState, err := newEventState(c.Events()) + require.NoError(s.t, err) + s.nodeEvents[i] = eventState + + waitForNetworkSetupEvents(s, i) + } + + // If the db was restarted we need to refresh the collection definitions as the old instances + // will reference the old (closed) database instances. + refreshCollections(s) + refreshIndexes(s) +} + +// refreshCollections refreshes all the collections of the given names, preserving order. +// +// If a given collection is not present in the database the value at the corresponding +// result-index will be nil. +func refreshCollections( + s *state, +) { + s.collections = make([][]client.Collection, len(s.nodes)) + + for nodeID, node := range s.nodes { + s.collections[nodeID] = make([]client.Collection, len(s.collectionNames)) + allCollections, err := node.GetCollections(s.ctx, client.CollectionFetchOptions{}) + require.Nil(s.t, err) + + for i, collectionName := range s.collectionNames { + for _, collection := range allCollections { + if collection.Name().Value() == collectionName { + s.collections[nodeID][i] = collection + break + } + } + } + } +} + +// configureNode configures and starts a new Defra node using the provided configuration. +// +// It returns the new node, and its peer address. Any errors generated during configuration +// will result in a test failure. +func configureNode( + s *state, + action ConfigureNode, +) { + if changeDetector.Enabled { + // We do not yet support the change detector for tests running across multiple nodes. + s.t.SkipNow() + return + } + + node, path, err := setupNode(s) //disable change dector, or allow it? + require.NoError(s.t, err) + + privateKey, err := crypto.GenerateEd25519() + require.NoError(s.t, err) + + nodeOpts := action() + nodeOpts = append(nodeOpts, net.WithPrivateKey(privateKey)) + + p, err := net.NewPeer(s.ctx, node.DB.Rootstore(), node.DB.Blockstore(), node.DB.Events(), nodeOpts...) + require.NoError(s.t, err) + + log.InfoContext(s.ctx, "Starting P2P node", corelog.Any("P2P address", p.PeerInfo())) + if err := p.Start(); err != nil { + p.Close() + require.NoError(s.t, err) + } + + s.nodeAddresses = append(s.nodeAddresses, p.PeerInfo()) + s.nodeConfigs = append(s.nodeConfigs, nodeOpts) + + node.Peer = p + + c, err := setupClient(s, node) + require.NoError(s.t, err) + + eventState, err := newEventState(c.Events()) + require.NoError(s.t, err) + + s.nodes = append(s.nodes, c) + s.nodeEvents = append(s.nodeEvents, eventState) + s.nodeP2P = append(s.nodeP2P, newP2PState()) + s.dbPaths = append(s.dbPaths, path) +} + +func refreshDocuments( + s *state, + startActionIndex int, +) { + if len(s.collections) == 0 { + // This should only be possible at the moment for P2P testing, for which the + // change detector is currently disabled. We'll likely need some fancier logic + // here if/when we wish to enable it. + return + } + + // For now just do the initial setup using the collections on the first node, + // this may need to become more involved at a later date depending on testing + // requirements. + s.docIDs = make([][]client.DocID, len(s.collections[0])) + + for i := range s.collections[0] { + s.docIDs[i] = []client.DocID{} + } + + for i := 0; i < startActionIndex; i++ { + // We need to add the existing documents in the order in which the test case lists them + // otherwise they cannot be referenced correctly by other actions. + switch action := s.testCase.Actions[i].(type) { + case CreateDoc: + // Just use the collection from the first relevant node, as all will be the same for this + // purpose. + collection := getNodeCollections(action.NodeID, s.collections)[0][action.CollectionID] + + if action.DocMap != nil { + substituteRelations(s, action) + } + docs, err := parseCreateDocs(action, collection) + if err != nil { + // If an err has been returned, ignore it - it may be expected and if not + // the test will fail later anyway + continue + } + + for _, doc := range docs { + s.docIDs[action.CollectionID] = append(s.docIDs[action.CollectionID], doc.ID()) + } + } + } +} + +func refreshIndexes( + s *state, +) { + if len(s.collections) == 0 { + return + } + + s.indexes = make([][][]client.IndexDescription, len(s.collections)) + + for i, nodeCols := range s.collections { + s.indexes[i] = make([][]client.IndexDescription, len(nodeCols)) + + for j, col := range nodeCols { + if col == nil { + continue + } + colIndexes, err := col.GetIndexes(s.ctx) + if err != nil { + continue + } + + s.indexes[i][j] = colIndexes + } + } +} + +func getIndexes( + s *state, + action GetIndexes, +) { + if len(s.collections) == 0 { + return + } + + var expectedErrorRaised bool + actionNodes := getNodes(action.NodeID, s.nodes) + for nodeID, collections := range getNodeCollections(action.NodeID, s.collections) { + err := withRetry( + actionNodes, + nodeID, + func() error { + actualIndexes, err := collections[action.CollectionID].GetIndexes(s.ctx) + if err != nil { + return err + } + + assertIndexesListsEqual(action.ExpectedIndexes, + actualIndexes, s.t, s.testCase.Description) + + return nil + }, + ) + expectedErrorRaised = expectedErrorRaised || + AssertError(s.t, s.testCase.Description, err, action.ExpectedError) + } + + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) +} + +func assertIndexesListsEqual( + expectedIndexes []client.IndexDescription, + actualIndexes []client.IndexDescription, + t testing.TB, + testDescription string, +) { + toNames := func(indexes []client.IndexDescription) []string { + names := make([]string, len(indexes)) + for i, index := range indexes { + names[i] = index.Name + } + return names + } + + require.ElementsMatch(t, toNames(expectedIndexes), toNames(actualIndexes), testDescription) + + toMap := func(indexes []client.IndexDescription) map[string]client.IndexDescription { + resultMap := map[string]client.IndexDescription{} + for _, index := range indexes { + resultMap[index.Name] = index + } + return resultMap + } + + expectedMap := toMap(expectedIndexes) + actualMap := toMap(actualIndexes) + for key := range expectedMap { + assertIndexesEqual(expectedMap[key], actualMap[key], t, testDescription) + } +} + +func assertIndexesEqual(expectedIndex, actualIndex client.IndexDescription, + t testing.TB, + testDescription string, +) { + assert.Equal(t, expectedIndex.Name, actualIndex.Name, testDescription) + assert.Equal(t, expectedIndex.ID, actualIndex.ID, testDescription) + + toNames := func(fields []client.IndexedFieldDescription) []string { + names := make([]string, len(fields)) + for i, field := range fields { + names[i] = field.Name + } + return names + } + + require.ElementsMatch(t, toNames(expectedIndex.Fields), toNames(actualIndex.Fields), testDescription) + + toMap := func(fields []client.IndexedFieldDescription) map[string]client.IndexedFieldDescription { + resultMap := map[string]client.IndexedFieldDescription{} + for _, field := range fields { + resultMap[field.Name] = field + } + return resultMap + } + + expectedMap := toMap(expectedIndex.Fields) + actualMap := toMap(actualIndex.Fields) + for key := range expectedMap { + assert.Equal(t, expectedMap[key], actualMap[key], testDescription) + } +} + +// updateSchema updates the schema using the given details. +func updateSchema( + s *state, + action SchemaUpdate, +) { + for _, node := range getNodes(action.NodeID, s.nodes) { + results, err := node.AddSchema(s.ctx, action.Schema) + expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) + + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) + + if action.ExpectedResults != nil { + assertCollectionDescriptions(s, action.ExpectedResults, results) + } + } + + // If the schema was updated we need to refresh the collection definitions. + refreshCollections(s) + refreshIndexes(s) +} + +func patchSchema( + s *state, + action SchemaPatch, +) { + for _, node := range getNodes(action.NodeID, s.nodes) { + var setAsDefaultVersion bool + if action.SetAsDefaultVersion.HasValue() { + setAsDefaultVersion = action.SetAsDefaultVersion.Value() + } else { + setAsDefaultVersion = true + } + + err := node.PatchSchema(s.ctx, action.Patch, action.Lens, setAsDefaultVersion) + expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) + + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) + } + + // If the schema was updated we need to refresh the collection definitions. + refreshCollections(s) + refreshIndexes(s) +} + +func patchCollection( + s *state, + action PatchCollection, +) { + for _, node := range getNodes(action.NodeID, s.nodes) { + err := node.PatchCollection(s.ctx, action.Patch) + expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) + + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) + } + + // If the schema was updated we need to refresh the collection definitions. + refreshCollections(s) + refreshIndexes(s) +} + +func getSchema( + s *state, + action GetSchema, +) { + for _, node := range getNodes(action.NodeID, s.nodes) { + var results []client.SchemaDescription + var err error + switch { + case action.VersionID.HasValue(): + result, e := node.GetSchemaByVersionID(s.ctx, action.VersionID.Value()) + err = e + results = []client.SchemaDescription{result} + default: + results, err = node.GetSchemas( + s.ctx, + client.SchemaFetchOptions{ + Root: action.Root, + Name: action.Name, + }, + ) + } + + expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) + + if !expectedErrorRaised { + require.Equal(s.t, action.ExpectedResults, results) + } + } +} + +func getCollections( + s *state, + action GetCollections, +) { + for _, node := range getNodes(action.NodeID, s.nodes) { + txn := getTransaction(s, node, action.TransactionID, "") + ctx := db.SetContextTxn(s.ctx, txn) + results, err := node.GetCollections(ctx, action.FilterOptions) + resultDescriptions := make([]client.CollectionDescription, len(results)) + for i, col := range results { + resultDescriptions[i] = col.Description() + } + + expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) + + if !expectedErrorRaised { + assertCollectionDescriptions(s, action.ExpectedResults, resultDescriptions) + } + } +} + +func setActiveSchemaVersion( + s *state, + action SetActiveSchemaVersion, +) { + for _, node := range getNodes(action.NodeID, s.nodes) { + err := node.SetActiveSchemaVersion(s.ctx, action.SchemaVersionID) + expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) + + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) + } + + refreshCollections(s) + refreshIndexes(s) +} + +func createView( + s *state, + action CreateView, +) { + for _, node := range getNodes(action.NodeID, s.nodes) { + _, err := node.AddView(s.ctx, action.Query, action.SDL, action.Transform) + expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) + + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) + } +} + +// createDoc creates a document using the chosen [mutationType] and caches it in the +// test state object. +func createDoc( + s *state, + action CreateDoc, +) { + if action.DocMap != nil { + substituteRelations(s, action) + } + + var mutation func(*state, CreateDoc, client.DB, int, client.Collection) ([]client.DocID, error) + switch mutationType { + case CollectionSaveMutationType: + mutation = createDocViaColSave + case CollectionNamedMutationType: + mutation = createDocViaColCreate + case GQLRequestMutationType: + mutation = createDocViaGQL + default: + s.t.Fatalf("invalid mutationType: %v", mutationType) + } + + var expectedErrorRaised bool + var docIDs []client.DocID + actionNodes := getNodes(action.NodeID, s.nodes) + for nodeID, collections := range getNodeCollections(action.NodeID, s.collections) { + err := withRetry( + actionNodes, + nodeID, + func() error { + var err error + docIDs, err = mutation(s, action, actionNodes[nodeID], nodeID, collections[action.CollectionID]) + return err + }, + ) + expectedErrorRaised = AssertError(s.t, s.testCase.Description, err, action.ExpectedError) + } + + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) + + if action.CollectionID >= len(s.docIDs) { + // Expand the slice if required, so that the document can be accessed by collection index + s.docIDs = append(s.docIDs, make([][]client.DocID, action.CollectionID-len(s.docIDs)+1)...) + } + s.docIDs[action.CollectionID] = append(s.docIDs[action.CollectionID], docIDs...) + + if action.ExpectedError == "" { + waitForUpdateEvents(s, action.NodeID, getEventsForCreateDoc(s, action)) + } +} + +func createDocViaColSave( + s *state, + action CreateDoc, + node client.DB, + nodeIndex int, + collection client.Collection, +) ([]client.DocID, error) { + docs, err := parseCreateDocs(action, collection) + if err != nil { + return nil, err + } + + txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) + ctx := makeContextForDocCreate(s, db.SetContextTxn(s.ctx, txn), nodeIndex, &action) + + docIDs := make([]client.DocID, len(docs)) + for i, doc := range docs { + err := collection.Save(ctx, doc) + if err != nil { + return nil, err + } + docIDs[i] = doc.ID() + } + return docIDs, nil +} + +func makeContextForDocCreate(s *state, ctx context.Context, nodeIndex int, action *CreateDoc) context.Context { + identity := getIdentity(s, nodeIndex, action.Identity) + ctx = db.SetContextIdentity(ctx, identity) + ctx = encryption.SetContextConfigFromParams(ctx, action.IsDocEncrypted, action.EncryptedFields) + return ctx +} + +func createDocViaColCreate( + s *state, + action CreateDoc, + node client.DB, + nodeIndex int, + collection client.Collection, +) ([]client.DocID, error) { + docs, err := parseCreateDocs(action, collection) + if err != nil { + return nil, err + } + + txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) + ctx := makeContextForDocCreate(s, db.SetContextTxn(s.ctx, txn), nodeIndex, &action) + + switch { + case len(docs) > 1: + err := collection.CreateMany(ctx, docs) + if err != nil { + return nil, err + } + + default: + err := collection.Create(ctx, docs[0]) + if err != nil { + return nil, err + } + } + + docIDs := make([]client.DocID, len(docs)) + for i, doc := range docs { + docIDs[i] = doc.ID() + } + return docIDs, nil +} + +func createDocViaGQL( + s *state, + action CreateDoc, + node client.DB, + nodeIndex int, + collection client.Collection, +) ([]client.DocID, error) { + var input string + + paramName := request.Input + + var err error + if action.DocMap != nil { + input, err = valueToGQL(action.DocMap) + } else if client.IsJSONArray([]byte(action.Doc)) { + var docMaps []map[string]any + err = json.Unmarshal([]byte(action.Doc), &docMaps) + require.NoError(s.t, err) + paramName = request.Inputs + input, err = arrayToGQL(docMaps) + } else { + input, err = jsonToGQL(action.Doc) + } + require.NoError(s.t, err) + + params := paramName + ": " + input + + if action.IsDocEncrypted { + params = params + ", " + request.EncryptDocArgName + ": true" + } + if len(action.EncryptedFields) > 0 { + params = params + ", " + request.EncryptFieldsArgName + ": [" + + strings.Join(action.EncryptedFields, ", ") + "]" + } + + key := fmt.Sprintf("create_%s", collection.Name().Value()) + req := fmt.Sprintf(`mutation { %s(%s) { _docID } }`, key, params) - // docs is a map from Collection Index, to a list - // of docs in stringified JSON format - Docs map[int][]string + txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) + ctx := db.SetContextIdentity(db.SetContextTxn(s.ctx, txn), getIdentity(s, nodeIndex, action.Identity)) - Results map[string]any + result := node.ExecRequest(ctx, req) + if len(result.GQL.Errors) > 0 { + return nil, result.GQL.Errors[0] + } + + resultData := result.GQL.Data.(map[string]any) + resultDocs := ConvertToArrayOfMaps(s.t, resultData[key]) + + docIDs := make([]client.DocID, len(resultDocs)) + for i, docMap := range resultDocs { + docIDString := docMap[request.DocIDFieldName].(string) + docID, err := client.NewDocIDFromString(docIDString) + require.NoError(s.t, err) + docIDs[i] = docID + } - // The expected content of an expected error - ExpectedError string + return docIDs, nil } -func ExecuteRequestTestCase( - t *testing.T, - schema string, - collectionNames []string, - test RequestTestCase, +// substituteRelations scans the fields defined in [action.DocMap], if any are of type [DocIndex] +// it will substitute the [DocIndex] for the the corresponding document ID found in the state. +// +// If a document at that index is not found it will panic. +func substituteRelations( + s *state, + action CreateDoc, +) { + for k, v := range action.DocMap { + index, isIndex := v.(DocIndex) + if !isIndex { + continue + } + + docID := s.docIDs[index.CollectionIndex][index.Index] + action.DocMap[k] = docID.String() + } +} + +// deleteDoc deletes a document using the collection api and caches it in the +// given documents slice. +func deleteDoc( + s *state, + action DeleteDoc, +) { + docID := s.docIDs[action.CollectionID][action.DocID] + + var expectedErrorRaised bool + actionNodes := getNodes(action.NodeID, s.nodes) + for nodeID, collections := range getNodeCollections(action.NodeID, s.collections) { + identity := getIdentity(s, nodeID, action.Identity) + ctx := db.SetContextIdentity(s.ctx, identity) + + err := withRetry( + actionNodes, + nodeID, + func() error { + _, err := collections[action.CollectionID].Delete(ctx, docID) + return err + }, + ) + expectedErrorRaised = AssertError(s.t, s.testCase.Description, err, action.ExpectedError) + } + + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) + + if action.ExpectedError == "" { + docIDs := map[string]struct{}{ + docID.String(): {}, + } + waitForUpdateEvents(s, action.NodeID, docIDs) + } +} + +// updateDoc updates a document using the chosen [mutationType]. +func updateDoc( + s *state, + action UpdateDoc, ) { - actions := []any{ - SchemaUpdate{ - Schema: schema, - }, + var mutation func(*state, UpdateDoc, client.DB, int, client.Collection) error + switch mutationType { + case CollectionSaveMutationType: + mutation = updateDocViaColSave + case CollectionNamedMutationType: + mutation = updateDocViaColUpdate + case GQLRequestMutationType: + mutation = updateDocViaGQL + default: + s.t.Fatalf("invalid mutationType: %v", mutationType) + } + + var expectedErrorRaised bool + actionNodes := getNodes(action.NodeID, s.nodes) + for nodeID, collections := range getNodeCollections(action.NodeID, s.collections) { + err := withRetry( + actionNodes, + nodeID, + func() error { + return mutation(s, action, actionNodes[nodeID], nodeID, collections[action.CollectionID]) + }, + ) + expectedErrorRaised = AssertError(s.t, s.testCase.Description, err, action.ExpectedError) + } + + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) + + if action.ExpectedError == "" && !action.SkipLocalUpdateEvent { + waitForUpdateEvents(s, action.NodeID, getEventsForUpdateDoc(s, action)) + } +} + +func updateDocViaColSave( + s *state, + action UpdateDoc, + node client.DB, + nodeIndex int, + collection client.Collection, +) error { + identity := getIdentity(s, nodeIndex, action.Identity) + ctx := db.SetContextIdentity(s.ctx, identity) + + doc, err := collection.Get(ctx, s.docIDs[action.CollectionID][action.DocID], true) + if err != nil { + return err + } + err = doc.SetWithJSON([]byte(action.Doc)) + if err != nil { + return err + } + return collection.Save(ctx, doc) +} + +func updateDocViaColUpdate( + s *state, + action UpdateDoc, + node client.DB, + nodeIndex int, + collection client.Collection, +) error { + identity := getIdentity(s, nodeIndex, action.Identity) + ctx := db.SetContextIdentity(s.ctx, identity) + + doc, err := collection.Get(ctx, s.docIDs[action.CollectionID][action.DocID], true) + if err != nil { + return err + } + err = doc.SetWithJSON([]byte(action.Doc)) + if err != nil { + return err + } + return collection.Update(ctx, doc) +} + +func updateDocViaGQL( + s *state, + action UpdateDoc, + node client.DB, + nodeIndex int, + collection client.Collection, +) error { + docID := s.docIDs[action.CollectionID][action.DocID] + + input, err := jsonToGQL(action.Doc) + require.NoError(s.t, err) + + request := fmt.Sprintf( + `mutation { + update_%s(docID: "%s", input: %s) { + _docID + } + }`, + collection.Name().Value(), + docID.String(), + input, + ) + + identity := getIdentity(s, nodeIndex, action.Identity) + ctx := db.SetContextIdentity(s.ctx, identity) + + result := node.ExecRequest(ctx, request) + if len(result.GQL.Errors) > 0 { + return result.GQL.Errors[0] + } + return nil +} + +// updateWithFilter updates the set of matched documents. +func updateWithFilter(s *state, action UpdateWithFilter) { + var res *client.UpdateResult + var expectedErrorRaised bool + actionNodes := getNodes(action.NodeID, s.nodes) + for nodeID, collections := range getNodeCollections(action.NodeID, s.collections) { + identity := getIdentity(s, nodeID, action.Identity) + ctx := db.SetContextIdentity(s.ctx, identity) + + err := withRetry( + actionNodes, + nodeID, + func() error { + var err error + res, err = collections[action.CollectionID].UpdateWithFilter(ctx, action.Filter, action.Updater) + return err + }, + ) + expectedErrorRaised = AssertError(s.t, s.testCase.Description, err, action.ExpectedError) + } + + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) + + if action.ExpectedError == "" && !action.SkipLocalUpdateEvent { + waitForUpdateEvents(s, action.NodeID, getEventsForUpdateWithFilter(s, action, res)) } +} - for collectionIndex, docs := range test.Docs { - for _, doc := range docs { - actions = append( - actions, - CreateDoc{ - CollectionID: collectionIndex, - Doc: doc, +// createIndex creates a secondary index using the collection api. +func createIndex( + s *state, + action CreateIndex, +) { + if action.CollectionID >= len(s.indexes) { + // Expand the slice if required, so that the index can be accessed by collection index + s.indexes = append(s.indexes, + make([][][]client.IndexDescription, action.CollectionID-len(s.indexes)+1)...) + } + actionNodes := getNodes(action.NodeID, s.nodes) + for nodeID, collections := range getNodeCollections(action.NodeID, s.collections) { + indexDesc := client.IndexDescription{ + Name: action.IndexName, + } + if action.FieldName != "" { + indexDesc.Fields = []client.IndexedFieldDescription{ + { + Name: action.FieldName, }, - ) + } + } else if len(action.Fields) > 0 { + for i := range action.Fields { + indexDesc.Fields = append(indexDesc.Fields, client.IndexedFieldDescription{ + Name: action.Fields[i].Name, + Descending: action.Fields[i].Descending, + }) + } + } + indexDesc.Unique = action.Unique + err := withRetry( + actionNodes, + nodeID, + func() error { + desc, err := collections[action.CollectionID].CreateIndex(s.ctx, indexDesc) + if err != nil { + return err + } + s.indexes[nodeID][action.CollectionID] = + append(s.indexes[nodeID][action.CollectionID], desc) + return nil + }, + ) + if AssertError(s.t, s.testCase.Description, err, action.ExpectedError) { + return } } - if test.Request != "" { - actions = append( - actions, - Request{ - ExpectedError: test.ExpectedError, - Request: test.Request, - Results: test.Results, + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, false) +} + +// dropIndex drops the secondary index using the collection api. +func dropIndex( + s *state, + action DropIndex, +) { + var expectedErrorRaised bool + actionNodes := getNodes(action.NodeID, s.nodes) + for nodeID, collections := range getNodeCollections(action.NodeID, s.collections) { + indexName := action.IndexName + if indexName == "" { + indexName = s.indexes[nodeID][action.CollectionID][action.IndexID].Name + } + + err := withRetry( + actionNodes, + nodeID, + func() error { + return collections[action.CollectionID].DropIndex(s.ctx, indexName) }, ) + expectedErrorRaised = AssertError(s.t, s.testCase.Description, err, action.ExpectedError) + } + + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) +} + +// backupExport generates a backup using the db api. +func backupExport( + s *state, + action BackupExport, +) { + if action.Config.Filepath == "" { + action.Config.Filepath = s.t.TempDir() + testJSONFile + } + + var expectedErrorRaised bool + actionNodes := getNodes(action.NodeID, s.nodes) + for nodeID, node := range actionNodes { + err := withRetry( + actionNodes, + nodeID, + func() error { return node.BasicExport(s.ctx, &action.Config) }, + ) + expectedErrorRaised = AssertError(s.t, s.testCase.Description, err, action.ExpectedError) + + if !expectedErrorRaised { + assertBackupContent(s.t, action.ExpectedContent, action.Config.Filepath) + } + } + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) +} + +// backupImport imports data from a backup using the db api. +func backupImport( + s *state, + action BackupImport, +) { + if action.Filepath == "" { + action.Filepath = s.t.TempDir() + testJSONFile + } + + // we can avoid checking the error here as this would mean the filepath is invalid + // and we want to make sure that `BasicImport` fails in this case. + _ = os.WriteFile(action.Filepath, []byte(action.ImportContent), 0664) + + var expectedErrorRaised bool + actionNodes := getNodes(action.NodeID, s.nodes) + for nodeID, node := range actionNodes { + err := withRetry( + actionNodes, + nodeID, + func() error { return node.BasicImport(s.ctx, action.Filepath) }, + ) + expectedErrorRaised = AssertError(s.t, s.testCase.Description, err, action.ExpectedError) + } + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) +} + +// withRetry attempts to perform the given action, retrying up to a DB-defined +// maximum attempt count if a transaction conflict error is returned. +// +// If a P2P-sync commit for the given document is already in progress this +// Save call can fail as the transaction will conflict. We dont want to worry +// about this in our tests so we just retry a few times until it works (or the +// retry limit is breached - important incase this is a different error) +func withRetry( + nodes []clients.Client, + nodeID int, + action func() error, +) error { + for i := 0; i < nodes[nodeID].MaxTxnRetries(); i++ { + err := action() + if errors.Is(err, datastore.ErrTxnConflict) { + time.Sleep(100 * time.Millisecond) + continue + } + return err + } + return nil +} + +func getTransaction( + s *state, + db client.DB, + transactionSpecifier immutable.Option[int], + expectedError string, +) datastore.Txn { + if !transactionSpecifier.HasValue() { + return nil + } + + transactionID := transactionSpecifier.Value() + + if transactionID >= len(s.txns) { + // Extend the txn slice so this txn can fit and be accessed by TransactionId + s.txns = append(s.txns, make([]datastore.Txn, transactionID-len(s.txns)+1)...) + } + + if s.txns[transactionID] == nil { + // Create a new transaction if one does not already exist. + txn, err := db.NewTxn(s.ctx, false) + if AssertError(s.t, s.testCase.Description, err, expectedError) { + txn.Discard(s.ctx) + return nil + } + + s.txns[transactionID] = txn + } + + return s.txns[transactionID] +} + +// commitTransaction commits the given transaction. +// +// Will panic if the given transaction does not exist. Discards the transaction if +// an error is returned on commit. +func commitTransaction( + s *state, + action TransactionCommit, +) { + err := s.txns[action.TransactionID].Commit(s.ctx) + if err != nil { + s.txns[action.TransactionID].Discard(s.ctx) + } + + expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) + + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) +} + +// executeRequest executes the given request. +func executeRequest( + s *state, + action Request, +) { + var expectedErrorRaised bool + for nodeID, node := range getNodes(action.NodeID, s.nodes) { + txn := getTransaction(s, node, action.TransactionID, action.ExpectedError) + + ctx := db.SetContextTxn(s.ctx, txn) + identity := getIdentity(s, nodeID, action.Identity) + ctx = db.SetContextIdentity(ctx, identity) + + result := node.ExecRequest(ctx, action.Request) + + anyOfByFieldKey := map[docFieldKey][]any{} + expectedErrorRaised = assertRequestResults( + s, + &result.GQL, + action.Results, + action.ExpectedError, + action.Asserter, + nodeID, + anyOfByFieldKey, + ) + } + + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) +} + +// executeSubscriptionRequest executes the given subscription request, returning +// a channel that will receive a single event once the subscription has been completed. +// +// The returned channel will receive a function that asserts that +// the subscription received all its expected results and no more. +// It should be called from the main test routine to ensure that +// failures are recorded properly. It will only yield once, once +// the subscription has terminated. +func executeSubscriptionRequest( + s *state, + action SubscriptionRequest, +) { + subscriptionAssert := make(chan func()) + + for _, node := range getNodes(action.NodeID, s.nodes) { + result := node.ExecRequest(s.ctx, action.Request) + if AssertErrors(s.t, s.testCase.Description, result.GQL.Errors, action.ExpectedError) { + return + } + + go func() { + var results []*client.GQLResult + allActionsAreDone := false + for !allActionsAreDone || len(results) < len(action.Results) { + select { + case s := <-result.Subscription: + results = append(results, &s) + + case <-s.allActionsDone: + allActionsAreDone = true + } + } + + subscriptionAssert <- func() { + for i, r := range action.Results { + // This assert should be executed from the main test routine + // so that failures will be properly handled. + expectedErrorRaised := assertRequestResults( + s, + results[i], + r, + action.ExpectedError, + nil, + // anyof is not yet supported by subscription requests + 0, + map[docFieldKey][]any{}, + ) + + assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) + } + } + }() + } + + s.subscriptionResultsChans = append(s.subscriptionResultsChans, subscriptionAssert) +} + +// Asserts as to whether an error has been raised as expected (or not). If an expected +// error has been raised it will return true, returns false in all other cases. +func AssertError(t testing.TB, description string, err error, expectedError string) bool { + if err == nil { + return false + } + + if expectedError == "" { + require.NoError(t, err, description) + return false + } else { + if !strings.Contains(err.Error(), expectedError) { + // Must be require instead of assert, otherwise will show a fake "error not raised". + require.ErrorIs(t, err, errors.New(expectedError)) + return false + } + return true + } +} + +// Asserts as to whether an error has been raised as expected (or not). If an expected +// error has been raised it will return true, returns false in all other cases. +func AssertErrors( + t testing.TB, + description string, + errs []error, + expectedError string, +) bool { + if expectedError == "" { + require.Empty(t, errs, description) + } else { + for _, e := range errs { + // This is always a string at the moment, add support for other types as and when needed + errorString := e.Error() + if !strings.Contains(errorString, expectedError) { + // We use ErrorIs for clearer failures (is a error comparison even if it is just a string) + require.ErrorIs(t, errors.New(errorString), errors.New(expectedError)) + continue + } + return true + } + } + return false +} + +// docFieldKey is an internal key type that wraps docIndex and fieldName +type docFieldKey struct { + docIndex int + fieldName string +} + +func assertRequestResults( + s *state, + result *client.GQLResult, + expectedResults map[string]any, + expectedError string, + asserter ResultAsserter, + nodeID int, + anyOfByField map[docFieldKey][]any, +) bool { + // we skip assertion benchmark because you don't specify expected result for benchmark. + if AssertErrors(s.t, s.testCase.Description, result.Errors, expectedError) || s.isBench { + return true + } + + if expectedResults == nil && result.Data == nil { + return true + } + + // Note: if result.Data == nil this panics (the panic seems useful while testing). + resultantData := result.Data.(map[string]any) + log.InfoContext(s.ctx, "", corelog.Any("RequestResults", result.Data)) + + if asserter != nil { + asserter.Assert(s.t, resultantData) + return true + } + + // merge all keys so we can check for missing values + keys := make(map[string]struct{}) + for key := range resultantData { + keys[key] = struct{}{} + } + for key := range expectedResults { + keys[key] = struct{}{} + } + + for key := range keys { + expect, ok := expectedResults[key] + require.True(s.t, ok, "expected key not found: %s", key) + + actual, ok := resultantData[key] + require.True(s.t, ok, "result key not found: %s", key) + + expectDocs, ok := expect.([]map[string]any) + if ok { + actualDocs := ConvertToArrayOfMaps(s.t, actual) + assertRequestResultDocs( + s, + nodeID, + expectDocs, + actualDocs, + anyOfByField) + } else { + assertResultsEqual( + s.t, + s.clientType, + expect, + actual, + fmt.Sprintf("node: %v, key: %v", nodeID, key), + ) + } + } + + return false +} + +func assertRequestResultDocs( + s *state, + nodeID int, + expectedResults []map[string]any, + actualResults []map[string]any, + anyOfByField map[docFieldKey][]any, +) bool { + // compare results + require.Equal(s.t, len(expectedResults), len(actualResults), + s.testCase.Description+" \n(number of results don't match)") + + for actualDocIndex, actualDoc := range actualResults { + expectedDoc := expectedResults[actualDocIndex] + + require.Equal( + s.t, + len(expectedDoc), + len(actualDoc), + fmt.Sprintf( + "%s \n(number of properties for item at index %v don't match)", + s.testCase.Description, + actualDocIndex, + ), + ) + + for field, actualValue := range actualDoc { + switch expectedValue := expectedDoc[field].(type) { + case AnyOf: + assertResultsAnyOf(s.t, s.clientType, expectedValue, actualValue) + + dfk := docFieldKey{actualDocIndex, field} + valueSet := anyOfByField[dfk] + valueSet = append(valueSet, actualValue) + anyOfByField[dfk] = valueSet + case DocIndex: + expectedDocID := s.docIDs[expectedValue.CollectionIndex][expectedValue.Index].String() + assertResultsEqual( + s.t, + s.clientType, + expectedDocID, + actualValue, + fmt.Sprintf("node: %v, doc: %v", nodeID, actualDocIndex), + ) + case []map[string]any: + actualValueMap := ConvertToArrayOfMaps(s.t, actualValue) + + assertRequestResultDocs( + s, + nodeID, + expectedValue, + actualValueMap, + anyOfByField, + ) + + default: + assertResultsEqual( + s.t, + s.clientType, + expectedValue, + actualValue, + fmt.Sprintf("node: %v, doc: %v", nodeID, actualDocIndex), + ) + } + } + } + + return false +} + +func ConvertToArrayOfMaps(t testing.TB, value any) []map[string]any { + valueArrayMap, ok := value.([]map[string]any) + if ok { + return valueArrayMap + } + valueArray, ok := value.([]any) + require.True(t, ok, "expected value to be an array of maps %v", value) + + valueArrayMap = make([]map[string]any, len(valueArray)) + for i, v := range valueArray { + valueArrayMap[i], ok = v.(map[string]any) + require.True(t, ok, "expected value to be an array of maps %v", value) + } + return valueArrayMap +} + +func assertExpectedErrorRaised(t testing.TB, description string, expectedError string, wasRaised bool) { + if expectedError != "" && !wasRaised { + assert.Fail(t, "Expected an error however none was raised.", description) + } +} + +func assertIntrospectionResults( + s *state, + action IntrospectionRequest, +) bool { + for _, node := range getNodes(action.NodeID, s.nodes) { + result := node.ExecRequest(s.ctx, action.Request) + + if AssertErrors(s.t, s.testCase.Description, result.GQL.Errors, action.ExpectedError) { + return true + } + resultantData := result.GQL.Data.(map[string]any) + + if len(action.ExpectedData) == 0 && len(action.ContainsData) == 0 { + require.Equal(s.t, action.ExpectedData, resultantData) + } + + if len(action.ExpectedData) == 0 && len(action.ContainsData) > 0 { + assertContains(s.t, action.ContainsData, resultantData) + } else { + require.Equal(s.t, len(action.ExpectedData), len(resultantData)) + + for k, result := range resultantData { + assert.Equal(s.t, action.ExpectedData[k], result) + } + } + } + + return false +} + +// Asserts that the client introspection results conform to our expectations. +func assertClientIntrospectionResults( + s *state, + action ClientIntrospectionRequest, +) bool { + for _, node := range getNodes(action.NodeID, s.nodes) { + result := node.ExecRequest(s.ctx, action.Request) + + if AssertErrors(s.t, s.testCase.Description, result.GQL.Errors, action.ExpectedError) { + return true + } + resultantData := result.GQL.Data.(map[string]any) + + if len(resultantData) == 0 { + return false + } + + // Iterate through all types, validating each type definition. + // Inspired from buildClientSchema.ts from graphql-js, + // which is one way that clients do validate the schema. + types := resultantData["__schema"].(map[string]any)["types"].([]any) + + for _, typeData := range types { + typeDef := typeData.(map[string]any) + kind := typeDef["kind"].(string) + + switch kind { + case "SCALAR", "INTERFACE", "UNION", "ENUM": + // No validation for these types in this test + case "OBJECT": + fields := typeDef["fields"] + if fields == nil { + s.t.Errorf("Fields are missing for OBJECT type %v", typeDef["name"]) + } + case "INPUT_OBJECT": + inputFields := typeDef["inputFields"] + if inputFields == nil { + s.t.Errorf("InputFields are missing for INPUT_OBJECT type %v", typeDef["name"]) + } + default: + // t.Errorf("Unknown type kind: %v", kind) + } + } + } + + return true +} + +// Asserts that the `actual` contains the given `contains` value according to the logic +// described on the [RequestTestCase.ContainsData] property. +func assertContains(t testing.TB, contains map[string]any, actual map[string]any) { + for k, expected := range contains { + innerActual := actual[k] + if innerExpected, innerIsMap := expected.(map[string]any); innerIsMap { + if innerActual == nil { + assert.Equal(t, innerExpected, innerActual) + } else if innerActualMap, isMap := innerActual.(map[string]any); isMap { + // If the inner is another map then we continue down the chain + assertContains(t, innerExpected, innerActualMap) + } else { + // If the types don't match then we use assert.Equal for a clean failure message + assert.Equal(t, innerExpected, innerActual) + } + } else if innerExpected, innerIsArray := expected.([]any); innerIsArray { + if actualArray, isActualArray := innerActual.([]any); isActualArray { + // If the inner is an array/slice, then assert that each expected item is present + // in the actual. Note how the actual may contain additional items - this should + // not result in a test failure. + for _, innerExpectedItem := range innerExpected { + assert.Contains(t, actualArray, innerExpectedItem) + } + } else { + // If the types don't match then we use assert.Equal for a clean failure message + assert.Equal(t, expected, innerActual) + } + } else { + assert.Equal(t, expected, innerActual) + } } +} - ExecuteTestCase( +func assertBackupContent(t testing.TB, expectedContent, filepath string) { + b, err := os.ReadFile(filepath) + assert.NoError(t, err) + assert.Equal( t, - TestCase{ - Description: test.Description, - Actions: actions, - }, + expectedContent, + string(b), ) } + +// skipIfMutationTypeUnsupported skips the current test if the given supportedMutationTypes option has value +// and the active mutation type is not contained within that value set. +func skipIfMutationTypeUnsupported(t testing.TB, supportedMutationTypes immutable.Option[[]MutationType]) { + if supportedMutationTypes.HasValue() { + var isTypeSupported bool + for _, supportedMutationType := range supportedMutationTypes.Value() { + if supportedMutationType == mutationType { + isTypeSupported = true + break + } + } + + if !isTypeSupported { + t.Skipf("test does not support given mutation type. Type: %s", mutationType) + } + } +} + +// skipIfClientTypeUnsupported returns a new set of client types that match the given supported set. +// +// If supportedClientTypes is none no filtering will take place and the input client set will be returned. +// If the resultant filtered set is empty the test will be skipped. +func skipIfClientTypeUnsupported( + t testing.TB, + clients []ClientType, + supportedClientTypes immutable.Option[[]ClientType], +) []ClientType { + if !supportedClientTypes.HasValue() { + return clients + } + + filteredClients := []ClientType{} + for _, supportedMutationType := range supportedClientTypes.Value() { + for _, client := range clients { + if supportedMutationType == client { + filteredClients = append(filteredClients, client) + break + } + } + } + + if len(filteredClients) == 0 { + t.Skipf("test does not support any given client type. Type: %v", supportedClientTypes) + } + + return filteredClients +} + +func skipIfACPTypeUnsupported(t testing.TB, supporteACPTypes immutable.Option[[]ACPType]) { + if supporteACPTypes.HasValue() { + var isTypeSupported bool + for _, supportedType := range supporteACPTypes.Value() { + if supportedType == acpType { + isTypeSupported = true + break + } + } + + if !isTypeSupported { + t.Skipf("test does not support given acp type. Type: %s", acpType) + } + } +} + +// skipIfNetworkTest skips the current test if the given actions +// contain network actions and skipNetworkTests is true. +func skipIfNetworkTest(t testing.TB, actions []any) { + hasNetworkAction := false + for _, act := range actions { + switch act.(type) { + case ConfigureNode: + hasNetworkAction = true + } + } + if skipNetworkTests && hasNetworkAction { + t.Skip("test involves network actions") + } +} + +func ParseSDL(gqlSDL string) (map[string]client.CollectionDefinition, error) { + parser, err := graphql.NewParser() + if err != nil { + return nil, err + } + cols, err := parser.ParseSDL(context.Background(), gqlSDL) + if err != nil { + return nil, err + } + result := make(map[string]client.CollectionDefinition) + for _, col := range cols { + result[col.Description.Name.Value()] = col + } + return result, nil +} + +func MustParseTime(timeString string) time.Time { + t, err := time.Parse(time.RFC3339, timeString) + if err != nil { + panic(err) + } + return t +} + +func CBORValue(value any) []byte { + enc, err := cbor.Marshal(value) + if err != nil { + panic(err) + } + return enc +} + +// parseCreateDocs parses and returns documents from a CreateDoc action. +func parseCreateDocs(action CreateDoc, collection client.Collection) ([]*client.Document, error) { + switch { + case action.DocMap != nil: + val, err := client.NewDocFromMap(action.DocMap, collection.Definition()) + if err != nil { + return nil, err + } + return []*client.Document{val}, nil + + case client.IsJSONArray([]byte(action.Doc)): + return client.NewDocsFromJSON([]byte(action.Doc), collection.Definition()) + + default: + val, err := client.NewDocFromJSON([]byte(action.Doc), collection.Definition()) + if err != nil { + return nil, err + } + return []*client.Document{val}, nil + } +} diff --git a/tests/integration/utils2.go b/tests/integration/utils2.go deleted file mode 100644 index f26ee4ed5b..0000000000 --- a/tests/integration/utils2.go +++ /dev/null @@ -1,2242 +0,0 @@ -// Copyright 2022 Democratized Data Foundation -// -// Use of this software is governed by the Business Source License -// included in the file licenses/BSL.txt. -// -// As of the Change Date specified in that file, in accordance with -// the Business Source License, use of this software will be governed -// by the Apache License, Version 2.0, included in the file -// licenses/APL.txt. - -package tests - -import ( - "context" - "encoding/json" - "fmt" - "os" - "reflect" - "strconv" - "strings" - "testing" - "time" - - "github.com/bxcodec/faker/support/slice" - "github.com/fxamacker/cbor/v2" - "github.com/sourcenetwork/corelog" - "github.com/sourcenetwork/immutable" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/sourcenetwork/defradb/client" - "github.com/sourcenetwork/defradb/client/request" - "github.com/sourcenetwork/defradb/crypto" - "github.com/sourcenetwork/defradb/datastore" - "github.com/sourcenetwork/defradb/errors" - "github.com/sourcenetwork/defradb/internal/db" - "github.com/sourcenetwork/defradb/internal/encryption" - "github.com/sourcenetwork/defradb/internal/request/graphql" - "github.com/sourcenetwork/defradb/net" - changeDetector "github.com/sourcenetwork/defradb/tests/change_detector" - "github.com/sourcenetwork/defradb/tests/clients" - "github.com/sourcenetwork/defradb/tests/gen" - "github.com/sourcenetwork/defradb/tests/predefined" -) - -const ( - mutationTypeEnvName = "DEFRA_MUTATION_TYPE" - skipNetworkTestsEnvName = "DEFRA_SKIP_NETWORK_TESTS" -) - -// The MutationType that tests will run using. -// -// For example if set to [CollectionSaveMutationType], all supporting -// actions (such as [UpdateDoc]) will execute via [Collection.Save]. -// -// Defaults to CollectionSaveMutationType. -type MutationType string - -const ( - // CollectionSaveMutationType will cause all supporting actions - // to run their mutations via [Collection.Save]. - CollectionSaveMutationType MutationType = "collection-save" - - // CollectionNamedMutationType will cause all supporting actions - // to run their mutations via their corresponding named [Collection] - // call. - // - // For example, CreateDoc will call [Collection.Create], and - // UpdateDoc will call [Collection.Update]. - CollectionNamedMutationType MutationType = "collection-named" - - // GQLRequestMutationType will cause all supporting actions to - // run their mutations using GQL requests, typically these will - // include a `id` parameter to target the specified document. - GQLRequestMutationType MutationType = "gql" -) - -var ( - log = corelog.NewLogger("tests.integration") - mutationType MutationType - // skipNetworkTests will skip any tests that involve network actions - skipNetworkTests = false -) - -const ( - // subscriptionTimeout is the maximum time to wait for subscription results to be returned. - subscriptionTimeout = 1 * time.Second - // Instantiating lenses is expensive, and our tests do not benefit from a large number of them, - // so we explicitly set it to a low value. - lensPoolSize = 2 -) - -const testJSONFile = "/test.json" - -func init() { - // We use environment variables instead of flags `go test ./...` throws for all packages - // that don't have the flag defined - if value, ok := os.LookupEnv(mutationTypeEnvName); ok { - mutationType = MutationType(value) - } else { - // Default to testing mutations via Collection.Save - it should be simpler and - // faster. We assume this is desirable when not explicitly testing any particular - // mutation type. - mutationType = CollectionSaveMutationType - } - if value, ok := os.LookupEnv(skipNetworkTestsEnvName); ok { - skipNetworkTests, _ = strconv.ParseBool(value) - } -} - -// AssertPanic asserts that the code inside the specified PanicTestFunc panics. -// -// This function is not supported by either the change detector, or the http-client. -// Calling this within either of them will result in the test being skipped. -// -// Usage: AssertPanic(t, func() { executeTestCase(t, test) }) -func AssertPanic(t *testing.T, f assert.PanicTestFunc) bool { - if changeDetector.Enabled { - // The `assert.Panics` call will falsely fail if this test is executed during - // a detect changes test run. - t.Skip("Assert panic with the change detector is not currently supported.") - } - - if httpClient || cliClient { - // The http / cli client will return an error instead of panicing at the moment. - t.Skip("Assert panic with the http client is not currently supported.") - } - - return assert.Panics(t, f, "expected a panic, but none found.") -} - -// ExecuteTestCase executes the given TestCase against the configured database -// instances. -// -// Will also attempt to detect incompatible changes in the persisted data if -// configured to do so (the CI will do so, but disabled by default as it is slow). -func ExecuteTestCase( - t testing.TB, - testCase TestCase, -) { - flattenActions(&testCase) - collectionNames := getCollectionNames(testCase) - changeDetector.PreTestChecks(t, collectionNames) - skipIfMutationTypeUnsupported(t, testCase.SupportedMutationTypes) - skipIfACPTypeUnsupported(t, testCase.SupportedACPTypes) - skipIfNetworkTest(t, testCase.Actions) - - var clients []ClientType - if httpClient { - clients = append(clients, HTTPClientType) - } - if goClient { - clients = append(clients, GoClientType) - } - if cliClient { - clients = append(clients, CLIClientType) - } - - var databases []DatabaseType - if badgerInMemory { - databases = append(databases, badgerIMType) - } - if badgerFile { - databases = append(databases, badgerFileType) - } - if inMemoryStore { - databases = append(databases, defraIMType) - } - - // Assert that these are not empty to protect against accidental mis-configurations, - // otherwise an empty set would silently pass all the tests. - require.NotEmpty(t, databases) - require.NotEmpty(t, clients) - - clients = skipIfClientTypeUnsupported(t, clients, testCase.SupportedClientTypes) - - ctx := context.Background() - for _, ct := range clients { - for _, dbt := range databases { - executeTestCase(ctx, t, collectionNames, testCase, dbt, ct) - } - } -} - -func executeTestCase( - ctx context.Context, - t testing.TB, - collectionNames []string, - testCase TestCase, - dbt DatabaseType, - clientType ClientType, -) { - log.InfoContext( - ctx, - testCase.Description, - corelog.Any("database", dbt), - corelog.Any("client", clientType), - corelog.Any("mutationType", mutationType), - corelog.String("databaseDir", databaseDir), - corelog.Bool("badgerEncryption", badgerEncryption), - corelog.Bool("skipNetworkTests", skipNetworkTests), - corelog.Bool("changeDetector.Enabled", changeDetector.Enabled), - corelog.Bool("changeDetector.SetupOnly", changeDetector.SetupOnly), - corelog.String("changeDetector.SourceBranch", changeDetector.SourceBranch), - corelog.String("changeDetector.TargetBranch", changeDetector.TargetBranch), - corelog.String("changeDetector.Repository", changeDetector.Repository), - ) - - startActionIndex, endActionIndex := getActionRange(t, testCase) - - s := newState(ctx, t, testCase, dbt, clientType, collectionNames) - setStartingNodes(s) - - // It is very important that the databases are always closed, otherwise resources will leak - // as tests run. This is particularly important for file based datastores. - defer closeNodes(s) - - // Documents and Collections may already exist in the database if actions have been split - // by the change detector so we should fetch them here at the start too (if they exist). - // collections are by node (index), as they are specific to nodes. - refreshCollections(s) - refreshDocuments(s, startActionIndex) - refreshIndexes(s) - - for i := startActionIndex; i <= endActionIndex; i++ { - performAction(s, i, testCase.Actions[i]) - } - - // Notify any active subscriptions that all requests have been sent. - close(s.allActionsDone) - - for _, resultsChan := range s.subscriptionResultsChans { - select { - case subscriptionAssert := <-resultsChan: - // We want to assert back in the main thread so failures get recorded properly - subscriptionAssert() - - // a safety in case the stream hangs - we don't want the tests to run forever. - case <-time.After(subscriptionTimeout): - assert.Fail(t, "timeout occurred while waiting for data stream", testCase.Description) - } - } -} - -func performAction( - s *state, - actionIndex int, - act any, -) { - switch action := act.(type) { - case ConfigureNode: - configureNode(s, action) - - case Restart: - restartNodes(s) - - case ConnectPeers: - connectPeers(s, action) - - case ConfigureReplicator: - configureReplicator(s, action) - - case DeleteReplicator: - deleteReplicator(s, action) - - case SubscribeToCollection: - subscribeToCollection(s, action) - - case UnsubscribeToCollection: - unsubscribeToCollection(s, action) - - case GetAllP2PCollections: - getAllP2PCollections(s, action) - - case SchemaUpdate: - updateSchema(s, action) - - case SchemaPatch: - patchSchema(s, action) - - case PatchCollection: - patchCollection(s, action) - - case GetSchema: - getSchema(s, action) - - case GetCollections: - getCollections(s, action) - - case SetActiveSchemaVersion: - setActiveSchemaVersion(s, action) - - case CreateView: - createView(s, action) - - case ConfigureMigration: - configureMigration(s, action) - - case AddPolicy: - addPolicyACP(s, action) - - case CreateDoc: - createDoc(s, action) - - case DeleteDoc: - deleteDoc(s, action) - - case UpdateDoc: - updateDoc(s, action) - - case UpdateWithFilter: - updateWithFilter(s, action) - - case CreateIndex: - createIndex(s, action) - - case DropIndex: - dropIndex(s, action) - - case GetIndexes: - getIndexes(s, action) - - case BackupExport: - backupExport(s, action) - - case BackupImport: - backupImport(s, action) - - case TransactionCommit: - commitTransaction(s, action) - - case SubscriptionRequest: - executeSubscriptionRequest(s, action) - - case Request: - executeRequest(s, action) - - case ExplainRequest: - executeExplainRequest(s, action) - - case IntrospectionRequest: - assertIntrospectionResults(s, action) - - case ClientIntrospectionRequest: - assertClientIntrospectionResults(s, action) - - case WaitForSync: - waitForMergeEvents(s) - - case Benchmark: - benchmarkAction(s, actionIndex, action) - - case GenerateDocs: - generateDocs(s, action) - - case CreatePredefinedDocs: - generatePredefinedDocs(s, action) - - case SetupComplete: - // no-op, just continue. - - default: - s.t.Fatalf("Unknown action type %T", action) - } -} - -func createGenerateDocs(s *state, docs []gen.GeneratedDoc, nodeID immutable.Option[int]) { - nameToInd := make(map[string]int) - for i, name := range s.collectionNames { - nameToInd[name] = i - } - for _, doc := range docs { - docJSON, err := doc.Doc.String() - if err != nil { - s.t.Fatalf("Failed to generate docs %s", err) - } - createDoc(s, CreateDoc{CollectionID: nameToInd[doc.Col.Description.Name.Value()], Doc: docJSON, NodeID: nodeID}) - } -} - -func generateDocs(s *state, action GenerateDocs) { - collections := getNodeCollections(action.NodeID, s.collections) - defs := make([]client.CollectionDefinition, 0, len(collections[0])) - for _, col := range collections[0] { - if len(action.ForCollections) == 0 || slice.Contains(action.ForCollections, col.Name().Value()) { - defs = append(defs, col.Definition()) - } - } - docs, err := gen.AutoGenerate(defs, action.Options...) - if err != nil { - s.t.Fatalf("Failed to generate docs %s", err) - } - createGenerateDocs(s, docs, action.NodeID) -} - -func generatePredefinedDocs(s *state, action CreatePredefinedDocs) { - collections := getNodeCollections(action.NodeID, s.collections) - defs := make([]client.CollectionDefinition, 0, len(collections[0])) - for _, col := range collections[0] { - defs = append(defs, col.Definition()) - } - docs, err := predefined.Create(defs, action.Docs) - if err != nil { - s.t.Fatalf("Failed to generate docs %s", err) - } - createGenerateDocs(s, docs, action.NodeID) -} - -func benchmarkAction( - s *state, - actionIndex int, - bench Benchmark, -) { - if s.dbt == defraIMType { - // Benchmarking makes no sense for test in-memory storage - return - } - if len(bench.FocusClients) > 0 { - isFound := false - for _, clientType := range bench.FocusClients { - if s.clientType == clientType { - isFound = true - break - } - } - if !isFound { - return - } - } - - runBench := func(benchCase any) time.Duration { - startTime := time.Now() - for i := 0; i < bench.Reps; i++ { - performAction(s, actionIndex, benchCase) - } - return time.Since(startTime) - } - - s.isBench = true - defer func() { s.isBench = false }() - - baseElapsedTime := runBench(bench.BaseCase) - optimizedElapsedTime := runBench(bench.OptimizedCase) - - factoredBaseTime := int64(float64(baseElapsedTime) / bench.Factor) - assert.Greater(s.t, factoredBaseTime, optimizedElapsedTime, - "Optimized case should be faster at least by factor of %.2f than the base case. Base: %d, Optimized: %d (μs)", - bench.Factor, optimizedElapsedTime.Microseconds(), baseElapsedTime.Microseconds()) -} - -// getCollectionNames gets an ordered, unique set of collection names across all nodes -// from the action set within the given test case. -// -// It preserves the order in which they are declared, and shares indexes across all nodes, so -// if a second node adds a collection of a name that was previously declared in another node -// the new node will respect the index originally assigned. This allows collections to be -// referenced across multiple nodes by a consistent, predictable index - allowing a single -// action to target the same collection across multiple nodes. -// -// WARNING: This will not work with schemas ending in `type`, e.g. `user_type` -func getCollectionNames(testCase TestCase) []string { - nextIndex := 0 - collectionIndexByName := map[string]int{} - - for _, a := range testCase.Actions { - switch action := a.(type) { - case SchemaUpdate: - if action.ExpectedError != "" { - // If an error is expected then no collections should result from this action - continue - } - - nextIndex = getCollectionNamesFromSchema(collectionIndexByName, action.Schema, nextIndex) - } - } - - collectionNames := make([]string, len(collectionIndexByName)) - for name, index := range collectionIndexByName { - collectionNames[index] = name - } - - return collectionNames -} - -func getCollectionNamesFromSchema(result map[string]int, schema string, nextIndex int) int { - // WARNING: This will not work with schemas ending in `type`, e.g. `user_type` - splitByType := strings.Split(schema, "type ") - // Skip the first, as that preceeds `type ` if `type ` is present, - // else there are no types. - for i := 1; i < len(splitByType); i++ { - wipSplit := strings.TrimLeft(splitByType[i], " ") - indexOfLastChar := strings.IndexAny(wipSplit, " {") - if indexOfLastChar <= 0 { - // This should never happen - continue - } - - collectionName := wipSplit[:indexOfLastChar] - if _, ok := result[collectionName]; ok { - // Collection name has already been added, possibly via another node - continue - } - - result[collectionName] = nextIndex - nextIndex++ - } - return nextIndex -} - -// closeNodes closes all the given nodes, ensuring that resources are properly released. -func closeNodes( - s *state, -) { - for _, node := range s.nodes { - node.Close() - } -} - -// getNodes gets the set of applicable nodes for the given nodeID. -// -// If nodeID has a value it will return that node only, otherwise all nodes will be returned. -func getNodes(nodeID immutable.Option[int], nodes []clients.Client) []clients.Client { - if !nodeID.HasValue() { - return nodes - } - - return []clients.Client{nodes[nodeID.Value()]} -} - -// getNodeCollections gets the set of applicable collections for the given nodeID. -// -// If nodeID has a value it will return collections for that node only, otherwise all collections across all -// nodes will be returned. -func getNodeCollections(nodeID immutable.Option[int], collections [][]client.Collection) [][]client.Collection { - if !nodeID.HasValue() { - return collections - } - - return [][]client.Collection{collections[nodeID.Value()]} -} - -func calculateLenForFlattenedActions(testCase *TestCase) int { - newLen := 0 - for _, a := range testCase.Actions { - actionGroup := reflect.ValueOf(a) - switch actionGroup.Kind() { - case reflect.Array, reflect.Slice: - newLen += actionGroup.Len() - default: - newLen++ - } - } - return newLen -} - -func flattenActions(testCase *TestCase) { - newLen := calculateLenForFlattenedActions(testCase) - if newLen == len(testCase.Actions) { - return - } - newActions := make([]any, 0, newLen) - - for _, a := range testCase.Actions { - actionGroup := reflect.ValueOf(a) - switch actionGroup.Kind() { - case reflect.Array, reflect.Slice: - for i := 0; i < actionGroup.Len(); i++ { - newActions = append( - newActions, - actionGroup.Index(i).Interface(), - ) - } - default: - newActions = append(newActions, a) - } - } - testCase.Actions = newActions -} - -// getActionRange returns the index of the first action to be run, and the last. -// -// Not all processes will run all actions - if this is a change detector run they -// will be split. -// -// If a SetupComplete action is provided, the actions will be split there, if not -// they will be split at the first non SchemaUpdate/CreateDoc/UpdateDoc action. -func getActionRange(t testing.TB, testCase TestCase) (int, int) { - startIndex := 0 - endIndex := len(testCase.Actions) - 1 - - if !changeDetector.Enabled { - return startIndex, endIndex - } - - setupCompleteIndex := -1 - firstNonSetupIndex := -1 - -ActionLoop: - for i := range testCase.Actions { - switch testCase.Actions[i].(type) { - case SetupComplete: - setupCompleteIndex = i - // We don't care about anything else if this has been explicitly provided - break ActionLoop - - case SchemaUpdate, CreateDoc, UpdateDoc, Restart: - continue - - default: - firstNonSetupIndex = i - break ActionLoop - } - } - - if changeDetector.SetupOnly { - if setupCompleteIndex > -1 { - endIndex = setupCompleteIndex - } else if firstNonSetupIndex > -1 { - // -1 to exclude this index - endIndex = firstNonSetupIndex - 1 - } - } else { - if setupCompleteIndex > -1 { - // +1 to exclude the SetupComplete action - startIndex = setupCompleteIndex + 1 - } else if firstNonSetupIndex > -1 { - // We must not set this to -1 :) - startIndex = firstNonSetupIndex - } else { - // if we don't have any non-mutation actions and the change detector is enabled - // skip this test as we will not gain anything from running (change detector would - // run an idential profile to a normal test run) - t.Skipf("no actions to execute") - } - } - - return startIndex, endIndex -} - -// setStartingNodes adds a set of initial Defra nodes for the test to execute against. -// -// If a node(s) has been explicitly configured via a `ConfigureNode` action then no new -// nodes will be added. -func setStartingNodes( - s *state, -) { - hasExplicitNode := false - for _, action := range s.testCase.Actions { - switch action.(type) { - case ConfigureNode: - hasExplicitNode = true - } - } - - // If nodes have not been explicitly configured via actions, setup a default one. - if !hasExplicitNode { - node, path, err := setupNode(s) - require.Nil(s.t, err) - - c, err := setupClient(s, node) - require.Nil(s.t, err) - - eventState, err := newEventState(c.Events()) - require.NoError(s.t, err) - - s.nodes = append(s.nodes, c) - s.nodeEvents = append(s.nodeEvents, eventState) - s.nodeP2P = append(s.nodeP2P, newP2PState()) - s.dbPaths = append(s.dbPaths, path) - } -} - -func restartNodes( - s *state, -) { - if s.dbt == badgerIMType || s.dbt == defraIMType { - return - } - closeNodes(s) - - // We need to restart the nodes in reverse order, to avoid dial backoff issues. - for i := len(s.nodes) - 1; i >= 0; i-- { - originalPath := databaseDir - databaseDir = s.dbPaths[i] - node, _, err := setupNode(s) - require.Nil(s.t, err) - databaseDir = originalPath - - if len(s.nodeConfigs) == 0 { - // If there are no explicit node configuration actions the node will be - // basic (i.e. no P2P stuff) and can be yielded now. - c, err := setupClient(s, node) - require.NoError(s.t, err) - s.nodes[i] = c - - eventState, err := newEventState(c.Events()) - require.NoError(s.t, err) - s.nodeEvents[i] = eventState - continue - } - - // We need to make sure the node is configured with its old address, otherwise - // a new one may be selected and reconnnection to it will fail. - var addresses []string - for _, addr := range s.nodeAddresses[i].Addrs { - addresses = append(addresses, addr.String()) - } - - nodeOpts := s.nodeConfigs[i] - nodeOpts = append(nodeOpts, net.WithListenAddresses(addresses...)) - - p, err := net.NewPeer(s.ctx, node.DB.Rootstore(), node.DB.Blockstore(), node.DB.Events(), nodeOpts...) - require.NoError(s.t, err) - - if err := p.Start(); err != nil { - p.Close() - require.NoError(s.t, err) - } - node.Peer = p - - c, err := setupClient(s, node) - require.NoError(s.t, err) - s.nodes[i] = c - - eventState, err := newEventState(c.Events()) - require.NoError(s.t, err) - s.nodeEvents[i] = eventState - - waitForNetworkSetupEvents(s, i) - } - - // If the db was restarted we need to refresh the collection definitions as the old instances - // will reference the old (closed) database instances. - refreshCollections(s) - refreshIndexes(s) -} - -// refreshCollections refreshes all the collections of the given names, preserving order. -// -// If a given collection is not present in the database the value at the corresponding -// result-index will be nil. -func refreshCollections( - s *state, -) { - s.collections = make([][]client.Collection, len(s.nodes)) - - for nodeID, node := range s.nodes { - s.collections[nodeID] = make([]client.Collection, len(s.collectionNames)) - allCollections, err := node.GetCollections(s.ctx, client.CollectionFetchOptions{}) - require.Nil(s.t, err) - - for i, collectionName := range s.collectionNames { - for _, collection := range allCollections { - if collection.Name().Value() == collectionName { - s.collections[nodeID][i] = collection - break - } - } - } - } -} - -// configureNode configures and starts a new Defra node using the provided configuration. -// -// It returns the new node, and its peer address. Any errors generated during configuration -// will result in a test failure. -func configureNode( - s *state, - action ConfigureNode, -) { - if changeDetector.Enabled { - // We do not yet support the change detector for tests running across multiple nodes. - s.t.SkipNow() - return - } - - node, path, err := setupNode(s) //disable change dector, or allow it? - require.NoError(s.t, err) - - privateKey, err := crypto.GenerateEd25519() - require.NoError(s.t, err) - - nodeOpts := action() - nodeOpts = append(nodeOpts, net.WithPrivateKey(privateKey)) - - p, err := net.NewPeer(s.ctx, node.DB.Rootstore(), node.DB.Blockstore(), node.DB.Events(), nodeOpts...) - require.NoError(s.t, err) - - log.InfoContext(s.ctx, "Starting P2P node", corelog.Any("P2P address", p.PeerInfo())) - if err := p.Start(); err != nil { - p.Close() - require.NoError(s.t, err) - } - - s.nodeAddresses = append(s.nodeAddresses, p.PeerInfo()) - s.nodeConfigs = append(s.nodeConfigs, nodeOpts) - - node.Peer = p - - c, err := setupClient(s, node) - require.NoError(s.t, err) - - eventState, err := newEventState(c.Events()) - require.NoError(s.t, err) - - s.nodes = append(s.nodes, c) - s.nodeEvents = append(s.nodeEvents, eventState) - s.nodeP2P = append(s.nodeP2P, newP2PState()) - s.dbPaths = append(s.dbPaths, path) -} - -func refreshDocuments( - s *state, - startActionIndex int, -) { - if len(s.collections) == 0 { - // This should only be possible at the moment for P2P testing, for which the - // change detector is currently disabled. We'll likely need some fancier logic - // here if/when we wish to enable it. - return - } - - // For now just do the initial setup using the collections on the first node, - // this may need to become more involved at a later date depending on testing - // requirements. - s.docIDs = make([][]client.DocID, len(s.collections[0])) - - for i := range s.collections[0] { - s.docIDs[i] = []client.DocID{} - } - - for i := 0; i < startActionIndex; i++ { - // We need to add the existing documents in the order in which the test case lists them - // otherwise they cannot be referenced correctly by other actions. - switch action := s.testCase.Actions[i].(type) { - case CreateDoc: - // Just use the collection from the first relevant node, as all will be the same for this - // purpose. - collection := getNodeCollections(action.NodeID, s.collections)[0][action.CollectionID] - - if action.DocMap != nil { - substituteRelations(s, action) - } - docs, err := parseCreateDocs(action, collection) - if err != nil { - // If an err has been returned, ignore it - it may be expected and if not - // the test will fail later anyway - continue - } - - for _, doc := range docs { - s.docIDs[action.CollectionID] = append(s.docIDs[action.CollectionID], doc.ID()) - } - } - } -} - -func refreshIndexes( - s *state, -) { - if len(s.collections) == 0 { - return - } - - s.indexes = make([][][]client.IndexDescription, len(s.collections)) - - for i, nodeCols := range s.collections { - s.indexes[i] = make([][]client.IndexDescription, len(nodeCols)) - - for j, col := range nodeCols { - if col == nil { - continue - } - colIndexes, err := col.GetIndexes(s.ctx) - if err != nil { - continue - } - - s.indexes[i][j] = colIndexes - } - } -} - -func getIndexes( - s *state, - action GetIndexes, -) { - if len(s.collections) == 0 { - return - } - - var expectedErrorRaised bool - actionNodes := getNodes(action.NodeID, s.nodes) - for nodeID, collections := range getNodeCollections(action.NodeID, s.collections) { - err := withRetry( - actionNodes, - nodeID, - func() error { - actualIndexes, err := collections[action.CollectionID].GetIndexes(s.ctx) - if err != nil { - return err - } - - assertIndexesListsEqual(action.ExpectedIndexes, - actualIndexes, s.t, s.testCase.Description) - - return nil - }, - ) - expectedErrorRaised = expectedErrorRaised || - AssertError(s.t, s.testCase.Description, err, action.ExpectedError) - } - - assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) -} - -func assertIndexesListsEqual( - expectedIndexes []client.IndexDescription, - actualIndexes []client.IndexDescription, - t testing.TB, - testDescription string, -) { - toNames := func(indexes []client.IndexDescription) []string { - names := make([]string, len(indexes)) - for i, index := range indexes { - names[i] = index.Name - } - return names - } - - require.ElementsMatch(t, toNames(expectedIndexes), toNames(actualIndexes), testDescription) - - toMap := func(indexes []client.IndexDescription) map[string]client.IndexDescription { - resultMap := map[string]client.IndexDescription{} - for _, index := range indexes { - resultMap[index.Name] = index - } - return resultMap - } - - expectedMap := toMap(expectedIndexes) - actualMap := toMap(actualIndexes) - for key := range expectedMap { - assertIndexesEqual(expectedMap[key], actualMap[key], t, testDescription) - } -} - -func assertIndexesEqual(expectedIndex, actualIndex client.IndexDescription, - t testing.TB, - testDescription string, -) { - assert.Equal(t, expectedIndex.Name, actualIndex.Name, testDescription) - assert.Equal(t, expectedIndex.ID, actualIndex.ID, testDescription) - - toNames := func(fields []client.IndexedFieldDescription) []string { - names := make([]string, len(fields)) - for i, field := range fields { - names[i] = field.Name - } - return names - } - - require.ElementsMatch(t, toNames(expectedIndex.Fields), toNames(actualIndex.Fields), testDescription) - - toMap := func(fields []client.IndexedFieldDescription) map[string]client.IndexedFieldDescription { - resultMap := map[string]client.IndexedFieldDescription{} - for _, field := range fields { - resultMap[field.Name] = field - } - return resultMap - } - - expectedMap := toMap(expectedIndex.Fields) - actualMap := toMap(actualIndex.Fields) - for key := range expectedMap { - assert.Equal(t, expectedMap[key], actualMap[key], testDescription) - } -} - -// updateSchema updates the schema using the given details. -func updateSchema( - s *state, - action SchemaUpdate, -) { - for _, node := range getNodes(action.NodeID, s.nodes) { - results, err := node.AddSchema(s.ctx, action.Schema) - expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) - - assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) - - if action.ExpectedResults != nil { - assertCollectionDescriptions(s, action.ExpectedResults, results) - } - } - - // If the schema was updated we need to refresh the collection definitions. - refreshCollections(s) - refreshIndexes(s) -} - -func patchSchema( - s *state, - action SchemaPatch, -) { - for _, node := range getNodes(action.NodeID, s.nodes) { - var setAsDefaultVersion bool - if action.SetAsDefaultVersion.HasValue() { - setAsDefaultVersion = action.SetAsDefaultVersion.Value() - } else { - setAsDefaultVersion = true - } - - err := node.PatchSchema(s.ctx, action.Patch, action.Lens, setAsDefaultVersion) - expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) - - assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) - } - - // If the schema was updated we need to refresh the collection definitions. - refreshCollections(s) - refreshIndexes(s) -} - -func patchCollection( - s *state, - action PatchCollection, -) { - for _, node := range getNodes(action.NodeID, s.nodes) { - err := node.PatchCollection(s.ctx, action.Patch) - expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) - - assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) - } - - // If the schema was updated we need to refresh the collection definitions. - refreshCollections(s) - refreshIndexes(s) -} - -func getSchema( - s *state, - action GetSchema, -) { - for _, node := range getNodes(action.NodeID, s.nodes) { - var results []client.SchemaDescription - var err error - switch { - case action.VersionID.HasValue(): - result, e := node.GetSchemaByVersionID(s.ctx, action.VersionID.Value()) - err = e - results = []client.SchemaDescription{result} - default: - results, err = node.GetSchemas( - s.ctx, - client.SchemaFetchOptions{ - Root: action.Root, - Name: action.Name, - }, - ) - } - - expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) - assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) - - if !expectedErrorRaised { - require.Equal(s.t, action.ExpectedResults, results) - } - } -} - -func getCollections( - s *state, - action GetCollections, -) { - for _, node := range getNodes(action.NodeID, s.nodes) { - txn := getTransaction(s, node, action.TransactionID, "") - ctx := db.SetContextTxn(s.ctx, txn) - results, err := node.GetCollections(ctx, action.FilterOptions) - resultDescriptions := make([]client.CollectionDescription, len(results)) - for i, col := range results { - resultDescriptions[i] = col.Description() - } - - expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) - assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) - - if !expectedErrorRaised { - assertCollectionDescriptions(s, action.ExpectedResults, resultDescriptions) - } - } -} - -func setActiveSchemaVersion( - s *state, - action SetActiveSchemaVersion, -) { - for _, node := range getNodes(action.NodeID, s.nodes) { - err := node.SetActiveSchemaVersion(s.ctx, action.SchemaVersionID) - expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) - - assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) - } - - refreshCollections(s) - refreshIndexes(s) -} - -func createView( - s *state, - action CreateView, -) { - for _, node := range getNodes(action.NodeID, s.nodes) { - _, err := node.AddView(s.ctx, action.Query, action.SDL, action.Transform) - expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) - - assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) - } -} - -// createDoc creates a document using the chosen [mutationType] and caches it in the -// test state object. -func createDoc( - s *state, - action CreateDoc, -) { - if action.DocMap != nil { - substituteRelations(s, action) - } - - var mutation func(*state, CreateDoc, client.DB, int, client.Collection) ([]client.DocID, error) - switch mutationType { - case CollectionSaveMutationType: - mutation = createDocViaColSave - case CollectionNamedMutationType: - mutation = createDocViaColCreate - case GQLRequestMutationType: - mutation = createDocViaGQL - default: - s.t.Fatalf("invalid mutationType: %v", mutationType) - } - - var expectedErrorRaised bool - var docIDs []client.DocID - actionNodes := getNodes(action.NodeID, s.nodes) - for nodeID, collections := range getNodeCollections(action.NodeID, s.collections) { - err := withRetry( - actionNodes, - nodeID, - func() error { - var err error - docIDs, err = mutation(s, action, actionNodes[nodeID], nodeID, collections[action.CollectionID]) - return err - }, - ) - expectedErrorRaised = AssertError(s.t, s.testCase.Description, err, action.ExpectedError) - } - - assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) - - if action.CollectionID >= len(s.docIDs) { - // Expand the slice if required, so that the document can be accessed by collection index - s.docIDs = append(s.docIDs, make([][]client.DocID, action.CollectionID-len(s.docIDs)+1)...) - } - s.docIDs[action.CollectionID] = append(s.docIDs[action.CollectionID], docIDs...) - - if action.ExpectedError == "" { - waitForUpdateEvents(s, action.NodeID, getEventsForCreateDoc(s, action)) - } -} - -func createDocViaColSave( - s *state, - action CreateDoc, - node client.DB, - nodeIndex int, - collection client.Collection, -) ([]client.DocID, error) { - docs, err := parseCreateDocs(action, collection) - if err != nil { - return nil, err - } - - txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) - ctx := makeContextForDocCreate(s, db.SetContextTxn(s.ctx, txn), nodeIndex, &action) - - docIDs := make([]client.DocID, len(docs)) - for i, doc := range docs { - err := collection.Save(ctx, doc) - if err != nil { - return nil, err - } - docIDs[i] = doc.ID() - } - return docIDs, nil -} - -func makeContextForDocCreate(s *state, ctx context.Context, nodeIndex int, action *CreateDoc) context.Context { - identity := getIdentity(s, nodeIndex, action.Identity) - ctx = db.SetContextIdentity(ctx, identity) - ctx = encryption.SetContextConfigFromParams(ctx, action.IsDocEncrypted, action.EncryptedFields) - return ctx -} - -func createDocViaColCreate( - s *state, - action CreateDoc, - node client.DB, - nodeIndex int, - collection client.Collection, -) ([]client.DocID, error) { - docs, err := parseCreateDocs(action, collection) - if err != nil { - return nil, err - } - - txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) - ctx := makeContextForDocCreate(s, db.SetContextTxn(s.ctx, txn), nodeIndex, &action) - - switch { - case len(docs) > 1: - err := collection.CreateMany(ctx, docs) - if err != nil { - return nil, err - } - - default: - err := collection.Create(ctx, docs[0]) - if err != nil { - return nil, err - } - } - - docIDs := make([]client.DocID, len(docs)) - for i, doc := range docs { - docIDs[i] = doc.ID() - } - return docIDs, nil -} - -func createDocViaGQL( - s *state, - action CreateDoc, - node client.DB, - nodeIndex int, - collection client.Collection, -) ([]client.DocID, error) { - var input string - - paramName := request.Input - - var err error - if action.DocMap != nil { - input, err = valueToGQL(action.DocMap) - } else if client.IsJSONArray([]byte(action.Doc)) { - var docMaps []map[string]any - err = json.Unmarshal([]byte(action.Doc), &docMaps) - require.NoError(s.t, err) - paramName = request.Inputs - input, err = arrayToGQL(docMaps) - } else { - input, err = jsonToGQL(action.Doc) - } - require.NoError(s.t, err) - - params := paramName + ": " + input - - if action.IsDocEncrypted { - params = params + ", " + request.EncryptDocArgName + ": true" - } - if len(action.EncryptedFields) > 0 { - params = params + ", " + request.EncryptFieldsArgName + ": [" + - strings.Join(action.EncryptedFields, ", ") + "]" - } - - key := fmt.Sprintf("create_%s", collection.Name().Value()) - req := fmt.Sprintf(`mutation { %s(%s) { _docID } }`, key, params) - - txn := getTransaction(s, node, immutable.None[int](), action.ExpectedError) - ctx := db.SetContextIdentity(db.SetContextTxn(s.ctx, txn), getIdentity(s, nodeIndex, action.Identity)) - - result := node.ExecRequest(ctx, req) - if len(result.GQL.Errors) > 0 { - return nil, result.GQL.Errors[0] - } - - resultData := result.GQL.Data.(map[string]any) - resultDocs := ConvertToArrayOfMaps(s.t, resultData[key]) - - docIDs := make([]client.DocID, len(resultDocs)) - for i, docMap := range resultDocs { - docIDString := docMap[request.DocIDFieldName].(string) - docID, err := client.NewDocIDFromString(docIDString) - require.NoError(s.t, err) - docIDs[i] = docID - } - - return docIDs, nil -} - -// substituteRelations scans the fields defined in [action.DocMap], if any are of type [DocIndex] -// it will substitute the [DocIndex] for the the corresponding document ID found in the state. -// -// If a document at that index is not found it will panic. -func substituteRelations( - s *state, - action CreateDoc, -) { - for k, v := range action.DocMap { - index, isIndex := v.(DocIndex) - if !isIndex { - continue - } - - docID := s.docIDs[index.CollectionIndex][index.Index] - action.DocMap[k] = docID.String() - } -} - -// deleteDoc deletes a document using the collection api and caches it in the -// given documents slice. -func deleteDoc( - s *state, - action DeleteDoc, -) { - docID := s.docIDs[action.CollectionID][action.DocID] - - var expectedErrorRaised bool - actionNodes := getNodes(action.NodeID, s.nodes) - for nodeID, collections := range getNodeCollections(action.NodeID, s.collections) { - identity := getIdentity(s, nodeID, action.Identity) - ctx := db.SetContextIdentity(s.ctx, identity) - - err := withRetry( - actionNodes, - nodeID, - func() error { - _, err := collections[action.CollectionID].Delete(ctx, docID) - return err - }, - ) - expectedErrorRaised = AssertError(s.t, s.testCase.Description, err, action.ExpectedError) - } - - assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) - - if action.ExpectedError == "" { - docIDs := map[string]struct{}{ - docID.String(): {}, - } - waitForUpdateEvents(s, action.NodeID, docIDs) - } -} - -// updateDoc updates a document using the chosen [mutationType]. -func updateDoc( - s *state, - action UpdateDoc, -) { - var mutation func(*state, UpdateDoc, client.DB, int, client.Collection) error - switch mutationType { - case CollectionSaveMutationType: - mutation = updateDocViaColSave - case CollectionNamedMutationType: - mutation = updateDocViaColUpdate - case GQLRequestMutationType: - mutation = updateDocViaGQL - default: - s.t.Fatalf("invalid mutationType: %v", mutationType) - } - - var expectedErrorRaised bool - actionNodes := getNodes(action.NodeID, s.nodes) - for nodeID, collections := range getNodeCollections(action.NodeID, s.collections) { - err := withRetry( - actionNodes, - nodeID, - func() error { - return mutation(s, action, actionNodes[nodeID], nodeID, collections[action.CollectionID]) - }, - ) - expectedErrorRaised = AssertError(s.t, s.testCase.Description, err, action.ExpectedError) - } - - assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) - - if action.ExpectedError == "" && !action.SkipLocalUpdateEvent { - waitForUpdateEvents(s, action.NodeID, getEventsForUpdateDoc(s, action)) - } -} - -func updateDocViaColSave( - s *state, - action UpdateDoc, - node client.DB, - nodeIndex int, - collection client.Collection, -) error { - identity := getIdentity(s, nodeIndex, action.Identity) - ctx := db.SetContextIdentity(s.ctx, identity) - - doc, err := collection.Get(ctx, s.docIDs[action.CollectionID][action.DocID], true) - if err != nil { - return err - } - err = doc.SetWithJSON([]byte(action.Doc)) - if err != nil { - return err - } - return collection.Save(ctx, doc) -} - -func updateDocViaColUpdate( - s *state, - action UpdateDoc, - node client.DB, - nodeIndex int, - collection client.Collection, -) error { - identity := getIdentity(s, nodeIndex, action.Identity) - ctx := db.SetContextIdentity(s.ctx, identity) - - doc, err := collection.Get(ctx, s.docIDs[action.CollectionID][action.DocID], true) - if err != nil { - return err - } - err = doc.SetWithJSON([]byte(action.Doc)) - if err != nil { - return err - } - return collection.Update(ctx, doc) -} - -func updateDocViaGQL( - s *state, - action UpdateDoc, - node client.DB, - nodeIndex int, - collection client.Collection, -) error { - docID := s.docIDs[action.CollectionID][action.DocID] - - input, err := jsonToGQL(action.Doc) - require.NoError(s.t, err) - - request := fmt.Sprintf( - `mutation { - update_%s(docID: "%s", input: %s) { - _docID - } - }`, - collection.Name().Value(), - docID.String(), - input, - ) - - identity := getIdentity(s, nodeIndex, action.Identity) - ctx := db.SetContextIdentity(s.ctx, identity) - - result := node.ExecRequest(ctx, request) - if len(result.GQL.Errors) > 0 { - return result.GQL.Errors[0] - } - return nil -} - -// updateWithFilter updates the set of matched documents. -func updateWithFilter(s *state, action UpdateWithFilter) { - var res *client.UpdateResult - var expectedErrorRaised bool - actionNodes := getNodes(action.NodeID, s.nodes) - for nodeID, collections := range getNodeCollections(action.NodeID, s.collections) { - identity := getIdentity(s, nodeID, action.Identity) - ctx := db.SetContextIdentity(s.ctx, identity) - - err := withRetry( - actionNodes, - nodeID, - func() error { - var err error - res, err = collections[action.CollectionID].UpdateWithFilter(ctx, action.Filter, action.Updater) - return err - }, - ) - expectedErrorRaised = AssertError(s.t, s.testCase.Description, err, action.ExpectedError) - } - - assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) - - if action.ExpectedError == "" && !action.SkipLocalUpdateEvent { - waitForUpdateEvents(s, action.NodeID, getEventsForUpdateWithFilter(s, action, res)) - } -} - -// createIndex creates a secondary index using the collection api. -func createIndex( - s *state, - action CreateIndex, -) { - if action.CollectionID >= len(s.indexes) { - // Expand the slice if required, so that the index can be accessed by collection index - s.indexes = append(s.indexes, - make([][][]client.IndexDescription, action.CollectionID-len(s.indexes)+1)...) - } - actionNodes := getNodes(action.NodeID, s.nodes) - for nodeID, collections := range getNodeCollections(action.NodeID, s.collections) { - indexDesc := client.IndexDescription{ - Name: action.IndexName, - } - if action.FieldName != "" { - indexDesc.Fields = []client.IndexedFieldDescription{ - { - Name: action.FieldName, - }, - } - } else if len(action.Fields) > 0 { - for i := range action.Fields { - indexDesc.Fields = append(indexDesc.Fields, client.IndexedFieldDescription{ - Name: action.Fields[i].Name, - Descending: action.Fields[i].Descending, - }) - } - } - indexDesc.Unique = action.Unique - err := withRetry( - actionNodes, - nodeID, - func() error { - desc, err := collections[action.CollectionID].CreateIndex(s.ctx, indexDesc) - if err != nil { - return err - } - s.indexes[nodeID][action.CollectionID] = - append(s.indexes[nodeID][action.CollectionID], desc) - return nil - }, - ) - if AssertError(s.t, s.testCase.Description, err, action.ExpectedError) { - return - } - } - - assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, false) -} - -// dropIndex drops the secondary index using the collection api. -func dropIndex( - s *state, - action DropIndex, -) { - var expectedErrorRaised bool - actionNodes := getNodes(action.NodeID, s.nodes) - for nodeID, collections := range getNodeCollections(action.NodeID, s.collections) { - indexName := action.IndexName - if indexName == "" { - indexName = s.indexes[nodeID][action.CollectionID][action.IndexID].Name - } - - err := withRetry( - actionNodes, - nodeID, - func() error { - return collections[action.CollectionID].DropIndex(s.ctx, indexName) - }, - ) - expectedErrorRaised = AssertError(s.t, s.testCase.Description, err, action.ExpectedError) - } - - assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) -} - -// backupExport generates a backup using the db api. -func backupExport( - s *state, - action BackupExport, -) { - if action.Config.Filepath == "" { - action.Config.Filepath = s.t.TempDir() + testJSONFile - } - - var expectedErrorRaised bool - actionNodes := getNodes(action.NodeID, s.nodes) - for nodeID, node := range actionNodes { - err := withRetry( - actionNodes, - nodeID, - func() error { return node.BasicExport(s.ctx, &action.Config) }, - ) - expectedErrorRaised = AssertError(s.t, s.testCase.Description, err, action.ExpectedError) - - if !expectedErrorRaised { - assertBackupContent(s.t, action.ExpectedContent, action.Config.Filepath) - } - } - assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) -} - -// backupImport imports data from a backup using the db api. -func backupImport( - s *state, - action BackupImport, -) { - if action.Filepath == "" { - action.Filepath = s.t.TempDir() + testJSONFile - } - - // we can avoid checking the error here as this would mean the filepath is invalid - // and we want to make sure that `BasicImport` fails in this case. - _ = os.WriteFile(action.Filepath, []byte(action.ImportContent), 0664) - - var expectedErrorRaised bool - actionNodes := getNodes(action.NodeID, s.nodes) - for nodeID, node := range actionNodes { - err := withRetry( - actionNodes, - nodeID, - func() error { return node.BasicImport(s.ctx, action.Filepath) }, - ) - expectedErrorRaised = AssertError(s.t, s.testCase.Description, err, action.ExpectedError) - } - assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) -} - -// withRetry attempts to perform the given action, retrying up to a DB-defined -// maximum attempt count if a transaction conflict error is returned. -// -// If a P2P-sync commit for the given document is already in progress this -// Save call can fail as the transaction will conflict. We dont want to worry -// about this in our tests so we just retry a few times until it works (or the -// retry limit is breached - important incase this is a different error) -func withRetry( - nodes []clients.Client, - nodeID int, - action func() error, -) error { - for i := 0; i < nodes[nodeID].MaxTxnRetries(); i++ { - err := action() - if errors.Is(err, datastore.ErrTxnConflict) { - time.Sleep(100 * time.Millisecond) - continue - } - return err - } - return nil -} - -func getTransaction( - s *state, - db client.DB, - transactionSpecifier immutable.Option[int], - expectedError string, -) datastore.Txn { - if !transactionSpecifier.HasValue() { - return nil - } - - transactionID := transactionSpecifier.Value() - - if transactionID >= len(s.txns) { - // Extend the txn slice so this txn can fit and be accessed by TransactionId - s.txns = append(s.txns, make([]datastore.Txn, transactionID-len(s.txns)+1)...) - } - - if s.txns[transactionID] == nil { - // Create a new transaction if one does not already exist. - txn, err := db.NewTxn(s.ctx, false) - if AssertError(s.t, s.testCase.Description, err, expectedError) { - txn.Discard(s.ctx) - return nil - } - - s.txns[transactionID] = txn - } - - return s.txns[transactionID] -} - -// commitTransaction commits the given transaction. -// -// Will panic if the given transaction does not exist. Discards the transaction if -// an error is returned on commit. -func commitTransaction( - s *state, - action TransactionCommit, -) { - err := s.txns[action.TransactionID].Commit(s.ctx) - if err != nil { - s.txns[action.TransactionID].Discard(s.ctx) - } - - expectedErrorRaised := AssertError(s.t, s.testCase.Description, err, action.ExpectedError) - - assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) -} - -// executeRequest executes the given request. -func executeRequest( - s *state, - action Request, -) { - var expectedErrorRaised bool - for nodeID, node := range getNodes(action.NodeID, s.nodes) { - txn := getTransaction(s, node, action.TransactionID, action.ExpectedError) - - ctx := db.SetContextTxn(s.ctx, txn) - identity := getIdentity(s, nodeID, action.Identity) - ctx = db.SetContextIdentity(ctx, identity) - - result := node.ExecRequest(ctx, action.Request) - - anyOfByFieldKey := map[docFieldKey][]any{} - expectedErrorRaised = assertRequestResults( - s, - &result.GQL, - action.Results, - action.ExpectedError, - action.Asserter, - nodeID, - anyOfByFieldKey, - ) - } - - assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) -} - -// executeSubscriptionRequest executes the given subscription request, returning -// a channel that will receive a single event once the subscription has been completed. -// -// The returned channel will receive a function that asserts that -// the subscription received all its expected results and no more. -// It should be called from the main test routine to ensure that -// failures are recorded properly. It will only yield once, once -// the subscription has terminated. -func executeSubscriptionRequest( - s *state, - action SubscriptionRequest, -) { - subscriptionAssert := make(chan func()) - - for _, node := range getNodes(action.NodeID, s.nodes) { - result := node.ExecRequest(s.ctx, action.Request) - if AssertErrors(s.t, s.testCase.Description, result.GQL.Errors, action.ExpectedError) { - return - } - - go func() { - var results []*client.GQLResult - allActionsAreDone := false - for !allActionsAreDone || len(results) < len(action.Results) { - select { - case s := <-result.Subscription: - results = append(results, &s) - - case <-s.allActionsDone: - allActionsAreDone = true - } - } - - subscriptionAssert <- func() { - for i, r := range action.Results { - // This assert should be executed from the main test routine - // so that failures will be properly handled. - expectedErrorRaised := assertRequestResults( - s, - results[i], - r, - action.ExpectedError, - nil, - // anyof is not yet supported by subscription requests - 0, - map[docFieldKey][]any{}, - ) - - assertExpectedErrorRaised(s.t, s.testCase.Description, action.ExpectedError, expectedErrorRaised) - } - } - }() - } - - s.subscriptionResultsChans = append(s.subscriptionResultsChans, subscriptionAssert) -} - -// Asserts as to whether an error has been raised as expected (or not). If an expected -// error has been raised it will return true, returns false in all other cases. -func AssertError(t testing.TB, description string, err error, expectedError string) bool { - if err == nil { - return false - } - - if expectedError == "" { - require.NoError(t, err, description) - return false - } else { - if !strings.Contains(err.Error(), expectedError) { - // Must be require instead of assert, otherwise will show a fake "error not raised". - require.ErrorIs(t, err, errors.New(expectedError)) - return false - } - return true - } -} - -// Asserts as to whether an error has been raised as expected (or not). If an expected -// error has been raised it will return true, returns false in all other cases. -func AssertErrors( - t testing.TB, - description string, - errs []error, - expectedError string, -) bool { - if expectedError == "" { - require.Empty(t, errs, description) - } else { - for _, e := range errs { - // This is always a string at the moment, add support for other types as and when needed - errorString := e.Error() - if !strings.Contains(errorString, expectedError) { - // We use ErrorIs for clearer failures (is a error comparison even if it is just a string) - require.ErrorIs(t, errors.New(errorString), errors.New(expectedError)) - continue - } - return true - } - } - return false -} - -// docFieldKey is an internal key type that wraps docIndex and fieldName -type docFieldKey struct { - docIndex int - fieldName string -} - -func assertRequestResults( - s *state, - result *client.GQLResult, - expectedResults map[string]any, - expectedError string, - asserter ResultAsserter, - nodeID int, - anyOfByField map[docFieldKey][]any, -) bool { - // we skip assertion benchmark because you don't specify expected result for benchmark. - if AssertErrors(s.t, s.testCase.Description, result.Errors, expectedError) || s.isBench { - return true - } - - if expectedResults == nil && result.Data == nil { - return true - } - - // Note: if result.Data == nil this panics (the panic seems useful while testing). - resultantData := result.Data.(map[string]any) - log.InfoContext(s.ctx, "", corelog.Any("RequestResults", result.Data)) - - if asserter != nil { - asserter.Assert(s.t, resultantData) - return true - } - - // merge all keys so we can check for missing values - keys := make(map[string]struct{}) - for key := range resultantData { - keys[key] = struct{}{} - } - for key := range expectedResults { - keys[key] = struct{}{} - } - - for key := range keys { - expect, ok := expectedResults[key] - require.True(s.t, ok, "expected key not found: %s", key) - - actual, ok := resultantData[key] - require.True(s.t, ok, "result key not found: %s", key) - - expectDocs, ok := expect.([]map[string]any) - if ok { - actualDocs := ConvertToArrayOfMaps(s.t, actual) - assertRequestResultDocs( - s, - nodeID, - expectDocs, - actualDocs, - anyOfByField) - } else { - assertResultsEqual( - s.t, - s.clientType, - expect, - actual, - fmt.Sprintf("node: %v, key: %v", nodeID, key), - ) - } - } - - return false -} - -func assertRequestResultDocs( - s *state, - nodeID int, - expectedResults []map[string]any, - actualResults []map[string]any, - anyOfByField map[docFieldKey][]any, -) bool { - // compare results - require.Equal(s.t, len(expectedResults), len(actualResults), - s.testCase.Description+" \n(number of results don't match)") - - for actualDocIndex, actualDoc := range actualResults { - expectedDoc := expectedResults[actualDocIndex] - - require.Equal( - s.t, - len(expectedDoc), - len(actualDoc), - fmt.Sprintf( - "%s \n(number of properties for item at index %v don't match)", - s.testCase.Description, - actualDocIndex, - ), - ) - - for field, actualValue := range actualDoc { - switch expectedValue := expectedDoc[field].(type) { - case AnyOf: - assertResultsAnyOf(s.t, s.clientType, expectedValue, actualValue) - - dfk := docFieldKey{actualDocIndex, field} - valueSet := anyOfByField[dfk] - valueSet = append(valueSet, actualValue) - anyOfByField[dfk] = valueSet - case DocIndex: - expectedDocID := s.docIDs[expectedValue.CollectionIndex][expectedValue.Index].String() - assertResultsEqual( - s.t, - s.clientType, - expectedDocID, - actualValue, - fmt.Sprintf("node: %v, doc: %v", nodeID, actualDocIndex), - ) - case []map[string]any: - actualValueMap := ConvertToArrayOfMaps(s.t, actualValue) - - assertRequestResultDocs( - s, - nodeID, - expectedValue, - actualValueMap, - anyOfByField, - ) - - default: - assertResultsEqual( - s.t, - s.clientType, - expectedValue, - actualValue, - fmt.Sprintf("node: %v, doc: %v", nodeID, actualDocIndex), - ) - } - } - } - - return false -} - -func ConvertToArrayOfMaps(t testing.TB, value any) []map[string]any { - valueArrayMap, ok := value.([]map[string]any) - if ok { - return valueArrayMap - } - valueArray, ok := value.([]any) - require.True(t, ok, "expected value to be an array of maps %v", value) - - valueArrayMap = make([]map[string]any, len(valueArray)) - for i, v := range valueArray { - valueArrayMap[i], ok = v.(map[string]any) - require.True(t, ok, "expected value to be an array of maps %v", value) - } - return valueArrayMap -} - -func assertExpectedErrorRaised(t testing.TB, description string, expectedError string, wasRaised bool) { - if expectedError != "" && !wasRaised { - assert.Fail(t, "Expected an error however none was raised.", description) - } -} - -func assertIntrospectionResults( - s *state, - action IntrospectionRequest, -) bool { - for _, node := range getNodes(action.NodeID, s.nodes) { - result := node.ExecRequest(s.ctx, action.Request) - - if AssertErrors(s.t, s.testCase.Description, result.GQL.Errors, action.ExpectedError) { - return true - } - resultantData := result.GQL.Data.(map[string]any) - - if len(action.ExpectedData) == 0 && len(action.ContainsData) == 0 { - require.Equal(s.t, action.ExpectedData, resultantData) - } - - if len(action.ExpectedData) == 0 && len(action.ContainsData) > 0 { - assertContains(s.t, action.ContainsData, resultantData) - } else { - require.Equal(s.t, len(action.ExpectedData), len(resultantData)) - - for k, result := range resultantData { - assert.Equal(s.t, action.ExpectedData[k], result) - } - } - } - - return false -} - -// Asserts that the client introspection results conform to our expectations. -func assertClientIntrospectionResults( - s *state, - action ClientIntrospectionRequest, -) bool { - for _, node := range getNodes(action.NodeID, s.nodes) { - result := node.ExecRequest(s.ctx, action.Request) - - if AssertErrors(s.t, s.testCase.Description, result.GQL.Errors, action.ExpectedError) { - return true - } - resultantData := result.GQL.Data.(map[string]any) - - if len(resultantData) == 0 { - return false - } - - // Iterate through all types, validating each type definition. - // Inspired from buildClientSchema.ts from graphql-js, - // which is one way that clients do validate the schema. - types := resultantData["__schema"].(map[string]any)["types"].([]any) - - for _, typeData := range types { - typeDef := typeData.(map[string]any) - kind := typeDef["kind"].(string) - - switch kind { - case "SCALAR", "INTERFACE", "UNION", "ENUM": - // No validation for these types in this test - case "OBJECT": - fields := typeDef["fields"] - if fields == nil { - s.t.Errorf("Fields are missing for OBJECT type %v", typeDef["name"]) - } - case "INPUT_OBJECT": - inputFields := typeDef["inputFields"] - if inputFields == nil { - s.t.Errorf("InputFields are missing for INPUT_OBJECT type %v", typeDef["name"]) - } - default: - // t.Errorf("Unknown type kind: %v", kind) - } - } - } - - return true -} - -// Asserts that the `actual` contains the given `contains` value according to the logic -// described on the [RequestTestCase.ContainsData] property. -func assertContains(t testing.TB, contains map[string]any, actual map[string]any) { - for k, expected := range contains { - innerActual := actual[k] - if innerExpected, innerIsMap := expected.(map[string]any); innerIsMap { - if innerActual == nil { - assert.Equal(t, innerExpected, innerActual) - } else if innerActualMap, isMap := innerActual.(map[string]any); isMap { - // If the inner is another map then we continue down the chain - assertContains(t, innerExpected, innerActualMap) - } else { - // If the types don't match then we use assert.Equal for a clean failure message - assert.Equal(t, innerExpected, innerActual) - } - } else if innerExpected, innerIsArray := expected.([]any); innerIsArray { - if actualArray, isActualArray := innerActual.([]any); isActualArray { - // If the inner is an array/slice, then assert that each expected item is present - // in the actual. Note how the actual may contain additional items - this should - // not result in a test failure. - for _, innerExpectedItem := range innerExpected { - assert.Contains(t, actualArray, innerExpectedItem) - } - } else { - // If the types don't match then we use assert.Equal for a clean failure message - assert.Equal(t, expected, innerActual) - } - } else { - assert.Equal(t, expected, innerActual) - } - } -} - -func assertBackupContent(t testing.TB, expectedContent, filepath string) { - b, err := os.ReadFile(filepath) - assert.NoError(t, err) - assert.Equal( - t, - expectedContent, - string(b), - ) -} - -// skipIfMutationTypeUnsupported skips the current test if the given supportedMutationTypes option has value -// and the active mutation type is not contained within that value set. -func skipIfMutationTypeUnsupported(t testing.TB, supportedMutationTypes immutable.Option[[]MutationType]) { - if supportedMutationTypes.HasValue() { - var isTypeSupported bool - for _, supportedMutationType := range supportedMutationTypes.Value() { - if supportedMutationType == mutationType { - isTypeSupported = true - break - } - } - - if !isTypeSupported { - t.Skipf("test does not support given mutation type. Type: %s", mutationType) - } - } -} - -// skipIfClientTypeUnsupported returns a new set of client types that match the given supported set. -// -// If supportedClientTypes is none no filtering will take place and the input client set will be returned. -// If the resultant filtered set is empty the test will be skipped. -func skipIfClientTypeUnsupported( - t testing.TB, - clients []ClientType, - supportedClientTypes immutable.Option[[]ClientType], -) []ClientType { - if !supportedClientTypes.HasValue() { - return clients - } - - filteredClients := []ClientType{} - for _, supportedMutationType := range supportedClientTypes.Value() { - for _, client := range clients { - if supportedMutationType == client { - filteredClients = append(filteredClients, client) - break - } - } - } - - if len(filteredClients) == 0 { - t.Skipf("test does not support any given client type. Type: %v", supportedClientTypes) - } - - return filteredClients -} - -func skipIfACPTypeUnsupported(t testing.TB, supporteACPTypes immutable.Option[[]ACPType]) { - if supporteACPTypes.HasValue() { - var isTypeSupported bool - for _, supportedType := range supporteACPTypes.Value() { - if supportedType == acpType { - isTypeSupported = true - break - } - } - - if !isTypeSupported { - t.Skipf("test does not support given acp type. Type: %s", acpType) - } - } -} - -// skipIfNetworkTest skips the current test if the given actions -// contain network actions and skipNetworkTests is true. -func skipIfNetworkTest(t testing.TB, actions []any) { - hasNetworkAction := false - for _, act := range actions { - switch act.(type) { - case ConfigureNode: - hasNetworkAction = true - } - } - if skipNetworkTests && hasNetworkAction { - t.Skip("test involves network actions") - } -} - -func ParseSDL(gqlSDL string) (map[string]client.CollectionDefinition, error) { - parser, err := graphql.NewParser() - if err != nil { - return nil, err - } - cols, err := parser.ParseSDL(context.Background(), gqlSDL) - if err != nil { - return nil, err - } - result := make(map[string]client.CollectionDefinition) - for _, col := range cols { - result[col.Description.Name.Value()] = col - } - return result, nil -} - -func MustParseTime(timeString string) time.Time { - t, err := time.Parse(time.RFC3339, timeString) - if err != nil { - panic(err) - } - return t -} - -func CBORValue(value any) []byte { - enc, err := cbor.Marshal(value) - if err != nil { - panic(err) - } - return enc -} - -// parseCreateDocs parses and returns documents from a CreateDoc action. -func parseCreateDocs(action CreateDoc, collection client.Collection) ([]*client.Document, error) { - switch { - case action.DocMap != nil: - val, err := client.NewDocFromMap(action.DocMap, collection.Definition()) - if err != nil { - return nil, err - } - return []*client.Document{val}, nil - - case client.IsJSONArray([]byte(action.Doc)): - return client.NewDocsFromJSON([]byte(action.Doc), collection.Definition()) - - default: - val, err := client.NewDocFromJSON([]byte(action.Doc), collection.Definition()) - if err != nil { - return nil, err - } - return []*client.Document{val}, nil - } -} From 4c857a5427857cbe37f3b3bbc4efcc8c68c5026c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 21:33:54 -0400 Subject: [PATCH 28/41] bot: Update dependencies (bulk dependabot PRs) 06-08-2024 (#2889) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✅ This PR was created by combining the following PRs: #2887 bot: Bump github.com/getkin/kin-openapi from 0.125.0 to 0.127.0 #2886 bot: Bump @typescript-eslint/eslint-plugin from 7.16.1 to 8.0.0 in /playground #2879 bot: Bump typescript from 5.5.3 to 5.5.4 in /playground #2876 bot: Bump github.com/lestrrat-go/jwx/v2 from 2.1.0 to 2.1.1 #2854 bot: Bump github.com/vito/go-sse from 1.0.0 to 1.1.1 #2853 bot: Bump golang.org/x/term from 0.21.0 to 0.22.0 #2852 bot: Bump github.com/cosmos/cosmos-sdk from 0.50.6 to 0.50.8 ⚠️ The following PRs were resolved manually due to merge conflicts: #2877 bot: Bump vite from 5.3.4 to 5.3.5 in /playground #2855 bot: Bump eslint-plugin-react-refresh from 0.4.8 to 0.4.9 in /playground #2885 bot: Bump @typescript-eslint/parser from 7.16.1 to 7.18.0 in /playground --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Shahzad Lone --- go.mod | 28 +- go.sum | 57 ++- playground/package-lock.json | 815 +++-------------------------------- playground/package.json | 10 +- 4 files changed, 115 insertions(+), 795 deletions(-) diff --git a/go.mod b/go.mod index 6af60bcdf1..858aff0285 100644 --- a/go.mod +++ b/go.mod @@ -5,13 +5,13 @@ go 1.21.3 require ( github.com/bits-and-blooms/bitset v1.13.0 github.com/bxcodec/faker v2.0.1+incompatible - github.com/cosmos/cosmos-sdk v0.50.6 + github.com/cosmos/cosmos-sdk v0.50.8 github.com/cosmos/gogoproto v1.5.0 github.com/cyware/ssi-sdk v0.0.0-20231229164914-f93f3006379f github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 github.com/evanphx/json-patch/v5 v5.9.0 github.com/fxamacker/cbor/v2 v2.7.0 - github.com/getkin/kin-openapi v0.125.0 + github.com/getkin/kin-openapi v0.127.0 github.com/go-chi/chi/v5 v5.1.0 github.com/go-chi/cors v1.2.1 github.com/go-errors/errors v1.5.1 @@ -28,7 +28,7 @@ require ( github.com/ipld/go-ipld-prime/storage/bsrvadapter v0.0.0-20240322071758-198d7dba8fb8 github.com/jbenet/goprocess v0.1.4 github.com/lens-vm/lens/host-go v0.0.0-20231127204031-8d858ed2926c - github.com/lestrrat-go/jwx/v2 v2.1.0 + github.com/lestrrat-go/jwx/v2 v2.1.1 github.com/libp2p/go-libp2p v0.35.1 github.com/libp2p/go-libp2p-gostream v0.6.0 github.com/libp2p/go-libp2p-kad-dht v0.25.2 @@ -53,13 +53,13 @@ require ( github.com/stretchr/testify v1.9.0 github.com/tidwall/btree v1.7.0 github.com/valyala/fastjson v1.6.4 - github.com/vito/go-sse v1.0.0 + github.com/vito/go-sse v1.1.1 github.com/zalando/go-keyring v0.2.5 go.opentelemetry.io/otel/metric v1.28.0 go.opentelemetry.io/otel/sdk/metric v1.28.0 go.uber.org/zap v1.27.0 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 - golang.org/x/term v0.21.0 + golang.org/x/term v0.22.0 google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 ) @@ -70,7 +70,7 @@ require ( cloud.google.com/go/compute/metadata v0.3.0 // indirect cloud.google.com/go/iam v1.1.6 // indirect cloud.google.com/go/storage v1.38.0 // indirect - cosmossdk.io/api v0.7.4 // indirect + cosmossdk.io/api v0.7.5 // indirect cosmossdk.io/collections v0.4.0 // indirect cosmossdk.io/core v0.11.0 // indirect cosmossdk.io/depinject v1.0.0-alpha.4 // indirect @@ -81,7 +81,7 @@ require ( cosmossdk.io/x/circuit v0.1.0 // indirect cosmossdk.io/x/evidence v0.1.0 // indirect cosmossdk.io/x/feegrant v0.1.0 // indirect - cosmossdk.io/x/tx v0.13.2 // indirect + cosmossdk.io/x/tx v0.13.3 // indirect cosmossdk.io/x/upgrade v0.1.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect @@ -114,7 +114,7 @@ require ( github.com/cockroachdb/pebble v1.1.0 // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/cometbft/cometbft v0.38.8 // indirect + github.com/cometbft/cometbft v0.38.9 // indirect github.com/cometbft/cometbft-db v0.9.1 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect @@ -155,8 +155,8 @@ require ( github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.20.2 // indirect - github.com/go-openapi/swag v0.22.8 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.15.1 // indirect @@ -214,7 +214,7 @@ require ( github.com/ignite/cli/v28 v28.4.0 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/invopop/yaml v0.2.0 // indirect + github.com/invopop/yaml v0.3.1 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect @@ -238,7 +238,7 @@ require ( github.com/leodido/go-urn v1.2.4 // indirect github.com/lestrrat-go/blackmagic v1.0.2 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect - github.com/lestrrat-go/httprc v1.0.5 // indirect + github.com/lestrrat-go/httprc v1.0.6 // indirect github.com/lestrrat-go/iter v1.0.2 // indirect github.com/lestrrat-go/option v1.0.1 // indirect github.com/lib/pq v1.10.9 // indirect @@ -355,12 +355,12 @@ require ( go.uber.org/fx v1.22.0 // indirect go.uber.org/mock v0.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.24.0 // indirect + golang.org/x/crypto v0.25.0 // indirect golang.org/x/mod v0.18.0 // indirect golang.org/x/net v0.26.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.21.0 // indirect + golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.22.0 // indirect diff --git a/go.sum b/go.sum index 3d191a245f..0f22b26344 100644 --- a/go.sum +++ b/go.sum @@ -186,8 +186,8 @@ cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xX cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -cosmossdk.io/api v0.7.4 h1:sPo8wKwCty1lht8kgL3J7YL1voJywP3YWuA5JKkBz30= -cosmossdk.io/api v0.7.4/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= +cosmossdk.io/api v0.7.5 h1:eMPTReoNmGUm8DeiQL9DyM8sYDjEhWzL1+nLbI9DqtQ= +cosmossdk.io/api v0.7.5/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= cosmossdk.io/client/v2 v2.0.0-beta.1 h1:XkHh1lhrLYIT9zKl7cIOXUXg2hdhtjTPBUfqERNA1/Q= cosmossdk.io/client/v2 v2.0.0-beta.1/go.mod h1:JEUSu9moNZQ4kU3ir1DKD5eU4bllmAexrGWjmb9k8qU= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= @@ -210,8 +210,8 @@ cosmossdk.io/x/evidence v0.1.0 h1:J6OEyDl1rbykksdGynzPKG5R/zm6TacwW2fbLTW4nCk= cosmossdk.io/x/evidence v0.1.0/go.mod h1:hTaiiXsoiJ3InMz1uptgF0BnGqROllAN8mwisOMMsfw= cosmossdk.io/x/feegrant v0.1.0 h1:c7s3oAq/8/UO0EiN1H5BIjwVntujVTkYs35YPvvrdQk= cosmossdk.io/x/feegrant v0.1.0/go.mod h1:4r+FsViJRpcZif/yhTn+E0E6OFfg4n0Lx+6cCtnZElU= -cosmossdk.io/x/tx v0.13.2 h1:Kh90UH30bhnnUdJH+CmWLyaH8IKdY6BBGY3EkdOk82o= -cosmossdk.io/x/tx v0.13.2/go.mod h1:yhPokDCfXVIuAtyp49IFlWB5YAXUgD7Zek+ZHwsHzvU= +cosmossdk.io/x/tx v0.13.3 h1:Ha4mNaHmxBc6RMun9aKuqul8yHiL78EKJQ8g23Zf73g= +cosmossdk.io/x/tx v0.13.3/go.mod h1:I8xaHv0rhUdIvIdptKIqzYy27+n2+zBVaxO6fscFhys= cosmossdk.io/x/upgrade v0.1.1 h1:aoPe2gNvH+Gwt/Pgq3dOxxQVU3j5P6Xf+DaUJTDZATc= cosmossdk.io/x/upgrade v0.1.1/go.mod h1:MNLptLPcIFK9CWt7Ra//8WUZAxweyRDNcbs5nkOcQy0= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= @@ -371,8 +371,8 @@ github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZ github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/cometbft/cometbft v0.38.8 h1:XyJ9Cu3xqap6xtNxiemrO8roXZ+KS2Zlu7qQ0w1trvU= -github.com/cometbft/cometbft v0.38.8/go.mod h1:xOoGZrtUT+A5izWfHSJgl0gYZUE7lu7Z2XIS1vWG/QQ= +github.com/cometbft/cometbft v0.38.9 h1:cJBJBG0mPKz+sqelCi/hlfZjadZQGdDNnu6YQ1ZsUHQ= +github.com/cometbft/cometbft v0.38.9/go.mod h1:xOoGZrtUT+A5izWfHSJgl0gYZUE7lu7Z2XIS1vWG/QQ= github.com/cometbft/cometbft-db v0.9.1 h1:MIhVX5ja5bXNHF8EYrThkG9F7r9kSfv8BX4LWaxWJ4M= github.com/cometbft/cometbft-db v0.9.1/go.mod h1:iliyWaoV0mRwBJoizElCwwRA9Tf7jZJOURcRZF9m60U= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= @@ -395,8 +395,8 @@ github.com/cosmos/cosmos-db v1.0.2 h1:hwMjozuY1OlJs/uh6vddqnk9j7VamLv+0DBlbEXbAK github.com/cosmos/cosmos-db v1.0.2/go.mod h1:Z8IXcFJ9PqKK6BIsVOB3QXtkKoqUOp1vRvPT39kOXEA= github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= -github.com/cosmos/cosmos-sdk v0.50.6 h1:efR3MsvMHX5sxS3be+hOobGk87IzlZbSpsI2x/Vw3hk= -github.com/cosmos/cosmos-sdk v0.50.6/go.mod h1:lVkRY6cdMJ0fG3gp8y4hFrsKZqF4z7y0M2UXFb9Yt40= +github.com/cosmos/cosmos-sdk v0.50.8 h1:2UJHssUaGHTl4/dFp8xyREKAnfiRU6VVfqtKG9n8w5g= +github.com/cosmos/cosmos-sdk v0.50.8/go.mod h1:Zb+DgHtiByNwgj71IlJBXwOq6dLhtyAq3AgqpXm/jHo= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= @@ -513,8 +513,8 @@ github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= -github.com/getkin/kin-openapi v0.125.0 h1:jyQCyf2qXS1qvs2U00xQzkGCqYPhEhZDmSmVt65fXno= -github.com/getkin/kin-openapi v0.125.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM= +github.com/getkin/kin-openapi v0.127.0 h1:Mghqi3Dhryf3F8vR370nN67pAERW+3a95vomb3MAREY= +github.com/getkin/kin-openapi v0.127.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -554,10 +554,10 @@ github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= -github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= -github.com/go-openapi/swag v0.22.8 h1:/9RjDSQ0vbFR+NyjGMkFTsA1IA0fmhKSThmfGZjicbw= -github.com/go-openapi/swag v0.22.8/go.mod h1:6QT22icPLEqAM/z/TChgb4WAveCHF92+2gF0CNjHpPI= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -851,8 +851,8 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY= -github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= +github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= +github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= github.com/ipfs/boxo v0.21.0 h1:XpGXb+TQQ0IUdYaeAxGzWjSs6ow/Lce148A/2IbRDVE= @@ -977,12 +977,12 @@ github.com/lestrrat-go/blackmagic v1.0.2 h1:Cg2gVSc9h7sz9NOByczrbUvLopQmXrfFx//N github.com/lestrrat-go/blackmagic v1.0.2/go.mod h1:UrEqBzIR2U6CnzVyUtfM6oZNMt/7O7Vohk2J0OGSAtU= github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= -github.com/lestrrat-go/httprc v1.0.5 h1:bsTfiH8xaKOJPrg1R+E3iE/AWZr/x0Phj9PBTG/OLUk= -github.com/lestrrat-go/httprc v1.0.5/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo= +github.com/lestrrat-go/httprc v1.0.6 h1:qgmgIRhpvBqexMJjA/PmwSvhNk679oqD1RbovdCGW8k= +github.com/lestrrat-go/httprc v1.0.6/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo= github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI= github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= -github.com/lestrrat-go/jwx/v2 v2.1.0 h1:0zs7Ya6+39qoit7gwAf+cYm1zzgS3fceIdo7RmQ5lkw= -github.com/lestrrat-go/jwx/v2 v2.1.0/go.mod h1:Xpw9QIaUGiIUD1Wx0NcY1sIHwFf8lDuZn/cmxtXYRys= +github.com/lestrrat-go/jwx/v2 v2.1.1 h1:Y2ltVl8J6izLYFs54BVcpXLv5msSW4o8eXwnzZLI32E= +github.com/lestrrat-go/jwx/v2 v2.1.1/go.mod h1:4LvZg7oxu6Q5VJwn7Mk/UwooNRnTHUpXBj2C4j3HNx0= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= @@ -1488,8 +1488,8 @@ github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXV github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= -github.com/vito/go-sse v1.0.0 h1:e6/iTrrvy8BRrOwJwmQmlndlil+TLdxXvHi55ZDzH6M= -github.com/vito/go-sse v1.0.0/go.mod h1:2wkcaQ+jtlZ94Uve8gYZjFpL68luAjssTINA2hpgcZs= +github.com/vito/go-sse v1.1.1 h1:9TlsS/xk9++g+W61ZR8dusNq2BAsqR1Kq8NhMfqpzGI= +github.com/vito/go-sse v1.1.1/go.mod h1:2wkcaQ+jtlZ94Uve8gYZjFpL68luAjssTINA2hpgcZs= github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= github.com/warpfork/go-testmark v0.12.1/go.mod h1:kHwy7wfvGSPh1rQJYKayD4AbtNaeyZdcGi9tNJTaa5Y= github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ= @@ -1604,8 +1604,8 @@ golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98y golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1880,8 +1880,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1893,8 +1893,8 @@ golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2270,7 +2270,6 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= diff --git a/playground/package-lock.json b/playground/package-lock.json index 127c51617e..ebf9541943 100644 --- a/playground/package-lock.json +++ b/playground/package-lock.json @@ -18,14 +18,14 @@ "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@types/swagger-ui-react": "^4.18.3", - "@typescript-eslint/eslint-plugin": "^7.16.1", - "@typescript-eslint/parser": "^7.16.1", + "@typescript-eslint/eslint-plugin": "^8.0.1", + "@typescript-eslint/parser": "^8.0.1", "@vitejs/plugin-react-swc": "^3.7.0", "eslint": "^8.57.0", "eslint-plugin-react-hooks": "^4.6.2", - "eslint-plugin-react-refresh": "^0.4.7", - "typescript": "^5.5.3", - "vite": "^5.3.4" + "eslint-plugin-react-refresh": "^0.4.9", + "typescript": "^5.5.4", + "vite": "^5.3.5" } }, "node_modules/@babel/runtime": { @@ -102,262 +102,6 @@ "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", "optional": true }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@esbuild/linux-x64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", @@ -374,102 +118,6 @@ "node": ">=12" } }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -1404,149 +1052,6 @@ "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==" }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.1.tgz", - "integrity": "sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.1.tgz", - "integrity": "sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.1.tgz", - "integrity": "sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.1.tgz", - "integrity": "sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.1.tgz", - "integrity": "sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.1.tgz", - "integrity": "sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.1.tgz", - "integrity": "sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.1.tgz", - "integrity": "sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.1.tgz", - "integrity": "sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.1.tgz", - "integrity": "sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.1.tgz", - "integrity": "sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, "node_modules/@rollup/rollup-linux-x64-gnu": { "version": "4.18.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.1.tgz", @@ -1573,45 +1078,6 @@ "linux" ] }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.1.tgz", - "integrity": "sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.1.tgz", - "integrity": "sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.1.tgz", - "integrity": "sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@swagger-api/apidom-ast": { "version": "1.0.0-alpha.6", "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-1.0.0-alpha.6.tgz", @@ -2107,86 +1573,6 @@ } } }, - "node_modules/@swc/core-darwin-arm64": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.0.tgz", - "integrity": "sha512-2ylhM7f0HwUwLrFYZAe/dse8PCbPsYcJS3Dt7Q8NT3PUn7vy6QOMxNcOPPuDrnmaXqQQO3oxdmRapguTxaat9g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-darwin-x64": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.7.0.tgz", - "integrity": "sha512-SgVnN4gT1Rb9YfTkp4FCUITqSs7Yj0uB2SUciu5CV3HuGvS5YXCUzh+KrwpLFtx8NIgivISKcNnb41mJi98X8Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.0.tgz", - "integrity": "sha512-+Z9Dayart1iKJQEJJ9N/KS4z5EdXJE3WPFikY0jonKTo4Dd8RuyVz5yLvqcIMeVdz/SwximATaL6iJXw7hZS9A==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.0.tgz", - "integrity": "sha512-UnLrCiZ1EI4shznJn0xP6DLgsXUSwtfsdgHhGYCrvbgVBBve3S9iFgVFEB3SPl7Q/TdowNbrN4zHU0oChfiNfw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.0.tgz", - "integrity": "sha512-H724UANA+ptsfwKRr9mnaDa9cb5fw0oFysiGKTgb3DMYcgk3Od0jMTnXVPFSVpo7FlmyxeC9K8ueUPBOoOK6XA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, "node_modules/@swc/core-linux-x64-gnu": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.0.tgz", @@ -2219,54 +1605,6 @@ "node": ">=10" } }, - "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.0.tgz", - "integrity": "sha512-ecQOOmzEssz+m0pR4xDYCGuvn3E/l0nQ3tk5jp1NA1lsAy4bMV0YbYCHjptYvWL/UjhIerIp3IlCJ8x5DodSog==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.0.tgz", - "integrity": "sha512-gz81seZkRn3zMnVOc7L5k6F4vQC82gIxmHiL+GedK+A37XI/X26AASU3zxvORnqQbwQYXQ+AEVckxBmFlz3v2g==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.0.tgz", - "integrity": "sha512-b5Fd1xEOw9uqBpj2lqsaR4Iq9UhiL84hNDcEsi6DQA7Y1l85waQAslTbS0E4/pJ1PISAs0jW0zIGLco1eaWBOg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, "node_modules/@swc/counter": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", @@ -2389,31 +1727,31 @@ "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.16.1.tgz", - "integrity": "sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.0.1.tgz", + "integrity": "sha512-5g3Y7GDFsJAnY4Yhvk8sZtFfV6YNF2caLzjrRPUBzewjPCaj0yokePB4LJSobyCzGMzjZZYFbwuzbfDHlimXbQ==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.16.1", - "@typescript-eslint/type-utils": "7.16.1", - "@typescript-eslint/utils": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", + "@typescript-eslint/scope-manager": "8.0.1", + "@typescript-eslint/type-utils": "8.0.1", + "@typescript-eslint/utils": "8.0.1", + "@typescript-eslint/visitor-keys": "8.0.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -2422,26 +1760,26 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.16.1.tgz", - "integrity": "sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.0.1.tgz", + "integrity": "sha512-5IgYJ9EO/12pOUwiBKFkpU7rS3IU21mtXzB81TNwq2xEybcmAZrE9qwDtsb5uQd9aVO9o0fdabFyAmKveXyujg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.16.1", - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/typescript-estree": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", + "@typescript-eslint/scope-manager": "8.0.1", + "@typescript-eslint/types": "8.0.1", + "@typescript-eslint/typescript-estree": "8.0.1", + "@typescript-eslint/visitor-keys": "8.0.1", "debug": "^4.3.4" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -2450,16 +1788,16 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", - "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.0.1.tgz", + "integrity": "sha512-NpixInP5dm7uukMiRyiHjRKkom5RIFA4dfiHvalanD2cF0CLUuQqxfg8PtEUo9yqJI2bBhF+pcSafqnG3UBnRQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1" + "@typescript-eslint/types": "8.0.1", + "@typescript-eslint/visitor-keys": "8.0.1" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -2467,26 +1805,23 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.16.1.tgz", - "integrity": "sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.0.1.tgz", + "integrity": "sha512-+/UT25MWvXeDX9YaHv1IS6KI1fiuTto43WprE7pgSMswHbn1Jm9GEM4Txp+X74ifOWV8emu2AWcbLhpJAvD5Ng==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.16.1", - "@typescript-eslint/utils": "7.16.1", + "@typescript-eslint/typescript-estree": "8.0.1", + "@typescript-eslint/utils": "8.0.1", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "eslint": "^8.56.0" - }, "peerDependenciesMeta": { "typescript": { "optional": true @@ -2494,12 +1829,12 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.16.1.tgz", - "integrity": "sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.0.1.tgz", + "integrity": "sha512-PpqTVT3yCA/bIgJ12czBuE3iBlM3g4inRSC5J0QOdQFAn07TYrYEQBBKgXH1lQpglup+Zy6c1fxuwTk4MTNKIw==", "dev": true, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -2507,13 +1842,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.16.1.tgz", - "integrity": "sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.1.tgz", + "integrity": "sha512-8V9hriRvZQXPWU3bbiUV4Epo7EvgM6RTs+sUmxp5G//dBGy402S7Fx0W0QkB2fb4obCF8SInoUzvTYtc3bkb5w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", + "@typescript-eslint/types": "8.0.1", + "@typescript-eslint/visitor-keys": "8.0.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2522,7 +1857,7 @@ "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -2535,38 +1870,38 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.16.1.tgz", - "integrity": "sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.1.tgz", + "integrity": "sha512-CBFR0G0sCt0+fzfnKaciu9IBsKvEKYwN9UZ+eeogK1fYHg4Qxk1yf/wLQkLXlq8wbU2dFlgAesxt8Gi76E8RTA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.16.1", - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/typescript-estree": "7.16.1" + "@typescript-eslint/scope-manager": "8.0.1", + "@typescript-eslint/types": "8.0.1", + "@typescript-eslint/typescript-estree": "8.0.1" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.16.1.tgz", - "integrity": "sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.1.tgz", + "integrity": "sha512-W5E+o0UfUcK5EgchLZsyVWqARmsM7v54/qEq6PY3YI5arkgmCzHiuk0zKSJJbm71V0xdRna4BGomkCTXz2/LkQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/types": "8.0.1", "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -3286,9 +2621,9 @@ } }, "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.8", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.8.tgz", - "integrity": "sha512-MIKAclwaDFIiYtVBLzDdm16E+Ty4GwhB6wZlCAG1R3Ur+F9Qbo6PRxpA5DK7XtDgm+WlCoAY2WxAwqhmIDHg6Q==", + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.9.tgz", + "integrity": "sha512-QK49YrBAo5CLNLseZ7sZgvgTy21E6NEw22eZqc4teZfH8pxV3yXc9XXOYfUI6JNpw7mfHNkAeWtBxrTyykB6HA==", "dev": true, "peerDependencies": { "eslint": ">=7" @@ -3624,20 +2959,6 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -5797,9 +5118,9 @@ } }, "node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -5893,9 +5214,9 @@ "optional": true }, "node_modules/vite": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", - "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==", + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.5.tgz", + "integrity": "sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==", "dev": true, "dependencies": { "esbuild": "^0.21.3", diff --git a/playground/package.json b/playground/package.json index b8b263a9a3..0e44c066ed 100644 --- a/playground/package.json +++ b/playground/package.json @@ -20,13 +20,13 @@ "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@types/swagger-ui-react": "^4.18.3", - "@typescript-eslint/eslint-plugin": "^7.16.1", - "@typescript-eslint/parser": "^7.16.1", + "@typescript-eslint/eslint-plugin": "^8.0.1", + "@typescript-eslint/parser": "^8.0.1", "@vitejs/plugin-react-swc": "^3.7.0", "eslint": "^8.57.0", "eslint-plugin-react-hooks": "^4.6.2", - "eslint-plugin-react-refresh": "^0.4.7", - "typescript": "^5.5.3", - "vite": "^5.3.4" + "eslint-plugin-react-refresh": "^0.4.9", + "typescript": "^5.5.4", + "vite": "^5.3.5" } } From a74bd92153cce79963a52b1a3c90c574812c4970 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 22:21:09 -0400 Subject: [PATCH 29/41] bot: Bump golang.org/x/term from 0.22.0 to 0.23.0 (#2890) Bumps [golang.org/x/term](https://github.com/golang/term) from 0.22.0 to 0.23.0.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=golang.org/x/term&package-manager=go_modules&previous-version=0.22.0&new-version=0.23.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 858aff0285..680ae39650 100644 --- a/go.mod +++ b/go.mod @@ -59,7 +59,7 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.28.0 go.uber.org/zap v1.27.0 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 - golang.org/x/term v0.22.0 + golang.org/x/term v0.23.0 google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 ) @@ -360,7 +360,7 @@ require ( golang.org/x/net v0.26.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect + golang.org/x/sys v0.23.0 // indirect golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.22.0 // indirect diff --git a/go.sum b/go.sum index 0f22b26344..4b2fa38972 100644 --- a/go.sum +++ b/go.sum @@ -1880,8 +1880,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1893,8 +1893,8 @@ golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= From 356f47cc8e8ae5c4b0fd679dd5bf99a622882aef Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 07:50:36 -0400 Subject: [PATCH 30/41] bot: Bump eslint from 8.57.0 to 9.9.0 in /playground (#2903) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [eslint](https://github.com/eslint/eslint) from 8.57.0 to 9.9.0.
Release notes

Sourced from eslint's releases.

v9.9.0

Features

  • 41d0206 feat: Add support for TS config files (#18134) (Arya Emami)
  • 3a4eaf9 feat: add suggestion to require-await to remove async keyword (#18716) (Dave)

Documentation

  • 9fe068c docs: how to author plugins with configs that extend other configs (#18753) (Alec Gibson)
  • 48117b2 docs: add version support page in the side navbar (#18738) (Amaresh S M)
  • fec2951 docs: add version support page to the dropdown (#18730) (Amaresh S M)
  • 38a0661 docs: Fix typo (#18735) (Zaina Al Habash)
  • 3c32a9e docs: Update yarn command for creating ESLint config (#18739) (Temitope Ogunleye)
  • f9ac978 docs: Update README (GitHub Actions Bot)

Chores

  • 461b2c3 chore: upgrade to @eslint/js@9.9.0 (#18765) (Francesco Trotta)
  • 59dba1b chore: package.json update for @​eslint/js release (Jenkins)
  • fea8563 chore: update dependency @​eslint/core to ^0.3.0 (#18724) (renovate[bot])
  • aac191e chore: update dependency @​eslint/json to ^0.3.0 (#18760) (renovate[bot])
  • b97fa05 chore: update wdio dependencies for more stable tests (#18759) (Christian Bromann)

v9.8.0

Features

  • 13d0bd3 feat: Add and use SourceCode#getLoc/getRange (#18703) (Nicholas C. Zakas)

Bug Fixes

  • ab0ff27 fix: Throw error when invalid flags passed (#18705) (Nicholas C. Zakas)
  • 70dc803 fix: basePath directory can never be ignored (#18711) (Milos Djermanovic)

Documentation

Build Related

  • 4514424 build: Enable JSON linting (#18681) (Nicholas C. Zakas)

Chores

  • deee448 chore: upgrade to @eslint/js@9.8.0 (#18720) (Francesco Trotta)
  • 4aaf2b3 chore: package.json update for @​eslint/js release (Jenkins)
  • 8e1a627 chore: update dependency @​eslint/core to ^0.2.0 (#18700) (renovate[bot])

v9.7.0

Features

  • 7bd9839 feat: add support for es2025 duplicate named capturing groups (#18630) (Yosuke Ota)
  • 1381394 feat: add regex option in no-restricted-imports (#18622) (Nitin Kumar)

Bug Fixes

  • 14e9f81 fix: destructuring in catch clause in no-unused-vars (#18636) (Francesco Trotta)

Documentation

... (truncated)

Changelog

Sourced from eslint's changelog.

v9.9.0 - August 9, 2024

  • 461b2c3 chore: upgrade to @eslint/js@9.9.0 (#18765) (Francesco Trotta)
  • 59dba1b chore: package.json update for @​eslint/js release (Jenkins)
  • fea8563 chore: update dependency @​eslint/core to ^0.3.0 (#18724) (renovate[bot])
  • 41d0206 feat: Add support for TS config files (#18134) (Arya Emami)
  • aac191e chore: update dependency @​eslint/json to ^0.3.0 (#18760) (renovate[bot])
  • 9fe068c docs: how to author plugins with configs that extend other configs (#18753) (Alec Gibson)
  • b97fa05 chore: update wdio dependencies for more stable tests (#18759) (Christian Bromann)
  • 3a4eaf9 feat: add suggestion to require-await to remove async keyword (#18716) (Dave)
  • 48117b2 docs: add version support page in the side navbar (#18738) (Amaresh S M)
  • fec2951 docs: add version support page to the dropdown (#18730) (Amaresh S M)
  • 38a0661 docs: Fix typo (#18735) (Zaina Al Habash)
  • 3c32a9e docs: Update yarn command for creating ESLint config (#18739) (Temitope Ogunleye)
  • f9ac978 docs: Update README (GitHub Actions Bot)

v9.8.0 - July 26, 2024

  • deee448 chore: upgrade to @eslint/js@9.8.0 (#18720) (Francesco Trotta)
  • 4aaf2b3 chore: package.json update for @​eslint/js release (Jenkins)
  • 8e1a627 chore: update dependency @​eslint/core to ^0.2.0 (#18700) (renovate[bot])
  • 13d0bd3 feat: Add and use SourceCode#getLoc/getRange (#18703) (Nicholas C. Zakas)
  • 282df1a docs: Add system theme option (#18617) (Amaresh S M)
  • ab0ff27 fix: Throw error when invalid flags passed (#18705) (Nicholas C. Zakas)
  • 70dc803 fix: basePath directory can never be ignored (#18711) (Milos Djermanovic)
  • 53b1ff0 docs: Debug config docs (#18698) (Nicholas C. Zakas)
  • 4514424 build: Enable JSON linting (#18681) (Nicholas C. Zakas)
  • a7016a5 docs: fix search input stylings (#18682) (Amaresh S M)

v9.7.0 - July 12, 2024

  • 793b718 chore: upgrade @​eslint/js@​9.7.0 (#18680) (Francesco Trotta)
  • 7ed6f9a chore: package.json update for @​eslint/js release (Jenkins)
  • 14e9f81 fix: destructuring in catch clause in no-unused-vars (#18636) (Francesco Trotta)
  • 7bcda76 refactor: Add type references (#18652) (Nicholas C. Zakas)
  • 51bf57c chore: add tech sponsors through actions (#18624) (Strek)
  • 9f416db docs: Add Powered by Algolia label to the search. (#18633) (Amaresh S M)
  • 6320732 refactor: don't use parent property in NodeEventGenerator (#18653) (Milos Djermanovic)
  • 7bd9839 feat: add support for es2025 duplicate named capturing groups (#18630) (Yosuke Ota)
  • 1381394 feat: add regex option in no-restricted-imports (#18622) (Nitin Kumar)
  • 9e6d640 refactor: move "Parsing error" prefix adding to Linter (#18650) (Milos Djermanovic)
  • c8d26cb docs: Open JS Foundation -> OpenJS Foundation (#18649) (Milos Djermanovic)
  • 6e79ac7 docs: loadESLint does not support option cwd (#18641) (Francesco Trotta)

v9.6.0 - June 28, 2024

  • b15ee30 chore: upgrade @​eslint/js@​9.6.0 (#18632) (Milos Djermanovic)
  • d655503 chore: package.json update for @​eslint/js release (Jenkins)
  • 1613e2e fix: Allow escaping characters in config patterns on Windows (#18628) (Milos Djermanovic)
  • 13dbecd docs: Limit search to just docs (#18627) (Nicholas C. Zakas)

... (truncated)

Commits
  • 0dd3863 9.9.0
  • 2e5ba77 Build: changelog update for 9.9.0
  • 461b2c3 chore: upgrade to @eslint/js@9.9.0 (#18765)
  • 59dba1b chore: package.json update for @​eslint/js release
  • fea8563 chore: update dependency @​eslint/core to ^0.3.0 (#18724)
  • 41d0206 feat: Add support for TS config files (#18134)
  • aac191e chore: update dependency @​eslint/json to ^0.3.0 (#18760)
  • 9fe068c docs: how to author plugins with configs that extend other configs (#18753)
  • b97fa05 chore: update wdio dependencies for more stable tests (#18759)
  • 3a4eaf9 feat: add suggestion to require-await to remove async keyword (#18716)
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=eslint&package-manager=npm_and_yarn&previous-version=8.57.0&new-version=9.9.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Shahzad Lone --- playground/package-lock.json | 1610 ++++++++++++---------------------- playground/package.json | 2 +- tools/defradb.containerfile | 2 +- 3 files changed, 547 insertions(+), 1067 deletions(-) diff --git a/playground/package-lock.json b/playground/package-lock.json index ebf9541943..7093c27fef 100644 --- a/playground/package-lock.json +++ b/playground/package-lock.json @@ -21,7 +21,7 @@ "@typescript-eslint/eslint-plugin": "^8.0.1", "@typescript-eslint/parser": "^8.0.1", "@vitejs/plugin-react-swc": "^3.7.0", - "eslint": "^8.57.0", + "eslint": "^9.9.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.9", "typescript": "^5.5.4", @@ -30,8 +30,7 @@ }, "node_modules/@babel/runtime": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", - "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -41,8 +40,7 @@ }, "node_modules/@babel/runtime-corejs3": { "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.24.8.tgz", - "integrity": "sha512-DXG/BhegtMHhnN7YPIvxWd303/9aXvYFD1TjNL3CD6tUrhI2LVsg3Lck0aql5TRH29n4sj3emcROypkZVUfSuA==", + "license": "MIT", "dependencies": { "core-js-pure": "^3.30.2", "regenerator-runtime": "^0.14.0" @@ -53,44 +51,11 @@ }, "node_modules/@braintree/sanitize-url": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.0.2.tgz", - "integrity": "sha512-NVf/1YycDMs6+FxS0Tb/W8MjJRDQdXF+tBfDtZ5UZeiRUkTmwKc4vmYCKZTyymfJk1gnMsauvZSX/HiV9jOABw==" - }, - "node_modules/@codemirror/language": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.0.0.tgz", - "integrity": "sha512-rtjk5ifyMzOna1c7PBu7J1VCt0PvA5wy3o8eMVnxMKb7z8KA7JFecvD04dSn14vj/bBaAbqRsGed5OjtofEnLA==", - "peer": true, - "dependencies": { - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", - "@lezer/common": "^1.0.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0", - "style-mod": "^4.0.0" - } - }, - "node_modules/@codemirror/state": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz", - "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==", - "peer": true - }, - "node_modules/@codemirror/view": { - "version": "6.28.5", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.28.5.tgz", - "integrity": "sha512-NkUtfUa1lV7Jqg5DfHE/uLl7jKyoymDkaueMQXzePYuezL7FwX3ATANy74iAGlHCGe25hBGB0R+I5dC5EZ5JBg==", - "peer": true, - "dependencies": { - "@codemirror/state": "^6.4.0", - "style-mod": "^4.1.0", - "w3c-keyname": "^2.2.4" - } + "license": "MIT" }, "node_modules/@emotion/is-prop-valid": { "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", - "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "license": "MIT", "optional": true, "dependencies": { "@emotion/memoize": "0.7.4" @@ -98,18 +63,16 @@ }, "node_modules/@emotion/memoize": { "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", - "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", + "license": "MIT", "optional": true }, "node_modules/@esbuild/linux-x64": { "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -120,9 +83,8 @@ }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -135,23 +97,58 @@ }, "node_modules/@eslint-community/regexpp": { "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/config-array": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz", + "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==", + "dev": true, + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -159,7 +156,7 @@ "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -188,26 +185,33 @@ } }, "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.0.tgz", + "integrity": "sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@floating-ui/core": { "version": "1.6.4", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.4.tgz", - "integrity": "sha512-a4IowK4QkXl4SCWTGUR0INAfEOX3wtsYw3rKK5InQEHMGObkR8Xk44qYQD9P4r6HHw0iIfK6GUKECmY8sTkqRA==", + "license": "MIT", "dependencies": { "@floating-ui/utils": "^0.2.4" } }, "node_modules/@floating-ui/dom": { "version": "1.6.7", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.7.tgz", - "integrity": "sha512-wmVfPG5o2xnKDU4jx/m4w5qva9FWHcnZ8BvzEe90D/RpwsJaTAVYPEPdQ8sbr/N8zZTAHlZUTQdqg8ZUbzHmng==", + "license": "MIT", "dependencies": { "@floating-ui/core": "^1.6.0", "@floating-ui/utils": "^0.2.4" @@ -215,8 +219,7 @@ }, "node_modules/@floating-ui/react-dom": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", - "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", + "license": "MIT", "dependencies": { "@floating-ui/dom": "^1.0.0" }, @@ -227,13 +230,11 @@ }, "node_modules/@floating-ui/utils": { "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.4.tgz", - "integrity": "sha512-dWO2pw8hhi+WrXq1YJy2yCuWoL20PddgGaqTgVe4cOS9Q6qklXCiA1tJEqX6BEwRNSCP84/afac9hd4MS+zEUA==" + "license": "MIT" }, "node_modules/@graphiql/react": { "version": "0.22.4", - "resolved": "https://registry.npmjs.org/@graphiql/react/-/react-0.22.4.tgz", - "integrity": "sha512-FsupNjAUJ17qhdyCjKo150wpNH7gr0ScAm/Rmk7VHP4Mh0Osid+1bKLPtXEOjGI+InuTPSKhJw3Zbm8dD3+o1A==", + "license": "MIT", "dependencies": { "@graphiql/toolkit": "^0.9.1", "@headlessui/react": "^1.7.15", @@ -259,8 +260,7 @@ }, "node_modules/@graphiql/toolkit": { "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@graphiql/toolkit/-/toolkit-0.9.1.tgz", - "integrity": "sha512-LVt9pdk0830so50ZnU2Znb2rclcoWznG8r8asqAENzV0U1FM1kuY0sdPpc/rBc9MmmNgnB6A+WZzDhq6dbhTHA==", + "license": "MIT", "dependencies": { "@n1ru4l/push-pull-async-iterable-iterator": "^3.1.0", "meros": "^1.1.4" @@ -277,8 +277,7 @@ }, "node_modules/@headlessui/react": { "version": "1.7.19", - "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.19.tgz", - "integrity": "sha512-Ll+8q3OlMJfJbAKM/+/Y2q6PPYbryqNTXDbryx7SXLIDamkF6iQFbriYHga0dY44PvDhvvBWCx1Xj4U5+G4hOw==", + "license": "MIT", "dependencies": { "@tanstack/react-virtual": "^3.0.0-beta.60", "client-only": "^0.0.1" @@ -291,48 +290,10 @@ "react-dom": "^16 || ^17 || ^18" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -341,41 +302,22 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true - }, - "node_modules/@lezer/common": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz", - "integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ==", - "peer": true - }, - "node_modules/@lezer/highlight": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz", - "integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==", - "peer": true, - "dependencies": { - "@lezer/common": "^1.0.0" - } - }, - "node_modules/@lezer/lr": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.1.tgz", - "integrity": "sha512-CHsKq8DMKBf9b3yXPDIU4DbH+ZJd/sJdYOW2llbW/HudP5u0VS6Bfq1hLYfgU7uAYGFIyGGQIsSOXGPEErZiJw==", - "peer": true, - "dependencies": { - "@lezer/common": "^1.0.0" + "node_modules/@humanwhocodes/retry": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", + "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, "node_modules/@motionone/animation": { "version": "10.18.0", - "resolved": "https://registry.npmjs.org/@motionone/animation/-/animation-10.18.0.tgz", - "integrity": "sha512-9z2p5GFGCm0gBsZbi8rVMOAJCtw1WqBTIPw3ozk06gDvZInBPIsQcHgYogEJ4yuHJ+akuW8g1SEIOpTOvYs8hw==", + "license": "MIT", "dependencies": { "@motionone/easing": "^10.18.0", "@motionone/types": "^10.17.1", @@ -385,8 +327,7 @@ }, "node_modules/@motionone/dom": { "version": "10.12.0", - "resolved": "https://registry.npmjs.org/@motionone/dom/-/dom-10.12.0.tgz", - "integrity": "sha512-UdPTtLMAktHiqV0atOczNYyDd/d8Cf5fFsd1tua03PqTwwCe/6lwhLSQ8a7TbnQ5SN0gm44N1slBfj+ORIhrqw==", + "license": "MIT", "dependencies": { "@motionone/animation": "^10.12.0", "@motionone/generators": "^10.12.0", @@ -398,8 +339,7 @@ }, "node_modules/@motionone/easing": { "version": "10.18.0", - "resolved": "https://registry.npmjs.org/@motionone/easing/-/easing-10.18.0.tgz", - "integrity": "sha512-VcjByo7XpdLS4o9T8t99JtgxkdMcNWD3yHU/n6CLEz3bkmKDRZyYQ/wmSf6daum8ZXqfUAgFeCZSpJZIMxaCzg==", + "license": "MIT", "dependencies": { "@motionone/utils": "^10.18.0", "tslib": "^2.3.1" @@ -407,8 +347,7 @@ }, "node_modules/@motionone/generators": { "version": "10.18.0", - "resolved": "https://registry.npmjs.org/@motionone/generators/-/generators-10.18.0.tgz", - "integrity": "sha512-+qfkC2DtkDj4tHPu+AFKVfR/C30O1vYdvsGYaR13W/1cczPrrcjdvYCj0VLFuRMN+lP1xvpNZHCRNM4fBzn1jg==", + "license": "MIT", "dependencies": { "@motionone/types": "^10.17.1", "@motionone/utils": "^10.18.0", @@ -417,13 +356,11 @@ }, "node_modules/@motionone/types": { "version": "10.17.1", - "resolved": "https://registry.npmjs.org/@motionone/types/-/types-10.17.1.tgz", - "integrity": "sha512-KaC4kgiODDz8hswCrS0btrVrzyU2CSQKO7Ps90ibBVSQmjkrt2teqta6/sOG59v7+dPnKMAg13jyqtMKV2yJ7A==" + "license": "MIT" }, "node_modules/@motionone/utils": { "version": "10.18.0", - "resolved": "https://registry.npmjs.org/@motionone/utils/-/utils-10.18.0.tgz", - "integrity": "sha512-3XVF7sgyTSI2KWvTf6uLlBJ5iAgRgmvp3bpuOiQJvInd4nZ19ET8lX5unn30SlmRH7hXbBbH+Gxd0m0klJ3Xtw==", + "license": "MIT", "dependencies": { "@motionone/types": "^10.17.1", "hey-listen": "^1.0.8", @@ -432,17 +369,15 @@ }, "node_modules/@n1ru4l/push-pull-async-iterable-iterator": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@n1ru4l/push-pull-async-iterable-iterator/-/push-pull-async-iterable-iterator-3.2.0.tgz", - "integrity": "sha512-3fkKj25kEjsfObL6IlKPAlHYPq/oYwUkkQ03zsTTiDjD7vg/RxjdiLeCydqtxHZP0JgsXL3D/X5oAkMGzuUp/Q==", + "license": "MIT", "engines": { "node": ">=12" } }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -453,18 +388,16 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -475,13 +408,11 @@ }, "node_modules/@radix-ui/primitive": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", - "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==" + "license": "MIT" }, "node_modules/@radix-ui/react-arrow": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", - "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==", + "license": "MIT", "dependencies": { "@radix-ui/react-primitive": "2.0.0" }, @@ -502,8 +433,7 @@ }, "node_modules/@radix-ui/react-collection": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz", - "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==", + "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.0", "@radix-ui/react-context": "1.1.0", @@ -527,8 +457,7 @@ }, "node_modules/@radix-ui/react-compose-refs": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", - "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -541,8 +470,7 @@ }, "node_modules/@radix-ui/react-context": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", - "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -555,8 +483,7 @@ }, "node_modules/@radix-ui/react-dialog": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.1.tgz", - "integrity": "sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==", + "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", @@ -590,8 +517,7 @@ }, "node_modules/@radix-ui/react-direction": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", - "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -604,8 +530,7 @@ }, "node_modules/@radix-ui/react-dismissable-layer": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz", - "integrity": "sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==", + "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", @@ -630,8 +555,7 @@ }, "node_modules/@radix-ui/react-dropdown-menu": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.1.tgz", - "integrity": "sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==", + "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", @@ -658,8 +582,7 @@ }, "node_modules/@radix-ui/react-focus-guards": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz", - "integrity": "sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -672,8 +595,7 @@ }, "node_modules/@radix-ui/react-focus-scope": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz", - "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==", + "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.0", "@radix-ui/react-primitive": "2.0.0", @@ -696,8 +618,7 @@ }, "node_modules/@radix-ui/react-id": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", - "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", + "license": "MIT", "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.0" }, @@ -713,8 +634,7 @@ }, "node_modules/@radix-ui/react-menu": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.1.tgz", - "integrity": "sha512-oa3mXRRVjHi6DZu/ghuzdylyjaMXLymx83irM7hTxutQbD+7IhPKdMdRHD26Rm+kHRrWcrUkkRPv5pd47a2xFQ==", + "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-collection": "1.1.0", @@ -752,8 +672,7 @@ }, "node_modules/@radix-ui/react-popper": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", - "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==", + "license": "MIT", "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.0", @@ -783,8 +702,7 @@ }, "node_modules/@radix-ui/react-portal": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.1.tgz", - "integrity": "sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==", + "license": "MIT", "dependencies": { "@radix-ui/react-primitive": "2.0.0", "@radix-ui/react-use-layout-effect": "1.1.0" @@ -806,8 +724,7 @@ }, "node_modules/@radix-ui/react-presence": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz", - "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==", + "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.0", "@radix-ui/react-use-layout-effect": "1.1.0" @@ -829,8 +746,7 @@ }, "node_modules/@radix-ui/react-primitive": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", - "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", + "license": "MIT", "dependencies": { "@radix-ui/react-slot": "1.1.0" }, @@ -851,8 +767,7 @@ }, "node_modules/@radix-ui/react-roving-focus": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz", - "integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==", + "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-collection": "1.1.0", @@ -881,8 +796,7 @@ }, "node_modules/@radix-ui/react-slot": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", - "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", + "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.0" }, @@ -898,8 +812,7 @@ }, "node_modules/@radix-ui/react-tooltip": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.2.tgz", - "integrity": "sha512-9XRsLwe6Yb9B/tlnYCPVUd/TFS4J7HuOZW345DCeC6vKIxQGMZdx21RK4VoZauPD5frgkXTYVS5y90L+3YBn4w==", + "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", @@ -931,8 +844,7 @@ }, "node_modules/@radix-ui/react-use-callback-ref": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", - "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -945,8 +857,7 @@ }, "node_modules/@radix-ui/react-use-controllable-state": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", - "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", + "license": "MIT", "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.0" }, @@ -962,8 +873,7 @@ }, "node_modules/@radix-ui/react-use-escape-keydown": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", - "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", + "license": "MIT", "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.0" }, @@ -979,8 +889,7 @@ }, "node_modules/@radix-ui/react-use-layout-effect": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", - "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -993,8 +902,7 @@ }, "node_modules/@radix-ui/react-use-rect": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", - "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", + "license": "MIT", "dependencies": { "@radix-ui/rect": "1.1.0" }, @@ -1010,8 +918,7 @@ }, "node_modules/@radix-ui/react-use-size": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", - "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", + "license": "MIT", "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.0" }, @@ -1027,8 +934,7 @@ }, "node_modules/@radix-ui/react-visually-hidden": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz", - "integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==", + "license": "MIT", "dependencies": { "@radix-ui/react-primitive": "2.0.0" }, @@ -1049,17 +955,15 @@ }, "node_modules/@radix-ui/rect": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", - "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==" + "license": "MIT" }, "node_modules/@rollup/rollup-linux-x64-gnu": { "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.1.tgz", - "integrity": "sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -1067,12 +971,11 @@ }, "node_modules/@rollup/rollup-linux-x64-musl": { "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.1.tgz", - "integrity": "sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -1080,8 +983,7 @@ }, "node_modules/@swagger-api/apidom-ast": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-1.0.0-alpha.6.tgz", - "integrity": "sha512-uzDNIeTLFeITzK7yX9PSsu3dl92rHP/gKMNAlJhmDRr7r+OLr5dCpAzyZ0WvONRxjxR8Otj5LX4AD12+EX32fg==", + "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", "@swagger-api/apidom-error": "^1.0.0-alpha.6", @@ -1093,8 +995,7 @@ }, "node_modules/@swagger-api/apidom-core": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-1.0.0-alpha.6.tgz", - "integrity": "sha512-5u7dK3+8cF2h5bHEI/qrA6JrfXX+HIHSmUgPGbeMAqSCEfpsjnsngXK6gHtd4ktLlPz3TplNZAQl88wIp+39nw==", + "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", "@swagger-api/apidom-ast": "^1.0.0-alpha.6", @@ -1109,16 +1010,14 @@ }, "node_modules/@swagger-api/apidom-error": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-error/-/apidom-error-1.0.0-alpha.6.tgz", - "integrity": "sha512-eOcqaXwLitjp5CIGYR0W2oM6p4UiTL7EjNdkCcfrELKHdgNS6U7kZdl3KCBlOuMb14CijwtZNEJbIGhhGZUYHg==", + "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.20.7" } }, "node_modules/@swagger-api/apidom-json-pointer": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-1.0.0-alpha.6.tgz", - "integrity": "sha512-8ULBcQRQ1UPgqJ+ZuuKjmeKeuxqbuIUHwWHRRA848jK5+IHmNw/Cp68MhNiwYXLmTLkTIGaDubcOplMeHCxSyA==", + "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", "@swagger-api/apidom-core": "^1.0.0-alpha.6", @@ -1130,8 +1029,7 @@ }, "node_modules/@swagger-api/apidom-ns-api-design-systems": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-api-design-systems/-/apidom-ns-api-design-systems-1.0.0-alpha.6.tgz", - "integrity": "sha512-JRiImw3XKrfm22pzlx7uM6XYJtWM71QkCLy86gOTBFybWgTOCECnN4c8jFBnYl6KYuIb2VV9kXZs38xjK4NfBQ==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", @@ -1146,8 +1044,7 @@ }, "node_modules/@swagger-api/apidom-ns-asyncapi-2": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-asyncapi-2/-/apidom-ns-asyncapi-2-1.0.0-alpha.6.tgz", - "integrity": "sha512-I8Yq+AmJPUJihGneBv1/m/ly+2dp4FJiCxW/auRQSicvYIV7hoBO5qGZqcEEoVt7OpuhFbFqI2pwnambz90Uvg==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", @@ -1161,8 +1058,7 @@ }, "node_modules/@swagger-api/apidom-ns-json-schema-draft-4": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-1.0.0-alpha.6.tgz", - "integrity": "sha512-E8JjqdDgopnLd4HXEXGSrc6rkbDyB8Qk6sYgmyT6lB8caFUMRdJ5Rp57fPePETnVpegb8cAuKjBdjTImX1gQ3Q==", + "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", "@swagger-api/apidom-ast": "^1.0.0-alpha.6", @@ -1175,8 +1071,7 @@ }, "node_modules/@swagger-api/apidom-ns-json-schema-draft-6": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-1.0.0-alpha.6.tgz", - "integrity": "sha512-uzYmV65nn7i6nlp7Kp7ldGfAoXWPPquIocoHLWDBTx5sPdS+ALu2T2yvytav0z6StKeV+gU2HZjMLVRWdLzLZA==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", @@ -1191,8 +1086,7 @@ }, "node_modules/@swagger-api/apidom-ns-json-schema-draft-7": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-1.0.0-alpha.6.tgz", - "integrity": "sha512-dWEVUVMByOs5JIMsgcceETOYH3nTiAHoIIjXbYeHP6m6HaNP8IE5ex0ZgfmQc29uH0E6H+6aYAv1flfvy56rVQ==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", @@ -1207,8 +1101,7 @@ }, "node_modules/@swagger-api/apidom-ns-openapi-2": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-2/-/apidom-ns-openapi-2-1.0.0-alpha.6.tgz", - "integrity": "sha512-sPwvOY+FGd5yEAijYLupmIYwf4HIpW6yegzrz6uUvGmONZpiCNIidCu+2m6GyYCoZ/lQZdPMw29DuU2O4iiDKw==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", @@ -1223,8 +1116,7 @@ }, "node_modules/@swagger-api/apidom-ns-openapi-3-0": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-1.0.0-alpha.6.tgz", - "integrity": "sha512-kE4s17j69DDvXrf7xeRTunmSQJLiX52fCX1YnfC81e1IPm3q/mdpkZiysM87FuJQQj522fX2G+QUIJlDkD5U9w==", + "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", "@swagger-api/apidom-core": "^1.0.0-alpha.6", @@ -1238,8 +1130,7 @@ }, "node_modules/@swagger-api/apidom-ns-openapi-3-1": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-1.0.0-alpha.6.tgz", - "integrity": "sha512-2QA2z9beyaVyZDOXbLg4Nu8o8xKWo9L0WHWOP+hg/haGRyyPHXgyg2XdwRuFBozBI9wBaIfEg1lvNC+J0taDjg==", + "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", "@swagger-api/apidom-ast": "^1.0.0-alpha.6", @@ -1254,8 +1145,7 @@ }, "node_modules/@swagger-api/apidom-ns-workflows-1": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-workflows-1/-/apidom-ns-workflows-1-1.0.0-alpha.6.tgz", - "integrity": "sha512-9kXU7hUdz25TTGF8b1pmKGugkET4gkW7ING+qSUjU5nWdrkdUIVuq1o8qjaZwRDRvkNynnlRbWHqXeWgRWyi/w==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", @@ -1269,8 +1159,7 @@ }, "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-json": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-json/-/apidom-parser-adapter-api-design-systems-json-1.0.0-alpha.6.tgz", - "integrity": "sha512-7THBmhvwTmsb1eFXvj/tbIK91g5tzkvhxGSUVbpGt1zApEFmKvjZbDhGnMx15CImIUURW1QZ6TQ/cZ7jRWk8kQ==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", @@ -1284,8 +1173,7 @@ }, "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-yaml": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/-/apidom-parser-adapter-api-design-systems-yaml-1.0.0-alpha.6.tgz", - "integrity": "sha512-xD0aRgRGPaM1J+H3nRg8qP6bQ4fNtsUopoc6JEKzi7NJxd+r/mZV4pVa+Gr6CS+xv4d6TJ53UCJmGsjgmR1bQw==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", @@ -1299,8 +1187,7 @@ }, "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-json-2": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-json-2/-/apidom-parser-adapter-asyncapi-json-2-1.0.0-alpha.6.tgz", - "integrity": "sha512-BVouq+7XiS2/HmNHd/CHHieyRT5mTN+kqYACnKV/TAzC5+fK3t2mcdng4I81m3Mzb9OJ/VpHiEVlSZiWZoPU/Q==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", @@ -1314,8 +1201,7 @@ }, "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/-/apidom-parser-adapter-asyncapi-yaml-2-1.0.0-alpha.6.tgz", - "integrity": "sha512-CsUu5t6ijflz0DDjdoxE/OUbSjBAeh5v2zfMRVOfGdnNDhDhrE/3P0VTpdKdVmbWQ1ueIbq2QaC8thQ+Jcxwyg==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", @@ -1329,8 +1215,7 @@ }, "node_modules/@swagger-api/apidom-parser-adapter-json": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-json/-/apidom-parser-adapter-json-1.0.0-alpha.6.tgz", - "integrity": "sha512-ruEkgvJSmBUUsGZdYiHeczekTWCJSWHrNvhAczY6c1ZFhpCukZg9tCqdVhnni/LPp4r4h7BdNldjY7dtrUkCiQ==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", @@ -1347,8 +1232,7 @@ }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-2": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-2/-/apidom-parser-adapter-openapi-json-2-1.0.0-alpha.6.tgz", - "integrity": "sha512-RLvjHvjURnqfWxEdLFOW6agBS8CzVyV9++Vg4TSB9gPCNsTlz5w9iy82NYvApExHJIlN55Ga92OZ6CuWXJ8iKw==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", @@ -1362,8 +1246,7 @@ }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-0": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-0/-/apidom-parser-adapter-openapi-json-3-0-1.0.0-alpha.6.tgz", - "integrity": "sha512-cf9+M9vySTrUZW+m2SR04IMnl+5QX6P7S2xgFF705ySOMkPiA9GTgAZJFqwzncAEPovkp7/A24adxyhFz52iZg==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", @@ -1377,8 +1260,7 @@ }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-1": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-1/-/apidom-parser-adapter-openapi-json-3-1-1.0.0-alpha.6.tgz", - "integrity": "sha512-Z7TCUWB/VotmHU5kjUcAlu3qMHCVr1pOpnsuI01I6vCHGJOqUZPelnNqVyw5tjiVbgwDCKzXiPSQo9gGG1HoGA==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", @@ -1392,8 +1274,7 @@ }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-2": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-2/-/apidom-parser-adapter-openapi-yaml-2-1.0.0-alpha.6.tgz", - "integrity": "sha512-XI0qlTjL2Q1TMvzxjjEki2iuJqt43C0mwGHremjcpbNHpJejnkEGFDPJqs1rp3RobwRl1ftHVFJi7JVPiA8Zvw==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", @@ -1407,8 +1288,7 @@ }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/-/apidom-parser-adapter-openapi-yaml-3-0-1.0.0-alpha.6.tgz", - "integrity": "sha512-yGd5dP52BrBMO4/nCJdcvotxCbmbXYOi/nQrj7rL4/7VFdKbC4ngT0ggprvKE8CVQC99qPz4qR1y728QdioPAg==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", @@ -1422,8 +1302,7 @@ }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/-/apidom-parser-adapter-openapi-yaml-3-1-1.0.0-alpha.6.tgz", - "integrity": "sha512-4F/rWh7bi97y20SRskrqz9UdO+YwHOn+vcOvNs5/arI5niSmTeAN3dgH9emTx1LJi8d7woUAct+TEqshwoh/zQ==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", @@ -1437,8 +1316,7 @@ }, "node_modules/@swagger-api/apidom-parser-adapter-workflows-json-1": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-workflows-json-1/-/apidom-parser-adapter-workflows-json-1-1.0.0-alpha.6.tgz", - "integrity": "sha512-K2gZFUHtp+Vw9rcizanIJLxSsaYQWNh1QtsEVGtAkn3RBVa130i3umcgQBKuvaBzfhi+Zr21sR4LSrs4XiRHiQ==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", @@ -1452,8 +1330,7 @@ }, "node_modules/@swagger-api/apidom-parser-adapter-workflows-yaml-1": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-workflows-yaml-1/-/apidom-parser-adapter-workflows-yaml-1-1.0.0-alpha.6.tgz", - "integrity": "sha512-yaJ9Iir43odK/zTB0tVL43RBC4ktQvNRfuT21vedqNaxO9J2pjTPy9NkIXJuOrcizinAASDLLUYX/b0UONhVxg==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", @@ -1467,8 +1344,7 @@ }, "node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-yaml-1-2/-/apidom-parser-adapter-yaml-1-2-1.0.0-alpha.6.tgz", - "integrity": "sha512-qevJf2IRvskyvgeGnkJXCGKFnmrcnuMoFHoboI3nJFqdesN74g1hGm1VIVAOOkM4AcdG1w7BviCHEt4YEYGPcQ==", + "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", @@ -1485,8 +1361,7 @@ }, "node_modules/@swagger-api/apidom-reference": { "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/@swagger-api/apidom-reference/-/apidom-reference-1.0.0-alpha.6.tgz", - "integrity": "sha512-DbsxxgQCVd8ZTJag3EOtzJ2rtsaq4z5z/A4nEgzVQhStuHdRwrbQfxem1g7p6dOK2VrGEGf73UllGJvGV+uPpg==", + "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", "@swagger-api/apidom-core": "^1.0.0-alpha.6", @@ -1523,8 +1398,7 @@ }, "node_modules/@swagger-api/apidom-reference/node_modules/minimatch": { "version": "7.4.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", - "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -1537,10 +1411,9 @@ }, "node_modules/@swc/core": { "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.7.0.tgz", - "integrity": "sha512-d4vMzH6ICllDwlPuhset2h8gu/USHdbyfJim+2hQEdxC0UONtfpmu38XBgNqRjStrji1Q5M10jfeUZL3cu1i8g==", "dev": true, "hasInstallScript": true, + "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.9" @@ -1575,12 +1448,11 @@ }, "node_modules/@swc/core-linux-x64-gnu": { "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.0.tgz", - "integrity": "sha512-SY3HA0K0Dpqt1HIfMLGpwL4hd4UaL2xHP5oZXPlRQPhUDZrbb4PbI3ZJnh66c63eL4ZR8EJ+HRFI0Alx5p69Zw==", "cpu": [ "x64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" @@ -1591,12 +1463,11 @@ }, "node_modules/@swc/core-linux-x64-musl": { "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.0.tgz", - "integrity": "sha512-cEJ2ebtV1v/5Ilb55E05J6F5SrHKQWzUttIhR5Mkayyo+yvPslcpByuFC3D+J7X1ebziTOBpWuMpUdjLfh3SMQ==", "cpu": [ "x64" ], "dev": true, + "license": "Apache-2.0 AND MIT", "optional": true, "os": [ "linux" @@ -1607,23 +1478,20 @@ }, "node_modules/@swc/counter": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", - "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/@swc/types": { "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.9.tgz", - "integrity": "sha512-qKnCno++jzcJ4lM4NTfYifm1EFSCeIfKiAHAfkENZAV5Kl9PjJIyd2yeeVv6c/2CckuLyv2NmRC5pv6pm2WQBg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@swc/counter": "^0.1.3" } }, "node_modules/@tanstack/react-virtual": { "version": "3.8.3", - "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.8.3.tgz", - "integrity": "sha512-9ICwbDUUzN99CJIGc373i8NLoj6zFTKI2Hlcmo0+lCSAhPQ5mxq4dGOMKmLYoEFyHcGQ64Bd6ZVbnPpM6lNK5w==", + "license": "MIT", "dependencies": { "@tanstack/virtual-core": "3.8.3" }, @@ -1638,8 +1506,7 @@ }, "node_modules/@tanstack/virtual-core": { "version": "3.8.3", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.8.3.tgz", - "integrity": "sha512-vd2A2TnM5lbnWZnHi9B+L2gPtkSeOtJOAw358JqokIH1+v2J7vUAzFVPwB/wrye12RFOurffXu33plm4uQ+JBQ==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" @@ -1647,44 +1514,38 @@ }, "node_modules/@types/codemirror": { "version": "5.60.15", - "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.15.tgz", - "integrity": "sha512-dTOvwEQ+ouKJ/rE9LT1Ue2hmP6H1mZv5+CCnNWu2qtiOe2LQa9lCprEY20HxiDmV/Bxh+dXjywmy5aKvoGjULA==", + "license": "MIT", "dependencies": { "@types/tern": "*" } }, "node_modules/@types/estree": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + "license": "MIT" }, "node_modules/@types/hast": { "version": "2.3.10", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", - "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", + "license": "MIT", "dependencies": { "@types/unist": "^2" } }, "node_modules/@types/prop-types": { "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", - "devOptional": true + "dev": true, + "license": "MIT" }, "node_modules/@types/ramda": { "version": "0.30.1", - "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.30.1.tgz", - "integrity": "sha512-aoyF/ADPL6N+/NXXfhPWF+Qj6w1Cql59m9wX0Gi15uyF+bpzXeLd63HPdiTDE2bmLXfNcVufsDPKmbfOrOzTBA==", + "license": "MIT", "dependencies": { "types-ramda": "^0.30.1" } }, "node_modules/@types/react": { "version": "18.3.3", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", - "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", - "devOptional": true, + "dev": true, + "license": "MIT", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -1692,45 +1553,39 @@ }, "node_modules/@types/react-dom": { "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", - "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", - "devOptional": true, + "dev": true, + "license": "MIT", "dependencies": { "@types/react": "*" } }, "node_modules/@types/swagger-ui-react": { "version": "4.18.3", - "resolved": "https://registry.npmjs.org/@types/swagger-ui-react/-/swagger-ui-react-4.18.3.tgz", - "integrity": "sha512-Mo/R7IjDVwtiFPs84pWvh5pI9iyNGBjmfielxqbOh2Jv+8WVSDVe8Nu25kb5BOuV2xmGS3o33jr6nwDJMBcX+Q==", "dev": true, + "license": "MIT", "dependencies": { "@types/react": "*" } }, "node_modules/@types/tern": { "version": "0.23.9", - "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.9.tgz", - "integrity": "sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==", + "license": "MIT", "dependencies": { "@types/estree": "*" } }, "node_modules/@types/unist": { "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + "license": "MIT" }, "node_modules/@types/use-sync-external-store": { "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", - "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.0.1.tgz", - "integrity": "sha512-5g3Y7GDFsJAnY4Yhvk8sZtFfV6YNF2caLzjrRPUBzewjPCaj0yokePB4LJSobyCzGMzjZZYFbwuzbfDHlimXbQ==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.0.1", @@ -1761,9 +1616,8 @@ }, "node_modules/@typescript-eslint/parser": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.0.1.tgz", - "integrity": "sha512-5IgYJ9EO/12pOUwiBKFkpU7rS3IU21mtXzB81TNwq2xEybcmAZrE9qwDtsb5uQd9aVO9o0fdabFyAmKveXyujg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/scope-manager": "8.0.1", "@typescript-eslint/types": "8.0.1", @@ -1789,9 +1643,8 @@ }, "node_modules/@typescript-eslint/scope-manager": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.0.1.tgz", - "integrity": "sha512-NpixInP5dm7uukMiRyiHjRKkom5RIFA4dfiHvalanD2cF0CLUuQqxfg8PtEUo9yqJI2bBhF+pcSafqnG3UBnRQ==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.0.1", "@typescript-eslint/visitor-keys": "8.0.1" @@ -1806,9 +1659,8 @@ }, "node_modules/@typescript-eslint/type-utils": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.0.1.tgz", - "integrity": "sha512-+/UT25MWvXeDX9YaHv1IS6KI1fiuTto43WprE7pgSMswHbn1Jm9GEM4Txp+X74ifOWV8emu2AWcbLhpJAvD5Ng==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/typescript-estree": "8.0.1", "@typescript-eslint/utils": "8.0.1", @@ -1830,9 +1682,8 @@ }, "node_modules/@typescript-eslint/types": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.0.1.tgz", - "integrity": "sha512-PpqTVT3yCA/bIgJ12czBuE3iBlM3g4inRSC5J0QOdQFAn07TYrYEQBBKgXH1lQpglup+Zy6c1fxuwTk4MTNKIw==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -1843,9 +1694,8 @@ }, "node_modules/@typescript-eslint/typescript-estree": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.0.1.tgz", - "integrity": "sha512-8V9hriRvZQXPWU3bbiUV4Epo7EvgM6RTs+sUmxp5G//dBGy402S7Fx0W0QkB2fb4obCF8SInoUzvTYtc3bkb5w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "8.0.1", "@typescript-eslint/visitor-keys": "8.0.1", @@ -1871,9 +1721,8 @@ }, "node_modules/@typescript-eslint/utils": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.0.1.tgz", - "integrity": "sha512-CBFR0G0sCt0+fzfnKaciu9IBsKvEKYwN9UZ+eeogK1fYHg4Qxk1yf/wLQkLXlq8wbU2dFlgAesxt8Gi76E8RTA==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.0.1", @@ -1893,9 +1742,8 @@ }, "node_modules/@typescript-eslint/visitor-keys": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.0.1.tgz", - "integrity": "sha512-W5E+o0UfUcK5EgchLZsyVWqARmsM7v54/qEq6PY3YI5arkgmCzHiuk0zKSJJbm71V0xdRna4BGomkCTXz2/LkQ==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.0.1", "eslint-visitor-keys": "^3.4.3" @@ -1908,17 +1756,10 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, "node_modules/@vitejs/plugin-react-swc": { "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.7.0.tgz", - "integrity": "sha512-yrknSb3Dci6svCd/qhHqhFPDSw0QtjumcqdKMoNNzmOl5lMXTTiqzjWtG4Qask2HdvvzaNgSunbQGet8/GrKdA==", "dev": true, + "license": "MIT", "dependencies": { "@swc/core": "^1.5.7" }, @@ -1965,18 +1806,16 @@ }, "node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -1989,18 +1828,15 @@ }, "node_modules/apg-lite": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/apg-lite/-/apg-lite-1.0.4.tgz", - "integrity": "sha512-B32zCN3IdHIc99Vy7V9BaYTUzLeRA8YXYY1aQD1/5I2aqIrO0coi4t6hJPqMisidlBxhyME8UexkHt31SlR6Og==" + "license": "BSD-2-Clause" }, "node_modules/argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "license": "Python-2.0" }, "node_modules/aria-hidden": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", - "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", + "license": "MIT", "dependencies": { "tslib": "^2.0.0" }, @@ -2010,30 +1846,26 @@ }, "node_modules/array-union": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/asynckit": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "license": "MIT" }, "node_modules/autolinker": { "version": "3.16.2", - "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-3.16.2.tgz", - "integrity": "sha512-JiYl7j2Z19F9NdTmirENSUUIIL/9MytEWtmzhfmsKPCp9E+G35Y0UNCMoM9tFigxT59qSc8Ml2dlZXOCVTYwuA==", + "license": "MIT", "dependencies": { "tslib": "^2.3.0" } }, "node_modules/axios": { "version": "1.7.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", - "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -2042,13 +1874,10 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "license": "MIT" }, "node_modules/base64-js": { "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "funding": [ { "type": "github", @@ -2062,12 +1891,12 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/bl": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", "optional": true, "dependencies": { "buffer": "^5.5.0", @@ -2077,17 +1906,15 @@ }, "node_modules/brace-expansion": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, "node_modules/braces": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -2097,8 +1924,6 @@ }, "node_modules/buffer": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "funding": [ { "type": "github", @@ -2113,6 +1938,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "optional": true, "dependencies": { "base64-js": "^1.3.1", @@ -2121,8 +1947,7 @@ }, "node_modules/call-bind": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -2148,9 +1973,8 @@ }, "node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -2164,8 +1988,7 @@ }, "node_modules/character-entities": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -2173,8 +1996,7 @@ }, "node_modules/character-entities-legacy": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -2182,8 +2004,7 @@ }, "node_modules/character-reference-invalid": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -2191,37 +2012,31 @@ }, "node_modules/chownr": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC", "optional": true }, "node_modules/classnames": { "version": "2.5.1", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", - "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" + "license": "MIT" }, "node_modules/client-only": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + "license": "MIT" }, "node_modules/clsx": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/codemirror": { "version": "5.65.16", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.16.tgz", - "integrity": "sha512-br21LjYmSlVL0vFCPWPfhzUCT34FM/pAdK7rRIZwa0rrtrIdotvP4Oh4GUHsu2E3IrQMCfRkL/fN3ytMNxVQvg==" + "license": "MIT" }, "node_modules/codemirror-graphql": { "version": "2.0.12", - "resolved": "https://registry.npmjs.org/codemirror-graphql/-/codemirror-graphql-2.0.12.tgz", - "integrity": "sha512-5UCqhWzck1jClCmRewFb8aSiabnAqiaRfsvIPfmbf6WJvOb8oiefJeHilclPPiZBzY8v/Et6EBMtOeKnWCoyng==", + "license": "MIT", "dependencies": { "@types/codemirror": "^0.0.90", "graphql-language-service": "5.2.1" @@ -2234,17 +2049,15 @@ }, "node_modules/codemirror-graphql/node_modules/@types/codemirror": { "version": "0.0.90", - "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-0.0.90.tgz", - "integrity": "sha512-8Z9+tSg27NPRGubbUPUCrt5DDG/OWzLph5BvcDykwR5D7RyZh5mhHG0uS1ePKV1YFCA+/cwc4Ey2AJAEFfV3IA==", + "license": "MIT", "dependencies": { "@types/tern": "*" } }, "node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -2254,14 +2067,12 @@ }, "node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -2271,8 +2082,7 @@ }, "node_modules/comma-separated-tokens": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", - "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -2280,31 +2090,27 @@ }, "node_modules/concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cookie": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/copy-to-clipboard": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", - "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "license": "MIT", "dependencies": { "toggle-selection": "^1.0.6" } }, "node_modules/core-js-pure": { "version": "3.37.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.37.1.tgz", - "integrity": "sha512-J/r5JTHSmzTxbiYYrzXg9w1VpqrYt+gexenBE9pugeyhwPZTAEJddyiReJWsLO6uNQ8xJZFbod6XC7KKwatCiA==", "hasInstallScript": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" @@ -2312,9 +2118,8 @@ }, "node_modules/cross-spawn": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -2326,20 +2131,17 @@ }, "node_modules/css.escape": { "version": "1.5.1", - "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==" + "license": "MIT" }, "node_modules/csstype": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "devOptional": true + "dev": true, + "license": "MIT" }, "node_modules/debug": { "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, + "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -2354,8 +2156,7 @@ }, "node_modules/decompress-response": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "license": "MIT", "optional": true, "dependencies": { "mimic-response": "^3.1.0" @@ -2369,30 +2170,26 @@ }, "node_modules/deep-extend": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", "engines": { "node": ">=4.0.0" } }, "node_modules/deep-is": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/deepmerge": { "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/define-data-property": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -2407,16 +2204,14 @@ }, "node_modules/delayed-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/detect-libc": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", - "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "license": "Apache-2.0", "optional": true, "engines": { "node": ">=8" @@ -2424,14 +2219,12 @@ }, "node_modules/detect-node-es": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", - "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + "license": "MIT" }, "node_modules/dir-glob": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -2439,35 +2232,20 @@ "node": ">=8" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/dompurify": { "version": "3.1.4", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.4.tgz", - "integrity": "sha512-2gnshi6OshmuKil8rMZuQCGiUF3cUxHY3NGDzUAdUx/NPEe5DVnO8BDoAQouvgwnx0R/+a6jUn36Z0FSdq8vww==" + "license": "(MPL-2.0 OR Apache-2.0)" }, "node_modules/drange": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/drange/-/drange-1.1.1.tgz", - "integrity": "sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/end-of-stream": { "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "license": "MIT", "optional": true, "dependencies": { "once": "^1.4.0" @@ -2475,8 +2253,7 @@ }, "node_modules/entities": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -2486,8 +2263,7 @@ }, "node_modules/es-define-property": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -2497,18 +2273,16 @@ }, "node_modules/es-errors": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/esbuild": { "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -2543,9 +2317,8 @@ }, "node_modules/escape-string-regexp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -2554,41 +2327,37 @@ } }, "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "9.9.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.9.0.tgz", + "integrity": "sha512-JfiKJrbx0506OEerjK2Y1QlldtBxkAlLxT5OEcRF8uaQ86noDe2k31Vw9rnSWv+MXZHj7OOUV/dA0AhdLFcyvA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.17.1", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.9.0", "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.3.0", "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.0.2", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", @@ -2602,17 +2371,24 @@ "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, "node_modules/eslint-plugin-react-hooks": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", - "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -2622,24 +2398,23 @@ }, "node_modules/eslint-plugin-react-refresh": { "version": "0.4.9", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.9.tgz", - "integrity": "sha512-QK49YrBAo5CLNLseZ7sZgvgTy21E6NEw22eZqc4teZfH8pxV3yXc9XXOYfUI6JNpw7mfHNkAeWtBxrTyykB6HA==", "dev": true, + "license": "MIT", "peerDependencies": { "eslint": ">=7" } }, "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", + "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -2647,9 +2422,8 @@ }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -2659,19 +2433,29 @@ }, "node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -2680,17 +2464,29 @@ } }, "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", "dev": true, "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.12.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -2698,9 +2494,8 @@ }, "node_modules/esquery": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -2722,9 +2517,8 @@ }, "node_modules/estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -2740,8 +2534,7 @@ }, "node_modules/expand-template": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "license": "(MIT OR WTFPL)", "optional": true, "engines": { "node": ">=6" @@ -2755,9 +2548,8 @@ }, "node_modules/fast-glob": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -2771,9 +2563,8 @@ }, "node_modules/fast-glob/node_modules/glob-parent": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -2783,8 +2574,7 @@ }, "node_modules/fast-json-patch": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", - "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==" + "license": "MIT" }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", @@ -2794,23 +2584,20 @@ }, "node_modules/fast-levenshtein": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fastq": { "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, "node_modules/fault": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", - "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", + "license": "MIT", "dependencies": { "format": "^0.2.0" }, @@ -2820,22 +2607,21 @@ } }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/fill-range": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -2845,9 +2631,8 @@ }, "node_modules/find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -2860,17 +2645,16 @@ } }, "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "dependencies": { "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16" } }, "node_modules/flatted": { @@ -2881,14 +2665,13 @@ }, "node_modules/follow-redirects": { "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -2900,8 +2683,7 @@ }, "node_modules/form-data": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -2913,16 +2695,13 @@ }, "node_modules/format": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", "engines": { "node": ">=0.4.x" } }, "node_modules/framer-motion": { "version": "6.5.1", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-6.5.1.tgz", - "integrity": "sha512-o1BGqqposwi7cgDrtg0dNONhkmPsUFDaLcKXigzuTFC5x58mE8iyTazxSudFzmT6MEyJKfjjU8ItoMe3W+3fiw==", + "license": "MIT", "dependencies": { "@motionone/dom": "10.12.0", "framesync": "6.0.1", @@ -2941,36 +2720,26 @@ }, "node_modules/framesync": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/framesync/-/framesync-6.0.1.tgz", - "integrity": "sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==", + "license": "MIT", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/fs-constants": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT", "optional": true }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, "node_modules/function-bind": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/get-intrinsic": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -2987,44 +2756,20 @@ }, "node_modules/get-nonce": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", - "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/github-from-package": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "license": "MIT", "optional": true }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/glob-parent": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -3032,38 +2777,13 @@ "node": ">=10.13.0" } }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -3071,9 +2791,8 @@ }, "node_modules/globby": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -3091,8 +2810,7 @@ }, "node_modules/gopd": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -3102,14 +2820,12 @@ }, "node_modules/graphemer": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/graphiql": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/graphiql/-/graphiql-3.3.2.tgz", - "integrity": "sha512-LJ8Q6UM3kUzTXvybud9a4sj/QBEVHwHWd5Oc3OjLp9DQiKjqVY/2P/Q3RdPQD/MihwaO+6eC69R4MYnPQGd2Hw==", + "license": "MIT", "dependencies": { "@graphiql/react": "^0.22.4", "@graphiql/toolkit": "^0.9.1", @@ -3124,16 +2840,14 @@ }, "node_modules/graphql": { "version": "16.9.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.9.0.tgz", - "integrity": "sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==", + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } }, "node_modules/graphql-language-service": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/graphql-language-service/-/graphql-language-service-5.2.1.tgz", - "integrity": "sha512-8ewD6otGO43vg2TiEGjoLz3CweTwfaf4ZnqfNREqZXS2JSJGXtsRBOMMknCxMfFVh4x14ql3jyDrXcyAAtbmkQ==", + "license": "MIT", "dependencies": { "nullthrows": "^1.0.0", "vscode-languageserver-types": "^3.17.1" @@ -3147,17 +2861,15 @@ }, "node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/has-property-descriptors": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, @@ -3167,8 +2879,7 @@ }, "node_modules/has-proto": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -3178,8 +2889,7 @@ }, "node_modules/has-symbols": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -3189,8 +2899,7 @@ }, "node_modules/hasown": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -3200,8 +2909,7 @@ }, "node_modules/hast-util-parse-selector": { "version": "2.2.5", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", - "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -3209,8 +2917,7 @@ }, "node_modules/hastscript": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", - "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", + "license": "MIT", "dependencies": { "@types/hast": "^2.0.0", "comma-separated-tokens": "^1.0.0", @@ -3225,21 +2932,17 @@ }, "node_modules/hey-listen": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz", - "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==" + "license": "MIT" }, "node_modules/highlight.js": { "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "license": "BSD-3-Clause", "engines": { "node": "*" } }, "node_modules/ieee754": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", @@ -3253,21 +2956,20 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "BSD-3-Clause" }, "node_modules/ignore": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/immutable": { "version": "3.8.2", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", - "integrity": "sha512-15gZoQ38eYjEjxkorfbcgBKBL6R7T459OuK+CpcWt7O3KF4uPCx2tD0uFETlUDIyo+1789crbMhTvQBSR5yBMg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -3290,47 +2992,31 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "license": "ISC" }, "node_modules/ini": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC", "optional": true }, "node_modules/invariant": { "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", "dependencies": { "loose-envify": "^1.0.0" } }, "node_modules/is-alphabetical": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -3338,8 +3024,7 @@ }, "node_modules/is-alphanumerical": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "license": "MIT", "dependencies": { "is-alphabetical": "^1.0.0", "is-decimal": "^1.0.0" @@ -3351,8 +3036,7 @@ }, "node_modules/is-decimal": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -3360,18 +3044,16 @@ }, "node_modules/is-extglob": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-glob": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -3381,8 +3063,7 @@ }, "node_modules/is-hexadecimal": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -3390,26 +3071,23 @@ }, "node_modules/is-number": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/is-path-inside": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-plain-object": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -3419,40 +3097,34 @@ }, "node_modules/is-primitive": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-3.0.1.tgz", - "integrity": "sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/isobject": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/js-file-download": { "version": "0.4.12", - "resolved": "https://registry.npmjs.org/js-file-download/-/js-file-download-0.4.12.tgz", - "integrity": "sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg==" + "license": "MIT" }, "node_modules/js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -3474,9 +3146,8 @@ }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/keyv": { "version": "4.5.4", @@ -3489,9 +3160,8 @@ }, "node_modules/levn": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -3502,17 +3172,15 @@ }, "node_modules/linkify-it": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "license": "MIT", "dependencies": { "uc.micro": "^2.0.0" } }, "node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -3525,24 +3193,20 @@ }, "node_modules/lodash": { "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "license": "MIT" }, "node_modules/lodash.debounce": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/loose-envify": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -3552,8 +3216,7 @@ }, "node_modules/lowlight": { "version": "1.20.0", - "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", - "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==", + "license": "MIT", "dependencies": { "fault": "^1.0.0", "highlight.js": "~10.7.0" @@ -3565,8 +3228,7 @@ }, "node_modules/markdown-it": { "version": "14.1.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", - "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "license": "MIT", "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", @@ -3581,22 +3243,19 @@ }, "node_modules/mdurl": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==" + "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/meros": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/meros/-/meros-1.3.0.tgz", - "integrity": "sha512-2BNGOimxEz5hmjUG2FwoxCt5HN7BXdaWyFqEwxPTrJzVdABtrL4TiHTcsWSFAxPQ/tOnEaQEJh3qWq71QRMY+w==", + "license": "MIT", "engines": { "node": ">=13" }, @@ -3611,9 +3270,8 @@ }, "node_modules/micromatch": { "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -3624,16 +3282,14 @@ }, "node_modules/mime-db": { "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -3643,8 +3299,7 @@ }, "node_modules/mimic-response": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "license": "MIT", "optional": true, "engines": { "node": ">=10" @@ -3655,8 +3310,7 @@ }, "node_modules/minim": { "version": "0.23.8", - "resolved": "https://registry.npmjs.org/minim/-/minim-0.23.8.tgz", - "integrity": "sha512-bjdr2xW1dBCMsMGGsUeqM4eFI60m94+szhxWys+B1ztIt6gWSfeGBdSVCIawezeHYLYn0j6zrsXdQS/JllBzww==", + "license": "MIT", "dependencies": { "lodash": "^4.15.0" }, @@ -3666,9 +3320,8 @@ }, "node_modules/minimatch": { "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -3681,8 +3334,7 @@ }, "node_modules/minimist": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", "optional": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3690,26 +3342,21 @@ }, "node_modules/mkdirp-classic": { "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "license": "MIT", "optional": true }, "node_modules/ms": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/nan": { "version": "2.20.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz", - "integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==", + "license": "MIT", "optional": true }, "node_modules/nanoid": { "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true, "funding": [ { @@ -3717,6 +3364,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -3726,20 +3374,17 @@ }, "node_modules/napi-build-utils": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", - "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "license": "MIT", "optional": true }, "node_modules/natural-compare": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-abi": { "version": "3.65.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.65.0.tgz", - "integrity": "sha512-ThjYBfoDNr08AWx6hGaRbfPwxKV9kVzAzOzlLKbk2CuqXE2xnCh+cbAGnwM3t8Lq4v9rUB7VfondlkBckcJrVA==", + "license": "MIT", "optional": true, "dependencies": { "semver": "^7.3.5" @@ -3750,13 +3395,10 @@ }, "node_modules/node-abort-controller": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", - "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==" + "license": "MIT" }, "node_modules/node-domexception": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", "funding": [ { "type": "github", @@ -3767,14 +3409,14 @@ "url": "https://paypal.me/jimmywarting" } ], + "license": "MIT", "engines": { "node": ">=10.5.0" } }, "node_modules/node-fetch-commonjs": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch-commonjs/-/node-fetch-commonjs-3.3.2.tgz", - "integrity": "sha512-VBlAiynj3VMLrotgwOS3OyECFxas5y7ltLcK4t41lMUZeaK15Ym4QRkqN0EQKAFL42q9i21EPKjzLUPfltR72A==", + "license": "MIT", "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" @@ -3789,21 +3431,18 @@ }, "node_modules/nullthrows": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", - "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==" + "license": "MIT" }, "node_modules/object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -3813,17 +3452,15 @@ }, "node_modules/once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "devOptional": true, + "license": "ISC", + "optional": true, "dependencies": { "wrappy": "1" } }, "node_modules/openapi-path-templating": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/openapi-path-templating/-/openapi-path-templating-1.6.0.tgz", - "integrity": "sha512-1atBNwOUrZXthTvlvvX8k8ovFEF3iA8mDidYMkdOtvVdndBhTrspbwGXNOzEUaJhm9iUl4Tf5uQaeTLAJvwPig==", + "license": "Apache-2.0", "dependencies": { "apg-lite": "^1.0.3" }, @@ -3833,8 +3470,7 @@ }, "node_modules/openapi-server-url-templating": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/openapi-server-url-templating/-/openapi-server-url-templating-1.1.0.tgz", - "integrity": "sha512-dtyTFKx2xVcO0W8JKaluXIHC9l/MLjHeflBaWjiWNMCHp/TBs9dEjQDbj/VFlHR4omFOKjjmqm1pW1aCAhmPBg==", + "license": "Apache-2.0", "dependencies": { "apg-lite": "^1.0.3" }, @@ -3844,9 +3480,8 @@ }, "node_modules/optionator": { "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -3861,9 +3496,8 @@ }, "node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -3876,9 +3510,8 @@ }, "node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -3903,8 +3536,7 @@ }, "node_modules/parse-entities": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "license": "MIT", "dependencies": { "character-entities": "^1.0.0", "character-entities-legacy": "^1.0.0", @@ -3920,51 +3552,37 @@ }, "node_modules/path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-type": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/picocolors": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -3974,8 +3592,7 @@ }, "node_modules/popmotion": { "version": "11.0.3", - "resolved": "https://registry.npmjs.org/popmotion/-/popmotion-11.0.3.tgz", - "integrity": "sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA==", + "license": "MIT", "dependencies": { "framesync": "6.0.1", "hey-listen": "^1.0.8", @@ -3985,8 +3602,6 @@ }, "node_modules/postcss": { "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", "dev": true, "funding": [ { @@ -4002,6 +3617,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.1", @@ -4013,8 +3629,7 @@ }, "node_modules/prebuild-install": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", - "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", + "license": "MIT", "optional": true, "dependencies": { "detect-libc": "^2.0.0", @@ -4039,33 +3654,29 @@ }, "node_modules/prelude-ls": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/prismjs": { "version": "1.29.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", - "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/process": { "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", "engines": { "node": ">= 0.6.0" } }, "node_modules/prop-types": { "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -4074,8 +3685,7 @@ }, "node_modules/property-information": { "version": "5.6.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", - "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", + "license": "MIT", "dependencies": { "xtend": "^4.0.0" }, @@ -4086,13 +3696,11 @@ }, "node_modules/proxy-from-env": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "license": "MIT" }, "node_modules/pump": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "license": "MIT", "optional": true, "dependencies": { "end-of-stream": "^1.1.0", @@ -4110,16 +3718,14 @@ }, "node_modules/punycode.js": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", - "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/qs": { "version": "6.12.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.3.tgz", - "integrity": "sha512-AWJm14H1vVaO/iNZ4/hO+HyaTehuy9nRqVdkTqlJt0HWvBiBIEXFmb4C0DGeYo3Xes9rrEW+TxHsaigCbN5ICQ==", + "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.6" }, @@ -4132,13 +3738,10 @@ }, "node_modules/querystringify": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + "license": "MIT" }, "node_modules/queue-microtask": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { @@ -4153,12 +3756,12 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/ramda": { "version": "0.30.1", - "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", - "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/ramda" @@ -4166,8 +3769,7 @@ }, "node_modules/ramda-adjunct": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.0.1.tgz", - "integrity": "sha512-UTQCcWnoiuYH+ua+jGg3GTktcmCSD2W7OO2++tmv8p2Ze+N9VgVACERg4g36rRfIXklVMtqazyBLBWXfoPKgRQ==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.3" }, @@ -4181,8 +3783,7 @@ }, "node_modules/randexp": { "version": "0.5.3", - "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.5.3.tgz", - "integrity": "sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==", + "license": "MIT", "dependencies": { "drange": "^1.0.2", "ret": "^0.2.0" @@ -4193,16 +3794,14 @@ }, "node_modules/randombytes": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } }, "node_modules/rc": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "optional": true, "dependencies": { "deep-extend": "^0.6.0", @@ -4216,8 +3815,7 @@ }, "node_modules/rc/node_modules/strip-json-comments": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", "optional": true, "engines": { "node": ">=0.10.0" @@ -4225,8 +3823,7 @@ }, "node_modules/react": { "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" }, @@ -4236,8 +3833,7 @@ }, "node_modules/react-copy-to-clipboard": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.1.0.tgz", - "integrity": "sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A==", + "license": "MIT", "dependencies": { "copy-to-clipboard": "^3.3.1", "prop-types": "^15.8.1" @@ -4248,8 +3844,7 @@ }, "node_modules/react-debounce-input": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/react-debounce-input/-/react-debounce-input-3.3.0.tgz", - "integrity": "sha512-VEqkvs8JvY/IIZvh71Z0TC+mdbxERvYF33RcebnodlsUZ8RSgyKe2VWaHXv4+/8aoOgXLxWrdsYs2hDhcwbUgA==", + "license": "MIT", "dependencies": { "lodash.debounce": "^4", "prop-types": "^15.8.1" @@ -4260,8 +3855,7 @@ }, "node_modules/react-dom": { "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -4272,8 +3866,7 @@ }, "node_modules/react-immutable-proptypes": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/react-immutable-proptypes/-/react-immutable-proptypes-2.2.0.tgz", - "integrity": "sha512-Vf4gBsePlwdGvSZoLSBfd4HAP93HDauMY4fDjXhreg/vg6F3Fj/MXDNyTbltPC/xZKmZc+cjLu3598DdYK6sgQ==", + "license": "MIT", "dependencies": { "invariant": "^2.2.2" }, @@ -4283,8 +3876,7 @@ }, "node_modules/react-immutable-pure-component": { "version": "2.2.2", - "resolved": "https://registry.npmjs.org/react-immutable-pure-component/-/react-immutable-pure-component-2.2.2.tgz", - "integrity": "sha512-vkgoMJUDqHZfXXnjVlG3keCxSO/U6WeDQ5/Sl0GK2cH8TOxEzQ5jXqDXHEL/jqk6fsNxV05oH5kD7VNMUE2k+A==", + "license": "MIT", "peerDependencies": { "immutable": ">= 2 || >= 4.0.0-rc", "react": ">= 16.6", @@ -4293,21 +3885,18 @@ }, "node_modules/react-inspector": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-6.0.2.tgz", - "integrity": "sha512-x+b7LxhmHXjHoU/VrFAzw5iutsILRoYyDq97EDYdFpPLcvqtEzk4ZSZSQjnFPbr5T57tLXnHcqFYoN1pI6u8uQ==", + "license": "MIT", "peerDependencies": { "react": "^16.8.4 || ^17.0.0 || ^18.0.0" } }, "node_modules/react-is": { "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "license": "MIT" }, "node_modules/react-redux": { "version": "9.1.2", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.2.tgz", - "integrity": "sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w==", + "license": "MIT", "dependencies": { "@types/use-sync-external-store": "^0.0.3", "use-sync-external-store": "^1.0.0" @@ -4328,8 +3917,7 @@ }, "node_modules/react-remove-scroll": { "version": "2.5.7", - "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz", - "integrity": "sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==", + "license": "MIT", "dependencies": { "react-remove-scroll-bar": "^2.3.4", "react-style-singleton": "^2.2.1", @@ -4352,8 +3940,7 @@ }, "node_modules/react-remove-scroll-bar": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz", - "integrity": "sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==", + "license": "MIT", "dependencies": { "react-style-singleton": "^2.2.1", "tslib": "^2.0.0" @@ -4373,8 +3960,7 @@ }, "node_modules/react-style-singleton": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", - "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "license": "MIT", "dependencies": { "get-nonce": "^1.0.0", "invariant": "^2.2.4", @@ -4395,8 +3981,7 @@ }, "node_modules/react-syntax-highlighter": { "version": "15.5.0", - "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz", - "integrity": "sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.3.1", "highlight.js": "^10.4.1", @@ -4410,8 +3995,7 @@ }, "node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", "optional": true, "dependencies": { "inherits": "^2.0.3", @@ -4424,21 +4008,18 @@ }, "node_modules/redux": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", - "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==" + "license": "MIT" }, "node_modules/redux-immutable": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/redux-immutable/-/redux-immutable-4.0.0.tgz", - "integrity": "sha512-SchSn/DWfGb3oAejd+1hhHx01xUoxY+V7TeK0BKqpkLKiQPVFf7DYzEaKmrEVxsWxielKfSK9/Xq66YyxgR1cg==", + "license": "BSD-3-Clause", "peerDependencies": { "immutable": "^3.8.1 || ^4.0.0-rc.1" } }, "node_modules/refractor": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz", - "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==", + "license": "MIT", "dependencies": { "hastscript": "^6.0.0", "parse-entities": "^2.0.0", @@ -4451,21 +4032,18 @@ }, "node_modules/refractor/node_modules/prismjs": { "version": "1.27.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz", - "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/regenerator-runtime": { "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + "license": "MIT" }, "node_modules/remarkable": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remarkable/-/remarkable-2.0.1.tgz", - "integrity": "sha512-YJyMcOH5lrR+kZdmB0aJJ4+93bEojRZ1HGDn9Eagu6ibg7aVZhc3OWbbShRid+Q5eAfsEqWxpe+g5W5nYNfNiA==", + "license": "MIT", "dependencies": { "argparse": "^1.0.10", "autolinker": "^3.11.0" @@ -4479,29 +4057,25 @@ }, "node_modules/remarkable/node_modules/argparse": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/repeat-string": { "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "license": "MIT", "engines": { "node": ">=0.10" } }, "node_modules/requires-port": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + "license": "MIT" }, "node_modules/reselect": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", - "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==" + "license": "MIT" }, "node_modules/resolve-from": { "version": "4.0.0", @@ -4514,43 +4088,24 @@ }, "node_modules/ret": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz", - "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/reusify": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/rollup": { "version": "4.18.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.1.tgz", - "integrity": "sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "1.0.5" }, @@ -4583,8 +4138,6 @@ }, "node_modules/run-parallel": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { @@ -4600,14 +4153,13 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -4621,21 +4173,20 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/scheduler": { "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" } }, "node_modules/semver": { "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "devOptional": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -4645,8 +4196,7 @@ }, "node_modules/serialize-error": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz", - "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==", + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -4659,8 +4209,7 @@ }, "node_modules/set-function-length": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -4675,13 +4224,12 @@ }, "node_modules/set-value": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-4.1.0.tgz", - "integrity": "sha512-zTEg4HL0RwVrqcWs3ztF+x1vkxfm0lP+MQQFPiMJTKVceBwEV0A569Ou8l9IYQG8jOZdMVI1hGsc0tmeD2o/Lw==", "funding": [ "https://github.com/sponsors/jonschlinkert", "https://paypal.me/jonathanschlinkert", "https://jonschlinkert.dev/sponsor" ], + "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4", "is-primitive": "^3.0.1" @@ -4692,8 +4240,7 @@ }, "node_modules/sha.js": { "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "license": "(MIT AND BSD-3-Clause)", "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -4704,9 +4251,8 @@ }, "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -4716,17 +4262,15 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/short-unique-id": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/short-unique-id/-/short-unique-id-5.2.0.tgz", - "integrity": "sha512-cMGfwNyfDZ/nzJ2k2M+ClthBIh//GlZl1JEf47Uoa9XR11bz8Pa2T2wQO4bVrRdH48LrIDWJahQziKo3MjhsWg==", + "license": "Apache-2.0", "bin": { "short-unique-id": "bin/short-unique-id", "suid": "bin/short-unique-id" @@ -4734,8 +4278,7 @@ }, "node_modules/side-channel": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -4751,8 +4294,6 @@ }, "node_modules/simple-concat": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", "funding": [ { "type": "github", @@ -4767,12 +4308,11 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "optional": true }, "node_modules/simple-get": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", "funding": [ { "type": "github", @@ -4787,6 +4327,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "optional": true, "dependencies": { "decompress-response": "^6.0.0", @@ -4796,26 +4337,23 @@ }, "node_modules/slash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/source-map-js": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/space-separated-tokens": { "version": "1.1.5", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", - "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4823,13 +4361,11 @@ }, "node_modules/sprintf-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + "license": "BSD-3-Clause" }, "node_modules/string_decoder": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", "optional": true, "dependencies": { "safe-buffer": "~5.2.0" @@ -4837,9 +4373,8 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -4859,16 +4394,9 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/style-mod": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz", - "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==", - "peer": true - }, "node_modules/style-value-types": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-5.0.0.tgz", - "integrity": "sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA==", + "license": "MIT", "dependencies": { "hey-listen": "^1.0.8", "tslib": "^2.1.0" @@ -4876,9 +4404,8 @@ }, "node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -4888,8 +4415,7 @@ }, "node_modules/swagger-client": { "version": "3.28.2", - "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.28.2.tgz", - "integrity": "sha512-g30KCdSVyZlMulWOJnheNo7Ea+L06OZebl0oRU6zHd5Zf5AZKHTqurKRdNOLsMWA3l3bWJiEh7s3JlzFJHRmoQ==", + "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.22.15", "@swagger-api/apidom-core": ">=1.0.0-alpha.5 <1.0.0-beta.0", @@ -4912,8 +4438,7 @@ }, "node_modules/swagger-ui-react": { "version": "5.17.14", - "resolved": "https://registry.npmjs.org/swagger-ui-react/-/swagger-ui-react-5.17.14.tgz", - "integrity": "sha512-mCXerZrbcn4ftPYifUF0+iKIRTHoVCv0HcJc/sXl9nCe3oeWdsjmOWVqKabzzAkAa0NwsbKNJFv2UL/Ivnf6VQ==", + "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.24.5", "@braintree/sanitize-url": "=7.0.2", @@ -4956,8 +4481,7 @@ }, "node_modules/tar-fs": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "license": "MIT", "optional": true, "dependencies": { "chownr": "^1.1.1", @@ -4968,8 +4492,7 @@ }, "node_modules/tar-stream": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", "optional": true, "dependencies": { "bl": "^4.0.3", @@ -4984,15 +4507,13 @@ }, "node_modules/text-table": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -5002,13 +4523,11 @@ }, "node_modules/toggle-selection": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" + "license": "MIT" }, "node_modules/traverse": { "version": "0.6.8", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.8.tgz", - "integrity": "sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -5018,9 +4537,8 @@ }, "node_modules/tree-sitter": { "version": "0.20.4", - "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.20.4.tgz", - "integrity": "sha512-rjfR5dc4knG3jnJNN/giJ9WOoN1zL/kZyrS0ILh+eqq8RNcIbiXA63JsMEgluug0aNvfQvK4BfCErN1vIzvKog==", "hasInstallScript": true, + "license": "MIT", "optional": true, "dependencies": { "nan": "^2.17.0", @@ -5029,9 +4547,7 @@ }, "node_modules/tree-sitter-json": { "version": "0.20.2", - "resolved": "https://registry.npmjs.org/tree-sitter-json/-/tree-sitter-json-0.20.2.tgz", - "integrity": "sha512-eUxrowp4F1QEGk/i7Sa+Xl8Crlfp7J0AXxX1QdJEQKQYMWhgMbCIgyQvpO3Q0P9oyTrNQxRLlRipDS44a8EtRw==", - "hasInstallScript": true, + "license": "MIT", "optional": true, "dependencies": { "nan": "^2.18.0" @@ -5039,9 +4555,7 @@ }, "node_modules/tree-sitter-yaml": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/tree-sitter-yaml/-/tree-sitter-yaml-0.5.0.tgz", - "integrity": "sha512-POJ4ZNXXSWIG/W4Rjuyg36MkUD4d769YRUGKRqN+sVaj/VCo6Dh6Pkssn1Rtewd5kybx+jT1BWMyWN0CijXnMA==", - "hasInstallScript": true, + "license": "MIT", "optional": true, "dependencies": { "nan": "^2.14.0" @@ -5049,9 +4563,8 @@ }, "node_modules/ts-api-utils": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" }, @@ -5061,23 +4574,19 @@ }, "node_modules/ts-mixer": { "version": "6.0.4", - "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz", - "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==" + "license": "MIT" }, "node_modules/ts-toolbelt": { "version": "9.6.0", - "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz", - "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==" + "license": "Apache-2.0" }, "node_modules/tslib": { "version": "2.6.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", - "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + "license": "0BSD" }, "node_modules/tunnel-agent": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", "optional": true, "dependencies": { "safe-buffer": "^5.0.1" @@ -5088,9 +4597,8 @@ }, "node_modules/type-check": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -5100,8 +4608,7 @@ }, "node_modules/type-fest": { "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -5111,17 +4618,15 @@ }, "node_modules/types-ramda": { "version": "0.30.1", - "resolved": "https://registry.npmjs.org/types-ramda/-/types-ramda-0.30.1.tgz", - "integrity": "sha512-1HTsf5/QVRmLzcGfldPFvkVsAdi1db1BBKzi7iW3KBUlOICg/nKnFS+jGqDJS3YD8VsWbAh7JiHeBvbsw8RPxA==", + "license": "MIT", "dependencies": { "ts-toolbelt": "^9.6.0" } }, "node_modules/typescript": { "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5132,13 +4637,11 @@ }, "node_modules/uc.micro": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", - "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==" + "license": "MIT" }, "node_modules/unraw": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unraw/-/unraw-3.0.0.tgz", - "integrity": "sha512-08/DA66UF65OlpUDIQtbJyrqTR0jTAlJ+jsnkQ4jxR7+K5g5YG1APZKQSMCE1vqqmD+2pv6+IdEjmopFatacvg==" + "license": "MIT" }, "node_modules/uri-js": { "version": "4.4.1", @@ -5151,8 +4654,7 @@ }, "node_modules/url-parse": { "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "license": "MIT", "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -5160,8 +4662,7 @@ }, "node_modules/use-callback-ref": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz", - "integrity": "sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==", + "license": "MIT", "dependencies": { "tslib": "^2.0.0" }, @@ -5180,8 +4681,7 @@ }, "node_modules/use-sidecar": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", - "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", + "license": "MIT", "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" @@ -5201,23 +4701,20 @@ }, "node_modules/use-sync-external-store": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", - "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "license": "MIT", "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT", "optional": true }, "node_modules/vite": { "version": "5.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.5.tgz", - "integrity": "sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==", "dev": true, + "license": "MIT", "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.39", @@ -5270,34 +4767,24 @@ }, "node_modules/vscode-languageserver-types": { "version": "3.17.5", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", - "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==" - }, - "node_modules/w3c-keyname": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", - "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", - "peer": true + "license": "MIT" }, "node_modules/web-streams-polyfill": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/web-tree-sitter": { "version": "0.20.3", - "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.20.3.tgz", - "integrity": "sha512-zKGJW9r23y3BcJusbgvnOH2OYAW40MXAOi9bi3Gcc7T4Gms9WWgXF8m6adsJWpGJEhgOzCrfiz1IzKowJWrtYw==", + "license": "MIT", "optional": true }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -5310,45 +4797,39 @@ }, "node_modules/word-wrap": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "devOptional": true + "license": "ISC", + "optional": true }, "node_modules/xml": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", - "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==" + "license": "MIT" }, "node_modules/xml-but-prettier": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml-but-prettier/-/xml-but-prettier-1.0.1.tgz", - "integrity": "sha512-C2CJaadHrZTqESlH03WOyw0oZTtoy2uEg6dSDF6YRg+9GnYNub53RRemLpnvtbHDFelxMx4LajiFsYeR6XJHgQ==", + "license": "MIT", "dependencies": { "repeat-string": "^1.5.2" } }, "node_modules/xtend": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", "engines": { "node": ">=0.4" } }, "node_modules/yocto-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -5358,8 +4839,7 @@ }, "node_modules/zenscroll": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/zenscroll/-/zenscroll-4.0.2.tgz", - "integrity": "sha512-jEA1znR7b4C/NnaycInCU6h/d15ZzCd1jmsruqOKnZP6WXQSMH3W2GL+OXbkruslU4h+Tzuos0HdswzRUk/Vgg==" + "license": "Unlicense" } } } diff --git a/playground/package.json b/playground/package.json index 0e44c066ed..4873eff5e6 100644 --- a/playground/package.json +++ b/playground/package.json @@ -23,7 +23,7 @@ "@typescript-eslint/eslint-plugin": "^8.0.1", "@typescript-eslint/parser": "^8.0.1", "@vitejs/plugin-react-swc": "^3.7.0", - "eslint": "^8.57.0", + "eslint": "^9.9.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.9", "typescript": "^5.5.4", diff --git a/tools/defradb.containerfile b/tools/defradb.containerfile index 7e07bf887d..ed056ec572 100644 --- a/tools/defradb.containerfile +++ b/tools/defradb.containerfile @@ -6,7 +6,7 @@ FROM docker.io/node:20 AS PLAYGROUND_BUILD WORKDIR /repo/ COPY playground/ ./ -RUN npm install +RUN npm install --legacy-peer-deps RUN npm run build # Stage: BUILD From defb37ac082e4e825d9288d967e92f411308f1eb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 08:28:43 -0400 Subject: [PATCH 31/41] bot: Update dependencies (bulk dependabot PRs) 12-08-2024 (#2904) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✅ This PR was created by combining the following PRs: #2902 bot: Bump vite from 5.3.5 to 5.4.0 in /playground #2901 bot: Bump graphiql from 3.3.2 to 3.4.1 in /playground #2900 bot: Bump github.com/cosmos/gogoproto from 1.5.0 to 1.6.0 #2899 bot: Bump github.com/ipfs/boxo from 0.21.0 to 0.22.0 #2898 bot: Bump github.com/gofrs/uuid/v5 from 5.2.0 to 5.3.0 ⚠️ The following PRs were resolved manually due to merge conflicts: #2897 bot: Bump github.com/cosmos/cosmos-sdk from 0.50.8 to 0.50.9 --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Shahzad Lone --- go.mod | 56 ++--- go.sum | 138 ++++++------ playground/package-lock.json | 416 +++++++++++++++++++++++++---------- playground/package.json | 4 +- 4 files changed, 394 insertions(+), 220 deletions(-) diff --git a/go.mod b/go.mod index 680ae39650..5373d28a59 100644 --- a/go.mod +++ b/go.mod @@ -5,8 +5,8 @@ go 1.21.3 require ( github.com/bits-and-blooms/bitset v1.13.0 github.com/bxcodec/faker v2.0.1+incompatible - github.com/cosmos/cosmos-sdk v0.50.8 - github.com/cosmos/gogoproto v1.5.0 + github.com/cosmos/cosmos-sdk v0.50.9 + github.com/cosmos/gogoproto v1.6.0 github.com/cyware/ssi-sdk v0.0.0-20231229164914-f93f3006379f github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 github.com/evanphx/json-patch/v5 v5.9.0 @@ -15,9 +15,9 @@ require ( github.com/go-chi/chi/v5 v5.1.0 github.com/go-chi/cors v1.2.1 github.com/go-errors/errors v1.5.1 - github.com/gofrs/uuid/v5 v5.2.0 + github.com/gofrs/uuid/v5 v5.3.0 github.com/iancoleman/strcase v0.3.0 - github.com/ipfs/boxo v0.21.0 + github.com/ipfs/boxo v0.22.0 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-datastore v0.6.0 @@ -29,7 +29,7 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/lens-vm/lens/host-go v0.0.0-20231127204031-8d858ed2926c github.com/lestrrat-go/jwx/v2 v2.1.1 - github.com/libp2p/go-libp2p v0.35.1 + github.com/libp2p/go-libp2p v0.36.1 github.com/libp2p/go-libp2p-gostream v0.6.0 github.com/libp2p/go-libp2p-kad-dht v0.25.2 github.com/libp2p/go-libp2p-pubsub v0.11.0 @@ -58,7 +58,7 @@ require ( go.opentelemetry.io/otel/metric v1.28.0 go.opentelemetry.io/otel/sdk/metric v1.28.0 go.uber.org/zap v1.27.0 - golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/term v0.23.0 google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 @@ -72,8 +72,8 @@ require ( cloud.google.com/go/storage v1.38.0 // indirect cosmossdk.io/api v0.7.5 // indirect cosmossdk.io/collections v0.4.0 // indirect - cosmossdk.io/core v0.11.0 // indirect - cosmossdk.io/depinject v1.0.0-alpha.4 // indirect + cosmossdk.io/core v0.11.1 // indirect + cosmossdk.io/depinject v1.0.0 // indirect cosmossdk.io/errors v1.0.1 // indirect cosmossdk.io/log v1.3.1 // indirect cosmossdk.io/math v1.3.0 // indirect @@ -81,7 +81,7 @@ require ( cosmossdk.io/x/circuit v0.1.0 // indirect cosmossdk.io/x/evidence v0.1.0 // indirect cosmossdk.io/x/feegrant v0.1.0 // indirect - cosmossdk.io/x/tx v0.13.3 // indirect + cosmossdk.io/x/tx v0.13.4 // indirect cosmossdk.io/x/upgrade v0.1.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect @@ -114,7 +114,7 @@ require ( github.com/cockroachdb/pebble v1.1.0 // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/cometbft/cometbft v0.38.9 // indirect + github.com/cometbft/cometbft v0.38.10 // indirect github.com/cometbft/cometbft-db v0.9.1 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect @@ -176,7 +176,7 @@ require ( github.com/google/go-cmp v0.6.0 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/orderedcode v0.0.1 // indirect - github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8 // indirect + github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect github.com/google/s2a-go v0.1.7 // indirect github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect @@ -277,31 +277,32 @@ require ( github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multistream v0.5.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect github.com/oklog/run v1.1.0 // indirect - github.com/onsi/ginkgo/v2 v2.19.0 // indirect + github.com/onsi/ginkgo/v2 v2.19.1 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 // indirect - github.com/pion/datachannel v1.5.6 // indirect - github.com/pion/dtls/v2 v2.2.11 // indirect - github.com/pion/ice/v2 v2.3.25 // indirect + github.com/pion/datachannel v1.5.8 // indirect + github.com/pion/dtls/v2 v2.2.12 // indirect + github.com/pion/ice/v2 v2.3.32 // indirect github.com/pion/interceptor v0.1.29 // indirect github.com/pion/logging v0.2.2 // indirect github.com/pion/mdns v0.0.12 // indirect github.com/pion/randutil v0.1.0 // indirect github.com/pion/rtcp v1.2.14 // indirect - github.com/pion/rtp v1.8.6 // indirect - github.com/pion/sctp v1.8.16 // indirect + github.com/pion/rtp v1.8.8 // indirect + github.com/pion/sctp v1.8.20 // indirect github.com/pion/sdp/v3 v3.0.9 // indirect - github.com/pion/srtp/v2 v2.0.18 // indirect + github.com/pion/srtp/v2 v2.0.20 // indirect github.com/pion/stun v0.6.1 // indirect - github.com/pion/transport/v2 v2.2.5 // indirect + github.com/pion/transport/v2 v2.2.9 // indirect github.com/pion/turn/v2 v2.1.6 // indirect - github.com/pion/webrtc/v3 v3.2.42 // indirect + github.com/pion/webrtc/v3 v3.2.50 // indirect github.com/piprate/json-gold v0.5.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect @@ -309,10 +310,10 @@ require ( github.com/pquerna/cachecontrol v0.1.0 // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.54.0 // indirect + github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/quic-go v0.45.0 // indirect + github.com/quic-go/quic-go v0.45.2 // indirect github.com/quic-go/webtransport-go v0.8.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect @@ -341,6 +342,7 @@ require ( github.com/ulikunitz/xz v0.5.11 // indirect github.com/wasmerio/wasmer-go v1.0.4 // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect + github.com/wlynxg/anet v0.0.3 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect @@ -352,23 +354,23 @@ require ( go.opentelemetry.io/otel/sdk v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.22.0 // indirect + go.uber.org/fx v1.22.1 // indirect go.uber.org/mock v0.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/crypto v0.25.0 // indirect - golang.org/x/mod v0.18.0 // indirect - golang.org/x/net v0.26.0 // indirect + golang.org/x/mod v0.19.0 // indirect + golang.org/x/net v0.27.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.23.0 // indirect golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.22.0 // indirect + golang.org/x/tools v0.23.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/api v0.171.0 // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240709173604-40e1e62336c5 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 4b2fa38972..8ea366d226 100644 --- a/go.sum +++ b/go.sum @@ -192,10 +192,10 @@ cosmossdk.io/client/v2 v2.0.0-beta.1 h1:XkHh1lhrLYIT9zKl7cIOXUXg2hdhtjTPBUfqERNA cosmossdk.io/client/v2 v2.0.0-beta.1/go.mod h1:JEUSu9moNZQ4kU3ir1DKD5eU4bllmAexrGWjmb9k8qU= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0= -cosmossdk.io/core v0.11.0 h1:vtIafqUi+1ZNAE/oxLOQQ7Oek2n4S48SWLG8h/+wdbo= -cosmossdk.io/core v0.11.0/go.mod h1:LaTtayWBSoacF5xNzoF8tmLhehqlA9z1SWiPuNC6X1w= -cosmossdk.io/depinject v1.0.0-alpha.4 h1:PLNp8ZYAMPTUKyG9IK2hsbciDWqna2z1Wsl98okJopc= -cosmossdk.io/depinject v1.0.0-alpha.4/go.mod h1:HeDk7IkR5ckZ3lMGs/o91AVUc7E596vMaOmslGFM3yU= +cosmossdk.io/core v0.11.1 h1:h9WfBey7NAiFfIcUhDVNS503I2P2HdZLebJlUIs8LPA= +cosmossdk.io/core v0.11.1/go.mod h1:OJzxcdC+RPrgGF8NJZR2uoQr56tc7gfBKhiKeDO7hH0= +cosmossdk.io/depinject v1.0.0 h1:dQaTu6+O6askNXO06+jyeUAnF2/ssKwrrszP9t5q050= +cosmossdk.io/depinject v1.0.0/go.mod h1:zxK/h3HgHoA/eJVtiSsoaRaRA2D5U4cJ5thIG4ssbB8= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= @@ -210,8 +210,8 @@ cosmossdk.io/x/evidence v0.1.0 h1:J6OEyDl1rbykksdGynzPKG5R/zm6TacwW2fbLTW4nCk= cosmossdk.io/x/evidence v0.1.0/go.mod h1:hTaiiXsoiJ3InMz1uptgF0BnGqROllAN8mwisOMMsfw= cosmossdk.io/x/feegrant v0.1.0 h1:c7s3oAq/8/UO0EiN1H5BIjwVntujVTkYs35YPvvrdQk= cosmossdk.io/x/feegrant v0.1.0/go.mod h1:4r+FsViJRpcZif/yhTn+E0E6OFfg4n0Lx+6cCtnZElU= -cosmossdk.io/x/tx v0.13.3 h1:Ha4mNaHmxBc6RMun9aKuqul8yHiL78EKJQ8g23Zf73g= -cosmossdk.io/x/tx v0.13.3/go.mod h1:I8xaHv0rhUdIvIdptKIqzYy27+n2+zBVaxO6fscFhys= +cosmossdk.io/x/tx v0.13.4 h1:Eg0PbJgeO0gM8p5wx6xa0fKR7hIV6+8lC56UrsvSo0Y= +cosmossdk.io/x/tx v0.13.4/go.mod h1:BkFqrnGGgW50Y6cwTy+JvgAhiffbGEKW6KF9ufcDpvk= cosmossdk.io/x/upgrade v0.1.1 h1:aoPe2gNvH+Gwt/Pgq3dOxxQVU3j5P6Xf+DaUJTDZATc= cosmossdk.io/x/upgrade v0.1.1/go.mod h1:MNLptLPcIFK9CWt7Ra//8WUZAxweyRDNcbs5nkOcQy0= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= @@ -371,8 +371,8 @@ github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZ github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/cometbft/cometbft v0.38.9 h1:cJBJBG0mPKz+sqelCi/hlfZjadZQGdDNnu6YQ1ZsUHQ= -github.com/cometbft/cometbft v0.38.9/go.mod h1:xOoGZrtUT+A5izWfHSJgl0gYZUE7lu7Z2XIS1vWG/QQ= +github.com/cometbft/cometbft v0.38.10 h1:2ePuglchT+j0Iao+cfmt/nw5U7K2lnGDzXSUPGVdXaU= +github.com/cometbft/cometbft v0.38.10/go.mod h1:jHPx9vQpWzPHEAiYI/7EDKaB1NXhK6o3SArrrY8ExKc= github.com/cometbft/cometbft-db v0.9.1 h1:MIhVX5ja5bXNHF8EYrThkG9F7r9kSfv8BX4LWaxWJ4M= github.com/cometbft/cometbft-db v0.9.1/go.mod h1:iliyWaoV0mRwBJoizElCwwRA9Tf7jZJOURcRZF9m60U= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= @@ -395,15 +395,15 @@ github.com/cosmos/cosmos-db v1.0.2 h1:hwMjozuY1OlJs/uh6vddqnk9j7VamLv+0DBlbEXbAK github.com/cosmos/cosmos-db v1.0.2/go.mod h1:Z8IXcFJ9PqKK6BIsVOB3QXtkKoqUOp1vRvPT39kOXEA= github.com/cosmos/cosmos-proto v1.0.0-beta.5 h1:eNcayDLpip+zVLRLYafhzLvQlSmyab+RC5W7ZfmxJLA= github.com/cosmos/cosmos-proto v1.0.0-beta.5/go.mod h1:hQGLpiIUloJBMdQMMWb/4wRApmI9hjHH05nefC0Ojec= -github.com/cosmos/cosmos-sdk v0.50.8 h1:2UJHssUaGHTl4/dFp8xyREKAnfiRU6VVfqtKG9n8w5g= -github.com/cosmos/cosmos-sdk v0.50.8/go.mod h1:Zb+DgHtiByNwgj71IlJBXwOq6dLhtyAq3AgqpXm/jHo= +github.com/cosmos/cosmos-sdk v0.50.9 h1:gt2usjz0H0qW6KwAxWw7ZJ3XU8uDwmhN+hYG3nTLeSg= +github.com/cosmos/cosmos-sdk v0.50.9/go.mod h1:TMH6wpoYBcg7Cp5BEg8fneLr+8XloNQkf2MRNF9V6JE= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= -github.com/cosmos/gogoproto v1.5.0 h1:SDVwzEqZDDBoslaeZg+dGE55hdzHfgUA40pEanMh52o= -github.com/cosmos/gogoproto v1.5.0/go.mod h1:iUM31aofn3ymidYG6bUR5ZFrk+Om8p5s754eMUcyp8I= +github.com/cosmos/gogoproto v1.6.0 h1:Xm0F/96O5Ox4g6xGgjA41rWaaPjYtOdTi59uBcV2qEE= +github.com/cosmos/gogoproto v1.6.0/go.mod h1:Y+g956rcUf2vr4uwtCcK/1Xx9BWVluCtcI9vsh0GHmk= github.com/cosmos/iavl v1.1.2 h1:zL9FK7C4L/P4IF1Dm5fIwz0WXCnn7Bp1M2FxH0ayM7Y= github.com/cosmos/iavl v1.1.2/go.mod h1:jLeUvm6bGT1YutCaL2fIar/8vGUE8cPZvh/gXEWDaDM= github.com/cosmos/ibc-go/modules/capability v1.0.0 h1:r/l++byFtn7jHYa09zlAdSeevo8ci1mVZNO9+V0xsLE= @@ -592,8 +592,8 @@ github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/uuid/v5 v5.2.0 h1:qw1GMx6/y8vhVsx626ImfKMuS5CvJmhIKKtuyvfajMM= -github.com/gofrs/uuid/v5 v5.2.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= +github.com/gofrs/uuid/v5 v5.3.0 h1:m0mUMr+oVYUdxpMLgSYCZiXe7PuVPnI94+OMeVBNedk= +github.com/gofrs/uuid/v5 v5.3.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1-0.20201022092350-68b0159b7869/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/googleapis v1.4.1 h1:1Yx4Myt7BxzvUr5ldGSbwYiZG6t9wGBZ+8/fX3Wvtq0= @@ -703,8 +703,8 @@ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8 h1:ASJ/LAqdCHOyMYI+dwNxn7Rd8FscNkMyTr1KZU1JI/M= -github.com/google/pprof v0.0.0-20240618054019-d3b898a103f8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= @@ -855,8 +855,8 @@ github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.21.0 h1:XpGXb+TQQ0IUdYaeAxGzWjSs6ow/Lce148A/2IbRDVE= -github.com/ipfs/boxo v0.21.0/go.mod h1:NmweAYeY1USOaJJxouy7DLr/Y5M8UBSsCI2KRivO+TY= +github.com/ipfs/boxo v0.22.0 h1:QTC+P5uhsBNq6HzX728nsLyFW6rYDeR/5hggf9YZX78= +github.com/ipfs/boxo v0.22.0/go.mod h1:yp1loimX0BDYOR0cyjtcXHv15muEh5V1FqO2QLlzykw= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= @@ -894,6 +894,8 @@ github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fG github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= +github.com/ipfs/go-test v0.0.4 h1:DKT66T6GBB6PsDFLoO56QZPrOmzJkqU1FZH5C9ySkew= +github.com/ipfs/go-test v0.0.4/go.mod h1:qhIM1EluEfElKKM6fnWxGn822/z9knUGM1+I/OAQNKI= github.com/ipfs/kubo v0.25.0 h1:VKy9oOBW34xTqwi70FPRsoA3vJJBSdaYAbgIm5NmIbY= github.com/ipfs/kubo v0.25.0/go.mod h1:ZWSvdTvD7VLqYdquESyGTAkbiqODbLwyNCuqeOtPKsQ= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= @@ -993,8 +995,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.35.1 h1:Hm7Ub2BF+GCb14ojcsEK6WAy5it5smPDK02iXSZLl50= -github.com/libp2p/go-libp2p v0.35.1/go.mod h1:Dnkgba5hsfSv5dvvXC8nfqk44hH0gIKKno+HOMU0fdc= +github.com/libp2p/go-libp2p v0.36.1 h1:piAHesy0/8ifBEBUS8HF2m7ywR5vnktUFv00dTsVKcs= +github.com/libp2p/go-libp2p v0.36.1/go.mod h1:vHzel3CpRB+vS11fIjZSJAU4ALvieKV9VZHC9VerHj8= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qkCnjyaZUPYU= @@ -1125,6 +1127,8 @@ github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dy github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -1158,16 +1162,16 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= -github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= +github.com/onsi/ginkgo/v2 v2.19.1 h1:QXgq3Z8Crl5EL1WBAC98A5sEBHARrAJNzAmMxzLcRF0= +github.com/onsi/ginkgo/v2 v2.19.1/go.mod h1:O3DtEWQkPa/F7fBMgmZQKKsluAy8pd3rEQdrjkPb9zA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= -github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +github.com/onsi/gomega v1.34.0 h1:eSSPsPNp6ZpsG8X1OVmOTxig+CblTc4AxpPBykhe2Os= +github.com/onsi/gomega v1.34.0/go.mod h1:MIKI8c+f+QLWk+hxbePD4i0LMJSExPaZOVfkoex4cAo= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -1213,13 +1217,13 @@ github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0 github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pion/datachannel v1.5.6 h1:1IxKJntfSlYkpUj8LlYRSWpYiTTC02nUrOE8T3DqGeg= -github.com/pion/datachannel v1.5.6/go.mod h1:1eKT6Q85pRnr2mHiWHxJwO50SfZRtWHTsNIVb/NfGW4= +github.com/pion/datachannel v1.5.8 h1:ph1P1NsGkazkjrvyMfhRBUAWMxugJjq2HfQifaOoSNo= +github.com/pion/datachannel v1.5.8/go.mod h1:PgmdpoaNBLX9HNzNClmdki4DYW5JtI7Yibu8QzbL3tI= github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= -github.com/pion/dtls/v2 v2.2.11 h1:9U/dpCYl1ySttROPWJgqWKEylUdT0fXp/xst6JwY5Ks= -github.com/pion/dtls/v2 v2.2.11/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= -github.com/pion/ice/v2 v2.3.25 h1:M5rJA07dqhi3nobJIg+uPtcVjFECTrhcR3n0ns8kDZs= -github.com/pion/ice/v2 v2.3.25/go.mod h1:KXJJcZK7E8WzrBEYnV4UtqEZsGeWfHxsNqhVcVvgjxw= +github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= +github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= +github.com/pion/ice/v2 v2.3.32 h1:VwE/uEeqiMm0zUWpdt1DJtnqEkj3UjEbhX92/CurtWI= +github.com/pion/ice/v2 v2.3.32/go.mod h1:8fac0+qftclGy1tYd/nfwfHC729BLaxtVqMdMVCAVPU= github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= @@ -1232,31 +1236,30 @@ github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9 github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/rtp v1.8.6 h1:MTmn/b0aWWsAzux2AmP8WGllusBVw4NPYPVFFd7jUPw= -github.com/pion/rtp v1.8.6/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/sctp v1.8.13/go.mod h1:YKSgO/bO/6aOMP9LCie1DuD7m+GamiK2yIiPM6vH+GA= -github.com/pion/sctp v1.8.16 h1:PKrMs+o9EMLRvFfXq59WFsC+V8mN1wnKzqrv+3D/gYY= -github.com/pion/sctp v1.8.16/go.mod h1:P6PbDVA++OJMrVNg2AL3XtYHV4uD6dvfyOovCgMs0PE= +github.com/pion/rtp v1.8.8 h1:EtYFHI0rpUEjT/RMnGfb1vdJhbYmPG77szD72uUnSxs= +github.com/pion/rtp v1.8.8/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/sctp v1.8.20 h1:sOc3lkV/tQaP57ZUEXIMdM2V92IIB2ia5v/ygnBxaEg= +github.com/pion/sctp v1.8.20/go.mod h1:oTxw8i5m+WbDHZJL/xUpe6CPIn1Y0GIKKwTLF4h53H8= github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= -github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo= -github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= +github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk= +github.com/pion/srtp/v2 v2.0.20/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= -github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc= github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= -github.com/pion/transport/v2 v2.2.5 h1:iyi25i/21gQck4hfRhomF6SktmUQjRsRW4WJdhfc3Kc= -github.com/pion/transport/v2 v2.2.5/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v2 v2.2.8/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= +github.com/pion/transport/v2 v2.2.9 h1:WEDygVovkJlV2CCunM9KS2kds+kcl7zdIefQA5y/nkE= +github.com/pion/transport/v2 v2.2.9/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= -github.com/pion/transport/v3 v3.0.2 h1:r+40RJR25S9w3jbA6/5uEPTzcdn7ncyU44RWCbHkLg4= -github.com/pion/transport/v3 v3.0.2/go.mod h1:nIToODoOlb5If2jF9y2Igfx3PFYWfuXi37m0IlWa/D0= +github.com/pion/transport/v3 v3.0.6 h1:k1mQU06bmmX143qSWgXFqSH1KUJceQvIUuVH/K5ELWw= +github.com/pion/transport/v3 v3.0.6/go.mod h1:HvJr2N/JwNJAfipsRleqwFoR3t/pWyHeZUs89v3+t5s= github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.2.42 h1:WN/ZuMjtpQOoGRCZUg/zFG+JHEvYLVyDKOxU6H1qWlE= -github.com/pion/webrtc/v3 v3.2.42/go.mod h1:M1RAe3TNTD1tzyvqHrbVODfwdPGSXOUo/OgpoGGJqFY= +github.com/pion/webrtc/v3 v3.2.50 h1:C/rwL2mBfCxHv6tlLzDAO3krJpQXfVx8A8WHnGJ2j34= +github.com/pion/webrtc/v3 v3.2.50/go.mod h1:dytYYoSBy7ZUWhJMbndx9UckgYvzNAfL7xgVnrIKxqo= github.com/piprate/json-gold v0.5.0 h1:RmGh1PYboCFcchVFuh2pbSWAZy4XJaqTMU4KQYsApbM= github.com/piprate/json-gold v0.5.0/go.mod h1:WZ501QQMbZZ+3pXFPhQKzNwS1+jls0oqov3uQ2WasLs= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -1297,8 +1300,8 @@ github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt2 github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8= -github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -1310,8 +1313,8 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.45.0 h1:OHmkQGM37luZITyTSu6ff03HP/2IrwDX1ZFiNEhSFUE= -github.com/quic-go/quic-go v0.45.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= +github.com/quic-go/quic-go v0.45.2 h1:DfqBmqjb4ExSdxRIb/+qXhPC+7k6+DUNZha4oeiC9fY= +github.com/quic-go/quic-go v0.45.2/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -1502,6 +1505,8 @@ github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/wlynxg/anet v0.0.3 h1:PvR53psxFXstc12jelG6f1Lv4MWqE0tI76/hHGjh9rg= +github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= @@ -1556,8 +1561,8 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.22.0 h1:pApUK7yL0OUHMd8vkunWSlLxZVFFk70jR2nKde8X2NM= -go.uber.org/fx v1.22.0/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= +go.uber.org/fx v1.22.1 h1:nvvln7mwyT5s1q201YE29V/BFrGor6vMiDNpU/78Mys= +go.uber.org/fx v1.22.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -1599,11 +1604,8 @@ golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1617,8 +1619,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1647,8 +1649,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1714,13 +1716,10 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1874,12 +1873,9 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1888,11 +1884,8 @@ golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1907,7 +1900,6 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= @@ -1983,8 +1975,8 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= 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= @@ -2173,8 +2165,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4 h1:MuYw1wJzT+ZkybKfaOXKp5hJiZDn2iHaXRw0mRYdHSc= google.golang.org/genproto/googleapis/api v0.0.0-20240617180043-68d350f18fd4/go.mod h1:px9SlOOZBg1wM1zdnr8jEL4CNGUBZ+ZKYtNPApNQc4c= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 h1:Di6ANFilr+S60a4S61ZM00vLdw0IrQOSMS2/6mrnOU0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240709173604-40e1e62336c5 h1:SbSDUWW1PAO24TNpLdeheoYPd7kllICcLU52x6eD4kQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240709173604-40e1e62336c5/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= diff --git a/playground/package-lock.json b/playground/package-lock.json index 7093c27fef..d878c624b6 100644 --- a/playground/package-lock.json +++ b/playground/package-lock.json @@ -8,7 +8,7 @@ "name": "playground", "version": "0.0.0", "dependencies": { - "graphiql": "^3.3.2", + "graphiql": "^3.4.1", "graphql": "^16.9.0", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -25,7 +25,7 @@ "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.9", "typescript": "^5.5.4", - "vite": "^5.3.5" + "vite": "^5.4.0" } }, "node_modules/@babel/runtime": { @@ -53,9 +53,41 @@ "version": "7.0.2", "license": "MIT" }, + "node_modules/@codemirror/language": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.0.0.tgz", + "integrity": "sha512-rtjk5ifyMzOna1c7PBu7J1VCt0PvA5wy3o8eMVnxMKb7z8KA7JFecvD04dSn14vj/bBaAbqRsGed5OjtofEnLA==", + "peer": true, + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0", + "style-mod": "^4.0.0" + } + }, + "node_modules/@codemirror/state": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz", + "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==", + "peer": true + }, + "node_modules/@codemirror/view": { + "version": "6.32.0", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.32.0.tgz", + "integrity": "sha512-AgVNvED2QTsZp5e3syoHLsrWtwJFYWdx1Vr/m3f4h1ATQz0ax60CfXF3Htdmk69k2MlYZw8gXesnQdHtzyVmAw==", + "peer": true, + "dependencies": { + "@codemirror/state": "^6.4.0", + "style-mod": "^4.1.0", + "w3c-keyname": "^2.2.4" + } + }, "node_modules/@emotion/is-prop-valid": { "version": "0.8.8", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", "optional": true, "dependencies": { "@emotion/memoize": "0.7.4" @@ -63,7 +95,8 @@ }, "node_modules/@emotion/memoize": { "version": "0.7.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", "optional": true }, "node_modules/@esbuild/linux-x64": { @@ -203,23 +236,26 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.6.4", - "license": "MIT", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.7.tgz", + "integrity": "sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==", "dependencies": { - "@floating-ui/utils": "^0.2.4" + "@floating-ui/utils": "^0.2.7" } }, "node_modules/@floating-ui/dom": { - "version": "1.6.7", - "license": "MIT", + "version": "1.6.10", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.10.tgz", + "integrity": "sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==", "dependencies": { "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.4" + "@floating-ui/utils": "^0.2.7" } }, "node_modules/@floating-ui/react-dom": { "version": "2.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", + "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", "dependencies": { "@floating-ui/dom": "^1.0.0" }, @@ -229,14 +265,16 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.2.4", - "license": "MIT" + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.7.tgz", + "integrity": "sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==" }, "node_modules/@graphiql/react": { - "version": "0.22.4", - "license": "MIT", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@graphiql/react/-/react-0.23.1.tgz", + "integrity": "sha512-s0xeyDyaRcL5lkwloBob9vM+j5umfr+zxUvydRl3ZpIezmJiq5UXe5jRb2Rt+azHyNJ7yrcnqJgyW0MbyP9Mdw==", "dependencies": { - "@graphiql/toolkit": "^0.9.1", + "@graphiql/toolkit": "^0.9.2", "@headlessui/react": "^1.7.15", "@radix-ui/react-dialog": "^1.0.4", "@radix-ui/react-dropdown-menu": "^2.0.5", @@ -245,10 +283,10 @@ "@types/codemirror": "^5.60.8", "clsx": "^1.2.1", "codemirror": "^5.65.3", - "codemirror-graphql": "^2.0.12", + "codemirror-graphql": "^2.0.13", "copy-to-clipboard": "^3.2.0", "framer-motion": "^6.5.1", - "graphql-language-service": "^5.2.1", + "graphql-language-service": "^5.2.2", "markdown-it": "^14.1.0", "set-value": "^4.1.0" }, @@ -259,8 +297,9 @@ } }, "node_modules/@graphiql/toolkit": { - "version": "0.9.1", - "license": "MIT", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@graphiql/toolkit/-/toolkit-0.9.2.tgz", + "integrity": "sha512-QLPhwx9+E4JfGY+0iwFwa85OBjCJ7GHNypkQoz3pCOwAAlIpFBtXDOuLF1eH9Z08WNZSjRLL7VYW4Ci3hfTqxg==", "dependencies": { "@n1ru4l/push-pull-async-iterable-iterator": "^3.1.0", "meros": "^1.1.4" @@ -277,7 +316,8 @@ }, "node_modules/@headlessui/react": { "version": "1.7.19", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.19.tgz", + "integrity": "sha512-Ll+8q3OlMJfJbAKM/+/Y2q6PPYbryqNTXDbryx7SXLIDamkF6iQFbriYHga0dY44PvDhvvBWCx1Xj4U5+G4hOw==", "dependencies": { "@tanstack/react-virtual": "^3.0.0-beta.60", "client-only": "^0.0.1" @@ -315,9 +355,34 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@lezer/common": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz", + "integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ==", + "peer": true + }, + "node_modules/@lezer/highlight": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz", + "integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==", + "peer": true, + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@lezer/lr": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz", + "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==", + "peer": true, + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, "node_modules/@motionone/animation": { "version": "10.18.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@motionone/animation/-/animation-10.18.0.tgz", + "integrity": "sha512-9z2p5GFGCm0gBsZbi8rVMOAJCtw1WqBTIPw3ozk06gDvZInBPIsQcHgYogEJ4yuHJ+akuW8g1SEIOpTOvYs8hw==", "dependencies": { "@motionone/easing": "^10.18.0", "@motionone/types": "^10.17.1", @@ -327,7 +392,8 @@ }, "node_modules/@motionone/dom": { "version": "10.12.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@motionone/dom/-/dom-10.12.0.tgz", + "integrity": "sha512-UdPTtLMAktHiqV0atOczNYyDd/d8Cf5fFsd1tua03PqTwwCe/6lwhLSQ8a7TbnQ5SN0gm44N1slBfj+ORIhrqw==", "dependencies": { "@motionone/animation": "^10.12.0", "@motionone/generators": "^10.12.0", @@ -339,7 +405,8 @@ }, "node_modules/@motionone/easing": { "version": "10.18.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@motionone/easing/-/easing-10.18.0.tgz", + "integrity": "sha512-VcjByo7XpdLS4o9T8t99JtgxkdMcNWD3yHU/n6CLEz3bkmKDRZyYQ/wmSf6daum8ZXqfUAgFeCZSpJZIMxaCzg==", "dependencies": { "@motionone/utils": "^10.18.0", "tslib": "^2.3.1" @@ -347,7 +414,8 @@ }, "node_modules/@motionone/generators": { "version": "10.18.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@motionone/generators/-/generators-10.18.0.tgz", + "integrity": "sha512-+qfkC2DtkDj4tHPu+AFKVfR/C30O1vYdvsGYaR13W/1cczPrrcjdvYCj0VLFuRMN+lP1xvpNZHCRNM4fBzn1jg==", "dependencies": { "@motionone/types": "^10.17.1", "@motionone/utils": "^10.18.0", @@ -356,11 +424,13 @@ }, "node_modules/@motionone/types": { "version": "10.17.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@motionone/types/-/types-10.17.1.tgz", + "integrity": "sha512-KaC4kgiODDz8hswCrS0btrVrzyU2CSQKO7Ps90ibBVSQmjkrt2teqta6/sOG59v7+dPnKMAg13jyqtMKV2yJ7A==" }, "node_modules/@motionone/utils": { "version": "10.18.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@motionone/utils/-/utils-10.18.0.tgz", + "integrity": "sha512-3XVF7sgyTSI2KWvTf6uLlBJ5iAgRgmvp3bpuOiQJvInd4nZ19ET8lX5unn30SlmRH7hXbBbH+Gxd0m0klJ3Xtw==", "dependencies": { "@motionone/types": "^10.17.1", "hey-listen": "^1.0.8", @@ -369,7 +439,8 @@ }, "node_modules/@n1ru4l/push-pull-async-iterable-iterator": { "version": "3.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@n1ru4l/push-pull-async-iterable-iterator/-/push-pull-async-iterable-iterator-3.2.0.tgz", + "integrity": "sha512-3fkKj25kEjsfObL6IlKPAlHYPq/oYwUkkQ03zsTTiDjD7vg/RxjdiLeCydqtxHZP0JgsXL3D/X5oAkMGzuUp/Q==", "engines": { "node": ">=12" } @@ -408,11 +479,13 @@ }, "node_modules/@radix-ui/primitive": { "version": "1.1.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", + "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==" }, "node_modules/@radix-ui/react-arrow": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", + "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==", "dependencies": { "@radix-ui/react-primitive": "2.0.0" }, @@ -433,7 +506,8 @@ }, "node_modules/@radix-ui/react-collection": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz", + "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==", "dependencies": { "@radix-ui/react-compose-refs": "1.1.0", "@radix-ui/react-context": "1.1.0", @@ -457,7 +531,8 @@ }, "node_modules/@radix-ui/react-compose-refs": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", + "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -470,7 +545,8 @@ }, "node_modules/@radix-ui/react-context": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", + "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -483,7 +559,8 @@ }, "node_modules/@radix-ui/react-dialog": { "version": "1.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.1.tgz", + "integrity": "sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", @@ -517,7 +594,8 @@ }, "node_modules/@radix-ui/react-direction": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", + "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -530,7 +608,8 @@ }, "node_modules/@radix-ui/react-dismissable-layer": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz", + "integrity": "sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", @@ -555,7 +634,8 @@ }, "node_modules/@radix-ui/react-dropdown-menu": { "version": "2.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.1.tgz", + "integrity": "sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", @@ -582,7 +662,8 @@ }, "node_modules/@radix-ui/react-focus-guards": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz", + "integrity": "sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -595,7 +676,8 @@ }, "node_modules/@radix-ui/react-focus-scope": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz", + "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==", "dependencies": { "@radix-ui/react-compose-refs": "1.1.0", "@radix-ui/react-primitive": "2.0.0", @@ -618,7 +700,8 @@ }, "node_modules/@radix-ui/react-id": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", + "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.0" }, @@ -634,7 +717,8 @@ }, "node_modules/@radix-ui/react-menu": { "version": "2.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.1.tgz", + "integrity": "sha512-oa3mXRRVjHi6DZu/ghuzdylyjaMXLymx83irM7hTxutQbD+7IhPKdMdRHD26Rm+kHRrWcrUkkRPv5pd47a2xFQ==", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-collection": "1.1.0", @@ -672,7 +756,8 @@ }, "node_modules/@radix-ui/react-popper": { "version": "1.2.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", + "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==", "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.0", @@ -702,7 +787,8 @@ }, "node_modules/@radix-ui/react-portal": { "version": "1.1.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.1.tgz", + "integrity": "sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==", "dependencies": { "@radix-ui/react-primitive": "2.0.0", "@radix-ui/react-use-layout-effect": "1.1.0" @@ -724,7 +810,8 @@ }, "node_modules/@radix-ui/react-presence": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz", + "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==", "dependencies": { "@radix-ui/react-compose-refs": "1.1.0", "@radix-ui/react-use-layout-effect": "1.1.0" @@ -746,7 +833,8 @@ }, "node_modules/@radix-ui/react-primitive": { "version": "2.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", + "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", "dependencies": { "@radix-ui/react-slot": "1.1.0" }, @@ -767,7 +855,8 @@ }, "node_modules/@radix-ui/react-roving-focus": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz", + "integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-collection": "1.1.0", @@ -796,7 +885,8 @@ }, "node_modules/@radix-ui/react-slot": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", + "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", "dependencies": { "@radix-ui/react-compose-refs": "1.1.0" }, @@ -812,7 +902,8 @@ }, "node_modules/@radix-ui/react-tooltip": { "version": "1.1.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.2.tgz", + "integrity": "sha512-9XRsLwe6Yb9B/tlnYCPVUd/TFS4J7HuOZW345DCeC6vKIxQGMZdx21RK4VoZauPD5frgkXTYVS5y90L+3YBn4w==", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", @@ -844,7 +935,8 @@ }, "node_modules/@radix-ui/react-use-callback-ref": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", + "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -857,7 +949,8 @@ }, "node_modules/@radix-ui/react-use-controllable-state": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", + "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.0" }, @@ -873,7 +966,8 @@ }, "node_modules/@radix-ui/react-use-escape-keydown": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", + "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.0" }, @@ -889,7 +983,8 @@ }, "node_modules/@radix-ui/react-use-layout-effect": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", + "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -902,7 +997,8 @@ }, "node_modules/@radix-ui/react-use-rect": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", + "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", "dependencies": { "@radix-ui/rect": "1.1.0" }, @@ -918,7 +1014,8 @@ }, "node_modules/@radix-ui/react-use-size": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", + "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.0" }, @@ -934,7 +1031,8 @@ }, "node_modules/@radix-ui/react-visually-hidden": { "version": "1.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz", + "integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==", "dependencies": { "@radix-ui/react-primitive": "2.0.0" }, @@ -955,7 +1053,8 @@ }, "node_modules/@radix-ui/rect": { "version": "1.1.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", + "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==" }, "node_modules/@rollup/rollup-linux-x64-gnu": { "version": "4.18.1", @@ -1490,10 +1589,11 @@ } }, "node_modules/@tanstack/react-virtual": { - "version": "3.8.3", - "license": "MIT", + "version": "3.8.6", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.8.6.tgz", + "integrity": "sha512-YcOQAxccjIqiC8cQ8QQiDU6F+JZtfpKNvYsw/ju5Q6S5/m9KDs5SaJvKz1kLj3RKNAOBMIFA9snN2MDmyT9lBQ==", "dependencies": { - "@tanstack/virtual-core": "3.8.3" + "@tanstack/virtual-core": "3.8.6" }, "funding": { "type": "github", @@ -1505,8 +1605,9 @@ } }, "node_modules/@tanstack/virtual-core": { - "version": "3.8.3", - "license": "MIT", + "version": "3.8.6", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.8.6.tgz", + "integrity": "sha512-UJeU4SBrx3hqULNzJ3oC0kgJ5miIAg+FwomxMTlQNxob6ppTInifANHd9ukETvzdzxr6zt3CjQ0rttQpVjbt6Q==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" @@ -1514,7 +1615,8 @@ }, "node_modules/@types/codemirror": { "version": "5.60.15", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.15.tgz", + "integrity": "sha512-dTOvwEQ+ouKJ/rE9LT1Ue2hmP6H1mZv5+CCnNWu2qtiOe2LQa9lCprEY20HxiDmV/Bxh+dXjywmy5aKvoGjULA==", "dependencies": { "@types/tern": "*" } @@ -1532,7 +1634,7 @@ }, "node_modules/@types/prop-types": { "version": "15.7.12", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@types/ramda": { @@ -1544,7 +1646,7 @@ }, "node_modules/@types/react": { "version": "18.3.3", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -1553,7 +1655,7 @@ }, "node_modules/@types/react-dom": { "version": "18.3.0", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@types/react": "*" @@ -1569,7 +1671,8 @@ }, "node_modules/@types/tern": { "version": "0.23.9", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.9.tgz", + "integrity": "sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==", "dependencies": { "@types/estree": "*" } @@ -1836,7 +1939,8 @@ }, "node_modules/aria-hidden": { "version": "1.2.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", + "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", "dependencies": { "tslib": "^2.0.0" }, @@ -2021,25 +2125,29 @@ }, "node_modules/client-only": { "version": "0.0.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, "node_modules/clsx": { "version": "1.2.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", "engines": { "node": ">=6" } }, "node_modules/codemirror": { - "version": "5.65.16", - "license": "MIT" + "version": "5.65.17", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.17.tgz", + "integrity": "sha512-1zOsUx3lzAOu/gnMAZkQ9kpIHcPYOc9y1Fbm2UVk5UBPkdq380nhkelG0qUwm1f7wPvTbndu9ZYlug35EwAZRQ==" }, "node_modules/codemirror-graphql": { - "version": "2.0.12", - "license": "MIT", + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/codemirror-graphql/-/codemirror-graphql-2.0.13.tgz", + "integrity": "sha512-MBx8BtfqpacLUwcx0smI0JLq7uR6ssKvdF0ENz0yV1w1xqKmFcZ29uHh11LMWdeLL0j14KXGSIDl97fovfdszQ==", "dependencies": { "@types/codemirror": "^0.0.90", - "graphql-language-service": "5.2.1" + "graphql-language-service": "5.2.2" }, "peerDependencies": { "@codemirror/language": "6.0.0", @@ -2049,7 +2157,8 @@ }, "node_modules/codemirror-graphql/node_modules/@types/codemirror": { "version": "0.0.90", - "license": "MIT", + "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-0.0.90.tgz", + "integrity": "sha512-8Z9+tSg27NPRGubbUPUCrt5DDG/OWzLph5BvcDykwR5D7RyZh5mhHG0uS1ePKV1YFCA+/cwc4Ey2AJAEFfV3IA==", "dependencies": { "@types/tern": "*" } @@ -2135,9 +2244,14 @@ }, "node_modules/csstype": { "version": "3.1.3", - "dev": true, + "devOptional": true, "license": "MIT" }, + "node_modules/debounce-promise": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/debounce-promise/-/debounce-promise-3.1.2.tgz", + "integrity": "sha512-rZHcgBkbYavBeD9ej6sP56XfG53d51CD4dnaw989YX/nZ/ZJfgRx/9ePKmTNiUiyQvh4mtrMoS3OAWW+yoYtpg==" + }, "node_modules/debug": { "version": "4.3.5", "dev": true, @@ -2219,7 +2333,8 @@ }, "node_modules/detect-node-es": { "version": "1.1.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" }, "node_modules/dir-glob": { "version": "3.0.1", @@ -2253,7 +2368,8 @@ }, "node_modules/entities": { "version": "4.5.0", - "license": "BSD-2-Clause", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "engines": { "node": ">=0.12" }, @@ -2701,7 +2817,8 @@ }, "node_modules/framer-motion": { "version": "6.5.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-6.5.1.tgz", + "integrity": "sha512-o1BGqqposwi7cgDrtg0dNONhkmPsUFDaLcKXigzuTFC5x58mE8iyTazxSudFzmT6MEyJKfjjU8ItoMe3W+3fiw==", "dependencies": { "@motionone/dom": "10.12.0", "framesync": "6.0.1", @@ -2720,7 +2837,8 @@ }, "node_modules/framesync": { "version": "6.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/framesync/-/framesync-6.0.1.tgz", + "integrity": "sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==", "dependencies": { "tslib": "^2.1.0" } @@ -2730,6 +2848,20 @@ "license": "MIT", "optional": true }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "license": "MIT", @@ -2756,7 +2888,8 @@ }, "node_modules/get-nonce": { "version": "1.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", "engines": { "node": ">=6" } @@ -2824,13 +2957,11 @@ "license": "MIT" }, "node_modules/graphiql": { - "version": "3.3.2", - "license": "MIT", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/graphiql/-/graphiql-3.4.1.tgz", + "integrity": "sha512-jSx8O6OWa2wSsEt1OBT6aQRT3NQLzjQuVCjNNijZa81Y3h3DJJ9inDHk/UFNhzL8xUwiDxV1zYXNopCCM6OhNw==", "dependencies": { - "@graphiql/react": "^0.22.4", - "@graphiql/toolkit": "^0.9.1", - "graphql-language-service": "^5.2.1", - "markdown-it": "^14.1.0" + "@graphiql/react": "^0.23.1" }, "peerDependencies": { "graphql": "^15.5.0 || ^16.0.0", @@ -2846,9 +2977,11 @@ } }, "node_modules/graphql-language-service": { - "version": "5.2.1", - "license": "MIT", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/graphql-language-service/-/graphql-language-service-5.2.2.tgz", + "integrity": "sha512-ulIM1xE2eyEk8/QKg7I9QCGQWijNNZVwQ/dpm0B1XwD9AfYzeaGkipcsxW3JPmurt/d/ZMYRxK5Y0d2amrXEtQ==", "dependencies": { + "debounce-promise": "^3.1.2", "nullthrows": "^1.0.0", "vscode-languageserver-types": "^3.17.1" }, @@ -2932,7 +3065,8 @@ }, "node_modules/hey-listen": { "version": "1.0.8", - "license": "MIT" + "resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz", + "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==" }, "node_modules/highlight.js": { "version": "10.7.3", @@ -3087,7 +3221,8 @@ }, "node_modules/is-plain-object": { "version": "2.0.4", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dependencies": { "isobject": "^3.0.1" }, @@ -3097,7 +3232,8 @@ }, "node_modules/is-primitive": { "version": "3.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-3.0.1.tgz", + "integrity": "sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w==", "engines": { "node": ">=0.10.0" } @@ -3109,7 +3245,8 @@ }, "node_modules/isobject": { "version": "3.0.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "engines": { "node": ">=0.10.0" } @@ -3172,7 +3309,8 @@ }, "node_modules/linkify-it": { "version": "5.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", "dependencies": { "uc.micro": "^2.0.0" } @@ -3228,7 +3366,8 @@ }, "node_modules/markdown-it": { "version": "14.1.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", @@ -3243,7 +3382,8 @@ }, "node_modules/mdurl": { "version": "2.0.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==" }, "node_modules/merge2": { "version": "1.4.1", @@ -3255,7 +3395,8 @@ }, "node_modules/meros": { "version": "1.3.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/meros/-/meros-1.3.0.tgz", + "integrity": "sha512-2BNGOimxEz5hmjUG2FwoxCt5HN7BXdaWyFqEwxPTrJzVdABtrL4TiHTcsWSFAxPQ/tOnEaQEJh3qWq71QRMY+w==", "engines": { "node": ">=13" }, @@ -3357,6 +3498,8 @@ }, "node_modules/nanoid": { "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true, "funding": [ { @@ -3364,7 +3507,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -3431,7 +3573,8 @@ }, "node_modules/nullthrows": { "version": "1.1.1", - "license": "MIT" + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==" }, "node_modules/object-assign": { "version": "4.1.1", @@ -3576,8 +3719,9 @@ }, "node_modules/picocolors": { "version": "1.0.1", - "dev": true, - "license": "ISC" + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true }, "node_modules/picomatch": { "version": "2.3.1", @@ -3592,7 +3736,8 @@ }, "node_modules/popmotion": { "version": "11.0.3", - "license": "MIT", + "resolved": "https://registry.npmjs.org/popmotion/-/popmotion-11.0.3.tgz", + "integrity": "sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA==", "dependencies": { "framesync": "6.0.1", "hey-listen": "^1.0.8", @@ -3601,7 +3746,9 @@ } }, "node_modules/postcss": { - "version": "8.4.39", + "version": "8.4.41", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", + "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", "dev": true, "funding": [ { @@ -3617,7 +3764,6 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.1", @@ -3718,7 +3864,8 @@ }, "node_modules/punycode.js": { "version": "2.3.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", "engines": { "node": ">=6" } @@ -3917,7 +4064,8 @@ }, "node_modules/react-remove-scroll": { "version": "2.5.7", - "license": "MIT", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz", + "integrity": "sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==", "dependencies": { "react-remove-scroll-bar": "^2.3.4", "react-style-singleton": "^2.2.1", @@ -3940,7 +4088,8 @@ }, "node_modules/react-remove-scroll-bar": { "version": "2.3.6", - "license": "MIT", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz", + "integrity": "sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==", "dependencies": { "react-style-singleton": "^2.2.1", "tslib": "^2.0.0" @@ -3960,7 +4109,8 @@ }, "node_modules/react-style-singleton": { "version": "2.2.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", "dependencies": { "get-nonce": "^1.0.0", "invariant": "^2.2.4", @@ -4224,12 +4374,13 @@ }, "node_modules/set-value": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-4.1.0.tgz", + "integrity": "sha512-zTEg4HL0RwVrqcWs3ztF+x1vkxfm0lP+MQQFPiMJTKVceBwEV0A569Ou8l9IYQG8jOZdMVI1hGsc0tmeD2o/Lw==", "funding": [ "https://github.com/sponsors/jonschlinkert", "https://paypal.me/jonathanschlinkert", "https://jonschlinkert.dev/sponsor" ], - "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4", "is-primitive": "^3.0.1" @@ -4345,8 +4496,9 @@ }, "node_modules/source-map-js": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true, - "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -4394,9 +4546,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/style-mod": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz", + "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==", + "peer": true + }, "node_modules/style-value-types": { "version": "5.0.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-5.0.0.tgz", + "integrity": "sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA==", "dependencies": { "hey-listen": "^1.0.8", "tslib": "^2.1.0" @@ -4637,7 +4796,8 @@ }, "node_modules/uc.micro": { "version": "2.1.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==" }, "node_modules/unraw": { "version": "3.0.0", @@ -4662,7 +4822,8 @@ }, "node_modules/use-callback-ref": { "version": "1.3.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz", + "integrity": "sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==", "dependencies": { "tslib": "^2.0.0" }, @@ -4681,7 +4842,8 @@ }, "node_modules/use-sidecar": { "version": "1.1.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" @@ -4712,12 +4874,13 @@ "optional": true }, "node_modules/vite": { - "version": "5.3.5", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.0.tgz", + "integrity": "sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg==", "dev": true, - "license": "MIT", "dependencies": { "esbuild": "^0.21.3", - "postcss": "^8.4.39", + "postcss": "^8.4.40", "rollup": "^4.13.0" }, "bin": { @@ -4737,6 +4900,7 @@ "less": "*", "lightningcss": "^1.21.0", "sass": "*", + "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" @@ -4754,6 +4918,9 @@ "sass": { "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true }, @@ -4767,7 +4934,20 @@ }, "node_modules/vscode-languageserver-types": { "version": "3.17.5", - "license": "MIT" + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==" + }, + "node_modules/w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", + "peer": true + }, + "node_modules/w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", + "peer": true }, "node_modules/web-streams-polyfill": { "version": "3.3.3", diff --git a/playground/package.json b/playground/package.json index 4873eff5e6..6be92d6c8c 100644 --- a/playground/package.json +++ b/playground/package.json @@ -10,7 +10,7 @@ "preview": "vite preview" }, "dependencies": { - "graphiql": "^3.3.2", + "graphiql": "^3.4.1", "graphql": "^16.9.0", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -27,6 +27,6 @@ "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.9", "typescript": "^5.5.4", - "vite": "^5.3.5" + "vite": "^5.4.0" } } From 94222441f2df2023829bbc480fc6f87adaad461f Mon Sep 17 00:00:00 2001 From: Islam Aliev Date: Tue, 20 Aug 2024 08:20:17 +0200 Subject: [PATCH 32/41] fix: No panic if filter condition on indexed field is empty (#2929) ## Relevant issue(s) Resolves #2916 ## Description Check if given filter condition is empty before proceeding with secondary index fetching. --- internal/db/fetcher/indexer.go | 30 ++++++++------ internal/db/fetcher/indexer_iterators.go | 5 +++ .../query_with_index_only_filter_test.go | 41 +++++++++++++++++++ 3 files changed, 63 insertions(+), 13 deletions(-) diff --git a/internal/db/fetcher/indexer.go b/internal/db/fetcher/indexer.go index e75cc18067..7eb8f5b117 100644 --- a/internal/db/fetcher/indexer.go +++ b/internal/db/fetcher/indexer.go @@ -31,7 +31,6 @@ type IndexFetcher struct { col client.Collection txn datastore.Txn indexFilter *mapper.Filter - docFilter *mapper.Filter doc *encodedDocument mapping *core.DocumentMapping indexedFields []client.FieldDefinition @@ -71,7 +70,6 @@ func (f *IndexFetcher) Init( f.resetState() f.col = col - f.docFilter = filter f.doc = &encodedDocument{} f.mapping = docMapper f.txn = txn @@ -100,7 +98,12 @@ outer: } f.indexIter = iter - if f.docFetcher != nil && len(f.docFields) > 0 { + // if it turns out that we can't use the index, we need to fall back to the document fetcher + if f.indexIter == nil { + f.docFields = fields + } + + if len(f.docFields) > 0 { err = f.docFetcher.Init( ctx, identity, @@ -108,7 +111,7 @@ outer: acp, f.col, f.docFields, - f.docFilter, + filter, f.mapping, false, false, @@ -119,14 +122,16 @@ outer: } func (f *IndexFetcher) Start(ctx context.Context, spans core.Spans) error { - err := f.indexIter.Init(ctx, f.txn.Datastore()) - if err != nil { - return err + if f.indexIter == nil { + return f.docFetcher.Start(ctx, spans) } - return nil + return f.indexIter.Init(ctx, f.txn.Datastore()) } func (f *IndexFetcher) FetchNext(ctx context.Context) (EncodedDocument, ExecInfo, error) { + if f.indexIter == nil { + return f.docFetcher.FetchNext(ctx) + } totalExecInfo := f.execInfo defer func() { f.execInfo.Add(totalExecInfo) }() f.execInfo.Reset() @@ -176,7 +181,7 @@ func (f *IndexFetcher) FetchNext(ctx context.Context) (EncodedDocument, ExecInfo } } - if f.docFetcher != nil && len(f.docFields) > 0 { + if len(f.docFields) > 0 { targetKey := base.MakeDataStoreKeyWithCollectionAndDocID(f.col.Description(), string(f.doc.id)) spans := core.NewSpans(core.NewSpan(targetKey, targetKey.PrefixEnd())) err := f.docFetcher.Start(ctx, spans) @@ -204,10 +209,10 @@ func (f *IndexFetcher) FetchNext(ctx context.Context) (EncodedDocument, ExecInfo } func (f *IndexFetcher) Close() error { - if f.indexIter != nil { - return f.indexIter.Close() + if f.indexIter == nil { + return f.docFetcher.Close() } - return nil + return f.indexIter.Close() } // resetState resets the mutable state of this IndexFetcher, returning the state to how it @@ -217,7 +222,6 @@ func (f *IndexFetcher) resetState() { f.col = nil f.txn = nil - f.docFilter = nil f.doc = nil f.mapping = nil f.indexedFields = nil diff --git a/internal/db/fetcher/indexer_iterators.go b/internal/db/fetcher/indexer_iterators.go index 9f01379fa6..c36d679355 100644 --- a/internal/db/fetcher/indexer_iterators.go +++ b/internal/db/fetcher/indexer_iterators.go @@ -538,6 +538,11 @@ func (f *IndexFetcher) createIndexIterator() (indexIterator, error) { return nil, err } + // this can happen if a query contains an empty condition like User(filter: {name: {}}) + if len(fieldConditions) == 0 { + return nil, nil + } + matchers, err := createValueMatchers(fieldConditions) if err != nil { return nil, err diff --git a/tests/integration/index/query_with_index_only_filter_test.go b/tests/integration/index/query_with_index_only_filter_test.go index 1800b855aa..5de362ec81 100644 --- a/tests/integration/index/query_with_index_only_filter_test.go +++ b/tests/integration/index/query_with_index_only_filter_test.go @@ -677,3 +677,44 @@ func TestQueryWithIndex_WithNotLikeFilter_ShouldFetch(t *testing.T) { testUtils.ExecuteTestCase(t, test) } + +func TestQueryWithIndex_EmptyFilterOnIndexedField_ShouldSucceed(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String @index + age: Int + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Islam", + "age": 33 + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "John", + "age": 21 + }`, + }, + testUtils.Request{ + Request: `query { + User(filter: {name: {}}) { + name + } + }`, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Islam"}, + {"name": "John"}, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} From 373f90bf1220380b60e013a1156cd77b811c8307 Mon Sep 17 00:00:00 2001 From: Islam Aliev Date: Tue, 20 Aug 2024 22:43:35 +0200 Subject: [PATCH 33/41] feat: Enable indexing for DateTime fields (#2933) ## Relevant issue(s) Resolves #2914 ## Description Make indexes handle time.Time type as well. For this encoding/decoding of time type is added to encoding package. --- go.mod | 2 +- internal/db/fetcher/indexer_iterators.go | 38 +++ internal/encoding/encoding.go | 1 + internal/encoding/field_value.go | 26 ++ internal/encoding/time.go | 78 +++++ internal/encoding/type.go | 3 + tests/integration/index/create_unique_test.go | 32 ++ .../index/query_with_index_on_datetime.go | 276 ++++++++++++++++++ ...uery_with_unique_index_only_filter_test.go | 47 +++ 9 files changed, 502 insertions(+), 1 deletion(-) create mode 100644 internal/encoding/time.go create mode 100644 tests/integration/index/query_with_index_on_datetime.go diff --git a/go.mod b/go.mod index 5373d28a59..c755e99730 100644 --- a/go.mod +++ b/go.mod @@ -40,6 +40,7 @@ require ( github.com/multiformats/go-multicodec v0.9.0 github.com/multiformats/go-multihash v0.2.3 github.com/pelletier/go-toml v1.9.5 + github.com/pkg/errors v0.9.1 github.com/sourcenetwork/acp_core v0.0.0-20240607160510-47a5306b2ad2 github.com/sourcenetwork/badger/v4 v4.2.1-0.20231113215945-a63444ca5276 github.com/sourcenetwork/corelog v0.0.8 @@ -304,7 +305,6 @@ require ( github.com/pion/turn/v2 v2.1.6 // indirect github.com/pion/webrtc/v3 v3.2.50 // indirect github.com/piprate/json-gold v0.5.0 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/pquerna/cachecontrol v0.1.0 // indirect diff --git a/internal/db/fetcher/indexer_iterators.go b/internal/db/fetcher/indexer_iterators.go index c36d679355..2589ea92e4 100644 --- a/internal/db/fetcher/indexer_iterators.go +++ b/internal/db/fetcher/indexer_iterators.go @@ -15,6 +15,7 @@ import ( "context" "errors" "strings" + "time" ds "github.com/ipfs/go-datastore" @@ -331,6 +332,37 @@ func (m *stringMatcher) Match(value client.NormalValue) (bool, error) { return false, NewErrUnexpectedTypeValue[string](value) } +type timeMatcher struct { + op string + value time.Time +} + +func (m *timeMatcher) Match(value client.NormalValue) (bool, error) { + timeVal, ok := value.Time() + if !ok { + if timeOptVal, ok := value.NillableTime(); ok { + timeVal = timeOptVal.Value() + } else { + return false, NewErrUnexpectedTypeValue[time.Time](value) + } + } + switch m.op { + case opEq: + return timeVal.Equal(m.value), nil + case opGt: + return timeVal.After(m.value), nil + case opGe: + return !timeVal.Before(m.value), nil + case opLt: + return timeVal.Before(m.value), nil + case opLe: + return !timeVal.After(m.value), nil + case opNe: + return !timeVal.Equal(m.value), nil + } + return false, NewErrInvalidFilterOperator(m.op) +} + type nilMatcher struct { matchNil bool } @@ -608,6 +640,12 @@ func createValueMatcher(condition *fieldFilterCond) (valueMatcher, error) { if v, ok := condition.val.NillableString(); ok { return &stringMatcher{value: v.Value(), evalFunc: getCompareValsFunc[string](condition.op)}, nil } + if v, ok := condition.val.Time(); ok { + return &timeMatcher{value: v, op: condition.op}, nil + } + if v, ok := condition.val.NillableTime(); ok { + return &timeMatcher{value: v.Value(), op: condition.op}, nil + } case opIn, opNin: inVals, err := client.ToArrayOfNormalValues(condition.val) if err != nil { diff --git a/internal/encoding/encoding.go b/internal/encoding/encoding.go index 164706d922..188cf73ad3 100644 --- a/internal/encoding/encoding.go +++ b/internal/encoding/encoding.go @@ -27,6 +27,7 @@ const ( floatNaNDesc bytesMarker bytesDescMarker + timeMarker // These constants define a range of values and are used to determine how many bytes are // needed to represent the given uint64 value. The constants IntMin and IntMax define the diff --git a/internal/encoding/field_value.go b/internal/encoding/field_value.go index f62375a461..34bbdd99df 100644 --- a/internal/encoding/field_value.go +++ b/internal/encoding/field_value.go @@ -11,6 +11,8 @@ package encoding import ( + "time" + "github.com/sourcenetwork/defradb/client" ) @@ -80,6 +82,18 @@ func EncodeFieldValue(b []byte, val client.NormalValue, descending bool) []byte } return EncodeStringAscending(b, v.Value()) } + if v, ok := val.Time(); ok { + if descending { + return EncodeTimeDescending(b, v) + } + return EncodeTimeAscending(b, v) + } + if v, ok := val.NillableTime(); ok { + if descending { + return EncodeTimeDescending(b, v.Value()) + } + return EncodeTimeAscending(b, v.Value()) + } return b } @@ -129,6 +143,18 @@ func DecodeFieldValue(b []byte, descending bool, kind client.FieldKind) ([]byte, return nil, nil, NewErrCanNotDecodeFieldValue(b, kind, err) } return b, client.NewNormalString(v), nil + case Time: + var v time.Time + var err error + if descending { + b, v, err = DecodeTimeDescending(b) + } else { + b, v, err = DecodeTimeAscending(b) + } + if err != nil { + return nil, nil, NewErrCanNotDecodeFieldValue(b, kind, err) + } + return b, client.NewNormalTime(v), nil } return nil, nil, NewErrCanNotDecodeFieldValue(b, kind) diff --git a/internal/encoding/time.go b/internal/encoding/time.go new file mode 100644 index 0000000000..4fb9d4aa4a --- /dev/null +++ b/internal/encoding/time.go @@ -0,0 +1,78 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License + +package encoding + +import ( + "time" + + "github.com/pkg/errors" +) + +// EncodeTimeAscending encodes a time value, appends it to the supplied buffer, +// and returns the final buffer. The encoding is guaranteed to be ordered +// Such that if t1.Before(t2) then after EncodeTime(b1, t1), and +// EncodeTime(b2, t2), Compare(b1, b2) < 0. The time zone offset not +// included in the encoding. +func EncodeTimeAscending(b []byte, t time.Time) []byte { + return encodeTime(b, t.Unix(), int64(t.Nanosecond())) +} + +// EncodeTimeDescending is the descending version of EncodeTimeAscending. +func EncodeTimeDescending(b []byte, t time.Time) []byte { + return encodeTime(b, ^t.Unix(), ^int64(t.Nanosecond())) +} + +func encodeTime(b []byte, unix, nanos int64) []byte { + // Read the unix absolute time. This is the absolute time and is + // not time zone offset dependent. + b = append(b, timeMarker) + b = EncodeVarintAscending(b, unix) + b = EncodeVarintAscending(b, nanos) + return b +} + +// DecodeTimeAscending decodes a time.Time value which was encoded using +// EncodeTime. The remainder of the input buffer and the decoded +// time.Time are returned. +func DecodeTimeAscending(b []byte) ([]byte, time.Time, error) { + b, sec, nsec, err := decodeTime(b) + if err != nil { + return b, time.Time{}, err + } + return b, time.Unix(sec, nsec).UTC(), nil +} + +// DecodeTimeDescending is the descending version of DecodeTimeAscending. +func DecodeTimeDescending(b []byte) ([]byte, time.Time, error) { + b, sec, nsec, err := decodeTime(b) + if err != nil { + return b, time.Time{}, err + } + return b, time.Unix(^sec, ^nsec).UTC(), nil +} + +func decodeTime(b []byte) (r []byte, sec int64, nsec int64, err error) { + if PeekType(b) != Time { + return nil, 0, 0, errors.Errorf("did not find marker") + } + b = b[1:] + b, sec, err = DecodeVarintAscending(b) + if err != nil { + return b, 0, 0, err + } + b, nsec, err = DecodeVarintAscending(b) + if err != nil { + return b, 0, 0, err + } + return b, sec, nsec, nil +} diff --git a/internal/encoding/type.go b/internal/encoding/type.go index b4b85cf7bf..a551ca93e6 100644 --- a/internal/encoding/type.go +++ b/internal/encoding/type.go @@ -23,6 +23,7 @@ const ( Float Type = 4 Bytes Type = 6 BytesDesc Type = 7 + Time Type = 8 ) // PeekType peeks at the type of the value encoded at the start of b. @@ -40,6 +41,8 @@ func PeekType(b []byte) Type { return Int case m >= floatNaN && m <= floatNaNDesc: return Float + case m == timeMarker: + return Time } } return Unknown diff --git a/tests/integration/index/create_unique_test.go b/tests/integration/index/create_unique_test.go index eb353ca70e..932beb5e40 100644 --- a/tests/integration/index/create_unique_test.go +++ b/tests/integration/index/create_unique_test.go @@ -315,3 +315,35 @@ func TestUniqueIndexCreate_UponAddingDocWithExistingNilValue_ShouldSucceed(t *te testUtils.ExecuteTestCase(t, test) } + +func TestUniqueQueryWithIndex_UponAddingDocWithSameDateTime_Error(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + birthday: DateTime @index(unique: true) + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Fred", + "birthday": "2000-07-23T03:00:00-00:00" + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Andy", + "birthday": "2000-07-23T03:00:00-00:00" + }`, + ExpectedError: db.NewErrCanNotIndexNonUniqueFields( + "bae-2000529a-8b27-539b-91e9-c35f431fb78e", + errors.NewKV("birthday", testUtils.MustParseTime("2000-07-23T03:00:00-00:00")), + ).Error(), + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/index/query_with_index_on_datetime.go b/tests/integration/index/query_with_index_on_datetime.go new file mode 100644 index 0000000000..d6618fbc1a --- /dev/null +++ b/tests/integration/index/query_with_index_on_datetime.go @@ -0,0 +1,276 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package index + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestQueryWithIndex_WithEqFilterOnDateTimeField_ShouldIndex(t *testing.T) { + req := `query { + User(filter: {birthday: {_eq: "2000-07-23T03:00:00-00:00"}}) { + name + } + }` + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + birthday: DateTime @index + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Fred", + "birthday": "2000-07-23T03:00:00-00:00" + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Andy", + "birthday": "2001-08-23T03:00:00-00:00" + }`, + }, + testUtils.Request{ + Request: req, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Fred"}, + }, + }, + }, + testUtils.Request{ + Request: makeExplainQuery(req), + Asserter: testUtils.NewExplainAsserter().WithFieldFetches(1).WithIndexFetches(1), + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestQueryWithIndex_WithGtFilterOnDateTimeField_ShouldIndex(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + birthday: DateTime @index + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Fred", + "birthday": "2000-07-23T03:00:00-00:00" + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Andy", + "birthday": "2001-08-23T03:00:00-00:00" + }`, + }, + testUtils.Request{ + Request: `query { + User(filter: {birthday: {_gt: "2001-01-01T00:00:00-00:00"}}) { + name + } + }`, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Andy"}, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestQueryWithIndex_WithGeFilterOnDateTimeField_ShouldIndex(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + birthday: DateTime @index + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Fred", + "birthday": "2000-07-23T03:00:00-00:00" + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Andy", + "birthday": "2001-08-23T03:00:00-00:00" + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Keenan", + "birthday": "2001-01-01T00:00:00-00:00" + }`, + }, + testUtils.Request{ + Request: `query { + User(filter: {birthday: {_ge: "2001-01-01T00:00:00-00:00"}}) { + name + } + }`, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Keenan"}, + {"name": "Andy"}, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestQueryWithIndex_WithLtFilterOnDateTimeField_ShouldIndex(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + birthday: DateTime @index + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Fred", + "birthday": "2000-07-23T03:00:00-00:00" + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Andy", + "birthday": "2001-08-23T03:00:00-00:00" + }`, + }, + testUtils.Request{ + Request: `query { + User(filter: {birthday: {_lt: "2001-01-01T00:00:00-00:00"}}) { + name + } + }`, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Fred"}, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestQueryWithIndex_WithLeFilterOnDateTimeField_ShouldIndex(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + birthday: DateTime @index + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Fred", + "birthday": "2000-07-23T03:00:00-00:00" + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Andy", + "birthday": "2001-08-23T03:00:00-00:00" + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Keenan", + "birthday": "2001-01-01T00:00:00-00:00" + }`, + }, + testUtils.Request{ + Request: `query { + User(filter: {birthday: {_le: "2001-01-01T00:00:00-00:00"}}) { + name + } + }`, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Fred"}, + {"name": "Keenan"}, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestQueryWithIndex_WithNeFilterOnDateTimeField_ShouldIndex(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + birthday: DateTime @index + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Fred", + "birthday": "2000-07-23T03:00:00-00:00" + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Andy", + "birthday": "2001-08-23T03:00:00-00:00" + }`, + }, + testUtils.Request{ + Request: `query { + User(filter: {birthday: {_ne: "2000-07-23T03:00:00-00:00"}}) { + name + } + }`, + Results: map[string]any{ + "User": []map[string]any{ + {"name": "Andy"}, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/index/query_with_unique_index_only_filter_test.go b/tests/integration/index/query_with_unique_index_only_filter_test.go index 50bb86712d..4da1bb63ed 100644 --- a/tests/integration/index/query_with_unique_index_only_filter_test.go +++ b/tests/integration/index/query_with_unique_index_only_filter_test.go @@ -778,3 +778,50 @@ func TestQueryWithUniqueIndex_WithMultipleNilValuesAndEqualFilter_ShouldFetch(t testUtils.ExecuteTestCase(t, test) } + +func TestQueryWithUniqueIndex_WithDateTimeField_ShouldIndex(t *testing.T) { + req := `query { + User(filter: {birthday: {_eq: "2000-07-23T03:00:00-00:00"}}) { + name + } + }` + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + birthday: DateTime @index(unique: true) + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Fred", + "birthday": "2000-07-23T03:00:00-00:00" + }`, + }, + testUtils.CreateDoc{ + Doc: `{ + "name": "Andy", + "birthday": "2001-08-23T03:00:00-00:00" + }`, + }, + testUtils.Request{ + Request: req, + Results: map[string]any{ + "User": []map[string]any{ + { + "name": "Fred", + }, + }, + }, + }, + testUtils.Request{ + Request: makeExplainQuery(req), + Asserter: testUtils.NewExplainAsserter().WithFieldFetches(1).WithIndexFetches(1), + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} From c4b256824b665c2f2ff852d3714f9141627b55d3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2024 04:38:58 -0400 Subject: [PATCH 34/41] bot: Update dependencies (bulk dependabot PRs) 20-08-2024 (#2932) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✅ This PR was created by combining the following PRs: #2923 bot: Bump github.com/cosmos/gogoproto from 1.6.0 to 1.7.0 #2922 bot: Bump github.com/libp2p/go-libp2p-pubsub from 0.11.0 to 0.12.0 #2921 bot: Bump vite from 5.4.0 to 5.4.1 in /playground #2920 bot: Bump graphiql from 3.4.1 to 3.7.0 in /playground #2919 bot: Bump @typescript-eslint/eslint-plugin from 8.0.1 to 8.1.0 in /playground ⚠️ The following PRs resolved manually due to merge conflicts: #2918 bot: Bump @typescript-eslint/parser from 8.0.1 to 8.1.0 in /playground --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Shahzad Lone --- go.mod | 48 ++--- go.sum | 106 ++++----- playground/package-lock.json | 405 +++++++++++++++++++++++++++++------ playground/package.json | 8 +- 4 files changed, 417 insertions(+), 150 deletions(-) diff --git a/go.mod b/go.mod index c755e99730..1fdba68594 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/bits-and-blooms/bitset v1.13.0 github.com/bxcodec/faker v2.0.1+incompatible github.com/cosmos/cosmos-sdk v0.50.9 - github.com/cosmos/gogoproto v1.6.0 + github.com/cosmos/gogoproto v1.7.0 github.com/cyware/ssi-sdk v0.0.0-20231229164914-f93f3006379f github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 github.com/evanphx/json-patch/v5 v5.9.0 @@ -29,10 +29,10 @@ require ( github.com/jbenet/goprocess v0.1.4 github.com/lens-vm/lens/host-go v0.0.0-20231127204031-8d858ed2926c github.com/lestrrat-go/jwx/v2 v2.1.1 - github.com/libp2p/go-libp2p v0.36.1 + github.com/libp2p/go-libp2p v0.36.2 github.com/libp2p/go-libp2p-gostream v0.6.0 github.com/libp2p/go-libp2p-kad-dht v0.25.2 - github.com/libp2p/go-libp2p-pubsub v0.11.0 + github.com/libp2p/go-libp2p-pubsub v0.12.0 github.com/libp2p/go-libp2p-record v0.2.0 github.com/mr-tron/base58 v1.2.0 github.com/multiformats/go-multiaddr v0.13.0 @@ -59,7 +59,7 @@ require ( go.opentelemetry.io/otel/metric v1.28.0 go.opentelemetry.io/otel/sdk/metric v1.28.0 go.uber.org/zap v1.27.0 - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa golang.org/x/term v0.23.0 google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 @@ -262,7 +262,7 @@ require ( github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/miekg/dns v1.1.61 // indirect + github.com/miekg/dns v1.1.62 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/highwayhash v1.0.2 // indirect @@ -281,7 +281,7 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect github.com/oklog/run v1.1.0 // indirect - github.com/onsi/ginkgo/v2 v2.19.1 // indirect + github.com/onsi/ginkgo/v2 v2.20.0 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect @@ -290,30 +290,30 @@ require ( github.com/petermattis/goid v0.0.0-20231207134359-e60b3f734c67 // indirect github.com/pion/datachannel v1.5.8 // indirect github.com/pion/dtls/v2 v2.2.12 // indirect - github.com/pion/ice/v2 v2.3.32 // indirect - github.com/pion/interceptor v0.1.29 // indirect + github.com/pion/ice/v2 v2.3.34 // indirect + github.com/pion/interceptor v0.1.30 // indirect github.com/pion/logging v0.2.2 // indirect github.com/pion/mdns v0.0.12 // indirect github.com/pion/randutil v0.1.0 // indirect github.com/pion/rtcp v1.2.14 // indirect - github.com/pion/rtp v1.8.8 // indirect - github.com/pion/sctp v1.8.20 // indirect + github.com/pion/rtp v1.8.9 // indirect + github.com/pion/sctp v1.8.33 // indirect github.com/pion/sdp/v3 v3.0.9 // indirect github.com/pion/srtp/v2 v2.0.20 // indirect github.com/pion/stun v0.6.1 // indirect - github.com/pion/transport/v2 v2.2.9 // indirect + github.com/pion/transport/v2 v2.2.10 // indirect github.com/pion/turn/v2 v2.1.6 // indirect - github.com/pion/webrtc/v3 v3.2.50 // indirect + github.com/pion/webrtc/v3 v3.3.0 // indirect github.com/piprate/json-gold v0.5.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/pquerna/cachecontrol v0.1.0 // indirect - github.com/prometheus/client_golang v1.19.1 // indirect + github.com/prometheus/client_golang v1.20.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/quic-go v0.45.2 // indirect + github.com/quic-go/quic-go v0.46.0 // indirect github.com/quic-go/webtransport-go v0.8.0 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect @@ -342,7 +342,7 @@ require ( github.com/ulikunitz/xz v0.5.11 // indirect github.com/wasmerio/wasmer-go v1.0.4 // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect - github.com/wlynxg/anet v0.0.3 // indirect + github.com/wlynxg/anet v0.0.4 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect @@ -353,19 +353,19 @@ require ( go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/sdk v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.22.1 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.22.2 // indirect go.uber.org/mock v0.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/mod v0.19.0 // indirect - golang.org/x/net v0.27.0 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.23.0 // indirect + golang.org/x/tools v0.24.0 // indirect gonum.org/v1/gonum v0.15.0 // indirect google.golang.org/api v0.171.0 // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect diff --git a/go.sum b/go.sum index 8ea366d226..1165fcb757 100644 --- a/go.sum +++ b/go.sum @@ -402,8 +402,8 @@ github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4x github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= -github.com/cosmos/gogoproto v1.6.0 h1:Xm0F/96O5Ox4g6xGgjA41rWaaPjYtOdTi59uBcV2qEE= -github.com/cosmos/gogoproto v1.6.0/go.mod h1:Y+g956rcUf2vr4uwtCcK/1Xx9BWVluCtcI9vsh0GHmk= +github.com/cosmos/gogoproto v1.7.0 h1:79USr0oyXAbxg3rspGh/m4SWNyoz/GLaAh0QlCe2fro= +github.com/cosmos/gogoproto v1.7.0/go.mod h1:yWChEv5IUEYURQasfyBW5ffkMHR/90hiHgbNgrtp4j0= github.com/cosmos/iavl v1.1.2 h1:zL9FK7C4L/P4IF1Dm5fIwz0WXCnn7Bp1M2FxH0ayM7Y= github.com/cosmos/iavl v1.1.2/go.mod h1:jLeUvm6bGT1YutCaL2fIar/8vGUE8cPZvh/gXEWDaDM= github.com/cosmos/ibc-go/modules/capability v1.0.0 h1:r/l++byFtn7jHYa09zlAdSeevo8ci1mVZNO9+V0xsLE= @@ -970,6 +970,8 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lens-vm/lens/host-go v0.0.0-20231127204031-8d858ed2926c h1:bG+mr4SqbYRU69L6CSvHDsKbRg5Q9vaN2T5g7qcrPdQ= github.com/lens-vm/lens/host-go v0.0.0-20231127204031-8d858ed2926c/go.mod h1:a4edl+KcOVk1Nj3EjG77htqg2/0Mmy3bSG0kl+FWVqQ= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= @@ -995,8 +997,8 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.36.1 h1:piAHesy0/8ifBEBUS8HF2m7ywR5vnktUFv00dTsVKcs= -github.com/libp2p/go-libp2p v0.36.1/go.mod h1:vHzel3CpRB+vS11fIjZSJAU4ALvieKV9VZHC9VerHj8= +github.com/libp2p/go-libp2p v0.36.2 h1:BbqRkDaGC3/5xfaJakLV/BrpjlAuYqSB0lRvtzL3B/U= +github.com/libp2p/go-libp2p v0.36.2/go.mod h1:XO3joasRE4Eup8yCTTP/+kX+g92mOgRaadk46LmPhHY= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qkCnjyaZUPYU= @@ -1005,8 +1007,8 @@ github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0Trt github.com/libp2p/go-libp2p-kad-dht v0.25.2/go.mod h1:6za56ncRHYXX4Nc2vn8z7CZK0P4QiMcrn77acKLM2Oo= github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= -github.com/libp2p/go-libp2p-pubsub v0.11.0 h1:+JvS8Kty0OiyUiN0i8H5JbaCgjnJTRnTHe4rU88dLFc= -github.com/libp2p/go-libp2p-pubsub v0.11.0/go.mod h1:QEb+hEV9WL9wCiUAnpY29FZR6W3zK8qYlaml8R4q6gQ= +github.com/libp2p/go-libp2p-pubsub v0.12.0 h1:PENNZjSfk8KYxANRlpipdS7+BfLmOl3L2E/6vSNjbdI= +github.com/libp2p/go-libp2p-pubsub v0.12.0/go.mod h1:Oi0zw9aw8/Y5GC99zt+Ef2gYAl+0nZlwdJonDyOz/sE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= github.com/libp2p/go-libp2p-routing-helpers v0.7.3 h1:u1LGzAMVRK9Nqq5aYDVOiq/HaB93U9WWczBzGyAC5ZY= @@ -1062,8 +1064,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= -github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= +github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= +github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -1162,16 +1164,16 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.19.1 h1:QXgq3Z8Crl5EL1WBAC98A5sEBHARrAJNzAmMxzLcRF0= -github.com/onsi/ginkgo/v2 v2.19.1/go.mod h1:O3DtEWQkPa/F7fBMgmZQKKsluAy8pd3rEQdrjkPb9zA= +github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw= +github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.34.0 h1:eSSPsPNp6ZpsG8X1OVmOTxig+CblTc4AxpPBykhe2Os= -github.com/onsi/gomega v1.34.0/go.mod h1:MIKI8c+f+QLWk+hxbePD4i0LMJSExPaZOVfkoex4cAo= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -1222,10 +1224,10 @@ github.com/pion/datachannel v1.5.8/go.mod h1:PgmdpoaNBLX9HNzNClmdki4DYW5JtI7Yibu github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= -github.com/pion/ice/v2 v2.3.32 h1:VwE/uEeqiMm0zUWpdt1DJtnqEkj3UjEbhX92/CurtWI= -github.com/pion/ice/v2 v2.3.32/go.mod h1:8fac0+qftclGy1tYd/nfwfHC729BLaxtVqMdMVCAVPU= -github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= -github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= +github.com/pion/ice/v2 v2.3.34 h1:Ic1ppYCj4tUOcPAp76U6F3fVrlSw8A9JtRXLqw6BbUM= +github.com/pion/ice/v2 v2.3.34/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= +github.com/pion/interceptor v0.1.30 h1:au5rlVHsgmxNi+v/mjOPazbW1SHzfx7/hYOEYQnUcxA= +github.com/pion/interceptor v0.1.30/go.mod h1:RQuKT5HTdkP2Fi0cuOS5G5WNymTjzXaGF75J4k7z2nc= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8= @@ -1236,10 +1238,10 @@ github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9 github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/rtp v1.8.8 h1:EtYFHI0rpUEjT/RMnGfb1vdJhbYmPG77szD72uUnSxs= -github.com/pion/rtp v1.8.8/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/sctp v1.8.20 h1:sOc3lkV/tQaP57ZUEXIMdM2V92IIB2ia5v/ygnBxaEg= -github.com/pion/sctp v1.8.20/go.mod h1:oTxw8i5m+WbDHZJL/xUpe6CPIn1Y0GIKKwTLF4h53H8= +github.com/pion/rtp v1.8.9 h1:E2HX740TZKaqdcPmf4pw6ZZuG8u5RlMMt+l3dxeu6Wk= +github.com/pion/rtp v1.8.9/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/sctp v1.8.33 h1:dSE4wX6uTJBcNm8+YlMg7lw1wqyKHggsP5uKbdj+NZw= +github.com/pion/sctp v1.8.33/go.mod h1:beTnqSzewI53KWoG3nqB282oDMGrhNxBdb+JZnkCwRM= github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk= @@ -1249,17 +1251,16 @@ github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/ github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= -github.com/pion/transport/v2 v2.2.8/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= -github.com/pion/transport/v2 v2.2.9 h1:WEDygVovkJlV2CCunM9KS2kds+kcl7zdIefQA5y/nkE= -github.com/pion/transport/v2 v2.2.9/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= +github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q= +github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= -github.com/pion/transport/v3 v3.0.6 h1:k1mQU06bmmX143qSWgXFqSH1KUJceQvIUuVH/K5ELWw= -github.com/pion/transport/v3 v3.0.6/go.mod h1:HvJr2N/JwNJAfipsRleqwFoR3t/pWyHeZUs89v3+t5s= +github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0= +github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo= github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.2.50 h1:C/rwL2mBfCxHv6tlLzDAO3krJpQXfVx8A8WHnGJ2j34= -github.com/pion/webrtc/v3 v3.2.50/go.mod h1:dytYYoSBy7ZUWhJMbndx9UckgYvzNAfL7xgVnrIKxqo= +github.com/pion/webrtc/v3 v3.3.0 h1:Rf4u6n6U5t5sUxhYPQk/samzU/oDv7jk6BA5hyO2F9I= +github.com/pion/webrtc/v3 v3.3.0/go.mod h1:hVmrDJvwhEertRWObeb1xzulzHGeVUoPlWvxdGzcfU0= github.com/piprate/json-gold v0.5.0 h1:RmGh1PYboCFcchVFuh2pbSWAZy4XJaqTMU4KQYsApbM= github.com/piprate/json-gold v0.5.0/go.mod h1:WZ501QQMbZZ+3pXFPhQKzNwS1+jls0oqov3uQ2WasLs= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -1283,8 +1284,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI= +github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -1313,8 +1314,8 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.45.2 h1:DfqBmqjb4ExSdxRIb/+qXhPC+7k6+DUNZha4oeiC9fY= -github.com/quic-go/quic-go v0.45.2/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= +github.com/quic-go/quic-go v0.46.0 h1:uuwLClEEyk1DNvchH8uCByQVjo3yKL9opKulExNDs7Y= +github.com/quic-go/quic-go v0.46.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI= github.com/quic-go/webtransport-go v0.8.0 h1:HxSrwun11U+LlmwpgM1kEqIqH90IT4N8auv/cD7QFJg= github.com/quic-go/webtransport-go v0.8.0/go.mod h1:N99tjprW432Ut5ONql/aUhSLT0YVSlwHohQsuac9WaM= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= @@ -1505,8 +1506,9 @@ github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= -github.com/wlynxg/anet v0.0.3 h1:PvR53psxFXstc12jelG6f1Lv4MWqE0tI76/hHGjh9rg= github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= +github.com/wlynxg/anet v0.0.4 h1:0de1OFQxnNqAu+x2FAKKCVIrnfGKQbs7FQz++tB0+Uw= +github.com/wlynxg/anet v0.0.4/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= @@ -1559,10 +1561,10 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.22.1 h1:nvvln7mwyT5s1q201YE29V/BFrGor6vMiDNpU/78Mys= -go.uber.org/fx v1.22.1/go.mod h1:HT2M7d7RHo+ebKGh9NRcrsrHHfpZ60nW3QRubMRfv48= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.22.2 h1:iPW+OPxv0G8w75OemJ1RAnTUrF55zOJlXlo1TbJ0Buw= +go.uber.org/fx v1.22.2/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -1606,8 +1608,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1619,8 +1621,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1649,8 +1651,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1718,8 +1720,8 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1765,8 +1767,8 @@ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1876,8 +1878,8 @@ golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1902,8 +1904,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1975,8 +1977,8 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/playground/package-lock.json b/playground/package-lock.json index d878c624b6..357c69e9e3 100644 --- a/playground/package-lock.json +++ b/playground/package-lock.json @@ -8,7 +8,7 @@ "name": "playground", "version": "0.0.0", "dependencies": { - "graphiql": "^3.4.1", + "graphiql": "^3.7.0", "graphql": "^16.9.0", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -18,14 +18,14 @@ "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@types/swagger-ui-react": "^4.18.3", - "@typescript-eslint/eslint-plugin": "^8.0.1", - "@typescript-eslint/parser": "^8.0.1", + "@typescript-eslint/eslint-plugin": "^8.1.0", + "@typescript-eslint/parser": "^8.1.0", "@vitejs/plugin-react-swc": "^3.7.0", "eslint": "^9.9.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.9", "typescript": "^5.5.4", - "vite": "^5.4.0" + "vite": "^5.4.1" } }, "node_modules/@babel/runtime": { @@ -270,11 +270,11 @@ "integrity": "sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==" }, "node_modules/@graphiql/react": { - "version": "0.23.1", - "resolved": "https://registry.npmjs.org/@graphiql/react/-/react-0.23.1.tgz", - "integrity": "sha512-s0xeyDyaRcL5lkwloBob9vM+j5umfr+zxUvydRl3ZpIezmJiq5UXe5jRb2Rt+azHyNJ7yrcnqJgyW0MbyP9Mdw==", + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/@graphiql/react/-/react-0.26.0.tgz", + "integrity": "sha512-WMuv4/SPDw/+b5RuYX2/43SRknCiODQFIY1lYkUcAiU379gcX6QvezDkevrfFgWW8l4wb/pkQ6BR98Wjx9hXBw==", "dependencies": { - "@graphiql/toolkit": "^0.9.2", + "@graphiql/toolkit": "^0.10.0", "@headlessui/react": "^1.7.15", "@radix-ui/react-dialog": "^1.0.4", "@radix-ui/react-dropdown-menu": "^2.0.5", @@ -283,29 +283,30 @@ "@types/codemirror": "^5.60.8", "clsx": "^1.2.1", "codemirror": "^5.65.3", - "codemirror-graphql": "^2.0.13", + "codemirror-graphql": "^2.1.0", "copy-to-clipboard": "^3.2.0", "framer-motion": "^6.5.1", - "graphql-language-service": "^5.2.2", + "get-value": "^3.0.1", + "graphql-language-service": "^5.3.0", "markdown-it": "^14.1.0", "set-value": "^4.1.0" }, "peerDependencies": { - "graphql": "^15.5.0 || ^16.0.0", + "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0-alpha.2", "react": "^16.8.0 || ^17 || ^18", "react-dom": "^16.8.0 || ^17 || ^18" } }, "node_modules/@graphiql/toolkit": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@graphiql/toolkit/-/toolkit-0.9.2.tgz", - "integrity": "sha512-QLPhwx9+E4JfGY+0iwFwa85OBjCJ7GHNypkQoz3pCOwAAlIpFBtXDOuLF1eH9Z08WNZSjRLL7VYW4Ci3hfTqxg==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@graphiql/toolkit/-/toolkit-0.10.0.tgz", + "integrity": "sha512-tVWVYL4AKrkBr4f4Vw4/EV1NjstVYg3TGnatFVe6TdBW4kBeATBz5jyGJju/Oq2JrrrQ2LNXfhCDwfdjSlKyHg==", "dependencies": { "@n1ru4l/push-pull-async-iterable-iterator": "^3.1.0", "meros": "^1.1.4" }, "peerDependencies": { - "graphql": "^15.5.0 || ^16.0.0", + "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0-alpha.2", "graphql-ws": ">= 4.5.0" }, "peerDependenciesMeta": { @@ -362,9 +363,9 @@ "peer": true }, "node_modules/@lezer/highlight": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz", - "integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz", + "integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==", "peer": true, "dependencies": { "@lezer/common": "^1.0.0" @@ -1589,11 +1590,11 @@ } }, "node_modules/@tanstack/react-virtual": { - "version": "3.8.6", - "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.8.6.tgz", - "integrity": "sha512-YcOQAxccjIqiC8cQ8QQiDU6F+JZtfpKNvYsw/ju5Q6S5/m9KDs5SaJvKz1kLj3RKNAOBMIFA9snN2MDmyT9lBQ==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.9.0.tgz", + "integrity": "sha512-5TeTSQBMV1PIFzBP9cduIX5klRaTvbOw+CxRx3LaUhwqiZLEZBZqz8anEIqG4eHNhDAe+BLarRDeNE9cNM1/EA==", "dependencies": { - "@tanstack/virtual-core": "3.8.6" + "@tanstack/virtual-core": "3.9.0" }, "funding": { "type": "github", @@ -1605,9 +1606,9 @@ } }, "node_modules/@tanstack/virtual-core": { - "version": "3.8.6", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.8.6.tgz", - "integrity": "sha512-UJeU4SBrx3hqULNzJ3oC0kgJ5miIAg+FwomxMTlQNxob6ppTInifANHd9ukETvzdzxr6zt3CjQ0rttQpVjbt6Q==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.9.0.tgz", + "integrity": "sha512-Saga7/QRGej/IDCVP5BgJ1oDqlDT2d9rQyoflS3fgMS8ntJ8JGw/LBqK2GorHa06+VrNFc0tGz65XQHJQJetFQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" @@ -1686,15 +1687,16 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.0.1", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.1.0.tgz", + "integrity": "sha512-LlNBaHFCEBPHyD4pZXb35mzjGkuGKXU5eeCA1SxvHfiRES0E82dOounfVpL4DCqYvJEKab0bZIA0gCRpdLKkCw==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.0.1", - "@typescript-eslint/type-utils": "8.0.1", - "@typescript-eslint/utils": "8.0.1", - "@typescript-eslint/visitor-keys": "8.0.1", + "@typescript-eslint/scope-manager": "8.1.0", + "@typescript-eslint/type-utils": "8.1.0", + "@typescript-eslint/utils": "8.1.0", + "@typescript-eslint/visitor-keys": "8.1.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -1717,15 +1719,63 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.1.0.tgz", + "integrity": "sha512-DsuOZQji687sQUjm4N6c9xABJa7fjvfIdjqpSIIVOgaENf2jFXiM9hIBZOL3hb6DHK9Nvd2d7zZnoMLf9e0OtQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.1.0", + "@typescript-eslint/visitor-keys": "8.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.1.0.tgz", + "integrity": "sha512-q2/Bxa0gMOu/2/AKALI0tCKbG2zppccnRIRCW6BaaTlRVaPKft4oVYPp7WOPpcnsgbr0qROAVCVKCvIQ0tbWog==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.1.0.tgz", + "integrity": "sha512-ba0lNI19awqZ5ZNKh6wCModMwoZs457StTebQ0q1NP58zSi2F6MOZRXwfKZy+jB78JNJ/WH8GSh2IQNzXX8Nag==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.1.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/parser": { - "version": "8.0.1", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.1.0.tgz", + "integrity": "sha512-U7iTAtGgJk6DPX9wIWPPOlt1gO57097G06gIcl0N0EEnNw8RGD62c+2/DiP/zL7KrkqnnqF7gtFGR7YgzPllTA==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "8.0.1", - "@typescript-eslint/types": "8.0.1", - "@typescript-eslint/typescript-estree": "8.0.1", - "@typescript-eslint/visitor-keys": "8.0.1", + "@typescript-eslint/scope-manager": "8.1.0", + "@typescript-eslint/types": "8.1.0", + "@typescript-eslint/typescript-estree": "8.1.0", + "@typescript-eslint/visitor-keys": "8.1.0", "debug": "^4.3.4" }, "engines": { @@ -1744,6 +1794,81 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.1.0.tgz", + "integrity": "sha512-DsuOZQji687sQUjm4N6c9xABJa7fjvfIdjqpSIIVOgaENf2jFXiM9hIBZOL3hb6DHK9Nvd2d7zZnoMLf9e0OtQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.1.0", + "@typescript-eslint/visitor-keys": "8.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.1.0.tgz", + "integrity": "sha512-q2/Bxa0gMOu/2/AKALI0tCKbG2zppccnRIRCW6BaaTlRVaPKft4oVYPp7WOPpcnsgbr0qROAVCVKCvIQ0tbWog==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.1.0.tgz", + "integrity": "sha512-NTHhmufocEkMiAord/g++gWKb0Fr34e9AExBRdqgWdVBaKoei2dIyYKD9Q0jBnvfbEA5zaf8plUFMUH6kQ0vGg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.1.0", + "@typescript-eslint/visitor-keys": "8.1.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.1.0.tgz", + "integrity": "sha512-ba0lNI19awqZ5ZNKh6wCModMwoZs457StTebQ0q1NP58zSi2F6MOZRXwfKZy+jB78JNJ/WH8GSh2IQNzXX8Nag==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.1.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "8.0.1", "dev": true, @@ -1761,13 +1886,55 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.0.1", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.1.0.tgz", + "integrity": "sha512-oLYvTxljVvsMnldfl6jIKxTaU7ok7km0KDrwOt1RHYu6nxlhN3TIx8k5Q52L6wR33nOwDgM7VwW1fT1qMNfFIA==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "8.1.0", + "@typescript-eslint/utils": "8.1.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.1.0.tgz", + "integrity": "sha512-q2/Bxa0gMOu/2/AKALI0tCKbG2zppccnRIRCW6BaaTlRVaPKft4oVYPp7WOPpcnsgbr0qROAVCVKCvIQ0tbWog==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.1.0.tgz", + "integrity": "sha512-NTHhmufocEkMiAord/g++gWKb0Fr34e9AExBRdqgWdVBaKoei2dIyYKD9Q0jBnvfbEA5zaf8plUFMUH6kQ0vGg==", "dev": true, - "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.0.1", - "@typescript-eslint/utils": "8.0.1", + "@typescript-eslint/types": "8.1.0", + "@typescript-eslint/visitor-keys": "8.1.0", "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", "ts-api-utils": "^1.3.0" }, "engines": { @@ -1783,6 +1950,23 @@ } } }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.1.0.tgz", + "integrity": "sha512-ba0lNI19awqZ5ZNKh6wCModMwoZs457StTebQ0q1NP58zSi2F6MOZRXwfKZy+jB78JNJ/WH8GSh2IQNzXX8Nag==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.1.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/types": { "version": "8.0.1", "dev": true, @@ -1823,14 +2007,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.0.1", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.1.0.tgz", + "integrity": "sha512-ypRueFNKTIFwqPeJBfeIpxZ895PQhNyH4YID6js0UoBImWYoSjBsahUn9KMiJXh94uOjVBgHD9AmkyPsPnFwJA==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.0.1", - "@typescript-eslint/types": "8.0.1", - "@typescript-eslint/typescript-estree": "8.0.1" + "@typescript-eslint/scope-manager": "8.1.0", + "@typescript-eslint/types": "8.1.0", + "@typescript-eslint/typescript-estree": "8.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1843,6 +2028,81 @@ "eslint": "^8.57.0 || ^9.0.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.1.0.tgz", + "integrity": "sha512-DsuOZQji687sQUjm4N6c9xABJa7fjvfIdjqpSIIVOgaENf2jFXiM9hIBZOL3hb6DHK9Nvd2d7zZnoMLf9e0OtQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.1.0", + "@typescript-eslint/visitor-keys": "8.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.1.0.tgz", + "integrity": "sha512-q2/Bxa0gMOu/2/AKALI0tCKbG2zppccnRIRCW6BaaTlRVaPKft4oVYPp7WOPpcnsgbr0qROAVCVKCvIQ0tbWog==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.1.0.tgz", + "integrity": "sha512-NTHhmufocEkMiAord/g++gWKb0Fr34e9AExBRdqgWdVBaKoei2dIyYKD9Q0jBnvfbEA5zaf8plUFMUH6kQ0vGg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.1.0", + "@typescript-eslint/visitor-keys": "8.1.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.1.0.tgz", + "integrity": "sha512-ba0lNI19awqZ5ZNKh6wCModMwoZs457StTebQ0q1NP58zSi2F6MOZRXwfKZy+jB78JNJ/WH8GSh2IQNzXX8Nag==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.1.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "8.0.1", "dev": true, @@ -2142,17 +2402,17 @@ "integrity": "sha512-1zOsUx3lzAOu/gnMAZkQ9kpIHcPYOc9y1Fbm2UVk5UBPkdq380nhkelG0qUwm1f7wPvTbndu9ZYlug35EwAZRQ==" }, "node_modules/codemirror-graphql": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/codemirror-graphql/-/codemirror-graphql-2.0.13.tgz", - "integrity": "sha512-MBx8BtfqpacLUwcx0smI0JLq7uR6ssKvdF0ENz0yV1w1xqKmFcZ29uHh11LMWdeLL0j14KXGSIDl97fovfdszQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/codemirror-graphql/-/codemirror-graphql-2.1.0.tgz", + "integrity": "sha512-Lm5augEJOd+7L6HXzBDmx/n7ViL8P/Dt0ba21X0JLeaMMEWtcG1SOvIdeI35St9ADOGdu/eMOg7aciX/RnWDFA==", "dependencies": { "@types/codemirror": "^0.0.90", - "graphql-language-service": "5.2.2" + "graphql-language-service": "5.3.0" }, "peerDependencies": { "@codemirror/language": "6.0.0", "codemirror": "^5.65.3", - "graphql": "^15.5.0 || ^16.0.0" + "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0-alpha.2" } }, "node_modules/codemirror-graphql/node_modules/@types/codemirror": { @@ -2894,6 +3154,17 @@ "node": ">=6" } }, + "node_modules/get-value": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-3.0.1.tgz", + "integrity": "sha512-mKZj9JLQrwMBtj5wxi6MH8Z5eSKaERpAwjg43dPtlGI1ZVEgH/qC7T8/6R2OBSUA+zzHBZgICsVJaEIV2tKTDA==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=6.0" + } + }, "node_modules/github-from-package": { "version": "0.0.0", "license": "MIT", @@ -2957,14 +3228,14 @@ "license": "MIT" }, "node_modules/graphiql": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/graphiql/-/graphiql-3.4.1.tgz", - "integrity": "sha512-jSx8O6OWa2wSsEt1OBT6aQRT3NQLzjQuVCjNNijZa81Y3h3DJJ9inDHk/UFNhzL8xUwiDxV1zYXNopCCM6OhNw==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/graphiql/-/graphiql-3.7.0.tgz", + "integrity": "sha512-M38uOeD8y0M85VnrifhpXtcgGshQG2dtQGJ6fPZB9c659sA6y2Yh9aDnE055/n2ricidwSLrKmsiDXrvDuoU1A==", "dependencies": { - "@graphiql/react": "^0.23.1" + "@graphiql/react": "^0.26.0" }, "peerDependencies": { - "graphql": "^15.5.0 || ^16.0.0", + "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0-alpha.2", "react": "^16.8.0 || ^17 || ^18", "react-dom": "^16.8.0 || ^17 || ^18" } @@ -2977,9 +3248,9 @@ } }, "node_modules/graphql-language-service": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/graphql-language-service/-/graphql-language-service-5.2.2.tgz", - "integrity": "sha512-ulIM1xE2eyEk8/QKg7I9QCGQWijNNZVwQ/dpm0B1XwD9AfYzeaGkipcsxW3JPmurt/d/ZMYRxK5Y0d2amrXEtQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/graphql-language-service/-/graphql-language-service-5.3.0.tgz", + "integrity": "sha512-gCQIIy7lM9CB1KPLEb+DNZLczA9zuTLEOJE2hEQZTFYInogdmMDRa6RAkvM4LL0LcgcS+3uPs6KtHlcjCqRbUg==", "dependencies": { "debounce-promise": "^3.1.2", "nullthrows": "^1.0.0", @@ -2989,7 +3260,7 @@ "graphql": "dist/temp-bin.js" }, "peerDependencies": { - "graphql": "^15.5.0 || ^16.0.0" + "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0-alpha.2" } }, "node_modules/has-flag": { @@ -4874,13 +5145,13 @@ "optional": true }, "node_modules/vite": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.0.tgz", - "integrity": "sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.1.tgz", + "integrity": "sha512-1oE6yuNXssjrZdblI9AfBbHCC41nnyoVoEZxQnID6yvQZAFBzxxkqoFLtHUMkYunL8hwOLEjgTuxpkRxvba3kA==", "dev": true, "dependencies": { "esbuild": "^0.21.3", - "postcss": "^8.4.40", + "postcss": "^8.4.41", "rollup": "^4.13.0" }, "bin": { @@ -4943,12 +5214,6 @@ "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", "peer": true }, - "node_modules/w3c-keyname": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", - "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", - "peer": true - }, "node_modules/web-streams-polyfill": { "version": "3.3.3", "license": "MIT", diff --git a/playground/package.json b/playground/package.json index 6be92d6c8c..49442b1fd2 100644 --- a/playground/package.json +++ b/playground/package.json @@ -10,7 +10,7 @@ "preview": "vite preview" }, "dependencies": { - "graphiql": "^3.4.1", + "graphiql": "^3.7.0", "graphql": "^16.9.0", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -20,13 +20,13 @@ "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@types/swagger-ui-react": "^4.18.3", - "@typescript-eslint/eslint-plugin": "^8.0.1", - "@typescript-eslint/parser": "^8.0.1", + "@typescript-eslint/eslint-plugin": "^8.1.0", + "@typescript-eslint/parser": "^8.1.0", "@vitejs/plugin-react-swc": "^3.7.0", "eslint": "^9.9.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.9", "typescript": "^5.5.4", - "vite": "^5.4.0" + "vite": "^5.4.1" } } From 601a92adb61736b1d3b64302855c1180b054fb90 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 Aug 2024 07:26:50 -0400 Subject: [PATCH 35/41] bot: Update dependencies (bulk dependabot PRs) 21-08-2024 (#2939) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✅ This PR was created by combining the following PRs: #2938 bot: Bump @typescript-eslint/eslint-plugin from 8.1.0 to 8.2.0 in /playground ⚠️ The following PRs were resolved manually due to merge conflicts: #2937 bot: Bump @typescript-eslint/parser from 8.1.0 to 8.2.0 in /playground #2936 bot: Bump vite from 5.4.1 to 5.4.2 in /playground #2935 bot: Bump axios from 1.7.2 to 1.7.4 in /playground --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Shahzad Lone --- playground/package-lock.json | 667 +++++++++-------------------------- playground/package.json | 6 +- 2 files changed, 163 insertions(+), 510 deletions(-) diff --git a/playground/package-lock.json b/playground/package-lock.json index 357c69e9e3..c0a43faeca 100644 --- a/playground/package-lock.json +++ b/playground/package-lock.json @@ -18,14 +18,14 @@ "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@types/swagger-ui-react": "^4.18.3", - "@typescript-eslint/eslint-plugin": "^8.1.0", - "@typescript-eslint/parser": "^8.1.0", + "@typescript-eslint/eslint-plugin": "^8.2.0", + "@typescript-eslint/parser": "^8.2.0", "@vitejs/plugin-react-swc": "^3.7.0", "eslint": "^9.9.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.9", "typescript": "^5.5.4", - "vite": "^5.4.1" + "vite": "^5.4.2" } }, "node_modules/@babel/runtime": { @@ -53,37 +53,6 @@ "version": "7.0.2", "license": "MIT" }, - "node_modules/@codemirror/language": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.0.0.tgz", - "integrity": "sha512-rtjk5ifyMzOna1c7PBu7J1VCt0PvA5wy3o8eMVnxMKb7z8KA7JFecvD04dSn14vj/bBaAbqRsGed5OjtofEnLA==", - "peer": true, - "dependencies": { - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", - "@lezer/common": "^1.0.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0", - "style-mod": "^4.0.0" - } - }, - "node_modules/@codemirror/state": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz", - "integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A==", - "peer": true - }, - "node_modules/@codemirror/view": { - "version": "6.32.0", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.32.0.tgz", - "integrity": "sha512-AgVNvED2QTsZp5e3syoHLsrWtwJFYWdx1Vr/m3f4h1ATQz0ax60CfXF3Htdmk69k2MlYZw8gXesnQdHtzyVmAw==", - "peer": true, - "dependencies": { - "@codemirror/state": "^6.4.0", - "style-mod": "^4.1.0", - "w3c-keyname": "^2.2.4" - } - }, "node_modules/@emotion/is-prop-valid": { "version": "0.8.8", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", @@ -138,9 +107,8 @@ }, "node_modules/@eslint/config-array": { "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz", - "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@eslint/object-schema": "^2.1.4", "debug": "^4.3.1", @@ -152,9 +120,8 @@ }, "node_modules/@eslint/config-array/node_modules/brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -162,9 +129,8 @@ }, "node_modules/@eslint/config-array/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -174,9 +140,8 @@ }, "node_modules/@eslint/eslintrc": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", - "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -197,9 +162,8 @@ }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -207,9 +171,8 @@ }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -219,18 +182,16 @@ }, "node_modules/@eslint/js": { "version": "9.9.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.0.tgz", - "integrity": "sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/object-schema": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", - "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -345,9 +306,8 @@ }, "node_modules/@humanwhocodes/retry": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", - "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=18.18" }, @@ -356,30 +316,6 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@lezer/common": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz", - "integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ==", - "peer": true - }, - "node_modules/@lezer/highlight": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz", - "integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==", - "peer": true, - "dependencies": { - "@lezer/common": "^1.0.0" - } - }, - "node_modules/@lezer/lr": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz", - "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==", - "peer": true, - "dependencies": { - "@lezer/common": "^1.0.0" - } - }, "node_modules/@motionone/animation": { "version": "10.18.0", "resolved": "https://registry.npmjs.org/@motionone/animation/-/animation-10.18.0.tgz", @@ -1058,24 +994,26 @@ "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==" }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.18.1", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.0.tgz", + "integrity": "sha512-e2hrvElFIh6kW/UNBQK/kzqMNY5mO+67YtEh9OA65RM5IJXYTWiXjX6fjIiPaqOkBthYF1EqgiZ6OXKcQsM0hg==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.18.1", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.0.tgz", + "integrity": "sha512-1vvmgDdUSebVGXWX2lIcgRebqfQSff0hMEkLJyakQ9JQUbLDkEaMsPTLOmyccyC6IJ/l3FZuJbmrBw/u0A0uCQ==", "cpu": [ "x64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "linux" @@ -1590,11 +1528,11 @@ } }, "node_modules/@tanstack/react-virtual": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.9.0.tgz", - "integrity": "sha512-5TeTSQBMV1PIFzBP9cduIX5klRaTvbOw+CxRx3LaUhwqiZLEZBZqz8anEIqG4eHNhDAe+BLarRDeNE9cNM1/EA==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.10.1.tgz", + "integrity": "sha512-h5kNeE+yQwspjl9E3sJ3UYQu/MuspNOBT5cVdc+NA0uU9B1XSkxbzp86teV3arMDVcQ4ESExqs4JyIirYAMcuA==", "dependencies": { - "@tanstack/virtual-core": "3.9.0" + "@tanstack/virtual-core": "3.10.1" }, "funding": { "type": "github", @@ -1606,9 +1544,9 @@ } }, "node_modules/@tanstack/virtual-core": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.9.0.tgz", - "integrity": "sha512-Saga7/QRGej/IDCVP5BgJ1oDqlDT2d9rQyoflS3fgMS8ntJ8JGw/LBqK2GorHa06+VrNFc0tGz65XQHJQJetFQ==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.10.1.tgz", + "integrity": "sha512-JDi3wU1HIxuxx8BgD7Ix8IXlelCKdTJIh9c0qBs+QXHdix3mjMbkXI3wOq0TuCx1w1RGgzZue34QrM/NPdp/sw==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" @@ -1624,7 +1562,8 @@ }, "node_modules/@types/estree": { "version": "1.0.5", - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, "node_modules/@types/hast": { "version": "2.3.10", @@ -1635,7 +1574,7 @@ }, "node_modules/@types/prop-types": { "version": "15.7.12", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/@types/ramda": { @@ -1647,7 +1586,7 @@ }, "node_modules/@types/react": { "version": "18.3.3", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -1656,7 +1595,7 @@ }, "node_modules/@types/react-dom": { "version": "18.3.0", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "@types/react": "*" @@ -1687,16 +1626,16 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.1.0.tgz", - "integrity": "sha512-LlNBaHFCEBPHyD4pZXb35mzjGkuGKXU5eeCA1SxvHfiRES0E82dOounfVpL4DCqYvJEKab0bZIA0gCRpdLKkCw==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.2.0.tgz", + "integrity": "sha512-02tJIs655em7fvt9gps/+4k4OsKULYGtLBPJfOsmOq1+3cdClYiF0+d6mHu6qDnTcg88wJBkcPLpQhq7FyDz0A==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.1.0", - "@typescript-eslint/type-utils": "8.1.0", - "@typescript-eslint/utils": "8.1.0", - "@typescript-eslint/visitor-keys": "8.1.0", + "@typescript-eslint/scope-manager": "8.2.0", + "@typescript-eslint/type-utils": "8.2.0", + "@typescript-eslint/utils": "8.2.0", + "@typescript-eslint/visitor-keys": "8.2.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -1719,63 +1658,16 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.1.0.tgz", - "integrity": "sha512-DsuOZQji687sQUjm4N6c9xABJa7fjvfIdjqpSIIVOgaENf2jFXiM9hIBZOL3hb6DHK9Nvd2d7zZnoMLf9e0OtQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.1.0", - "@typescript-eslint/visitor-keys": "8.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.1.0.tgz", - "integrity": "sha512-q2/Bxa0gMOu/2/AKALI0tCKbG2zppccnRIRCW6BaaTlRVaPKft4oVYPp7WOPpcnsgbr0qROAVCVKCvIQ0tbWog==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.1.0.tgz", - "integrity": "sha512-ba0lNI19awqZ5ZNKh6wCModMwoZs457StTebQ0q1NP58zSi2F6MOZRXwfKZy+jB78JNJ/WH8GSh2IQNzXX8Nag==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.1.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/parser": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.1.0.tgz", - "integrity": "sha512-U7iTAtGgJk6DPX9wIWPPOlt1gO57097G06gIcl0N0EEnNw8RGD62c+2/DiP/zL7KrkqnnqF7gtFGR7YgzPllTA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.2.0.tgz", + "integrity": "sha512-j3Di+o0lHgPrb7FxL3fdEy6LJ/j2NE8u+AP/5cQ9SKb+JLH6V6UHDqJ+e0hXBkHP1wn1YDFjYCS9LBQsZDlDEg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.1.0", - "@typescript-eslint/types": "8.1.0", - "@typescript-eslint/typescript-estree": "8.1.0", - "@typescript-eslint/visitor-keys": "8.1.0", + "@typescript-eslint/scope-manager": "8.2.0", + "@typescript-eslint/types": "8.2.0", + "@typescript-eslint/typescript-estree": "8.2.0", + "@typescript-eslint/visitor-keys": "8.2.0", "debug": "^4.3.4" }, "engines": { @@ -1794,88 +1686,14 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.1.0.tgz", - "integrity": "sha512-DsuOZQji687sQUjm4N6c9xABJa7fjvfIdjqpSIIVOgaENf2jFXiM9hIBZOL3hb6DHK9Nvd2d7zZnoMLf9e0OtQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.1.0", - "@typescript-eslint/visitor-keys": "8.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.1.0.tgz", - "integrity": "sha512-q2/Bxa0gMOu/2/AKALI0tCKbG2zppccnRIRCW6BaaTlRVaPKft4oVYPp7WOPpcnsgbr0qROAVCVKCvIQ0tbWog==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.1.0.tgz", - "integrity": "sha512-NTHhmufocEkMiAord/g++gWKb0Fr34e9AExBRdqgWdVBaKoei2dIyYKD9Q0jBnvfbEA5zaf8plUFMUH6kQ0vGg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.1.0", - "@typescript-eslint/visitor-keys": "8.1.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.1.0.tgz", - "integrity": "sha512-ba0lNI19awqZ5ZNKh6wCModMwoZs457StTebQ0q1NP58zSi2F6MOZRXwfKZy+jB78JNJ/WH8GSh2IQNzXX8Nag==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.1.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.0.1", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.2.0.tgz", + "integrity": "sha512-OFn80B38yD6WwpoHU2Tz/fTz7CgFqInllBoC3WP+/jLbTb4gGPTy9HBSTsbDWkMdN55XlVU0mMDYAtgvlUspGw==", "dev": true, - "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.0.1", - "@typescript-eslint/visitor-keys": "8.0.1" + "@typescript-eslint/types": "8.2.0", + "@typescript-eslint/visitor-keys": "8.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1886,55 +1704,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.1.0.tgz", - "integrity": "sha512-oLYvTxljVvsMnldfl6jIKxTaU7ok7km0KDrwOt1RHYu6nxlhN3TIx8k5Q52L6wR33nOwDgM7VwW1fT1qMNfFIA==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "8.1.0", - "@typescript-eslint/utils": "8.1.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.1.0.tgz", - "integrity": "sha512-q2/Bxa0gMOu/2/AKALI0tCKbG2zppccnRIRCW6BaaTlRVaPKft4oVYPp7WOPpcnsgbr0qROAVCVKCvIQ0tbWog==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.1.0.tgz", - "integrity": "sha512-NTHhmufocEkMiAord/g++gWKb0Fr34e9AExBRdqgWdVBaKoei2dIyYKD9Q0jBnvfbEA5zaf8plUFMUH6kQ0vGg==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.2.0.tgz", + "integrity": "sha512-g1CfXGFMQdT5S+0PSO0fvGXUaiSkl73U1n9LTK5aRAFnPlJ8dLKkXr4AaLFvPedW8lVDoMgLLE3JN98ZZfsj0w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.1.0", - "@typescript-eslint/visitor-keys": "8.1.0", + "@typescript-eslint/typescript-estree": "8.2.0", + "@typescript-eslint/utils": "8.2.0", "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", "ts-api-utils": "^1.3.0" }, "engines": { @@ -1950,27 +1727,11 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.1.0.tgz", - "integrity": "sha512-ba0lNI19awqZ5ZNKh6wCModMwoZs457StTebQ0q1NP58zSi2F6MOZRXwfKZy+jB78JNJ/WH8GSh2IQNzXX8Nag==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.1.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/types": { - "version": "8.0.1", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.2.0.tgz", + "integrity": "sha512-6a9QSK396YqmiBKPkJtxsgZZZVjYQ6wQ/TlI0C65z7vInaETuC6HAHD98AGLC8DyIPqHytvNuS8bBVvNLKyqvQ==", "dev": true, - "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -1980,12 +1741,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.0.1", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.2.0.tgz", + "integrity": "sha512-kiG4EDUT4dImplOsbh47B1QnNmXSoUqOjWDvCJw/o8LgfD0yr7k2uy54D5Wm0j4t71Ge1NkynGhpWdS0dEIAUA==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "8.0.1", - "@typescript-eslint/visitor-keys": "8.0.1", + "@typescript-eslint/types": "8.2.0", + "@typescript-eslint/visitor-keys": "8.2.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2007,15 +1769,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.1.0.tgz", - "integrity": "sha512-ypRueFNKTIFwqPeJBfeIpxZ895PQhNyH4YID6js0UoBImWYoSjBsahUn9KMiJXh94uOjVBgHD9AmkyPsPnFwJA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.2.0.tgz", + "integrity": "sha512-O46eaYKDlV3TvAVDNcoDzd5N550ckSe8G4phko++OCSC1dYIb9LTc3HDGYdWqWIAT5qDUKphO6sd9RrpIJJPfg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.1.0", - "@typescript-eslint/types": "8.1.0", - "@typescript-eslint/typescript-estree": "8.1.0" + "@typescript-eslint/scope-manager": "8.2.0", + "@typescript-eslint/types": "8.2.0", + "@typescript-eslint/typescript-estree": "8.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2028,87 +1790,13 @@ "eslint": "^8.57.0 || ^9.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.1.0.tgz", - "integrity": "sha512-DsuOZQji687sQUjm4N6c9xABJa7fjvfIdjqpSIIVOgaENf2jFXiM9hIBZOL3hb6DHK9Nvd2d7zZnoMLf9e0OtQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.1.0", - "@typescript-eslint/visitor-keys": "8.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.1.0.tgz", - "integrity": "sha512-q2/Bxa0gMOu/2/AKALI0tCKbG2zppccnRIRCW6BaaTlRVaPKft4oVYPp7WOPpcnsgbr0qROAVCVKCvIQ0tbWog==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.1.0.tgz", - "integrity": "sha512-NTHhmufocEkMiAord/g++gWKb0Fr34e9AExBRdqgWdVBaKoei2dIyYKD9Q0jBnvfbEA5zaf8plUFMUH6kQ0vGg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.1.0", - "@typescript-eslint/visitor-keys": "8.1.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.1.0.tgz", - "integrity": "sha512-ba0lNI19awqZ5ZNKh6wCModMwoZs457StTebQ0q1NP58zSi2F6MOZRXwfKZy+jB78JNJ/WH8GSh2IQNzXX8Nag==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "8.1.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.0.1", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.2.0.tgz", + "integrity": "sha512-sbgsPMW9yLvS7IhCi8IpuK1oBmtbWUNP+hBdwl/I9nzqVsszGnNGti5r9dUtF5RLivHUFFIdRvLiTsPhzSyJ3Q==", "dev": true, - "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.0.1", + "@typescript-eslint/types": "8.2.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -2132,9 +1820,8 @@ }, "node_modules/acorn": { "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -2144,18 +1831,16 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -2210,8 +1895,9 @@ }, "node_modules/array-union": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -2228,8 +1914,9 @@ } }, "node_modules/axios": { - "version": "1.7.2", - "license": "MIT", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", + "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -2277,8 +1964,9 @@ }, "node_modules/braces": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, - "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -2328,9 +2016,8 @@ }, "node_modules/callsites": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -2504,7 +2191,7 @@ }, "node_modules/csstype": { "version": "3.1.3", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/debounce-promise": { @@ -2598,8 +2285,9 @@ }, "node_modules/dir-glob": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -2704,9 +2392,8 @@ }, "node_modules/eslint": { "version": "9.9.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.9.0.tgz", - "integrity": "sha512-JfiKJrbx0506OEerjK2Y1QlldtBxkAlLxT5OEcRF8uaQ86noDe2k31Vw9rnSWv+MXZHj7OOUV/dA0AhdLFcyvA==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.11.0", @@ -2782,9 +2469,8 @@ }, "node_modules/eslint-scope": { "version": "8.0.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", - "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -2818,9 +2504,8 @@ }, "node_modules/eslint/node_modules/eslint-visitor-keys": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -2841,9 +2526,8 @@ }, "node_modules/espree": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", - "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.12.0", "acorn-jsx": "^5.3.2", @@ -2858,9 +2542,8 @@ }, "node_modules/espree/node_modules/eslint-visitor-keys": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -2881,9 +2564,8 @@ }, "node_modules/esrecurse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -2901,9 +2583,8 @@ }, "node_modules/esutils": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -2918,14 +2599,14 @@ }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -2939,8 +2620,9 @@ }, "node_modules/fast-glob/node_modules/glob-parent": { "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -2954,9 +2636,8 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -2984,9 +2665,8 @@ }, "node_modules/file-entry-cache": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, + "license": "MIT", "dependencies": { "flat-cache": "^4.0.0" }, @@ -2996,8 +2676,9 @@ }, "node_modules/fill-range": { "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, - "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -3022,9 +2703,8 @@ }, "node_modules/flat-cache": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, + "license": "MIT", "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" @@ -3035,9 +2715,8 @@ }, "node_modules/flatted": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/follow-redirects": { "version": "1.15.6", @@ -3108,20 +2787,6 @@ "license": "MIT", "optional": true }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "license": "MIT", @@ -3183,9 +2848,8 @@ }, "node_modules/globals": { "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -3195,8 +2859,9 @@ }, "node_modules/globby": { "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, - "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -3381,9 +3046,8 @@ }, "node_modules/import-fresh": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -3476,8 +3140,9 @@ }, "node_modules/is-number": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -3542,15 +3207,13 @@ }, "node_modules/json-buffer": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -3559,9 +3222,8 @@ }, "node_modules/keyv": { "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } @@ -3658,8 +3320,9 @@ }, "node_modules/merge2": { "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8" } @@ -3682,8 +3345,9 @@ }, "node_modules/micromatch": { "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "dev": true, - "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -3732,8 +3396,9 @@ }, "node_modules/minimatch": { "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -3938,9 +3603,8 @@ }, "node_modules/parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -3982,8 +3646,9 @@ }, "node_modules/path-type": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -3996,8 +3661,9 @@ }, "node_modules/picomatch": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "license": "MIT", "engines": { "node": ">=8.6" }, @@ -4126,9 +3792,8 @@ }, "node_modules/punycode": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4500,9 +4165,8 @@ }, "node_modules/resolve-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -4524,9 +4188,10 @@ } }, "node_modules/rollup": { - "version": "4.18.1", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.0.tgz", + "integrity": "sha512-vo+S/lfA2lMS7rZ2Qoubi6I5hwZwzXeUIctILZLbHI+laNtvhhOIon2S1JksA5UEDQ7l3vberd0fxK44lTYjbQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/estree": "1.0.5" }, @@ -4538,22 +4203,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.18.1", - "@rollup/rollup-android-arm64": "4.18.1", - "@rollup/rollup-darwin-arm64": "4.18.1", - "@rollup/rollup-darwin-x64": "4.18.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.18.1", - "@rollup/rollup-linux-arm-musleabihf": "4.18.1", - "@rollup/rollup-linux-arm64-gnu": "4.18.1", - "@rollup/rollup-linux-arm64-musl": "4.18.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.18.1", - "@rollup/rollup-linux-riscv64-gnu": "4.18.1", - "@rollup/rollup-linux-s390x-gnu": "4.18.1", - "@rollup/rollup-linux-x64-gnu": "4.18.1", - "@rollup/rollup-linux-x64-musl": "4.18.1", - "@rollup/rollup-win32-arm64-msvc": "4.18.1", - "@rollup/rollup-win32-ia32-msvc": "4.18.1", - "@rollup/rollup-win32-x64-msvc": "4.18.1", + "@rollup/rollup-android-arm-eabi": "4.21.0", + "@rollup/rollup-android-arm64": "4.21.0", + "@rollup/rollup-darwin-arm64": "4.21.0", + "@rollup/rollup-darwin-x64": "4.21.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.21.0", + "@rollup/rollup-linux-arm-musleabihf": "4.21.0", + "@rollup/rollup-linux-arm64-gnu": "4.21.0", + "@rollup/rollup-linux-arm64-musl": "4.21.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.21.0", + "@rollup/rollup-linux-riscv64-gnu": "4.21.0", + "@rollup/rollup-linux-s390x-gnu": "4.21.0", + "@rollup/rollup-linux-x64-gnu": "4.21.0", + "@rollup/rollup-linux-x64-musl": "4.21.0", + "@rollup/rollup-win32-arm64-msvc": "4.21.0", + "@rollup/rollup-win32-ia32-msvc": "4.21.0", + "@rollup/rollup-win32-x64-msvc": "4.21.0", "fsevents": "~2.3.2" } }, @@ -4759,8 +4424,9 @@ }, "node_modules/slash": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -4807,9 +4473,8 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -4817,12 +4482,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/style-mod": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz", - "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==", - "peer": true - }, "node_modules/style-value-types": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-5.0.0.tgz", @@ -4942,8 +4601,9 @@ }, "node_modules/to-regex-range": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -5076,9 +4736,8 @@ }, "node_modules/uri-js": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -5145,14 +4804,14 @@ "optional": true }, "node_modules/vite": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.1.tgz", - "integrity": "sha512-1oE6yuNXssjrZdblI9AfBbHCC41nnyoVoEZxQnID6yvQZAFBzxxkqoFLtHUMkYunL8hwOLEjgTuxpkRxvba3kA==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.2.tgz", + "integrity": "sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==", "dev": true, "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.41", - "rollup": "^4.13.0" + "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" @@ -5208,12 +4867,6 @@ "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==" }, - "node_modules/w3c-keyname": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", - "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", - "peer": true - }, "node_modules/web-streams-polyfill": { "version": "3.3.3", "license": "MIT", diff --git a/playground/package.json b/playground/package.json index 49442b1fd2..3a98aa92e5 100644 --- a/playground/package.json +++ b/playground/package.json @@ -20,13 +20,13 @@ "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@types/swagger-ui-react": "^4.18.3", - "@typescript-eslint/eslint-plugin": "^8.1.0", - "@typescript-eslint/parser": "^8.1.0", + "@typescript-eslint/eslint-plugin": "^8.2.0", + "@typescript-eslint/parser": "^8.2.0", "@vitejs/plugin-react-swc": "^3.7.0", "eslint": "^9.9.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-react-refresh": "^0.4.9", "typescript": "^5.5.4", - "vite": "^5.4.1" + "vite": "^5.4.2" } } From a4029a92a57a5b2c1e9e8aa0e270a7f7385be914 Mon Sep 17 00:00:00 2001 From: AndrewSisley Date: Wed, 21 Aug 2024 15:24:58 -0400 Subject: [PATCH 36/41] fix: Add ns precision support to time values (#2940) ## Relevant issue(s) Resolves #2927 ## Description Add nanosecond precision support to time values. Was previously only second precision, which is not particularly useful for many applications (such as createdAt timestamps used to allow multiple similar documents to be created within the same second). --- client/document.go | 19 +++- client/value.go | 3 +- .../i2927-time-ns-precision.md | 3 + internal/db/merge_test.go | 3 +- tests/integration/index/create_unique_test.go | 2 +- .../create/field_kinds/date_time_test.go | 104 ++++++++++++++++++ .../update/field_kinds/date_time_test.go | 4 +- .../query/one_to_many/with_cid_doc_id_test.go | 2 +- .../simple/with_group_average_filter_test.go | 10 +- .../query/simple/with_group_test.go | 4 +- tests/integration/results.go | 2 +- 11 files changed, 137 insertions(+), 19 deletions(-) create mode 100644 docs/data_format_changes/i2927-time-ns-precision.md create mode 100644 tests/integration/mutation/create/field_kinds/date_time_test.go diff --git a/client/document.go b/client/document.go index 05cefd02e4..82f0a8bb36 100644 --- a/client/document.go +++ b/client/document.go @@ -27,6 +27,21 @@ import ( ccid "github.com/sourcenetwork/defradb/internal/core/cid" ) +// CborEncodingOptions returns the set of cbor encoding options to be used whenever +// encoding defra documents. +// +// It is the canonical encoding options that ensure consistent serialization of +// indeterministic datastructures, like Go Maps, plus nano-second precision for +// time values (not canon). +func CborEncodingOptions() cbor.EncOptions { + // Important: CanonicalEncOptions ensures consistent serialization of + // indeterministic datastructures, like Go Maps + + opts := cbor.CanonicalEncOptions() + opts.Time = cbor.TimeRFC3339Nano + return opts +} + // This is the main implementation starting point for accessing the internal Document API // which provides API access to the various operations available for Documents, i.e. CRUD. // @@ -659,9 +674,7 @@ func (doc *Document) Bytes() ([]byte, error) { return nil, err } - // Important: CanonicalEncOptions ensures consistent serialization of - // indeterministic datastructures, like Go Maps - em, err := cbor.CanonicalEncOptions().EncMode() + em, err := CborEncodingOptions().EncMode() if err != nil { return nil, err } diff --git a/client/value.go b/client/value.go index bc84205cd9..23fb329132 100644 --- a/client/value.go +++ b/client/value.go @@ -11,7 +11,6 @@ package client import ( - "github.com/fxamacker/cbor/v2" "github.com/sourcenetwork/immutable" ) @@ -60,7 +59,7 @@ func (val *FieldValue) SetType(t CType) { } func (val FieldValue) Bytes() ([]byte, error) { - em, err := cbor.EncOptions{Time: cbor.TimeRFC3339}.EncMode() + em, err := CborEncodingOptions().EncMode() if err != nil { return nil, err } diff --git a/docs/data_format_changes/i2927-time-ns-precision.md b/docs/data_format_changes/i2927-time-ns-precision.md new file mode 100644 index 0000000000..85b9e856eb --- /dev/null +++ b/docs/data_format_changes/i2927-time-ns-precision.md @@ -0,0 +1,3 @@ +# Add ns precision support to time values + +Adds nanosecond precision to DateTime values. As a result the serialization format of DateTime values has changed. diff --git a/internal/db/merge_test.go b/internal/db/merge_test.go index a78fd59983..55cc172634 100644 --- a/internal/db/merge_test.go +++ b/internal/db/merge_test.go @@ -15,7 +15,6 @@ import ( "testing" "time" - "github.com/fxamacker/cbor/v2" "github.com/ipld/go-ipld-prime" "github.com/ipld/go-ipld-prime/linking" cidlink "github.com/ipld/go-ipld-prime/linking/cid" @@ -286,7 +285,7 @@ func (d *dagBuilder) generateCompositeUpdate(lsys *linking.LinkSystem, fields ma } func encodeValue(val any) []byte { - em, err := cbor.EncOptions{Time: cbor.TimeRFC3339}.EncMode() + em, err := client.CborEncodingOptions().EncMode() if err != nil { // safe to panic here as this is a test panic(err) diff --git a/tests/integration/index/create_unique_test.go b/tests/integration/index/create_unique_test.go index 932beb5e40..9d7ffb8471 100644 --- a/tests/integration/index/create_unique_test.go +++ b/tests/integration/index/create_unique_test.go @@ -338,7 +338,7 @@ func TestUniqueQueryWithIndex_UponAddingDocWithSameDateTime_Error(t *testing.T) "birthday": "2000-07-23T03:00:00-00:00" }`, ExpectedError: db.NewErrCanNotIndexNonUniqueFields( - "bae-2000529a-8b27-539b-91e9-c35f431fb78e", + "bae-7e20b26e-5d93-572a-9724-d8f862efbe63", errors.NewKV("birthday", testUtils.MustParseTime("2000-07-23T03:00:00-00:00")), ).Error(), }, diff --git a/tests/integration/mutation/create/field_kinds/date_time_test.go b/tests/integration/mutation/create/field_kinds/date_time_test.go new file mode 100644 index 0000000000..e051aee90f --- /dev/null +++ b/tests/integration/mutation/create/field_kinds/date_time_test.go @@ -0,0 +1,104 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package field_kinds + +import ( + "testing" + "time" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +func TestMutationCreateFieldKinds_WithDateTime(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + time: DateTime + } + `, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "time": "2017-07-23T03:46:56.000Z", + }, + }, + testUtils.Request{ + Request: `query { + User { + time + } + }`, + Results: map[string]any{ + "User": []map[string]any{ + { + "time": time.Date(2017, time.July, 23, 3, 46, 56, 0, time.UTC), + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestMutationCreateFieldKinds_WithDateTimesNanoSecondsAppart(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + time: DateTime + } + `, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "time": "2017-07-23T03:46:56.000Z", + }, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "time": "2017-07-23T03:46:56.000000001Z", + }, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "time": "2017-07-23T03:46:56.000000002Z", + }, + }, + testUtils.Request{ + Request: `query { + User { + time + } + }`, + Results: map[string]any{ + "User": []map[string]any{ + { + "time": time.Date(2017, time.July, 23, 3, 46, 56, 1, time.UTC), + }, + { + "time": time.Date(2017, time.July, 23, 3, 46, 56, 0, time.UTC), + }, + { + "time": time.Date(2017, time.July, 23, 3, 46, 56, 2, time.UTC), + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/mutation/update/field_kinds/date_time_test.go b/tests/integration/mutation/update/field_kinds/date_time_test.go index 1eb8a412bc..b91de56d99 100644 --- a/tests/integration/mutation/update/field_kinds/date_time_test.go +++ b/tests/integration/mutation/update/field_kinds/date_time_test.go @@ -95,11 +95,11 @@ func TestMutationUpdate_WithDateTimeField_MultipleDocs(t *testing.T) { Results: map[string]any{ "update_Users": []map[string]any{ { - "name": "Fred", + "name": "John", "created_at": testUtils.MustParseTime("2031-07-23T03:23:23Z"), }, { - "name": "John", + "name": "Fred", "created_at": testUtils.MustParseTime("2031-07-23T03:23:23Z"), }, }, diff --git a/tests/integration/query/one_to_many/with_cid_doc_id_test.go b/tests/integration/query/one_to_many/with_cid_doc_id_test.go index 91f2d5782b..becc516dbc 100644 --- a/tests/integration/query/one_to_many/with_cid_doc_id_test.go +++ b/tests/integration/query/one_to_many/with_cid_doc_id_test.go @@ -331,7 +331,7 @@ func TestQueryOneToManyWithParentUpdateAndLastCidAndDocID(t *testing.T) { testUtils.Request{ Request: `query { Book ( - cid: "bafyreigyxgn2tss7objjzen5s77w6hijpe6wmmz4z3ercpxdcrq7uwnhl4", + cid: "bafyreihylh2iftquu5vukm2myjrfbkjnpr5vonlp5s5oo22bfrhddkju6e", docID: "bae-5366ba09-54e8-5381-8169-a770aa9282ae" ) { name diff --git a/tests/integration/query/simple/with_group_average_filter_test.go b/tests/integration/query/simple/with_group_average_filter_test.go index d5c145c15f..9fd5c918d9 100644 --- a/tests/integration/query/simple/with_group_average_filter_test.go +++ b/tests/integration/query/simple/with_group_average_filter_test.go @@ -289,6 +289,11 @@ func TestQuerySimpleWithGroupByStringWithRenderedGroupWithFilterAndChildAverageW }`, Results: map[string]any{ "Users": []map[string]any{ + { + "Name": "Alice", + "_avg": float64(0), + "_group": []map[string]any{}, + }, { "Name": "John", "_avg": float64(34), @@ -298,11 +303,6 @@ func TestQuerySimpleWithGroupByStringWithRenderedGroupWithFilterAndChildAverageW }, }, }, - { - "Name": "Alice", - "_avg": float64(0), - "_group": []map[string]any{}, - }, }, }, }, diff --git a/tests/integration/query/simple/with_group_test.go b/tests/integration/query/simple/with_group_test.go index ddb141afab..d12ca3035e 100644 --- a/tests/integration/query/simple/with_group_test.go +++ b/tests/integration/query/simple/with_group_test.go @@ -155,10 +155,10 @@ func TestQuerySimpleWithGroupByDateTime(t *testing.T) { "CreatedAt": testUtils.MustParseTime("2011-07-23T03:46:56-05:00"), }, { - "CreatedAt": testUtils.MustParseTime("2013-07-23T03:46:56-05:00"), + "CreatedAt": testUtils.MustParseTime("2012-07-23T03:46:56-05:00"), }, { - "CreatedAt": testUtils.MustParseTime("2012-07-23T03:46:56-05:00"), + "CreatedAt": testUtils.MustParseTime("2013-07-23T03:46:56-05:00"), }, }, }, diff --git a/tests/integration/results.go b/tests/integration/results.go index 755608394d..e246aa5aa0 100644 --- a/tests/integration/results.go +++ b/tests/integration/results.go @@ -147,7 +147,7 @@ func areResultsEqual(expected any, actual any) bool { case []immutable.Option[string]: return areResultArraysEqual(expectedVal, actual) case time.Time: - return areResultsEqual(expectedVal.Format(time.RFC3339), actual) + return areResultsEqual(expectedVal.Format(time.RFC3339Nano), actual) default: return assert.ObjectsAreEqualValues(expected, actual) } From 53e55c428f8868c992c24adb4febdc9e0add55f9 Mon Sep 17 00:00:00 2001 From: AndrewSisley Date: Thu, 22 Aug 2024 08:56:48 -0400 Subject: [PATCH 37/41] fix: Handle index queries where child found without parent (#2942) ## Relevant issue(s) Resolves #2925 ## Description Handles secondary index queries where child found without parent. Previously the new test would panic further up the callstack (to the prod change), as the parent doc would be nil minus the joined property. --- internal/planner/type_join.go | 7 ++++ .../index/query_with_relation_filter_test.go | 38 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/internal/planner/type_join.go b/internal/planner/type_join.go index ce97f98723..8b781b94b6 100644 --- a/internal/planner/type_join.go +++ b/internal/planner/type_join.go @@ -687,6 +687,13 @@ func (join *invertibleTypeJoin) Next() (bool, error) { } else { join.docsToYield = append(join.docsToYield, secondaryDoc) } + + // If we reach this line and there are no docs to yield, it likely means that a child + // document was found but not a parent - this can happen when inverting the join, for + // example when working with a secondary index. + if len(join.docsToYield) == 0 { + return false, nil + } } return true, nil diff --git a/tests/integration/index/query_with_relation_filter_test.go b/tests/integration/index/query_with_relation_filter_test.go index 10492a99aa..c9798903b3 100644 --- a/tests/integration/index/query_with_relation_filter_test.go +++ b/tests/integration/index/query_with_relation_filter_test.go @@ -1017,3 +1017,41 @@ func TestQueryWithIndexOnManyToOne_MultipleViaOneToMany(t *testing.T) { testUtils.ExecuteTestCase(t, test) } + +func TestQueryWithIndex_UniqueIndexOnChildWithEmptyParentCollection(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type Action { + key: String @index(unique: true) + playerActions: [PlayerAction] + } + + type PlayerAction { + deleted: Boolean + action: Action + } + `, + }, + testUtils.CreateDoc{ + CollectionID: 0, + DocMap: map[string]any{ + "key": "ACTION_KEY", + }, + }, + testUtils.Request{ + Request: `query { + PlayerAction(filter: {action: {key: {_eq: "ACTION_KEY"}}}) { + deleted + } + }`, + Results: map[string]any{ + "PlayerAction": []map[string]any{}, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} From 64a2adae2dea52a2fab53d6407521d8ccf1ba36f Mon Sep 17 00:00:00 2001 From: Fred Carle Date: Thu, 22 Aug 2024 11:15:07 -0400 Subject: [PATCH 38/41] fix: Filter with date and document with nil date value (#2946) ## Relevant issue(s) Resolves #2945 ## Description This PR ensures that no error occurs when filtering for a date while having documents with `nil` date value. --- internal/connor/ge.go | 2 + internal/connor/gt.go | 2 + internal/connor/le.go | 2 + internal/connor/lt.go | 2 + .../with_filter/with_eq_datetime_test.go | 50 ++++++++++++++++- .../with_filter/with_ge_datetime_test.go | 53 +++++++++++++++++++ .../with_filter/with_gt_datetime_test.go | 48 +++++++++++++++++ .../with_filter/with_le_datetime_test.go | 53 +++++++++++++++++++ .../with_filter/with_lt_datetime_test.go | 49 +++++++++++++++++ .../with_filter/with_ne_datetime_test.go | 53 +++++++++++++++++++ 10 files changed, 313 insertions(+), 1 deletion(-) diff --git a/internal/connor/ge.go b/internal/connor/ge.go index 851c59c53f..055a27b30a 100644 --- a/internal/connor/ge.go +++ b/internal/connor/ge.go @@ -26,6 +26,8 @@ func ge(condition, data any) (bool, error) { return false, err } return dt.After(c) || dt.Equal(c), nil + case nil: + return false, nil default: return false, client.NewErrUnhandledType("data", d) } diff --git a/internal/connor/gt.go b/internal/connor/gt.go index d5689ebd52..c6852a3db3 100644 --- a/internal/connor/gt.go +++ b/internal/connor/gt.go @@ -25,6 +25,8 @@ func gt(condition, data any) (bool, error) { return false, err } return dt.After(c), nil + case nil: + return false, nil default: return false, client.NewErrUnhandledType("data", d) } diff --git a/internal/connor/le.go b/internal/connor/le.go index 0c89c8ffbf..89eca1f3f9 100644 --- a/internal/connor/le.go +++ b/internal/connor/le.go @@ -26,6 +26,8 @@ func le(condition, data any) (bool, error) { return false, err } return dt.Before(c) || dt.Equal(c), nil + case nil: + return false, nil default: return false, client.NewErrUnhandledType("data", d) } diff --git a/internal/connor/lt.go b/internal/connor/lt.go index a7e5e7bb03..7255fc8810 100644 --- a/internal/connor/lt.go +++ b/internal/connor/lt.go @@ -26,6 +26,8 @@ func lt(condition, data any) (bool, error) { return false, err } return dt.Before(c), nil + case nil: + return false, nil default: return false, client.NewErrUnhandledType("data", d) } diff --git a/tests/integration/query/simple/with_filter/with_eq_datetime_test.go b/tests/integration/query/simple/with_filter/with_eq_datetime_test.go index dbf6152244..bdc2b4845f 100644 --- a/tests/integration/query/simple/with_filter/with_eq_datetime_test.go +++ b/tests/integration/query/simple/with_filter/with_eq_datetime_test.go @@ -60,7 +60,7 @@ func TestQuerySimpleWithDateTimeEqualsFilterBlock(t *testing.T) { func TestQuerySimpleWithDateTimeEqualsNilFilterBlock(t *testing.T) { test := testUtils.TestCase{ - Description: "Simple query with basic filter(age)", + Description: "Simple query with basic filter(CreatedAt)", Actions: []any{ testUtils.CreateDoc{ Doc: `{ @@ -105,3 +105,51 @@ func TestQuerySimpleWithDateTimeEqualsNilFilterBlock(t *testing.T) { executeTestCase(t, test) } + +func TestQuerySimple_WithNilDateTimeEqualsAndNonNilFilterBlock_ShouldSucceed(t *testing.T) { + test := testUtils.TestCase{ + Description: "Simple query with basic filter with nil value and non-nil filter", + Actions: []any{ + testUtils.CreateDoc{ + DocMap: map[string]any{ + "Name": "John", + "Age": int64(21), + "CreatedAt": "2017-07-23T03:46:56-05:00", + }, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "Name": "Bob", + "Age": int64(32), + "CreatedAt": "2016-07-23T03:46:56-05:00", + }, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "Name": "Fred", + "Age": 44, + }, + }, + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_eq: "2016-07-23T03:46:56-05:00"}}) { + Name + Age + CreatedAt + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + "Age": int64(32), + "CreatedAt": testUtils.MustParseTime("2016-07-23T03:46:56-05:00"), + }, + }, + }, + }, + }, + } + + executeTestCase(t, test) +} diff --git a/tests/integration/query/simple/with_filter/with_ge_datetime_test.go b/tests/integration/query/simple/with_filter/with_ge_datetime_test.go index 5c2aacaa00..4ad799d0b0 100644 --- a/tests/integration/query/simple/with_filter/with_ge_datetime_test.go +++ b/tests/integration/query/simple/with_filter/with_ge_datetime_test.go @@ -163,3 +163,56 @@ func TestQuerySimpleWithDateTimeGEFilterBlockWithNilValue(t *testing.T) { executeTestCase(t, test) } + +func TestQuerySimple_WithNilDateTimeGEAndNonNilFilterBlock_ShouldSucceed(t *testing.T) { + test := testUtils.TestCase{ + Description: "Simple query with basic filter with nil value and non-nil filter", + Actions: []any{ + testUtils.CreateDoc{ + DocMap: map[string]any{ + "Name": "John", + "Age": int64(21), + "CreatedAt": "2017-07-23T03:46:56-05:00", + }, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "Name": "Bob", + "Age": int64(32), + "CreatedAt": "2016-07-23T03:46:56-05:00", + }, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "Name": "Fred", + "Age": 44, + }, + }, + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_ge: "2016-07-23T03:46:56-05:00"}}) { + Name + Age + CreatedAt + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + "Age": int64(32), + "CreatedAt": testUtils.MustParseTime("2016-07-23T03:46:56-05:00"), + }, + { + "Name": "John", + "Age": int64(21), + "CreatedAt": testUtils.MustParseTime("2017-07-23T03:46:56-05:00"), + }, + }, + }, + }, + }, + } + + executeTestCase(t, test) +} diff --git a/tests/integration/query/simple/with_filter/with_gt_datetime_test.go b/tests/integration/query/simple/with_filter/with_gt_datetime_test.go index 67ee8a05a0..956e445573 100644 --- a/tests/integration/query/simple/with_filter/with_gt_datetime_test.go +++ b/tests/integration/query/simple/with_filter/with_gt_datetime_test.go @@ -160,3 +160,51 @@ func TestQuerySimpleWithDateTimeGTFilterBlockWithNilValue(t *testing.T) { executeTestCase(t, test) } + +func TestQuerySimple_WithNilDateTimeGTAndNonNilFilterBlock_ShouldSucceed(t *testing.T) { + test := testUtils.TestCase{ + Description: "Simple query with basic filter with nil value and non-nil filter", + Actions: []any{ + testUtils.CreateDoc{ + DocMap: map[string]any{ + "Name": "John", + "Age": int64(21), + "CreatedAt": "2017-07-23T03:46:56-05:00", + }, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "Name": "Bob", + "Age": int64(32), + "CreatedAt": "2016-07-23T03:46:56-05:00", + }, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "Name": "Fred", + "Age": 44, + }, + }, + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_gt: "2016-07-23T03:46:56-05:00"}}) { + Name + Age + CreatedAt + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + "CreatedAt": testUtils.MustParseTime("2017-07-23T03:46:56-05:00"), + }, + }, + }, + }, + }, + } + + executeTestCase(t, test) +} diff --git a/tests/integration/query/simple/with_filter/with_le_datetime_test.go b/tests/integration/query/simple/with_filter/with_le_datetime_test.go index 6ffbbbac69..1cfe06ac89 100644 --- a/tests/integration/query/simple/with_filter/with_le_datetime_test.go +++ b/tests/integration/query/simple/with_filter/with_le_datetime_test.go @@ -128,3 +128,56 @@ func TestQuerySimpleWithDateTimeLEFilterBlockWithNullValue(t *testing.T) { executeTestCase(t, test) } + +func TestQuerySimple_WithNilDateTimeLEAndNonNilFilterBlock_ShouldSucceed(t *testing.T) { + test := testUtils.TestCase{ + Description: "Simple query with basic filter with nil value and non-nil filter", + Actions: []any{ + testUtils.CreateDoc{ + DocMap: map[string]any{ + "Name": "John", + "Age": int64(21), + "CreatedAt": "2017-07-23T03:46:56-05:00", + }, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "Name": "Bob", + "Age": int64(32), + "CreatedAt": "2016-07-23T03:46:56-05:00", + }, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "Name": "Fred", + "Age": 44, + }, + }, + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_le: "2017-07-23T03:46:56-05:00"}}) { + Name + Age + CreatedAt + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "Bob", + "Age": int64(32), + "CreatedAt": testUtils.MustParseTime("2016-07-23T03:46:56-05:00"), + }, + { + "Name": "John", + "Age": int64(21), + "CreatedAt": testUtils.MustParseTime("2017-07-23T03:46:56-05:00"), + }, + }, + }, + }, + }, + } + + executeTestCase(t, test) +} diff --git a/tests/integration/query/simple/with_filter/with_lt_datetime_test.go b/tests/integration/query/simple/with_filter/with_lt_datetime_test.go index a2230b3b20..8fbcf440a2 100644 --- a/tests/integration/query/simple/with_filter/with_lt_datetime_test.go +++ b/tests/integration/query/simple/with_filter/with_lt_datetime_test.go @@ -86,3 +86,52 @@ func TestQuerySimpleWithDateTimeLTFilterBlockWithNullValue(t *testing.T) { executeTestCase(t, test) } + +func TestQuerySimple_WithNilDateTimeLTAndNonNilFilterBlock_ShouldSucceed(t *testing.T) { + test := testUtils.TestCase{ + Description: "Simple query with basic filter with nil value and non-nil filter", + Actions: []any{ + testUtils.CreateDoc{ + DocMap: map[string]any{ + "Name": "John", + "Age": int64(21), + "CreatedAt": "2017-07-23T03:46:56-05:00", + }, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "Name": "Bob", + "Age": int64(32), + "CreatedAt": "2016-07-23T03:46:56-05:00", + }, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "Name": "Fred", + "Age": 44, + }, + }, + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_lt: "2017-07-23T03:46:56-05:00"}}) { + Name + Age + CreatedAt + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + + { + "Name": "Bob", + "Age": int64(32), + "CreatedAt": testUtils.MustParseTime("2016-07-23T03:46:56-05:00"), + }, + }, + }, + }, + }, + } + + executeTestCase(t, test) +} diff --git a/tests/integration/query/simple/with_filter/with_ne_datetime_test.go b/tests/integration/query/simple/with_filter/with_ne_datetime_test.go index 5320a9c7eb..ecc40d3969 100644 --- a/tests/integration/query/simple/with_filter/with_ne_datetime_test.go +++ b/tests/integration/query/simple/with_filter/with_ne_datetime_test.go @@ -100,3 +100,56 @@ func TestQuerySimpleWithDateTimeNotEqualsNilFilterBlock(t *testing.T) { executeTestCase(t, test) } + +func TestQuerySimple_WithNilDateTimeNotEqualAndNonNilFilterBlock_ShouldSucceed(t *testing.T) { + test := testUtils.TestCase{ + Description: "Simple query with basic filter with nil value and non-nil filter", + Actions: []any{ + testUtils.CreateDoc{ + DocMap: map[string]any{ + "Name": "John", + "Age": int64(21), + "CreatedAt": "2017-07-23T03:46:56-05:00", + }, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "Name": "Bob", + "Age": int64(32), + "CreatedAt": "2016-07-23T03:46:56-05:00", + }, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "Name": "Fred", + "Age": 44, + }, + }, + testUtils.Request{ + Request: `query { + Users(filter: {CreatedAt: {_ne: "2016-07-23T03:46:56-05:00"}}) { + Name + Age + CreatedAt + } + }`, + Results: map[string]any{ + "Users": []map[string]any{ + { + "Name": "John", + "Age": int64(21), + "CreatedAt": testUtils.MustParseTime("2017-07-23T03:46:56-05:00"), + }, + { + "Name": "Fred", + "Age": int64(44), + "CreatedAt": nil, + }, + }, + }, + }, + }, + } + + executeTestCase(t, test) +} From 002851ea9bcb694bbc77343695cd7e77446342b4 Mon Sep 17 00:00:00 2001 From: Islam Aliev Date: Thu, 22 Aug 2024 20:35:35 +0200 Subject: [PATCH 39/41] fix: Panic with different composite-indexed child objects (#2947) ## Relevant issue(s) Resolves #2924 ## Description Make multiScanNode keep track of all calls. The issue was that multiScanNode that keeps track of how many calls to Next() should be made, would call Init() and Start() every time without tracking, which would result in child nodes being initialized and started multiple times, which in turn created index iterators without closing them. --- internal/db/fetcher/indexer_iterators.go | 150 ++++++++---------- internal/planner/multi.go | 12 +- internal/planner/scan.go | 69 ++++++-- ...y_with_composite_inxed_on_relation_test.go | 116 ++++++++++++++ 4 files changed, 238 insertions(+), 109 deletions(-) create mode 100644 tests/integration/index/query_with_composite_inxed_on_relation_test.go diff --git a/internal/db/fetcher/indexer_iterators.go b/internal/db/fetcher/indexer_iterators.go index 2589ea92e4..5d9da70c9f 100644 --- a/internal/db/fetcher/indexer_iterators.go +++ b/internal/db/fetcher/indexer_iterators.go @@ -64,13 +64,46 @@ type indexIterResult struct { value []byte } -type queryResultIterator struct { - resultIter query.Results +// indexPrefixIterator is an iterator over index keys with a specific prefix. +type indexPrefixIterator struct { indexDesc client.IndexDescription indexedFields []client.FieldDefinition + indexKey core.IndexDataStoreKey + matchers []valueMatcher + execInfo *ExecInfo + resultIter query.Results + ctx context.Context + store datastore.DSReaderWriter +} + +var _ indexIterator = (*indexPrefixIterator)(nil) + +func (iter *indexPrefixIterator) Init(ctx context.Context, store datastore.DSReaderWriter) error { + iter.ctx = ctx + iter.store = store + if iter.resultIter != nil { + if err := iter.resultIter.Close(); err != nil { + return err + } + } + iter.resultIter = nil + return nil +} + +func (iter *indexPrefixIterator) checkResultIterator() error { + if iter.resultIter == nil { + resultIter, err := iter.store.Query(iter.ctx, query.Query{ + Prefix: iter.indexKey.ToString(), + }) + if err != nil { + return err + } + iter.resultIter = resultIter + } + return nil } -func (iter *queryResultIterator) Next() (indexIterResult, error) { +func (iter *indexPrefixIterator) nextResult() (indexIterResult, error) { res, hasVal := iter.resultIter.NextSync() if res.Error != nil { return indexIterResult{}, res.Error @@ -86,46 +119,31 @@ func (iter *queryResultIterator) Next() (indexIterResult, error) { return indexIterResult{key: key, value: res.Value, foundKey: true}, nil } -func (iter *queryResultIterator) Close() error { - return iter.resultIter.Close() -} - -type eqPrefixIndexIterator struct { - queryResultIterator - indexKey core.IndexDataStoreKey - execInfo *ExecInfo - matchers []valueMatcher -} - -func (iter *eqPrefixIndexIterator) Init(ctx context.Context, store datastore.DSReaderWriter) error { - resultIter, err := store.Query(ctx, query.Query{ - Prefix: iter.indexKey.ToString(), - }) - if err != nil { - return err +func (iter *indexPrefixIterator) Next() (indexIterResult, error) { + if err := iter.checkResultIterator(); err != nil { + return indexIterResult{}, err } - iter.resultIter = resultIter - return nil -} -func (iter *eqPrefixIndexIterator) Next() (indexIterResult, error) { for { - res, err := iter.queryResultIterator.Next() + res, err := iter.nextResult() if err != nil || !res.foundKey { return res, err } iter.execInfo.IndexesFetched++ - doesMatch, err := executeValueMatchers(iter.matchers, res.key.Fields) + didMatch, err := executeValueMatchers(iter.matchers, res.key.Fields) if err != nil { return indexIterResult{}, err } - if !doesMatch { - continue + if didMatch { + return res, nil } - return res, err } } +func (iter *indexPrefixIterator) Close() error { + return iter.resultIter.Close() +} + type eqSingleIndexIterator struct { indexKey core.IndexDataStoreKey execInfo *ExecInfo @@ -182,7 +200,7 @@ func (iter *inIndexIterator) nextIterator() (bool, error) { } switch fieldIter := iter.indexIterator.(type) { - case *eqPrefixIndexIterator: + case *indexPrefixIterator: fieldIter.indexKey.Fields[0].Value = iter.inValues[iter.nextValIndex] case *eqSingleIndexIterator: fieldIter.indexKey.Fields[0].Value = iter.inValues[iter.nextValIndex] @@ -238,41 +256,6 @@ func executeValueMatchers(matchers []valueMatcher, fields []core.IndexedField) ( return true, nil } -type scanningIndexIterator struct { - queryResultIterator - indexKey core.IndexDataStoreKey - matchers []valueMatcher - execInfo *ExecInfo -} - -func (iter *scanningIndexIterator) Init(ctx context.Context, store datastore.DSReaderWriter) error { - resultIter, err := store.Query(ctx, query.Query{ - Prefix: iter.indexKey.ToString(), - }) - if err != nil { - return err - } - iter.resultIter = resultIter - - return nil -} - -func (iter *scanningIndexIterator) Next() (indexIterResult, error) { - for { - res, err := iter.queryResultIterator.Next() - if err != nil || !res.foundKey { - return indexIterResult{}, err - } - iter.execInfo.IndexesFetched++ - - didMatch, err := executeValueMatchers(iter.matchers, res.key.Fields) - - if didMatch { - return res, err - } - } -} - // checks if the value satisfies the condition type valueMatcher interface { Match(client.NormalValue) (bool, error) @@ -468,7 +451,7 @@ func (m *anyMatcher) Match(client.NormalValue) (bool, error) { return true, nil func (f *IndexFetcher) newPrefixIndexIterator( fieldConditions []fieldFilterCond, matchers []valueMatcher, -) (*eqPrefixIndexIterator, error) { +) (*indexPrefixIterator, error) { keyFieldValues := make([]client.NormalValue, 0, len(fieldConditions)) for i := range fieldConditions { if fieldConditions[i].op != opEq { @@ -488,16 +471,21 @@ func (f *IndexFetcher) newPrefixIndexIterator( key := f.newIndexDataStoreKeyWithValues(keyFieldValues) - return &eqPrefixIndexIterator{ - queryResultIterator: f.newQueryResultIterator(), - indexKey: key, - execInfo: &f.execInfo, - matchers: matchers, - }, nil + return f.newQueryResultIterator(key, matchers, &f.execInfo), nil } -func (f *IndexFetcher) newQueryResultIterator() queryResultIterator { - return queryResultIterator{indexDesc: f.indexDesc, indexedFields: f.indexedFields} +func (f *IndexFetcher) newQueryResultIterator( + indexKey core.IndexDataStoreKey, + matchers []valueMatcher, + execInfo *ExecInfo, +) *indexPrefixIterator { + return &indexPrefixIterator{ + indexDesc: f.indexDesc, + indexedFields: f.indexedFields, + indexKey: indexKey, + matchers: matchers, + execInfo: execInfo, + } } // newInIndexIterator creates a new inIndexIterator for fetching indexed data. @@ -537,12 +525,7 @@ func (f *IndexFetcher) newInIndexIterator( indexKey := f.newIndexDataStoreKey() indexKey.Fields = []core.IndexedField{{Descending: f.indexDesc.Fields[0].Descending}} - iter = &eqPrefixIndexIterator{ - queryResultIterator: f.newQueryResultIterator(), - indexKey: indexKey, - execInfo: &f.execInfo, - matchers: matchers, - } + iter = f.newQueryResultIterator(indexKey, matchers, &f.execInfo) } return &inIndexIterator{ indexIterator: iter, @@ -600,12 +583,7 @@ func (f *IndexFetcher) createIndexIterator() (indexIterator, error) { case opIn: return f.newInIndexIterator(fieldConditions, matchers) case opGt, opGe, opLt, opLe, opNe, opNin, opLike, opNlike, opILike, opNILike: - return &scanningIndexIterator{ - queryResultIterator: f.newQueryResultIterator(), - indexKey: f.newIndexDataStoreKey(), - matchers: matchers, - execInfo: &f.execInfo, - }, nil + return f.newQueryResultIterator(f.newIndexDataStoreKey(), matchers, &f.execInfo), nil } return nil, NewErrInvalidFilterOperator(fieldConditions[0].op) diff --git a/internal/planner/multi.go b/internal/planner/multi.go index de220c43e5..ac564c4ed1 100644 --- a/internal/planner/multi.go +++ b/internal/planner/multi.go @@ -1,4 +1,4 @@ -// Copyright 2022 Democratized Data Foundation +// Copyright 2024 Democratized Data Foundation // // Use of this software is governed by the Business Source License // included in the file licenses/BSL.txt. @@ -214,22 +214,22 @@ func (s *selectNode) addSubPlan(fieldIndex int, newPlan planNode) error { if err := s.planner.walkAndReplacePlan(s.source, origScan, multiscan); err != nil { return err } - // create multinode - multinode := ¶llelNode{ + // create parallelNode + parallelNode := ¶llelNode{ p: s.planner, multiscan: multiscan, docMapper: docMapper{s.source.DocumentMap()}, } - multinode.addChild(-1, s.source) + parallelNode.addChild(-1, s.source) multiscan.addReader() // replace our new node internal scanNode with our new multiscanner if err := s.planner.walkAndReplacePlan(newPlan, origScan, multiscan); err != nil { return err } // add our newly updated plan to the multinode - multinode.addChild(fieldIndex, newPlan) + parallelNode.addChild(fieldIndex, newPlan) multiscan.addReader() - s.source = multinode + s.source = parallelNode // we already have an existing parallelNode as our source case *parallelNode: diff --git a/internal/planner/scan.go b/internal/planner/scan.go index 5c0e3d4faf..151705a698 100644 --- a/internal/planner/scan.go +++ b/internal/planner/scan.go @@ -1,4 +1,4 @@ -// Copyright 2022 Democratized Data Foundation +// Copyright 2024 Democratized Data Foundation // // Use of this software is governed by the Business Source License // included in the file licenses/BSL.txt. @@ -322,38 +322,70 @@ func (p *Planner) Scan( // If we have two readers on our multiScanNode, then // we call Next() on the underlying scanNode only // once every 2 Next() calls on the multiScan +// +// NOTE: calling Init() on multiScanNode is subject to counting as well and as such +// doesn't not provide idempotency guarantees. Counting is purely for performance +// reasons and removing it should be safe. type multiScanNode struct { scanNode *scanNode numReaders int - numCalls int + nextCount int + initCount int + startCount int + closeCount int - lastBool bool - lastErr error + nextResult bool + err error } +// Init initializes the multiScanNode. +// NOTE: this function is subject to counting based on the number of readers and as such +// doesn't not provide idempotency guarantees. Counting is purely for performance +// reasons and removing it should be safe. func (n *multiScanNode) Init() error { - return n.scanNode.Init() + n.countAndCall(&n.initCount, func() error { + return n.scanNode.Init() + }) + return n.err } func (n *multiScanNode) Start() error { - return n.scanNode.Start() + n.countAndCall(&n.startCount, func() error { + return n.scanNode.Start() + }) + return n.err } -// Next only calls Next() on the underlying -// scanNode every numReaders. -func (n *multiScanNode) Next() (bool, error) { - if n.numCalls == 0 { - n.lastBool, n.lastErr = n.scanNode.Next() +// countAndCall keeps track of number of requests to call a given function by checking a +// function's count. +// The function is only called when the count is 0. +// If the count is equal to the number of readers, the count is reset. +// If the function returns an error, the error is stored in the multiScanNode. +func (n *multiScanNode) countAndCall(count *int, f func() error) { + if *count == 0 { + err := f() + if err != nil { + n.err = err + } } - n.numCalls++ + *count++ // if the number of calls equals the numbers of readers - // reset the counter, so our next call actually executes the Next() - if n.numCalls == n.numReaders { - n.numCalls = 0 + // reset the counter, so our next call actually executes the function + if *count == n.numReaders { + *count = 0 } +} + +// Next only calls Next() on the underlying +// scanNode every numReaders. +func (n *multiScanNode) Next() (bool, error) { + n.countAndCall(&n.nextCount, func() (err error) { + n.nextResult, err = n.scanNode.Next() + return + }) - return n.lastBool, n.lastErr + return n.nextResult, n.err } func (n *multiScanNode) Value() core.Doc { @@ -373,7 +405,10 @@ func (n *multiScanNode) Kind() string { } func (n *multiScanNode) Close() error { - return n.scanNode.Close() + n.countAndCall(&n.closeCount, func() error { + return n.scanNode.Close() + }) + return n.err } func (n *multiScanNode) DocumentMap() *core.DocumentMapping { diff --git a/tests/integration/index/query_with_composite_inxed_on_relation_test.go b/tests/integration/index/query_with_composite_inxed_on_relation_test.go new file mode 100644 index 0000000000..40d736ba3c --- /dev/null +++ b/tests/integration/index/query_with_composite_inxed_on_relation_test.go @@ -0,0 +1,116 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package index + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" +) + +// This test was added during https://github.com/sourcenetwork/defradb/issues/2924 +// The issue was that [multiScanNode] that keeps track of how many calls to [Next()] should +// be made, would call [Init()] and [Start()] every time without tracking, which would result +// in child nodes being initialized and started multiple times, which in turn created +// index iterators without closing them. +func TestQueryWithCompositeIndexOnManyToOne_WithMultipleIndexedChildNodes_ShouldSucceed(t *testing.T) { + test := testUtils.TestCase{ + Actions: []any{ + testUtils.SchemaUpdate{ + Schema: ` + type User { + name: String + devices: [Device] + } + + type Device @index(fields: ["owner_id", "manufacturer_id"]) { + model: String + owner: User + manufacturer: Manufacturer + } + + type Manufacturer { + name: String + devices: [Device] + } + `, + }, + testUtils.CreateDoc{ + DocMap: map[string]any{ + "name": "John", + }, + }, + testUtils.CreateDoc{ + CollectionID: 2, + DocMap: map[string]any{ + "name": "Apple", + }, + }, + testUtils.CreateDoc{ + CollectionID: 2, + DocMap: map[string]any{ + "name": "Sony", + }, + }, + testUtils.CreateDoc{ + CollectionID: 1, + DocMap: map[string]any{ + "model": "MacBook Pro", + "owner": testUtils.NewDocIndex(0, 0), + "manufacturer": testUtils.NewDocIndex(2, 0), + }, + }, + testUtils.CreateDoc{ + CollectionID: 1, + DocMap: map[string]any{ + "model": "PlayStation 5", + "owner": testUtils.NewDocIndex(0, 0), + "manufacturer": testUtils.NewDocIndex(2, 1), + }, + }, + testUtils.Request{ + Request: `query { + User { + devices { + model + owner { + name + } + manufacturer { + name + } + } + } + }`, + Results: map[string]any{ + "User": []map[string]any{ + { + "devices": []map[string]any{ + { + "model": "MacBook Pro", + "owner": map[string]any{"name": "John"}, + "manufacturer": map[string]any{"name": "Apple"}, + }, + { + "model": "PlayStation 5", + "owner": map[string]any{"name": "John"}, + "manufacturer": map[string]any{"name": "Sony"}, + }, + }, + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} From 470343681f4906fa1b8605d108d3cf34e8f18e56 Mon Sep 17 00:00:00 2001 From: Fred Carle Date: Fri, 23 Aug 2024 14:08:59 -0400 Subject: [PATCH 40/41] ci(i): Docker build separate from goreleaser (#2944) ## Relevant issue(s) Resolves #2941 ## Description This PR brings our docker build and push outside the goreleaser process and instead defines it as a separate ci job. Since I was working on the release and testing the build, I noticed problem with the JS dependencies of the playground and I added the fix here. --- .github/workflows/release.yml | 76 +- .goreleaser.yaml | 20 - Makefile | 2 +- playground/package-lock.json | 1976 ++++++++++++++++++++++++++------ tools/defradb.containerfile | 14 +- tools/goreleaser.containerfile | 17 - 6 files changed, 1662 insertions(+), 443 deletions(-) delete mode 100644 tools/goreleaser.containerfile diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2eee0900a9..fea78d61aa 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -43,30 +43,11 @@ jobs: cache: false - name: Apply tag - run: git tag ${{ github.event.inputs.tag }} + run: git tag v${{ github.event.inputs.tag }} - name: Build modules run: make deps:modules - - name: Set up QEMU - if: matrix.os == 'ubuntu-latest' - uses: docker/setup-qemu-action@v3 - - - name: Log in to Docker Hub - if: matrix.os == 'ubuntu-latest' - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - - name: Log in to the Container registry - if: matrix.os == 'ubuntu-latest' - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Run command to get SHA environment shell: bash run: echo "sha_short=$(git rev-parse --short HEAD)" >> ${GITHUB_ENV} @@ -114,7 +95,7 @@ jobs: fetch-depth: 0 - name: Apply tag - run: git tag ${{ github.event.inputs.tag }} + run: git tag v${{ github.event.inputs.tag }} - name: Setup Go environment explicitly uses: actions/setup-go@v5 @@ -123,12 +104,6 @@ jobs: check-latest: true cache: false - - name: Log in to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - name: Run command to get SHA environment shell: bash run: echo "sha_short=$(git rev-parse --short HEAD)" >> ${GITHUB_ENV} @@ -179,17 +154,58 @@ jobs: GITHUB_REPOSITORY: ${{ github.repository }} GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} + docker-build-push: + name: Build and push Docker image + runs-on: ubuntu-latest + steps: + - name: Checkout code into the directory + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + file: tools/defradb.containerfile + platforms: linux/amd64,linux/arm64 + push: true + tags: | + ${{ github.repository_owner }}/defradb:latest + ${{ github.repository_owner }}/defradb:${{ github.event.inputs.tag }} + ghcr.io/${{ github.repository_owner }}/defradb:latest + ghcr.io/${{ github.repository_owner }}/defradb:${{ github.event.inputs.tag }} + pull-docker-image: name: Pull docker image job runs-on: ubuntu-latest - needs: prepare + needs: docker-build-push strategy: fail-fast: false matrix: image_tag: - - sourcenetwork/defradb:latest - - ghcr.io/sourcenetwork/defradb:latest + - ${{ github.repository_owner }}/defradb:latest + - ghcr.io/${{ github.repository_owner }}/defradb:latest steps: - name: Log in to Docker Hub diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 4abe0b198a..db5c3a0231 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -97,23 +97,3 @@ milestones: - close: true fail_on_error: false name_template: "DefraDB v{{ .Major }}.{{ .Minor }}" - -dockers: - - ids: - - "defradb_playground" - image_templates: - - "{{ .Env.GITHUB_REPOSITORY }}:latest" - - "{{ .Env.GITHUB_REPOSITORY }}:{{ .Version }}" - - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:latest" - - "ghcr.io/{{ .Env.GITHUB_REPOSITORY }}:{{ .Version }}" - use: buildx - build_flag_templates: - - "--pull" - - "--label=org.opencontainers.image.description=DefraDB is a Peer-to-Peer Edge Database." - - "--label=org.opencontainers.image.created={{ .Date }}" - - "--label=org.opencontainers.image.name={{ .ProjectName }}" - - "--label=org.opencontainers.image.revision={{ .FullCommit }}" - - "--label=org.opencontainers.image.version={{ .Version }}" - - "--label=org.opencontainers.image.source={{ .GitURL }}" - - "--platform=linux/amd64" - dockerfile: ./tools/goreleaser.containerfile diff --git a/Makefile b/Makefile index 3f2b95dd4d..cfc48d50c7 100644 --- a/Makefile +++ b/Makefile @@ -164,7 +164,7 @@ deps\:mocks: .PHONY: deps\:playground deps\:playground: - cd $(PLAYGROUND_DIRECTORY) && npm install && npm run build + cd $(PLAYGROUND_DIRECTORY) && npm install --legacy-peer-deps && npm run build .PHONY: deps deps: diff --git a/playground/package-lock.json b/playground/package-lock.json index c0a43faeca..2fa682a907 100644 --- a/playground/package-lock.json +++ b/playground/package-lock.json @@ -29,7 +29,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.24.8", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.4.tgz", + "integrity": "sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w==", "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" @@ -39,7 +41,9 @@ } }, "node_modules/@babel/runtime-corejs3": { - "version": "7.24.8", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.25.0.tgz", + "integrity": "sha512-BOehWE7MgQ8W8Qn0CQnMtg2tHPHPulcS/5AVpFvs2KCK1ET+0WqZqPvnpRpFN81gYoFopdIEJX9Sgjw3ZBccPg==", "license": "MIT", "dependencies": { "core-js-pure": "^3.30.2", @@ -51,12 +55,15 @@ }, "node_modules/@braintree/sanitize-url": { "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.0.2.tgz", + "integrity": "sha512-NVf/1YycDMs6+FxS0Tb/W8MjJRDQdXF+tBfDtZ5UZeiRUkTmwKc4vmYCKZTyymfJk1gnMsauvZSX/HiV9jOABw==", "license": "MIT" }, "node_modules/@emotion/is-prop-valid": { "version": "0.8.8", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "license": "MIT", "optional": true, "dependencies": { "@emotion/memoize": "0.7.4" @@ -66,10 +73,285 @@ "version": "0.7.4", "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", + "license": "MIT", "optional": true }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/linux-x64": { "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "cpu": [ "x64" ], @@ -83,8 +365,112 @@ "node": ">=12" } }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, "license": "MIT", "dependencies": { @@ -99,6 +485,8 @@ }, "node_modules/@eslint-community/regexpp": { "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", "dev": true, "license": "MIT", "engines": { @@ -107,6 +495,8 @@ }, "node_modules/@eslint/config-array": { "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz", + "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -120,6 +510,8 @@ }, "node_modules/@eslint/config-array/node_modules/brace-expansion": { "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", "dependencies": { @@ -129,6 +521,8 @@ }, "node_modules/@eslint/config-array/node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { @@ -140,6 +534,8 @@ }, "node_modules/@eslint/eslintrc": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", "dev": true, "license": "MIT", "dependencies": { @@ -162,6 +558,8 @@ }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", "dependencies": { @@ -171,6 +569,8 @@ }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { @@ -182,6 +582,8 @@ }, "node_modules/@eslint/js": { "version": "9.9.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.9.0.tgz", + "integrity": "sha512-hhetes6ZHP3BlXLxmd8K2SNgkhNSi+UcecbnwWKwpP7kyi/uC75DJ1lOOBO3xrC4jyojtGE3YxKZPHfk4yrgug==", "dev": true, "license": "MIT", "engines": { @@ -190,6 +592,8 @@ }, "node_modules/@eslint/object-schema": { "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -200,6 +604,7 @@ "version": "1.6.7", "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.7.tgz", "integrity": "sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==", + "license": "MIT", "dependencies": { "@floating-ui/utils": "^0.2.7" } @@ -208,6 +613,7 @@ "version": "1.6.10", "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.10.tgz", "integrity": "sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==", + "license": "MIT", "dependencies": { "@floating-ui/core": "^1.6.0", "@floating-ui/utils": "^0.2.7" @@ -217,6 +623,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", + "license": "MIT", "dependencies": { "@floating-ui/dom": "^1.0.0" }, @@ -228,12 +635,14 @@ "node_modules/@floating-ui/utils": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.7.tgz", - "integrity": "sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==" + "integrity": "sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==", + "license": "MIT" }, "node_modules/@graphiql/react": { "version": "0.26.0", "resolved": "https://registry.npmjs.org/@graphiql/react/-/react-0.26.0.tgz", "integrity": "sha512-WMuv4/SPDw/+b5RuYX2/43SRknCiODQFIY1lYkUcAiU379gcX6QvezDkevrfFgWW8l4wb/pkQ6BR98Wjx9hXBw==", + "license": "MIT", "dependencies": { "@graphiql/toolkit": "^0.10.0", "@headlessui/react": "^1.7.15", @@ -262,6 +671,7 @@ "version": "0.10.0", "resolved": "https://registry.npmjs.org/@graphiql/toolkit/-/toolkit-0.10.0.tgz", "integrity": "sha512-tVWVYL4AKrkBr4f4Vw4/EV1NjstVYg3TGnatFVe6TdBW4kBeATBz5jyGJju/Oq2JrrrQ2LNXfhCDwfdjSlKyHg==", + "license": "MIT", "dependencies": { "@n1ru4l/push-pull-async-iterable-iterator": "^3.1.0", "meros": "^1.1.4" @@ -280,6 +690,7 @@ "version": "1.7.19", "resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.19.tgz", "integrity": "sha512-Ll+8q3OlMJfJbAKM/+/Y2q6PPYbryqNTXDbryx7SXLIDamkF6iQFbriYHga0dY44PvDhvvBWCx1Xj4U5+G4hOw==", + "license": "MIT", "dependencies": { "@tanstack/react-virtual": "^3.0.0-beta.60", "client-only": "^0.0.1" @@ -294,6 +705,8 @@ }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -306,6 +719,8 @@ }, "node_modules/@humanwhocodes/retry": { "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", + "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", "dev": true, "license": "Apache-2.0", "engines": { @@ -320,6 +735,7 @@ "version": "10.18.0", "resolved": "https://registry.npmjs.org/@motionone/animation/-/animation-10.18.0.tgz", "integrity": "sha512-9z2p5GFGCm0gBsZbi8rVMOAJCtw1WqBTIPw3ozk06gDvZInBPIsQcHgYogEJ4yuHJ+akuW8g1SEIOpTOvYs8hw==", + "license": "MIT", "dependencies": { "@motionone/easing": "^10.18.0", "@motionone/types": "^10.17.1", @@ -331,6 +747,7 @@ "version": "10.12.0", "resolved": "https://registry.npmjs.org/@motionone/dom/-/dom-10.12.0.tgz", "integrity": "sha512-UdPTtLMAktHiqV0atOczNYyDd/d8Cf5fFsd1tua03PqTwwCe/6lwhLSQ8a7TbnQ5SN0gm44N1slBfj+ORIhrqw==", + "license": "MIT", "dependencies": { "@motionone/animation": "^10.12.0", "@motionone/generators": "^10.12.0", @@ -344,6 +761,7 @@ "version": "10.18.0", "resolved": "https://registry.npmjs.org/@motionone/easing/-/easing-10.18.0.tgz", "integrity": "sha512-VcjByo7XpdLS4o9T8t99JtgxkdMcNWD3yHU/n6CLEz3bkmKDRZyYQ/wmSf6daum8ZXqfUAgFeCZSpJZIMxaCzg==", + "license": "MIT", "dependencies": { "@motionone/utils": "^10.18.0", "tslib": "^2.3.1" @@ -353,6 +771,7 @@ "version": "10.18.0", "resolved": "https://registry.npmjs.org/@motionone/generators/-/generators-10.18.0.tgz", "integrity": "sha512-+qfkC2DtkDj4tHPu+AFKVfR/C30O1vYdvsGYaR13W/1cczPrrcjdvYCj0VLFuRMN+lP1xvpNZHCRNM4fBzn1jg==", + "license": "MIT", "dependencies": { "@motionone/types": "^10.17.1", "@motionone/utils": "^10.18.0", @@ -362,12 +781,14 @@ "node_modules/@motionone/types": { "version": "10.17.1", "resolved": "https://registry.npmjs.org/@motionone/types/-/types-10.17.1.tgz", - "integrity": "sha512-KaC4kgiODDz8hswCrS0btrVrzyU2CSQKO7Ps90ibBVSQmjkrt2teqta6/sOG59v7+dPnKMAg13jyqtMKV2yJ7A==" + "integrity": "sha512-KaC4kgiODDz8hswCrS0btrVrzyU2CSQKO7Ps90ibBVSQmjkrt2teqta6/sOG59v7+dPnKMAg13jyqtMKV2yJ7A==", + "license": "MIT" }, "node_modules/@motionone/utils": { "version": "10.18.0", "resolved": "https://registry.npmjs.org/@motionone/utils/-/utils-10.18.0.tgz", "integrity": "sha512-3XVF7sgyTSI2KWvTf6uLlBJ5iAgRgmvp3bpuOiQJvInd4nZ19ET8lX5unn30SlmRH7hXbBbH+Gxd0m0klJ3Xtw==", + "license": "MIT", "dependencies": { "@motionone/types": "^10.17.1", "hey-listen": "^1.0.8", @@ -378,12 +799,15 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/@n1ru4l/push-pull-async-iterable-iterator/-/push-pull-async-iterable-iterator-3.2.0.tgz", "integrity": "sha512-3fkKj25kEjsfObL6IlKPAlHYPq/oYwUkkQ03zsTTiDjD7vg/RxjdiLeCydqtxHZP0JgsXL3D/X5oAkMGzuUp/Q==", + "license": "MIT", "engines": { "node": ">=12" } }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "license": "MIT", "dependencies": { @@ -396,6 +820,8 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, "license": "MIT", "engines": { @@ -404,6 +830,8 @@ }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "license": "MIT", "dependencies": { @@ -417,12 +845,14 @@ "node_modules/@radix-ui/primitive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", - "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==" + "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==", + "license": "MIT" }, "node_modules/@radix-ui/react-arrow": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==", + "license": "MIT", "dependencies": { "@radix-ui/react-primitive": "2.0.0" }, @@ -445,6 +875,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz", "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==", + "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.0", "@radix-ui/react-context": "1.1.0", @@ -470,6 +901,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -484,6 +916,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -498,6 +931,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.1.tgz", "integrity": "sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==", + "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", @@ -533,6 +967,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -547,6 +982,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz", "integrity": "sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==", + "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", @@ -573,6 +1009,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.1.tgz", "integrity": "sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==", + "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", @@ -601,6 +1038,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz", "integrity": "sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -615,6 +1053,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz", "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==", + "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.0", "@radix-ui/react-primitive": "2.0.0", @@ -639,6 +1078,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", + "license": "MIT", "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.0" }, @@ -656,6 +1096,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.1.tgz", "integrity": "sha512-oa3mXRRVjHi6DZu/ghuzdylyjaMXLymx83irM7hTxutQbD+7IhPKdMdRHD26Rm+kHRrWcrUkkRPv5pd47a2xFQ==", + "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-collection": "1.1.0", @@ -695,6 +1136,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==", + "license": "MIT", "dependencies": { "@floating-ui/react-dom": "^2.0.0", "@radix-ui/react-arrow": "1.1.0", @@ -726,6 +1168,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.1.tgz", "integrity": "sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==", + "license": "MIT", "dependencies": { "@radix-ui/react-primitive": "2.0.0", "@radix-ui/react-use-layout-effect": "1.1.0" @@ -749,6 +1192,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz", "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==", + "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.0", "@radix-ui/react-use-layout-effect": "1.1.0" @@ -772,6 +1216,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", + "license": "MIT", "dependencies": { "@radix-ui/react-slot": "1.1.0" }, @@ -794,6 +1239,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz", "integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==", + "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-collection": "1.1.0", @@ -824,6 +1270,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", + "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.0" }, @@ -841,6 +1288,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.2.tgz", "integrity": "sha512-9XRsLwe6Yb9B/tlnYCPVUd/TFS4J7HuOZW345DCeC6vKIxQGMZdx21RK4VoZauPD5frgkXTYVS5y90L+3YBn4w==", + "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", @@ -874,6 +1322,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -888,6 +1337,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", + "license": "MIT", "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.0" }, @@ -905,6 +1355,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", + "license": "MIT", "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.0" }, @@ -922,6 +1373,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -936,6 +1388,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", + "license": "MIT", "dependencies": { "@radix-ui/rect": "1.1.0" }, @@ -953,6 +1406,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", + "license": "MIT", "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.0" }, @@ -970,6 +1424,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz", "integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==", + "license": "MIT", "dependencies": { "@radix-ui/react-primitive": "2.0.0" }, @@ -991,7 +1446,162 @@ "node_modules/@radix-ui/rect": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", - "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==" + "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==", + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.0.tgz", + "integrity": "sha512-WTWD8PfoSAJ+qL87lE7votj3syLavxunWhzCnx3XFxFiI/BA/r3X7MUM8dVrH8rb2r4AiO8jJsr3ZjdaftmnfA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.0.tgz", + "integrity": "sha512-a1sR2zSK1B4eYkiZu17ZUZhmUQcKjk2/j9Me2IDjk1GHW7LB5Z35LEzj9iJch6gtUfsnvZs1ZNyDW2oZSThrkA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.0.tgz", + "integrity": "sha512-zOnKWLgDld/svhKO5PD9ozmL6roy5OQ5T4ThvdYZLpiOhEGY+dp2NwUmxK0Ld91LrbjrvtNAE0ERBwjqhZTRAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.0.tgz", + "integrity": "sha512-7doS8br0xAkg48SKE2QNtMSFPFUlRdw9+votl27MvT46vo44ATBmdZdGysOevNELmZlfd+NEa0UYOA8f01WSrg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.0.tgz", + "integrity": "sha512-pWJsfQjNWNGsoCq53KjMtwdJDmh/6NubwQcz52aEwLEuvx08bzcy6tOUuawAOncPnxz/3siRtd8hiQ32G1y8VA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.0.tgz", + "integrity": "sha512-efRIANsz3UHZrnZXuEvxS9LoCOWMGD1rweciD6uJQIx2myN3a8Im1FafZBzh7zk1RJ6oKcR16dU3UPldaKd83w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.0.tgz", + "integrity": "sha512-ZrPhydkTVhyeGTW94WJ8pnl1uroqVHM3j3hjdquwAcWnmivjAwOYjTEAuEDeJvGX7xv3Z9GAvrBkEzCgHq9U1w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.0.tgz", + "integrity": "sha512-cfaupqd+UEFeURmqNP2eEvXqgbSox/LHOyN9/d2pSdV8xTrjdg3NgOFJCtc1vQ/jEke1qD0IejbBfxleBPHnPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.0.tgz", + "integrity": "sha512-ZKPan1/RvAhrUylwBXC9t7B2hXdpb/ufeu22pG2psV7RN8roOfGurEghw1ySmX/CmDDHNTDDjY3lo9hRlgtaHg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.0.tgz", + "integrity": "sha512-H1eRaCwd5E8eS8leiS+o/NqMdljkcb1d6r2h4fKSsCXQilLKArq6WS7XBLDu80Yz+nMqHVFDquwcVrQmGr28rg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.0.tgz", + "integrity": "sha512-zJ4hA+3b5tu8u7L58CCSI0A9N1vkfwPhWd/puGXwtZlsB5bTkwDNW/+JCU84+3QYmKpLi+XvHdmrlwUwDA6kqw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { "version": "4.21.0", @@ -1001,6 +1611,7 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -1014,17 +1625,62 @@ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.0.tgz", + "integrity": "sha512-s5oFkZ/hFcrlAyBTONFY1TWndfyre1wOMwU+6KCpm/iatybvrRgmZVM+vCFwxmC5ZhdlgfE0N4XorsDpi7/4XQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.0.tgz", + "integrity": "sha512-G9+TEqRnAA6nbpqyUqgTiopmnfgnMkR3kMukFBDsiyy23LZvUCpiUwjTRx6ezYCjJODXrh52rBR9oXvm+Fp5wg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.0.tgz", + "integrity": "sha512-2jsCDZwtQvRhejHLfZ1JY6w6kEuEtfF9nzYsZxzSlNVKDX+DpsDJ+Rbjkm74nvg2rdx0gwBS+IMdvwJuq3S9pQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@swagger-api/apidom-ast": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-1.0.0-alpha.9.tgz", + "integrity": "sha512-SAOQrFSFwgDiI4QSIPDwAIJEb4Za+8bu45sNojgV3RMtCz+n4Agw66iqGsDib5YSI/Cg1h4AKFovT3iWdfGWfw==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-error": "^1.0.0-alpha.6", + "@swagger-api/apidom-error": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1032,12 +1688,14 @@ } }, "node_modules/@swagger-api/apidom-core": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-core/-/apidom-core-1.0.0-alpha.9.tgz", + "integrity": "sha512-vGl8BWRf6ODl39fxElcIOjRE2QG5AJhn8tTNMqjjHB/2WppNBuxOVStYZeVJoWfK03OPK8v4Fp/TAcaP9+R7DQ==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^1.0.0-alpha.6", - "@swagger-api/apidom-error": "^1.0.0-alpha.6", + "@swagger-api/apidom-ast": "^1.0.0-alpha.9", + "@swagger-api/apidom-error": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "minim": "~0.23.8", "ramda": "~0.30.0", @@ -1047,33 +1705,39 @@ } }, "node_modules/@swagger-api/apidom-error": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-error/-/apidom-error-1.0.0-alpha.9.tgz", + "integrity": "sha512-FU/2sFSgsICB9HYFELJ79caRpXXzlAV41QTHsAM46WfRehbzZUQpOBQm4jRi3qJGSa/Jk+mQ7Vt8HLRFMpJFfg==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.20.7" } }, "node_modules/@swagger-api/apidom-json-pointer": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-json-pointer/-/apidom-json-pointer-1.0.0-alpha.9.tgz", + "integrity": "sha512-/W8Ktbgbs29zdhed6KHTFk0qmuIRbvEFi8wu2MHGQ5UT4i99Bdu2OyUiayhnpejWztfQxDgL08pjrQPEwgY8Yg==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-error": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-error": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-ns-api-design-systems": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-api-design-systems/-/apidom-ns-api-design-systems-1.0.0-alpha.9.tgz", + "integrity": "sha512-aduC2vbwGgn6ia9IkKpqBYBaKyIDGM/80M3oU3DFgaYIIwynzuwVpN1TkBOLIFy3mAzkWoYKUS0jdZJhMy/6Ug==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-error": "^1.0.0-alpha.6", - "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-error": "^1.0.0-alpha.9", + "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1081,13 +1745,15 @@ } }, "node_modules/@swagger-api/apidom-ns-asyncapi-2": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-asyncapi-2/-/apidom-ns-asyncapi-2-1.0.0-alpha.9.tgz", + "integrity": "sha512-hZjxXJgMt517ADnAauWJh01k7WNRwkbWT5p6b7AXF2H3tl549A2hhLnIg3BBSE3GwB3Nv25GyrI3aA/1dFVC8A==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-ns-json-schema-draft-7": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-ns-json-schema-draft-7": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1095,12 +1761,14 @@ } }, "node_modules/@swagger-api/apidom-ns-json-schema-draft-4": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-4/-/apidom-ns-json-schema-draft-4-1.0.0-alpha.9.tgz", + "integrity": "sha512-OfX4UBb08C0xD5+F80dQAM2yt5lXxcURWkVEeCwxz7i23BB3nNEbnZXNV91Qo9eaJflPh8dO9iiHQxvfw5IgSg==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^1.0.0-alpha.6", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-ast": "^1.0.0-alpha.9", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1108,14 +1776,16 @@ } }, "node_modules/@swagger-api/apidom-ns-json-schema-draft-6": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-6/-/apidom-ns-json-schema-draft-6-1.0.0-alpha.9.tgz", + "integrity": "sha512-qzUVRSSrnlYGMhK6w57o/RboNvy1FO0iFgEnTk56dD4wN49JRNuFqKI18IgXc1W2r9tTTG70nG1khe4cPE8TNg==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-error": "^1.0.0-alpha.6", - "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-error": "^1.0.0-alpha.9", + "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1123,14 +1793,16 @@ } }, "node_modules/@swagger-api/apidom-ns-json-schema-draft-7": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-json-schema-draft-7/-/apidom-ns-json-schema-draft-7-1.0.0-alpha.9.tgz", + "integrity": "sha512-Zml8Z8VCckdFjvTogaec1dabd85hg1+xZDseWcCuD0tYkaTY/sZ8zzI0dz6/4HsKCb58qjiWSa0w60N8Syr6WQ==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-error": "^1.0.0-alpha.6", - "@swagger-api/apidom-ns-json-schema-draft-6": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-error": "^1.0.0-alpha.9", + "@swagger-api/apidom-ns-json-schema-draft-6": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1138,14 +1810,16 @@ } }, "node_modules/@swagger-api/apidom-ns-openapi-2": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-2/-/apidom-ns-openapi-2-1.0.0-alpha.9.tgz", + "integrity": "sha512-WUZxt7Gs7P4EQsGtoD6cKAjf0uDJhkUxsIW9Bb4EAgO6tdp7LlXhbJ0fJ2QycCLY717SfJbvGLfhuSfTYo4Iow==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-error": "^1.0.0-alpha.6", - "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-error": "^1.0.0-alpha.9", + "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1153,13 +1827,15 @@ } }, "node_modules/@swagger-api/apidom-ns-openapi-3-0": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-0/-/apidom-ns-openapi-3-0-1.0.0-alpha.9.tgz", + "integrity": "sha512-7ra5uoZGrfCn1LabfJLueChPcYXyg24//LCYBtjTstyueqd5Vp7JCPeP5NnJSAaqVAP47r8ygceBPoxNp9k1EQ==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-error": "^1.0.0-alpha.6", - "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-error": "^1.0.0-alpha.9", + "@swagger-api/apidom-ns-json-schema-draft-4": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1167,14 +1843,16 @@ } }, "node_modules/@swagger-api/apidom-ns-openapi-3-1": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-openapi-3-1/-/apidom-ns-openapi-3-1-1.0.0-alpha.9.tgz", + "integrity": "sha512-nQOwNQgf0C8EVjf2loAAl4ifRuVOdcqycvXUdcTpsUfHN3fbndR8IKpb26mQNmnACmqgmX+LkbMdW9b+K6089g==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^1.0.0-alpha.6", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-json-pointer": "^1.0.0-alpha.6", - "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-alpha.6", + "@swagger-api/apidom-ast": "^1.0.0-alpha.9", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-json-pointer": "^1.0.0-alpha.9", + "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1182,13 +1860,15 @@ } }, "node_modules/@swagger-api/apidom-ns-workflows-1": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-ns-workflows-1/-/apidom-ns-workflows-1-1.0.0-alpha.9.tgz", + "integrity": "sha512-yKo0p8OkQmDib93Kt1yqWmI7JsD6D9qUHxr/SCuAmNNWny1hxm7cZGoKJwJlGd0uAg84j4vmzWOlG3AsJbnT8g==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1196,70 +1876,80 @@ } }, "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-json": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-json/-/apidom-parser-adapter-api-design-systems-json-1.0.0-alpha.9.tgz", + "integrity": "sha512-xfVMR4HrTzXU0HB4TtxwkNbUIa/cQrPa0BWutJZ0fMYMAtUox2s8GsFYnJfZP52XfpSHFM1VPclivorZqET14g==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-ns-api-design-systems": "^1.0.0-alpha.6", - "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-ns-api-design-systems": "^1.0.0-alpha.9", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-api-design-systems-yaml": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-api-design-systems-yaml/-/apidom-parser-adapter-api-design-systems-yaml-1.0.0-alpha.9.tgz", + "integrity": "sha512-lJZkrhZ8qRTtc5fSLKefCv8j7Xzo8UBfMjpqTJhmETAtU8YfVV2i2znjgxJpm0QwV6FVQqGfK1+ASZQWPLiVcA==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-ns-api-design-systems": "^1.0.0-alpha.6", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-ns-api-design-systems": "^1.0.0-alpha.9", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-json-2": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-json-2/-/apidom-parser-adapter-asyncapi-json-2-1.0.0-alpha.9.tgz", + "integrity": "sha512-65nmKdPzw4C1bmtYn+3zoxXCI6Gnobr0StI9XE0YWiK+lpso7RH3Cgyl1yPZ0DBRVGzP+Fn9FVzmDNulEfR95w==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-alpha.6", - "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-alpha.9", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-asyncapi-yaml-2/-/apidom-parser-adapter-asyncapi-yaml-2-1.0.0-alpha.9.tgz", + "integrity": "sha512-RLI4FpVB3vB6mIuT77yrsv5V2LMZ80dW9XpV+Fmbd4Jkdj+ysAFwT38cI4AsUMOxixpTDIXY1oWD7AjvylHhQQ==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-alpha.6", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-ns-asyncapi-2": "^1.0.0-alpha.9", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-json": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-json/-/apidom-parser-adapter-json-1.0.0-alpha.9.tgz", + "integrity": "sha512-aOewp8/3zobf/O+5Jx8y7+bX3BPRfRlHIv15qp4YVTsLs6gLISWSzTO9JpWe9cR+AfhpsAalFq4t1LwIkmLk4A==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^1.0.0-alpha.6", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-error": "^1.0.0-alpha.6", + "@swagger-api/apidom-ast": "^1.0.0-alpha.9", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-error": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1269,126 +1959,144 @@ } }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-2": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-2/-/apidom-parser-adapter-openapi-json-2-1.0.0-alpha.9.tgz", + "integrity": "sha512-zgtsAfkplCFusX2P/saqdn10J8P3kQizCXxHLvxd2j0EhMJk2wfu4HYN5Pej/7/qf/OR1QZxqtacwebd4RfpXA==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-ns-openapi-2": "^1.0.0-alpha.6", - "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-ns-openapi-2": "^1.0.0-alpha.9", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-0": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-0/-/apidom-parser-adapter-openapi-json-3-0-1.0.0-alpha.9.tgz", + "integrity": "sha512-iPuHf0cAZSUhSv8mB0FnVgatTc26cVYohgqz2cvjoGofdqoh5KKIfxOkWlIhm+qGuBp71CfZUrPYPRsd0dHgeg==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-alpha.6", - "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-alpha.9", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-json-3-1": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-json-3-1/-/apidom-parser-adapter-openapi-json-3-1-1.0.0-alpha.9.tgz", + "integrity": "sha512-jwkfO7tzZyyrAgok+O9fKFOv1q/5njMb9DBc3D/ZF3ZLTcnEw8uj4V2HkjKxUweH5k8ip/gc8ueKmO/i7p2fng==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.6", - "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.9", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-2": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-2/-/apidom-parser-adapter-openapi-yaml-2-1.0.0-alpha.9.tgz", + "integrity": "sha512-jEIDpjbjwFKXQXS/RHJeA4tthsguLoz+nJPYS3AOLfuSiby5QXsKTxgqHXxG/YJqF1xJbZL+5KcF8UyiDePumw==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-ns-openapi-2": "^1.0.0-alpha.6", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-ns-openapi-2": "^1.0.0-alpha.9", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-0/-/apidom-parser-adapter-openapi-yaml-3-0-1.0.0-alpha.9.tgz", + "integrity": "sha512-ieJL8dfIF8fmP3uJRNh/duJa3cCIIv6MzUe6o4uPT/oTDroy4qIATvnq9Dq/gtAv6rcPRpA9VhyghJ1DmjKsZQ==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-alpha.6", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-ns-openapi-3-0": "^1.0.0-alpha.9", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-openapi-yaml-3-1/-/apidom-parser-adapter-openapi-yaml-3-1-1.0.0-alpha.9.tgz", + "integrity": "sha512-EatIH7PZQSNDsRn9ompc62MYzboY7wAkjfYz+2FzBaSA8Vl5/+740qGQj22tu/xhwW4K72aV2NNL1m47QVF7hA==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.6", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-ns-openapi-3-1": "^1.0.0-alpha.9", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-workflows-json-1": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-workflows-json-1/-/apidom-parser-adapter-workflows-json-1-1.0.0-alpha.9.tgz", + "integrity": "sha512-LylC2cQdAmvR7bXqwMwBt6FHTMVGinwIdI8pjl4EbPT9hCVm1rdED53caTYM4gCm+CJGRw20r4gb9vn3+N6RrA==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-ns-workflows-1": "^1.0.0-alpha.6", - "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-ns-workflows-1": "^1.0.0-alpha.9", + "@swagger-api/apidom-parser-adapter-json": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-workflows-yaml-1": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-workflows-yaml-1/-/apidom-parser-adapter-workflows-yaml-1-1.0.0-alpha.9.tgz", + "integrity": "sha512-TlA4+1ca33D7fWxO5jKBytSCv86IGI4Lze4JfrawWUXZ5efhi4LiNmW5TrGlZUyvL7yJtZcA4tn3betlj6jVwA==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-ns-workflows-1": "^1.0.0-alpha.6", - "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-ns-workflows-1": "^1.0.0-alpha.9", + "@swagger-api/apidom-parser-adapter-yaml-1-2": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0" } }, "node_modules/@swagger-api/apidom-parser-adapter-yaml-1-2": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-parser-adapter-yaml-1-2/-/apidom-parser-adapter-yaml-1-2-1.0.0-alpha.9.tgz", + "integrity": "sha512-jSIHEB7lbh+MP3BhYIXFkeivDR01kugXN70e5FskW7oet2TIARsVEPheWKQFSP1U8bUZA4bsp9h9gOQ9xEeErw==", "license": "Apache-2.0", "optional": true, "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-ast": "^1.0.0-alpha.6", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", - "@swagger-api/apidom-error": "^1.0.0-alpha.6", + "@swagger-api/apidom-ast": "^1.0.0-alpha.9", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", + "@swagger-api/apidom-error": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "ramda": "~0.30.0", "ramda-adjunct": "^5.0.0", @@ -1398,11 +2106,13 @@ } }, "node_modules/@swagger-api/apidom-reference": { - "version": "1.0.0-alpha.6", + "version": "1.0.0-alpha.9", + "resolved": "https://registry.npmjs.org/@swagger-api/apidom-reference/-/apidom-reference-1.0.0-alpha.9.tgz", + "integrity": "sha512-KQ6wB5KplqdSsjxdA8BaQulj5zlF5VBCd5KP3RN/9vvixgsD/gyrVY59nisdzmPTqiL6yjhk612eQ96MgG8KiA==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.20.7", - "@swagger-api/apidom-core": "^1.0.0-alpha.6", + "@swagger-api/apidom-core": "^1.0.0-alpha.9", "@types/ramda": "~0.30.0", "axios": "^1.4.0", "minimatch": "^7.4.3", @@ -1436,71 +2146,215 @@ }, "node_modules/@swagger-api/apidom-reference/node_modules/minimatch": { "version": "7.4.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", + "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@swc/core": { + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.7.14.tgz", + "integrity": "sha512-9aeXeifnyuvc2pcuuhPQgVUwdpGEzZ+9nJu0W8/hNl/aESFsJGR5i9uQJRGu0atoNr01gK092fvmqMmQAPcKow==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.12" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.7.14", + "@swc/core-darwin-x64": "1.7.14", + "@swc/core-linux-arm-gnueabihf": "1.7.14", + "@swc/core-linux-arm64-gnu": "1.7.14", + "@swc/core-linux-arm64-musl": "1.7.14", + "@swc/core-linux-x64-gnu": "1.7.14", + "@swc/core-linux-x64-musl": "1.7.14", + "@swc/core-win32-arm64-msvc": "1.7.14", + "@swc/core-win32-ia32-msvc": "1.7.14", + "@swc/core-win32-x64-msvc": "1.7.14" + }, + "peerDependencies": { + "@swc/helpers": "*" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.14.tgz", + "integrity": "sha512-V0OUXjOH+hdGxDYG8NkQzy25mKOpcNKFpqtZEzLe5V/CpLJPnpg1+pMz70m14s9ZFda9OxsjlvPbg1FLUwhgIQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.7.14.tgz", + "integrity": "sha512-9iFvUnxG6FC3An5ogp5jbBfQuUmTTwy8KMB+ZddUoPB3NR1eV+Y9vOh/tfWcenSJbgOKDLgYC5D/b1mHAprsrQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.14.tgz", + "integrity": "sha512-zGJsef9qPivKSH8Vv4F/HiBXBTHZ5Hs3ZjVGo/UIdWPJF8fTL9OVADiRrl34Q7zOZEtGXRwEKLUW1SCQcbDvZA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.14.tgz", + "integrity": "sha512-AxV3MPsoI7i4B8FXOew3dx3N8y00YoJYvIPfxelw07RegeCEH3aHp2U2DtgbP/NV1ugZMx0TL2Z2DEvocmA51g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.14.tgz", + "integrity": "sha512-JDLdNjUj3zPehd4+DrQD8Ltb3B5lD8D05IwePyDWw+uR/YPc7w/TX1FUVci5h3giJnlMCJRvi1IQYV7K1n7KtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.14.tgz", + "integrity": "sha512-Siy5OvPCLLWmMdx4msnEs8HvEVUEigSn0+3pbLjv78iwzXd0qSBNHUPZyC1xeurVaUbpNDxZTpPRIwpqNE2+Og==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.14.tgz", + "integrity": "sha512-FtEGm9mwtRYQNK43WMtUIadxHs/ja2rnDurB99os0ZoFTGG2IHuht2zD97W0wB8JbqEabT1XwSG9Y5wmN+ciEQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" } }, - "node_modules/@swc/core": { - "version": "1.7.0", + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.14.tgz", + "integrity": "sha512-Jp8KDlfq7Ntt2/BXr0y344cYgB1zf0DaLzDZ1ZJR6rYlAzWYSccLYcxHa97VGnsYhhPspMpmCvHid97oe2hl4A==", + "cpu": [ + "arm64" + ], "dev": true, - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@swc/counter": "^0.1.3", - "@swc/types": "^0.1.9" - }, + "license": "Apache-2.0 AND MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/swc" - }, - "optionalDependencies": { - "@swc/core-darwin-arm64": "1.7.0", - "@swc/core-darwin-x64": "1.7.0", - "@swc/core-linux-arm-gnueabihf": "1.7.0", - "@swc/core-linux-arm64-gnu": "1.7.0", - "@swc/core-linux-arm64-musl": "1.7.0", - "@swc/core-linux-x64-gnu": "1.7.0", - "@swc/core-linux-x64-musl": "1.7.0", - "@swc/core-win32-arm64-msvc": "1.7.0", - "@swc/core-win32-ia32-msvc": "1.7.0", - "@swc/core-win32-x64-msvc": "1.7.0" - }, - "peerDependencies": { - "@swc/helpers": "*" - }, - "peerDependenciesMeta": { - "@swc/helpers": { - "optional": true - } } }, - "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.7.0", + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.14.tgz", + "integrity": "sha512-I+cFsXF0OU0J9J4zdWiQKKLURO5dvCujH9Jr8N0cErdy54l9d4gfIxdctfTF+7FyXtWKLTCkp+oby9BQhkFGWA==", "cpu": [ - "x64" + "ia32" ], "dev": true, "license": "Apache-2.0 AND MIT", "optional": true, "os": [ - "linux" + "win32" ], "engines": { "node": ">=10" } }, - "node_modules/@swc/core-linux-x64-musl": { - "version": "1.7.0", + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.14.tgz", + "integrity": "sha512-NNrprQCK6d28mG436jVo2TD+vACHseUECacEBGZ9Ef0qfOIWS1XIt2MisQKG0Oea2VvLFl6tF/V4Lnx/H0Sn3Q==", "cpu": [ "x64" ], @@ -1508,7 +2362,7 @@ "license": "Apache-2.0 AND MIT", "optional": true, "os": [ - "linux" + "win32" ], "engines": { "node": ">=10" @@ -1516,11 +2370,15 @@ }, "node_modules/@swc/counter": { "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", "dev": true, "license": "Apache-2.0" }, "node_modules/@swc/types": { - "version": "0.1.9", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.12.tgz", + "integrity": "sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1528,11 +2386,12 @@ } }, "node_modules/@tanstack/react-virtual": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.10.1.tgz", - "integrity": "sha512-h5kNeE+yQwspjl9E3sJ3UYQu/MuspNOBT5cVdc+NA0uU9B1XSkxbzp86teV3arMDVcQ4ESExqs4JyIirYAMcuA==", + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.10.2.tgz", + "integrity": "sha512-RXOj33/xYgylGNczUrufi/ZbpUreBQmlD9ewz1PNZ4NIe6clTMh5NqAL9gXjRBy59UyZSlqo3c1p3EEzEX27oA==", + "license": "MIT", "dependencies": { - "@tanstack/virtual-core": "3.10.1" + "@tanstack/virtual-core": "3.10.2" }, "funding": { "type": "github", @@ -1544,9 +2403,10 @@ } }, "node_modules/@tanstack/virtual-core": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.10.1.tgz", - "integrity": "sha512-JDi3wU1HIxuxx8BgD7Ix8IXlelCKdTJIh9c0qBs+QXHdix3mjMbkXI3wOq0TuCx1w1RGgzZue34QrM/NPdp/sw==", + "version": "3.10.2", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.10.2.tgz", + "integrity": "sha512-nQXJnavN0D5PcKW2XL+w05aO/bxnuBq0+p3X+RG+R+lTHluNSWp5ePNbz0wIfg7U4HPrX/LBE9llMOvS3/6Cuw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" @@ -1556,6 +2416,7 @@ "version": "5.60.15", "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.15.tgz", "integrity": "sha512-dTOvwEQ+ouKJ/rE9LT1Ue2hmP6H1mZv5+CCnNWu2qtiOe2LQa9lCprEY20HxiDmV/Bxh+dXjywmy5aKvoGjULA==", + "license": "MIT", "dependencies": { "@types/tern": "*" } @@ -1563,10 +2424,13 @@ "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "license": "MIT" }, "node_modules/@types/hast": { "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", + "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", "license": "MIT", "dependencies": { "@types/unist": "^2" @@ -1574,18 +2438,24 @@ }, "node_modules/@types/prop-types": { "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", "dev": true, "license": "MIT" }, "node_modules/@types/ramda": { "version": "0.30.1", + "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-aoyF/ADPL6N+/NXXfhPWF+Qj6w1Cql59m9wX0Gi15uyF+bpzXeLd63HPdiTDE2bmLXfNcVufsDPKmbfOrOzTBA==", "license": "MIT", "dependencies": { "types-ramda": "^0.30.1" } }, "node_modules/@types/react": { - "version": "18.3.3", + "version": "18.3.4", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.4.tgz", + "integrity": "sha512-J7W30FTdfCxDDjmfRM+/JqLHBIyl7xUIp9kwK637FGmY7+mkSFSe6L4jpZzhj5QMfLssSDP4/i75AKkrdC7/Jw==", "dev": true, "license": "MIT", "dependencies": { @@ -1595,6 +2465,8 @@ }, "node_modules/@types/react-dom": { "version": "18.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", + "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", "dev": true, "license": "MIT", "dependencies": { @@ -1603,6 +2475,8 @@ }, "node_modules/@types/swagger-ui-react": { "version": "4.18.3", + "resolved": "https://registry.npmjs.org/@types/swagger-ui-react/-/swagger-ui-react-4.18.3.tgz", + "integrity": "sha512-Mo/R7IjDVwtiFPs84pWvh5pI9iyNGBjmfielxqbOh2Jv+8WVSDVe8Nu25kb5BOuV2xmGS3o33jr6nwDJMBcX+Q==", "dev": true, "license": "MIT", "dependencies": { @@ -1613,16 +2487,21 @@ "version": "0.23.9", "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.9.tgz", "integrity": "sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==", + "license": "MIT", "dependencies": { "@types/estree": "*" } }, "node_modules/@types/unist": { - "version": "2.0.10", + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", "license": "MIT" }, "node_modules/@types/use-sync-external-store": { "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==", "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { @@ -1630,6 +2509,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.2.0.tgz", "integrity": "sha512-02tJIs655em7fvt9gps/+4k4OsKULYGtLBPJfOsmOq1+3cdClYiF0+d6mHu6qDnTcg88wJBkcPLpQhq7FyDz0A==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.2.0", @@ -1663,6 +2543,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.2.0.tgz", "integrity": "sha512-j3Di+o0lHgPrb7FxL3fdEy6LJ/j2NE8u+AP/5cQ9SKb+JLH6V6UHDqJ+e0hXBkHP1wn1YDFjYCS9LBQsZDlDEg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/scope-manager": "8.2.0", "@typescript-eslint/types": "8.2.0", @@ -1691,6 +2572,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.2.0.tgz", "integrity": "sha512-OFn80B38yD6WwpoHU2Tz/fTz7CgFqInllBoC3WP+/jLbTb4gGPTy9HBSTsbDWkMdN55XlVU0mMDYAtgvlUspGw==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.2.0", "@typescript-eslint/visitor-keys": "8.2.0" @@ -1708,6 +2590,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.2.0.tgz", "integrity": "sha512-g1CfXGFMQdT5S+0PSO0fvGXUaiSkl73U1n9LTK5aRAFnPlJ8dLKkXr4AaLFvPedW8lVDoMgLLE3JN98ZZfsj0w==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/typescript-estree": "8.2.0", "@typescript-eslint/utils": "8.2.0", @@ -1732,6 +2615,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.2.0.tgz", "integrity": "sha512-6a9QSK396YqmiBKPkJtxsgZZZVjYQ6wQ/TlI0C65z7vInaETuC6HAHD98AGLC8DyIPqHytvNuS8bBVvNLKyqvQ==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -1745,6 +2629,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.2.0.tgz", "integrity": "sha512-kiG4EDUT4dImplOsbh47B1QnNmXSoUqOjWDvCJw/o8LgfD0yr7k2uy54D5Wm0j4t71Ge1NkynGhpWdS0dEIAUA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/types": "8.2.0", "@typescript-eslint/visitor-keys": "8.2.0", @@ -1773,6 +2658,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.2.0.tgz", "integrity": "sha512-O46eaYKDlV3TvAVDNcoDzd5N550ckSe8G4phko++OCSC1dYIb9LTc3HDGYdWqWIAT5qDUKphO6sd9RrpIJJPfg==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.2.0", @@ -1795,6 +2681,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.2.0.tgz", "integrity": "sha512-sbgsPMW9yLvS7IhCi8IpuK1oBmtbWUNP+hBdwl/I9nzqVsszGnNGti5r9dUtF5RLivHUFFIdRvLiTsPhzSyJ3Q==", "dev": true, + "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.2.0", "eslint-visitor-keys": "^3.4.3" @@ -1809,6 +2696,8 @@ }, "node_modules/@vitejs/plugin-react-swc": { "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.7.0.tgz", + "integrity": "sha512-yrknSb3Dci6svCd/qhHqhFPDSw0QtjumcqdKMoNNzmOl5lMXTTiqzjWtG4Qask2HdvvzaNgSunbQGet8/GrKdA==", "dev": true, "license": "MIT", "dependencies": { @@ -1820,6 +2709,8 @@ }, "node_modules/acorn": { "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true, "license": "MIT", "bin": { @@ -1831,6 +2722,8 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "license": "MIT", "peerDependencies": { @@ -1839,6 +2732,8 @@ }, "node_modules/ajv": { "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", "dependencies": { @@ -1854,6 +2749,8 @@ }, "node_modules/ansi-regex": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", "engines": { @@ -1862,6 +2759,8 @@ }, "node_modules/ansi-styles": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "license": "MIT", "dependencies": { @@ -1876,16 +2775,21 @@ }, "node_modules/apg-lite": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/apg-lite/-/apg-lite-1.0.4.tgz", + "integrity": "sha512-B32zCN3IdHIc99Vy7V9BaYTUzLeRA8YXYY1aQD1/5I2aqIrO0coi4t6hJPqMisidlBxhyME8UexkHt31SlR6Og==", "license": "BSD-2-Clause" }, "node_modules/argparse": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "license": "Python-2.0" }, "node_modules/aria-hidden": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", + "license": "MIT", "dependencies": { "tslib": "^2.0.0" }, @@ -1898,16 +2802,21 @@ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/asynckit": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, "node_modules/autolinker": { "version": "3.16.2", + "resolved": "https://registry.npmjs.org/autolinker/-/autolinker-3.16.2.tgz", + "integrity": "sha512-JiYl7j2Z19F9NdTmirENSUUIIL/9MytEWtmzhfmsKPCp9E+G35Y0UNCMoM9tFigxT59qSc8Ml2dlZXOCVTYwuA==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1917,6 +2826,7 @@ "version": "1.7.4", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -1925,10 +2835,14 @@ }, "node_modules/balanced-match": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, "node_modules/base64-js": { "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "funding": [ { "type": "github", @@ -1947,6 +2861,8 @@ }, "node_modules/bl": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "license": "MIT", "optional": true, "dependencies": { @@ -1957,6 +2873,8 @@ }, "node_modules/brace-expansion": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -1967,6 +2885,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -1976,6 +2895,8 @@ }, "node_modules/buffer": { "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "funding": [ { "type": "github", @@ -1997,25 +2918,10 @@ "ieee754": "^1.1.13" } }, - "node_modules/call-bind": { - "version": "1.0.7", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/callsites": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "license": "MIT", "engines": { @@ -2024,6 +2930,8 @@ }, "node_modules/chalk": { "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", "dependencies": { @@ -2039,6 +2947,8 @@ }, "node_modules/character-entities": { "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", "license": "MIT", "funding": { "type": "github", @@ -2047,6 +2957,8 @@ }, "node_modules/character-entities-legacy": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", "license": "MIT", "funding": { "type": "github", @@ -2055,6 +2967,8 @@ }, "node_modules/character-reference-invalid": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", "license": "MIT", "funding": { "type": "github", @@ -2063,22 +2977,28 @@ }, "node_modules/chownr": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "license": "ISC", "optional": true }, "node_modules/classnames": { "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", "license": "MIT" }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" }, "node_modules/clsx": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "license": "MIT", "engines": { "node": ">=6" } @@ -2086,12 +3006,14 @@ "node_modules/codemirror": { "version": "5.65.17", "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.17.tgz", - "integrity": "sha512-1zOsUx3lzAOu/gnMAZkQ9kpIHcPYOc9y1Fbm2UVk5UBPkdq380nhkelG0qUwm1f7wPvTbndu9ZYlug35EwAZRQ==" + "integrity": "sha512-1zOsUx3lzAOu/gnMAZkQ9kpIHcPYOc9y1Fbm2UVk5UBPkdq380nhkelG0qUwm1f7wPvTbndu9ZYlug35EwAZRQ==", + "license": "MIT" }, "node_modules/codemirror-graphql": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/codemirror-graphql/-/codemirror-graphql-2.1.0.tgz", "integrity": "sha512-Lm5augEJOd+7L6HXzBDmx/n7ViL8P/Dt0ba21X0JLeaMMEWtcG1SOvIdeI35St9ADOGdu/eMOg7aciX/RnWDFA==", + "license": "MIT", "dependencies": { "@types/codemirror": "^0.0.90", "graphql-language-service": "5.3.0" @@ -2106,12 +3028,15 @@ "version": "0.0.90", "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-0.0.90.tgz", "integrity": "sha512-8Z9+tSg27NPRGubbUPUCrt5DDG/OWzLph5BvcDykwR5D7RyZh5mhHG0uS1ePKV1YFCA+/cwc4Ey2AJAEFfV3IA==", + "license": "MIT", "dependencies": { "@types/tern": "*" } }, "node_modules/color-convert": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2123,11 +3048,15 @@ }, "node_modules/color-name": { "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" @@ -2138,6 +3067,8 @@ }, "node_modules/comma-separated-tokens": { "version": "1.0.8", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", + "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", "license": "MIT", "funding": { "type": "github", @@ -2146,11 +3077,15 @@ }, "node_modules/concat-map": { "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, "license": "MIT" }, "node_modules/cookie": { "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -2158,13 +3093,17 @@ }, "node_modules/copy-to-clipboard": { "version": "3.3.3", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", "license": "MIT", "dependencies": { "toggle-selection": "^1.0.6" } }, "node_modules/core-js-pure": { - "version": "3.37.1", + "version": "3.38.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.38.1.tgz", + "integrity": "sha512-BY8Etc1FZqdw1glX0XNOq2FDwfrg/VGqoZOZCdaL+UmdaqDwQwYXkMJT4t6In+zfEfOJDcM9T0KdbBeJg8KKCQ==", "hasInstallScript": true, "license": "MIT", "funding": { @@ -2174,6 +3113,8 @@ }, "node_modules/cross-spawn": { "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "license": "MIT", "dependencies": { @@ -2187,20 +3128,27 @@ }, "node_modules/css.escape": { "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", "license": "MIT" }, "node_modules/csstype": { "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "dev": true, "license": "MIT" }, "node_modules/debounce-promise": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/debounce-promise/-/debounce-promise-3.1.2.tgz", - "integrity": "sha512-rZHcgBkbYavBeD9ej6sP56XfG53d51CD4dnaw989YX/nZ/ZJfgRx/9ePKmTNiUiyQvh4mtrMoS3OAWW+yoYtpg==" + "integrity": "sha512-rZHcgBkbYavBeD9ej6sP56XfG53d51CD4dnaw989YX/nZ/ZJfgRx/9ePKmTNiUiyQvh4mtrMoS3OAWW+yoYtpg==", + "license": "MIT" }, "node_modules/debug": { - "version": "4.3.5", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", + "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", "dev": true, "license": "MIT", "dependencies": { @@ -2217,6 +3165,8 @@ }, "node_modules/decompress-response": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "license": "MIT", "optional": true, "dependencies": { @@ -2231,6 +3181,8 @@ }, "node_modules/deep-extend": { "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "license": "MIT", "engines": { "node": ">=4.0.0" @@ -2238,33 +3190,24 @@ }, "node_modules/deep-is": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true, "license": "MIT" }, "node_modules/deepmerge": { "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/define-data-property": { - "version": "1.1.4", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "license": "MIT", "engines": { "node": ">=0.4.0" @@ -2272,6 +3215,8 @@ }, "node_modules/detect-libc": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", "license": "Apache-2.0", "optional": true, "engines": { @@ -2281,13 +3226,15 @@ "node_modules/detect-node-es": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", - "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -2297,10 +3244,14 @@ }, "node_modules/dompurify": { "version": "3.1.4", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.4.tgz", + "integrity": "sha512-2gnshi6OshmuKil8rMZuQCGiUF3cUxHY3NGDzUAdUx/NPEe5DVnO8BDoAQouvgwnx0R/+a6jUn36Z0FSdq8vww==", "license": "(MPL-2.0 OR Apache-2.0)" }, "node_modules/drange": { "version": "1.1.1", + "resolved": "https://registry.npmjs.org/drange/-/drange-1.1.1.tgz", + "integrity": "sha512-pYxfDYpued//QpnLIm4Avk7rsNtAtQkUES2cwAYSvD/wd2pKD71gN2Ebj3e7klzXwjocvE8c5vx/1fxwpqmSxA==", "license": "MIT", "engines": { "node": ">=4" @@ -2308,6 +3259,8 @@ }, "node_modules/end-of-stream": { "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "license": "MIT", "optional": true, "dependencies": { @@ -2318,6 +3271,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -2325,25 +3279,10 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/es-define-property": { - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, "node_modules/esbuild": { "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -2381,6 +3320,8 @@ }, "node_modules/escape-string-regexp": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "license": "MIT", "engines": { @@ -2392,6 +3333,8 @@ }, "node_modules/eslint": { "version": "9.9.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.9.0.tgz", + "integrity": "sha512-JfiKJrbx0506OEerjK2Y1QlldtBxkAlLxT5OEcRF8uaQ86noDe2k31Vw9rnSWv+MXZHj7OOUV/dA0AhdLFcyvA==", "dev": true, "license": "MIT", "dependencies": { @@ -2450,6 +3393,8 @@ }, "node_modules/eslint-plugin-react-hooks": { "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", "dev": true, "license": "MIT", "engines": { @@ -2460,7 +3405,9 @@ } }, "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.9", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.11.tgz", + "integrity": "sha512-wrAKxMbVr8qhXTtIKfXqAn5SAtRZt0aXxe5P23Fh4pUAdC6XEsybGLB8P0PI4j1yYqOgUEUlzKAGDfo7rJOjcw==", "dev": true, "license": "MIT", "peerDependencies": { @@ -2469,6 +3416,8 @@ }, "node_modules/eslint-scope": { "version": "8.0.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", + "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -2484,6 +3433,8 @@ }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "license": "Apache-2.0", "engines": { @@ -2495,6 +3446,8 @@ }, "node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", "dependencies": { @@ -2504,6 +3457,8 @@ }, "node_modules/eslint/node_modules/eslint-visitor-keys": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", "dev": true, "license": "Apache-2.0", "engines": { @@ -2515,6 +3470,8 @@ }, "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { @@ -2526,6 +3483,8 @@ }, "node_modules/espree": { "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -2542,6 +3501,8 @@ }, "node_modules/espree/node_modules/eslint-visitor-keys": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", "dev": true, "license": "Apache-2.0", "engines": { @@ -2553,6 +3514,8 @@ }, "node_modules/esquery": { "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -2564,6 +3527,8 @@ }, "node_modules/esrecurse": { "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -2575,6 +3540,8 @@ }, "node_modules/estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -2583,6 +3550,8 @@ }, "node_modules/esutils": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -2591,6 +3560,8 @@ }, "node_modules/expand-template": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", "license": "(MIT OR WTFPL)", "optional": true, "engines": { @@ -2599,6 +3570,8 @@ }, "node_modules/fast-deep-equal": { "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true, "license": "MIT" }, @@ -2607,6 +3580,7 @@ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -2623,6 +3597,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -2632,20 +3607,28 @@ }, "node_modules/fast-json-patch": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", + "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==", "license": "MIT" }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true, "license": "MIT" }, "node_modules/fastq": { "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, "license": "ISC", "dependencies": { @@ -2654,6 +3637,8 @@ }, "node_modules/fault": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz", + "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==", "license": "MIT", "dependencies": { "format": "^0.2.0" @@ -2665,6 +3650,8 @@ }, "node_modules/file-entry-cache": { "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2679,6 +3666,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -2688,6 +3676,8 @@ }, "node_modules/find-up": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", "dependencies": { @@ -2703,6 +3693,8 @@ }, "node_modules/flat-cache": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "license": "MIT", "dependencies": { @@ -2715,11 +3707,15 @@ }, "node_modules/flatted": { "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true, "license": "ISC" }, "node_modules/follow-redirects": { "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "funding": [ { "type": "individual", @@ -2738,6 +3734,8 @@ }, "node_modules/form-data": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -2750,6 +3748,8 @@ }, "node_modules/format": { "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", "engines": { "node": ">=0.4.x" } @@ -2758,6 +3758,7 @@ "version": "6.5.1", "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-6.5.1.tgz", "integrity": "sha512-o1BGqqposwi7cgDrtg0dNONhkmPsUFDaLcKXigzuTFC5x58mE8iyTazxSudFzmT6MEyJKfjjU8ItoMe3W+3fiw==", + "license": "MIT", "dependencies": { "@motionone/dom": "10.12.0", "framesync": "6.0.1", @@ -2778,43 +3779,38 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/framesync/-/framesync-6.0.1.tgz", "integrity": "sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==", + "license": "MIT", "dependencies": { "tslib": "^2.1.0" } }, "node_modules/fs-constants": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "license": "MIT", "optional": true }, - "node_modules/function-bind": { - "version": "1.1.2", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/get-nonce": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", "engines": { "node": ">=6" } @@ -2823,6 +3819,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/get-value/-/get-value-3.0.1.tgz", "integrity": "sha512-mKZj9JLQrwMBtj5wxi6MH8Z5eSKaERpAwjg43dPtlGI1ZVEgH/qC7T8/6R2OBSUA+zzHBZgICsVJaEIV2tKTDA==", + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -2832,11 +3829,15 @@ }, "node_modules/github-from-package": { "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", "license": "MIT", "optional": true }, "node_modules/glob-parent": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "license": "ISC", "dependencies": { @@ -2848,6 +3849,8 @@ }, "node_modules/globals": { "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, "license": "MIT", "engines": { @@ -2862,6 +3865,7 @@ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -2877,18 +3881,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/gopd": { - "version": "1.0.1", - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/graphemer": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true, "license": "MIT" }, @@ -2896,6 +3892,7 @@ "version": "3.7.0", "resolved": "https://registry.npmjs.org/graphiql/-/graphiql-3.7.0.tgz", "integrity": "sha512-M38uOeD8y0M85VnrifhpXtcgGshQG2dtQGJ6fPZB9c659sA6y2Yh9aDnE055/n2ricidwSLrKmsiDXrvDuoU1A==", + "license": "MIT", "dependencies": { "@graphiql/react": "^0.26.0" }, @@ -2907,6 +3904,8 @@ }, "node_modules/graphql": { "version": "16.9.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.9.0.tgz", + "integrity": "sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==", "license": "MIT", "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" @@ -2916,6 +3915,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/graphql-language-service/-/graphql-language-service-5.3.0.tgz", "integrity": "sha512-gCQIIy7lM9CB1KPLEb+DNZLczA9zuTLEOJE2hEQZTFYInogdmMDRa6RAkvM4LL0LcgcS+3uPs6KtHlcjCqRbUg==", + "license": "MIT", "dependencies": { "debounce-promise": "^3.1.2", "nullthrows": "^1.0.0", @@ -2930,54 +3930,18 @@ }, "node_modules/has-flag": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/hast-util-parse-selector": { "version": "2.2.5", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", + "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", "license": "MIT", "funding": { "type": "opencollective", @@ -2986,6 +3950,8 @@ }, "node_modules/hastscript": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", + "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", "license": "MIT", "dependencies": { "@types/hast": "^2.0.0", @@ -3002,10 +3968,13 @@ "node_modules/hey-listen": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz", - "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==" + "integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==", + "license": "MIT" }, "node_modules/highlight.js": { "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", "license": "BSD-3-Clause", "engines": { "node": "*" @@ -3013,6 +3982,8 @@ }, "node_modules/ieee754": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", @@ -3030,7 +4001,9 @@ "license": "BSD-3-Clause" }, "node_modules/ignore": { - "version": "5.3.1", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { @@ -3039,6 +4012,8 @@ }, "node_modules/immutable": { "version": "3.8.2", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", + "integrity": "sha512-15gZoQ38eYjEjxkorfbcgBKBL6R7T459OuK+CpcWt7O3KF4uPCx2tD0uFETlUDIyo+1789crbMhTvQBSR5yBMg==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -3046,6 +4021,8 @@ }, "node_modules/import-fresh": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "license": "MIT", "dependencies": { @@ -3061,6 +4038,8 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "license": "MIT", "engines": { @@ -3069,15 +4048,21 @@ }, "node_modules/inherits": { "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, "node_modules/ini": { "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "license": "ISC", "optional": true }, "node_modules/invariant": { "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "license": "MIT", "dependencies": { "loose-envify": "^1.0.0" @@ -3085,6 +4070,8 @@ }, "node_modules/is-alphabetical": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", "license": "MIT", "funding": { "type": "github", @@ -3093,6 +4080,8 @@ }, "node_modules/is-alphanumerical": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", "license": "MIT", "dependencies": { "is-alphabetical": "^1.0.0", @@ -3105,6 +4094,8 @@ }, "node_modules/is-decimal": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", "license": "MIT", "funding": { "type": "github", @@ -3113,6 +4104,8 @@ }, "node_modules/is-extglob": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "license": "MIT", "engines": { @@ -3121,6 +4114,8 @@ }, "node_modules/is-glob": { "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "license": "MIT", "dependencies": { @@ -3132,6 +4127,8 @@ }, "node_modules/is-hexadecimal": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", "license": "MIT", "funding": { "type": "github", @@ -3143,12 +4140,15 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/is-path-inside": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, "license": "MIT", "engines": { @@ -3159,6 +4159,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -3170,12 +4171,15 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-3.0.1.tgz", "integrity": "sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/isexe": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true, "license": "ISC" }, @@ -3183,20 +4187,27 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/js-file-download": { "version": "0.4.12", + "resolved": "https://registry.npmjs.org/js-file-download/-/js-file-download-0.4.12.tgz", + "integrity": "sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg==", "license": "MIT" }, "node_modules/js-tokens": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -3207,21 +4218,29 @@ }, "node_modules/json-buffer": { "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true, "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true, "license": "MIT" }, "node_modules/keyv": { "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "license": "MIT", "dependencies": { @@ -3230,6 +4249,8 @@ }, "node_modules/levn": { "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3244,12 +4265,15 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "license": "MIT", "dependencies": { "uc.micro": "^2.0.0" } }, "node_modules/locate-path": { "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", "dependencies": { @@ -3264,19 +4288,27 @@ }, "node_modules/lodash": { "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "license": "MIT" }, "node_modules/lodash.debounce": { "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true, "license": "MIT" }, "node_modules/loose-envify": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" @@ -3287,6 +4319,8 @@ }, "node_modules/lowlight": { "version": "1.20.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", + "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==", "license": "MIT", "dependencies": { "fault": "^1.0.0", @@ -3301,6 +4335,7 @@ "version": "14.1.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "license": "MIT", "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", @@ -3316,13 +4351,15 @@ "node_modules/mdurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==" + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -3331,6 +4368,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/meros/-/meros-1.3.0.tgz", "integrity": "sha512-2BNGOimxEz5hmjUG2FwoxCt5HN7BXdaWyFqEwxPTrJzVdABtrL4TiHTcsWSFAxPQ/tOnEaQEJh3qWq71QRMY+w==", + "license": "MIT", "engines": { "node": ">=13" }, @@ -3348,6 +4386,7 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -3358,6 +4397,8 @@ }, "node_modules/mime-db": { "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -3365,6 +4406,8 @@ }, "node_modules/mime-types": { "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -3375,6 +4418,8 @@ }, "node_modules/mimic-response": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "license": "MIT", "optional": true, "engines": { @@ -3386,6 +4431,8 @@ }, "node_modules/minim": { "version": "0.23.8", + "resolved": "https://registry.npmjs.org/minim/-/minim-0.23.8.tgz", + "integrity": "sha512-bjdr2xW1dBCMsMGGsUeqM4eFI60m94+szhxWys+B1ztIt6gWSfeGBdSVCIawezeHYLYn0j6zrsXdQS/JllBzww==", "license": "MIT", "dependencies": { "lodash": "^4.15.0" @@ -3399,6 +4446,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -3411,6 +4459,8 @@ }, "node_modules/minimist": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "license": "MIT", "optional": true, "funding": { @@ -3419,16 +4469,22 @@ }, "node_modules/mkdirp-classic": { "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "license": "MIT", "optional": true }, "node_modules/ms": { "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true, "license": "MIT" }, "node_modules/nan": { "version": "2.20.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz", + "integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==", "license": "MIT", "optional": true }, @@ -3443,6 +4499,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -3452,16 +4509,31 @@ }, "node_modules/napi-build-utils": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", "license": "MIT", "optional": true }, "node_modules/natural-compare": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true, "license": "MIT" }, + "node_modules/neotraverse": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.18.tgz", + "integrity": "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, "node_modules/node-abi": { - "version": "3.65.0", + "version": "3.67.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.67.0.tgz", + "integrity": "sha512-bLn/fU/ALVBE9wj+p4Y21ZJWYFjUXLXPi/IewyLZkx3ApxKDNBWCKdReeKOtD8dWpOdDCeMyLh6ZewzcLsG2Nw==", "license": "MIT", "optional": true, "dependencies": { @@ -3473,10 +4545,14 @@ }, "node_modules/node-abort-controller": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", "license": "MIT" }, "node_modules/node-domexception": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", "funding": [ { "type": "github", @@ -3494,6 +4570,8 @@ }, "node_modules/node-fetch-commonjs": { "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch-commonjs/-/node-fetch-commonjs-3.3.2.tgz", + "integrity": "sha512-VBlAiynj3VMLrotgwOS3OyECFxas5y7ltLcK4t41lMUZeaK15Ym4QRkqN0EQKAFL42q9i21EPKjzLUPfltR72A==", "license": "MIT", "dependencies": { "node-domexception": "^1.0.0", @@ -3510,27 +4588,22 @@ "node_modules/nullthrows": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", - "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==" + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", + "license": "MIT" }, "node_modules/object-assign": { "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/object-inspect": { - "version": "1.13.2", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/once": { "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "license": "ISC", "optional": true, "dependencies": { @@ -3539,6 +4612,8 @@ }, "node_modules/openapi-path-templating": { "version": "1.6.0", + "resolved": "https://registry.npmjs.org/openapi-path-templating/-/openapi-path-templating-1.6.0.tgz", + "integrity": "sha512-1atBNwOUrZXthTvlvvX8k8ovFEF3iA8mDidYMkdOtvVdndBhTrspbwGXNOzEUaJhm9iUl4Tf5uQaeTLAJvwPig==", "license": "Apache-2.0", "dependencies": { "apg-lite": "^1.0.3" @@ -3549,6 +4624,8 @@ }, "node_modules/openapi-server-url-templating": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/openapi-server-url-templating/-/openapi-server-url-templating-1.1.0.tgz", + "integrity": "sha512-dtyTFKx2xVcO0W8JKaluXIHC9l/MLjHeflBaWjiWNMCHp/TBs9dEjQDbj/VFlHR4omFOKjjmqm1pW1aCAhmPBg==", "license": "Apache-2.0", "dependencies": { "apg-lite": "^1.0.3" @@ -3559,6 +4636,8 @@ }, "node_modules/optionator": { "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "license": "MIT", "dependencies": { @@ -3575,6 +4654,8 @@ }, "node_modules/p-limit": { "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3589,6 +4670,8 @@ }, "node_modules/p-locate": { "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "license": "MIT", "dependencies": { @@ -3603,6 +4686,8 @@ }, "node_modules/parent-module": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "license": "MIT", "dependencies": { @@ -3614,6 +4699,8 @@ }, "node_modules/parse-entities": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", "license": "MIT", "dependencies": { "character-entities": "^1.0.0", @@ -3630,6 +4717,8 @@ }, "node_modules/path-exists": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "license": "MIT", "engines": { @@ -3638,6 +4727,8 @@ }, "node_modules/path-key": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "license": "MIT", "engines": { @@ -3649,6 +4740,7 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -3657,13 +4749,15 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -3675,6 +4769,7 @@ "version": "11.0.3", "resolved": "https://registry.npmjs.org/popmotion/-/popmotion-11.0.3.tgz", "integrity": "sha512-Y55FLdj3UxkR7Vl3s7Qr4e9m0onSnP8W7d/xQLsoJM40vs6UKHFdygs6SWryasTZYqugMjm3BepCF4CWXDiHgA==", + "license": "MIT", "dependencies": { "framesync": "6.0.1", "hey-listen": "^1.0.8", @@ -3701,6 +4796,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.1", @@ -3712,6 +4808,8 @@ }, "node_modules/prebuild-install": { "version": "7.1.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", + "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", "license": "MIT", "optional": true, "dependencies": { @@ -3737,6 +4835,8 @@ }, "node_modules/prelude-ls": { "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "license": "MIT", "engines": { @@ -3745,6 +4845,8 @@ }, "node_modules/prismjs": { "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", "license": "MIT", "engines": { "node": ">=6" @@ -3752,6 +4854,8 @@ }, "node_modules/process": { "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "license": "MIT", "engines": { "node": ">= 0.6.0" @@ -3759,6 +4863,8 @@ }, "node_modules/prop-types": { "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", @@ -3768,6 +4874,8 @@ }, "node_modules/property-information": { "version": "5.6.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", + "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", "license": "MIT", "dependencies": { "xtend": "^4.0.0" @@ -3779,10 +4887,14 @@ }, "node_modules/proxy-from-env": { "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "license": "MIT" }, "node_modules/pump": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "license": "MIT", "optional": true, "dependencies": { @@ -3792,6 +4904,8 @@ }, "node_modules/punycode": { "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "license": "MIT", "engines": { @@ -3802,29 +4916,21 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/qs": { - "version": "6.12.3", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/querystringify": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", "license": "MIT" }, "node_modules/queue-microtask": { "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { @@ -3844,6 +4950,8 @@ }, "node_modules/ramda": { "version": "0.30.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.30.1.tgz", + "integrity": "sha512-tEF5I22zJnuclswcZMc8bDIrwRHRzf+NqVEmqg50ShAZMP7MWeR/RGDthfM/p+BlqvF2fXAzpn8i+SJcYD3alw==", "license": "MIT", "funding": { "type": "opencollective", @@ -3851,7 +4959,9 @@ } }, "node_modules/ramda-adjunct": { - "version": "5.0.1", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ramda-adjunct/-/ramda-adjunct-5.1.0.tgz", + "integrity": "sha512-8qCpl2vZBXEJyNbi4zqcgdfHtcdsWjOGbiNSEnEBrM6Y0OKOT8UxJbIVGm1TIcjaSu2MxaWcgtsNlKlCk7o7qg==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.3" @@ -3866,6 +4976,8 @@ }, "node_modules/randexp": { "version": "0.5.3", + "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.5.3.tgz", + "integrity": "sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==", "license": "MIT", "dependencies": { "drange": "^1.0.2", @@ -3877,6 +4989,8 @@ }, "node_modules/randombytes": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" @@ -3884,6 +4998,8 @@ }, "node_modules/rc": { "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "optional": true, "dependencies": { @@ -3898,6 +5014,8 @@ }, "node_modules/rc/node_modules/strip-json-comments": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "license": "MIT", "optional": true, "engines": { @@ -3906,6 +5024,8 @@ }, "node_modules/react": { "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" @@ -3916,6 +5036,8 @@ }, "node_modules/react-copy-to-clipboard": { "version": "5.1.0", + "resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.1.0.tgz", + "integrity": "sha512-k61RsNgAayIJNoy9yDsYzDe/yAZAzEbEgcz3DZMhF686LEyukcE1hzurxe85JandPUG+yTfGVFzuEw3xt8WP/A==", "license": "MIT", "dependencies": { "copy-to-clipboard": "^3.3.1", @@ -3927,6 +5049,8 @@ }, "node_modules/react-debounce-input": { "version": "3.3.0", + "resolved": "https://registry.npmjs.org/react-debounce-input/-/react-debounce-input-3.3.0.tgz", + "integrity": "sha512-VEqkvs8JvY/IIZvh71Z0TC+mdbxERvYF33RcebnodlsUZ8RSgyKe2VWaHXv4+/8aoOgXLxWrdsYs2hDhcwbUgA==", "license": "MIT", "dependencies": { "lodash.debounce": "^4", @@ -3938,6 +5062,8 @@ }, "node_modules/react-dom": { "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", @@ -3949,6 +5075,8 @@ }, "node_modules/react-immutable-proptypes": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/react-immutable-proptypes/-/react-immutable-proptypes-2.2.0.tgz", + "integrity": "sha512-Vf4gBsePlwdGvSZoLSBfd4HAP93HDauMY4fDjXhreg/vg6F3Fj/MXDNyTbltPC/xZKmZc+cjLu3598DdYK6sgQ==", "license": "MIT", "dependencies": { "invariant": "^2.2.2" @@ -3959,6 +5087,8 @@ }, "node_modules/react-immutable-pure-component": { "version": "2.2.2", + "resolved": "https://registry.npmjs.org/react-immutable-pure-component/-/react-immutable-pure-component-2.2.2.tgz", + "integrity": "sha512-vkgoMJUDqHZfXXnjVlG3keCxSO/U6WeDQ5/Sl0GK2cH8TOxEzQ5jXqDXHEL/jqk6fsNxV05oH5kD7VNMUE2k+A==", "license": "MIT", "peerDependencies": { "immutable": ">= 2 || >= 4.0.0-rc", @@ -3968,6 +5098,8 @@ }, "node_modules/react-inspector": { "version": "6.0.2", + "resolved": "https://registry.npmjs.org/react-inspector/-/react-inspector-6.0.2.tgz", + "integrity": "sha512-x+b7LxhmHXjHoU/VrFAzw5iutsILRoYyDq97EDYdFpPLcvqtEzk4ZSZSQjnFPbr5T57tLXnHcqFYoN1pI6u8uQ==", "license": "MIT", "peerDependencies": { "react": "^16.8.4 || ^17.0.0 || ^18.0.0" @@ -3975,10 +5107,14 @@ }, "node_modules/react-is": { "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, "node_modules/react-redux": { "version": "9.1.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.2.tgz", + "integrity": "sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w==", "license": "MIT", "dependencies": { "@types/use-sync-external-store": "^0.0.3", @@ -4002,6 +5138,7 @@ "version": "2.5.7", "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz", "integrity": "sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==", + "license": "MIT", "dependencies": { "react-remove-scroll-bar": "^2.3.4", "react-style-singleton": "^2.2.1", @@ -4026,6 +5163,7 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz", "integrity": "sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==", + "license": "MIT", "dependencies": { "react-style-singleton": "^2.2.1", "tslib": "^2.0.0" @@ -4047,6 +5185,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "license": "MIT", "dependencies": { "get-nonce": "^1.0.0", "invariant": "^2.2.4", @@ -4067,6 +5206,8 @@ }, "node_modules/react-syntax-highlighter": { "version": "15.5.0", + "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz", + "integrity": "sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.3.1", @@ -4081,6 +5222,8 @@ }, "node_modules/readable-stream": { "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "license": "MIT", "optional": true, "dependencies": { @@ -4094,10 +5237,14 @@ }, "node_modules/redux": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", "license": "MIT" }, "node_modules/redux-immutable": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/redux-immutable/-/redux-immutable-4.0.0.tgz", + "integrity": "sha512-SchSn/DWfGb3oAejd+1hhHx01xUoxY+V7TeK0BKqpkLKiQPVFf7DYzEaKmrEVxsWxielKfSK9/Xq66YyxgR1cg==", "license": "BSD-3-Clause", "peerDependencies": { "immutable": "^3.8.1 || ^4.0.0-rc.1" @@ -4105,6 +5252,8 @@ }, "node_modules/refractor": { "version": "3.6.0", + "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz", + "integrity": "sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==", "license": "MIT", "dependencies": { "hastscript": "^6.0.0", @@ -4118,6 +5267,8 @@ }, "node_modules/refractor/node_modules/prismjs": { "version": "1.27.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz", + "integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==", "license": "MIT", "engines": { "node": ">=6" @@ -4125,10 +5276,14 @@ }, "node_modules/regenerator-runtime": { "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", "license": "MIT" }, "node_modules/remarkable": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/remarkable/-/remarkable-2.0.1.tgz", + "integrity": "sha512-YJyMcOH5lrR+kZdmB0aJJ4+93bEojRZ1HGDn9Eagu6ibg7aVZhc3OWbbShRid+Q5eAfsEqWxpe+g5W5nYNfNiA==", "license": "MIT", "dependencies": { "argparse": "^1.0.10", @@ -4143,6 +5298,8 @@ }, "node_modules/remarkable/node_modules/argparse": { "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" @@ -4150,6 +5307,8 @@ }, "node_modules/repeat-string": { "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", "license": "MIT", "engines": { "node": ">=0.10" @@ -4157,14 +5316,20 @@ }, "node_modules/requires-port": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "license": "MIT" }, "node_modules/reselect": { "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", "license": "MIT" }, "node_modules/resolve-from": { "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, "license": "MIT", "engines": { @@ -4173,6 +5338,8 @@ }, "node_modules/ret": { "version": "0.2.2", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.2.2.tgz", + "integrity": "sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==", "license": "MIT", "engines": { "node": ">=4" @@ -4180,6 +5347,8 @@ }, "node_modules/reusify": { "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, "license": "MIT", "engines": { @@ -4192,6 +5361,7 @@ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.0.tgz", "integrity": "sha512-vo+S/lfA2lMS7rZ2Qoubi6I5hwZwzXeUIctILZLbHI+laNtvhhOIon2S1JksA5UEDQ7l3vberd0fxK44lTYjbQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "1.0.5" }, @@ -4224,6 +5394,8 @@ }, "node_modules/run-parallel": { "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { @@ -4246,6 +5418,8 @@ }, "node_modules/safe-buffer": { "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -4264,6 +5438,8 @@ }, "node_modules/scheduler": { "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" @@ -4271,6 +5447,8 @@ }, "node_modules/semver": { "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "devOptional": true, "license": "ISC", "bin": { @@ -4282,6 +5460,8 @@ }, "node_modules/serialize-error": { "version": "8.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz", + "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==", "license": "MIT", "dependencies": { "type-fest": "^0.20.2" @@ -4293,21 +5473,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/set-function-length": { - "version": "1.2.2", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/set-value": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/set-value/-/set-value-4.1.0.tgz", @@ -4317,6 +5482,7 @@ "https://paypal.me/jonathanschlinkert", "https://jonschlinkert.dev/sponsor" ], + "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4", "is-primitive": "^3.0.1" @@ -4327,6 +5493,8 @@ }, "node_modules/sha.js": { "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "license": "(MIT AND BSD-3-Clause)", "dependencies": { "inherits": "^2.0.1", @@ -4338,6 +5506,8 @@ }, "node_modules/shebang-command": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "license": "MIT", "dependencies": { @@ -4349,6 +5519,8 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "license": "MIT", "engines": { @@ -4357,30 +5529,18 @@ }, "node_modules/short-unique-id": { "version": "5.2.0", + "resolved": "https://registry.npmjs.org/short-unique-id/-/short-unique-id-5.2.0.tgz", + "integrity": "sha512-cMGfwNyfDZ/nzJ2k2M+ClthBIh//GlZl1JEf47Uoa9XR11bz8Pa2T2wQO4bVrRdH48LrIDWJahQziKo3MjhsWg==", "license": "Apache-2.0", "bin": { "short-unique-id": "bin/short-unique-id", "suid": "bin/short-unique-id" } }, - "node_modules/side-channel": { - "version": "1.0.6", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/simple-concat": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", "funding": [ { "type": "github", @@ -4400,6 +5560,8 @@ }, "node_modules/simple-get": { "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", "funding": [ { "type": "github", @@ -4427,6 +5589,7 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -4436,12 +5599,15 @@ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/space-separated-tokens": { "version": "1.1.5", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", + "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", "license": "MIT", "funding": { "type": "github", @@ -4450,10 +5616,14 @@ }, "node_modules/sprintf-js": { "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "license": "BSD-3-Clause" }, "node_modules/string_decoder": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "license": "MIT", "optional": true, "dependencies": { @@ -4462,6 +5632,8 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { @@ -4473,6 +5645,8 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "license": "MIT", "engines": { @@ -4486,6 +5660,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-5.0.0.tgz", "integrity": "sha512-08yq36Ikn4kx4YU6RD7jWEv27v4V+PUsOGa4n/as8Et3CuODMJQ00ENeAVXAeydX4Z2j1XHZF1K2sX4mGl18fA==", + "license": "MIT", "dependencies": { "hey-listen": "^1.0.8", "tslib": "^2.1.0" @@ -4493,6 +5668,8 @@ }, "node_modules/supports-color": { "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", "dependencies": { @@ -4503,30 +5680,33 @@ } }, "node_modules/swagger-client": { - "version": "3.28.2", + "version": "3.29.2", + "resolved": "https://registry.npmjs.org/swagger-client/-/swagger-client-3.29.2.tgz", + "integrity": "sha512-7dOIAodJeUsYbvWTpDODY2+bfJcZ34WG84TByMet76OJ/ZjOLHZtJSgMFxEvnh9+yR0qn8wvHUdfg27ylg2eiQ==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.22.15", - "@swagger-api/apidom-core": ">=1.0.0-alpha.5 <1.0.0-beta.0", - "@swagger-api/apidom-error": ">=1.0.0-alpha.5 <1.0.0-beta.0", - "@swagger-api/apidom-json-pointer": ">=1.0.0-alpha.5 <1.0.0-beta.0", - "@swagger-api/apidom-ns-openapi-3-1": ">=1.0.0-alpha.5 <1.0.0-beta.0", - "@swagger-api/apidom-reference": ">=1.0.0-alpha.5 <1.0.0-beta.0", + "@swagger-api/apidom-core": ">=1.0.0-alpha.9 <1.0.0-beta.0", + "@swagger-api/apidom-error": ">=1.0.0-alpha.9 <1.0.0-beta.0", + "@swagger-api/apidom-json-pointer": ">=1.0.0-alpha.9 <1.0.0-beta.0", + "@swagger-api/apidom-ns-openapi-3-1": ">=1.0.0-alpha.9 <1.0.0-beta.0", + "@swagger-api/apidom-reference": ">=1.0.0-alpha.9 <1.0.0-beta.0", "cookie": "~0.6.0", "deepmerge": "~4.3.0", "fast-json-patch": "^3.0.0-1", "js-yaml": "^4.1.0", + "neotraverse": "=0.6.18", "node-abort-controller": "^3.1.1", "node-fetch-commonjs": "^3.3.2", "openapi-path-templating": "^1.5.1", "openapi-server-url-templating": "^1.0.0", - "qs": "^6.10.2", - "ramda-adjunct": "^5.0.0", - "traverse": "=0.6.8" + "ramda-adjunct": "^5.0.0" } }, "node_modules/swagger-ui-react": { "version": "5.17.14", + "resolved": "https://registry.npmjs.org/swagger-ui-react/-/swagger-ui-react-5.17.14.tgz", + "integrity": "sha512-mCXerZrbcn4ftPYifUF0+iKIRTHoVCv0HcJc/sXl9nCe3oeWdsjmOWVqKabzzAkAa0NwsbKNJFv2UL/Ivnf6VQ==", "license": "Apache-2.0", "dependencies": { "@babel/runtime-corejs3": "^7.24.5", @@ -4570,6 +5750,8 @@ }, "node_modules/tar-fs": { "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "license": "MIT", "optional": true, "dependencies": { @@ -4581,6 +5763,8 @@ }, "node_modules/tar-stream": { "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "license": "MIT", "optional": true, "dependencies": { @@ -4596,6 +5780,8 @@ }, "node_modules/text-table": { "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true, "license": "MIT" }, @@ -4604,6 +5790,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -4613,20 +5800,14 @@ }, "node_modules/toggle-selection": { "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==", "license": "MIT" }, - "node_modules/traverse": { - "version": "0.6.8", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/tree-sitter": { "version": "0.20.4", + "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.20.4.tgz", + "integrity": "sha512-rjfR5dc4knG3jnJNN/giJ9WOoN1zL/kZyrS0ILh+eqq8RNcIbiXA63JsMEgluug0aNvfQvK4BfCErN1vIzvKog==", "hasInstallScript": true, "license": "MIT", "optional": true, @@ -4637,6 +5818,9 @@ }, "node_modules/tree-sitter-json": { "version": "0.20.2", + "resolved": "https://registry.npmjs.org/tree-sitter-json/-/tree-sitter-json-0.20.2.tgz", + "integrity": "sha512-eUxrowp4F1QEGk/i7Sa+Xl8Crlfp7J0AXxX1QdJEQKQYMWhgMbCIgyQvpO3Q0P9oyTrNQxRLlRipDS44a8EtRw==", + "hasInstallScript": true, "license": "MIT", "optional": true, "dependencies": { @@ -4645,6 +5829,9 @@ }, "node_modules/tree-sitter-yaml": { "version": "0.5.0", + "resolved": "https://registry.npmjs.org/tree-sitter-yaml/-/tree-sitter-yaml-0.5.0.tgz", + "integrity": "sha512-POJ4ZNXXSWIG/W4Rjuyg36MkUD4d769YRUGKRqN+sVaj/VCo6Dh6Pkssn1Rtewd5kybx+jT1BWMyWN0CijXnMA==", + "hasInstallScript": true, "license": "MIT", "optional": true, "dependencies": { @@ -4653,6 +5840,8 @@ }, "node_modules/ts-api-utils": { "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, "license": "MIT", "engines": { @@ -4664,18 +5853,26 @@ }, "node_modules/ts-mixer": { "version": "6.0.4", + "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz", + "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==", "license": "MIT" }, "node_modules/ts-toolbelt": { "version": "9.6.0", + "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz", + "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==", "license": "Apache-2.0" }, "node_modules/tslib": { "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", "license": "0BSD" }, "node_modules/tunnel-agent": { "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -4687,6 +5884,8 @@ }, "node_modules/type-check": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "license": "MIT", "dependencies": { @@ -4698,6 +5897,8 @@ }, "node_modules/type-fest": { "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -4708,6 +5909,8 @@ }, "node_modules/types-ramda": { "version": "0.30.1", + "resolved": "https://registry.npmjs.org/types-ramda/-/types-ramda-0.30.1.tgz", + "integrity": "sha512-1HTsf5/QVRmLzcGfldPFvkVsAdi1db1BBKzi7iW3KBUlOICg/nKnFS+jGqDJS3YD8VsWbAh7JiHeBvbsw8RPxA==", "license": "MIT", "dependencies": { "ts-toolbelt": "^9.6.0" @@ -4715,6 +5918,8 @@ }, "node_modules/typescript": { "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, "license": "Apache-2.0", "bin": { @@ -4728,14 +5933,19 @@ "node_modules/uc.micro": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", - "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==" + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "license": "MIT" }, "node_modules/unraw": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unraw/-/unraw-3.0.0.tgz", + "integrity": "sha512-08/DA66UF65OlpUDIQtbJyrqTR0jTAlJ+jsnkQ4jxR7+K5g5YG1APZKQSMCE1vqqmD+2pv6+IdEjmopFatacvg==", "license": "MIT" }, "node_modules/uri-js": { "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -4744,6 +5954,8 @@ }, "node_modules/url-parse": { "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "license": "MIT", "dependencies": { "querystringify": "^2.1.1", @@ -4754,6 +5966,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz", "integrity": "sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==", + "license": "MIT", "dependencies": { "tslib": "^2.0.0" }, @@ -4774,6 +5987,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", + "license": "MIT", "dependencies": { "detect-node-es": "^1.1.0", "tslib": "^2.0.0" @@ -4793,6 +6007,8 @@ }, "node_modules/use-sync-external-store": { "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", "license": "MIT", "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" @@ -4800,6 +6016,8 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT", "optional": true }, @@ -4808,6 +6026,7 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.2.tgz", "integrity": "sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==", "dev": true, + "license": "MIT", "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.41", @@ -4865,10 +6084,13 @@ "node_modules/vscode-languageserver-types": { "version": "3.17.5", "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", - "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==" + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "license": "MIT" }, "node_modules/web-streams-polyfill": { "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "license": "MIT", "engines": { "node": ">= 8" @@ -4876,11 +6098,15 @@ }, "node_modules/web-tree-sitter": { "version": "0.20.3", + "resolved": "https://registry.npmjs.org/web-tree-sitter/-/web-tree-sitter-0.20.3.tgz", + "integrity": "sha512-zKGJW9r23y3BcJusbgvnOH2OYAW40MXAOi9bi3Gcc7T4Gms9WWgXF8m6adsJWpGJEhgOzCrfiz1IzKowJWrtYw==", "license": "MIT", "optional": true }, "node_modules/which": { "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "license": "ISC", "dependencies": { @@ -4895,6 +6121,8 @@ }, "node_modules/word-wrap": { "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "license": "MIT", "engines": { @@ -4903,15 +6131,21 @@ }, "node_modules/wrappy": { "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "license": "ISC", "optional": true }, "node_modules/xml": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", + "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==", "license": "MIT" }, "node_modules/xml-but-prettier": { "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml-but-prettier/-/xml-but-prettier-1.0.1.tgz", + "integrity": "sha512-C2CJaadHrZTqESlH03WOyw0oZTtoy2uEg6dSDF6YRg+9GnYNub53RRemLpnvtbHDFelxMx4LajiFsYeR6XJHgQ==", "license": "MIT", "dependencies": { "repeat-string": "^1.5.2" @@ -4919,6 +6153,8 @@ }, "node_modules/xtend": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "license": "MIT", "engines": { "node": ">=0.4" @@ -4926,6 +6162,8 @@ }, "node_modules/yocto-queue": { "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "license": "MIT", "engines": { @@ -4937,6 +6175,8 @@ }, "node_modules/zenscroll": { "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zenscroll/-/zenscroll-4.0.2.tgz", + "integrity": "sha512-jEA1znR7b4C/NnaycInCU6h/d15ZzCd1jmsruqOKnZP6WXQSMH3W2GL+OXbkruslU4h+Tzuos0HdswzRUk/Vgg==", "license": "Unlicense" } } diff --git a/tools/defradb.containerfile b/tools/defradb.containerfile index ed056ec572..37b2275839 100644 --- a/tools/defradb.containerfile +++ b/tools/defradb.containerfile @@ -2,21 +2,21 @@ # An image to run defradb. -# Stage: PLAYGROUND_BUILD -FROM docker.io/node:20 AS PLAYGROUND_BUILD +# Stage: playground_build +FROM docker.io/node:20 AS playground_build WORKDIR /repo/ COPY playground/ ./ RUN npm install --legacy-peer-deps RUN npm run build -# Stage: BUILD +# Stage: build # Several steps are involved to enable caching and because of the behavior of COPY regarding directories. -FROM docker.io/golang:1.21 AS BUILD +FROM docker.io/golang:1.21 AS build WORKDIR /repo/ COPY go.mod go.sum Makefile ./ RUN make deps:modules COPY . . -COPY --from=PLAYGROUND_BUILD /repo/dist /repo/playground/dist/ +COPY --from=playground_build /repo/dist /repo/playground/dist/ ENV BUILD_TAGS=playground # manually copy libwasmer.so to fix linking issue https://github.com/wasmerio/wasmer-go/issues/281 RUN export WASMER_ARCH=$(go env GOHOSTARCH | sed "s/arm64/aarch64/") && \ @@ -26,8 +26,8 @@ RUN make build # Stage: RUN FROM debian:bookworm-slim -COPY --from=BUILD /repo/build/defradb /defradb -COPY --from=BUILD /lib/libwasmer.so /lib/libwasmer.so +COPY --from=build /repo/build/defradb /defradb +COPY --from=build /lib/libwasmer.so /lib/libwasmer.so # Documents which ports are normally used. # To publish the ports: `docker run -p 9181:9181` ... diff --git a/tools/goreleaser.containerfile b/tools/goreleaser.containerfile deleted file mode 100644 index d8a8af4e6b..0000000000 --- a/tools/goreleaser.containerfile +++ /dev/null @@ -1,17 +0,0 @@ -# syntax=docker/dockerfile:1 - -# An image to run defradb. - -# Stage: RUN -FROM debian:bookworm-slim -COPY defradb /defradb - -# Documents which ports are normally used. -# To publish the ports: `docker run -p 9181:9181` ... -EXPOSE 9161 -EXPOSE 9171 -EXPOSE 9181 - -# Default command provided for convenience. -# e.g. docker run -p 9181:9181 source/defradb start --url 0.0.0.0:9181 -ENTRYPOINT [ "/defradb" ] From f9e3be636c111357052b44ccc3f7363022d162f0 Mon Sep 17 00:00:00 2001 From: Fred Carle Date: Fri, 23 Aug 2024 14:27:06 -0400 Subject: [PATCH 41/41] Release v0.13.0 --- CHANGELOG copy.md | 1170 --------------------------------------------- CHANGELOG.md | 61 +++ licenses/BSL.txt | 4 +- 3 files changed, 63 insertions(+), 1172 deletions(-) delete mode 100644 CHANGELOG copy.md diff --git a/CHANGELOG copy.md b/CHANGELOG copy.md deleted file mode 100644 index 7345a58cc8..0000000000 --- a/CHANGELOG copy.md +++ /dev/null @@ -1,1170 +0,0 @@ - - -## [v0.11.0](https://github.com/sourcenetwork/defradb/compare/v0.10.0...v0.11.0) - -> 2024-05-03 - -DefraDB v0.11 is a major pre-production release. Until the stable version 1.0 is reached, the SemVer minor patch number will denote notable releases, which will give the project freedom to experiment and explore potentially breaking changes. - -To get a full outline of the changes, we invite you to review the official changelog below. This release does include a Breaking Change to existing v0.10.x databases. If you need help migrating an existing deployment, reach out at [hello@source.network](mailto:hello@source.network) or join our Discord at https://discord.gg/w7jYQVJ/. - -### Features - -* Update corelog to 0.0.7 ([#2547](https://github.com/sourcenetwork/defradb/issues/2547)) -* Move relation field properties onto collection ([#2529](https://github.com/sourcenetwork/defradb/issues/2529)) -* Lens runtime config ([#2497](https://github.com/sourcenetwork/defradb/issues/2497)) -* Add P Counter CRDT ([#2482](https://github.com/sourcenetwork/defradb/issues/2482)) -* Add Access Control Policy ([#2338](https://github.com/sourcenetwork/defradb/issues/2338)) -* Force explicit primary decl. in SDL for one-ones ([#2462](https://github.com/sourcenetwork/defradb/issues/2462)) -* Allow mutation of col sources via PatchCollection ([#2424](https://github.com/sourcenetwork/defradb/issues/2424)) -* Add Defra-Lens support for branching schema ([#2421](https://github.com/sourcenetwork/defradb/issues/2421)) -* Add PatchCollection ([#2402](https://github.com/sourcenetwork/defradb/issues/2402)) - -### Fixes - -* Return correct results from one-many indexed filter ([#2579](https://github.com/sourcenetwork/defradb/issues/2579)) -* Handle compound filters on related indexed fields ([#2575](https://github.com/sourcenetwork/defradb/issues/2575)) -* Add check to filter result for logical ops ([#2573](https://github.com/sourcenetwork/defradb/issues/2573)) -* Make all array kinds nillable ([#2534](https://github.com/sourcenetwork/defradb/issues/2534)) -* Allow update when updating non-indexed field ([#2511](https://github.com/sourcenetwork/defradb/issues/2511)) - -### Documentation - -* Add data definition document ([#2544](https://github.com/sourcenetwork/defradb/issues/2544)) - -### Refactoring - -* Merge collection UpdateWith and DeleteWith ([#2531](https://github.com/sourcenetwork/defradb/issues/2531)) -* DB transactions context ([#2513](https://github.com/sourcenetwork/defradb/issues/2513)) -* Add NormalValue ([#2404](https://github.com/sourcenetwork/defradb/issues/2404)) -* Clean up client/request package ([#2443](https://github.com/sourcenetwork/defradb/issues/2443)) -* Rewrite convertImmutable ([#2445](https://github.com/sourcenetwork/defradb/issues/2445)) -* Unify Field Kind and Schema properties ([#2414](https://github.com/sourcenetwork/defradb/issues/2414)) -* Replace logging package with corelog ([#2406](https://github.com/sourcenetwork/defradb/issues/2406)) - -### Testing - -* Add flag to skip network tests ([#2495](https://github.com/sourcenetwork/defradb/issues/2495)) - -### Bot - -* Update dependencies (bulk dependabot PRs) 30-04-2024 ([#2570](https://github.com/sourcenetwork/defradb/issues/2570)) -* Bump [@typescript](https://github.com/typescript)-eslint/parser from 7.7.0 to 7.7.1 in /playground ([#2550](https://github.com/sourcenetwork/defradb/issues/2550)) -* Bump [@typescript](https://github.com/typescript)-eslint/eslint-plugin from 7.7.0 to 7.7.1 in /playground ([#2551](https://github.com/sourcenetwork/defradb/issues/2551)) -* Bump swagger-ui-react from 5.16.2 to 5.17.0 in /playground ([#2549](https://github.com/sourcenetwork/defradb/issues/2549)) -* Update dependencies (bulk dependabot PRs) 23-04-2023 ([#2548](https://github.com/sourcenetwork/defradb/issues/2548)) -* Bump go.opentelemetry.io/otel/sdk/metric from 1.24.0 to 1.25.0 ([#2499](https://github.com/sourcenetwork/defradb/issues/2499)) -* Bump typescript from 5.4.3 to 5.4.5 in /playground ([#2515](https://github.com/sourcenetwork/defradb/issues/2515)) -* Bump swagger-ui-react from 5.14.0 to 5.15.0 in /playground ([#2514](https://github.com/sourcenetwork/defradb/issues/2514)) -* Update dependencies (bulk dependabot PRs) 2024-04-09 ([#2509](https://github.com/sourcenetwork/defradb/issues/2509)) -* Update dependencies (bulk dependabot PRs) 2024-04-03 ([#2492](https://github.com/sourcenetwork/defradb/issues/2492)) -* Update dependencies (bulk dependabot PRs) 03-04-2024 ([#2486](https://github.com/sourcenetwork/defradb/issues/2486)) -* Bump github.com/multiformats/go-multiaddr from 0.12.2 to 0.12.3 ([#2480](https://github.com/sourcenetwork/defradb/issues/2480)) -* Bump [@types](https://github.com/types)/react from 18.2.66 to 18.2.67 in /playground ([#2427](https://github.com/sourcenetwork/defradb/issues/2427)) -* Bump [@typescript](https://github.com/typescript)-eslint/parser from 7.2.0 to 7.3.1 in /playground ([#2428](https://github.com/sourcenetwork/defradb/issues/2428)) -* Update dependencies (bulk dependabot PRs) 19-03-2024 ([#2426](https://github.com/sourcenetwork/defradb/issues/2426)) -* Update dependencies (bulk dependabot PRs) 03-11-2024 ([#2399](https://github.com/sourcenetwork/defradb/issues/2399)) - - -## [v0.10.0](https://github.com/sourcenetwork/defradb/compare/v0.9.0...v0.10.0) - -> 2024-03-08 - -DefraDB v0.10 is a major pre-production release. Until the stable version 1.0 is reached, the SemVer minor patch number will denote notable releases, which will give the project freedom to experiment and explore potentially breaking changes. - -To get a full outline of the changes, we invite you to review the official changelog below. This release does include a Breaking Change to existing v0.9.x databases. If you need help migrating an existing deployment, reach out at [hello@source.network](mailto:hello@source.network) or join our Discord at https://discord.gg/w7jYQVJ/. - -### Features - -* Add case insensitive `like` operator ([#2368](https://github.com/sourcenetwork/defradb/issues/2368)) -* Reverted order for indexed fields ([#2335](https://github.com/sourcenetwork/defradb/issues/2335)) -* Rework GetCollection/SchemaByFoo funcs into single ([#2319](https://github.com/sourcenetwork/defradb/issues/2319)) -* Add support for views with Lens transforms ([#2311](https://github.com/sourcenetwork/defradb/issues/2311)) -* Model Col. SchemaVersions and migrations on Cols ([#2286](https://github.com/sourcenetwork/defradb/issues/2286)) -* Replace FieldDescription.RelationType with IsPrimary ([#2288](https://github.com/sourcenetwork/defradb/issues/2288)) -* Multiple docs with nil value on unique-indexed field ([#2276](https://github.com/sourcenetwork/defradb/issues/2276)) -* Allow setting null values on doc fields ([#2273](https://github.com/sourcenetwork/defradb/issues/2273)) -* Add JSON scalar ([#2254](https://github.com/sourcenetwork/defradb/issues/2254)) -* Generate OpenAPI command ([#2235](https://github.com/sourcenetwork/defradb/issues/2235)) -* Add composite indexes ([#2226](https://github.com/sourcenetwork/defradb/issues/2226)) - -### Fixes - -* Add `latest` image tag for ghcr ([#2340](https://github.com/sourcenetwork/defradb/issues/2340)) -* Move field id off of schema ([#2336](https://github.com/sourcenetwork/defradb/issues/2336)) -* Make returned collections respect explicit transactions ([#2385](https://github.com/sourcenetwork/defradb/issues/2385)) -* Update GetCollections behaviour ([#2378](https://github.com/sourcenetwork/defradb/issues/2378)) -* Add missing directive definitions ([#2369](https://github.com/sourcenetwork/defradb/issues/2369)) -* Add validation to JSON fields ([#2375](https://github.com/sourcenetwork/defradb/issues/2375)) -* Make peers sync secondary index ([#2390](https://github.com/sourcenetwork/defradb/issues/2390)) -* Load root dir before loading config ([#2266](https://github.com/sourcenetwork/defradb/issues/2266)) -* Mark docs as deleted when querying in delete mut ([#2298](https://github.com/sourcenetwork/defradb/issues/2298)) -* Add missing logs at startup ([#2391](https://github.com/sourcenetwork/defradb/issues/2391)) -* Add missing delta payload ([#2306](https://github.com/sourcenetwork/defradb/issues/2306)) -* Fix compound relational filters in aggregates ([#2297](https://github.com/sourcenetwork/defradb/issues/2297)) - -### Refactoring - -* Generate field ids using a sequence ([#2339](https://github.com/sourcenetwork/defradb/issues/2339)) -* Make config internal to CLI ([#2310](https://github.com/sourcenetwork/defradb/issues/2310)) -* Node config ([#2296](https://github.com/sourcenetwork/defradb/issues/2296)) -* HTTP config ([#2278](https://github.com/sourcenetwork/defradb/issues/2278)) -* Remove unused Delete field from client.Document ([#2275](https://github.com/sourcenetwork/defradb/issues/2275)) -* Decouple net config ([#2258](https://github.com/sourcenetwork/defradb/issues/2258)) -* Make CollectionDescription.Name Option ([#2223](https://github.com/sourcenetwork/defradb/issues/2223)) - -### Chore - -* Bump to GoLang v1.21 ([#2195](https://github.com/sourcenetwork/defradb/issues/2195)) - -### Bot - -* Update dependencies (bulk dependabot PRs) 05-02-2024 ([#2372](https://github.com/sourcenetwork/defradb/issues/2372)) -* Update dependencies (bulk dependabot PRs) 02-27-2024 ([#2353](https://github.com/sourcenetwork/defradb/issues/2353)) -* Bump [@typescript](https://github.com/typescript)-eslint/eslint-plugin from 6.21.0 to 7.0.1 in /playground ([#2331](https://github.com/sourcenetwork/defradb/issues/2331)) -* Bump google.golang.org/grpc from 1.61.0 to 1.61.1 ([#2320](https://github.com/sourcenetwork/defradb/issues/2320)) -* Update dependencies (bulk dependabot PRs) 2024-02-19 ([#2330](https://github.com/sourcenetwork/defradb/issues/2330)) -* Bump vite from 5.1.1 to 5.1.2 in /playground ([#2317](https://github.com/sourcenetwork/defradb/issues/2317)) -* Bump golang.org/x/net from 0.20.0 to 0.21.0 ([#2301](https://github.com/sourcenetwork/defradb/issues/2301)) -* Update dependencies (bulk dependabot PRs) 2023-02-14 ([#2313](https://github.com/sourcenetwork/defradb/issues/2313)) -* Update dependencies (bulk dependabot PRs) 02-07-2024 ([#2294](https://github.com/sourcenetwork/defradb/issues/2294)) -* Update dependencies (bulk dependabot PRs) 30-01-2024 ([#2270](https://github.com/sourcenetwork/defradb/issues/2270)) -* Update dependencies (bulk dependabot PRs) 23-01-2024 ([#2252](https://github.com/sourcenetwork/defradb/issues/2252)) -* Bump vite from 5.0.11 to 5.0.12 in /playground ([#2236](https://github.com/sourcenetwork/defradb/issues/2236)) -* Bump github.com/evanphx/json-patch/v5 from 5.7.0 to 5.8.1 ([#2233](https://github.com/sourcenetwork/defradb/issues/2233)) - - -## [v0.9.0](https://github.com/sourcenetwork/defradb/compare/v0.8.0...v0.9.0) - -> 2024-01-18 - -DefraDB v0.9 is a major pre-production release. Until the stable version 1.0 is reached, the SemVer minor patch number will denote notable releases, which will give the project freedom to experiment and explore potentially breaking changes. - -To get a full outline of the changes, we invite you to review the official changelog below. This release does include a Breaking Change to existing v0.8.x databases. If you need help migrating an existing deployment, reach out at [hello@source.network](mailto:hello@source.network) or join our Discord at https://discord.gg/w7jYQVJ/. - -### Features - -* Mutation typed input ([#2167](https://github.com/sourcenetwork/defradb/issues/2167)) -* Add PN Counter CRDT type ([#2119](https://github.com/sourcenetwork/defradb/issues/2119)) -* Allow users to add Views ([#2114](https://github.com/sourcenetwork/defradb/issues/2114)) -* Add unique secondary index ([#2131](https://github.com/sourcenetwork/defradb/issues/2131)) -* New cmd for docs auto generation ([#2096](https://github.com/sourcenetwork/defradb/issues/2096)) -* Add blob scalar type ([#2091](https://github.com/sourcenetwork/defradb/issues/2091)) - -### Fixes - -* Add entropy to counter CRDT type updates ([#2186](https://github.com/sourcenetwork/defradb/issues/2186)) -* Handle multiple nil values on unique indexed fields ([#2178](https://github.com/sourcenetwork/defradb/issues/2178)) -* Filtering on unique index if there is no match ([#2177](https://github.com/sourcenetwork/defradb/issues/2177)) - -### Performance - -* Switch LensVM to wasmtime runtime ([#2030](https://github.com/sourcenetwork/defradb/issues/2030)) - -### Refactoring - -* Add strong typing to document creation ([#2161](https://github.com/sourcenetwork/defradb/issues/2161)) -* Rename key,id,dockey to docID terminology ([#1749](https://github.com/sourcenetwork/defradb/issues/1749)) -* Simplify Merkle CRDT workflow ([#2111](https://github.com/sourcenetwork/defradb/issues/2111)) - -### Testing - -* Add auto-doc generation ([#2051](https://github.com/sourcenetwork/defradb/issues/2051)) - -### Continuous integration - -* Add windows test runner ([#2033](https://github.com/sourcenetwork/defradb/issues/2033)) - -### Chore - -* Update Lens to v0.5 ([#2083](https://github.com/sourcenetwork/defradb/issues/2083)) - -### Bot - -* Bump [@types](https://github.com/types)/react from 18.2.47 to 18.2.48 in /playground ([#2213](https://github.com/sourcenetwork/defradb/issues/2213)) -* Bump [@typescript](https://github.com/typescript)-eslint/eslint-plugin from 6.18.0 to 6.18.1 in /playground ([#2215](https://github.com/sourcenetwork/defradb/issues/2215)) -* Update dependencies (bulk dependabot PRs) 15-01-2024 ([#2217](https://github.com/sourcenetwork/defradb/issues/2217)) -* Bump follow-redirects from 1.15.3 to 1.15.4 in /playground ([#2181](https://github.com/sourcenetwork/defradb/issues/2181)) -* Bump github.com/getkin/kin-openapi from 0.120.0 to 0.122.0 ([#2097](https://github.com/sourcenetwork/defradb/issues/2097)) -* Update dependencies (bulk dependabot PRs) 08-01-2024 ([#2173](https://github.com/sourcenetwork/defradb/issues/2173)) -* Bump github.com/bits-and-blooms/bitset from 1.12.0 to 1.13.0 ([#2160](https://github.com/sourcenetwork/defradb/issues/2160)) -* Bump [@types](https://github.com/types)/react from 18.2.45 to 18.2.46 in /playground ([#2159](https://github.com/sourcenetwork/defradb/issues/2159)) -* Bump [@typescript](https://github.com/typescript)-eslint/parser from 6.15.0 to 6.16.0 in /playground ([#2156](https://github.com/sourcenetwork/defradb/issues/2156)) -* Bump [@typescript](https://github.com/typescript)-eslint/eslint-plugin from 6.15.0 to 6.16.0 in /playground ([#2155](https://github.com/sourcenetwork/defradb/issues/2155)) -* Update dependencies (bulk dependabot PRs) 27-12-2023 ([#2154](https://github.com/sourcenetwork/defradb/issues/2154)) -* Bump github.com/spf13/viper from 1.17.0 to 1.18.2 ([#2145](https://github.com/sourcenetwork/defradb/issues/2145)) -* Bump golang.org/x/crypto from 0.16.0 to 0.17.0 ([#2144](https://github.com/sourcenetwork/defradb/issues/2144)) -* Update dependencies (bulk dependabot PRs) 18-12-2023 ([#2142](https://github.com/sourcenetwork/defradb/issues/2142)) -* Bump [@typescript](https://github.com/typescript)-eslint/parser from 6.13.2 to 6.14.0 in /playground ([#2136](https://github.com/sourcenetwork/defradb/issues/2136)) -* Bump [@types](https://github.com/types)/react from 18.2.43 to 18.2.45 in /playground ([#2134](https://github.com/sourcenetwork/defradb/issues/2134)) -* Bump vite from 5.0.7 to 5.0.10 in /playground ([#2135](https://github.com/sourcenetwork/defradb/issues/2135)) -* Update dependencies (bulk dependabot PRs) 04-12-2023 ([#2133](https://github.com/sourcenetwork/defradb/issues/2133)) -* Bump [@typescript](https://github.com/typescript)-eslint/eslint-plugin from 6.13.1 to 6.13.2 in /playground ([#2109](https://github.com/sourcenetwork/defradb/issues/2109)) -* Bump vite from 5.0.2 to 5.0.5 in /playground ([#2112](https://github.com/sourcenetwork/defradb/issues/2112)) -* Bump [@types](https://github.com/types)/react from 18.2.41 to 18.2.42 in /playground ([#2108](https://github.com/sourcenetwork/defradb/issues/2108)) -* Update dependencies (bulk dependabot PRs) 04-12-2023 ([#2107](https://github.com/sourcenetwork/defradb/issues/2107)) -* Bump [@types](https://github.com/types)/react from 18.2.38 to 18.2.39 in /playground ([#2086](https://github.com/sourcenetwork/defradb/issues/2086)) -* Bump [@typescript](https://github.com/typescript)-eslint/parser from 6.12.0 to 6.13.0 in /playground ([#2085](https://github.com/sourcenetwork/defradb/issues/2085)) -* Update dependencies (bulk dependabot PRs) 27-11-2023 ([#2081](https://github.com/sourcenetwork/defradb/issues/2081)) -* Bump swagger-ui-react from 5.10.0 to 5.10.3 in /playground ([#2067](https://github.com/sourcenetwork/defradb/issues/2067)) -* Bump [@typescript](https://github.com/typescript)-eslint/eslint-plugin from 6.11.0 to 6.12.0 in /playground ([#2068](https://github.com/sourcenetwork/defradb/issues/2068)) -* Update dependencies (bulk dependabot PRs) 20-11-2023 ([#2066](https://github.com/sourcenetwork/defradb/issues/2066)) - - -## [v0.8.0](https://github.com/sourcenetwork/defradb/compare/v0.7.0...v0.8.0) - -> 2023-11-14 - -DefraDB v0.8 is a major pre-production release. Until the stable version 1.0 is reached, the SemVer minor patch number will denote notable releases, which will give the project freedom to experiment and explore potentially breaking changes. - -To get a full outline of the changes, we invite you to review the official changelog below. This release does include a Breaking Change to existing v0.7.x databases. If you need help migrating an existing deployment, reach out at [hello@source.network](mailto:hello@source.network) or join our Discord at https://discord.gg/w7jYQVJ/. - -### Features - -* Add means to fetch schema ([#2006](https://github.com/sourcenetwork/defradb/issues/2006)) -* Rename Schema.SchemaID to Schema.Root ([#2005](https://github.com/sourcenetwork/defradb/issues/2005)) -* Enable playground in Docker build ([#1986](https://github.com/sourcenetwork/defradb/issues/1986)) -* Change GetCollectionBySchemaFoo funcs to return many ([#1984](https://github.com/sourcenetwork/defradb/issues/1984)) -* Add Swagger UI to playground ([#1979](https://github.com/sourcenetwork/defradb/issues/1979)) -* Add OpenAPI route ([#1960](https://github.com/sourcenetwork/defradb/issues/1960)) -* Remove CollectionDescription.Schema ([#1965](https://github.com/sourcenetwork/defradb/issues/1965)) -* Remove collection from patch schema ([#1957](https://github.com/sourcenetwork/defradb/issues/1957)) -* Make queries utilise secondary indexes ([#1925](https://github.com/sourcenetwork/defradb/issues/1925)) -* Allow setting of default schema version ([#1888](https://github.com/sourcenetwork/defradb/issues/1888)) -* Add CCIP Support ([#1896](https://github.com/sourcenetwork/defradb/issues/1896)) - -### Fixes - -* Fix test module relying on closed memory leak ([#2037](https://github.com/sourcenetwork/defradb/issues/2037)) -* Make return type for FieldKind_INT an int64 ([#1982](https://github.com/sourcenetwork/defradb/issues/1982)) -* Node private key requires data directory ([#1938](https://github.com/sourcenetwork/defradb/issues/1938)) -* Remove collection name from schema ID generation ([#1920](https://github.com/sourcenetwork/defradb/issues/1920)) -* Infinite loop when updating one-one relation ([#1915](https://github.com/sourcenetwork/defradb/issues/1915)) - -### Refactoring - -* CRDT merge direction ([#2016](https://github.com/sourcenetwork/defradb/issues/2016)) -* Reorganise collection description storage ([#1988](https://github.com/sourcenetwork/defradb/issues/1988)) -* Add peerstore to multistore ([#1980](https://github.com/sourcenetwork/defradb/issues/1980)) -* P2P client interface ([#1924](https://github.com/sourcenetwork/defradb/issues/1924)) -* Deprecate CollectionDescription.Schema ([#1939](https://github.com/sourcenetwork/defradb/issues/1939)) -* Remove net GRPC API ([#1927](https://github.com/sourcenetwork/defradb/issues/1927)) -* CLI client interface ([#1839](https://github.com/sourcenetwork/defradb/issues/1839)) - -### Continuous integration - -* Add goreleaser workflow ([#2040](https://github.com/sourcenetwork/defradb/issues/2040)) -* Add mac test runner ([#2035](https://github.com/sourcenetwork/defradb/issues/2035)) -* Parallelize change detector ([#1871](https://github.com/sourcenetwork/defradb/issues/1871)) - -### Chore - -* Update dependencies ([#2044](https://github.com/sourcenetwork/defradb/issues/2044)) - -### Bot - -* Bump [@typescript](https://github.com/typescript)-eslint/parser from 6.10.0 to 6.11.0 in /playground ([#2053](https://github.com/sourcenetwork/defradb/issues/2053)) -* Update dependencies (bulk dependabot PRs) 13-11-2023 ([#2052](https://github.com/sourcenetwork/defradb/issues/2052)) -* Bump axios from 1.5.1 to 1.6.1 in /playground ([#2041](https://github.com/sourcenetwork/defradb/issues/2041)) -* Bump [@typescript](https://github.com/typescript)-eslint/eslint-plugin from 6.9.1 to 6.10.0 in /playground ([#2042](https://github.com/sourcenetwork/defradb/issues/2042)) -* Bump [@vitejs](https://github.com/vitejs)/plugin-react-swc from 3.4.0 to 3.4.1 in /playground ([#2022](https://github.com/sourcenetwork/defradb/issues/2022)) -* Update dependencies (bulk dependabot PRs) 08-11-2023 ([#2038](https://github.com/sourcenetwork/defradb/issues/2038)) -* Update dependencies (bulk dependabot PRs) 30-10-2023 ([#2015](https://github.com/sourcenetwork/defradb/issues/2015)) -* Bump eslint-plugin and parser from 6.8.0 to 6.9.0 in /playground ([#2000](https://github.com/sourcenetwork/defradb/issues/2000)) -* Update dependencies (bulk dependabot PRs) 16-10-2023 ([#1998](https://github.com/sourcenetwork/defradb/issues/1998)) -* Update dependencies (bulk dependabot PRs) 16-10-2023 ([#1976](https://github.com/sourcenetwork/defradb/issues/1976)) -* Bump golang.org/x/net from 0.16.0 to 0.17.0 ([#1961](https://github.com/sourcenetwork/defradb/issues/1961)) -* Bump [@types](https://github.com/types)/react-dom from 18.2.11 to 18.2.12 in /playground ([#1952](https://github.com/sourcenetwork/defradb/issues/1952)) -* Bump [@typescript](https://github.com/typescript)-eslint/eslint-plugin from 6.7.4 to 6.7.5 in /playground ([#1953](https://github.com/sourcenetwork/defradb/issues/1953)) -* Bump combined dependencies 09-10-2023 ([#1951](https://github.com/sourcenetwork/defradb/issues/1951)) -* Bump [@types](https://github.com/types)/react from 18.2.24 to 18.2.25 in /playground ([#1932](https://github.com/sourcenetwork/defradb/issues/1932)) -* Bump [@typescript](https://github.com/typescript)-eslint/parser from 6.7.3 to 6.7.4 in /playground ([#1933](https://github.com/sourcenetwork/defradb/issues/1933)) -* Bump [@vitejs](https://github.com/vitejs)/plugin-react-swc from 3.3.2 to 3.4.0 in /playground ([#1904](https://github.com/sourcenetwork/defradb/issues/1904)) -* Bump combined dependencies 19-09-2023 ([#1931](https://github.com/sourcenetwork/defradb/issues/1931)) -* Bump graphql from 16.8.0 to 16.8.1 in /playground ([#1901](https://github.com/sourcenetwork/defradb/issues/1901)) -* Update combined dependabot PRs 19-09-2023 ([#1898](https://github.com/sourcenetwork/defradb/issues/1898)) - - -## [v0.7.0](https://github.com/sourcenetwork/defradb/compare/v0.6.0...v0.7.0) - -> 2023-09-18 - -DefraDB v0.7 is a major pre-production release. Until the stable version 1.0 is reached, the SemVer minor patch number will denote notable releases, which will give the project freedom to experiment and explore potentially breaking changes. - -This release has focused on robustness, testing, and schema management. Some highlight new features include notable expansions to the expressiveness of schema migrations. - -To get a full outline of the changes, we invite you to review the official changelog below. This release does include a Breaking Change to existing v0.6.x databases. If you need help migrating an existing deployment, reach out at [hello@source.network](mailto:hello@source.network) or join our Discord at https://discord.gg/w7jYQVJ/. - -### Features - -* Allow field indexing by name in PatchSchema ([#1810](https://github.com/sourcenetwork/defradb/issues/1810)) -* Auto-create relation id fields via PatchSchema ([#1807](https://github.com/sourcenetwork/defradb/issues/1807)) -* Support PatchSchema relational field kind substitution ([#1777](https://github.com/sourcenetwork/defradb/issues/1777)) -* Add support for adding of relational fields ([#1766](https://github.com/sourcenetwork/defradb/issues/1766)) -* Enable downgrading of documents via Lens inverses ([#1721](https://github.com/sourcenetwork/defradb/issues/1721)) - -### Fixes - -* Correctly handle serialisation of nil field values ([#1872](https://github.com/sourcenetwork/defradb/issues/1872)) -* Compound filter operators with relations ([#1855](https://github.com/sourcenetwork/defradb/issues/1855)) -* Only update updated fields via update requests ([#1817](https://github.com/sourcenetwork/defradb/issues/1817)) -* Error when saving a deleted document ([#1806](https://github.com/sourcenetwork/defradb/issues/1806)) -* Prevent multiple docs from being linked in one one ([#1790](https://github.com/sourcenetwork/defradb/issues/1790)) -* Handle the querying of secondary relation id fields ([#1768](https://github.com/sourcenetwork/defradb/issues/1768)) -* Improve the way migrations handle transactions ([#1737](https://github.com/sourcenetwork/defradb/issues/1737)) - -### Tooling - -* Add Akash deployment configuration ([#1736](https://github.com/sourcenetwork/defradb/issues/1736)) - -### Refactoring - -* HTTP client interface ([#1776](https://github.com/sourcenetwork/defradb/issues/1776)) -* Simplify fetcher interface ([#1746](https://github.com/sourcenetwork/defradb/issues/1746)) - -### Testing - -* Convert and move out of place explain tests ([#1878](https://github.com/sourcenetwork/defradb/issues/1878)) -* Update mutation tests to make use of mutation system ([#1853](https://github.com/sourcenetwork/defradb/issues/1853)) -* Test top level agg. with compound relational filter ([#1870](https://github.com/sourcenetwork/defradb/issues/1870)) -* Skip unsupported mutation types at test level ([#1850](https://github.com/sourcenetwork/defradb/issues/1850)) -* Extend mutation tests with col.Update and Create ([#1838](https://github.com/sourcenetwork/defradb/issues/1838)) -* Add tests for multiple one-one joins ([#1793](https://github.com/sourcenetwork/defradb/issues/1793)) - -### Chore - -* Update Badger version to v4 ([#1740](https://github.com/sourcenetwork/defradb/issues/1740)) -* Update go-libp2p to 0.29.2 ([#1780](https://github.com/sourcenetwork/defradb/issues/1780)) -* Bump golangci-lint to v1.54 ([#1881](https://github.com/sourcenetwork/defradb/issues/1881)) -* Bump go.opentelemetry.io/otel/metric from 1.17.0 to 1.18.0 ([#1890](https://github.com/sourcenetwork/defradb/issues/1890)) -* Bump [@tanstack](https://github.com/tanstack)/react-query from 4.35.0 to 4.35.3 in /playground ([#1876](https://github.com/sourcenetwork/defradb/issues/1876)) -* Bump [@typescript](https://github.com/typescript)-eslint/eslint-plugin from 6.5.0 to 6.7.0 in /playground ([#1874](https://github.com/sourcenetwork/defradb/issues/1874)) -* Bump [@typescript](https://github.com/typescript)-eslint/parser from 6.6.0 to 6.7.0 in /playground ([#1875](https://github.com/sourcenetwork/defradb/issues/1875)) -* Combined PRs 2023-09-14 ([#1873](https://github.com/sourcenetwork/defradb/issues/1873)) -* Bump [@typescript](https://github.com/typescript)-eslint/eslint-plugin from 6.4.0 to 6.5.0 in /playground ([#1827](https://github.com/sourcenetwork/defradb/issues/1827)) -* Bump go.opentelemetry.io/otel/sdk/metric from 0.39.0 to 0.40.0 ([#1829](https://github.com/sourcenetwork/defradb/issues/1829)) -* Bump github.com/ipfs/go-block-format from 0.1.2 to 0.2.0 ([#1819](https://github.com/sourcenetwork/defradb/issues/1819)) -* Combined PRs ([#1826](https://github.com/sourcenetwork/defradb/issues/1826)) -* Bump [@typescript](https://github.com/typescript)-eslint/parser from 6.4.0 to 6.4.1 in /playground ([#1804](https://github.com/sourcenetwork/defradb/issues/1804)) -* Combined PRs ([#1803](https://github.com/sourcenetwork/defradb/issues/1803)) -* Combined PRs ([#1791](https://github.com/sourcenetwork/defradb/issues/1791)) -* Combined PRs ([#1778](https://github.com/sourcenetwork/defradb/issues/1778)) -* Bump dependencies ([#1761](https://github.com/sourcenetwork/defradb/issues/1761)) -* Bump vite from 4.3.9 to 4.4.8 in /playground ([#1748](https://github.com/sourcenetwork/defradb/issues/1748)) -* Bump graphiql from 3.0.4 to 3.0.5 in /playground ([#1730](https://github.com/sourcenetwork/defradb/issues/1730)) -* Combined bumps of dependencies under /playground ([#1744](https://github.com/sourcenetwork/defradb/issues/1744)) -* Bump github.com/ipfs/boxo from 0.10.2 to 0.11.0 ([#1726](https://github.com/sourcenetwork/defradb/issues/1726)) -* Bump github.com/libp2p/go-libp2p-kad-dht from 0.24.2 to 0.24.3 ([#1724](https://github.com/sourcenetwork/defradb/issues/1724)) -* Bump google.golang.org/grpc from 1.56.2 to 1.57.0 ([#1725](https://github.com/sourcenetwork/defradb/issues/1725)) - - -## [v0.6.0](https://github.com/sourcenetwork/defradb/compare/v0.5.1...v0.6.0) - -> 2023-07-31 - -DefraDB v0.6 is a major pre-production release. Until the stable version 1.0 is reached, the SemVer minor patch number will denote notable releases, which will give the project freedom to experiment and explore potentially breaking changes. - -There are several new and powerful features, important bug fixes, and notable refactors in this release. Some highlight features include: The initial release of our LensVM based schema migration engine powered by WebAssembly ([#1650](https://github.com/sourcenetwork/defradb/issues/1650)), newly embedded DefraDB Playround which includes a bundled GraphQL client and schema manager, and last but not least a relation field (_id) alias to improve the developer experience ([#1609](https://github.com/sourcenetwork/defradb/issues/1609)). - -To get a full outline of the changes, we invite you to review the official changelog below. This release does include a Breaking Change to existing v0.5.x databases. If you need help migrating an existing deployment, reach out at [hello@source.network](mailto:hello@source.network) or join our Discord at https://discord.gg/w7jYQVJ/. - -### Features - -* Add `_not` operator ([#1631](https://github.com/sourcenetwork/defradb/issues/1631)) -* Schema list API ([#1625](https://github.com/sourcenetwork/defradb/issues/1625)) -* Add simple data import and export ([#1630](https://github.com/sourcenetwork/defradb/issues/1630)) -* Playground ([#1575](https://github.com/sourcenetwork/defradb/issues/1575)) -* Add schema migration get and set cmds to CLI ([#1650](https://github.com/sourcenetwork/defradb/issues/1650)) -* Allow relation alias on create and update ([#1609](https://github.com/sourcenetwork/defradb/issues/1609)) -* Make fetcher calculate docFetches and fieldFetches ([#1713](https://github.com/sourcenetwork/defradb/issues/1713)) -* Add lens migration engine to defra ([#1564](https://github.com/sourcenetwork/defradb/issues/1564)) -* Add `_keys` attribute to `selectNode` simple explain ([#1546](https://github.com/sourcenetwork/defradb/issues/1546)) -* CLI commands for secondary indexes ([#1595](https://github.com/sourcenetwork/defradb/issues/1595)) -* Add alias to `groupBy` related object ([#1579](https://github.com/sourcenetwork/defradb/issues/1579)) -* Non-unique secondary index (no querying) ([#1450](https://github.com/sourcenetwork/defradb/issues/1450)) -* Add ability to explain-debug all nodes ([#1563](https://github.com/sourcenetwork/defradb/issues/1563)) -* Include dockey in doc exists err ([#1558](https://github.com/sourcenetwork/defradb/issues/1558)) - -### Fixes - -* Better wait in CLI integration test ([#1415](https://github.com/sourcenetwork/defradb/issues/1415)) -* Return error when relation is not defined on both types ([#1647](https://github.com/sourcenetwork/defradb/issues/1647)) -* Change `core.DocumentMapping` to pointer ([#1528](https://github.com/sourcenetwork/defradb/issues/1528)) -* Fix invalid (badger) datastore state ([#1685](https://github.com/sourcenetwork/defradb/issues/1685)) -* Discard index and subscription implicit transactions ([#1715](https://github.com/sourcenetwork/defradb/issues/1715)) -* Remove duplicated `peers` in peerstore prefix ([#1678](https://github.com/sourcenetwork/defradb/issues/1678)) -* Return errors from typeJoinOne ([#1716](https://github.com/sourcenetwork/defradb/issues/1716)) -* Document change detector breaking change ([#1531](https://github.com/sourcenetwork/defradb/issues/1531)) -* Standardise `schema migration` CLI errors ([#1682](https://github.com/sourcenetwork/defradb/issues/1682)) -* Introspection OrderArg returns null inputFields ([#1633](https://github.com/sourcenetwork/defradb/issues/1633)) -* Avoid duplicated requestable fields ([#1621](https://github.com/sourcenetwork/defradb/issues/1621)) -* Normalize int field kind ([#1619](https://github.com/sourcenetwork/defradb/issues/1619)) -* Change the WriteSyncer to use lock when piping ([#1608](https://github.com/sourcenetwork/defradb/issues/1608)) -* Filter splitting and rendering for related types ([#1541](https://github.com/sourcenetwork/defradb/issues/1541)) - -### Documentation - -* Improve CLI command documentation ([#1505](https://github.com/sourcenetwork/defradb/issues/1505)) - -### Refactoring - -* Schema list output to include schemaVersionID ([#1706](https://github.com/sourcenetwork/defradb/issues/1706)) -* Reuse lens wasm modules ([#1641](https://github.com/sourcenetwork/defradb/issues/1641)) -* Remove redundant txn param from fetcher start ([#1635](https://github.com/sourcenetwork/defradb/issues/1635)) -* Remove first CRDT byte from field encoded values ([#1622](https://github.com/sourcenetwork/defradb/issues/1622)) -* Merge `node` into `net` and improve coverage ([#1593](https://github.com/sourcenetwork/defradb/issues/1593)) -* Fetcher filter and field optimization ([#1500](https://github.com/sourcenetwork/defradb/issues/1500)) - -### Testing - -* Rework transaction test framework capabilities ([#1603](https://github.com/sourcenetwork/defradb/issues/1603)) -* Expand backup integration tests ([#1699](https://github.com/sourcenetwork/defradb/issues/1699)) -* Disable test ([#1675](https://github.com/sourcenetwork/defradb/issues/1675)) -* Add tests for 1-1 group by id ([#1655](https://github.com/sourcenetwork/defradb/issues/1655)) -* Remove CLI tests from make test ([#1643](https://github.com/sourcenetwork/defradb/issues/1643)) -* Bundle test state into single var ([#1645](https://github.com/sourcenetwork/defradb/issues/1645)) -* Convert explain group tests to new explain setup ([#1537](https://github.com/sourcenetwork/defradb/issues/1537)) -* Add tests for foo_id field name clashes ([#1521](https://github.com/sourcenetwork/defradb/issues/1521)) -* Resume wait correctly following test node restart ([#1515](https://github.com/sourcenetwork/defradb/issues/1515)) -* Require no errors when none expected ([#1509](https://github.com/sourcenetwork/defradb/issues/1509)) - -### Continuous integration - -* Add workflows to push, pull, and validate docker images ([#1676](https://github.com/sourcenetwork/defradb/issues/1676)) -* Build mocks using make ([#1612](https://github.com/sourcenetwork/defradb/issues/1612)) -* Fix terraform plan and merge AMI build + deploy workflow ([#1514](https://github.com/sourcenetwork/defradb/issues/1514)) -* Reconfigure CodeCov action to ensure stability ([#1414](https://github.com/sourcenetwork/defradb/issues/1414)) - -### Chore - -* Bump to GoLang v1.20 ([#1689](https://github.com/sourcenetwork/defradb/issues/1689)) -* Update to ipfs boxo 0.10.0 ([#1573](https://github.com/sourcenetwork/defradb/issues/1573)) - - - -## [v0.5.1](https://github.com/sourcenetwork/defradb/compare/v0.5.0...v0.5.1) - -> 2023-05-16 - -### Features - -* Add collection response information on creation ([#1499](https://github.com/sourcenetwork/defradb/issues/1499)) -* CLI client request from file ([#1503](https://github.com/sourcenetwork/defradb/issues/1503)) -* Add commits fieldName and fieldId fields ([#1451](https://github.com/sourcenetwork/defradb/issues/1451)) -* Add allowed origins config ([#1408](https://github.com/sourcenetwork/defradb/issues/1408)) -* Add descriptions to all system defined GQL stuff ([#1387](https://github.com/sourcenetwork/defradb/issues/1387)) -* Strongly type Request.Errors ([#1364](https://github.com/sourcenetwork/defradb/issues/1364)) - -### Fixes - -* Skip new test packages in change detector ([#1495](https://github.com/sourcenetwork/defradb/issues/1495)) -* Make nested joins work correctly from primary direction ([#1491](https://github.com/sourcenetwork/defradb/issues/1491)) -* Add reconnection to known peers ([#1482](https://github.com/sourcenetwork/defradb/issues/1482)) -* Rename commit field input arg to fieldId ([#1460](https://github.com/sourcenetwork/defradb/issues/1460)) -* Reference collectionID in p2p readme ([#1466](https://github.com/sourcenetwork/defradb/issues/1466)) -* Handling SIGTERM in CLI `start` command ([#1459](https://github.com/sourcenetwork/defradb/issues/1459)) -* Update QL documentation link and replicator command ([#1440](https://github.com/sourcenetwork/defradb/issues/1440)) -* Fix typo in readme ([#1419](https://github.com/sourcenetwork/defradb/issues/1419)) -* Limit the size of http request bodies that we handle ([#1405](https://github.com/sourcenetwork/defradb/issues/1405)) -* Improve P2P event handling ([#1388](https://github.com/sourcenetwork/defradb/issues/1388)) -* Serialize DB errors to json in http package ([#1401](https://github.com/sourcenetwork/defradb/issues/1401)) -* Do not commit if errors have been returned ([#1390](https://github.com/sourcenetwork/defradb/issues/1390)) -* Unlock replicator lock before returning error ([#1369](https://github.com/sourcenetwork/defradb/issues/1369)) -* Improve NonNull error message ([#1362](https://github.com/sourcenetwork/defradb/issues/1362)) -* Use ring-buffer for WaitForFoo chans ([#1359](https://github.com/sourcenetwork/defradb/issues/1359)) -* Guarantee event processing order ([#1352](https://github.com/sourcenetwork/defradb/issues/1352)) -* Explain of _group with dockeys filter to be []string ([#1348](https://github.com/sourcenetwork/defradb/issues/1348)) - -### Refactoring - -* Use `int32` for proper gql scalar Int parsing ([#1493](https://github.com/sourcenetwork/defradb/issues/1493)) -* Improve rollback on peer P2P collection error ([#1461](https://github.com/sourcenetwork/defradb/issues/1461)) -* Improve CLI with test suite and builder pattern ([#928](https://github.com/sourcenetwork/defradb/issues/928)) - -### Testing - -* Add DB/Node Restart tests ([#1504](https://github.com/sourcenetwork/defradb/issues/1504)) -* Provide tests for client introspection query ([#1492](https://github.com/sourcenetwork/defradb/issues/1492)) -* Convert explain count tests to new explain setup ([#1488](https://github.com/sourcenetwork/defradb/issues/1488)) -* Convert explain sum tests to new explain setup ([#1489](https://github.com/sourcenetwork/defradb/issues/1489)) -* Convert explain average tests to new explain setup ([#1487](https://github.com/sourcenetwork/defradb/issues/1487)) -* Convert explain top-level tests to new explain setup ([#1480](https://github.com/sourcenetwork/defradb/issues/1480)) -* Convert explain order tests to new explain setup ([#1478](https://github.com/sourcenetwork/defradb/issues/1478)) -* Convert explain join tests to new explain setup ([#1476](https://github.com/sourcenetwork/defradb/issues/1476)) -* Convert explain dagscan tests to new explain setup ([#1474](https://github.com/sourcenetwork/defradb/issues/1474)) -* Add tests to assert schema id order independence ([#1456](https://github.com/sourcenetwork/defradb/issues/1456)) -* Capitalize all integration schema types ([#1445](https://github.com/sourcenetwork/defradb/issues/1445)) -* Convert explain limit tests to new explain setup ([#1446](https://github.com/sourcenetwork/defradb/issues/1446)) -* Improve change detector performance ([#1433](https://github.com/sourcenetwork/defradb/issues/1433)) -* Convert mutation explain tests to new explain setup ([#1416](https://github.com/sourcenetwork/defradb/issues/1416)) -* Convert filter explain tests to new explain setup ([#1380](https://github.com/sourcenetwork/defradb/issues/1380)) -* Retry test doc mutation on transaction conflict ([#1366](https://github.com/sourcenetwork/defradb/issues/1366)) - -### Continuous integration - -* Remove secret ssh key stuff from change detector wf ([#1438](https://github.com/sourcenetwork/defradb/issues/1438)) -* Fix the SSH security issue from AMI scan report ([#1426](https://github.com/sourcenetwork/defradb/issues/1426)) -* Add a separate workflow to run the linter ([#1434](https://github.com/sourcenetwork/defradb/issues/1434)) -* Allow CI to work from forked repo ([#1392](https://github.com/sourcenetwork/defradb/issues/1392)) -* Bump go version within packer for AWS AMI ([#1344](https://github.com/sourcenetwork/defradb/issues/1344)) - -### Chore - -* Enshrine defra logger names ([#1410](https://github.com/sourcenetwork/defradb/issues/1410)) -* Remove some dead code ([#1470](https://github.com/sourcenetwork/defradb/issues/1470)) -* Update graphql-go ([#1422](https://github.com/sourcenetwork/defradb/issues/1422)) -* Improve logging consistency ([#1424](https://github.com/sourcenetwork/defradb/issues/1424)) -* Makefile tests with shorter timeout and common flags ([#1397](https://github.com/sourcenetwork/defradb/issues/1397)) -* Move to gofrs/uuid ([#1396](https://github.com/sourcenetwork/defradb/issues/1396)) -* Move to ipfs boxo ([#1393](https://github.com/sourcenetwork/defradb/issues/1393)) -* Document collection.txn ([#1363](https://github.com/sourcenetwork/defradb/issues/1363)) - -### Bot - -* Bump golang.org/x/crypto from 0.8.0 to 0.9.0 ([#1497](https://github.com/sourcenetwork/defradb/issues/1497)) -* Bump golang.org/x/net from 0.9.0 to 0.10.0 ([#1496](https://github.com/sourcenetwork/defradb/issues/1496)) -* Bump google.golang.org/grpc from 1.54.0 to 1.55.0 ([#1464](https://github.com/sourcenetwork/defradb/issues/1464)) -* Bump github.com/ipfs/boxo from 0.8.0 to 0.8.1 ([#1427](https://github.com/sourcenetwork/defradb/issues/1427)) -* Bump golang.org/x/crypto from 0.7.0 to 0.8.0 ([#1398](https://github.com/sourcenetwork/defradb/issues/1398)) -* Bump github.com/spf13/cobra from 1.6.1 to 1.7.0 ([#1399](https://github.com/sourcenetwork/defradb/issues/1399)) -* Bump github.com/ipfs/go-blockservice from 0.5.0 to 0.5.1 ([#1300](https://github.com/sourcenetwork/defradb/issues/1300)) -* Bump github.com/ipfs/go-cid from 0.4.0 to 0.4.1 ([#1301](https://github.com/sourcenetwork/defradb/issues/1301)) - - -## [v0.5.0](https://github.com/sourcenetwork/defradb/compare/v0.4.0...v0.5.0) - -> 2023-04-12 - -DefraDB v0.5 is a major pre-production release. Until the stable version 1.0 is reached, the SemVer minor patch number will denote notable releases, which will give the project freedom to experiment and explore potentially breaking changes. - -There many new features in this release, but most importantly, this is the first open source release for DefraDB. As such, this release focused on various quality of life changes and refactors, bug fixes, and overall cleanliness of the repo so it can effectively be used and tested in the public domain. - -To get a full outline of the changes, we invite you to review the official changelog below. Some highlights are the first iteration of our schema update system, allowing developers to add new fields to schemas using our JSON Patch based DDL, a new DAG based delete system which will persist "soft-delete" ops into the CRDT Merkle DAG, and a early prototype for our collection level peer-to-peer synchronization. - -This release does include a Breaking Change to existing v0.4.x databases. If you need help migrating an existing deployment, reach out at [hello@source.network](mailto:hello@source.network) or join our Discord at https://discord.gg/w7jYQVJ/. - -### Features - -* Add document delete mechanics ([#1263](https://github.com/sourcenetwork/defradb/issues/1263)) -* Ability to explain an executed request ([#1188](https://github.com/sourcenetwork/defradb/issues/1188)) -* Add SchemaPatch CLI command ([#1250](https://github.com/sourcenetwork/defradb/issues/1250)) -* Add support for one-one mutation from sec. side ([#1247](https://github.com/sourcenetwork/defradb/issues/1247)) -* Store only key in DAG instead of dockey path ([#1245](https://github.com/sourcenetwork/defradb/issues/1245)) -* Add collectionId field to commit field ([#1235](https://github.com/sourcenetwork/defradb/issues/1235)) -* Add field kind substitution for PatchSchema ([#1223](https://github.com/sourcenetwork/defradb/issues/1223)) -* Add dockey field for commit field ([#1216](https://github.com/sourcenetwork/defradb/issues/1216)) -* Allow new fields to be added locally to schema ([#1139](https://github.com/sourcenetwork/defradb/issues/1139)) -* Add `like` sub-string filter ([#1091](https://github.com/sourcenetwork/defradb/issues/1091)) -* Add ability for P2P to wait for pushlog by peer ([#1098](https://github.com/sourcenetwork/defradb/issues/1098)) -* Add P2P collection topic subscription ([#1086](https://github.com/sourcenetwork/defradb/issues/1086)) -* Add support for schema version id in queries ([#1067](https://github.com/sourcenetwork/defradb/issues/1067)) -* Add schema version id to commit queries ([#1061](https://github.com/sourcenetwork/defradb/issues/1061)) -* Persist schema version at time of commit ([#1055](https://github.com/sourcenetwork/defradb/issues/1055)) -* Add ability to input simple explain type arg ([#1039](https://github.com/sourcenetwork/defradb/issues/1039)) - -### Fixes - -* API address parameter validation ([#1311](https://github.com/sourcenetwork/defradb/issues/1311)) -* Improve error message for NonNull GQL types ([#1333](https://github.com/sourcenetwork/defradb/issues/1333)) -* Handle panics in the rpc server ([#1330](https://github.com/sourcenetwork/defradb/issues/1330)) -* Handle returned error in select.go ([#1329](https://github.com/sourcenetwork/defradb/issues/1329)) -* Resolve handful of CLI issues ([#1318](https://github.com/sourcenetwork/defradb/issues/1318)) -* Only check for events queue on subscription request ([#1326](https://github.com/sourcenetwork/defradb/issues/1326)) -* Remove client Create/UpdateCollection ([#1309](https://github.com/sourcenetwork/defradb/issues/1309)) -* CLI to display specific command usage help ([#1314](https://github.com/sourcenetwork/defradb/issues/1314)) -* Fix P2P collection CLI commands ([#1295](https://github.com/sourcenetwork/defradb/issues/1295)) -* Dont double up badger file path ([#1299](https://github.com/sourcenetwork/defradb/issues/1299)) -* Update immutable package ([#1290](https://github.com/sourcenetwork/defradb/issues/1290)) -* Fix panic on success of Add/RemoveP2PCollections ([#1297](https://github.com/sourcenetwork/defradb/issues/1297)) -* Fix deadlock on memory-datastore Close ([#1273](https://github.com/sourcenetwork/defradb/issues/1273)) -* Determine if query is introspection query ([#1255](https://github.com/sourcenetwork/defradb/issues/1255)) -* Allow newly added fields to sync via p2p ([#1226](https://github.com/sourcenetwork/defradb/issues/1226)) -* Expose `ExplainEnum` in the GQL schema ([#1204](https://github.com/sourcenetwork/defradb/issues/1204)) -* Resolve aggregates' mapping with deep nested subtypes ([#1175](https://github.com/sourcenetwork/defradb/issues/1175)) -* Make sort stable and handle nil comparison ([#1094](https://github.com/sourcenetwork/defradb/issues/1094)) -* Change successful schema add status to 200 ([#1106](https://github.com/sourcenetwork/defradb/issues/1106)) -* Add delay in P2P test util execution ([#1093](https://github.com/sourcenetwork/defradb/issues/1093)) -* Ensure errors test don't hard expect folder name ([#1072](https://github.com/sourcenetwork/defradb/issues/1072)) -* Remove potential P2P deadlock ([#1056](https://github.com/sourcenetwork/defradb/issues/1056)) -* Rework the P2P integration tests ([#989](https://github.com/sourcenetwork/defradb/issues/989)) -* Improve DAG sync with highly concurrent updates ([#1031](https://github.com/sourcenetwork/defradb/issues/1031)) - -### Documentation - -* Update docs for the v0.5 release ([#1320](https://github.com/sourcenetwork/defradb/issues/1320)) -* Document client interfaces in client/db.go ([#1305](https://github.com/sourcenetwork/defradb/issues/1305)) -* Document client Description types ([#1307](https://github.com/sourcenetwork/defradb/issues/1307)) -* Improve security policy ([#1240](https://github.com/sourcenetwork/defradb/issues/1240)) -* Add security disclosure policy ([#1194](https://github.com/sourcenetwork/defradb/issues/1194)) -* Correct commits query example in readme ([#1172](https://github.com/sourcenetwork/defradb/issues/1172)) - -### Refactoring - -* Improve p2p collection operations on peer ([#1286](https://github.com/sourcenetwork/defradb/issues/1286)) -* Migrate gql introspection tests to new framework ([#1211](https://github.com/sourcenetwork/defradb/issues/1211)) -* Reorganise client transaction related interfaces ([#1180](https://github.com/sourcenetwork/defradb/issues/1180)) -* Config-local viper, rootdir, and logger parsing ([#1132](https://github.com/sourcenetwork/defradb/issues/1132)) -* Migrate mutation-relation tests to new framework ([#1109](https://github.com/sourcenetwork/defradb/issues/1109)) -* Rework integration test framework ([#1089](https://github.com/sourcenetwork/defradb/issues/1089)) -* Generate gql types using col. desc ([#1080](https://github.com/sourcenetwork/defradb/issues/1080)) -* Extract config errors to dedicated file ([#1107](https://github.com/sourcenetwork/defradb/issues/1107)) -* Change terminology from query to request ([#1054](https://github.com/sourcenetwork/defradb/issues/1054)) -* Allow db keys to handle multiple schema versions ([#1026](https://github.com/sourcenetwork/defradb/issues/1026)) -* Extract query schema errors to dedicated file ([#1037](https://github.com/sourcenetwork/defradb/issues/1037)) -* Extract planner errors to dedicated file ([#1034](https://github.com/sourcenetwork/defradb/issues/1034)) -* Extract query parser errors to dedicated file ([#1035](https://github.com/sourcenetwork/defradb/issues/1035)) - -### Testing - -* Remove test reference to DEFRA_ROOTDIR env var ([#1328](https://github.com/sourcenetwork/defradb/issues/1328)) -* Expand tests for Peer subscribe actions ([#1287](https://github.com/sourcenetwork/defradb/issues/1287)) -* Fix flaky TestCloseThroughContext test ([#1265](https://github.com/sourcenetwork/defradb/issues/1265)) -* Add gql introspection tests for patch schema ([#1219](https://github.com/sourcenetwork/defradb/issues/1219)) -* Explicitly state change detector split for test ([#1228](https://github.com/sourcenetwork/defradb/issues/1228)) -* Add test for successful one-one create mutation ([#1215](https://github.com/sourcenetwork/defradb/issues/1215)) -* Ensure that all databases are always closed on exit ([#1187](https://github.com/sourcenetwork/defradb/issues/1187)) -* Add P2P tests for Schema Update adding field ([#1182](https://github.com/sourcenetwork/defradb/issues/1182)) -* Migrate P2P/state tests to new framework ([#1160](https://github.com/sourcenetwork/defradb/issues/1160)) -* Remove sleep from subscription tests ([#1156](https://github.com/sourcenetwork/defradb/issues/1156)) -* Fetch documents on test execution start ([#1163](https://github.com/sourcenetwork/defradb/issues/1163)) -* Introduce basic testing for the `version` module ([#1111](https://github.com/sourcenetwork/defradb/issues/1111)) -* Boost test coverage for collection_update ([#1050](https://github.com/sourcenetwork/defradb/issues/1050)) -* Wait between P2P update retry attempts ([#1052](https://github.com/sourcenetwork/defradb/issues/1052)) -* Exclude auto-generated protobuf files from codecov ([#1048](https://github.com/sourcenetwork/defradb/issues/1048)) -* Add P2P tests for relational docs ([#1042](https://github.com/sourcenetwork/defradb/issues/1042)) - -### Continuous integration - -* Add workflow that builds DefraDB AMI upon tag push ([#1304](https://github.com/sourcenetwork/defradb/issues/1304)) -* Allow PR title to end with a capital letter ([#1291](https://github.com/sourcenetwork/defradb/issues/1291)) -* Changes for `dependabot` to be well-behaved ([#1165](https://github.com/sourcenetwork/defradb/issues/1165)) -* Skip benchmarks for dependabot ([#1144](https://github.com/sourcenetwork/defradb/issues/1144)) -* Add workflow to ensure deps build properly ([#1078](https://github.com/sourcenetwork/defradb/issues/1078)) -* Runner and Builder Containerfiles ([#951](https://github.com/sourcenetwork/defradb/issues/951)) -* Fix go-header linter rule to be any year ([#1021](https://github.com/sourcenetwork/defradb/issues/1021)) - -### Chore - -* Add Islam as contributor ([#1302](https://github.com/sourcenetwork/defradb/issues/1302)) -* Update go-libp2p to 0.26.4 ([#1257](https://github.com/sourcenetwork/defradb/issues/1257)) -* Improve the test coverage of datastore ([#1203](https://github.com/sourcenetwork/defradb/issues/1203)) -* Add issue and discussion templates ([#1193](https://github.com/sourcenetwork/defradb/issues/1193)) -* Bump libp2p/go-libp2p-kad-dht from 0.21.0 to 0.21.1 ([#1146](https://github.com/sourcenetwork/defradb/issues/1146)) -* Enable dependabot ([#1120](https://github.com/sourcenetwork/defradb/issues/1120)) -* Update `opentelemetry` dependencies ([#1114](https://github.com/sourcenetwork/defradb/issues/1114)) -* Update dependencies including go-ipfs ([#1112](https://github.com/sourcenetwork/defradb/issues/1112)) -* Bump to GoLang v1.19 ([#818](https://github.com/sourcenetwork/defradb/issues/818)) -* Remove versionedScan node ([#1049](https://github.com/sourcenetwork/defradb/issues/1049)) - -### Bot - -* Bump github.com/multiformats/go-multiaddr from 0.8.0 to 0.9.0 ([#1277](https://github.com/sourcenetwork/defradb/issues/1277)) -* Bump google.golang.org/grpc from 1.53.0 to 1.54.0 ([#1233](https://github.com/sourcenetwork/defradb/issues/1233)) -* Bump github.com/multiformats/go-multibase from 0.1.1 to 0.2.0 ([#1230](https://github.com/sourcenetwork/defradb/issues/1230)) -* Bump github.com/ipfs/go-libipfs from 0.6.2 to 0.7.0 ([#1231](https://github.com/sourcenetwork/defradb/issues/1231)) -* Bump github.com/ipfs/go-cid from 0.3.2 to 0.4.0 ([#1200](https://github.com/sourcenetwork/defradb/issues/1200)) -* Bump github.com/ipfs/go-ipfs-blockstore from 1.2.0 to 1.3.0 ([#1199](https://github.com/sourcenetwork/defradb/issues/1199)) -* Bump github.com/stretchr/testify from 1.8.1 to 1.8.2 ([#1198](https://github.com/sourcenetwork/defradb/issues/1198)) -* Bump github.com/ipfs/go-libipfs from 0.6.1 to 0.6.2 ([#1201](https://github.com/sourcenetwork/defradb/issues/1201)) -* Bump golang.org/x/crypto from 0.6.0 to 0.7.0 ([#1197](https://github.com/sourcenetwork/defradb/issues/1197)) -* Bump libp2p/go-libp2p-gostream from 0.5.0 to 0.6.0 ([#1152](https://github.com/sourcenetwork/defradb/issues/1152)) -* Bump github.com/ipfs/go-libipfs from 0.5.0 to 0.6.1 ([#1166](https://github.com/sourcenetwork/defradb/issues/1166)) -* Bump github.com/ugorji/go/codec from 1.2.9 to 1.2.11 ([#1173](https://github.com/sourcenetwork/defradb/issues/1173)) -* Bump github.com/libp2p/go-libp2p-pubsub from 0.9.0 to 0.9.3 ([#1183](https://github.com/sourcenetwork/defradb/issues/1183)) - - -## [v0.4.0](https://github.com/sourcenetwork/defradb/compare/v0.3.1...v0.4.0) - -> 2023-12-23 - -DefraDB v0.4 is a major pre-production release. Until the stable version 1.0 is reached, the SemVer minor patch number will denote notable releases, which will give the project freedom to experiment and explore potentially breaking changes. - -There are various new features in this release - some of which are breaking - and we invite you to review the official changelog below. Some highlights are persistence of replicators, DateTime scalars, TLS support, and GQL subscriptions. - -This release does include a Breaking Change to existing v0.3.x databases. If you need help migrating an existing deployment, reach out at [hello@source.network](mailto:hello@source.network) or join our Discord at https://discord.gg/w7jYQVJ/. - -### Features - -* Add basic metric functionality ([#971](https://github.com/sourcenetwork/defradb/issues/971)) -* Add thread safe transactional in-memory datastore ([#947](https://github.com/sourcenetwork/defradb/issues/947)) -* Persist p2p replicators ([#960](https://github.com/sourcenetwork/defradb/issues/960)) -* Add DateTime custom scalars ([#931](https://github.com/sourcenetwork/defradb/issues/931)) -* Add GraphQL subscriptions ([#934](https://github.com/sourcenetwork/defradb/issues/934)) -* Add support for tls ([#885](https://github.com/sourcenetwork/defradb/issues/885)) -* Add group by support for commits ([#887](https://github.com/sourcenetwork/defradb/issues/887)) -* Add depth support for commits ([#889](https://github.com/sourcenetwork/defradb/issues/889)) -* Make dockey optional for allCommits queries ([#847](https://github.com/sourcenetwork/defradb/issues/847)) -* Add WithStack to the errors package ([#870](https://github.com/sourcenetwork/defradb/issues/870)) -* Add event system ([#834](https://github.com/sourcenetwork/defradb/issues/834)) - -### Fixes - -* Correct errors.WithStack behaviour ([#984](https://github.com/sourcenetwork/defradb/issues/984)) -* Correctly handle nested one to one joins ([#964](https://github.com/sourcenetwork/defradb/issues/964)) -* Do not assume parent record exists when joining ([#963](https://github.com/sourcenetwork/defradb/issues/963)) -* Change time format for HTTP API log ([#910](https://github.com/sourcenetwork/defradb/issues/910)) -* Error if group select contains non-group-by fields ([#898](https://github.com/sourcenetwork/defradb/issues/898)) -* Add inspection of values for ENV flags ([#900](https://github.com/sourcenetwork/defradb/issues/900)) -* Remove panics from document ([#881](https://github.com/sourcenetwork/defradb/issues/881)) -* Add __typename support ([#871](https://github.com/sourcenetwork/defradb/issues/871)) -* Handle subscriber close ([#877](https://github.com/sourcenetwork/defradb/issues/877)) -* Publish update events post commit ([#866](https://github.com/sourcenetwork/defradb/issues/866)) - -### Refactoring - -* Make rootstore require Batching and TxnDatastore ([#940](https://github.com/sourcenetwork/defradb/issues/940)) -* Conceptually clarify schema vs query-language ([#924](https://github.com/sourcenetwork/defradb/issues/924)) -* Decouple db.db from gql ([#912](https://github.com/sourcenetwork/defradb/issues/912)) -* Merkle clock heads cleanup ([#918](https://github.com/sourcenetwork/defradb/issues/918)) -* Simplify dag fetcher ([#913](https://github.com/sourcenetwork/defradb/issues/913)) -* Cleanup parsing logic ([#909](https://github.com/sourcenetwork/defradb/issues/909)) -* Move planner outside the gql directory ([#907](https://github.com/sourcenetwork/defradb/issues/907)) -* Refactor commit nodes ([#892](https://github.com/sourcenetwork/defradb/issues/892)) -* Make latest commits syntax sugar ([#890](https://github.com/sourcenetwork/defradb/issues/890)) -* Remove commit query ([#841](https://github.com/sourcenetwork/defradb/issues/841)) - -### Testing - -* Add event tests ([#965](https://github.com/sourcenetwork/defradb/issues/965)) -* Add new setup for testing explain functionality ([#949](https://github.com/sourcenetwork/defradb/issues/949)) -* Add txn relation-type delete and create tests ([#875](https://github.com/sourcenetwork/defradb/issues/875)) -* Skip change detection for tests that assert panic ([#883](https://github.com/sourcenetwork/defradb/issues/883)) - -### Continuous integration - -* Bump all gh-action versions to support node16 ([#990](https://github.com/sourcenetwork/defradb/issues/990)) -* Bump ssh-agent action to v0.7.0 ([#978](https://github.com/sourcenetwork/defradb/issues/978)) -* Add error message format check ([#901](https://github.com/sourcenetwork/defradb/issues/901)) - -### Chore - -* Extract (events, merkle) errors to errors.go ([#973](https://github.com/sourcenetwork/defradb/issues/973)) -* Extract (datastore, db) errors to errors.go ([#969](https://github.com/sourcenetwork/defradb/issues/969)) -* Extract (connor, crdt, core) errors to errors.go ([#968](https://github.com/sourcenetwork/defradb/issues/968)) -* Extract inline (http and client) errors to errors.go ([#967](https://github.com/sourcenetwork/defradb/issues/967)) -* Update badger version ([#966](https://github.com/sourcenetwork/defradb/issues/966)) -* Move Option and Enumerable to immutables ([#939](https://github.com/sourcenetwork/defradb/issues/939)) -* Add configuration of external loggers ([#942](https://github.com/sourcenetwork/defradb/issues/942)) -* Strip DSKey prefixes and simplify NewDataStoreKey ([#944](https://github.com/sourcenetwork/defradb/issues/944)) -* Include version metadata in cross-building ([#930](https://github.com/sourcenetwork/defradb/issues/930)) -* Update to v0.23.2 the libP2P package ([#908](https://github.com/sourcenetwork/defradb/issues/908)) -* Remove `ipfslite` dependency ([#739](https://github.com/sourcenetwork/defradb/issues/739)) - - - -## [v0.3.1](https://github.com/sourcenetwork/defradb/compare/v0.3.0...v0.3.1) - -> 2022-09-23 - -DefraDB v0.3.1 is a minor release, primarily focusing on additional/extended features and fixes of items added in the `v0.3.0` release. - -### Features - -* Add cid support for allCommits ([#857](https://github.com/sourcenetwork/defradb/issues/857)) -* Add offset support to allCommits ([#859](https://github.com/sourcenetwork/defradb/issues/859)) -* Add limit support to allCommits query ([#856](https://github.com/sourcenetwork/defradb/issues/856)) -* Add order support to allCommits ([#845](https://github.com/sourcenetwork/defradb/issues/845)) -* Display CLI usage on user error ([#819](https://github.com/sourcenetwork/defradb/issues/819)) -* Add support for dockey filters in child joins ([#806](https://github.com/sourcenetwork/defradb/issues/806)) -* Add sort support for numeric aggregates ([#786](https://github.com/sourcenetwork/defradb/issues/786)) -* Allow filtering by nil ([#789](https://github.com/sourcenetwork/defradb/issues/789)) -* Add aggregate offset support ([#778](https://github.com/sourcenetwork/defradb/issues/778)) -* Remove filter depth limit ([#777](https://github.com/sourcenetwork/defradb/issues/777)) -* Add support for and-or inline array aggregate filters ([#779](https://github.com/sourcenetwork/defradb/issues/779)) -* Add limit support for aggregates ([#771](https://github.com/sourcenetwork/defradb/issues/771)) -* Add support for inline arrays of nillable types ([#759](https://github.com/sourcenetwork/defradb/issues/759)) -* Create errors package ([#548](https://github.com/sourcenetwork/defradb/issues/548)) -* Add ability to display peer id ([#719](https://github.com/sourcenetwork/defradb/issues/719)) -* Add a config option to set the vlog max file size ([#743](https://github.com/sourcenetwork/defradb/issues/743)) -* Explain `topLevelNode` like a `MultiNode` plan ([#749](https://github.com/sourcenetwork/defradb/issues/749)) -* Make `topLevelNode` explainable ([#737](https://github.com/sourcenetwork/defradb/issues/737)) - -### Fixes - -* Order subtype without selecting the join child ([#810](https://github.com/sourcenetwork/defradb/issues/810)) -* Correctly handles nil one-one joins ([#837](https://github.com/sourcenetwork/defradb/issues/837)) -* Reset scan node for each join ([#828](https://github.com/sourcenetwork/defradb/issues/828)) -* Handle filter input field argument being nil ([#787](https://github.com/sourcenetwork/defradb/issues/787)) -* Ensure CLI outputs JSON to stdout when directed to pipe ([#804](https://github.com/sourcenetwork/defradb/issues/804)) -* Error if given the wrong side of a one-one relationship ([#795](https://github.com/sourcenetwork/defradb/issues/795)) -* Add object marker to enable return of empty docs ([#800](https://github.com/sourcenetwork/defradb/issues/800)) -* Resolve the extra `typeIndexJoin`s for `_avg` aggregate ([#774](https://github.com/sourcenetwork/defradb/issues/774)) -* Remove _like filter operator ([#797](https://github.com/sourcenetwork/defradb/issues/797)) -* Remove having gql types ([#785](https://github.com/sourcenetwork/defradb/issues/785)) -* Error if child _group selected without parent groupBy ([#781](https://github.com/sourcenetwork/defradb/issues/781)) -* Error nicely on missing field specifier ([#782](https://github.com/sourcenetwork/defradb/issues/782)) -* Handle order input field argument being nil ([#701](https://github.com/sourcenetwork/defradb/issues/701)) -* Change output to outputpath in config file template for logger ([#716](https://github.com/sourcenetwork/defradb/issues/716)) -* Delete mutations not correct persisting all keys ([#731](https://github.com/sourcenetwork/defradb/issues/731)) - -### Tooling - -* Ban the usage of `ioutil` package ([#747](https://github.com/sourcenetwork/defradb/issues/747)) -* Migrate from CircleCi to GitHub Actions ([#679](https://github.com/sourcenetwork/defradb/issues/679)) - -### Documentation - -* Clarify meaning of url param, update in-repo CLI docs ([#814](https://github.com/sourcenetwork/defradb/issues/814)) -* Disclaimer of exposed to network and not encrypted ([#793](https://github.com/sourcenetwork/defradb/issues/793)) -* Update logo to respect theme ([#728](https://github.com/sourcenetwork/defradb/issues/728)) - -### Refactoring - -* Replace all `interface{}` with `any` alias ([#805](https://github.com/sourcenetwork/defradb/issues/805)) -* Use fastjson to parse mutation data string ([#772](https://github.com/sourcenetwork/defradb/issues/772)) -* Rework limit node flow ([#767](https://github.com/sourcenetwork/defradb/issues/767)) -* Make Option immutable ([#769](https://github.com/sourcenetwork/defradb/issues/769)) -* Rework sum and count nodes to make use of generics ([#757](https://github.com/sourcenetwork/defradb/issues/757)) -* Remove some possible panics from codebase ([#732](https://github.com/sourcenetwork/defradb/issues/732)) -* Change logging calls to use feedback in CLI package ([#714](https://github.com/sourcenetwork/defradb/issues/714)) - -### Testing - -* Add tests for aggs with nil filters ([#813](https://github.com/sourcenetwork/defradb/issues/813)) -* Add not equals filter tests ([#798](https://github.com/sourcenetwork/defradb/issues/798)) -* Fix `cli/peerid_test` to not clash addresses ([#766](https://github.com/sourcenetwork/defradb/issues/766)) -* Add change detector summary to test readme ([#754](https://github.com/sourcenetwork/defradb/issues/754)) -* Add tests for inline array grouping ([#752](https://github.com/sourcenetwork/defradb/issues/752)) - -### Continuous integration - -* Reduce test resource usage and test with file db ([#791](https://github.com/sourcenetwork/defradb/issues/791)) -* Add makefile target to verify the local module cache ([#775](https://github.com/sourcenetwork/defradb/issues/775)) -* Allow PR titles to end with a number ([#745](https://github.com/sourcenetwork/defradb/issues/745)) -* Add a workflow to validate pull request titles ([#734](https://github.com/sourcenetwork/defradb/issues/734)) -* Fix the linter version to `v1.47` ([#726](https://github.com/sourcenetwork/defradb/issues/726)) - -### Chore - -* Remove file system paths from resulting executable ([#831](https://github.com/sourcenetwork/defradb/issues/831)) -* Add goimports linter for consistent imports ordering ([#816](https://github.com/sourcenetwork/defradb/issues/816)) -* Improve UX by providing more information ([#802](https://github.com/sourcenetwork/defradb/issues/802)) -* Change to defra errors and handle errors stacktrace ([#794](https://github.com/sourcenetwork/defradb/issues/794)) -* Clean up `go.mod` with pruned module graphs ([#756](https://github.com/sourcenetwork/defradb/issues/756)) -* Update to v0.20.3 of libp2p ([#740](https://github.com/sourcenetwork/defradb/issues/740)) -* Bump to GoLang `v1.18` ([#721](https://github.com/sourcenetwork/defradb/issues/721)) - - - -## [v0.3.0](https://github.com/sourcenetwork/defradb/compare/v0.2.1...v0.3.0) - -> 2022-08-02 - -DefraDB v0.3 is a major pre-production release. Until the stable version 1.0 is reached, the SemVer minor patch number will denote notable releases, which will give the project freedom to experiment and explore potentially breaking changes. - -There are *several* new features in this release, and we invite you to review the official changelog below. Some highlights are various new features for Grouping & Aggregation for the query system, like top-level aggregation and group filtering. Moreover, a brand new Query Explain system was added to introspect the execution plans created by DefraDB. Lastly we introduced a revamped CLI configuration system. - -This release does include a Breaking Change to existing v0.2.x databases. If you need help migrating an existing deployment, reach out at [hello@source.network](mailto:hello@source.network) or join our Discord at https://discord.gg/w7jYQVJ/. - -### Features - -* Add named config overrides ([#659](https://github.com/sourcenetwork/defradb/issues/659)) -* Expose color and caller log options, add validation ([#652](https://github.com/sourcenetwork/defradb/issues/652)) -* Add ability to explain `groupNode` and it's attribute(s). ([#641](https://github.com/sourcenetwork/defradb/issues/641)) -* Add primary directive for schema definitions ([@primary](https://github.com/primary)) ([#650](https://github.com/sourcenetwork/defradb/issues/650)) -* Add support for aggregate filters on inline arrays ([#622](https://github.com/sourcenetwork/defradb/issues/622)) -* Add explainable renderLimitNode & hardLimitNode attributes. ([#614](https://github.com/sourcenetwork/defradb/issues/614)) -* Add support for top level aggregates ([#594](https://github.com/sourcenetwork/defradb/issues/594)) -* Update `countNode` explanation to be consistent. ([#600](https://github.com/sourcenetwork/defradb/issues/600)) -* Add support for stdin as input in CLI ([#608](https://github.com/sourcenetwork/defradb/issues/608)) -* Explain `cid` & `field` attributes for `dagScanNode` ([#598](https://github.com/sourcenetwork/defradb/issues/598)) -* Add ability to explain `dagScanNode` attribute(s). ([#560](https://github.com/sourcenetwork/defradb/issues/560)) -* Add the ability to send user feedback to the console even when logging to file. ([#568](https://github.com/sourcenetwork/defradb/issues/568)) -* Add ability to explain `sortNode` attribute(s). ([#558](https://github.com/sourcenetwork/defradb/issues/558)) -* Add ability to explain `sumNode` attribute(s). ([#559](https://github.com/sourcenetwork/defradb/issues/559)) -* Introduce top-level config package ([#389](https://github.com/sourcenetwork/defradb/issues/389)) -* Add ability to explain `updateNode` attributes. ([#514](https://github.com/sourcenetwork/defradb/issues/514)) -* Add `typeIndexJoin` explainable attributes. ([#499](https://github.com/sourcenetwork/defradb/issues/499)) -* Add support to explain `countNode` attributes. ([#504](https://github.com/sourcenetwork/defradb/issues/504)) -* Add CORS capability to HTTP API ([#467](https://github.com/sourcenetwork/defradb/issues/467)) -* Add explaination of spans for `scanNode`. ([#492](https://github.com/sourcenetwork/defradb/issues/492)) -* Add ability to Explain the response plan. ([#385](https://github.com/sourcenetwork/defradb/issues/385)) -* Add aggregate filter support for groups only ([#426](https://github.com/sourcenetwork/defradb/issues/426)) -* Configurable caller option in logger ([#416](https://github.com/sourcenetwork/defradb/issues/416)) -* Add Average aggregate support ([#383](https://github.com/sourcenetwork/defradb/issues/383)) -* Allow summation of aggregates ([#341](https://github.com/sourcenetwork/defradb/issues/341)) -* Add ability to check DefraDB CLI version. ([#339](https://github.com/sourcenetwork/defradb/issues/339)) - -### Fixes - -* Add a check to ensure limit is not 0 when evaluating query limit and offset ([#706](https://github.com/sourcenetwork/defradb/issues/706)) -* Support multiple `--logger` flags ([#704](https://github.com/sourcenetwork/defradb/issues/704)) -* Return without an error if relation is finalized ([#698](https://github.com/sourcenetwork/defradb/issues/698)) -* Logger not correctly applying named config ([#696](https://github.com/sourcenetwork/defradb/issues/696)) -* Add content-type media type parsing ([#678](https://github.com/sourcenetwork/defradb/issues/678)) -* Remove portSyncLock deadlock condition ([#671](https://github.com/sourcenetwork/defradb/issues/671)) -* Silence cobra default errors and usage printing ([#668](https://github.com/sourcenetwork/defradb/issues/668)) -* Add stdout validation when setting logging output path ([#666](https://github.com/sourcenetwork/defradb/issues/666)) -* Consider `--logoutput` CLI flag properly ([#645](https://github.com/sourcenetwork/defradb/issues/645)) -* Handle errors and responses in CLI `client` commands ([#579](https://github.com/sourcenetwork/defradb/issues/579)) -* Rename aggregate gql types ([#638](https://github.com/sourcenetwork/defradb/issues/638)) -* Error when attempting to insert value into relationship field ([#632](https://github.com/sourcenetwork/defradb/issues/632)) -* Allow adding of new schema to database ([#635](https://github.com/sourcenetwork/defradb/issues/635)) -* Correctly parse dockey in broadcast log event. ([#631](https://github.com/sourcenetwork/defradb/issues/631)) -* Increase system's open files limit in integration tests ([#627](https://github.com/sourcenetwork/defradb/issues/627)) -* Avoid populating `order.ordering` with empties. ([#618](https://github.com/sourcenetwork/defradb/issues/618)) -* Change to supporting of non-null inline arrays ([#609](https://github.com/sourcenetwork/defradb/issues/609)) -* Assert fields exist in collection before saving to them ([#604](https://github.com/sourcenetwork/defradb/issues/604)) -* CLI `init` command to reinitialize only config file ([#603](https://github.com/sourcenetwork/defradb/issues/603)) -* Add config and registry clearing to TestLogWritesMessagesToFeedbackLog ([#596](https://github.com/sourcenetwork/defradb/issues/596)) -* Change `$eq` to `_eq` in the failing test. ([#576](https://github.com/sourcenetwork/defradb/issues/576)) -* Resolve failing HTTP API tests via cleanup ([#557](https://github.com/sourcenetwork/defradb/issues/557)) -* Ensure Makefile compatibility with macOS ([#527](https://github.com/sourcenetwork/defradb/issues/527)) -* Separate out iotas in their own blocks. ([#464](https://github.com/sourcenetwork/defradb/issues/464)) -* Use x/cases for titling instead of strings to handle deprecation ([#457](https://github.com/sourcenetwork/defradb/issues/457)) -* Handle limit and offset in sub groups ([#440](https://github.com/sourcenetwork/defradb/issues/440)) -* Issue preventing DB from restarting with no records ([#437](https://github.com/sourcenetwork/defradb/issues/437)) -* log serving HTTP API before goroutine blocks ([#358](https://github.com/sourcenetwork/defradb/issues/358)) - -### Testing - -* Add integration testing for P2P. ([#655](https://github.com/sourcenetwork/defradb/issues/655)) -* Fix formatting of tests with no extra brackets ([#643](https://github.com/sourcenetwork/defradb/issues/643)) -* Add tests for `averageNode` explain. ([#639](https://github.com/sourcenetwork/defradb/issues/639)) -* Add schema integration tests ([#628](https://github.com/sourcenetwork/defradb/issues/628)) -* Add tests for default properties ([#611](https://github.com/sourcenetwork/defradb/issues/611)) -* Specify which collection to update in test framework ([#601](https://github.com/sourcenetwork/defradb/issues/601)) -* Add tests for grouping by undefined value ([#543](https://github.com/sourcenetwork/defradb/issues/543)) -* Add test for querying undefined field ([#544](https://github.com/sourcenetwork/defradb/issues/544)) -* Expand commit query tests ([#541](https://github.com/sourcenetwork/defradb/issues/541)) -* Add cid (time-travel) query tests ([#539](https://github.com/sourcenetwork/defradb/issues/539)) -* Restructure and expand filter tests ([#512](https://github.com/sourcenetwork/defradb/issues/512)) -* Basic unit testing of `node` package ([#503](https://github.com/sourcenetwork/defradb/issues/503)) -* Test filter in filter tests ([#473](https://github.com/sourcenetwork/defradb/issues/473)) -* Add test for deletion of records in a relationship ([#329](https://github.com/sourcenetwork/defradb/issues/329)) -* Benchmark transaction iteration ([#289](https://github.com/sourcenetwork/defradb/issues/289)) - -### Refactoring - -* Improve CLI error handling and fix small issues ([#649](https://github.com/sourcenetwork/defradb/issues/649)) -* Add top-level `version` package ([#583](https://github.com/sourcenetwork/defradb/issues/583)) -* Remove extra log levels ([#634](https://github.com/sourcenetwork/defradb/issues/634)) -* Change `sortNode` to `orderNode`. ([#591](https://github.com/sourcenetwork/defradb/issues/591)) -* Rework update and delete node to remove secondary planner ([#571](https://github.com/sourcenetwork/defradb/issues/571)) -* Trim imported connor package ([#530](https://github.com/sourcenetwork/defradb/issues/530)) -* Internal doc restructure ([#471](https://github.com/sourcenetwork/defradb/issues/471)) -* Copy-paste connor fork into repo ([#567](https://github.com/sourcenetwork/defradb/issues/567)) -* Add safety to the tests, add ability to catch stderr logs and add output path validation ([#552](https://github.com/sourcenetwork/defradb/issues/552)) -* Change handler functions implementation and response formatting ([#498](https://github.com/sourcenetwork/defradb/issues/498)) -* Improve the HTTP API implementation ([#382](https://github.com/sourcenetwork/defradb/issues/382)) -* Use new logger in net/api ([#420](https://github.com/sourcenetwork/defradb/issues/420)) -* Rename NewCidV1_SHA2_256 to mixedCaps ([#415](https://github.com/sourcenetwork/defradb/issues/415)) -* Remove utils package ([#397](https://github.com/sourcenetwork/defradb/issues/397)) -* Rework planNode Next and Value(s) function ([#374](https://github.com/sourcenetwork/defradb/issues/374)) -* Restructure aggregate query syntax ([#373](https://github.com/sourcenetwork/defradb/issues/373)) -* Remove dead code from client package and document remaining ([#356](https://github.com/sourcenetwork/defradb/issues/356)) -* Restructure datastore keys ([#316](https://github.com/sourcenetwork/defradb/issues/316)) -* Add commits lost during github outage ([#303](https://github.com/sourcenetwork/defradb/issues/303)) -* Move public members out of core and base packages ([#295](https://github.com/sourcenetwork/defradb/issues/295)) -* Make db stuff internal/private ([#291](https://github.com/sourcenetwork/defradb/issues/291)) -* Rework client.DB to ensure interface contains only public types ([#277](https://github.com/sourcenetwork/defradb/issues/277)) -* Remove GetPrimaryIndexDocKey from collection interface ([#279](https://github.com/sourcenetwork/defradb/issues/279)) -* Remove DataStoreKey from (public) dockey struct ([#278](https://github.com/sourcenetwork/defradb/issues/278)) -* Renormalize to ensure consistent file line termination. ([#226](https://github.com/sourcenetwork/defradb/issues/226)) -* Strongly typed key refactor ([#17](https://github.com/sourcenetwork/defradb/issues/17)) - -### Documentation - -* Use permanent link to BSL license document ([#692](https://github.com/sourcenetwork/defradb/issues/692)) -* README update v0.3.0 ([#646](https://github.com/sourcenetwork/defradb/issues/646)) -* Improve code documentation ([#533](https://github.com/sourcenetwork/defradb/issues/533)) -* Add CONTRIBUTING.md ([#531](https://github.com/sourcenetwork/defradb/issues/531)) -* Add package level docs for logging lib ([#338](https://github.com/sourcenetwork/defradb/issues/338)) - -### Tooling - -* Include all touched packages in code coverage ([#673](https://github.com/sourcenetwork/defradb/issues/673)) -* Use `gotestsum` over `go test` ([#619](https://github.com/sourcenetwork/defradb/issues/619)) -* Update Github pull request template ([#524](https://github.com/sourcenetwork/defradb/issues/524)) -* Fix the cross-build script ([#460](https://github.com/sourcenetwork/defradb/issues/460)) -* Add test coverage html output ([#466](https://github.com/sourcenetwork/defradb/issues/466)) -* Add linter rule for `goconst`. ([#398](https://github.com/sourcenetwork/defradb/issues/398)) -* Add github PR template. ([#394](https://github.com/sourcenetwork/defradb/issues/394)) -* Disable auto-fixing linter issues by default ([#429](https://github.com/sourcenetwork/defradb/issues/429)) -* Fix linting of empty `else` code blocks ([#402](https://github.com/sourcenetwork/defradb/issues/402)) -* Add the `gofmt` linter rule. ([#405](https://github.com/sourcenetwork/defradb/issues/405)) -* Cleanup linter config file ([#400](https://github.com/sourcenetwork/defradb/issues/400)) -* Add linter rule for copyright headers ([#360](https://github.com/sourcenetwork/defradb/issues/360)) -* Organize our config files and tooling. ([#336](https://github.com/sourcenetwork/defradb/issues/336)) -* Limit line length to 100 characters (linter check) ([#224](https://github.com/sourcenetwork/defradb/issues/224)) -* Ignore db/tests folder and the bench marks. ([#280](https://github.com/sourcenetwork/defradb/issues/280)) - -### Continuous Integration - -* Fix circleci cache permission errors. ([#371](https://github.com/sourcenetwork/defradb/issues/371)) -* Ban extra elses ([#366](https://github.com/sourcenetwork/defradb/issues/366)) -* Fix change-detection to not fail when new tests are added. ([#333](https://github.com/sourcenetwork/defradb/issues/333)) -* Update golang-ci linter and explicit go-setup to use v1.17 ([#331](https://github.com/sourcenetwork/defradb/issues/331)) -* Comment the benchmarking result comparison to the PR ([#305](https://github.com/sourcenetwork/defradb/issues/305)) -* Add benchmark performance comparisons ([#232](https://github.com/sourcenetwork/defradb/issues/232)) -* Add caching / storing of bench report on default branch ([#290](https://github.com/sourcenetwork/defradb/issues/290)) -* Ensure full-benchmarks are ran on a PR-merge. ([#282](https://github.com/sourcenetwork/defradb/issues/282)) -* Add ability to control benchmarks by PR labels. ([#267](https://github.com/sourcenetwork/defradb/issues/267)) - -### Chore - -* Update APL to refer to D2 Foundation ([#711](https://github.com/sourcenetwork/defradb/issues/711)) -* Update gitignore to include `cmd` folders ([#617](https://github.com/sourcenetwork/defradb/issues/617)) -* Enable random execution order of tests ([#554](https://github.com/sourcenetwork/defradb/issues/554)) -* Enable linters exportloopref, nolintlint, whitespace ([#535](https://github.com/sourcenetwork/defradb/issues/535)) -* Add utility for generation of man pages ([#493](https://github.com/sourcenetwork/defradb/issues/493)) -* Add Dockerfile ([#517](https://github.com/sourcenetwork/defradb/issues/517)) -* Enable errorlint linter ([#520](https://github.com/sourcenetwork/defradb/issues/520)) -* Binaries in`cmd` folder, examples in `examples` folder ([#501](https://github.com/sourcenetwork/defradb/issues/501)) -* Improve log outputs ([#506](https://github.com/sourcenetwork/defradb/issues/506)) -* Move testing to top-level `tests` folder ([#446](https://github.com/sourcenetwork/defradb/issues/446)) -* Update dependencies ([#450](https://github.com/sourcenetwork/defradb/issues/450)) -* Update go-ipfs-blockstore and ipfs-lite ([#436](https://github.com/sourcenetwork/defradb/issues/436)) -* Update libp2p dependency to v0.19 ([#424](https://github.com/sourcenetwork/defradb/issues/424)) -* Update ioutil package to io / os packages. ([#376](https://github.com/sourcenetwork/defradb/issues/376)) -* git ignore vscode ([#343](https://github.com/sourcenetwork/defradb/issues/343)) -* Updated README.md contributors section ([#292](https://github.com/sourcenetwork/defradb/issues/292)) -* Update changelog v0.2.1 ([#252](https://github.com/sourcenetwork/defradb/issues/252)) - - - -## [v0.2.1](https://github.com/sourcenetwork/defradb/compare/v0.2.0...v0.2.1) - -> 2022-03-04 - -### Features - -* Add ability to delete multiple documents using filter ([#206](https://github.com/sourcenetwork/defradb/issues/206)) -* Add ability to delete multiple documents, using multiple ids ([#196](https://github.com/sourcenetwork/defradb/issues/196)) - -### Fixes - -* Concurrency control of Document using RWMutex ([#213](https://github.com/sourcenetwork/defradb/issues/213)) -* Only log errors and above when benchmarking ([#261](https://github.com/sourcenetwork/defradb/issues/261)) -* Handle proper type conversion on sort nodes ([#228](https://github.com/sourcenetwork/defradb/issues/228)) -* Return empty array if no values found ([#223](https://github.com/sourcenetwork/defradb/issues/223)) -* Close fetcher on error ([#210](https://github.com/sourcenetwork/defradb/issues/210)) -* Installing binary using defradb name ([#190](https://github.com/sourcenetwork/defradb/issues/190)) - -### Tooling - -* Add short benchmark runner option ([#263](https://github.com/sourcenetwork/defradb/issues/263)) - -### Documentation - -* Add data format changes documentation folder ([#89](https://github.com/sourcenetwork/defradb/issues/89)) -* Correcting typos ([#143](https://github.com/sourcenetwork/defradb/issues/143)) -* Update generated CLI docs ([#208](https://github.com/sourcenetwork/defradb/issues/208)) -* Updated readme with P2P section ([#220](https://github.com/sourcenetwork/defradb/issues/220)) -* Update old or missing license headers ([#205](https://github.com/sourcenetwork/defradb/issues/205)) -* Update git-chglog config and template ([#195](https://github.com/sourcenetwork/defradb/issues/195)) - -### Refactoring - -* Introduction of logging system ([#67](https://github.com/sourcenetwork/defradb/issues/67)) -* Restructure db/txn/multistore structures ([#199](https://github.com/sourcenetwork/defradb/issues/199)) -* Initialize database in constructor ([#211](https://github.com/sourcenetwork/defradb/issues/211)) -* Purge all println and ban it ([#253](https://github.com/sourcenetwork/defradb/issues/253)) - -### Testing - -* Detect and force breaking filesystem changes to be documented ([#89](https://github.com/sourcenetwork/defradb/issues/89)) -* Boost collection test coverage ([#183](https://github.com/sourcenetwork/defradb/issues/183)) - -### Continuous integration - -* Combine the Lint and Benchmark workflows so that the benchmark job depends on the lint job in one workflow ([#209](https://github.com/sourcenetwork/defradb/issues/209)) -* Add rule to only run benchmark if other check are successful ([#194](https://github.com/sourcenetwork/defradb/issues/194)) -* Increase linter timeout ([#230](https://github.com/sourcenetwork/defradb/issues/230)) - -### Chore - -* Remove commented out code ([#238](https://github.com/sourcenetwork/defradb/issues/238)) -* Remove dead code from multi node ([#186](https://github.com/sourcenetwork/defradb/issues/186)) - - - -## [v0.2.0](https://github.com/sourcenetwork/defradb/compare/v0.1.0...v0.2.0) - -> 2022-02-07 - -DefraDB v0.2 is a major pre-production release. Until the stable version 1.0 is reached, the SemVer minor patch number will denote notable releases, which will give the project freedom to experiment and explore potentially breaking changes. - -This release is jam-packed with new features and a small number of breaking changes. Read the full changelog for a detailed description. Most notable features include a new Peer-to-Peer (P2P) data synchronization system, an expanded query system to support GroupBy & Aggregate operations, and lastly TimeTraveling queries allowing to query previous states of a document. - -Much more than just that has been added to ensure we're building reliable software expected of any database, such as expanded test & benchmark suites, automated bug detection, performance gains, and more. - -This release does include a Breaking Change to existing v0.1 databases regarding the internal data model, which affects the "Content Identifiers" we use to generate DocKeys and VersionIDs. If you need help migrating an existing deployment, reach out at hello@source.network or join our Discord at https://discord.gg/w7jYQVJ. - -### Features - -* Added Peer-to-Peer networking data synchronization ([#177](https://github.com/sourcenetwork/defradb/issues/177)) -* TimeTraveling (History Traversing) query engine and doc fetcher ([#59](https://github.com/sourcenetwork/defradb/issues/59)) -* Add Document Deletion with a Key ([#150](https://github.com/sourcenetwork/defradb/issues/150)) -* Add support for sum aggregate ([#121](https://github.com/sourcenetwork/defradb/issues/121)) -* Add support for lwwr scalar arrays (full replace on update) ([#115](https://github.com/sourcenetwork/defradb/issues/115)) -* Add count aggregate support ([#102](https://github.com/sourcenetwork/defradb/issues/102)) -* Add support for named relationships ([#108](https://github.com/sourcenetwork/defradb/issues/108)) -* Add multi doc key lookup support ([#76](https://github.com/sourcenetwork/defradb/issues/76)) -* Add basic group by functionality ([#43](https://github.com/sourcenetwork/defradb/issues/43)) -* Update datastore packages to allow use of context ([#48](https://github.com/sourcenetwork/defradb/issues/48)) - -### Bug fixes - -* Only add join if aggregating child object collection ([#188](https://github.com/sourcenetwork/defradb/issues/188)) -* Handle errors generated during input object thunks ([#123](https://github.com/sourcenetwork/defradb/issues/123)) -* Remove new types from in-memory cache on generate error ([#122](https://github.com/sourcenetwork/defradb/issues/122)) -* Support relationships where both fields have the same name ([#109](https://github.com/sourcenetwork/defradb/issues/109)) -* Handle errors generated in fields thunk ([#66](https://github.com/sourcenetwork/defradb/issues/66)) -* Ensure OperationDefinition case has at least one selection([#24](https://github.com/sourcenetwork/defradb/pull/24)) -* Close datastore iterator on scan close ([#56](https://github.com/sourcenetwork/defradb/pull/56)) (resulted in a panic when using limit) -* Close superseded iterators before orphaning ([#56](https://github.com/sourcenetwork/defradb/pull/56)) (fixes a panic in the join code) -* Move discard to after error check ([#88](https://github.com/sourcenetwork/defradb/pull/88)) (did result in panic if transaction creation fails) -* Check for nil iterator before closing document fetcher ([#108](https://github.com/sourcenetwork/defradb/pull/108)) - -### Tooling -* Added benchmark suite ([#160](https://github.com/sourcenetwork/defradb/issues/160)) - -### Documentation - -* Correcting comment typos ([#142](https://github.com/sourcenetwork/defradb/issues/142)) -* Correcting README typos ([#140](https://github.com/sourcenetwork/defradb/issues/140)) - -### Testing - -* Add transaction integration tests ([#175](https://github.com/sourcenetwork/defradb/issues/175)) -* Allow running of tests using badger-file as well as IM options ([#128](https://github.com/sourcenetwork/defradb/issues/128)) -* Add test datastore selection support ([#88](https://github.com/sourcenetwork/defradb/issues/88)) - -### Refactoring - -* Datatype modification protection ([#138](https://github.com/sourcenetwork/defradb/issues/138)) -* Cleanup Linter Complaints and Setup Makefile ([#63](https://github.com/sourcenetwork/defradb/issues/63)) -* Rework document rendering to avoid data duplication and mutation ([#68](https://github.com/sourcenetwork/defradb/issues/68)) -* Remove dependency on concrete datastore implementations from db package ([#51](https://github.com/sourcenetwork/defradb/issues/51)) -* Remove all `errors.Wrap` and update them with `fmt.Errorf`. ([#41](https://github.com/sourcenetwork/defradb/issues/41)) -* Restructure integration tests to provide better visibility ([#15](https://github.com/sourcenetwork/defradb/pull/15)) -* Remove schemaless code branches ([#23](https://github.com/sourcenetwork/defradb/pull/23)) - -### Performance -* Add badger multi scan support ([#85](https://github.com/sourcenetwork/defradb/pull/85)) -* Add support for range spans ([#86](https://github.com/sourcenetwork/defradb/pull/86)) - -### Continous integration - -* Use more accurate test coverage. ([#134](https://github.com/sourcenetwork/defradb/issues/134)) -* Disable Codecov's Patch Check -* Make codcov less strict for now to unblock development ([#125](https://github.com/sourcenetwork/defradb/issues/125)) -* Add codecov config file. ([#118](https://github.com/sourcenetwork/defradb/issues/118)) -* Add workflow that runs a job on AWS EC2 instance. ([#110](https://github.com/sourcenetwork/defradb/issues/110)) -* Add Code Test Coverage with CodeCov ([#116](https://github.com/sourcenetwork/defradb/issues/116)) -* Integrate GitHub Action for golangci-lint Annotations ([#106](https://github.com/sourcenetwork/defradb/issues/106)) -* Add Linter Check to CircleCi ([#92](https://github.com/sourcenetwork/defradb/issues/92)) - -### Chore - -* Remove the S1038 rule of the gosimple linter. ([#129](https://github.com/sourcenetwork/defradb/issues/129)) -* Update to badger v3, and use badger as default in memory store ([#56](https://github.com/sourcenetwork/defradb/issues/56)) -* Make Cid versions consistent ([#57](https://github.com/sourcenetwork/defradb/issues/57)) - - - -## v0.1.0 - -> 2021-03-15 - diff --git a/CHANGELOG.md b/CHANGELOG.md index 48671840d5..2e8fa26f17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,64 @@ + +## [v0.13.0](https://github.com/sourcenetwork/defradb/compare/v0.12.0...v0.13.0) + +> 2024-08-23 + +DefraDB v0.13 is a major pre-production release. Until the stable version 1.0 is reached, the SemVer minor patch number will denote notable releases, which will give the project freedom to experiment and explore potentially breaking changes. + +To get a full outline of the changes, we invite you to review the official changelog below. This release does include a Breaking Change to existing v0.12.x databases. If you need help migrating an existing deployment, reach out at [hello@source.network](mailto:hello@source.network) or join our Discord at https://discord.gg/w7jYQVJ/. + +### Features + +* Enable indexing for DateTime fields ([#2933](https://github.com/sourcenetwork/defradb/issues/2933)) +* Remove IsObjectArray ([#2859](https://github.com/sourcenetwork/defradb/issues/2859)) +* Handle P2P with SourceHub ACP ([#2848](https://github.com/sourcenetwork/defradb/issues/2848)) +* Implement SourceHub ACP ([#2657](https://github.com/sourcenetwork/defradb/issues/2657)) +* Doc field encryption ([#2817](https://github.com/sourcenetwork/defradb/issues/2817)) +* Doc encryption with symmetric key ([#2731](https://github.com/sourcenetwork/defradb/issues/2731)) + +### Fixes + +* Filter with date and document with nil date value ([#2946](https://github.com/sourcenetwork/defradb/issues/2946)) +* Handle index queries where child found without parent ([#2942](https://github.com/sourcenetwork/defradb/issues/2942)) +* Add ns precision support to time values ([#2940](https://github.com/sourcenetwork/defradb/issues/2940)) +* Panic with different composite-indexed child objects ([#2947](https://github.com/sourcenetwork/defradb/issues/2947)) +* No panic if filter condition on indexed field is empty ([#2929](https://github.com/sourcenetwork/defradb/issues/2929)) +* Create mutation introspection ([#2881](https://github.com/sourcenetwork/defradb/issues/2881)) +* Handle multiple child index joins ([#2867](https://github.com/sourcenetwork/defradb/issues/2867)) +* Enable filtering doc by fields of JSON and Blob types ([#2841](https://github.com/sourcenetwork/defradb/issues/2841)) +* Allow querying of 9th, 19th, 29th, etc collections ([#2819](https://github.com/sourcenetwork/defradb/issues/2819)) +* Support one-many self joins without primary directive ([#2799](https://github.com/sourcenetwork/defradb/issues/2799)) +* Allow primary field declarations on one-many ([#2796](https://github.com/sourcenetwork/defradb/issues/2796)) + +### Refactoring + +* GQL responses ([#2872](https://github.com/sourcenetwork/defradb/issues/2872)) +* Network test sync logic ([#2748](https://github.com/sourcenetwork/defradb/issues/2748)) +* Decouple client.DB from net ([#2768](https://github.com/sourcenetwork/defradb/issues/2768)) + +### Testing + +* Add assert on DocIndex for child documents ([#2871](https://github.com/sourcenetwork/defradb/issues/2871)) +* Fix refreshing of docs in change detector ([#2832](https://github.com/sourcenetwork/defradb/issues/2832)) +* Remove hardcoded test identities ([#2822](https://github.com/sourcenetwork/defradb/issues/2822)) +* Allow assertion of AddSchema results ([#2788](https://github.com/sourcenetwork/defradb/issues/2788)) + +### Chore + +* Bump grpc version ([#2824](https://github.com/sourcenetwork/defradb/issues/2824)) + +### Bot + +* Update dependencies (bulk dependabot PRs) 21-08-2024 ([#2939](https://github.com/sourcenetwork/defradb/issues/2939)) +* Update dependencies (bulk dependabot PRs) 20-08-2024 ([#2932](https://github.com/sourcenetwork/defradb/issues/2932)) +* Update dependencies (bulk dependabot PRs) 12-08-2024 ([#2904](https://github.com/sourcenetwork/defradb/issues/2904)) +* Bump eslint from 8.57.0 to 9.9.0 in /playground ([#2903](https://github.com/sourcenetwork/defradb/issues/2903)) +* Bump golang.org/x/term from 0.22.0 to 0.23.0 ([#2890](https://github.com/sourcenetwork/defradb/issues/2890)) +* Update dependencies (bulk dependabot PRs) 06-08-2024 ([#2889](https://github.com/sourcenetwork/defradb/issues/2889)) +* Update dependencies (bulk dependabot PRs) 18-07-2024 ([#2846](https://github.com/sourcenetwork/defradb/issues/2846)) +* Update dependencies (bulk dependabot PRs) 05-07-2024 ([#2811](https://github.com/sourcenetwork/defradb/issues/2811)) +* Bump github.com/cometbft/cometbft from 0.38.7 to 0.38.8 ([#2794](https://github.com/sourcenetwork/defradb/issues/2794)) + ## [v0.12.0](https://github.com/sourcenetwork/defradb/compare/v0.11.0...v0.12.0) diff --git a/licenses/BSL.txt b/licenses/BSL.txt index 62ce0655d2..47d08e8a1e 100644 --- a/licenses/BSL.txt +++ b/licenses/BSL.txt @@ -7,7 +7,7 @@ Parameters Licensor: Democratized Data (D2) Foundation -Licensed Work: DefraDB v0.11.0 +Licensed Work: DefraDB v0.13.0 The Licensed Work is (c) 2023 D2 Foundation. @@ -28,7 +28,7 @@ Additional Use Grant: You may only use the Licensed Work for the -Change Date: 2028-06-28 +Change Date: 2028-08-23 Change License: Apache License, Version 2.0