diff --git a/.golangci.yml b/.golangci.yml
index 64275d2..9305561 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -27,6 +27,7 @@ linters:
- gocyclo
- gofmt
- goimports
+ - goheader
- gosimple
- godox
- govet
@@ -56,6 +57,12 @@ linters-settings:
- dot
goimports:
local-prefixes: code.icb4dc0.de/prskr/supabase-operator
+ goheader:
+ values:
+ const:
+ AUTHOR: Peter Kurfer
+ template-path: hack/header.tmpl
+
importas:
no-unaliased: true
no-extra-aliases: true
diff --git a/PROJECT b/PROJECT
index 732e315..49a57b9 100644
--- a/PROJECT
+++ b/PROJECT
@@ -47,4 +47,13 @@ resources:
defaulting: true
validation: true
webhookVersion: v1
+- api:
+ crdVersion: v1
+ namespaced: true
+ controller: true
+ domain: k8s.icb4dc0.de
+ group: supabase
+ kind: Storage
+ path: code.icb4dc0.de/prskr/supabase-operator/api/v1alpha1
+ version: v1alpha1
version: "3"
diff --git a/api/v1alpha1/apigateway_types.go b/api/v1alpha1/apigateway_types.go
index 782679a..e246c33 100644
--- a/api/v1alpha1/apigateway_types.go
+++ b/api/v1alpha1/apigateway_types.go
@@ -1,5 +1,5 @@
/*
-Copyright 2024 Peter Kurfer.
+Copyright 2025 Peter Kurfer.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -54,15 +54,30 @@ type APIGatewaySpec struct {
Envoy *EnvoySpec `json:"envoy"`
// JWKSSelector - selector where the JWKS can be retrieved from to enable the API gateway to validate JWTs
JWKSSelector *corev1.SecretKeySelector `json:"jwks"`
+ // ServiceSelector - selector to match all Supabase services (or in fact EndpointSlices) that should be considered for this APIGateway
+ // +kubebuilder:default={"matchExpressions":{{"key": "app.kubernetes.io/part-of", "operator":"In", "values":{"supabase"}},{"key":"supabase.k8s.icb4dc0.de/api-gateway-target","operator":"Exists"}}}
+ ServiceSelector *metav1.LabelSelector `json:"serviceSelector"`
+ // ComponentTypeLabel - Label to identify which Supabase component a Service represents (e.g. auth, postgrest, ...)
+ // +kubebuilder:default="app.kubernetes.io/name"
+ ComponentTypeLabel string `json:"componentTypeLabel,omitempty"`
+}
+
+type EnvoyStatus struct {
+ ConfigVersion string `json:"configVersion,omitempty"`
+ ResourceHash []byte `json:"resourceHash,omitempty"`
}
// APIGatewayStatus defines the observed state of APIGateway.
-type APIGatewayStatus struct{}
+type APIGatewayStatus struct {
+ Envoy EnvoyStatus `json:"envoy,omitempty"`
+ ServiceTargets map[string][]string `json:"serviceTargets,omitempty"`
+}
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// APIGateway is the Schema for the apigateways API.
+// +kubebuilder:printcolumn:name="EnvoyConfigVersion",type=string,JSONPath=`.status.envoy.configVersion`
type APIGateway struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
diff --git a/api/v1alpha1/storage_types.go b/api/v1alpha1/storage_types.go
new file mode 100644
index 0000000..3b6d376
--- /dev/null
+++ b/api/v1alpha1/storage_types.go
@@ -0,0 +1,64 @@
+/*
+Copyright 2025 Peter Kurfer.
+
+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 v1alpha1
+
+import (
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
+// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
+
+// StorageSpec defines the desired state of Storage.
+type StorageSpec struct {
+ // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
+ // Important: Run "make" to regenerate code after modifying this file
+
+ // Foo is an example field of Storage. Edit storage_types.go to remove/update
+ Foo string `json:"foo,omitempty"`
+}
+
+// StorageStatus defines the observed state of Storage.
+type StorageStatus struct {
+ // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
+ // Important: Run "make" to regenerate code after modifying this file
+}
+
+// +kubebuilder:object:root=true
+// +kubebuilder:subresource:status
+
+// Storage is the Schema for the storages API.
+type Storage struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ObjectMeta `json:"metadata,omitempty"`
+
+ Spec StorageSpec `json:"spec,omitempty"`
+ Status StorageStatus `json:"status,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+
+// StorageList contains a list of Storage.
+type StorageList struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ListMeta `json:"metadata,omitempty"`
+ Items []Storage `json:"items"`
+}
+
+func init() {
+ SchemeBuilder.Register(&Storage{}, &StorageList{})
+}
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 5fe7d9b..cd86b06 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -1,7 +1,7 @@
//go:build !ignore_autogenerated
/*
-Copyright 2024 Peter Kurfer.
+Copyright 2025 Peter Kurfer.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ package v1alpha1
import (
v1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
)
@@ -31,7 +32,7 @@ func (in *APIGateway) DeepCopyInto(out *APIGateway) {
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
- out.Status = in.Status
+ in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIGateway.
@@ -97,6 +98,11 @@ func (in *APIGatewaySpec) DeepCopyInto(out *APIGatewaySpec) {
*out = new(v1.SecretKeySelector)
(*in).DeepCopyInto(*out)
}
+ if in.ServiceSelector != nil {
+ in, out := &in.ServiceSelector, &out.ServiceSelector
+ *out = new(metav1.LabelSelector)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIGatewaySpec.
@@ -112,6 +118,23 @@ func (in *APIGatewaySpec) DeepCopy() *APIGatewaySpec {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *APIGatewayStatus) DeepCopyInto(out *APIGatewayStatus) {
*out = *in
+ in.Envoy.DeepCopyInto(&out.Envoy)
+ if in.ServiceTargets != nil {
+ in, out := &in.ServiceTargets, &out.ServiceTargets
+ *out = make(map[string][]string, len(*in))
+ for key, val := range *in {
+ var outVal []string
+ if val == nil {
+ (*out)[key] = nil
+ } else {
+ inVal := (*in)[key]
+ in, out := &inVal, &outVal
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+ (*out)[key] = outVal
+ }
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIGatewayStatus.
@@ -764,6 +787,26 @@ func (in *EnvoySpec) DeepCopy() *EnvoySpec {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EnvoyStatus) DeepCopyInto(out *EnvoyStatus) {
+ *out = *in
+ if in.ResourceHash != nil {
+ in, out := &in.ResourceHash, &out.ResourceHash
+ *out = make([]byte, len(*in))
+ copy(*out, *in)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyStatus.
+func (in *EnvoyStatus) DeepCopy() *EnvoyStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(EnvoyStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GithubAuthProvider) DeepCopyInto(out *GithubAuthProvider) {
*out = *in
@@ -903,6 +946,95 @@ func (in *PostgrestSpec) DeepCopy() *PostgrestSpec {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *Storage) DeepCopyInto(out *Storage) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ out.Spec = in.Spec
+ out.Status = in.Status
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Storage.
+func (in *Storage) DeepCopy() *Storage {
+ if in == nil {
+ return nil
+ }
+ out := new(Storage)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *Storage) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *StorageList) DeepCopyInto(out *StorageList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ListMeta.DeepCopyInto(&out.ListMeta)
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]Storage, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageList.
+func (in *StorageList) DeepCopy() *StorageList {
+ if in == nil {
+ return nil
+ }
+ out := new(StorageList)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *StorageList) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *StorageSpec) DeepCopyInto(out *StorageSpec) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageSpec.
+func (in *StorageSpec) DeepCopy() *StorageSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(StorageSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *StorageStatus) DeepCopyInto(out *StorageStatus) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageStatus.
+func (in *StorageStatus) DeepCopy() *StorageStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(StorageStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *StudioSpec) DeepCopyInto(out *StudioSpec) {
*out = *in
diff --git a/cmd/control_plane.go b/cmd/control_plane.go
index 1adfd0f..aada234 100644
--- a/cmd/control_plane.go
+++ b/cmd/control_plane.go
@@ -1,5 +1,5 @@
/*
-Copyright 2024 Peter Kurfer.
+Copyright 2025 Peter Kurfer.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,12 +18,11 @@ package main
import (
"context"
- "errors"
+ "crypto/tls"
"fmt"
"net"
"time"
- "github.com/alecthomas/kong"
clusterservice "github.com/envoyproxy/go-control-plane/envoy/service/cluster/v3"
discoverygrpc "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3"
endpointservice "github.com/envoyproxy/go-control-plane/envoy/service/endpoint/v3"
@@ -31,7 +30,7 @@ import (
routeservice "github.com/envoyproxy/go-control-plane/envoy/service/route/v3"
runtimeservice "github.com/envoyproxy/go-control-plane/envoy/service/runtime/v3"
secretservice "github.com/envoyproxy/go-control-plane/envoy/service/secret/v3"
- "github.com/envoyproxy/go-control-plane/pkg/cache/v3"
+ cachev3 "github.com/envoyproxy/go-control-plane/pkg/cache/v3"
"github.com/envoyproxy/go-control-plane/pkg/server/v3"
"google.golang.org/grpc"
grpchealth "google.golang.org/grpc/health"
@@ -39,16 +38,103 @@ import (
"google.golang.org/grpc/keepalive"
"google.golang.org/grpc/reflection"
ctrl "sigs.k8s.io/controller-runtime"
- "sigs.k8s.io/controller-runtime/pkg/client"
+ mgr "sigs.k8s.io/controller-runtime/pkg/manager"
+ "sigs.k8s.io/controller-runtime/pkg/metrics/filters"
+ metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
"code.icb4dc0.de/prskr/supabase-operator/internal/controlplane"
)
+//nolint:lll // flag declaration with struct tags is as long as it is
type controlPlane struct {
- ListenAddr string `name:"listen-address" default:":18000" help:"The address the control plane binds to."`
+ ListenAddr string `name:"listen-address" default:":18000" help:"The address the control plane binds to."`
+ MetricsAddr string `name:"metrics-bind-address" default:"0" help:"The address the metrics endpoint binds to. Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service."`
+ EnableLeaderElection bool `name:"leader-elect" default:"false" help:"Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager."`
+ ProbeAddr string `name:"health-probe-bind-address" default:":8081" help:"The address the probe endpoint binds to."`
+ SecureMetrics bool `name:"metrics-secure" default:"true" help:"If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead."`
+ EnableHTTP2 bool `name:"enable-http2" default:"false" help:"If set, HTTP/2 will be enabled for the metrics and webhook servers"`
}
-func (p controlPlane) Run(ctx context.Context, cache cache.SnapshotCache) (err error) {
+func (cp controlPlane) Run(ctx context.Context) error {
+ var tlsOpts []func(*tls.Config)
+
+ // if the enable-http2 flag is false (the default), http/2 should be disabled
+ // due to its vulnerabilities. More specifically, disabling http/2 will
+ // prevent from being vulnerable to the HTTP/2 Stream Cancellation and
+ // Rapid Reset CVEs. For more information see:
+ // - https://github.com/advisories/GHSA-qppj-fm5r-hxr3
+ // - https://github.com/advisories/GHSA-4374-p667-p6c8
+ disableHTTP2 := func(c *tls.Config) {
+ setupLog.Info("disabling http/2")
+ c.NextProtos = []string{"http/1.1"}
+ }
+
+ if !cp.EnableHTTP2 {
+ tlsOpts = append(tlsOpts, disableHTTP2)
+ }
+
+ // Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server.
+ // More info:
+ // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.1/pkg/metrics/server
+ // - https://book.kubebuilder.io/reference/metrics.html
+ metricsServerOptions := metricsserver.Options{
+ BindAddress: cp.MetricsAddr,
+ SecureServing: cp.SecureMetrics,
+ TLSOpts: tlsOpts,
+ }
+
+ if cp.SecureMetrics {
+ // FilterProvider is used to protect the metrics endpoint with authn/authz.
+ // These configurations ensure that only authorized users and service accounts
+ // can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info:
+ // https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.1/pkg/metrics/filters#WithAuthenticationAndAuthorization
+ metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization
+ }
+
+ mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
+ Scheme: scheme,
+ Metrics: metricsServerOptions,
+ HealthProbeBindAddress: cp.ProbeAddr,
+ LeaderElection: cp.EnableLeaderElection,
+ BaseContext: func() context.Context { return ctx },
+ LeaderElectionID: "30f6fafb.k8s.icb4dc0.de",
+ LeaderElectionReleaseOnCancel: true,
+ })
+ if err != nil {
+ return fmt.Errorf("unable to start control plane: %w", err)
+ }
+
+ envoySnapshotCache := cachev3.NewSnapshotCache(false, cachev3.IDHash{}, nil)
+
+ envoySrv, err := cp.envoyServer(ctx, envoySnapshotCache)
+ if err != nil {
+ return err
+ }
+
+ if err := mgr.Add(envoySrv); err != nil {
+ return fmt.Errorf("failed to add enovy server to manager: %w", err)
+ }
+
+ if err = (&controlplane.APIGatewayReconciler{
+ Client: mgr.GetClient(),
+ Scheme: mgr.GetScheme(),
+ Cache: envoySnapshotCache,
+ }).SetupWithManager(mgr); err != nil {
+ return fmt.Errorf("unable to create controller Core DB: %w", err)
+ }
+
+ setupLog.Info("starting manager")
+ if err := mgr.Start(ctx); err != nil {
+ return fmt.Errorf("problem running manager: %w", err)
+ }
+
+ return nil
+}
+
+func (cp controlPlane) envoyServer(
+ ctx context.Context,
+ cache cachev3.SnapshotCache,
+) (runnable mgr.Runnable, err error) {
const (
grpcKeepaliveTime = 30 * time.Second
grpcKeepaliveTimeout = 5 * time.Second
@@ -56,19 +142,10 @@ func (p controlPlane) Run(ctx context.Context, cache cache.SnapshotCache) (err e
grpcMaxConcurrentStreams = 1000000
)
- logger := ctrl.Log.WithName("control-plane")
-
- clientOpts := client.Options{
- Scheme: scheme,
- }
-
- logger.Info("Creating client")
- watcherClient, err := client.NewWithWatch(ctrl.GetConfigOrDie(), clientOpts)
- if err != nil {
- return err
- }
-
- srv := server.NewServer(ctx, cache, nil)
+ var (
+ logger = ctrl.Log.WithName("control-plane")
+ srv = server.NewServer(ctx, cache, nil)
+ )
// gRPC golang library sets a very small upper bound for the number gRPC/h2
// streams over a single TCP connection. If a proxy multiplexes requests over
@@ -89,13 +166,14 @@ func (p controlPlane) Run(ctx context.Context, cache cache.SnapshotCache) (err e
)
grpcServer := grpc.NewServer(grpcOptions...)
- logger.Info("Opening listener", "addr", p.ListenAddr)
- lis, err := net.Listen("tcp", p.ListenAddr)
+ logger.Info("Opening listener", "addr", cp.ListenAddr)
+ lis, err := net.Listen("tcp", cp.ListenAddr)
if err != nil {
- return fmt.Errorf("opening listener: %w", err)
+ return nil, fmt.Errorf("opening listener: %w", err)
}
logger.Info("Preparing health endpoints")
+
healthService := grpchealth.NewServer()
healthService.SetServingStatus("", grpc_health_v1.HealthCheckResponse_SERVING)
@@ -109,39 +187,11 @@ func (p controlPlane) Run(ctx context.Context, cache cache.SnapshotCache) (err e
runtimeservice.RegisterRuntimeDiscoveryServiceServer(grpcServer, srv)
grpc_health_v1.RegisterHealthServer(grpcServer, healthService)
- // discoverygrpc.AggregatedDiscoveryService_ServiceDesc.ServiceName
-
- endpointsController := controlplane.EndpointsController{
- Client: watcherClient,
- Cache: cache,
- }
-
- errOut := make(chan error)
-
- go func(errOut chan<- error) {
- logger.Info("Starting gRPC server")
- errOut <- grpcServer.Serve(lis)
- }(errOut)
-
- go func(errOut chan<- error) {
- logger.Info("Staring endpoints controller")
- errOut <- endpointsController.Run(ctx)
- }(errOut)
-
- go func(errOut chan error) {
- for out := range errOut {
- err = errors.Join(err, out)
- }
- }(errOut)
-
- <-ctx.Done()
- grpcServer.Stop()
-
- return err
-}
-
-//nolint:unparam // signature required by kong
-func (p controlPlane) AfterApply(kongctx *kong.Context) error {
- kongctx.BindTo(cache.NewSnapshotCache(false, cache.IDHash{}, nil), (*cache.SnapshotCache)(nil))
- return nil
+ return mgr.RunnableFunc(func(ctx context.Context) error {
+ go func(ctx context.Context) {
+ <-ctx.Done()
+ grpcServer.GracefulStop()
+ }(ctx)
+ return grpcServer.Serve(lis)
+ }), nil
}
diff --git a/cmd/manager.go b/cmd/manager.go
index fab0eec..8b96828 100644
--- a/cmd/manager.go
+++ b/cmd/manager.go
@@ -87,23 +87,14 @@ func (m manager) Run(ctx context.Context) error {
}
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
- Scheme: scheme,
- Metrics: metricsServerOptions,
- WebhookServer: webhookServer,
- HealthProbeBindAddress: m.ProbeAddr,
- LeaderElection: m.EnableLeaderElection,
- LeaderElectionID: "05f9463f.k8s.icb4dc0.de",
- // LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily
- // when the Manager ends. This requires the binary to immediately end when the
- // Manager is stopped, otherwise, this setting is unsafe. Setting this significantly
- // speeds up voluntary leader transitions as the new leader don't have to wait
- // LeaseDuration time first.
- //
- // In the default scaffold provided, the program ends immediately after
- // the manager stops, so would be fine to enable this option. However,
- // if you are doing or is intended to do any operation such as perform cleanups
- // after the manager stops then its usage might be unsafe.
- // LeaderElectionReleaseOnCancel: true,
+ Scheme: scheme,
+ Metrics: metricsServerOptions,
+ WebhookServer: webhookServer,
+ HealthProbeBindAddress: m.ProbeAddr,
+ LeaderElection: m.EnableLeaderElection,
+ BaseContext: func() context.Context { return ctx },
+ LeaderElectionID: "05f9463f.k8s.icb4dc0.de",
+ LeaderElectionReleaseOnCancel: true,
})
if err != nil {
return fmt.Errorf("unable to start manager: %w", err)
diff --git a/config/crd/bases/supabase.k8s.icb4dc0.de_apigateways.yaml b/config/crd/bases/supabase.k8s.icb4dc0.de_apigateways.yaml
index 36709d4..939e2cf 100644
--- a/config/crd/bases/supabase.k8s.icb4dc0.de_apigateways.yaml
+++ b/config/crd/bases/supabase.k8s.icb4dc0.de_apigateways.yaml
@@ -14,7 +14,11 @@ spec:
singular: apigateway
scope: Namespaced
versions:
- - name: v1alpha1
+ - additionalPrinterColumns:
+ - jsonPath: .status.envoy.configVersion
+ name: EnvoyConfigVersion
+ type: string
+ name: v1alpha1
schema:
openAPIV3Schema:
description: APIGateway is the Schema for the apigateways API.
@@ -39,6 +43,11 @@ spec:
spec:
description: APIGatewaySpec defines the desired state of APIGateway.
properties:
+ componentTypeLabel:
+ default: app.kubernetes.io/name
+ description: ComponentTypeLabel - Label to identify which Supabase
+ component a Service represents (e.g. auth, postgrest, ...)
+ type: string
envoy:
description: Envoy - configure the envoy instance and most importantly
the control-plane
@@ -61,6 +70,12 @@ spec:
- host
- port
type: object
+ nodeName:
+ description: |-
+ NodeName - identifies the Envoy cluster within the current namespace
+ if not set, the name of the APIGateway resource will be used
+ The primary use case is to make the assignment of multiple supabase instances in a single namespace explicit.
+ type: string
workloadTemplate:
description: WorkloadTemplate - customize the Envoy deployment
properties:
@@ -776,12 +791,83 @@ spec:
- key
type: object
x-kubernetes-map-type: atomic
+ serviceSelector:
+ default:
+ matchExpressions:
+ - key: app.kubernetes.io/part-of
+ operator: In
+ values:
+ - supabase
+ - key: supabase.k8s.icb4dc0.de/api-gateway-target
+ operator: Exists
+ description: ServiceSelector - selector to match all Supabase services
+ (or in fact EndpointSlices) that should be considered for this APIGateway
+ properties:
+ matchExpressions:
+ description: matchExpressions is a list of label selector requirements.
+ The requirements are ANDed.
+ items:
+ description: |-
+ A label selector requirement is a selector that contains values, a key, and an operator that
+ relates the key and values.
+ properties:
+ key:
+ description: key is the label key that the selector applies
+ to.
+ type: string
+ operator:
+ description: |-
+ operator represents a key's relationship to a set of values.
+ Valid operators are In, NotIn, Exists and DoesNotExist.
+ type: string
+ values:
+ description: |-
+ values is an array of string values. If the operator is In or NotIn,
+ the values array must be non-empty. If the operator is Exists or DoesNotExist,
+ the values array must be empty. This array is replaced during a strategic
+ merge patch.
+ items:
+ type: string
+ type: array
+ x-kubernetes-list-type: atomic
+ required:
+ - key
+ - operator
+ type: object
+ type: array
+ x-kubernetes-list-type: atomic
+ matchLabels:
+ additionalProperties:
+ type: string
+ description: |-
+ matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
+ map is equivalent to an element of matchExpressions, whose key field is "key", the
+ operator is "In", and the values array contains only "value". The requirements are ANDed.
+ type: object
+ type: object
+ x-kubernetes-map-type: atomic
required:
- envoy
- jwks
+ - serviceSelector
type: object
status:
description: APIGatewayStatus defines the observed state of APIGateway.
+ properties:
+ envoy:
+ properties:
+ configVersion:
+ type: string
+ resourceHash:
+ format: byte
+ type: string
+ type: object
+ serviceTargets:
+ additionalProperties:
+ items:
+ type: string
+ type: array
+ type: object
type: object
type: object
served: true
diff --git a/config/crd/bases/supabase.k8s.icb4dc0.de_storages.yaml b/config/crd/bases/supabase.k8s.icb4dc0.de_storages.yaml
new file mode 100644
index 0000000..7d0791f
--- /dev/null
+++ b/config/crd/bases/supabase.k8s.icb4dc0.de_storages.yaml
@@ -0,0 +1,54 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.16.5
+ name: storages.supabase.k8s.icb4dc0.de
+spec:
+ group: supabase.k8s.icb4dc0.de
+ names:
+ kind: Storage
+ listKind: StorageList
+ plural: storages
+ singular: storage
+ scope: Namespaced
+ versions:
+ - name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ description: Storage is the Schema for the storages API.
+ properties:
+ apiVersion:
+ description: |-
+ APIVersion defines the versioned schema of this representation of an object.
+ Servers should convert recognized schemas to the latest internal value, and
+ may reject unrecognized values.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+ type: string
+ kind:
+ description: |-
+ Kind is a string value representing the REST resource this object represents.
+ Servers may infer this from the endpoint the client submits requests to.
+ Cannot be updated.
+ In CamelCase.
+ More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: StorageSpec defines the desired state of Storage.
+ properties:
+ foo:
+ description: Foo is an example field of Storage. Edit storage_types.go
+ to remove/update
+ type: string
+ type: object
+ status:
+ description: StorageStatus defines the observed state of Storage.
+ type: object
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml
index cc2769b..fa629d2 100644
--- a/config/crd/kustomization.yaml
+++ b/config/crd/kustomization.yaml
@@ -5,6 +5,7 @@ resources:
- bases/supabase.k8s.icb4dc0.de_cores.yaml
- bases/supabase.k8s.icb4dc0.de_apigateways.yaml
- bases/supabase.k8s.icb4dc0.de_dashboards.yaml
+ - bases/supabase.k8s.icb4dc0.de_storages.yaml
# +kubebuilder:scaffold:crdkustomizeresource
patches:
diff --git a/config/rbac/control-plane-role.yaml b/config/rbac/control-plane-role.yaml
index e85f47b..9bccf5c 100644
--- a/config/rbac/control-plane-role.yaml
+++ b/config/rbac/control-plane-role.yaml
@@ -4,6 +4,23 @@ kind: ClusterRole
metadata:
name: control-plane-role
rules:
+ - apiGroups:
+ - supabase.k8s.icb4dc0.de
+ resources:
+ - apigateways
+ verbs:
+ - get
+ - list
+ - watch
+ - apiGroups:
+ - supabase.k8s.icb4dc0.de
+ resources:
+ - apigateways/status
+ verbs:
+ - get
+ - patch
+ - update
+
- apiGroups:
- discovery.k8s.io
resources:
diff --git a/config/rbac/kustomization.yaml b/config/rbac/kustomization.yaml
index 37a83d4..76bbd52 100644
--- a/config/rbac/kustomization.yaml
+++ b/config/rbac/kustomization.yaml
@@ -36,3 +36,10 @@ resources:
# if you do not want those helpers be installed with your Project.
- dashboard_editor_role.yaml
- dashboard_viewer_role.yaml
+ # For each CRD, "Admin", "Editor" and "Viewer" roles are scaffolded by
+ # default, aiding admins in cluster management. Those roles are
+ # not used by the {{ .ProjectName }} itself. You can comment the following lines
+ # if you do not want those helpers be installed with your Project.
+ - storage_admin_role.yaml
+ - storage_editor_role.yaml
+ - storage_viewer_role.yaml
diff --git a/config/rbac/leader_election_role_binding.yaml b/config/rbac/leader_election_role_binding.yaml
index 60907a6..1c6ae09 100644
--- a/config/rbac/leader_election_role_binding.yaml
+++ b/config/rbac/leader_election_role_binding.yaml
@@ -13,3 +13,6 @@ subjects:
- kind: ServiceAccount
name: controller-manager
namespace: supabase-system
+ - kind: ServiceAccount
+ name: control-plane
+ namespace: supabase-system
diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml
index a47705e..d59b600 100644
--- a/config/rbac/role.yaml
+++ b/config/rbac/role.yaml
@@ -42,6 +42,7 @@ rules:
- apigateways
- cores
- dashboards
+ - storages
verbs:
- create
- delete
@@ -56,6 +57,7 @@ rules:
- apigateways/finalizers
- cores/finalizers
- dashboards/finalizers
+ - storages/finalizers
verbs:
- update
- apiGroups:
@@ -64,6 +66,7 @@ rules:
- apigateways/status
- cores/status
- dashboards/status
+ - storages/status
verbs:
- get
- patch
diff --git a/config/rbac/storage_admin_role.yaml b/config/rbac/storage_admin_role.yaml
new file mode 100644
index 0000000..18ad774
--- /dev/null
+++ b/config/rbac/storage_admin_role.yaml
@@ -0,0 +1,27 @@
+# This rule is not used by the project supabase-operator itself.
+# It is provided to allow the cluster admin to help manage permissions for users.
+#
+# Grants full permissions ('*') over supabase.k8s.icb4dc0.de.
+# This role is intended for users authorized to modify roles and bindings within the cluster,
+# enabling them to delegate specific permissions to other users or groups as needed.
+
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ app.kubernetes.io/name: supabase-operator
+ app.kubernetes.io/managed-by: kustomize
+ name: storage-admin-role
+rules:
+- apiGroups:
+ - supabase.k8s.icb4dc0.de
+ resources:
+ - storages
+ verbs:
+ - '*'
+- apiGroups:
+ - supabase.k8s.icb4dc0.de
+ resources:
+ - storages/status
+ verbs:
+ - get
diff --git a/config/rbac/storage_editor_role.yaml b/config/rbac/storage_editor_role.yaml
new file mode 100644
index 0000000..29500f0
--- /dev/null
+++ b/config/rbac/storage_editor_role.yaml
@@ -0,0 +1,33 @@
+# This rule is not used by the project supabase-operator itself.
+# It is provided to allow the cluster admin to help manage permissions for users.
+#
+# Grants permissions to create, update, and delete resources within the supabase.k8s.icb4dc0.de.
+# This role is intended for users who need to manage these resources
+# but should not control RBAC or manage permissions for others.
+
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ app.kubernetes.io/name: supabase-operator
+ app.kubernetes.io/managed-by: kustomize
+ name: storage-editor-role
+rules:
+- apiGroups:
+ - supabase.k8s.icb4dc0.de
+ resources:
+ - storages
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - supabase.k8s.icb4dc0.de
+ resources:
+ - storages/status
+ verbs:
+ - get
diff --git a/config/rbac/storage_viewer_role.yaml b/config/rbac/storage_viewer_role.yaml
new file mode 100644
index 0000000..aca70f9
--- /dev/null
+++ b/config/rbac/storage_viewer_role.yaml
@@ -0,0 +1,29 @@
+# This rule is not used by the project supabase-operator itself.
+# It is provided to allow the cluster admin to help manage permissions for users.
+#
+# Grants read-only access to supabase.k8s.icb4dc0.de resources.
+# This role is intended for users who need visibility into these resources
+# without permissions to modify them. It is ideal for monitoring purposes and limited-access viewing.
+
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ labels:
+ app.kubernetes.io/name: supabase-operator
+ app.kubernetes.io/managed-by: kustomize
+ name: storage-viewer-role
+rules:
+- apiGroups:
+ - supabase.k8s.icb4dc0.de
+ resources:
+ - storages
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - supabase.k8s.icb4dc0.de
+ resources:
+ - storages/status
+ verbs:
+ - get
diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml
index e32f0fd..74dba7c 100644
--- a/config/samples/kustomization.yaml
+++ b/config/samples/kustomization.yaml
@@ -8,4 +8,5 @@ resources:
- supabase_v1alpha1_core.yaml
- supabase_v1alpha1_apigateway.yaml
- supabase_v1alpha1_dashboard.yaml
+ - supabase_v1alpha1_storage.yaml
# +kubebuilder:scaffold:manifestskustomizesamples
diff --git a/config/samples/supabase_v1alpha1_storage.yaml b/config/samples/supabase_v1alpha1_storage.yaml
new file mode 100644
index 0000000..fc5cd56
--- /dev/null
+++ b/config/samples/supabase_v1alpha1_storage.yaml
@@ -0,0 +1,9 @@
+apiVersion: supabase.k8s.icb4dc0.de/v1alpha1
+kind: Storage
+metadata:
+ labels:
+ app.kubernetes.io/name: supabase-operator
+ app.kubernetes.io/managed-by: kustomize
+ name: storage-sample
+spec:
+ # TODO(user): Add fields here
diff --git a/hack/boilerplate.go.txt b/hack/boilerplate.go.txt
index bb2d4b9..6ca537d 100644
--- a/hack/boilerplate.go.txt
+++ b/hack/boilerplate.go.txt
@@ -1,5 +1,5 @@
/*
-Copyright 2024 Peter Kurfer.
+Copyright 2025 Peter Kurfer.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -12,4 +12,4 @@ 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.
-*/
\ No newline at end of file
+*/
diff --git a/hack/header.tmpl b/hack/header.tmpl
new file mode 100644
index 0000000..2a46de8
--- /dev/null
+++ b/hack/header.tmpl
@@ -0,0 +1,13 @@
+Copyright {{ YEAR }} {{ AUTHOR }}.
+
+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.
diff --git a/internal/controller/apigateway_controller.go b/internal/controller/apigateway_controller.go
index a598687..490b2f9 100644
--- a/internal/controller/apigateway_controller.go
+++ b/internal/controller/apigateway_controller.go
@@ -1,5 +1,5 @@
/*
-Copyright 2024 Peter Kurfer.
+Copyright 2025 Peter Kurfer.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/internal/controller/core_db_controller.go b/internal/controller/core_db_controller.go
index 050a2d8..440d362 100644
--- a/internal/controller/core_db_controller.go
+++ b/internal/controller/core_db_controller.go
@@ -1,5 +1,5 @@
/*
-Copyright 2024 Peter Kurfer.
+Copyright 2025 Peter Kurfer.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/internal/controller/core_gotrue_controller.go b/internal/controller/core_gotrue_controller.go
index 8d28278..5d92bd6 100644
--- a/internal/controller/core_gotrue_controller.go
+++ b/internal/controller/core_gotrue_controller.go
@@ -221,8 +221,8 @@ func (r *CoreAuthReconciler) reconcileAuthService(
core.Labels,
)
- if _, ok := authService.Labels[meta.SupabaseLabel.EnvoyCluster]; !ok {
- authService.Labels[meta.SupabaseLabel.EnvoyCluster] = core.Name
+ if _, ok := authService.Labels[meta.SupabaseLabel.ApiGatewayTarget]; !ok {
+ authService.Labels[meta.SupabaseLabel.ApiGatewayTarget] = core.Name
}
authService.Spec = corev1.ServiceSpec{
diff --git a/internal/controller/core_postgrest_controller.go b/internal/controller/core_postgrest_controller.go
index b4deda2..dbc1751 100644
--- a/internal/controller/core_postgrest_controller.go
+++ b/internal/controller/core_postgrest_controller.go
@@ -228,8 +228,8 @@ func (r *CorePostgrestReconiler) reconcilePostgrestService(
core.Labels,
)
- if _, ok := postgrestService.Labels[meta.SupabaseLabel.EnvoyCluster]; !ok {
- postgrestService.Labels[meta.SupabaseLabel.EnvoyCluster] = core.Name
+ if _, ok := postgrestService.Labels[meta.SupabaseLabel.ApiGatewayTarget]; !ok {
+ postgrestService.Labels[meta.SupabaseLabel.ApiGatewayTarget] = ""
}
postgrestService.Spec = corev1.ServiceSpec{
diff --git a/internal/controller/dashboard_pg-meta_controller.go b/internal/controller/dashboard_pg-meta_controller.go
index ef08215..0ca6db3 100644
--- a/internal/controller/dashboard_pg-meta_controller.go
+++ b/internal/controller/dashboard_pg-meta_controller.go
@@ -196,8 +196,8 @@ func (r *DashboardPGMetaReconciler) reconcilePGMetaService(
dashboard.Labels,
)
- if _, ok := pgMetaService.Labels[meta.SupabaseLabel.EnvoyCluster]; !ok {
- pgMetaService.Labels[meta.SupabaseLabel.EnvoyCluster] = dashboard.Name
+ if _, ok := pgMetaService.Labels[meta.SupabaseLabel.ApiGatewayTarget]; !ok {
+ pgMetaService.Labels[meta.SupabaseLabel.ApiGatewayTarget] = ""
}
pgMetaService.Spec = corev1.ServiceSpec{
diff --git a/internal/controller/dashboard_studio_controller.go b/internal/controller/dashboard_studio_controller.go
index 25f1191..097ed38 100644
--- a/internal/controller/dashboard_studio_controller.go
+++ b/internal/controller/dashboard_studio_controller.go
@@ -218,8 +218,8 @@ func (r *DashboardStudioReconciler) reconcileStudioService(
dashboard.Labels,
)
- if _, ok := studioService.Labels[meta.SupabaseLabel.EnvoyCluster]; !ok {
- studioService.Labels[meta.SupabaseLabel.EnvoyCluster] = dashboard.Name
+ if _, ok := studioService.Labels[meta.SupabaseLabel.ApiGatewayTarget]; !ok {
+ studioService.Labels[meta.SupabaseLabel.ApiGatewayTarget] = ""
}
studioService.Spec = corev1.ServiceSpec{
diff --git a/internal/controller/pwgen.go b/internal/controller/pwgen.go
index 6e0cbde..d59f0bc 100644
--- a/internal/controller/pwgen.go
+++ b/internal/controller/pwgen.go
@@ -1,3 +1,19 @@
+// /*
+// Copyright 2025 Peter Kurfer.
+//
+// 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 controller
import (
diff --git a/internal/controller/storage_controller.go b/internal/controller/storage_controller.go
new file mode 100644
index 0000000..084af06
--- /dev/null
+++ b/internal/controller/storage_controller.go
@@ -0,0 +1,63 @@
+/*
+Copyright 2025 Peter Kurfer.
+
+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 controller
+
+import (
+ "context"
+
+ "k8s.io/apimachinery/pkg/runtime"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/log"
+
+ supabasev1alpha1 "code.icb4dc0.de/prskr/supabase-operator/api/v1alpha1"
+)
+
+// StorageReconciler reconciles a Storage object
+type StorageReconciler struct {
+ client.Client
+ Scheme *runtime.Scheme
+}
+
+// +kubebuilder:rbac:groups=supabase.k8s.icb4dc0.de,resources=storages,verbs=get;list;watch;create;update;patch;delete
+// +kubebuilder:rbac:groups=supabase.k8s.icb4dc0.de,resources=storages/status,verbs=get;update;patch
+// +kubebuilder:rbac:groups=supabase.k8s.icb4dc0.de,resources=storages/finalizers,verbs=update
+
+// Reconcile is part of the main kubernetes reconciliation loop which aims to
+// move the current state of the cluster closer to the desired state.
+// TODO(user): Modify the Reconcile function to compare the state specified by
+// the Storage object against the actual cluster state, and then
+// perform operations to make the cluster state reflect the state specified by
+// the user.
+//
+// For more details, check Reconcile and its Result here:
+// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.4/pkg/reconcile
+func (r *StorageReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
+ _ = log.FromContext(ctx)
+
+ // TODO(user): your logic here
+
+ return ctrl.Result{}, nil
+}
+
+// SetupWithManager sets up the controller with the Manager.
+func (r *StorageReconciler) SetupWithManager(mgr ctrl.Manager) error {
+ return ctrl.NewControllerManagedBy(mgr).
+ For(&supabasev1alpha1.Storage{}).
+ Named("storage").
+ Complete(r)
+}
diff --git a/internal/controller/storage_controller_test.go b/internal/controller/storage_controller_test.go
new file mode 100644
index 0000000..a081e1e
--- /dev/null
+++ b/internal/controller/storage_controller_test.go
@@ -0,0 +1,84 @@
+/*
+Copyright 2025 Peter Kurfer.
+
+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 controller
+
+import (
+ "context"
+
+ . "github.com/onsi/ginkgo/v2"
+ . "github.com/onsi/gomega"
+ "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/types"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
+
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+ supabasev1alpha1 "code.icb4dc0.de/prskr/supabase-operator/api/v1alpha1"
+)
+
+var _ = Describe("Storage Controller", func() {
+ Context("When reconciling a resource", func() {
+ const resourceName = "test-resource"
+
+ ctx := context.Background()
+
+ typeNamespacedName := types.NamespacedName{
+ Name: resourceName,
+ Namespace: "default", // TODO(user):Modify as needed
+ }
+ storage := &supabasev1alpha1.Storage{}
+
+ BeforeEach(func() {
+ By("creating the custom resource for the Kind Storage")
+ err := k8sClient.Get(ctx, typeNamespacedName, storage)
+ if err != nil && errors.IsNotFound(err) {
+ resource := &supabasev1alpha1.Storage{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: resourceName,
+ Namespace: "default",
+ },
+ // TODO(user): Specify other spec details if needed.
+ }
+ Expect(k8sClient.Create(ctx, resource)).To(Succeed())
+ }
+ })
+
+ AfterEach(func() {
+ // TODO(user): Cleanup logic after each test, like removing the resource instance.
+ resource := &supabasev1alpha1.Storage{}
+ err := k8sClient.Get(ctx, typeNamespacedName, resource)
+ Expect(err).NotTo(HaveOccurred())
+
+ By("Cleanup the specific resource instance Storage")
+ Expect(k8sClient.Delete(ctx, resource)).To(Succeed())
+ })
+ It("should successfully reconcile the resource", func() {
+ By("Reconciling the created resource")
+ controllerReconciler := &StorageReconciler{
+ Client: k8sClient,
+ Scheme: k8sClient.Scheme(),
+ }
+
+ _, err := controllerReconciler.Reconcile(ctx, reconcile.Request{
+ NamespacedName: typeNamespacedName,
+ })
+ Expect(err).NotTo(HaveOccurred())
+ // TODO(user): Add more specific assertions depending on your controller's reconciliation logic.
+ // Example: If you expect a certain status condition after reconciliation, verify it here.
+ })
+ })
+})
diff --git a/internal/controlplane/apigateway_controller.go b/internal/controlplane/apigateway_controller.go
new file mode 100644
index 0000000..54cd759
--- /dev/null
+++ b/internal/controlplane/apigateway_controller.go
@@ -0,0 +1,197 @@
+/*
+Copyright 2025 Peter Kurfer.
+
+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 controlplane
+
+import (
+ "bytes"
+ "context"
+ "crypto/sha256"
+ "encoding/json"
+ "fmt"
+ "strconv"
+ "strings"
+ "time"
+
+ cachev3 "github.com/envoyproxy/go-control-plane/pkg/cache/v3"
+ discoveryv1 "k8s.io/api/discovery/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/types"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/builder"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
+ "sigs.k8s.io/controller-runtime/pkg/handler"
+ "sigs.k8s.io/controller-runtime/pkg/log"
+ "sigs.k8s.io/controller-runtime/pkg/predicate"
+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
+
+ supabasev1alpha1 "code.icb4dc0.de/prskr/supabase-operator/api/v1alpha1"
+ "code.icb4dc0.de/prskr/supabase-operator/internal/meta"
+)
+
+// APIGatewayReconciler reconciles a APIGateway object
+type APIGatewayReconciler struct {
+ client.Client
+ Scheme *runtime.Scheme
+ Cache cachev3.SnapshotCache
+}
+
+// Reconcile is part of the main kubernetes reconciliation loop which aims to
+// move the current state of the cluster closer to the desired state.
+//
+// For more details, check Reconcile and its Result here:
+// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.1/pkg/reconcile
+func (r *APIGatewayReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.Result, err error) {
+ var (
+ gateway supabasev1alpha1.APIGateway
+ logger = log.FromContext(ctx)
+ endpointSliceList discoveryv1.EndpointSliceList
+ )
+
+ logger.Info("Reconciling APIGateway")
+
+ if err := r.Get(ctx, req.NamespacedName, &gateway); client.IgnoreNotFound(err) != nil {
+ logger.Error(err, "unable to fetch Gateway")
+ return ctrl.Result{}, err
+ }
+
+ selector, err := metav1.LabelSelectorAsSelector(gateway.Spec.ServiceSelector)
+ if err != nil {
+ return ctrl.Result{}, fmt.Errorf("failed to create selector for EndpointSlices: %w", err)
+ }
+
+ if err := r.List(ctx, &endpointSliceList, client.MatchingLabelsSelector{Selector: selector}); err != nil {
+ return ctrl.Result{}, err
+ }
+
+ services := EnvoyServices{ServiceLabelKey: gateway.Spec.ComponentTypeLabel}
+ services.UpsertEndpointSlices(endpointSliceList.Items...)
+
+ rawServices, err := json.Marshal(services)
+ if err != nil {
+ return ctrl.Result{}, fmt.Errorf("failed to prepare config hash: %w", err)
+ }
+
+ serviceHash := sha256.New().Sum(rawServices)
+ if bytes.Equal(serviceHash, gateway.Status.Envoy.ResourceHash) {
+ logger.Info("Resource hash did not change - skipping reconciliation")
+ return ctrl.Result{}, nil
+ }
+
+ logger.Info("Updating service targets")
+ _, err = controllerutil.CreateOrPatch(ctx, r.Client, &gateway, func() error {
+ gateway.Status.ServiceTargets = services.Targets()
+ gateway.Status.Envoy.ConfigVersion = strconv.FormatInt(time.Now().UTC().UnixMilli(), 10)
+ gateway.Status.Envoy.ResourceHash = serviceHash
+
+ return nil
+ })
+ if err != nil {
+ return ctrl.Result{}, err
+ }
+
+ instance := fmt.Sprintf("%s:%s", gateway.Spec.Envoy.NodeName, gateway.Namespace)
+
+ logger.Info("Computing Envoy snapshot for current service targets", "version", gateway.Status.Envoy.ConfigVersion)
+ snapshot, err := services.snapshot(ctx, instance, gateway.Status.Envoy.ConfigVersion)
+ if err != nil {
+ return ctrl.Result{}, fmt.Errorf("failed to prepare snapshot: %w", err)
+ }
+
+ logger.Info("Propagating Envoy snapshot", "version", gateway.Status.Envoy.ConfigVersion)
+ if err := r.Cache.SetSnapshot(ctx, instance, snapshot); err != nil {
+ return ctrl.Result{}, fmt.Errorf("failed to propagate snapshot: %w", err)
+ }
+
+ return ctrl.Result{}, nil
+}
+
+func (r *APIGatewayReconciler) SetupWithManager(mgr ctrl.Manager) error {
+ gatewayTargetLabelSelector, err := predicate.LabelSelectorPredicate(metav1.LabelSelector{
+ MatchExpressions: []metav1.LabelSelectorRequirement{{
+ Key: meta.SupabaseLabel.ApiGatewayTarget,
+ Operator: metav1.LabelSelectorOpExists,
+ }},
+ })
+ if err != nil {
+ return fmt.Errorf("failed to build gateway target predicate: %w", err)
+ }
+
+ return ctrl.NewControllerManagedBy(mgr).
+ For(new(supabasev1alpha1.APIGateway)).
+ Watches(
+ new(discoveryv1.EndpointSlice),
+ r.endpointSliceEventHandler(),
+ builder.WithPredicates(gatewayTargetLabelSelector)).
+ Complete(r)
+}
+
+// endpointSliceEventHandler - prepares an event handler that checks whether the EndpointSlice has a specific target
+// or if it is targeting the only APIGateway in its namespace (default behavior for the operator)
+func (r *APIGatewayReconciler) endpointSliceEventHandler() handler.TypedEventHandler[client.Object, reconcile.Request] {
+ return handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, obj client.Object) []reconcile.Request {
+ var (
+ logger = log.FromContext(ctx)
+ apiGatewayList supabasev1alpha1.APIGatewayList
+ )
+
+ endpointSlice, ok := obj.(*discoveryv1.EndpointSlice)
+ if !ok {
+ logger.Info("Cannot map event to reconcile request, because object has unexpected type", "type", fmt.Sprintf("%T", obj))
+ return nil
+ }
+
+ if err := r.Client.List(ctx, &apiGatewayList, client.InNamespace(endpointSlice.Namespace)); err != nil {
+ logger.Error(err, "failed to list APIGateways to determine reconcile targets")
+ return nil
+ }
+
+ target, ok := endpointSlice.Labels[meta.SupabaseLabel.ApiGatewayTarget]
+ if !ok {
+ // should not happen, just to be sure
+ return nil
+ }
+
+ var reconcileRequests []reconcile.Request
+
+ if target != "" {
+ for _, gw := range apiGatewayList.Items {
+ if strings.EqualFold(gw.Spec.Envoy.NodeName, target) {
+ reconcileRequests = append(reconcileRequests, reconcile.Request{
+ NamespacedName: types.NamespacedName{
+ Name: gw.Name,
+ Namespace: gw.Namespace,
+ },
+ })
+ }
+ }
+ } else {
+ reconcileRequests = make([]reconcile.Request, 0, len(apiGatewayList.Items))
+ for _, gw := range apiGatewayList.Items {
+ reconcileRequests = append(reconcileRequests, reconcile.Request{
+ NamespacedName: types.NamespacedName{
+ Name: gw.Name,
+ Namespace: gw.Namespace,
+ },
+ })
+ }
+ }
+
+ return reconcileRequests
+ })
+}
diff --git a/internal/controlplane/endpoints.go b/internal/controlplane/endpoints.go
index 5890c4e..c7149bc 100644
--- a/internal/controlplane/endpoints.go
+++ b/internal/controlplane/endpoints.go
@@ -1,6 +1,10 @@
package controlplane
import (
+ "encoding/json"
+ "fmt"
+ "slices"
+ "strings"
"time"
clusterv3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"
@@ -10,11 +14,28 @@ import (
discoveryv1 "k8s.io/api/discovery/v1"
)
+var _ json.Marshaler = (*ServiceCluster)(nil)
+
type ServiceCluster struct {
ServiceEndpoints map[string]Endpoints
}
-func (c *ServiceCluster) AddOrUpdateEndpoints(eps *discoveryv1.EndpointSlice) {
+// MarshalJSON implements json.Marshaler.
+func (c *ServiceCluster) MarshalJSON() ([]byte, error) {
+ tmp := struct {
+ Endpoints []string `json:"endpoints"`
+ }{}
+
+ for _, endpoints := range c.ServiceEndpoints {
+ tmp.Endpoints = append(tmp.Endpoints, endpoints.Targets...)
+ }
+
+ slices.Sort(tmp.Endpoints)
+
+ return json.Marshal(tmp)
+}
+
+func (c *ServiceCluster) AddOrUpdateEndpoints(eps discoveryv1.EndpointSlice) {
if c.ServiceEndpoints == nil {
c.ServiceEndpoints = make(map[string]Endpoints)
}
@@ -22,6 +43,16 @@ func (c *ServiceCluster) AddOrUpdateEndpoints(eps *discoveryv1.EndpointSlice) {
c.ServiceEndpoints[eps.Name] = newEndpointsFromSlice(eps)
}
+func (c ServiceCluster) Targets() []string {
+ var targets []string
+
+ for _, ep := range c.ServiceEndpoints {
+ targets = append(targets, ep.Targets...)
+ }
+
+ return targets
+}
+
func (c ServiceCluster) Cluster(name string, port uint32) *clusterv3.Cluster {
return &clusterv3.Cluster{
Name: name,
@@ -47,12 +78,13 @@ func (c ServiceCluster) endpoints(port uint32) []*endpointv3.LocalityLbEndpoints
return eps
}
-func newEndpointsFromSlice(eps *discoveryv1.EndpointSlice) Endpoints {
+func newEndpointsFromSlice(eps discoveryv1.EndpointSlice) Endpoints {
var result Endpoints
for _, ep := range eps.Endpoints {
if ep.Conditions.Ready != nil && *ep.Conditions.Ready {
result.Addresses = append(result.Addresses, ep.Addresses...)
+ result.Targets = append(result.Targets, strings.ToLower(fmt.Sprintf("%s/%s", ep.TargetRef.Kind, ep.TargetRef.Name)))
}
}
@@ -61,6 +93,7 @@ func newEndpointsFromSlice(eps *discoveryv1.EndpointSlice) Endpoints {
type Endpoints struct {
Addresses []string
+ Targets []string
}
func (e Endpoints) LBEndpoints(port uint32) []*endpointv3.LbEndpoint {
diff --git a/internal/controlplane/controller.go b/internal/controlplane/snapshot.go
similarity index 54%
rename from internal/controlplane/controller.go
rename to internal/controlplane/snapshot.go
index 272d1e1..004ebd5 100644
--- a/internal/controlplane/controller.go
+++ b/internal/controlplane/snapshot.go
@@ -1,29 +1,8 @@
-/*
-Copyright 2024 Peter Kurfer.
-
-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 controlplane
import (
"context"
- "errors"
- "fmt"
"slices"
- "strconv"
- "sync"
- "time"
corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
listenerv3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
@@ -35,171 +14,64 @@ import (
"github.com/envoyproxy/go-control-plane/pkg/resource/v3"
"google.golang.org/protobuf/types/known/anypb"
discoveryv1 "k8s.io/api/discovery/v1"
- "k8s.io/apimachinery/pkg/labels"
- "k8s.io/apimachinery/pkg/selection"
- "k8s.io/apimachinery/pkg/watch"
- ctrl "sigs.k8s.io/controller-runtime"
- "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
- "code.icb4dc0.de/prskr/supabase-operator/internal/meta"
"code.icb4dc0.de/prskr/supabase-operator/internal/supabase"
)
-var (
- ErrUnexpectedObject = errors.New("unexpected object")
- ErrNoEnvoyClusterLabel = errors.New("no Envoy cluster label set")
-
- supabaseServices = []string{
- supabase.ServiceConfig.Postgrest.Name,
- supabase.ServiceConfig.Auth.Name,
- supabase.ServiceConfig.PGMeta.Name,
- }
-)
-
-type EndpointsController struct {
- lock sync.Mutex
- Client client.WithWatch
- Cache cache.SnapshotCache
- envoyClusters map[string]*envoyClusterServices
+type EnvoyServices struct {
+ ServiceLabelKey string `json:"-"`
+ Postgrest *PostgrestCluster `json:"postgrest,omitempty"`
+ GoTrue *GoTrueCluster `json:"auth,omitempty"`
+ PGMeta *PGMetaCluster `json:"pgmeta,omitempty"`
+ Studio *StudioCluster `json:"studio,omitempty"`
}
-func (c *EndpointsController) Run(ctx context.Context) error {
- var (
- logger = ctrl.Log.WithName("endpoints-controller")
- endpointSlices discoveryv1.EndpointSliceList
- )
-
- selector := labels.NewSelector()
-
- partOfRequirement, err := labels.NewRequirement(meta.WellKnownLabel.PartOf, selection.Equals, []string{"supabase"})
- if err != nil {
- return fmt.Errorf("preparing watcher selectors: %w", err)
- }
-
- nameRequirement, err := labels.NewRequirement(meta.WellKnownLabel.Name, selection.In, supabaseServices)
- if err != nil {
- return fmt.Errorf("preparing watcher selectors: %w", err)
- }
-
- envoyClusterRequirement, err := labels.NewRequirement(meta.SupabaseLabel.EnvoyCluster, selection.Exists, nil)
- if err != nil {
- return fmt.Errorf("preparing watcher selectors: %w", err)
- }
-
- selector.Add(*partOfRequirement, *nameRequirement, *envoyClusterRequirement)
-
- watcher, err := c.Client.Watch(
- ctx,
- &endpointSlices,
- client.MatchingLabelsSelector{
- Selector: selector.Add(*partOfRequirement, *nameRequirement, *envoyClusterRequirement),
- },
- )
- if err != nil {
- return err
- }
-
- defer watcher.Stop()
-
- for {
- select {
- case ev, more := <-watcher.ResultChan():
- if !more {
- return nil
+func (s *EnvoyServices) UpsertEndpointSlices(endpointSlices ...discoveryv1.EndpointSlice) {
+ for _, eps := range endpointSlices {
+ switch eps.Labels[s.ServiceLabelKey] {
+ case supabase.ServiceConfig.Postgrest.Name:
+ if s.Postgrest == nil {
+ s.Postgrest = new(PostgrestCluster)
}
- eventLogger := logger.WithValues("event_type", ev.Type)
- switch ev.Type {
- case watch.Added, watch.Modified:
- eps, ok := ev.Object.(*discoveryv1.EndpointSlice)
- if !ok {
- logger.Error(fmt.Errorf("%w: %T", ErrUnexpectedObject, ev.Object), "expected EndpointSlice but got a different object type")
- continue
- }
-
- if err := c.handleModificationEvent(log.IntoContext(ctx, eventLogger), eps); err != nil {
- logger.Error(err, "error occurred during event handling")
- }
+ s.Postgrest.AddOrUpdateEndpoints(eps)
+ case supabase.ServiceConfig.Auth.Name:
+ if s.GoTrue == nil {
+ s.GoTrue = new(GoTrueCluster)
}
- case <-ctx.Done():
- return ctx.Err()
+ s.GoTrue.AddOrUpdateEndpoints(eps)
+ case supabase.ServiceConfig.PGMeta.Name:
+ if s.PGMeta == nil {
+ s.PGMeta = new(PGMetaCluster)
+ }
+ s.PGMeta.AddOrUpdateEndpoints(eps)
}
}
}
-func (c *EndpointsController) handleModificationEvent(ctx context.Context, epSlice *discoveryv1.EndpointSlice) error {
- c.lock.Lock()
- defer c.lock.Unlock()
+func (s EnvoyServices) Targets() map[string][]string {
+ targets := make(map[string][]string)
- var (
- logger = log.FromContext(ctx)
- instanceKey string
- svc *envoyClusterServices
- )
-
- logger.Info("Observed endpoint slice", "name", epSlice.Name)
-
- if c.envoyClusters == nil {
- c.envoyClusters = make(map[string]*envoyClusterServices)
+ if s.Postgrest != nil {
+ targets[supabase.ServiceConfig.Postgrest.Name] = s.Postgrest.Targets()
}
- envoyNodeName, ok := epSlice.Labels[meta.SupabaseLabel.EnvoyCluster]
- if !ok {
- return fmt.Errorf("%w: at object %s", ErrNoEnvoyClusterLabel, epSlice.Name)
+ if s.GoTrue != nil {
+ targets[supabase.ServiceConfig.Auth.Name] = s.GoTrue.Targets()
}
- instanceKey = fmt.Sprintf("%s:%s", envoyNodeName, epSlice.Namespace)
-
- if svc, ok = c.envoyClusters[instanceKey]; !ok {
- svc = new(envoyClusterServices)
+ if s.PGMeta != nil {
+ targets[supabase.ServiceConfig.PGMeta.Name] = s.PGMeta.Targets()
}
- svc.UpsertEndpoints(epSlice)
+ if s.Studio != nil {
+ targets[supabase.ServiceConfig.Studio.Name] = s.Studio.Targets()
+ }
- c.envoyClusters[instanceKey] = svc
-
- return c.updateSnapshot(ctx, instanceKey)
+ return targets
}
-func (c *EndpointsController) updateSnapshot(ctx context.Context, instance string) error {
- latestVersion := strconv.FormatInt(time.Now().UTC().UnixMilli(), 10)
-
- snapshot, err := c.envoyClusters[instance].snapshot(instance, latestVersion)
- if err != nil {
- return err
- }
-
- return c.Cache.SetSnapshot(ctx, instance, snapshot)
-}
-
-type envoyClusterServices struct {
- Postgrest *PostgrestCluster
- GoTrue *GoTrueCluster
- PGMeta *PGMetaCluster
- Studio *StudioCluster
-}
-
-func (s *envoyClusterServices) UpsertEndpoints(eps *discoveryv1.EndpointSlice) {
- switch eps.Labels[meta.WellKnownLabel.Name] {
- case supabase.ServiceConfig.Postgrest.Name:
- if s.Postgrest == nil {
- s.Postgrest = new(PostgrestCluster)
- }
- s.Postgrest.AddOrUpdateEndpoints(eps)
- case supabase.ServiceConfig.Auth.Name:
- if s.GoTrue == nil {
- s.GoTrue = new(GoTrueCluster)
- }
- s.GoTrue.AddOrUpdateEndpoints(eps)
- case supabase.ServiceConfig.PGMeta.Name:
- if s.PGMeta == nil {
- s.PGMeta = new(PGMetaCluster)
- }
- s.PGMeta.AddOrUpdateEndpoints(eps)
- }
-}
-
-func (s *envoyClusterServices) snapshot(instance, version string) (*cache.Snapshot, error) {
+func (s *EnvoyServices) snapshot(ctx context.Context, instance, version string) (*cache.Snapshot, error) {
const (
apiRouteName = "supabase"
studioRouteName = "supabas-studio"
@@ -207,6 +79,8 @@ func (s *envoyClusterServices) snapshot(instance, version string) (*cache.Snapsh
listenerName = "supabase"
)
+ logger := log.FromContext(ctx)
+
apiConnectionManager := &hcm.HttpConnectionManager{
CodecType: hcm.HttpConnectionManager_AUTO,
StatPrefix: "http",
@@ -327,6 +201,8 @@ func (s *envoyClusterServices) snapshot(instance, version string) (*cache.Snapsh
}}
if s.Studio != nil {
+ logger.Info("Adding studio listener")
+
listeners = append(listeners, &listenerv3.Listener{
Name: "studio",
Address: &corev3.Address{
diff --git a/internal/meta/labels.go b/internal/meta/labels.go
index b17d753..feda623 100644
--- a/internal/meta/labels.go
+++ b/internal/meta/labels.go
@@ -39,9 +39,9 @@ var WellKnownLabel = struct {
}
var SupabaseLabel = struct {
- Reload string
- EnvoyCluster string
+ Reload string
+ ApiGatewayTarget string
}{
- Reload: supabasev1alpha1.GroupVersion.Group + "/reload",
- EnvoyCluster: supabasev1alpha1.GroupVersion.Group + "/envoy-cluster",
+ Reload: supabasev1alpha1.GroupVersion.Group + "/reload",
+ ApiGatewayTarget: supabasev1alpha1.GroupVersion.Group + "/api-gateway-target",
}
diff --git a/testdata/dotnet-client/supabase-integration.sln b/testdata/dotnet-client/supabase-integration.sln
new file mode 100644
index 0000000..f895d3b
--- /dev/null
+++ b/testdata/dotnet-client/supabase-integration.sln
@@ -0,0 +1,27 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31903.59
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{1A6ACECB-D8D9-4613-B56E-8A4FEB6A78A0}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "supabase-integration.api-test", "test\supabase-integration.api-test\supabase-integration.api-test.csproj", "{8C0E9D7E-5331-4AFB-919A-F00967971025}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8C0E9D7E-5331-4AFB-919A-F00967971025}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8C0E9D7E-5331-4AFB-919A-F00967971025}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8C0E9D7E-5331-4AFB-919A-F00967971025}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8C0E9D7E-5331-4AFB-919A-F00967971025}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {8C0E9D7E-5331-4AFB-919A-F00967971025} = {1A6ACECB-D8D9-4613-B56E-8A4FEB6A78A0}
+ EndGlobalSection
+EndGlobal
diff --git a/testdata/dotnet-client/supabase-integration.sln.DotSettings.user b/testdata/dotnet-client/supabase-integration.sln.DotSettings.user
new file mode 100644
index 0000000..6b5966a
--- /dev/null
+++ b/testdata/dotnet-client/supabase-integration.sln.DotSettings.user
@@ -0,0 +1,6 @@
+
+ <SessionState ContinuousTestingMode="0" IsActive="True" Name="TestListTasks(SupabaseClientFixture)" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
+ <TestAncestor>
+ <TestId>Testing Platform::8C0E9D7E-5331-4AFB-919A-F00967971025::net9.0::ServiceKeyTest</TestId>
+ </TestAncestor>
+</SessionState>
\ No newline at end of file
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/ServiceKeyTest.cs b/testdata/dotnet-client/test/supabase-integration.api-test/ServiceKeyTest.cs
new file mode 100644
index 0000000..cb47f12
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/ServiceKeyTest.cs
@@ -0,0 +1,27 @@
+using Supabase.Postgrest.Attributes;
+using Supabase.Postgrest.Models;
+
+namespace supabase_integration.api_test;
+
+public class ServiceKeyTest
+{
+ [Test]
+ [ClassDataSource(Shared = SharedType.PerAssembly)]
+ public async Task TestListTasks(SupabaseClientFixture fixture)
+ {
+ var resp = await fixture.ApiClient.Postgrest.Table().Get().ConfigureAwait(false);
+
+ await Assert.That(resp.Models.Count).IsGreaterThan(0);
+ }
+}
+
+[Table("lists")]
+public class TaskList : BaseModel
+{
+ [PrimaryKey("id")]
+ public int Id { get; set; }
+ [Column("user_id")]
+ public int UserId { get; set; }
+ [Column("name")]
+ public string Name { get; set; }
+}
\ No newline at end of file
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/SupabaseClientFixture.cs b/testdata/dotnet-client/test/supabase-integration.api-test/SupabaseClientFixture.cs
new file mode 100644
index 0000000..496aec2
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/SupabaseClientFixture.cs
@@ -0,0 +1,22 @@
+using Supabase;
+using TUnit.Core.Interfaces;
+
+namespace supabase_integration.api_test;
+
+public class SupabaseClientFixture : IAsyncInitializer
+{
+ public Task InitializeAsync()
+ {
+ ApiClient = new Client(
+ Environment.GetEnvironmentVariable("SUPBASE_URL") ?? "http://localhost:8000",
+ Environment.GetEnvironmentVariable("SUPBASE_ACCESS_KEY") ?? throw new ArgumentException("Supabase access key is missing."),
+ new SupabaseOptions
+ {
+ AutoConnectRealtime = false
+ }
+ );
+ return Task.CompletedTask;
+ }
+
+ public Client ApiClient { get; private set; }
+}
\ No newline at end of file
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs
new file mode 100644
index 0000000..feda5e9
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs
@@ -0,0 +1,4 @@
+//
+using System;
+using System.Reflection;
+[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v9.0", FrameworkDisplayName = ".NET 9.0")]
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/AutoRegisteredExtensions.cs b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/AutoRegisteredExtensions.cs
new file mode 100644
index 0000000..9191c60
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/AutoRegisteredExtensions.cs
@@ -0,0 +1,16 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by Microsoft.Testing.Platform.MSBuild
+//
+//------------------------------------------------------------------------------
+
+[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+internal static class SelfRegisteredExtensions
+{
+ public static void AddSelfRegisteredExtensions(this global::Microsoft.Testing.Platform.Builder.ITestApplicationBuilder builder, string[] args)
+ {
+ Microsoft.Testing.Platform.MSBuild.TestingPlatformBuilderHook.AddExtensions(builder, args);
+ TUnit.Engine.Framework.TestingPlatformBuilderHook.AddExtensions(builder, args);
+ Microsoft.Testing.Extensions.CodeCoverage.TestingPlatformBuilderHook.AddExtensions(builder, args);
+ }
+}
\ No newline at end of file
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/TestPlatformEntryPoint.cs b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/TestPlatformEntryPoint.cs
new file mode 100644
index 0000000..2147f31
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/TestPlatformEntryPoint.cs
@@ -0,0 +1,19 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by Microsoft.Testing.Platform.MSBuild
+//
+//------------------------------------------------------------------------------
+
+[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+internal sealed class TestingPlatformEntryPoint
+{
+ public static async global::System.Threading.Tasks.Task Main(string[] args)
+ {
+ global::Microsoft.Testing.Platform.Builder.ITestApplicationBuilder builder = await global::Microsoft.Testing.Platform.Builder.TestApplication.CreateBuilderAsync(args);
+ SelfRegisteredExtensions.AddSelfRegisteredExtensions(builder, args);
+ using (global::Microsoft.Testing.Platform.Builder.ITestApplication app = await builder.BuildAsync())
+ {
+ return await app.RunAsync();
+ }
+ }
+}
\ No newline at end of file
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/apphost b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/apphost
new file mode 100755
index 0000000..600a326
Binary files /dev/null and b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/apphost differ
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/ref/supabase-integration.api-test.dll b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/ref/supabase-integration.api-test.dll
new file mode 100644
index 0000000..f34f656
Binary files /dev/null and b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/ref/supabase-integration.api-test.dll differ
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/refint/supabase-integration.api-test.dll b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/refint/supabase-integration.api-test.dll
new file mode 100644
index 0000000..f34f656
Binary files /dev/null and b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/refint/supabase-integration.api-test.dll differ
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.AssemblyInfo.cs b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.AssemblyInfo.cs
new file mode 100644
index 0000000..1ed9cc1
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.AssemblyInfo.cs
@@ -0,0 +1,23 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+using System;
+using System.Reflection;
+
+[assembly: System.Reflection.AssemblyCompanyAttribute("supabase-integration.api-test")]
+[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
+[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
+[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+a5c170a47816e50bce4b39b7d7b54764d92acb71")]
+[assembly: System.Reflection.AssemblyProductAttribute("supabase-integration.api-test")]
+[assembly: System.Reflection.AssemblyTitleAttribute("supabase-integration.api-test")]
+[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
+[assembly: System.Reflection.AssemblyMetadata("Microsoft.Testing.Platform.Application", "True")]
+
+// Generated by the MSBuild WriteCodeFragment class.
+
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.AssemblyInfoInputs.cache b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.AssemblyInfoInputs.cache
new file mode 100644
index 0000000..103494d
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.AssemblyInfoInputs.cache
@@ -0,0 +1 @@
+c30ee9d790c053bb091f7b65a0618bb1bd275cc4b6492d6624dc720874d75514
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.GeneratedMSBuildEditorConfig.editorconfig b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.GeneratedMSBuildEditorConfig.editorconfig
new file mode 100644
index 0000000..d8f86fd
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.GeneratedMSBuildEditorConfig.editorconfig
@@ -0,0 +1,15 @@
+is_global = true
+build_property.TargetFramework = net9.0
+build_property.TargetPlatformMinVersion =
+build_property.UsingMicrosoftNETSdkWeb =
+build_property.ProjectTypeGuids =
+build_property.InvariantGlobalization =
+build_property.PlatformNeutralAssembly =
+build_property.EnforceExtendedAnalyzerRules =
+build_property._SupportedPlatformList = Linux,macOS,Windows
+build_property.RootNamespace = supabase_integration.api_test
+build_property.ProjectDir = /Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/
+build_property.EnableComHosting =
+build_property.EnableGeneratedComInterfaceComImportInterop =
+build_property.EffectiveAnalysisLevelStyle = 9.0
+build_property.EnableCodeStyleSeverity =
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.GlobalUsings.g.cs b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.GlobalUsings.g.cs
new file mode 100644
index 0000000..e67468a
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.GlobalUsings.g.cs
@@ -0,0 +1,12 @@
+//
+global using global::System;
+global using global::System.Collections.Generic;
+global using global::System.IO;
+global using global::System.Linq;
+global using global::System.Net.Http;
+global using global::System.Threading;
+global using global::System.Threading.Tasks;
+global using global::TUnit.Assertions;
+global using global::TUnit.Assertions.Extensions;
+global using global::TUnit.Core;
+global using static global::TUnit.Core.HookType;
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.assets.cache b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.assets.cache
new file mode 100644
index 0000000..ddd9f45
Binary files /dev/null and b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.assets.cache differ
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.csproj.AssemblyReference.cache b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.csproj.AssemblyReference.cache
new file mode 100644
index 0000000..32f25b5
Binary files /dev/null and b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.csproj.AssemblyReference.cache differ
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.csproj.CoreCompileInputs.cache b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.csproj.CoreCompileInputs.cache
new file mode 100644
index 0000000..80c08f4
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.csproj.CoreCompileInputs.cache
@@ -0,0 +1 @@
+18cd98c3087cd64be3c7db21ec9acf602d7e3393abf67ab6c148e18f5288dcac
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.csproj.FileListAbsolute.txt b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.csproj.FileListAbsolute.txt
new file mode 100644
index 0000000..3a5ad72
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.csproj.FileListAbsolute.txt
@@ -0,0 +1,73 @@
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.csproj.AssemblyReference.cache
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.GeneratedMSBuildEditorConfig.editorconfig
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.AssemblyInfoInputs.cache
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.AssemblyInfo.cs
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.csproj.CoreCompileInputs.cache
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.gentestingplatformentrypointinputcache.cache
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.genautoregisteredextensionsinputcache.cache
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/AutoRegisteredExtensions.cs
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/TestPlatformEntryPoint.cs
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/supabase-integration.api-test
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/supabase-integration.api-test.deps.json
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/supabase-integration.api-test.runtimeconfig.json
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/supabase-integration.api-test.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/supabase-integration.api-test.pdb
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/EnumerableAsyncProcessor.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/Microsoft.Extensions.Logging.Abstractions.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/Microsoft.IdentityModel.Abstractions.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/Microsoft.IdentityModel.JsonWebTokens.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/Microsoft.IdentityModel.Logging.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/Microsoft.IdentityModel.Tokens.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/Microsoft.IO.RecyclableMemoryStream.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/Microsoft.Testing.Extensions.TrxReport.Abstractions.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/Microsoft.Testing.Platform.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/Microsoft.Testing.Platform.MSBuild.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/MimeMapping.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/Newtonsoft.Json.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/Supabase.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/Supabase.Core.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/Supabase.Functions.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/Supabase.Gotrue.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/Supabase.Postgrest.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/Supabase.Realtime.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/Supabase.Storage.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/System.IdentityModel.Tokens.Jwt.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/System.Reactive.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/TUnit.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/TUnit.Assertions.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/TUnit.Core.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/TUnit.Engine.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/Websocket.Client.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/cs/Microsoft.Testing.Platform.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/de/Microsoft.Testing.Platform.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/es/Microsoft.Testing.Platform.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/fr/Microsoft.Testing.Platform.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/it/Microsoft.Testing.Platform.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/ja/Microsoft.Testing.Platform.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/ko/Microsoft.Testing.Platform.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/pl/Microsoft.Testing.Platform.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/pt-BR/Microsoft.Testing.Platform.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/ru/Microsoft.Testing.Platform.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/tr/Microsoft.Testing.Platform.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/zh-Hans/Microsoft.Testing.Platform.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/zh-Hant/Microsoft.Testing.Platform.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/cs/Microsoft.Testing.Platform.MSBuild.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/de/Microsoft.Testing.Platform.MSBuild.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/es/Microsoft.Testing.Platform.MSBuild.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/fr/Microsoft.Testing.Platform.MSBuild.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/it/Microsoft.Testing.Platform.MSBuild.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/ja/Microsoft.Testing.Platform.MSBuild.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/ko/Microsoft.Testing.Platform.MSBuild.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/pl/Microsoft.Testing.Platform.MSBuild.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/pt-BR/Microsoft.Testing.Platform.MSBuild.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/ru/Microsoft.Testing.Platform.MSBuild.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/tr/Microsoft.Testing.Platform.MSBuild.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/zh-Hans/Microsoft.Testing.Platform.MSBuild.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/bin/Debug/net9.0/zh-Hant/Microsoft.Testing.Platform.MSBuild.resources.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase.88E5058B.Up2Date
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/refint/supabase-integration.api-test.dll
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.pdb
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.genruntimeconfig.cache
+/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/ref/supabase-integration.api-test.dll
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.dll b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.dll
new file mode 100644
index 0000000..ea8a969
Binary files /dev/null and b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.dll differ
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.genautoregisteredextensionsinputcache.cache b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.genautoregisteredextensionsinputcache.cache
new file mode 100644
index 0000000..be5f7c6
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.genautoregisteredextensionsinputcache.cache
@@ -0,0 +1 @@
+ac7cea3191876b400be0355099ee75cb19980b90abdf6abdaa74befcf3d99901
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.genruntimeconfig.cache b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.genruntimeconfig.cache
new file mode 100644
index 0000000..9a00829
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.genruntimeconfig.cache
@@ -0,0 +1 @@
+24f9af8c04e70f6b6181eaa2f0ed1638767c3450d7387a035086bd4dfd85d781
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.gentestingplatformentrypointinputcache.cache b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.gentestingplatformentrypointinputcache.cache
new file mode 100644
index 0000000..be5f7c6
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.gentestingplatformentrypointinputcache.cache
@@ -0,0 +1 @@
+ac7cea3191876b400be0355099ee75cb19980b90abdf6abdaa74befcf3d99901
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.pdb b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.pdb
new file mode 100644
index 0000000..4e1bea5
Binary files /dev/null and b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase-integration.api-test.pdb differ
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase.88E5058B.Up2Date b/testdata/dotnet-client/test/supabase-integration.api-test/obj/Debug/net9.0/supabase.88E5058B.Up2Date
new file mode 100644
index 0000000..e69de29
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/project.assets.json b/testdata/dotnet-client/test/supabase-integration.api-test/obj/project.assets.json
new file mode 100644
index 0000000..ebe4b35
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/obj/project.assets.json
@@ -0,0 +1,2176 @@
+{
+ "version": 3,
+ "targets": {
+ "net9.0": {
+ "EnumerableAsyncProcessor/2.0.6": {
+ "type": "package",
+ "compile": {
+ "lib/net9.0/EnumerableAsyncProcessor.dll": {}
+ },
+ "runtime": {
+ "lib/net9.0/EnumerableAsyncProcessor.dll": {}
+ }
+ },
+ "Microsoft.DiaSymReader/2.0.0": {
+ "type": "package",
+ "compile": {
+ "lib/netstandard2.0/Microsoft.DiaSymReader.dll": {
+ "related": ".pdb;.xml"
+ }
+ },
+ "runtime": {
+ "lib/netstandard2.0/Microsoft.DiaSymReader.dll": {
+ "related": ".pdb;.xml"
+ }
+ }
+ },
+ "Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": {
+ "type": "package",
+ "compile": {
+ "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {
+ "related": ".xml"
+ }
+ },
+ "build": {
+ "buildTransitive/net6.0/_._": {}
+ }
+ },
+ "Microsoft.Extensions.DependencyModel/6.0.1": {
+ "type": "package",
+ "dependencies": {
+ "System.Buffers": "4.5.1",
+ "System.Memory": "4.5.4",
+ "System.Runtime.CompilerServices.Unsafe": "6.0.0",
+ "System.Text.Encodings.Web": "6.0.0",
+ "System.Text.Json": "6.0.10"
+ },
+ "compile": {
+ "lib/netstandard2.0/Microsoft.Extensions.DependencyModel.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/netstandard2.0/Microsoft.Extensions.DependencyModel.dll": {
+ "related": ".xml"
+ }
+ }
+ },
+ "Microsoft.Extensions.Logging.Abstractions/8.0.0": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0"
+ },
+ "compile": {
+ "lib/net8.0/Microsoft.Extensions.Logging.Abstractions.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/net8.0/Microsoft.Extensions.Logging.Abstractions.dll": {
+ "related": ".xml"
+ }
+ },
+ "build": {
+ "buildTransitive/net6.0/Microsoft.Extensions.Logging.Abstractions.targets": {}
+ }
+ },
+ "Microsoft.IdentityModel.Abstractions/7.5.1": {
+ "type": "package",
+ "compile": {
+ "lib/net8.0/Microsoft.IdentityModel.Abstractions.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/net8.0/Microsoft.IdentityModel.Abstractions.dll": {
+ "related": ".xml"
+ }
+ }
+ },
+ "Microsoft.IdentityModel.JsonWebTokens/7.5.1": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.IdentityModel.Tokens": "7.5.1"
+ },
+ "compile": {
+ "lib/net8.0/Microsoft.IdentityModel.JsonWebTokens.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/net8.0/Microsoft.IdentityModel.JsonWebTokens.dll": {
+ "related": ".xml"
+ }
+ }
+ },
+ "Microsoft.IdentityModel.Logging/7.5.1": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.IdentityModel.Abstractions": "7.5.1"
+ },
+ "compile": {
+ "lib/net8.0/Microsoft.IdentityModel.Logging.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/net8.0/Microsoft.IdentityModel.Logging.dll": {
+ "related": ".xml"
+ }
+ }
+ },
+ "Microsoft.IdentityModel.Tokens/7.5.1": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.IdentityModel.Logging": "7.5.1"
+ },
+ "compile": {
+ "lib/net8.0/Microsoft.IdentityModel.Tokens.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/net8.0/Microsoft.IdentityModel.Tokens.dll": {
+ "related": ".xml"
+ }
+ }
+ },
+ "Microsoft.IO.RecyclableMemoryStream/3.0.0": {
+ "type": "package",
+ "compile": {
+ "lib/net6.0/Microsoft.IO.RecyclableMemoryStream.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/net6.0/Microsoft.IO.RecyclableMemoryStream.dll": {
+ "related": ".xml"
+ }
+ }
+ },
+ "Microsoft.Testing.Extensions.CodeCoverage/17.13.1": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.DiaSymReader": "2.0.0",
+ "Microsoft.Extensions.DependencyModel": "6.0.1",
+ "Microsoft.Testing.Platform": "1.4.3",
+ "Newtonsoft.Json": "13.0.3",
+ "System.Reflection.Metadata": "8.0.0"
+ },
+ "compile": {
+ "lib/net6.0/Microsoft.CodeCoverage.Core.dll": {},
+ "lib/net6.0/Microsoft.CodeCoverage.Instrumentation.Core.dll": {},
+ "lib/net6.0/Microsoft.CodeCoverage.Instrumentation.dll": {},
+ "lib/net6.0/Microsoft.CodeCoverage.Interprocess.dll": {},
+ "lib/net6.0/Microsoft.Testing.Extensions.CodeCoverage.dll": {
+ "related": ".pdb"
+ },
+ "lib/net6.0/Microsoft.VisualStudio.CodeCoverage.Shim.dll": {},
+ "lib/net6.0/Mono.Cecil.Mdb.dll": {},
+ "lib/net6.0/Mono.Cecil.Pdb.dll": {},
+ "lib/net6.0/Mono.Cecil.Rocks.dll": {},
+ "lib/net6.0/Mono.Cecil.dll": {}
+ },
+ "runtime": {
+ "lib/net6.0/Microsoft.CodeCoverage.Core.dll": {},
+ "lib/net6.0/Microsoft.CodeCoverage.Instrumentation.Core.dll": {},
+ "lib/net6.0/Microsoft.CodeCoverage.Instrumentation.dll": {},
+ "lib/net6.0/Microsoft.CodeCoverage.Interprocess.dll": {},
+ "lib/net6.0/Microsoft.Testing.Extensions.CodeCoverage.dll": {
+ "related": ".pdb"
+ },
+ "lib/net6.0/Microsoft.VisualStudio.CodeCoverage.Shim.dll": {},
+ "lib/net6.0/Mono.Cecil.Mdb.dll": {},
+ "lib/net6.0/Mono.Cecil.Pdb.dll": {},
+ "lib/net6.0/Mono.Cecil.Rocks.dll": {},
+ "lib/net6.0/Mono.Cecil.dll": {}
+ },
+ "resource": {
+ "lib/net6.0/cs/Microsoft.Testing.Extensions.CodeCoverage.resources.dll": {
+ "locale": "cs"
+ },
+ "lib/net6.0/de/Microsoft.Testing.Extensions.CodeCoverage.resources.dll": {
+ "locale": "de"
+ },
+ "lib/net6.0/es/Microsoft.Testing.Extensions.CodeCoverage.resources.dll": {
+ "locale": "es"
+ },
+ "lib/net6.0/fr/Microsoft.Testing.Extensions.CodeCoverage.resources.dll": {
+ "locale": "fr"
+ },
+ "lib/net6.0/it/Microsoft.Testing.Extensions.CodeCoverage.resources.dll": {
+ "locale": "it"
+ },
+ "lib/net6.0/ja/Microsoft.Testing.Extensions.CodeCoverage.resources.dll": {
+ "locale": "ja"
+ },
+ "lib/net6.0/ko/Microsoft.Testing.Extensions.CodeCoverage.resources.dll": {
+ "locale": "ko"
+ },
+ "lib/net6.0/pl/Microsoft.Testing.Extensions.CodeCoverage.resources.dll": {
+ "locale": "pl"
+ },
+ "lib/net6.0/pt-BR/Microsoft.Testing.Extensions.CodeCoverage.resources.dll": {
+ "locale": "pt-BR"
+ },
+ "lib/net6.0/ru/Microsoft.Testing.Extensions.CodeCoverage.resources.dll": {
+ "locale": "ru"
+ },
+ "lib/net6.0/tr/Microsoft.Testing.Extensions.CodeCoverage.resources.dll": {
+ "locale": "tr"
+ },
+ "lib/net6.0/zh-Hans/Microsoft.Testing.Extensions.CodeCoverage.resources.dll": {
+ "locale": "zh-Hans"
+ },
+ "lib/net6.0/zh-Hant/Microsoft.Testing.Extensions.CodeCoverage.resources.dll": {
+ "locale": "zh-Hant"
+ }
+ },
+ "build": {
+ "buildTransitive/net6.0/Microsoft.Testing.Extensions.CodeCoverage.props": {},
+ "buildTransitive/net6.0/Microsoft.Testing.Extensions.CodeCoverage.targets": {}
+ },
+ "buildMultiTargeting": {
+ "buildMultiTargeting/Microsoft.Testing.Extensions.CodeCoverage.props": {},
+ "buildMultiTargeting/Microsoft.Testing.Extensions.CodeCoverage.targets": {}
+ },
+ "runtimeTargets": {
+ "runtimes/linux-musl-x64/native/Cov_x64.config": {
+ "assetType": "native",
+ "rid": "linux-musl-x64"
+ },
+ "runtimes/linux-musl-x64/native/libCoverageInstrumentationMethod.so": {
+ "assetType": "native",
+ "rid": "linux-musl-x64"
+ },
+ "runtimes/linux-musl-x64/native/libInstrumentationEngine.so": {
+ "assetType": "native",
+ "rid": "linux-musl-x64"
+ },
+ "runtimes/linux-x64/native/Cov_x64.config": {
+ "assetType": "native",
+ "rid": "linux-x64"
+ },
+ "runtimes/linux-x64/native/libCoverageInstrumentationMethod.so": {
+ "assetType": "native",
+ "rid": "linux-x64"
+ },
+ "runtimes/linux-x64/native/libInstrumentationEngine.so": {
+ "assetType": "native",
+ "rid": "linux-x64"
+ },
+ "runtimes/osx-x64/native/Cov_x64.config": {
+ "assetType": "native",
+ "rid": "osx-x64"
+ },
+ "runtimes/osx-x64/native/libCoverageInstrumentationMethod.dylib": {
+ "assetType": "native",
+ "rid": "osx-x64"
+ },
+ "runtimes/osx-x64/native/libInstrumentationEngine.dylib": {
+ "assetType": "native",
+ "rid": "osx-x64"
+ },
+ "runtimes/win-arm64/native/CodeCoverageMessages.dll": {
+ "assetType": "native",
+ "rid": "win-arm64"
+ },
+ "runtimes/win-arm64/native/Cov_arm64.config": {
+ "assetType": "native",
+ "rid": "win-arm64"
+ },
+ "runtimes/win-arm64/native/Cov_x64.config": {
+ "assetType": "native",
+ "rid": "win-arm64"
+ },
+ "runtimes/win-arm64/native/Cov_x86.config": {
+ "assetType": "native",
+ "rid": "win-arm64"
+ },
+ "runtimes/win-arm64/native/MicrosoftInstrumentationEngine_arm64.dll": {
+ "assetType": "native",
+ "rid": "win-arm64"
+ },
+ "runtimes/win-arm64/native/MicrosoftInstrumentationEngine_x64.dll": {
+ "assetType": "native",
+ "rid": "win-arm64"
+ },
+ "runtimes/win-arm64/native/MicrosoftInstrumentationEngine_x86.dll": {
+ "assetType": "native",
+ "rid": "win-arm64"
+ },
+ "runtimes/win-arm64/native/covrun32.dll": {
+ "assetType": "native",
+ "rid": "win-arm64"
+ },
+ "runtimes/win-arm64/native/covrun64.dll": {
+ "assetType": "native",
+ "rid": "win-arm64"
+ },
+ "runtimes/win-arm64/native/covrunarm64.dll": {
+ "assetType": "native",
+ "rid": "win-arm64"
+ },
+ "runtimes/win-arm64/native/msdia140.dll": {
+ "assetType": "native",
+ "rid": "win-arm64"
+ },
+ "runtimes/win-x64/native/CodeCoverageMessages.dll": {
+ "assetType": "native",
+ "rid": "win-x64"
+ },
+ "runtimes/win-x64/native/Cov_arm64.config": {
+ "assetType": "native",
+ "rid": "win-x64"
+ },
+ "runtimes/win-x64/native/Cov_x64.config": {
+ "assetType": "native",
+ "rid": "win-x64"
+ },
+ "runtimes/win-x64/native/Cov_x86.config": {
+ "assetType": "native",
+ "rid": "win-x64"
+ },
+ "runtimes/win-x64/native/MicrosoftInstrumentationEngine_arm64.dll": {
+ "assetType": "native",
+ "rid": "win-x64"
+ },
+ "runtimes/win-x64/native/MicrosoftInstrumentationEngine_x64.dll": {
+ "assetType": "native",
+ "rid": "win-x64"
+ },
+ "runtimes/win-x64/native/MicrosoftInstrumentationEngine_x86.dll": {
+ "assetType": "native",
+ "rid": "win-x64"
+ },
+ "runtimes/win-x64/native/covrun32.dll": {
+ "assetType": "native",
+ "rid": "win-x64"
+ },
+ "runtimes/win-x64/native/covrun64.dll": {
+ "assetType": "native",
+ "rid": "win-x64"
+ },
+ "runtimes/win-x64/native/covrunarm64.dll": {
+ "assetType": "native",
+ "rid": "win-x64"
+ },
+ "runtimes/win-x64/native/msdia140.dll": {
+ "assetType": "native",
+ "rid": "win-x64"
+ },
+ "runtimes/win-x86/native/CodeCoverageMessages.dll": {
+ "assetType": "native",
+ "rid": "win-x86"
+ },
+ "runtimes/win-x86/native/Cov_arm64.config": {
+ "assetType": "native",
+ "rid": "win-x86"
+ },
+ "runtimes/win-x86/native/Cov_x64.config": {
+ "assetType": "native",
+ "rid": "win-x86"
+ },
+ "runtimes/win-x86/native/Cov_x86.config": {
+ "assetType": "native",
+ "rid": "win-x86"
+ },
+ "runtimes/win-x86/native/MicrosoftInstrumentationEngine_arm64.dll": {
+ "assetType": "native",
+ "rid": "win-x86"
+ },
+ "runtimes/win-x86/native/MicrosoftInstrumentationEngine_x64.dll": {
+ "assetType": "native",
+ "rid": "win-x86"
+ },
+ "runtimes/win-x86/native/MicrosoftInstrumentationEngine_x86.dll": {
+ "assetType": "native",
+ "rid": "win-x86"
+ },
+ "runtimes/win-x86/native/covrun32.dll": {
+ "assetType": "native",
+ "rid": "win-x86"
+ },
+ "runtimes/win-x86/native/covrun64.dll": {
+ "assetType": "native",
+ "rid": "win-x86"
+ },
+ "runtimes/win-x86/native/covrunarm64.dll": {
+ "assetType": "native",
+ "rid": "win-x86"
+ },
+ "runtimes/win-x86/native/msdia140.dll": {
+ "assetType": "native",
+ "rid": "win-x86"
+ }
+ }
+ },
+ "Microsoft.Testing.Extensions.TrxReport.Abstractions/1.4.3": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.Testing.Platform": "1.4.3"
+ },
+ "compile": {
+ "lib/net8.0/Microsoft.Testing.Extensions.TrxReport.Abstractions.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/net8.0/Microsoft.Testing.Extensions.TrxReport.Abstractions.dll": {
+ "related": ".xml"
+ }
+ }
+ },
+ "Microsoft.Testing.Platform/1.4.3": {
+ "type": "package",
+ "compile": {
+ "lib/net8.0/Microsoft.Testing.Platform.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/net8.0/Microsoft.Testing.Platform.dll": {
+ "related": ".xml"
+ }
+ },
+ "resource": {
+ "lib/net8.0/cs/Microsoft.Testing.Platform.resources.dll": {
+ "locale": "cs"
+ },
+ "lib/net8.0/de/Microsoft.Testing.Platform.resources.dll": {
+ "locale": "de"
+ },
+ "lib/net8.0/es/Microsoft.Testing.Platform.resources.dll": {
+ "locale": "es"
+ },
+ "lib/net8.0/fr/Microsoft.Testing.Platform.resources.dll": {
+ "locale": "fr"
+ },
+ "lib/net8.0/it/Microsoft.Testing.Platform.resources.dll": {
+ "locale": "it"
+ },
+ "lib/net8.0/ja/Microsoft.Testing.Platform.resources.dll": {
+ "locale": "ja"
+ },
+ "lib/net8.0/ko/Microsoft.Testing.Platform.resources.dll": {
+ "locale": "ko"
+ },
+ "lib/net8.0/pl/Microsoft.Testing.Platform.resources.dll": {
+ "locale": "pl"
+ },
+ "lib/net8.0/pt-BR/Microsoft.Testing.Platform.resources.dll": {
+ "locale": "pt-BR"
+ },
+ "lib/net8.0/ru/Microsoft.Testing.Platform.resources.dll": {
+ "locale": "ru"
+ },
+ "lib/net8.0/tr/Microsoft.Testing.Platform.resources.dll": {
+ "locale": "tr"
+ },
+ "lib/net8.0/zh-Hans/Microsoft.Testing.Platform.resources.dll": {
+ "locale": "zh-Hans"
+ },
+ "lib/net8.0/zh-Hant/Microsoft.Testing.Platform.resources.dll": {
+ "locale": "zh-Hant"
+ }
+ },
+ "build": {
+ "buildTransitive/net8.0/Microsoft.Testing.Platform.props": {}
+ },
+ "buildMultiTargeting": {
+ "buildMultiTargeting/Microsoft.Testing.Platform.props": {}
+ }
+ },
+ "Microsoft.Testing.Platform.MSBuild/1.4.3": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.Testing.Platform": "1.4.3"
+ },
+ "compile": {
+ "lib/net8.0/Microsoft.Testing.Platform.MSBuild.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/net8.0/Microsoft.Testing.Platform.MSBuild.dll": {
+ "related": ".xml"
+ }
+ },
+ "resource": {
+ "lib/net8.0/cs/Microsoft.Testing.Platform.MSBuild.resources.dll": {
+ "locale": "cs"
+ },
+ "lib/net8.0/de/Microsoft.Testing.Platform.MSBuild.resources.dll": {
+ "locale": "de"
+ },
+ "lib/net8.0/es/Microsoft.Testing.Platform.MSBuild.resources.dll": {
+ "locale": "es"
+ },
+ "lib/net8.0/fr/Microsoft.Testing.Platform.MSBuild.resources.dll": {
+ "locale": "fr"
+ },
+ "lib/net8.0/it/Microsoft.Testing.Platform.MSBuild.resources.dll": {
+ "locale": "it"
+ },
+ "lib/net8.0/ja/Microsoft.Testing.Platform.MSBuild.resources.dll": {
+ "locale": "ja"
+ },
+ "lib/net8.0/ko/Microsoft.Testing.Platform.MSBuild.resources.dll": {
+ "locale": "ko"
+ },
+ "lib/net8.0/pl/Microsoft.Testing.Platform.MSBuild.resources.dll": {
+ "locale": "pl"
+ },
+ "lib/net8.0/pt-BR/Microsoft.Testing.Platform.MSBuild.resources.dll": {
+ "locale": "pt-BR"
+ },
+ "lib/net8.0/ru/Microsoft.Testing.Platform.MSBuild.resources.dll": {
+ "locale": "ru"
+ },
+ "lib/net8.0/tr/Microsoft.Testing.Platform.MSBuild.resources.dll": {
+ "locale": "tr"
+ },
+ "lib/net8.0/zh-Hans/Microsoft.Testing.Platform.MSBuild.resources.dll": {
+ "locale": "zh-Hans"
+ },
+ "lib/net8.0/zh-Hant/Microsoft.Testing.Platform.MSBuild.resources.dll": {
+ "locale": "zh-Hant"
+ }
+ },
+ "build": {
+ "buildTransitive/net8.0/Microsoft.Testing.Platform.MSBuild.props": {},
+ "buildTransitive/net8.0/Microsoft.Testing.Platform.MSBuild.targets": {}
+ },
+ "buildMultiTargeting": {
+ "buildMultiTargeting/Microsoft.Testing.Platform.MSBuild.props": {},
+ "buildMultiTargeting/Microsoft.Testing.Platform.MSBuild.targets": {}
+ }
+ },
+ "MimeMapping/3.0.1": {
+ "type": "package",
+ "compile": {
+ "lib/netstandard2.0/MimeMapping.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/netstandard2.0/MimeMapping.dll": {
+ "related": ".xml"
+ }
+ }
+ },
+ "Newtonsoft.Json/13.0.3": {
+ "type": "package",
+ "compile": {
+ "lib/net6.0/Newtonsoft.Json.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/net6.0/Newtonsoft.Json.dll": {
+ "related": ".xml"
+ }
+ }
+ },
+ "Supabase/1.1.1": {
+ "type": "package",
+ "dependencies": {
+ "Newtonsoft.Json": "13.0.3",
+ "Supabase.Core": "1.0.0",
+ "Supabase.Functions": "2.0.0",
+ "Supabase.Gotrue": "6.0.3",
+ "Supabase.Postgrest": "4.0.3",
+ "Supabase.Realtime": "7.0.2",
+ "Supabase.Storage": "2.0.2"
+ },
+ "compile": {
+ "lib/netstandard2.1/Supabase.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/netstandard2.1/Supabase.dll": {
+ "related": ".xml"
+ }
+ }
+ },
+ "Supabase.Core/1.0.0": {
+ "type": "package",
+ "compile": {
+ "lib/netstandard2.0/Supabase.Core.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/netstandard2.0/Supabase.Core.dll": {
+ "related": ".xml"
+ }
+ }
+ },
+ "Supabase.Functions/2.0.0": {
+ "type": "package",
+ "dependencies": {
+ "Newtonsoft.Json": "13.0.3",
+ "Supabase.Core": "1.0.0"
+ },
+ "compile": {
+ "lib/netstandard2.0/Supabase.Functions.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/netstandard2.0/Supabase.Functions.dll": {
+ "related": ".xml"
+ }
+ }
+ },
+ "Supabase.Gotrue/6.0.3": {
+ "type": "package",
+ "dependencies": {
+ "Newtonsoft.Json": "13.0.3",
+ "Supabase.Core": "1.0.0",
+ "System.IdentityModel.Tokens.Jwt": "7.5.1"
+ },
+ "compile": {
+ "lib/netstandard2.1/Supabase.Gotrue.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/netstandard2.1/Supabase.Gotrue.dll": {
+ "related": ".xml"
+ }
+ }
+ },
+ "Supabase.Postgrest/4.0.3": {
+ "type": "package",
+ "dependencies": {
+ "Newtonsoft.Json": "13.0.3",
+ "Supabase.Core": "1.0.0"
+ },
+ "compile": {
+ "lib/netstandard2.0/Supabase.Postgrest.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/netstandard2.0/Supabase.Postgrest.dll": {
+ "related": ".xml"
+ }
+ }
+ },
+ "Supabase.Realtime/7.0.2": {
+ "type": "package",
+ "dependencies": {
+ "Newtonsoft.Json": "13.0.3",
+ "Supabase.Core": "1.0.0",
+ "Supabase.Postgrest": "4.0.3",
+ "Websocket.Client": "5.1.1"
+ },
+ "compile": {
+ "lib/netstandard2.1/Supabase.Realtime.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/netstandard2.1/Supabase.Realtime.dll": {
+ "related": ".xml"
+ }
+ }
+ },
+ "Supabase.Storage/2.0.2": {
+ "type": "package",
+ "dependencies": {
+ "MimeMapping": "3.0.1",
+ "Newtonsoft.Json": "13.0.3",
+ "Supabase.Core": "1.0.0"
+ },
+ "compile": {
+ "lib/netstandard2.0/Supabase.Storage.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/netstandard2.0/Supabase.Storage.dll": {
+ "related": ".xml"
+ }
+ }
+ },
+ "System.Buffers/4.5.1": {
+ "type": "package",
+ "compile": {
+ "ref/netcoreapp2.0/_._": {}
+ },
+ "runtime": {
+ "lib/netcoreapp2.0/_._": {}
+ }
+ },
+ "System.Collections.Immutable/8.0.0": {
+ "type": "package",
+ "compile": {
+ "lib/net8.0/System.Collections.Immutable.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/net8.0/System.Collections.Immutable.dll": {
+ "related": ".xml"
+ }
+ },
+ "build": {
+ "buildTransitive/net6.0/_._": {}
+ }
+ },
+ "System.IdentityModel.Tokens.Jwt/7.5.1": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.IdentityModel.JsonWebTokens": "7.5.1",
+ "Microsoft.IdentityModel.Tokens": "7.5.1"
+ },
+ "compile": {
+ "lib/net8.0/System.IdentityModel.Tokens.Jwt.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/net8.0/System.IdentityModel.Tokens.Jwt.dll": {
+ "related": ".xml"
+ }
+ }
+ },
+ "System.Memory/4.5.4": {
+ "type": "package",
+ "compile": {
+ "ref/netcoreapp2.1/_._": {}
+ },
+ "runtime": {
+ "lib/netcoreapp2.1/_._": {}
+ }
+ },
+ "System.Reactive/6.0.0": {
+ "type": "package",
+ "compile": {
+ "lib/net6.0/System.Reactive.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/net6.0/System.Reactive.dll": {
+ "related": ".xml"
+ }
+ },
+ "build": {
+ "buildTransitive/net6.0/_._": {}
+ }
+ },
+ "System.Reflection.Metadata/8.0.0": {
+ "type": "package",
+ "dependencies": {
+ "System.Collections.Immutable": "8.0.0"
+ },
+ "compile": {
+ "lib/net8.0/System.Reflection.Metadata.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/net8.0/System.Reflection.Metadata.dll": {
+ "related": ".xml"
+ }
+ },
+ "build": {
+ "buildTransitive/net6.0/_._": {}
+ }
+ },
+ "System.Runtime.CompilerServices.Unsafe/6.0.0": {
+ "type": "package",
+ "compile": {
+ "lib/net6.0/System.Runtime.CompilerServices.Unsafe.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/net6.0/System.Runtime.CompilerServices.Unsafe.dll": {
+ "related": ".xml"
+ }
+ },
+ "build": {
+ "buildTransitive/netcoreapp3.1/_._": {}
+ }
+ },
+ "System.Text.Encodings.Web/6.0.0": {
+ "type": "package",
+ "dependencies": {
+ "System.Runtime.CompilerServices.Unsafe": "6.0.0"
+ },
+ "compile": {
+ "lib/net6.0/System.Text.Encodings.Web.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/net6.0/System.Text.Encodings.Web.dll": {
+ "related": ".xml"
+ }
+ },
+ "build": {
+ "buildTransitive/netcoreapp3.1/_._": {}
+ },
+ "runtimeTargets": {
+ "runtimes/browser/lib/net6.0/System.Text.Encodings.Web.dll": {
+ "assetType": "runtime",
+ "rid": "browser"
+ }
+ }
+ },
+ "System.Text.Json/6.0.10": {
+ "type": "package",
+ "dependencies": {
+ "System.Runtime.CompilerServices.Unsafe": "6.0.0",
+ "System.Text.Encodings.Web": "6.0.0"
+ },
+ "compile": {
+ "lib/net6.0/System.Text.Json.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/net6.0/System.Text.Json.dll": {
+ "related": ".xml"
+ }
+ },
+ "build": {
+ "buildTransitive/netcoreapp3.1/System.Text.Json.targets": {}
+ }
+ },
+ "System.Threading.Channels/8.0.0": {
+ "type": "package",
+ "compile": {
+ "lib/net8.0/System.Threading.Channels.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/net8.0/System.Threading.Channels.dll": {
+ "related": ".xml"
+ }
+ },
+ "build": {
+ "buildTransitive/net6.0/_._": {}
+ }
+ },
+ "TUnit/0.6.123": {
+ "type": "package",
+ "dependencies": {
+ "TUnit.Assertions": "0.6.123",
+ "TUnit.Engine": "0.6.123"
+ },
+ "compile": {
+ "lib/net9.0/TUnit.dll": {}
+ },
+ "runtime": {
+ "lib/net9.0/TUnit.dll": {}
+ }
+ },
+ "TUnit.Assertions/0.6.123": {
+ "type": "package",
+ "compile": {
+ "lib/net9.0/TUnit.Assertions.dll": {}
+ },
+ "runtime": {
+ "lib/net9.0/TUnit.Assertions.dll": {}
+ },
+ "build": {
+ "buildTransitive/net9.0/TUnit.Assertions.props": {},
+ "buildTransitive/net9.0/TUnit.Assertions.targets": {}
+ }
+ },
+ "TUnit.Core/0.6.123": {
+ "type": "package",
+ "compile": {
+ "lib/net9.0/TUnit.Core.dll": {}
+ },
+ "runtime": {
+ "lib/net9.0/TUnit.Core.dll": {}
+ },
+ "build": {
+ "buildTransitive/net9.0/TUnit.Core.props": {},
+ "buildTransitive/net9.0/TUnit.Core.targets": {}
+ }
+ },
+ "TUnit.Engine/0.6.123": {
+ "type": "package",
+ "dependencies": {
+ "EnumerableAsyncProcessor": "2.0.6",
+ "Microsoft.Testing.Extensions.TrxReport.Abstractions": "1.4.3",
+ "Microsoft.Testing.Platform": "1.4.3",
+ "Microsoft.Testing.Platform.MSBuild": "1.4.3",
+ "TUnit.Core": "0.6.123"
+ },
+ "compile": {
+ "lib/net9.0/TUnit.Engine.dll": {}
+ },
+ "runtime": {
+ "lib/net9.0/TUnit.Engine.dll": {}
+ },
+ "build": {
+ "buildTransitive/net9.0/TUnit.Engine.props": {}
+ }
+ },
+ "Websocket.Client/5.1.1": {
+ "type": "package",
+ "dependencies": {
+ "Microsoft.Extensions.Logging.Abstractions": "8.0.0",
+ "Microsoft.IO.RecyclableMemoryStream": "3.0.0",
+ "System.Reactive": "6.0.0",
+ "System.Threading.Channels": "8.0.0"
+ },
+ "compile": {
+ "lib/net8.0/Websocket.Client.dll": {
+ "related": ".xml"
+ }
+ },
+ "runtime": {
+ "lib/net8.0/Websocket.Client.dll": {
+ "related": ".xml"
+ }
+ }
+ }
+ }
+ },
+ "libraries": {
+ "EnumerableAsyncProcessor/2.0.6": {
+ "sha512": "aBVYAcgpc/SODIXmXbWU2ua0Y03G5NYJL3pDl4Q6Tqjv6579vQCaK0LIwKDtIVVHU9Q26eZzZOT8GVcC1bZAiQ==",
+ "type": "package",
+ "path": "enumerableasyncprocessor/2.0.6",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "README.md",
+ "enumerableasyncprocessor.2.0.6.nupkg.sha512",
+ "enumerableasyncprocessor.nuspec",
+ "lib/net6.0/EnumerableAsyncProcessor.dll",
+ "lib/net8.0/EnumerableAsyncProcessor.dll",
+ "lib/net9.0/EnumerableAsyncProcessor.dll",
+ "lib/netstandard2.0/EnumerableAsyncProcessor.dll"
+ ]
+ },
+ "Microsoft.DiaSymReader/2.0.0": {
+ "sha512": "QcZrCETsBJqy/vQpFtJc+jSXQ0K5sucQ6NUFbTNVHD4vfZZOwjZ/3sBzczkC4DityhD3AVO/+K/+9ioLs1AgRA==",
+ "type": "package",
+ "path": "microsoft.diasymreader/2.0.0",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "Icon.png",
+ "lib/netstandard2.0/Microsoft.DiaSymReader.dll",
+ "lib/netstandard2.0/Microsoft.DiaSymReader.pdb",
+ "lib/netstandard2.0/Microsoft.DiaSymReader.xml",
+ "microsoft.diasymreader.2.0.0.nupkg.sha512",
+ "microsoft.diasymreader.nuspec"
+ ]
+ },
+ "Microsoft.Extensions.DependencyInjection.Abstractions/8.0.0": {
+ "sha512": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==",
+ "type": "package",
+ "path": "microsoft.extensions.dependencyinjection.abstractions/8.0.0",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "Icon.png",
+ "LICENSE.TXT",
+ "PACKAGE.md",
+ "THIRD-PARTY-NOTICES.TXT",
+ "buildTransitive/net461/Microsoft.Extensions.DependencyInjection.Abstractions.targets",
+ "buildTransitive/net462/_._",
+ "buildTransitive/net6.0/_._",
+ "buildTransitive/netcoreapp2.0/Microsoft.Extensions.DependencyInjection.Abstractions.targets",
+ "lib/net462/Microsoft.Extensions.DependencyInjection.Abstractions.dll",
+ "lib/net462/Microsoft.Extensions.DependencyInjection.Abstractions.xml",
+ "lib/net6.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll",
+ "lib/net6.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml",
+ "lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll",
+ "lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml",
+ "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll",
+ "lib/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml",
+ "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll",
+ "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.xml",
+ "lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.Abstractions.dll",
+ "lib/netstandard2.1/Microsoft.Extensions.DependencyInjection.Abstractions.xml",
+ "microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512",
+ "microsoft.extensions.dependencyinjection.abstractions.nuspec",
+ "useSharedDesignerContext.txt"
+ ]
+ },
+ "Microsoft.Extensions.DependencyModel/6.0.1": {
+ "sha512": "AdvrtrqZpMgW4tIAQ/8gE1LAM/FjFY8JrFdyiolOf9WLEfN3WuFG1Hje6n0jqaOs3ldZFGWhatJQHJRrIOd++w==",
+ "type": "package",
+ "path": "microsoft.extensions.dependencymodel/6.0.1",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "Icon.png",
+ "LICENSE.TXT",
+ "THIRD-PARTY-NOTICES.TXT",
+ "lib/net461/Microsoft.Extensions.DependencyModel.dll",
+ "lib/net461/Microsoft.Extensions.DependencyModel.xml",
+ "lib/netstandard2.0/Microsoft.Extensions.DependencyModel.dll",
+ "lib/netstandard2.0/Microsoft.Extensions.DependencyModel.xml",
+ "microsoft.extensions.dependencymodel.6.0.1.nupkg.sha512",
+ "microsoft.extensions.dependencymodel.nuspec",
+ "useSharedDesignerContext.txt"
+ ]
+ },
+ "Microsoft.Extensions.Logging.Abstractions/8.0.0": {
+ "sha512": "arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==",
+ "type": "package",
+ "path": "microsoft.extensions.logging.abstractions/8.0.0",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "Icon.png",
+ "LICENSE.TXT",
+ "PACKAGE.md",
+ "THIRD-PARTY-NOTICES.TXT",
+ "analyzers/dotnet/roslyn3.11/cs/Microsoft.Extensions.Logging.Generators.dll",
+ "analyzers/dotnet/roslyn3.11/cs/cs/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/de/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/es/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/fr/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/it/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/ja/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/ko/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/pl/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/pt-BR/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/ru/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/tr/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/zh-Hans/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/zh-Hant/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/Microsoft.Extensions.Logging.Generators.dll",
+ "analyzers/dotnet/roslyn4.0/cs/cs/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/de/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/es/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/fr/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/it/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/ja/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/ko/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/pl/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/pt-BR/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/ru/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/tr/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/zh-Hans/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/zh-Hant/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.4/cs/Microsoft.Extensions.Logging.Generators.dll",
+ "analyzers/dotnet/roslyn4.4/cs/cs/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.4/cs/de/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.4/cs/es/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.4/cs/fr/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.4/cs/it/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.4/cs/ja/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.4/cs/ko/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.4/cs/pl/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.4/cs/pt-BR/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.4/cs/ru/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.4/cs/tr/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.4/cs/zh-Hans/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "analyzers/dotnet/roslyn4.4/cs/zh-Hant/Microsoft.Extensions.Logging.Generators.resources.dll",
+ "buildTransitive/net461/Microsoft.Extensions.Logging.Abstractions.targets",
+ "buildTransitive/net462/Microsoft.Extensions.Logging.Abstractions.targets",
+ "buildTransitive/net6.0/Microsoft.Extensions.Logging.Abstractions.targets",
+ "buildTransitive/netcoreapp2.0/Microsoft.Extensions.Logging.Abstractions.targets",
+ "buildTransitive/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.targets",
+ "lib/net462/Microsoft.Extensions.Logging.Abstractions.dll",
+ "lib/net462/Microsoft.Extensions.Logging.Abstractions.xml",
+ "lib/net6.0/Microsoft.Extensions.Logging.Abstractions.dll",
+ "lib/net6.0/Microsoft.Extensions.Logging.Abstractions.xml",
+ "lib/net7.0/Microsoft.Extensions.Logging.Abstractions.dll",
+ "lib/net7.0/Microsoft.Extensions.Logging.Abstractions.xml",
+ "lib/net8.0/Microsoft.Extensions.Logging.Abstractions.dll",
+ "lib/net8.0/Microsoft.Extensions.Logging.Abstractions.xml",
+ "lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.dll",
+ "lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.xml",
+ "microsoft.extensions.logging.abstractions.8.0.0.nupkg.sha512",
+ "microsoft.extensions.logging.abstractions.nuspec",
+ "useSharedDesignerContext.txt"
+ ]
+ },
+ "Microsoft.IdentityModel.Abstractions/7.5.1": {
+ "sha512": "PT16ZFbPIiMsYv07oy3zOjqUOJ7xutGBkJTOX0+IbNyU6+O6X7aIxjq9EaSSRLWbekRgamgtmfg8Xjw6A6Ua9g==",
+ "type": "package",
+ "path": "microsoft.identitymodel.abstractions/7.5.1",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "lib/net461/Microsoft.IdentityModel.Abstractions.dll",
+ "lib/net461/Microsoft.IdentityModel.Abstractions.xml",
+ "lib/net462/Microsoft.IdentityModel.Abstractions.dll",
+ "lib/net462/Microsoft.IdentityModel.Abstractions.xml",
+ "lib/net472/Microsoft.IdentityModel.Abstractions.dll",
+ "lib/net472/Microsoft.IdentityModel.Abstractions.xml",
+ "lib/net6.0/Microsoft.IdentityModel.Abstractions.dll",
+ "lib/net6.0/Microsoft.IdentityModel.Abstractions.xml",
+ "lib/net8.0/Microsoft.IdentityModel.Abstractions.dll",
+ "lib/net8.0/Microsoft.IdentityModel.Abstractions.xml",
+ "lib/netstandard2.0/Microsoft.IdentityModel.Abstractions.dll",
+ "lib/netstandard2.0/Microsoft.IdentityModel.Abstractions.xml",
+ "microsoft.identitymodel.abstractions.7.5.1.nupkg.sha512",
+ "microsoft.identitymodel.abstractions.nuspec"
+ ]
+ },
+ "Microsoft.IdentityModel.JsonWebTokens/7.5.1": {
+ "sha512": "93CGSa8RPdZU8zfvA3nf9NGKUqEnQrE12VzYlMqKh72ddhzusosqLNEUgH/YhFWBLRFOnY1RCgHMV7pR+sAx2w==",
+ "type": "package",
+ "path": "microsoft.identitymodel.jsonwebtokens/7.5.1",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "lib/net461/Microsoft.IdentityModel.JsonWebTokens.dll",
+ "lib/net461/Microsoft.IdentityModel.JsonWebTokens.xml",
+ "lib/net462/Microsoft.IdentityModel.JsonWebTokens.dll",
+ "lib/net462/Microsoft.IdentityModel.JsonWebTokens.xml",
+ "lib/net472/Microsoft.IdentityModel.JsonWebTokens.dll",
+ "lib/net472/Microsoft.IdentityModel.JsonWebTokens.xml",
+ "lib/net6.0/Microsoft.IdentityModel.JsonWebTokens.dll",
+ "lib/net6.0/Microsoft.IdentityModel.JsonWebTokens.xml",
+ "lib/net8.0/Microsoft.IdentityModel.JsonWebTokens.dll",
+ "lib/net8.0/Microsoft.IdentityModel.JsonWebTokens.xml",
+ "lib/netstandard2.0/Microsoft.IdentityModel.JsonWebTokens.dll",
+ "lib/netstandard2.0/Microsoft.IdentityModel.JsonWebTokens.xml",
+ "microsoft.identitymodel.jsonwebtokens.7.5.1.nupkg.sha512",
+ "microsoft.identitymodel.jsonwebtokens.nuspec"
+ ]
+ },
+ "Microsoft.IdentityModel.Logging/7.5.1": {
+ "sha512": "PnpAQX20BAiDIPYmWUyQSlEaWD8BLXzHpiDGTCT568Cs0ReOeyzNe401LzCeiv6ilug/KefVeV1CeqtCHTo8dw==",
+ "type": "package",
+ "path": "microsoft.identitymodel.logging/7.5.1",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "lib/net461/Microsoft.IdentityModel.Logging.dll",
+ "lib/net461/Microsoft.IdentityModel.Logging.xml",
+ "lib/net462/Microsoft.IdentityModel.Logging.dll",
+ "lib/net462/Microsoft.IdentityModel.Logging.xml",
+ "lib/net472/Microsoft.IdentityModel.Logging.dll",
+ "lib/net472/Microsoft.IdentityModel.Logging.xml",
+ "lib/net6.0/Microsoft.IdentityModel.Logging.dll",
+ "lib/net6.0/Microsoft.IdentityModel.Logging.xml",
+ "lib/net8.0/Microsoft.IdentityModel.Logging.dll",
+ "lib/net8.0/Microsoft.IdentityModel.Logging.xml",
+ "lib/netstandard2.0/Microsoft.IdentityModel.Logging.dll",
+ "lib/netstandard2.0/Microsoft.IdentityModel.Logging.xml",
+ "microsoft.identitymodel.logging.7.5.1.nupkg.sha512",
+ "microsoft.identitymodel.logging.nuspec"
+ ]
+ },
+ "Microsoft.IdentityModel.Tokens/7.5.1": {
+ "sha512": "Q3DKpyFViP84IUlTFKH/zIkswIrmSh2Vd/eFDo4wlOHy4DYxoweZEEw4kDEiKt9VCX6o7SddK3HK2xDYyFpexA==",
+ "type": "package",
+ "path": "microsoft.identitymodel.tokens/7.5.1",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "lib/net461/Microsoft.IdentityModel.Tokens.dll",
+ "lib/net461/Microsoft.IdentityModel.Tokens.xml",
+ "lib/net462/Microsoft.IdentityModel.Tokens.dll",
+ "lib/net462/Microsoft.IdentityModel.Tokens.xml",
+ "lib/net472/Microsoft.IdentityModel.Tokens.dll",
+ "lib/net472/Microsoft.IdentityModel.Tokens.xml",
+ "lib/net6.0/Microsoft.IdentityModel.Tokens.dll",
+ "lib/net6.0/Microsoft.IdentityModel.Tokens.xml",
+ "lib/net8.0/Microsoft.IdentityModel.Tokens.dll",
+ "lib/net8.0/Microsoft.IdentityModel.Tokens.xml",
+ "lib/netstandard2.0/Microsoft.IdentityModel.Tokens.dll",
+ "lib/netstandard2.0/Microsoft.IdentityModel.Tokens.xml",
+ "microsoft.identitymodel.tokens.7.5.1.nupkg.sha512",
+ "microsoft.identitymodel.tokens.nuspec"
+ ]
+ },
+ "Microsoft.IO.RecyclableMemoryStream/3.0.0": {
+ "sha512": "irv0HuqoH8Ig5i2fO+8dmDNdFdsrO+DoQcedwIlb810qpZHBNQHZLW7C/AHBQDgLLpw2T96vmMAy/aE4Yj55Sg==",
+ "type": "package",
+ "path": "microsoft.io.recyclablememorystream/3.0.0",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "README.md",
+ "lib/net6.0/Microsoft.IO.RecyclableMemoryStream.dll",
+ "lib/net6.0/Microsoft.IO.RecyclableMemoryStream.xml",
+ "lib/netstandard2.0/Microsoft.IO.RecyclableMemoryStream.dll",
+ "lib/netstandard2.0/Microsoft.IO.RecyclableMemoryStream.xml",
+ "lib/netstandard2.1/Microsoft.IO.RecyclableMemoryStream.dll",
+ "lib/netstandard2.1/Microsoft.IO.RecyclableMemoryStream.xml",
+ "microsoft.io.recyclablememorystream.3.0.0.nupkg.sha512",
+ "microsoft.io.recyclablememorystream.nuspec"
+ ]
+ },
+ "Microsoft.Testing.Extensions.CodeCoverage/17.13.1": {
+ "sha512": "Ok2HWJdOTzErMqLlWQZ/i2Fw05VWmgh1yhUWFYJAtUmCv6uJSgz/qAiriRgpTjZRWaKbb7HDaGfMgKSNcmaVfw==",
+ "type": "package",
+ "path": "microsoft.testing.extensions.codecoverage/17.13.1",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "Icon.png",
+ "License.txt",
+ "PACKAGE.md",
+ "ThirdPartyNotices.txt",
+ "build/net6.0/Microsoft.Testing.Extensions.CodeCoverage.props",
+ "build/net6.0/Microsoft.Testing.Extensions.CodeCoverage.targets",
+ "build/netstandard2.0/Microsoft.Testing.Extensions.CodeCoverage.props",
+ "build/netstandard2.0/Microsoft.Testing.Extensions.CodeCoverage.targets",
+ "buildMultiTargeting/Microsoft.Testing.Extensions.CodeCoverage.props",
+ "buildMultiTargeting/Microsoft.Testing.Extensions.CodeCoverage.targets",
+ "buildTransitive/net6.0/Microsoft.Testing.Extensions.CodeCoverage.props",
+ "buildTransitive/net6.0/Microsoft.Testing.Extensions.CodeCoverage.targets",
+ "buildTransitive/netstandard2.0/Microsoft.Testing.Extensions.CodeCoverage.props",
+ "buildTransitive/netstandard2.0/Microsoft.Testing.Extensions.CodeCoverage.targets",
+ "lib/net6.0/Microsoft.CodeCoverage.Core.dll",
+ "lib/net6.0/Microsoft.CodeCoverage.Instrumentation.Core.dll",
+ "lib/net6.0/Microsoft.CodeCoverage.Instrumentation.dll",
+ "lib/net6.0/Microsoft.CodeCoverage.Interprocess.dll",
+ "lib/net6.0/Microsoft.Testing.Extensions.CodeCoverage.dll",
+ "lib/net6.0/Microsoft.Testing.Extensions.CodeCoverage.pdb",
+ "lib/net6.0/Microsoft.VisualStudio.CodeCoverage.Shim.dll",
+ "lib/net6.0/Mono.Cecil.Mdb.dll",
+ "lib/net6.0/Mono.Cecil.Pdb.dll",
+ "lib/net6.0/Mono.Cecil.Rocks.dll",
+ "lib/net6.0/Mono.Cecil.dll",
+ "lib/net6.0/cs/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/net6.0/de/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/net6.0/es/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/net6.0/fr/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/net6.0/it/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/net6.0/ja/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/net6.0/ko/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/net6.0/pl/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/net6.0/pt-BR/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/net6.0/ru/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/net6.0/tr/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/net6.0/zh-Hans/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/net6.0/zh-Hant/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/netstandard2.0/Microsoft.CodeCoverage.Core.dll",
+ "lib/netstandard2.0/Microsoft.CodeCoverage.Instrumentation.Core.dll",
+ "lib/netstandard2.0/Microsoft.CodeCoverage.Instrumentation.dll",
+ "lib/netstandard2.0/Microsoft.CodeCoverage.Interprocess.dll",
+ "lib/netstandard2.0/Microsoft.Testing.Extensions.CodeCoverage.dll",
+ "lib/netstandard2.0/Microsoft.Testing.Extensions.CodeCoverage.pdb",
+ "lib/netstandard2.0/Microsoft.VisualStudio.CodeCoverage.Shim.dll",
+ "lib/netstandard2.0/Mono.Cecil.Mdb.dll",
+ "lib/netstandard2.0/Mono.Cecil.Pdb.dll",
+ "lib/netstandard2.0/Mono.Cecil.Rocks.dll",
+ "lib/netstandard2.0/Mono.Cecil.dll",
+ "lib/netstandard2.0/cs/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/netstandard2.0/de/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/netstandard2.0/es/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/netstandard2.0/fr/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/netstandard2.0/it/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/netstandard2.0/ja/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/netstandard2.0/ko/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/netstandard2.0/pl/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/netstandard2.0/pt-BR/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/netstandard2.0/ru/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/netstandard2.0/tr/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/netstandard2.0/zh-Hans/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "lib/netstandard2.0/zh-Hant/Microsoft.Testing.Extensions.CodeCoverage.resources.dll",
+ "microsoft.testing.extensions.codecoverage.17.13.1.nupkg.sha512",
+ "microsoft.testing.extensions.codecoverage.nuspec",
+ "runtimes/linux-musl-x64/native/Cov_x64.config",
+ "runtimes/linux-musl-x64/native/libCoverageInstrumentationMethod.so",
+ "runtimes/linux-musl-x64/native/libInstrumentationEngine.so",
+ "runtimes/linux-x64/native/Cov_x64.config",
+ "runtimes/linux-x64/native/libCoverageInstrumentationMethod.so",
+ "runtimes/linux-x64/native/libInstrumentationEngine.so",
+ "runtimes/osx-x64/native/Cov_x64.config",
+ "runtimes/osx-x64/native/libCoverageInstrumentationMethod.dylib",
+ "runtimes/osx-x64/native/libInstrumentationEngine.dylib",
+ "runtimes/win-arm64/native/CodeCoverageMessages.dll",
+ "runtimes/win-arm64/native/Cov_arm64.config",
+ "runtimes/win-arm64/native/Cov_x64.config",
+ "runtimes/win-arm64/native/Cov_x86.config",
+ "runtimes/win-arm64/native/MicrosoftInstrumentationEngine_arm64.dll",
+ "runtimes/win-arm64/native/MicrosoftInstrumentationEngine_x64.dll",
+ "runtimes/win-arm64/native/MicrosoftInstrumentationEngine_x86.dll",
+ "runtimes/win-arm64/native/covrun32.dll",
+ "runtimes/win-arm64/native/covrun64.dll",
+ "runtimes/win-arm64/native/covrunarm64.dll",
+ "runtimes/win-arm64/native/msdia140.dll",
+ "runtimes/win-x64/native/CodeCoverageMessages.dll",
+ "runtimes/win-x64/native/Cov_arm64.config",
+ "runtimes/win-x64/native/Cov_x64.config",
+ "runtimes/win-x64/native/Cov_x86.config",
+ "runtimes/win-x64/native/MicrosoftInstrumentationEngine_arm64.dll",
+ "runtimes/win-x64/native/MicrosoftInstrumentationEngine_x64.dll",
+ "runtimes/win-x64/native/MicrosoftInstrumentationEngine_x86.dll",
+ "runtimes/win-x64/native/covrun32.dll",
+ "runtimes/win-x64/native/covrun64.dll",
+ "runtimes/win-x64/native/covrunarm64.dll",
+ "runtimes/win-x64/native/msdia140.dll",
+ "runtimes/win-x86/native/CodeCoverageMessages.dll",
+ "runtimes/win-x86/native/Cov_arm64.config",
+ "runtimes/win-x86/native/Cov_x64.config",
+ "runtimes/win-x86/native/Cov_x86.config",
+ "runtimes/win-x86/native/MicrosoftInstrumentationEngine_arm64.dll",
+ "runtimes/win-x86/native/MicrosoftInstrumentationEngine_x64.dll",
+ "runtimes/win-x86/native/MicrosoftInstrumentationEngine_x86.dll",
+ "runtimes/win-x86/native/covrun32.dll",
+ "runtimes/win-x86/native/covrun64.dll",
+ "runtimes/win-x86/native/covrunarm64.dll",
+ "runtimes/win-x86/native/msdia140.dll"
+ ]
+ },
+ "Microsoft.Testing.Extensions.TrxReport.Abstractions/1.4.3": {
+ "sha512": "16sWznD6ZMok/zgW+vrO6zerCFMD9N+ey9bi1iV/e9xxsQb4V4y/aW6cY/Y7E9jA7pc+aZ6ffZby43yxQOoYZA==",
+ "type": "package",
+ "path": "microsoft.testing.extensions.trxreport.abstractions/1.4.3",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "Icon.png",
+ "PACKAGE.md",
+ "lib/net6.0/Microsoft.Testing.Extensions.TrxReport.Abstractions.dll",
+ "lib/net6.0/Microsoft.Testing.Extensions.TrxReport.Abstractions.xml",
+ "lib/net7.0/Microsoft.Testing.Extensions.TrxReport.Abstractions.dll",
+ "lib/net7.0/Microsoft.Testing.Extensions.TrxReport.Abstractions.xml",
+ "lib/net8.0/Microsoft.Testing.Extensions.TrxReport.Abstractions.dll",
+ "lib/net8.0/Microsoft.Testing.Extensions.TrxReport.Abstractions.xml",
+ "lib/netstandard2.0/Microsoft.Testing.Extensions.TrxReport.Abstractions.dll",
+ "lib/netstandard2.0/Microsoft.Testing.Extensions.TrxReport.Abstractions.xml",
+ "microsoft.testing.extensions.trxreport.abstractions.1.4.3.nupkg.sha512",
+ "microsoft.testing.extensions.trxreport.abstractions.nuspec"
+ ]
+ },
+ "Microsoft.Testing.Platform/1.4.3": {
+ "sha512": "NedIbwl1T7+ZMeg7gwk0Db8/RFLf0siyVpeTcRMMOle6Xl/ujaYOM4Aduo8rEfVqNj3kcQ7blegpyT3dHi+0PA==",
+ "type": "package",
+ "path": "microsoft.testing.platform/1.4.3",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "Icon.png",
+ "PACKAGE.md",
+ "build/net6.0/Microsoft.Testing.Platform.props",
+ "build/net7.0/Microsoft.Testing.Platform.props",
+ "build/net8.0/Microsoft.Testing.Platform.props",
+ "build/netstandard2.0/Microsoft.Testing.Platform.props",
+ "buildMultiTargeting/Microsoft.Testing.Platform.props",
+ "buildTransitive/net6.0/Microsoft.Testing.Platform.props",
+ "buildTransitive/net7.0/Microsoft.Testing.Platform.props",
+ "buildTransitive/net8.0/Microsoft.Testing.Platform.props",
+ "buildTransitive/netstandard2.0/Microsoft.Testing.Platform.props",
+ "lib/net6.0/Microsoft.Testing.Platform.dll",
+ "lib/net6.0/Microsoft.Testing.Platform.xml",
+ "lib/net6.0/cs/Microsoft.Testing.Platform.resources.dll",
+ "lib/net6.0/de/Microsoft.Testing.Platform.resources.dll",
+ "lib/net6.0/es/Microsoft.Testing.Platform.resources.dll",
+ "lib/net6.0/fr/Microsoft.Testing.Platform.resources.dll",
+ "lib/net6.0/it/Microsoft.Testing.Platform.resources.dll",
+ "lib/net6.0/ja/Microsoft.Testing.Platform.resources.dll",
+ "lib/net6.0/ko/Microsoft.Testing.Platform.resources.dll",
+ "lib/net6.0/pl/Microsoft.Testing.Platform.resources.dll",
+ "lib/net6.0/pt-BR/Microsoft.Testing.Platform.resources.dll",
+ "lib/net6.0/ru/Microsoft.Testing.Platform.resources.dll",
+ "lib/net6.0/tr/Microsoft.Testing.Platform.resources.dll",
+ "lib/net6.0/zh-Hans/Microsoft.Testing.Platform.resources.dll",
+ "lib/net6.0/zh-Hant/Microsoft.Testing.Platform.resources.dll",
+ "lib/net7.0/Microsoft.Testing.Platform.dll",
+ "lib/net7.0/Microsoft.Testing.Platform.xml",
+ "lib/net7.0/cs/Microsoft.Testing.Platform.resources.dll",
+ "lib/net7.0/de/Microsoft.Testing.Platform.resources.dll",
+ "lib/net7.0/es/Microsoft.Testing.Platform.resources.dll",
+ "lib/net7.0/fr/Microsoft.Testing.Platform.resources.dll",
+ "lib/net7.0/it/Microsoft.Testing.Platform.resources.dll",
+ "lib/net7.0/ja/Microsoft.Testing.Platform.resources.dll",
+ "lib/net7.0/ko/Microsoft.Testing.Platform.resources.dll",
+ "lib/net7.0/pl/Microsoft.Testing.Platform.resources.dll",
+ "lib/net7.0/pt-BR/Microsoft.Testing.Platform.resources.dll",
+ "lib/net7.0/ru/Microsoft.Testing.Platform.resources.dll",
+ "lib/net7.0/tr/Microsoft.Testing.Platform.resources.dll",
+ "lib/net7.0/zh-Hans/Microsoft.Testing.Platform.resources.dll",
+ "lib/net7.0/zh-Hant/Microsoft.Testing.Platform.resources.dll",
+ "lib/net8.0/Microsoft.Testing.Platform.dll",
+ "lib/net8.0/Microsoft.Testing.Platform.xml",
+ "lib/net8.0/cs/Microsoft.Testing.Platform.resources.dll",
+ "lib/net8.0/de/Microsoft.Testing.Platform.resources.dll",
+ "lib/net8.0/es/Microsoft.Testing.Platform.resources.dll",
+ "lib/net8.0/fr/Microsoft.Testing.Platform.resources.dll",
+ "lib/net8.0/it/Microsoft.Testing.Platform.resources.dll",
+ "lib/net8.0/ja/Microsoft.Testing.Platform.resources.dll",
+ "lib/net8.0/ko/Microsoft.Testing.Platform.resources.dll",
+ "lib/net8.0/pl/Microsoft.Testing.Platform.resources.dll",
+ "lib/net8.0/pt-BR/Microsoft.Testing.Platform.resources.dll",
+ "lib/net8.0/ru/Microsoft.Testing.Platform.resources.dll",
+ "lib/net8.0/tr/Microsoft.Testing.Platform.resources.dll",
+ "lib/net8.0/zh-Hans/Microsoft.Testing.Platform.resources.dll",
+ "lib/net8.0/zh-Hant/Microsoft.Testing.Platform.resources.dll",
+ "lib/netstandard2.0/Microsoft.Testing.Platform.dll",
+ "lib/netstandard2.0/Microsoft.Testing.Platform.xml",
+ "lib/netstandard2.0/cs/Microsoft.Testing.Platform.resources.dll",
+ "lib/netstandard2.0/de/Microsoft.Testing.Platform.resources.dll",
+ "lib/netstandard2.0/es/Microsoft.Testing.Platform.resources.dll",
+ "lib/netstandard2.0/fr/Microsoft.Testing.Platform.resources.dll",
+ "lib/netstandard2.0/it/Microsoft.Testing.Platform.resources.dll",
+ "lib/netstandard2.0/ja/Microsoft.Testing.Platform.resources.dll",
+ "lib/netstandard2.0/ko/Microsoft.Testing.Platform.resources.dll",
+ "lib/netstandard2.0/pl/Microsoft.Testing.Platform.resources.dll",
+ "lib/netstandard2.0/pt-BR/Microsoft.Testing.Platform.resources.dll",
+ "lib/netstandard2.0/ru/Microsoft.Testing.Platform.resources.dll",
+ "lib/netstandard2.0/tr/Microsoft.Testing.Platform.resources.dll",
+ "lib/netstandard2.0/zh-Hans/Microsoft.Testing.Platform.resources.dll",
+ "lib/netstandard2.0/zh-Hant/Microsoft.Testing.Platform.resources.dll",
+ "microsoft.testing.platform.1.4.3.nupkg.sha512",
+ "microsoft.testing.platform.nuspec"
+ ]
+ },
+ "Microsoft.Testing.Platform.MSBuild/1.4.3": {
+ "sha512": "1gGqgHtiZ6tZn/6Tby+qlKpNe5Ye/5LnxlSsyl4XMZ4m4V+Cu1K1m+gD1zxoxHIvLjgX8mCnQRK95MGBBFuumw==",
+ "type": "package",
+ "path": "microsoft.testing.platform.msbuild/1.4.3",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "Icon.png",
+ "PACKAGE.md",
+ "_MSBuildTasks/netstandard2.0/Microsoft.Testing.Platform.MSBuild.dll",
+ "_MSBuildTasks/netstandard2.0/Microsoft.Testing.Platform.dll",
+ "build/net6.0/Microsoft.Testing.Platform.MSBuild.props",
+ "build/net6.0/Microsoft.Testing.Platform.MSBuild.targets",
+ "build/net7.0/Microsoft.Testing.Platform.MSBuild.props",
+ "build/net7.0/Microsoft.Testing.Platform.MSBuild.targets",
+ "build/net8.0/Microsoft.Testing.Platform.MSBuild.props",
+ "build/net8.0/Microsoft.Testing.Platform.MSBuild.targets",
+ "build/netstandard2.0/Microsoft.Testing.Platform.MSBuild.props",
+ "build/netstandard2.0/Microsoft.Testing.Platform.MSBuild.targets",
+ "buildMultiTargeting/Microsoft.Testing.Platform.MSBuild.VSTest.targets",
+ "buildMultiTargeting/Microsoft.Testing.Platform.MSBuild.props",
+ "buildMultiTargeting/Microsoft.Testing.Platform.MSBuild.targets",
+ "buildTransitive/net6.0/Microsoft.Testing.Platform.MSBuild.props",
+ "buildTransitive/net6.0/Microsoft.Testing.Platform.MSBuild.targets",
+ "buildTransitive/net7.0/Microsoft.Testing.Platform.MSBuild.props",
+ "buildTransitive/net7.0/Microsoft.Testing.Platform.MSBuild.targets",
+ "buildTransitive/net8.0/Microsoft.Testing.Platform.MSBuild.props",
+ "buildTransitive/net8.0/Microsoft.Testing.Platform.MSBuild.targets",
+ "buildTransitive/netstandard2.0/Microsoft.Testing.Platform.MSBuild.props",
+ "buildTransitive/netstandard2.0/Microsoft.Testing.Platform.MSBuild.targets",
+ "lib/net6.0/Microsoft.Testing.Platform.MSBuild.dll",
+ "lib/net6.0/Microsoft.Testing.Platform.MSBuild.xml",
+ "lib/net6.0/cs/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net6.0/de/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net6.0/es/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net6.0/fr/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net6.0/it/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net6.0/ja/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net6.0/ko/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net6.0/pl/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net6.0/pt-BR/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net6.0/ru/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net6.0/tr/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net6.0/zh-Hans/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net6.0/zh-Hant/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net7.0/Microsoft.Testing.Platform.MSBuild.dll",
+ "lib/net7.0/Microsoft.Testing.Platform.MSBuild.xml",
+ "lib/net7.0/cs/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net7.0/de/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net7.0/es/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net7.0/fr/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net7.0/it/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net7.0/ja/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net7.0/ko/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net7.0/pl/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net7.0/pt-BR/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net7.0/ru/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net7.0/tr/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net7.0/zh-Hans/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net7.0/zh-Hant/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net8.0/Microsoft.Testing.Platform.MSBuild.dll",
+ "lib/net8.0/Microsoft.Testing.Platform.MSBuild.xml",
+ "lib/net8.0/cs/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net8.0/de/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net8.0/es/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net8.0/fr/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net8.0/it/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net8.0/ja/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net8.0/ko/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net8.0/pl/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net8.0/pt-BR/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net8.0/ru/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net8.0/tr/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net8.0/zh-Hans/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/net8.0/zh-Hant/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/netstandard2.0/Microsoft.Testing.Platform.MSBuild.dll",
+ "lib/netstandard2.0/Microsoft.Testing.Platform.MSBuild.xml",
+ "lib/netstandard2.0/cs/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/netstandard2.0/de/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/netstandard2.0/es/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/netstandard2.0/fr/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/netstandard2.0/it/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/netstandard2.0/ja/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/netstandard2.0/ko/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/netstandard2.0/pl/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/netstandard2.0/pt-BR/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/netstandard2.0/ru/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/netstandard2.0/tr/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/netstandard2.0/zh-Hans/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "lib/netstandard2.0/zh-Hant/Microsoft.Testing.Platform.MSBuild.resources.dll",
+ "microsoft.testing.platform.msbuild.1.4.3.nupkg.sha512",
+ "microsoft.testing.platform.msbuild.nuspec"
+ ]
+ },
+ "MimeMapping/3.0.1": {
+ "sha512": "lhYcUVnWKaqrboAwi05YLCx3wdluM9Sr1Mv5Emhgc8c8yNVvdiSEnQJMdDvgb4grlYTaOmbnhYaezoeateX95w==",
+ "type": "package",
+ "path": "mimemapping/3.0.1",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "README.md",
+ "lib/net462/MimeMapping.dll",
+ "lib/net462/MimeMapping.xml",
+ "lib/netstandard2.0/MimeMapping.dll",
+ "lib/netstandard2.0/MimeMapping.xml",
+ "mimemapping.3.0.1.nupkg.sha512",
+ "mimemapping.nuspec"
+ ]
+ },
+ "Newtonsoft.Json/13.0.3": {
+ "sha512": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==",
+ "type": "package",
+ "path": "newtonsoft.json/13.0.3",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "LICENSE.md",
+ "README.md",
+ "lib/net20/Newtonsoft.Json.dll",
+ "lib/net20/Newtonsoft.Json.xml",
+ "lib/net35/Newtonsoft.Json.dll",
+ "lib/net35/Newtonsoft.Json.xml",
+ "lib/net40/Newtonsoft.Json.dll",
+ "lib/net40/Newtonsoft.Json.xml",
+ "lib/net45/Newtonsoft.Json.dll",
+ "lib/net45/Newtonsoft.Json.xml",
+ "lib/net6.0/Newtonsoft.Json.dll",
+ "lib/net6.0/Newtonsoft.Json.xml",
+ "lib/netstandard1.0/Newtonsoft.Json.dll",
+ "lib/netstandard1.0/Newtonsoft.Json.xml",
+ "lib/netstandard1.3/Newtonsoft.Json.dll",
+ "lib/netstandard1.3/Newtonsoft.Json.xml",
+ "lib/netstandard2.0/Newtonsoft.Json.dll",
+ "lib/netstandard2.0/Newtonsoft.Json.xml",
+ "newtonsoft.json.13.0.3.nupkg.sha512",
+ "newtonsoft.json.nuspec",
+ "packageIcon.png"
+ ]
+ },
+ "Supabase/1.1.1": {
+ "sha512": "LW9O05IiZBW3YUDT/gndPKvzT3I7PVgx0j87+AdJu7mT42m7oh2nOnjuDR9pU0E9FE2Ke/QGovrH/u5OjGn7lg==",
+ "type": "package",
+ "path": "supabase/1.1.1",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "README.md",
+ "icon.png",
+ "lib/netstandard2.1/Supabase.dll",
+ "lib/netstandard2.1/Supabase.xml",
+ "supabase.1.1.1.nupkg.sha512",
+ "supabase.nuspec"
+ ]
+ },
+ "Supabase.Core/1.0.0": {
+ "sha512": "fJK3Kfq1alw53AGWHBr+dhPu+BUR5dKuBjGhcxrFRVdsFFFWSD5iPIdTYi0CUQDA2b1OjGudYL1xd51yp4hU9Q==",
+ "type": "package",
+ "path": "supabase.core/1.0.0",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "README.md",
+ "icon.png",
+ "lib/netstandard2.0/Supabase.Core.dll",
+ "lib/netstandard2.0/Supabase.Core.xml",
+ "supabase.core.1.0.0.nupkg.sha512",
+ "supabase.core.nuspec"
+ ]
+ },
+ "Supabase.Functions/2.0.0": {
+ "sha512": "rc6zlo6XFkQw/B9fEgwpXHtmNPrnnHmtc96PTbviBJ9lzqPT/Un/G3V9MltlORtnG2RLkLvvS/t2AXAO8m2SCQ==",
+ "type": "package",
+ "path": "supabase.functions/2.0.0",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "README.md",
+ "icon.png",
+ "lib/netstandard2.0/Supabase.Functions.dll",
+ "lib/netstandard2.0/Supabase.Functions.xml",
+ "supabase.functions.2.0.0.nupkg.sha512",
+ "supabase.functions.nuspec"
+ ]
+ },
+ "Supabase.Gotrue/6.0.3": {
+ "sha512": "8dkg000ib95bJm0ffDPUrALrefBHrkiqcolNjuUEStF2TeytPbV+OtOUJAMBOqZ2f1nsCY61Ck/7NOmOyGteDw==",
+ "type": "package",
+ "path": "supabase.gotrue/6.0.3",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "README.md",
+ "icon.png",
+ "lib/netstandard2.1/Supabase.Gotrue.dll",
+ "lib/netstandard2.1/Supabase.Gotrue.xml",
+ "supabase.gotrue.6.0.3.nupkg.sha512",
+ "supabase.gotrue.nuspec"
+ ]
+ },
+ "Supabase.Postgrest/4.0.3": {
+ "sha512": "hpDIh+E5bDgZiHMuM6l+RDm9WWlt/T3fXXFQoqzlsrJFesFMNzkK9feVBG5egJyL/OlwmxuLsnPkR7O+bV3Vcw==",
+ "type": "package",
+ "path": "supabase.postgrest/4.0.3",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "README.md",
+ "icon.png",
+ "lib/netstandard2.0/Supabase.Postgrest.dll",
+ "lib/netstandard2.0/Supabase.Postgrest.xml",
+ "supabase.postgrest.4.0.3.nupkg.sha512",
+ "supabase.postgrest.nuspec"
+ ]
+ },
+ "Supabase.Realtime/7.0.2": {
+ "sha512": "9nwlR9RR+uyD63VUaiqAPsd76NaeM6ORAHq7otc4G34RzBtf6aqjPg9IF6d1DGIk78/lJP31+D4NJmQhl3PkJQ==",
+ "type": "package",
+ "path": "supabase.realtime/7.0.2",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "README.md",
+ "icon.png",
+ "lib/netstandard2.0/Supabase.Realtime.dll",
+ "lib/netstandard2.0/Supabase.Realtime.xml",
+ "lib/netstandard2.1/Supabase.Realtime.dll",
+ "lib/netstandard2.1/Supabase.Realtime.xml",
+ "supabase.realtime.7.0.2.nupkg.sha512",
+ "supabase.realtime.nuspec"
+ ]
+ },
+ "Supabase.Storage/2.0.2": {
+ "sha512": "YKxgwVgLjxi32ze29FT8aSLifiTVSZSxSyI9taOewp6wuxh+aMIPLKWtGEhFhegLv2iFwGcZ3ybMDkCi6RB7Rw==",
+ "type": "package",
+ "path": "supabase.storage/2.0.2",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "README.md",
+ "icon.png",
+ "lib/netstandard2.0/Supabase.Storage.dll",
+ "lib/netstandard2.0/Supabase.Storage.xml",
+ "supabase.storage.2.0.2.nupkg.sha512",
+ "supabase.storage.nuspec"
+ ]
+ },
+ "System.Buffers/4.5.1": {
+ "sha512": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==",
+ "type": "package",
+ "path": "system.buffers/4.5.1",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "LICENSE.TXT",
+ "THIRD-PARTY-NOTICES.TXT",
+ "lib/net461/System.Buffers.dll",
+ "lib/net461/System.Buffers.xml",
+ "lib/netcoreapp2.0/_._",
+ "lib/netstandard1.1/System.Buffers.dll",
+ "lib/netstandard1.1/System.Buffers.xml",
+ "lib/netstandard2.0/System.Buffers.dll",
+ "lib/netstandard2.0/System.Buffers.xml",
+ "lib/uap10.0.16299/_._",
+ "ref/net45/System.Buffers.dll",
+ "ref/net45/System.Buffers.xml",
+ "ref/netcoreapp2.0/_._",
+ "ref/netstandard1.1/System.Buffers.dll",
+ "ref/netstandard1.1/System.Buffers.xml",
+ "ref/netstandard2.0/System.Buffers.dll",
+ "ref/netstandard2.0/System.Buffers.xml",
+ "ref/uap10.0.16299/_._",
+ "system.buffers.4.5.1.nupkg.sha512",
+ "system.buffers.nuspec",
+ "useSharedDesignerContext.txt",
+ "version.txt"
+ ]
+ },
+ "System.Collections.Immutable/8.0.0": {
+ "sha512": "AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg==",
+ "type": "package",
+ "path": "system.collections.immutable/8.0.0",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "Icon.png",
+ "LICENSE.TXT",
+ "PACKAGE.md",
+ "THIRD-PARTY-NOTICES.TXT",
+ "buildTransitive/net461/System.Collections.Immutable.targets",
+ "buildTransitive/net462/_._",
+ "buildTransitive/net6.0/_._",
+ "buildTransitive/netcoreapp2.0/System.Collections.Immutable.targets",
+ "lib/net462/System.Collections.Immutable.dll",
+ "lib/net462/System.Collections.Immutable.xml",
+ "lib/net6.0/System.Collections.Immutable.dll",
+ "lib/net6.0/System.Collections.Immutable.xml",
+ "lib/net7.0/System.Collections.Immutable.dll",
+ "lib/net7.0/System.Collections.Immutable.xml",
+ "lib/net8.0/System.Collections.Immutable.dll",
+ "lib/net8.0/System.Collections.Immutable.xml",
+ "lib/netstandard2.0/System.Collections.Immutable.dll",
+ "lib/netstandard2.0/System.Collections.Immutable.xml",
+ "system.collections.immutable.8.0.0.nupkg.sha512",
+ "system.collections.immutable.nuspec",
+ "useSharedDesignerContext.txt"
+ ]
+ },
+ "System.IdentityModel.Tokens.Jwt/7.5.1": {
+ "sha512": "UUw+E0R73lZLlXgneYIJQxNs1kfbcxjVzw64JQyiwjqCd4HMpAbjn+xRo86QZT84uHq8/MkqvfH82tgjgPzpuw==",
+ "type": "package",
+ "path": "system.identitymodel.tokens.jwt/7.5.1",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "lib/net461/System.IdentityModel.Tokens.Jwt.dll",
+ "lib/net461/System.IdentityModel.Tokens.Jwt.xml",
+ "lib/net462/System.IdentityModel.Tokens.Jwt.dll",
+ "lib/net462/System.IdentityModel.Tokens.Jwt.xml",
+ "lib/net472/System.IdentityModel.Tokens.Jwt.dll",
+ "lib/net472/System.IdentityModel.Tokens.Jwt.xml",
+ "lib/net6.0/System.IdentityModel.Tokens.Jwt.dll",
+ "lib/net6.0/System.IdentityModel.Tokens.Jwt.xml",
+ "lib/net8.0/System.IdentityModel.Tokens.Jwt.dll",
+ "lib/net8.0/System.IdentityModel.Tokens.Jwt.xml",
+ "lib/netstandard2.0/System.IdentityModel.Tokens.Jwt.dll",
+ "lib/netstandard2.0/System.IdentityModel.Tokens.Jwt.xml",
+ "system.identitymodel.tokens.jwt.7.5.1.nupkg.sha512",
+ "system.identitymodel.tokens.jwt.nuspec"
+ ]
+ },
+ "System.Memory/4.5.4": {
+ "sha512": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==",
+ "type": "package",
+ "path": "system.memory/4.5.4",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "LICENSE.TXT",
+ "THIRD-PARTY-NOTICES.TXT",
+ "lib/net461/System.Memory.dll",
+ "lib/net461/System.Memory.xml",
+ "lib/netcoreapp2.1/_._",
+ "lib/netstandard1.1/System.Memory.dll",
+ "lib/netstandard1.1/System.Memory.xml",
+ "lib/netstandard2.0/System.Memory.dll",
+ "lib/netstandard2.0/System.Memory.xml",
+ "ref/netcoreapp2.1/_._",
+ "system.memory.4.5.4.nupkg.sha512",
+ "system.memory.nuspec",
+ "useSharedDesignerContext.txt",
+ "version.txt"
+ ]
+ },
+ "System.Reactive/6.0.0": {
+ "sha512": "31kfaW4ZupZzPsI5PVe77VhnvFF55qgma7KZr/E0iFTs6fmdhhG8j0mgEx620iLTey1EynOkEfnyTjtNEpJzGw==",
+ "type": "package",
+ "path": "system.reactive/6.0.0",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "build/net6.0-windows10.0.19041/_._",
+ "build/net6.0/_._",
+ "buildTransitive/net6.0-windows10.0.19041/_._",
+ "buildTransitive/net6.0/_._",
+ "icon.png",
+ "lib/net472/System.Reactive.dll",
+ "lib/net472/System.Reactive.xml",
+ "lib/net6.0-windows10.0.19041/System.Reactive.dll",
+ "lib/net6.0-windows10.0.19041/System.Reactive.xml",
+ "lib/net6.0/System.Reactive.dll",
+ "lib/net6.0/System.Reactive.xml",
+ "lib/netstandard2.0/System.Reactive.dll",
+ "lib/netstandard2.0/System.Reactive.xml",
+ "lib/uap10.0.18362/System.Reactive.dll",
+ "lib/uap10.0.18362/System.Reactive.pri",
+ "lib/uap10.0.18362/System.Reactive.xml",
+ "readme.md",
+ "system.reactive.6.0.0.nupkg.sha512",
+ "system.reactive.nuspec"
+ ]
+ },
+ "System.Reflection.Metadata/8.0.0": {
+ "sha512": "ptvgrFh7PvWI8bcVqG5rsA/weWM09EnthFHR5SCnS6IN+P4mj6rE1lBDC4U8HL9/57htKAqy4KQ3bBj84cfYyQ==",
+ "type": "package",
+ "path": "system.reflection.metadata/8.0.0",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "Icon.png",
+ "LICENSE.TXT",
+ "PACKAGE.md",
+ "THIRD-PARTY-NOTICES.TXT",
+ "buildTransitive/net461/System.Reflection.Metadata.targets",
+ "buildTransitive/net462/_._",
+ "buildTransitive/net6.0/_._",
+ "buildTransitive/netcoreapp2.0/System.Reflection.Metadata.targets",
+ "lib/net462/System.Reflection.Metadata.dll",
+ "lib/net462/System.Reflection.Metadata.xml",
+ "lib/net6.0/System.Reflection.Metadata.dll",
+ "lib/net6.0/System.Reflection.Metadata.xml",
+ "lib/net7.0/System.Reflection.Metadata.dll",
+ "lib/net7.0/System.Reflection.Metadata.xml",
+ "lib/net8.0/System.Reflection.Metadata.dll",
+ "lib/net8.0/System.Reflection.Metadata.xml",
+ "lib/netstandard2.0/System.Reflection.Metadata.dll",
+ "lib/netstandard2.0/System.Reflection.Metadata.xml",
+ "system.reflection.metadata.8.0.0.nupkg.sha512",
+ "system.reflection.metadata.nuspec",
+ "useSharedDesignerContext.txt"
+ ]
+ },
+ "System.Runtime.CompilerServices.Unsafe/6.0.0": {
+ "sha512": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==",
+ "type": "package",
+ "path": "system.runtime.compilerservices.unsafe/6.0.0",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "Icon.png",
+ "LICENSE.TXT",
+ "THIRD-PARTY-NOTICES.TXT",
+ "buildTransitive/netcoreapp2.0/System.Runtime.CompilerServices.Unsafe.targets",
+ "buildTransitive/netcoreapp3.1/_._",
+ "lib/net461/System.Runtime.CompilerServices.Unsafe.dll",
+ "lib/net461/System.Runtime.CompilerServices.Unsafe.xml",
+ "lib/net6.0/System.Runtime.CompilerServices.Unsafe.dll",
+ "lib/net6.0/System.Runtime.CompilerServices.Unsafe.xml",
+ "lib/netcoreapp3.1/System.Runtime.CompilerServices.Unsafe.dll",
+ "lib/netcoreapp3.1/System.Runtime.CompilerServices.Unsafe.xml",
+ "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.dll",
+ "lib/netstandard2.0/System.Runtime.CompilerServices.Unsafe.xml",
+ "system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512",
+ "system.runtime.compilerservices.unsafe.nuspec",
+ "useSharedDesignerContext.txt"
+ ]
+ },
+ "System.Text.Encodings.Web/6.0.0": {
+ "sha512": "Vg8eB5Tawm1IFqj4TVK1czJX89rhFxJo9ELqc/Eiq0eXy13RK00eubyU6TJE6y+GQXjyV5gSfiewDUZjQgSE0w==",
+ "type": "package",
+ "path": "system.text.encodings.web/6.0.0",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "Icon.png",
+ "LICENSE.TXT",
+ "THIRD-PARTY-NOTICES.TXT",
+ "buildTransitive/netcoreapp2.0/System.Text.Encodings.Web.targets",
+ "buildTransitive/netcoreapp3.1/_._",
+ "lib/net461/System.Text.Encodings.Web.dll",
+ "lib/net461/System.Text.Encodings.Web.xml",
+ "lib/net6.0/System.Text.Encodings.Web.dll",
+ "lib/net6.0/System.Text.Encodings.Web.xml",
+ "lib/netcoreapp3.1/System.Text.Encodings.Web.dll",
+ "lib/netcoreapp3.1/System.Text.Encodings.Web.xml",
+ "lib/netstandard2.0/System.Text.Encodings.Web.dll",
+ "lib/netstandard2.0/System.Text.Encodings.Web.xml",
+ "runtimes/browser/lib/net6.0/System.Text.Encodings.Web.dll",
+ "runtimes/browser/lib/net6.0/System.Text.Encodings.Web.xml",
+ "system.text.encodings.web.6.0.0.nupkg.sha512",
+ "system.text.encodings.web.nuspec",
+ "useSharedDesignerContext.txt"
+ ]
+ },
+ "System.Text.Json/6.0.10": {
+ "sha512": "NSB0kDipxn2ychp88NXWfFRFlmi1bst/xynOutbnpEfRCT9JZkZ7KOmF/I/hNKo2dILiMGnqblm+j1sggdLB9g==",
+ "type": "package",
+ "path": "system.text.json/6.0.10",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "Icon.png",
+ "LICENSE.TXT",
+ "THIRD-PARTY-NOTICES.TXT",
+ "analyzers/dotnet/roslyn3.11/cs/System.Text.Json.SourceGeneration.dll",
+ "analyzers/dotnet/roslyn3.11/cs/cs/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/de/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/es/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/fr/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/it/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/ja/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/ko/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/pl/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/pt-BR/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/ru/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/tr/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/zh-Hans/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn3.11/cs/zh-Hant/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/System.Text.Json.SourceGeneration.dll",
+ "analyzers/dotnet/roslyn4.0/cs/cs/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/de/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/es/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/fr/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/it/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/ja/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/ko/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/pl/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/pt-BR/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/ru/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/tr/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/zh-Hans/System.Text.Json.SourceGeneration.resources.dll",
+ "analyzers/dotnet/roslyn4.0/cs/zh-Hant/System.Text.Json.SourceGeneration.resources.dll",
+ "buildTransitive/netcoreapp2.0/System.Text.Json.targets",
+ "buildTransitive/netcoreapp3.1/System.Text.Json.targets",
+ "buildTransitive/netstandard2.0/System.Text.Json.targets",
+ "lib/net461/System.Text.Json.dll",
+ "lib/net461/System.Text.Json.xml",
+ "lib/net6.0/System.Text.Json.dll",
+ "lib/net6.0/System.Text.Json.xml",
+ "lib/netcoreapp3.1/System.Text.Json.dll",
+ "lib/netcoreapp3.1/System.Text.Json.xml",
+ "lib/netstandard2.0/System.Text.Json.dll",
+ "lib/netstandard2.0/System.Text.Json.xml",
+ "system.text.json.6.0.10.nupkg.sha512",
+ "system.text.json.nuspec",
+ "useSharedDesignerContext.txt"
+ ]
+ },
+ "System.Threading.Channels/8.0.0": {
+ "sha512": "CMaFr7v+57RW7uZfZkPExsPB6ljwzhjACWW1gfU35Y56rk72B/Wu+sTqxVmGSk4SFUlPc3cjeKND0zktziyjBA==",
+ "type": "package",
+ "path": "system.threading.channels/8.0.0",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "Icon.png",
+ "LICENSE.TXT",
+ "PACKAGE.md",
+ "THIRD-PARTY-NOTICES.TXT",
+ "buildTransitive/net461/System.Threading.Channels.targets",
+ "buildTransitive/net462/_._",
+ "buildTransitive/net6.0/_._",
+ "buildTransitive/netcoreapp2.0/System.Threading.Channels.targets",
+ "lib/net462/System.Threading.Channels.dll",
+ "lib/net462/System.Threading.Channels.xml",
+ "lib/net6.0/System.Threading.Channels.dll",
+ "lib/net6.0/System.Threading.Channels.xml",
+ "lib/net7.0/System.Threading.Channels.dll",
+ "lib/net7.0/System.Threading.Channels.xml",
+ "lib/net8.0/System.Threading.Channels.dll",
+ "lib/net8.0/System.Threading.Channels.xml",
+ "lib/netstandard2.0/System.Threading.Channels.dll",
+ "lib/netstandard2.0/System.Threading.Channels.xml",
+ "lib/netstandard2.1/System.Threading.Channels.dll",
+ "lib/netstandard2.1/System.Threading.Channels.xml",
+ "system.threading.channels.8.0.0.nupkg.sha512",
+ "system.threading.channels.nuspec",
+ "useSharedDesignerContext.txt"
+ ]
+ },
+ "TUnit/0.6.123": {
+ "sha512": "lbjLd39Yh+GMG4W/OwN2xRAmsm8y1klrKyC3RWB4n+HBoQxl8N/BfXuJ6yuxzMc8FyH9JgI++C+s9PAtSYP6QQ==",
+ "type": "package",
+ "path": "tunit/0.6.123",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "README.md",
+ "lib/net8.0/TUnit.dll",
+ "lib/net9.0/TUnit.dll",
+ "lib/netstandard2.0/TUnit.dll",
+ "logo.png",
+ "tunit.0.6.123.nupkg.sha512",
+ "tunit.nuspec"
+ ]
+ },
+ "TUnit.Assertions/0.6.123": {
+ "sha512": "mnoA8aNCYDoYRPOHZTleO591D/h3AUKadSs5jKq+eTliJipOTrxvBv33R/DtC649g8k8ANYASp9u5FC0adVEMA==",
+ "type": "package",
+ "path": "tunit.assertions/0.6.123",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "README.md",
+ "analyzers/dotnet/cs/TUnit.Assertions.Analyzers.CodeFixers.dll",
+ "analyzers/dotnet/cs/TUnit.Assertions.Analyzers.dll",
+ "build/netstandard2.0/TUnit.Assertions.props",
+ "build/netstandard2.0/TUnit.Assertions.targets",
+ "buildTransitive/net8.0/TUnit.Assertions.props",
+ "buildTransitive/net8.0/TUnit.Assertions.targets",
+ "buildTransitive/net9.0/TUnit.Assertions.props",
+ "buildTransitive/net9.0/TUnit.Assertions.targets",
+ "buildTransitive/netstandard2.0/TUnit.Assertions.props",
+ "buildTransitive/netstandard2.0/TUnit.Assertions.targets",
+ "lib/net8.0/TUnit.Assertions.dll",
+ "lib/net9.0/TUnit.Assertions.dll",
+ "lib/netstandard2.0/TUnit.Assertions.dll",
+ "logo.png",
+ "tunit.assertions.0.6.123.nupkg.sha512",
+ "tunit.assertions.nuspec"
+ ]
+ },
+ "TUnit.Core/0.6.123": {
+ "sha512": "DWrDQalsHscGNGfufUzY99pSJcro40u48QJIiwFufs0aqSvxlWTIREItLkqWZC6kPt8IxyYCdJwSl+AK9u6vhQ==",
+ "type": "package",
+ "path": "tunit.core/0.6.123",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "README.md",
+ "analyzers/dotnet/roslyn4.4/cs/TUnit.Analyzers.dll",
+ "analyzers/dotnet/roslyn4.4/cs/TUnit.Core.SourceGenerator.dll",
+ "analyzers/dotnet/roslyn4.7/cs/TUnit.Analyzers.dll",
+ "analyzers/dotnet/roslyn4.7/cs/TUnit.Core.SourceGenerator.dll",
+ "build/netstandard2.0/TUnit.Core.props",
+ "build/netstandard2.0/TUnit.Core.targets",
+ "buildTransitive/net8.0/TUnit.Core.props",
+ "buildTransitive/net8.0/TUnit.Core.targets",
+ "buildTransitive/net9.0/TUnit.Core.props",
+ "buildTransitive/net9.0/TUnit.Core.targets",
+ "buildTransitive/netstandard2.0/TUnit.Core.props",
+ "buildTransitive/netstandard2.0/TUnit.Core.targets",
+ "lib/net8.0/TUnit.Core.dll",
+ "lib/net9.0/TUnit.Core.dll",
+ "lib/netstandard2.0/TUnit.Core.dll",
+ "logo.png",
+ "tunit.core.0.6.123.nupkg.sha512",
+ "tunit.core.nuspec"
+ ]
+ },
+ "TUnit.Engine/0.6.123": {
+ "sha512": "p2J1t5/9ORvU2ap4Wde5L7on/Zb2wFTcm5lIFm7axb0iR+P8LZd28O8NRqTLJ97PgMYQ2aIas8da3vvEY1JDsw==",
+ "type": "package",
+ "path": "tunit.engine/0.6.123",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "README.md",
+ "build/netstandard2.0/TUnit.Engine.props",
+ "buildTransitive/net8.0/TUnit.Engine.props",
+ "buildTransitive/net9.0/TUnit.Engine.props",
+ "buildTransitive/netstandard2.0/TUnit.Engine.props",
+ "lib/net8.0/TUnit.Engine.dll",
+ "lib/net9.0/TUnit.Engine.dll",
+ "lib/netstandard2.0/TUnit.Engine.dll",
+ "logo.png",
+ "tunit.engine.0.6.123.nupkg.sha512",
+ "tunit.engine.nuspec"
+ ]
+ },
+ "Websocket.Client/5.1.1": {
+ "sha512": "VpQV6b8HRnw6bFFIPTOOMtOxba3/viH9K2U2LdOYNjQ2b2HrLHxjodmJr3nPwyNSrtrRPr1RDwOMJ5qqlPnCVg==",
+ "type": "package",
+ "path": "websocket.client/5.1.1",
+ "files": [
+ ".nupkg.metadata",
+ ".signature.p7s",
+ "README.md",
+ "icon-modern.png",
+ "icon.png",
+ "lib/net6.0/Websocket.Client.dll",
+ "lib/net6.0/Websocket.Client.xml",
+ "lib/net7.0/Websocket.Client.dll",
+ "lib/net7.0/Websocket.Client.xml",
+ "lib/net8.0/Websocket.Client.dll",
+ "lib/net8.0/Websocket.Client.xml",
+ "lib/netstandard2.1/Websocket.Client.dll",
+ "lib/netstandard2.1/Websocket.Client.xml",
+ "websocket.client.5.1.1.nupkg.sha512",
+ "websocket.client.nuspec"
+ ]
+ }
+ },
+ "projectFileDependencyGroups": {
+ "net9.0": [
+ "Microsoft.Testing.Extensions.CodeCoverage >= 17.13.1",
+ "Supabase >= 1.1.1",
+ "TUnit >= 0.6.123"
+ ]
+ },
+ "packageFolders": {
+ "/Users/baez/.nuget/packages/": {}
+ },
+ "project": {
+ "version": "1.0.0",
+ "restore": {
+ "projectUniqueName": "/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/supabase-integration.api-test.csproj",
+ "projectName": "supabase-integration.api-test",
+ "projectPath": "/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/supabase-integration.api-test.csproj",
+ "packagesPath": "/Users/baez/.nuget/packages/",
+ "outputPath": "/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/obj/",
+ "projectStyle": "PackageReference",
+ "configFilePaths": [
+ "/Users/baez/.nuget/NuGet/NuGet.Config"
+ ],
+ "originalTargetFrameworks": [
+ "net9.0"
+ ],
+ "sources": {
+ "https://api.nuget.org/v3/index.json": {}
+ },
+ "frameworks": {
+ "net9.0": {
+ "targetAlias": "net9.0",
+ "projectReferences": {}
+ }
+ },
+ "warningProperties": {
+ "warnAsError": [
+ "NU1605"
+ ]
+ },
+ "restoreAuditProperties": {
+ "enableAudit": "true",
+ "auditLevel": "low",
+ "auditMode": "direct"
+ },
+ "SdkAnalysisLevel": "9.0.100"
+ },
+ "frameworks": {
+ "net9.0": {
+ "targetAlias": "net9.0",
+ "dependencies": {
+ "Microsoft.Testing.Extensions.CodeCoverage": {
+ "target": "Package",
+ "version": "[17.13.1, )"
+ },
+ "Supabase": {
+ "target": "Package",
+ "version": "[1.1.1, )"
+ },
+ "TUnit": {
+ "target": "Package",
+ "version": "[0.6.123, )"
+ }
+ },
+ "imports": [
+ "net461",
+ "net462",
+ "net47",
+ "net471",
+ "net472",
+ "net48",
+ "net481"
+ ],
+ "assetTargetFallback": true,
+ "warn": true,
+ "frameworkReferences": {
+ "Microsoft.NETCore.App": {
+ "privateAssets": "all"
+ }
+ },
+ "runtimeIdentifierGraphPath": "/usr/local/share/dotnet/sdk/9.0.102/PortableRuntimeIdentifierGraph.json"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/project.nuget.cache b/testdata/dotnet-client/test/supabase-integration.api-test/obj/project.nuget.cache
new file mode 100644
index 0000000..6d0faf0
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/obj/project.nuget.cache
@@ -0,0 +1,47 @@
+{
+ "version": 2,
+ "dgSpecHash": "R14E93Erk28=",
+ "success": true,
+ "projectFilePath": "/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/supabase-integration.api-test.csproj",
+ "expectedPackageFiles": [
+ "/Users/baez/.nuget/packages/enumerableasyncprocessor/2.0.6/enumerableasyncprocessor.2.0.6.nupkg.sha512",
+ "/Users/baez/.nuget/packages/microsoft.diasymreader/2.0.0/microsoft.diasymreader.2.0.0.nupkg.sha512",
+ "/Users/baez/.nuget/packages/microsoft.extensions.dependencyinjection.abstractions/8.0.0/microsoft.extensions.dependencyinjection.abstractions.8.0.0.nupkg.sha512",
+ "/Users/baez/.nuget/packages/microsoft.extensions.dependencymodel/6.0.1/microsoft.extensions.dependencymodel.6.0.1.nupkg.sha512",
+ "/Users/baez/.nuget/packages/microsoft.extensions.logging.abstractions/8.0.0/microsoft.extensions.logging.abstractions.8.0.0.nupkg.sha512",
+ "/Users/baez/.nuget/packages/microsoft.identitymodel.abstractions/7.5.1/microsoft.identitymodel.abstractions.7.5.1.nupkg.sha512",
+ "/Users/baez/.nuget/packages/microsoft.identitymodel.jsonwebtokens/7.5.1/microsoft.identitymodel.jsonwebtokens.7.5.1.nupkg.sha512",
+ "/Users/baez/.nuget/packages/microsoft.identitymodel.logging/7.5.1/microsoft.identitymodel.logging.7.5.1.nupkg.sha512",
+ "/Users/baez/.nuget/packages/microsoft.identitymodel.tokens/7.5.1/microsoft.identitymodel.tokens.7.5.1.nupkg.sha512",
+ "/Users/baez/.nuget/packages/microsoft.io.recyclablememorystream/3.0.0/microsoft.io.recyclablememorystream.3.0.0.nupkg.sha512",
+ "/Users/baez/.nuget/packages/microsoft.testing.extensions.codecoverage/17.13.1/microsoft.testing.extensions.codecoverage.17.13.1.nupkg.sha512",
+ "/Users/baez/.nuget/packages/microsoft.testing.extensions.trxreport.abstractions/1.4.3/microsoft.testing.extensions.trxreport.abstractions.1.4.3.nupkg.sha512",
+ "/Users/baez/.nuget/packages/microsoft.testing.platform/1.4.3/microsoft.testing.platform.1.4.3.nupkg.sha512",
+ "/Users/baez/.nuget/packages/microsoft.testing.platform.msbuild/1.4.3/microsoft.testing.platform.msbuild.1.4.3.nupkg.sha512",
+ "/Users/baez/.nuget/packages/mimemapping/3.0.1/mimemapping.3.0.1.nupkg.sha512",
+ "/Users/baez/.nuget/packages/newtonsoft.json/13.0.3/newtonsoft.json.13.0.3.nupkg.sha512",
+ "/Users/baez/.nuget/packages/supabase/1.1.1/supabase.1.1.1.nupkg.sha512",
+ "/Users/baez/.nuget/packages/supabase.core/1.0.0/supabase.core.1.0.0.nupkg.sha512",
+ "/Users/baez/.nuget/packages/supabase.functions/2.0.0/supabase.functions.2.0.0.nupkg.sha512",
+ "/Users/baez/.nuget/packages/supabase.gotrue/6.0.3/supabase.gotrue.6.0.3.nupkg.sha512",
+ "/Users/baez/.nuget/packages/supabase.postgrest/4.0.3/supabase.postgrest.4.0.3.nupkg.sha512",
+ "/Users/baez/.nuget/packages/supabase.realtime/7.0.2/supabase.realtime.7.0.2.nupkg.sha512",
+ "/Users/baez/.nuget/packages/supabase.storage/2.0.2/supabase.storage.2.0.2.nupkg.sha512",
+ "/Users/baez/.nuget/packages/system.buffers/4.5.1/system.buffers.4.5.1.nupkg.sha512",
+ "/Users/baez/.nuget/packages/system.collections.immutable/8.0.0/system.collections.immutable.8.0.0.nupkg.sha512",
+ "/Users/baez/.nuget/packages/system.identitymodel.tokens.jwt/7.5.1/system.identitymodel.tokens.jwt.7.5.1.nupkg.sha512",
+ "/Users/baez/.nuget/packages/system.memory/4.5.4/system.memory.4.5.4.nupkg.sha512",
+ "/Users/baez/.nuget/packages/system.reactive/6.0.0/system.reactive.6.0.0.nupkg.sha512",
+ "/Users/baez/.nuget/packages/system.reflection.metadata/8.0.0/system.reflection.metadata.8.0.0.nupkg.sha512",
+ "/Users/baez/.nuget/packages/system.runtime.compilerservices.unsafe/6.0.0/system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512",
+ "/Users/baez/.nuget/packages/system.text.encodings.web/6.0.0/system.text.encodings.web.6.0.0.nupkg.sha512",
+ "/Users/baez/.nuget/packages/system.text.json/6.0.10/system.text.json.6.0.10.nupkg.sha512",
+ "/Users/baez/.nuget/packages/system.threading.channels/8.0.0/system.threading.channels.8.0.0.nupkg.sha512",
+ "/Users/baez/.nuget/packages/tunit/0.6.123/tunit.0.6.123.nupkg.sha512",
+ "/Users/baez/.nuget/packages/tunit.assertions/0.6.123/tunit.assertions.0.6.123.nupkg.sha512",
+ "/Users/baez/.nuget/packages/tunit.core/0.6.123/tunit.core.0.6.123.nupkg.sha512",
+ "/Users/baez/.nuget/packages/tunit.engine/0.6.123/tunit.engine.0.6.123.nupkg.sha512",
+ "/Users/baez/.nuget/packages/websocket.client/5.1.1/websocket.client.5.1.1.nupkg.sha512"
+ ],
+ "logs": []
+}
\ No newline at end of file
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/project.packagespec.json b/testdata/dotnet-client/test/supabase-integration.api-test/obj/project.packagespec.json
new file mode 100644
index 0000000..f88e0b9
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/obj/project.packagespec.json
@@ -0,0 +1 @@
+"restore":{"projectUniqueName":"/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/supabase-integration.api-test.csproj","projectName":"supabase-integration.api-test","projectPath":"/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/supabase-integration.api-test.csproj","outputPath":"/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/obj/","projectStyle":"PackageReference","originalTargetFrameworks":["net9.0"],"sources":{"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net9.0":{"targetAlias":"net9.0","projectReferences":{}}},"warningProperties":{"warnAsError":["NU1605"]},"restoreAuditProperties":{"enableAudit":"true","auditLevel":"low","auditMode":"direct"},"SdkAnalysisLevel":"9.0.100"}"frameworks":{"net9.0":{"targetAlias":"net9.0","dependencies":{"Microsoft.Testing.Extensions.CodeCoverage":{"target":"Package","version":"[17.13.1, )"},"Supabase":{"target":"Package","version":"[1.1.1, )"},"TUnit":{"target":"Package","version":"[0.6.123, )"}},"imports":["net461","net462","net47","net471","net472","net48","net481"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"/usr/local/share/dotnet/sdk/9.0.102/PortableRuntimeIdentifierGraph.json"}}
\ No newline at end of file
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/rider.project.model.nuget.info b/testdata/dotnet-client/test/supabase-integration.api-test/obj/rider.project.model.nuget.info
new file mode 100644
index 0000000..6f87a25
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/obj/rider.project.model.nuget.info
@@ -0,0 +1 @@
+17372014475364470
\ No newline at end of file
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/rider.project.restore.info b/testdata/dotnet-client/test/supabase-integration.api-test/obj/rider.project.restore.info
new file mode 100644
index 0000000..6f87a25
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/obj/rider.project.restore.info
@@ -0,0 +1 @@
+17372014475364470
\ No newline at end of file
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/supabase-integration.api-test.csproj.nuget.dgspec.json b/testdata/dotnet-client/test/supabase-integration.api-test/obj/supabase-integration.api-test.csproj.nuget.dgspec.json
new file mode 100644
index 0000000..0eed750
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/obj/supabase-integration.api-test.csproj.nuget.dgspec.json
@@ -0,0 +1,81 @@
+{
+ "format": 1,
+ "restore": {
+ "/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/supabase-integration.api-test.csproj": {}
+ },
+ "projects": {
+ "/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/supabase-integration.api-test.csproj": {
+ "version": "1.0.0",
+ "restore": {
+ "projectUniqueName": "/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/supabase-integration.api-test.csproj",
+ "projectName": "supabase-integration.api-test",
+ "projectPath": "/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/supabase-integration.api-test.csproj",
+ "packagesPath": "/Users/baez/.nuget/packages/",
+ "outputPath": "/Users/baez/sources/code.icb4dc0.de/prskr/supabase-operator/testdata/dotnet-client/test/supabase-integration.api-test/obj/",
+ "projectStyle": "PackageReference",
+ "configFilePaths": [
+ "/Users/baez/.nuget/NuGet/NuGet.Config"
+ ],
+ "originalTargetFrameworks": [
+ "net9.0"
+ ],
+ "sources": {
+ "https://api.nuget.org/v3/index.json": {}
+ },
+ "frameworks": {
+ "net9.0": {
+ "targetAlias": "net9.0",
+ "projectReferences": {}
+ }
+ },
+ "warningProperties": {
+ "warnAsError": [
+ "NU1605"
+ ]
+ },
+ "restoreAuditProperties": {
+ "enableAudit": "true",
+ "auditLevel": "low",
+ "auditMode": "direct"
+ },
+ "SdkAnalysisLevel": "9.0.100"
+ },
+ "frameworks": {
+ "net9.0": {
+ "targetAlias": "net9.0",
+ "dependencies": {
+ "Microsoft.Testing.Extensions.CodeCoverage": {
+ "target": "Package",
+ "version": "[17.13.1, )"
+ },
+ "Supabase": {
+ "target": "Package",
+ "version": "[1.1.1, )"
+ },
+ "TUnit": {
+ "target": "Package",
+ "version": "[0.6.123, )"
+ }
+ },
+ "imports": [
+ "net461",
+ "net462",
+ "net47",
+ "net471",
+ "net472",
+ "net48",
+ "net481"
+ ],
+ "assetTargetFallback": true,
+ "warn": true,
+ "frameworkReferences": {
+ "Microsoft.NETCore.App": {
+ "privateAssets": "all"
+ }
+ },
+ "runtimeIdentifierGraphPath": "/usr/local/share/dotnet/sdk/9.0.102/PortableRuntimeIdentifierGraph.json"
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/supabase-integration.api-test.csproj.nuget.g.props b/testdata/dotnet-client/test/supabase-integration.api-test/obj/supabase-integration.api-test.csproj.nuget.g.props
new file mode 100644
index 0000000..768511d
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/obj/supabase-integration.api-test.csproj.nuget.g.props
@@ -0,0 +1,23 @@
+
+
+
+ True
+ NuGet
+ $(MSBuildThisFileDirectory)project.assets.json
+ /Users/baez/.nuget/packages/
+ /Users/baez/.nuget/packages/
+ PackageReference
+ 6.12.2
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/obj/supabase-integration.api-test.csproj.nuget.g.targets b/testdata/dotnet-client/test/supabase-integration.api-test/obj/supabase-integration.api-test.csproj.nuget.g.targets
new file mode 100644
index 0000000..be31931
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/obj/supabase-integration.api-test.csproj.nuget.g.targets
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/testdata/dotnet-client/test/supabase-integration.api-test/supabase-integration.api-test.csproj b/testdata/dotnet-client/test/supabase-integration.api-test/supabase-integration.api-test.csproj
new file mode 100644
index 0000000..147a306
--- /dev/null
+++ b/testdata/dotnet-client/test/supabase-integration.api-test/supabase-integration.api-test.csproj
@@ -0,0 +1,22 @@
+
+
+
+ net9.0
+ Exe
+ supabase_integration.api_test
+ enable
+ enable
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+