diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 251a22e..e682cff 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -73,7 +73,8 @@ jobs: src/AndreGoepel.AppFoundation.ServiceDefaults/AndreGoepel.AppFoundation.ServiceDefaults.csproj \ src/AndreGoepel.AppFoundation.MailService/AndreGoepel.AppFoundation.MailService.csproj \ src/AndreGoepel.AppFoundation/AndreGoepel.AppFoundation.csproj \ - src/AndreGoepel.AppFoundation.Hosting/AndreGoepel.AppFoundation.Hosting.csproj; do + src/AndreGoepel.AppFoundation.Hosting/AndreGoepel.AppFoundation.Hosting.csproj \ + src/AndreGoepel.AppFoundation.Aspire/AndreGoepel.AppFoundation.Aspire.csproj; do dotnet pack "$proj" -c Release -p:Version=$VERSION -p:RestoreLockedMode=true -o nupkgs done diff --git a/AndreGoepel.AppFoundation.slnx b/AndreGoepel.AppFoundation.slnx index b87aa70..a0dff1a 100644 --- a/AndreGoepel.AppFoundation.slnx +++ b/AndreGoepel.AppFoundation.slnx @@ -6,6 +6,7 @@ + @@ -13,6 +14,7 @@ + diff --git a/Directory.Packages.props b/Directory.Packages.props index 4ddc497..7fd1f8d 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -13,6 +13,7 @@ + diff --git a/samples/AndreGoepel.AppFoundation.AppHost/AndreGoepel.AppFoundation.AppHost.csproj b/samples/AndreGoepel.AppFoundation.AppHost/AndreGoepel.AppFoundation.AppHost.csproj index 55bef25..2d35192 100644 --- a/samples/AndreGoepel.AppFoundation.AppHost/AndreGoepel.AppFoundation.AppHost.csproj +++ b/samples/AndreGoepel.AppFoundation.AppHost/AndreGoepel.AppFoundation.AppHost.csproj @@ -24,5 +24,11 @@ + + diff --git a/samples/AndreGoepel.AppFoundation.AppHost/AppHost.cs b/samples/AndreGoepel.AppFoundation.AppHost/AppHost.cs index 11d2c51..e787720 100644 --- a/samples/AndreGoepel.AppFoundation.AppHost/AppHost.cs +++ b/samples/AndreGoepel.AppFoundation.AppHost/AppHost.cs @@ -1,26 +1,22 @@ -using Microsoft.Extensions.Configuration; +using AndreGoepel.AppFoundation.Aspire; var builder = DistributedApplication.CreateBuilder(args); -// A PostgreSQL container with a persistent volume so setup and accounts survive restarts. -// The E2E suite passes E2E=true to skip the volume: tests need a throwaway database, and +// The E2E suite passes E2E=true to skip the data volume: tests need a throwaway database, and // sharing the developer's volume would leak their local admin account into the test run. -var postgres = builder.AddPostgres("postgres"); -if (!builder.Configuration.GetValue("E2E")) -{ - postgres.WithDataVolume(); -} +var isE2E = string.Equals(builder.Configuration["E2E"], "true", StringComparison.OrdinalIgnoreCase); // The database resource name is the connection-string name the foundation reads by default // (AppFoundationOptions.DatabaseConnectionName == "appfoundation-database"). -var database = postgres.AddDatabase("appfoundation-database", "appfoundation"); +var (_, database) = builder.AddStandardPostgres( + isE2E, + databaseResourceName: "appfoundation-database", + databaseName: "appfoundation" +); // MailHog captures outgoing development email locally: an SMTP server on 1025 and a web UI on // 8025 to read what was "sent". Nothing leaves the machine, and no real mail account is needed. -var mailhog = builder - .AddContainer("mailhog", "mailhog/mailhog", "v1.0.1") - .WithEndpoint(name: "smtp", port: 1025, targetPort: 1025) - .WithHttpEndpoint(name: "http", port: 8025, targetPort: 8025); +var mailhog = builder.AddStandardMailHog(); // The sample web app, wired to the database and started only once it is ready. Email settings // are database-only (no configuration fallback) — the E2E fixture configures MailHog through the diff --git a/src/AndreGoepel.AppFoundation.Aspire/AndreGoepel.AppFoundation.Aspire.csproj b/src/AndreGoepel.AppFoundation.Aspire/AndreGoepel.AppFoundation.Aspire.csproj new file mode 100644 index 0000000..f0c9f47 --- /dev/null +++ b/src/AndreGoepel.AppFoundation.Aspire/AndreGoepel.AppFoundation.Aspire.csproj @@ -0,0 +1,25 @@ + + + net10.0 + enable + enable + + + + AndreGoepel.AppFoundation.Aspire + 1.8.0 + Standardized .NET Aspire AppHost building blocks (MailHog, Postgres) for AndreGoepel.AppFoundation hosts. + appfoundation;aspire;apphost;mailhog;postgresql + README.md + true + + + + + + + + + + + diff --git a/src/AndreGoepel.AppFoundation.Aspire/AppFoundationAspireExtensions.cs b/src/AndreGoepel.AppFoundation.Aspire/AppFoundationAspireExtensions.cs new file mode 100644 index 0000000..f30bb80 --- /dev/null +++ b/src/AndreGoepel.AppFoundation.Aspire/AppFoundationAspireExtensions.cs @@ -0,0 +1,126 @@ +using Aspire.Hosting; +using Aspire.Hosting.ApplicationModel; + +namespace AndreGoepel.AppFoundation.Aspire; + +/// +/// Standardized AppHost building blocks for the AndreGoepel ecosystem, extracted from the +/// near-identical MailHog + Postgres + EmailSender__* blocks that andregoepel-dev, +/// finance-app, customer-portal, and this repo's own sample AppHost each hand-rolled. +/// AppHost projects are dev-only orchestration — never part of the runtime dependency chain — so a +/// sibling package referenced only by *.AppHost projects stays architecturally consistent +/// with the rest of the ecosystem's AppHosts already referencing +/// AndreGoepel.AppFoundation.ServiceDefaults from this same repo. +/// +public static class AppFoundationAspireExtensions +{ + /// + /// Adds a MailHog container that captures outgoing development email locally: an SMTP + /// endpoint and an HTTP endpoint for its web UI / API. + /// + /// The AppHost's distributed application builder. + /// Resource name of the container. + /// + /// Image tag. Defaults to the pinned v1.0.1 for reproducible dev environments; pass + /// null to use the image's default (untagged/latest) instead. + /// + /// Host port MailHog's SMTP endpoint is exposed on. + /// Host port MailHog's HTTP (web UI / API) endpoint is exposed on. + /// + /// The container resource, so callers can still reference its endpoints (e.g. + /// mailhog.GetEndpoint("smtp")) to wire up their own app's EmailSender__* + /// environment variables — those stay app-specific (sender name, credentials) and are not + /// standardized here. + /// + /// + /// The HTTP endpoint is always named "http" — the canonical name across the ecosystem + /// (matching AndreGoepel.Testing.E2E's E2EAppFixtureOptions.MailHogEndpointName + /// default), not the "web" name andregoepel-dev/finance-app used historically. + /// + public static IResourceBuilder AddStandardMailHog( + this IDistributedApplicationBuilder builder, + string name = "mailhog", + string? tag = "v1.0.1", + int smtpPort = 1025, + int httpPort = 8025 + ) + { + var container = tag is null + ? builder.AddContainer(name, "mailhog/mailhog") + : builder.AddContainer(name, "mailhog/mailhog", tag); + + return container + .WithEndpoint(name: "smtp", port: smtpPort, targetPort: 1025) + .WithHttpEndpoint(name: "http", port: httpPort, targetPort: 8025); + } + + /// + /// Adds a Postgres server and database, applying the ecosystem's E2E convention: outside E2E + /// the server keeps its data across restarts on a fixed host port; under E2E every one of + /// those is dropped so each run gets a fresh, throwaway, volume-less database on a dynamic + /// port instead of a developer's persistent local data. + /// + /// The AppHost's distributed application builder. + /// + /// Whether the AppHost is running under the E2E test harness (typically + /// string.Equals(builder.Configuration["E2E"], "true", StringComparison.OrdinalIgnoreCase)). + /// true skips WithDataVolume, the persistent container lifetime, and the fixed + /// host port. + /// + /// Resource name of the Postgres server. + /// + /// Resource name of the logical database — the connection-string name a host reads (e.g. + /// AppFoundationOptions.DatabaseConnectionName, which defaults to + /// "appfoundation-database"). + /// + /// + /// Actual database name created on the server. Defaults to + /// when null. + /// + /// Optional explicit database user parameter; auto-generated when omitted. + /// Optional explicit database password parameter; auto-generated when omitted. + /// + /// Fixed host port used outside E2E. Pass null to leave the port dynamic even outside + /// E2E. Has no effect when is true. + /// + /// + /// Optional explicit data volume name, forwarded to WithDataVolume. Auto-generated when + /// null. Has no effect when is true. + /// + /// Both the server and database resources — the common case only needs Database. + public static StandardPostgres AddStandardPostgres( + this IDistributedApplicationBuilder builder, + bool isE2E, + string serverName = "postgres-server", + string databaseResourceName = "appfoundation-database", + string? databaseName = null, + IResourceBuilder? userName = null, + IResourceBuilder? password = null, + int? hostPort = 5432, + string? dataVolumeName = null + ) + { + var server = + userName is not null && password is not null + ? builder.AddPostgres(serverName, userName, password) + : builder.AddPostgres(serverName); + + if (!isE2E) + { + server = server.WithLifetime(ContainerLifetime.Persistent); + + if (hostPort is { } port) + { + server = server.WithHostPort(port); + } + + server = server.WithDataVolume(dataVolumeName); + } + + var database = databaseName is null + ? server.AddDatabase(databaseResourceName) + : server.AddDatabase(databaseResourceName, databaseName); + + return new StandardPostgres(server, database); + } +} diff --git a/src/AndreGoepel.AppFoundation.Aspire/StandardPostgres.cs b/src/AndreGoepel.AppFoundation.Aspire/StandardPostgres.cs new file mode 100644 index 0000000..9d9584b --- /dev/null +++ b/src/AndreGoepel.AppFoundation.Aspire/StandardPostgres.cs @@ -0,0 +1,17 @@ +using Aspire.Hosting.ApplicationModel; + +namespace AndreGoepel.AppFoundation.Aspire; + +/// +/// The two resources creates. +/// Deconstructs positionally, so the common case that only needs the database stays a +/// one-liner: var (_, appDb) = builder.AddStandardPostgres(isE2E); +/// +/// The Postgres server container resource. +/// +/// The logical database resource — what a host app passes to WithReference. +/// +public sealed record StandardPostgres( + IResourceBuilder Server, + IResourceBuilder Database +); diff --git a/src/AndreGoepel.AppFoundation.Aspire/packages.lock.json b/src/AndreGoepel.AppFoundation.Aspire/packages.lock.json new file mode 100644 index 0000000..66a9e5e --- /dev/null +++ b/src/AndreGoepel.AppFoundation.Aspire/packages.lock.json @@ -0,0 +1,702 @@ +{ + "version": 2, + "dependencies": { + "net10.0": { + "Aspire.Hosting": { + "type": "Direct", + "requested": "[13.4.6, )", + "resolved": "13.4.6", + "contentHash": "YJEvsrgcVLPQ88aJ3aFMIEJue0ZFmyH8RfyQu0PnHdZzjBAiK0c8BaYUAycWu35QpTe4hHxEYaY0wW4gpy/kwg==", + "dependencies": { + "AspNetCore.HealthChecks.Uris": "9.0.0", + "Google.Protobuf": "3.34.1", + "Grpc.AspNetCore": "2.80.0", + "Grpc.Net.ClientFactory": "2.80.0", + "Humanizer.Core": "3.0.10", + "JsonPatch.Net": "3.3.0", + "KubernetesClient": "19.0.2", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.Configuration.Binder": "10.0.8", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Diagnostics.HealthChecks": "8.0.27", + "Microsoft.Extensions.FileSystemGlobbing": "10.0.8", + "Microsoft.Extensions.Hosting": "10.0.8", + "Microsoft.Extensions.Hosting.Abstractions": "10.0.8", + "Microsoft.Extensions.Http": "10.0.8", + "Microsoft.Extensions.Logging": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8", + "Microsoft.Extensions.Primitives": "10.0.8", + "ModelContextProtocol": "1.3.0", + "Newtonsoft.Json": "13.0.4", + "OpenTelemetry.Exporter.OpenTelemetryProtocol": "1.15.3", + "OpenTelemetry.Extensions.Hosting": "1.15.3", + "Polly.Core": "8.6.6", + "Semver": "3.0.0", + "StreamJsonRpc": "2.25.29", + "System.IO.Hashing": "10.0.8" + } + }, + "Aspire.Hosting.PostgreSQL": { + "type": "Direct", + "requested": "[13.4.6, )", + "resolved": "13.4.6", + "contentHash": "NyL7O7e7DcpZSF0sAz332GIJ3S7X/66NoqhPqzVMPbNYfF97bTrk7C7Yq1tuilffHfq2SV2xi6aHbhGOmSoGqw==", + "dependencies": { + "AspNetCore.HealthChecks.NpgSql": "9.0.0", + "AspNetCore.HealthChecks.Uris": "9.0.0", + "Aspire.Hosting": "13.4.6", + "Google.Protobuf": "3.34.1", + "Grpc.AspNetCore": "2.80.0", + "Grpc.Net.ClientFactory": "2.80.0", + "Grpc.Tools": "2.80.0", + "Humanizer.Core": "3.0.10", + "JsonPatch.Net": "3.3.0", + "KubernetesClient": "19.0.2", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.Configuration.Binder": "10.0.8", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Diagnostics.HealthChecks": "8.0.27", + "Microsoft.Extensions.FileSystemGlobbing": "10.0.8", + "Microsoft.Extensions.Hosting": "10.0.8", + "Microsoft.Extensions.Hosting.Abstractions": "10.0.8", + "Microsoft.Extensions.Http": "10.0.8", + "Microsoft.Extensions.Logging": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8", + "Microsoft.Extensions.Primitives": "10.0.8", + "ModelContextProtocol": "1.3.0", + "Newtonsoft.Json": "13.0.4", + "OpenTelemetry.Exporter.OpenTelemetryProtocol": "1.15.3", + "OpenTelemetry.Extensions.Hosting": "1.15.3", + "Polly.Core": "8.6.6", + "Semver": "3.0.0", + "StreamJsonRpc": "2.25.29", + "System.IO.Hashing": "10.0.8" + } + }, + "AspNetCore.HealthChecks.NpgSql": { + "type": "Transitive", + "resolved": "9.0.0", + "contentHash": "npc58/AD5zuVxERdhCl2Kb7WnL37mwX42SJcXIwvmEig0/dugOLg3SIwtfvvh3TnvTwR/sk5LYNkkPaBdks61A==", + "dependencies": { + "Microsoft.Extensions.Diagnostics.HealthChecks": "8.0.11", + "Npgsql": "8.0.3" + } + }, + "AspNetCore.HealthChecks.Uris": { + "type": "Transitive", + "resolved": "9.0.0", + "contentHash": "XYdNlA437KeF8p9qOpZFyNqAN+c0FXt/JjTvzH/Qans0q0O3pPE8KPnn39ucQQjR/Roum1vLTP3kXiUs8VHyuA==", + "dependencies": { + "Microsoft.Extensions.Diagnostics.HealthChecks": "8.0.11", + "Microsoft.Extensions.Http": "8.0.0" + } + }, + "Fractions": { + "type": "Transitive", + "resolved": "7.3.0", + "contentHash": "2bETFWLBc8b7Ut2SVi+bxhGVwiSpknHYGBh2PADyGWONLkTxT7bKyDRhF8ao+XUv90tq8Fl7GTPxSI5bacIRJw==" + }, + "Google.Protobuf": { + "type": "Transitive", + "resolved": "3.34.1", + "contentHash": "212vdYxRuVopGE5bess6Jg5oXWyizA6hcLPTI7G+qA4PthQEvfeof3njT+7VSY5v/+O0P22xTydiP5fSJJpGEA==" + }, + "Grpc.AspNetCore": { + "type": "Transitive", + "resolved": "2.80.0", + "contentHash": "ASbJbdtCUlGiKxe9NsN/QeG1PdibYoN0pEgP9U87cvS6HV0XsT+VdO/g2M6Ri8zZURfX5c7MBTaFVP/YCrC72A==", + "dependencies": { + "Google.Protobuf": "3.31.1", + "Grpc.AspNetCore.Server.ClientFactory": "2.80.0", + "Grpc.Tools": "2.80.0" + } + }, + "Grpc.AspNetCore.Server": { + "type": "Transitive", + "resolved": "2.80.0", + "contentHash": "lbK7z1sZP5imPdQ035f/CZ61iIaBWouY6A580E9JNo7vzXYX/Qo+GQtSjOzhP9VFbxk7mtLoMhn/v1fT2U7kTw==", + "dependencies": { + "Grpc.Net.Common": "2.80.0" + } + }, + "Grpc.AspNetCore.Server.ClientFactory": { + "type": "Transitive", + "resolved": "2.80.0", + "contentHash": "7JdfxQZv/pO9qU5Ild2mrkzYA7PmVGDKVmWqKVCZNRSDN/RluRN4S4utYgBSwAcYgUBWQDHNb1Ll7wm3BdHfqw==", + "dependencies": { + "Grpc.AspNetCore.Server": "2.80.0", + "Grpc.Net.ClientFactory": "2.80.0" + } + }, + "Grpc.Core.Api": { + "type": "Transitive", + "resolved": "2.80.0", + "contentHash": "i/8s+MOrYa6n7BmZ5bilcbHk+EMJDQHm2MKLhwGAT+urQqlZ6cpjvSivYvuULjebuX+UKieLYZbLRCmVQxFRkw==" + }, + "Grpc.Net.Client": { + "type": "Transitive", + "resolved": "2.80.0", + "contentHash": "I1Aa24nTRMHqx0pmQfvthFsOpejquDjiJV6092KBqjw6EEr3wA9CMXlrdkoEgHartOiJrpKyZiQRl7n0NVlfBg==", + "dependencies": { + "Grpc.Net.Common": "2.80.0", + "Microsoft.Extensions.Logging.Abstractions": "8.0.0" + } + }, + "Grpc.Net.ClientFactory": { + "type": "Transitive", + "resolved": "2.80.0", + "contentHash": "YtY1DWID2phwiGc8qBG7+wf00Do5jE7BkJgCc6nbu5b50OsD89mSd73oCE8fCnUo7IjtDAEYFOYI3NSzgn28gw==", + "dependencies": { + "Grpc.Net.Client": "2.80.0", + "Microsoft.Extensions.Http": "8.0.0" + } + }, + "Grpc.Net.Common": { + "type": "Transitive", + "resolved": "2.80.0", + "contentHash": "E2ERsx+9IXlry4yjBl8btx0XMIKzymGNSvX5jmBS/uSwYyYDoKIDcIREyLqFLvd8vcJdcoRlycpvn9YRXutFpQ==", + "dependencies": { + "Grpc.Core.Api": "2.80.0" + } + }, + "Grpc.Tools": { + "type": "Transitive", + "resolved": "2.80.0", + "contentHash": "NS1AxwVZnrdbBoMf5L5ruGjBjoLBej9avhqxWNsgfu2GU6FhpxEVJOwLJsdljlDCjvquJiAH2zf/WodIWMvf2w==" + }, + "Humanizer.Core": { + "type": "Transitive", + "resolved": "3.0.10", + "contentHash": "yZIhtw8sYuvsONzQbZxWpR60tMWYHXoo0DL6nyOqSFiU5POjBTSEyWFpTQtJEZuy+oqiYTXKXY/Mjx7KnqIQFw==" + }, + "Json.More.Net": { + "type": "Transitive", + "resolved": "2.1.0", + "contentHash": "qtwsyAsL55y2vB2/sK4Pjg3ZyVzD5KKSpV3lOAMHlnjFfsjQ/86eHJfQT9aV1YysVXzF4+xyHOZbh7Iu3YQ7Lg==" + }, + "JsonPatch.Net": { + "type": "Transitive", + "resolved": "3.3.0", + "contentHash": "GIcMMDtzfzVfIpQgey8w7dhzcw6jG5nD4DDAdQCTmHfblkCvN7mI8K03to8YyUhKMl4PTR6D6nLSvWmyOGFNTg==", + "dependencies": { + "JsonPointer.Net": "5.2.0" + } + }, + "JsonPointer.Net": { + "type": "Transitive", + "resolved": "5.2.0", + "contentHash": "qe1F7Tr/p4mgwLPU9P60MbYkp+xnL2uCPnWXGgzfR/AZCunAZIC0RZ32dLGJJEhSuLEfm0YF/1R3u5C7mEVq+w==", + "dependencies": { + "Humanizer.Core": "2.14.1", + "Json.More.Net": "2.1.0" + } + }, + "KubernetesClient": { + "type": "Transitive", + "resolved": "19.0.2", + "contentHash": "0m8FuzCDBygaXMbsb7qVapNZzTm4ftM7ECp/waTRh/XOUQziRF2rKJCRmsvYbBXgJkQvU+FBbkoa40hexzDC+g==", + "dependencies": { + "Fractions": "7.3.0", + "YamlDotNet": "16.3.0" + } + }, + "MessagePack": { + "type": "Transitive", + "resolved": "2.5.302", + "contentHash": "5DZsKli4dMEpm/glcMAheuO8/IesfaTskbfsuvgnQwWFKS5FN7Z6yNx+5F+UW94E+9N2qt8Zs63/XVzpLsElgA==", + "dependencies": { + "MessagePack.Annotations": "2.5.302", + "Microsoft.NET.StringTools": "17.6.3" + } + }, + "MessagePack.Annotations": { + "type": "Transitive", + "resolved": "2.5.302", + "contentHash": "PTHQHbMJzx1VtUUCpnvPavD7o5X9s2dAJ4uQHAP2kBCwJKICpPTZq0qxzbB4/6iJJiIxem8zlxyfldGAx1SjSQ==" + }, + "Microsoft.Extensions.AI.Abstractions": { + "type": "Transitive", + "resolved": "10.5.2", + "contentHash": "Ei+YWV9Ybnps7pR1dgjlG29gelXEwZkhLVAcWmKe6HvXS6LNBYgSdWiY3Hk9OZXYtK34rv/NtLWBQYQGOBQYPQ==" + }, + "Microsoft.Extensions.Caching.Abstractions": { + "type": "Transitive", + "resolved": "10.0.7", + "contentHash": "pUDgQKEqNUFlerDIFRg7zzoDVRPEWIG7nR40h8Gzg8RXza4Ry0lWZ7u91bmwu3iUDCxw3Dv6TLHVFoAgY0gy7Q==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.7" + } + }, + "Microsoft.Extensions.Configuration": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "ehZcoPbjzWzS4XFvuz7R3V55SmpdkyMqFURLH3yXaN9NtXd9tR6CGB7pd49HYtCkenl+G7ctXSFLhNI08xLfRg==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.Primitives": "10.0.8" + } + }, + "Microsoft.Extensions.Configuration.Abstractions": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "I63esIFbL3h5pSt7gXpXOlmcwDmYBUoYNEglKfDPFUqtYvSV84f2l28hO2lfVXsV0wdlplgAM7IVz16matapSg==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.8" + } + }, + "Microsoft.Extensions.Configuration.Binder": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "R3NN1X+kVu14uoxLEW6sBSQyhogDSbaOQzILnCtuXxBN4hx22AgjWPwZX6v/suERFkEDgU1lk12AglHTrUxhlw==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8" + } + }, + "Microsoft.Extensions.Configuration.CommandLine": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "nQXq1a4MiInYh+0VF9fguxAl06q2ftmOyYQ+5e933s4rk57xjgkbTjUdFUySzjrcrvDeWsSqlZB+TE8+TbM2HA==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8" + } + }, + "Microsoft.Extensions.Configuration.EnvironmentVariables": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "bVGqctAfPGfTxJvNp8pMshtvpsUj6r6JkeiCNVIGVYO5gBxuxdN0Lbr25kEvE/zXdctkEc44g8HssnPgDnFGVA==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8" + } + }, + "Microsoft.Extensions.Configuration.FileExtensions": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "1g9mzuu8gIHkjYb0jLxOTQVl/QDG5nn0b0JzgT/gbgNKr6gXZzxOHRAsdYRc1eDApB7LdHR8uK5vQrNjIQdRrQ==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.8", + "Microsoft.Extensions.FileProviders.Physical": "10.0.8", + "Microsoft.Extensions.Primitives": "10.0.8" + } + }, + "Microsoft.Extensions.Configuration.Json": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "KLtAZ6A38s1pIfCO2ns6aG14NNGMYNZ4PBYfFK4M+R4A+xuSc6oklhqDcpHZxvDpyBWeFtR5C8iQBw2ng8tUHQ==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.Configuration.FileExtensions": "10.0.8", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.8" + } + }, + "Microsoft.Extensions.Configuration.UserSecrets": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "6XTfFOnf27WY8kEeZkTZ4YNn0t+imgvdQ0YaAdR4vgURKATo9bCaVJ1KB71IOJAQtJP7Elb53VHlTNXg2CtSsA==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.Configuration.Json": "10.0.8", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.8", + "Microsoft.Extensions.FileProviders.Physical": "10.0.8" + } + }, + "Microsoft.Extensions.DependencyInjection": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "daf62xHIrq8pnE709hgaZZN9tSam9TGGepWe1+bE6V3GEuVwJiMs6ib+38lfMCyAJAHiX0vapxBhsuMSV7U+cg==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8" + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "21nbDV60SRPWGIivsyl6lqBeEJNG1sginhhfWgRrr3Ais7aQ12To25OAHQxgoiJkjqy1aQ6RxpZBGYuTi7Ge6A==" + }, + "Microsoft.Extensions.Diagnostics": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "uduyw9d3Fi+sbredO5drA1S44AQS2FRNFyn72UmB2vmQIO1qaXprpp1U/2lYhYi8yFdVERfY9sy/pxw/qPOU9w==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.8", + "Microsoft.Extensions.Diagnostics.Abstractions": "10.0.8", + "Microsoft.Extensions.Options.ConfigurationExtensions": "10.0.8" + } + }, + "Microsoft.Extensions.Diagnostics.Abstractions": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "+f4C5g78QCGNyxzUfrTYsB7qYx06Zca0e88s3qFlea9/lQhgPImYdNprlgzl1uHhRU3fVHLfmbijayU2sJEZ6w==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8" + } + }, + "Microsoft.Extensions.Diagnostics.HealthChecks": { + "type": "Transitive", + "resolved": "8.0.27", + "contentHash": "NzhCnD8d9fQz4QzMjCS64Yu+zeqtvJDeSIWBdgp2n3ySj/3DKH6JC5txzvWi5evh3AQ8pYVvBQAoCh/opEruVQ==", + "dependencies": { + "Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions": "8.0.27", + "Microsoft.Extensions.Hosting.Abstractions": "8.0.1", + "Microsoft.Extensions.Logging.Abstractions": "8.0.3", + "Microsoft.Extensions.Options": "8.0.2" + } + }, + "Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions": { + "type": "Transitive", + "resolved": "8.0.27", + "contentHash": "jnnmIxGWNKE40xjGdDuRHXRHAqF5gMsmyY4BB/WMddSZMb4rLLzKENdZ+t2rw0bBW9MDjdPTxUFx7NsuGy7Uvg==" + }, + "Microsoft.Extensions.FileProviders.Abstractions": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "U+oquaPxFdY8lYeEIWO/AD7jDIl9sPW6aVWMQRHU/pZ/SWpLcOrAj2fcLe1HwXl4sYw1ONI56K/eELT3xr4RRQ==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.8" + } + }, + "Microsoft.Extensions.FileProviders.Physical": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "GkPvQe6IdidLu6Q3Lw6+B8NJpW8feW8czZ5mBKt5rXM/x8MvZfEp5WvAsjznzDGd23chIDrW0b2mmt+ScnEgiw==", + "dependencies": { + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.8", + "Microsoft.Extensions.FileSystemGlobbing": "10.0.8", + "Microsoft.Extensions.Primitives": "10.0.8" + } + }, + "Microsoft.Extensions.FileSystemGlobbing": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "IUQet3SY51xIFcFZKtAB6a54/Zdxs7T3SQ84kJtOD6yeXfZgiOMksACWD5qtTmXGQGFH4QYGBOT0KIO8Uy/dJw==" + }, + "Microsoft.Extensions.Hosting": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "VfEyM2BipThcSd0GG/FS2ZPCVCTiosVq2zLKEDsfeMIg78sOVZPEmS7CgWlb+dqTlgXvLSL4OG2q6sM4xRhHNg==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.Configuration.Binder": "10.0.8", + "Microsoft.Extensions.Configuration.CommandLine": "10.0.8", + "Microsoft.Extensions.Configuration.EnvironmentVariables": "10.0.8", + "Microsoft.Extensions.Configuration.FileExtensions": "10.0.8", + "Microsoft.Extensions.Configuration.Json": "10.0.8", + "Microsoft.Extensions.Configuration.UserSecrets": "10.0.8", + "Microsoft.Extensions.DependencyInjection": "10.0.8", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Diagnostics": "10.0.8", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.8", + "Microsoft.Extensions.FileProviders.Physical": "10.0.8", + "Microsoft.Extensions.Hosting.Abstractions": "10.0.8", + "Microsoft.Extensions.Logging": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8", + "Microsoft.Extensions.Logging.Configuration": "10.0.8", + "Microsoft.Extensions.Logging.Console": "10.0.8", + "Microsoft.Extensions.Logging.Debug": "10.0.8", + "Microsoft.Extensions.Logging.EventLog": "10.0.8", + "Microsoft.Extensions.Logging.EventSource": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8" + } + }, + "Microsoft.Extensions.Hosting.Abstractions": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "MoOWFPT88/pDfmWpbU9PydKRX/rJFQkliowE/L9wbQcl94IicUphb5BFgepkWiDkYYxPnuEqjN4buzOGW4vJpQ==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Diagnostics.Abstractions": "10.0.8", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8" + } + }, + "Microsoft.Extensions.Http": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "/9LU/KWJOrtZJB9ymPjcARDyjp679BvBA/aSncv2Kt84WlSKz767HtxHg8EFsu8n21BMLZi+5XxlkKbLwfn4iA==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Diagnostics": "10.0.8", + "Microsoft.Extensions.Logging": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8" + } + }, + "Microsoft.Extensions.Logging": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "K60JhWC2hN/Gi7TP68tBxSzk5ACWOs7lkmPzsfA8Bcf/IXTajujt2ORMf9rSMk1bsng6Lv4Y3fuxp3bm1+15ug==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8" + } + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "fdVadZmsC8jRP0KvKy8mO8f6GV/HyBvElfcSxEhd+5FM5boAw/01iSaCto5G3G37ApJira4A3pNaVvBv8cUiLQ==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8" + } + }, + "Microsoft.Extensions.Logging.Configuration": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "rxSLTO7xTbcC3DuEJHNEijBr8g14Jj62zQ+DeFu68bsoTYoU8jLcMhc1735PV21bESXsATlL5LsfaWH71FOWAg==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.Configuration.Binder": "10.0.8", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Logging": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8", + "Microsoft.Extensions.Options.ConfigurationExtensions": "10.0.8" + } + }, + "Microsoft.Extensions.Logging.Console": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "6cv53sHsPnFS56PJw8X4GbNcjeX1KGyFJRxJWvxOgK63cnqeSB1k1eRwjUdkse0tBhwlH6qc9EOYDlan+CYTuw==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Logging": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8", + "Microsoft.Extensions.Logging.Configuration": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8" + } + }, + "Microsoft.Extensions.Logging.Debug": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "4HW3M1lGHHDwEYcDZHRNptBQ48LCI2yW+XV4vuxdfQUqafTpVT8j9RqAsez08krZKhIiaArWu8iQq5uRKZ9Ffg==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Logging": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8" + } + }, + "Microsoft.Extensions.Logging.EventLog": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "kK/C3SLIoGrcZvddYQw4eMm6YaROiSYBO7YgUR5Hdv5l+GIjBmbvQK5cST2FqjeubiAOPqFEimBT2N/8wVI+3A==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Logging": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8", + "System.Diagnostics.EventLog": "10.0.8" + } + }, + "Microsoft.Extensions.Logging.EventSource": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "HX2M0MgzwQM8jpLe3AYAEMd0YsUfOP5RgGrDuk+Ki9n7HSuMbvLm9TEV3qRI3Pg9aqxc56GfgK/KdMRBhfWwKw==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Logging": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8", + "Microsoft.Extensions.Primitives": "10.0.8" + } + }, + "Microsoft.Extensions.Options": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "VBD+131DpTNCNDfA4kIyKTiCySvJGNhwibdWBSdFRu7GMfXLXcXODkgA+KStKbbhzraLglZWUN4nXyHgW4JIRA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Primitives": "10.0.8" + } + }, + "Microsoft.Extensions.Options.ConfigurationExtensions": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "VOapXeO3lhBH0zYoyAH7tjapuo4V5pTHlevPpiSHueEquAajqd5nF0mttm+h/uE/exwAEuM5s26SzOJtletE3w==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.Configuration.Binder": "10.0.8", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8", + "Microsoft.Extensions.Primitives": "10.0.8" + } + }, + "Microsoft.Extensions.Primitives": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "OBPo4nYhMyIbtueoC10CBm6AGAbo/A9IV8QQ/6ryZS7VvmqpGT7hunazeHLxFawRzn3oLOq4jhqhpBX4tfswWQ==" + }, + "Microsoft.NET.StringTools": { + "type": "Transitive", + "resolved": "18.4.0", + "contentHash": "iQWOKi3L5QStmWqDjDubcr1KlTDy88qBTe88I0etlUUo1l0zSNebGJXl1Xetyl+ACA+ujP3YUtxo3Nz54JPriw==" + }, + "Microsoft.VisualStudio.Threading.Only": { + "type": "Transitive", + "resolved": "17.14.15", + "contentHash": "NqONyw1RXyj9P3k5e1uU2k9kc1ptwuU5NJQzG+MPq7vQVHUzBY8HLuJf/N2Rw5H/myD96CVxziDxmjawPuzntw==", + "dependencies": { + "Microsoft.VisualStudio.Validation": "17.8.8" + } + }, + "Microsoft.VisualStudio.Validation": { + "type": "Transitive", + "resolved": "17.13.22", + "contentHash": "fC20ITOxlUpGQ0ltAxITQbeFxwuB6OjLT3lByC4+/Gm46o/Mwv9hlIVrBhiUhnqdQzUUvr4EHkdiYe7WOSMLmw==" + }, + "ModelContextProtocol": { + "type": "Transitive", + "resolved": "1.3.0", + "contentHash": "WDaD6z9KkkCUHSo15xK7tYBERHy8uqP+cIUp8uIxhR0yrlpJLXTRcJcUUVqpXlBkV7MK9Eo3mTrAnctLnJuHDQ==", + "dependencies": { + "Microsoft.Extensions.Caching.Abstractions": "10.0.7", + "Microsoft.Extensions.Hosting.Abstractions": "10.0.7", + "ModelContextProtocol.Core": "1.3.0" + } + }, + "ModelContextProtocol.Core": { + "type": "Transitive", + "resolved": "1.3.0", + "contentHash": "OWmdxDSwA7K9pNNg4t98MXNIssHG/wOQEr/G8pG5B7synDdw4MnmZ/IIVeb3yUdeznPqnDHvd3FBCK0jRk4IZQ==", + "dependencies": { + "Microsoft.Extensions.AI.Abstractions": "10.5.2", + "Microsoft.Extensions.Logging.Abstractions": "10.0.7" + } + }, + "Nerdbank.MessagePack": { + "type": "Transitive", + "resolved": "1.2.4", + "contentHash": "9NKlDsKkOV5zQFkZZnQmssdV6npFNs0Of1Nz5mvAJA4uANxCge2TfXQ9nCYUet58bEWQ00a/aNHdjmcXEI7iuQ==", + "dependencies": { + "Microsoft.NET.StringTools": "18.4.0", + "Microsoft.VisualStudio.Validation": "17.13.22", + "PolyType": "1.3.1" + } + }, + "Nerdbank.Streams": { + "type": "Transitive", + "resolved": "2.13.16", + "contentHash": "GjifQ5M4IpQWjGNNbIrsj8M/M7ESb2328OeoGeqxk5rOJiuaAJ5zFc6CyqB+5UWKr1KEGK23hKoxA+z1gooAKA==", + "dependencies": { + "Microsoft.VisualStudio.Threading.Only": "17.13.61", + "Microsoft.VisualStudio.Validation": "17.8.8" + } + }, + "Newtonsoft.Json": { + "type": "Transitive", + "resolved": "13.0.4", + "contentHash": "pdgNNMai3zv51W5aq268sujXUyx7SNdE2bj1wZcWjAQrKMFZV260lbqYop1d2GM67JI1huLRwxo9ZqnfF/lC6A==" + }, + "OpenTelemetry": { + "type": "Transitive", + "resolved": "1.17.0", + "contentHash": "rMLOTftlMlTm7+MSrvXDHnJRjVkROFNKXHZrYjOsX+LankaFG7QSflx7qRRGjoqZoirohnxmJQ7GEb9occO4Gg==", + "dependencies": { + "Microsoft.Extensions.Configuration.EnvironmentVariables": "10.0.0", + "Microsoft.Extensions.Diagnostics.Abstractions": "10.0.0", + "Microsoft.Extensions.Logging.Configuration": "10.0.0", + "OpenTelemetry.Api.ProviderBuilderExtensions": "1.17.0" + } + }, + "OpenTelemetry.Api": { + "type": "Transitive", + "resolved": "1.17.0", + "contentHash": "mSBxzomZgHIJu9CyVNqyDu/n2JHEtqVgfcCD1Br0cV5iLYogjZOMqhlVLt99PEp+0KGBNUR3GXgeOdN2GR3F9g==" + }, + "OpenTelemetry.Api.ProviderBuilderExtensions": { + "type": "Transitive", + "resolved": "1.17.0", + "contentHash": "Xgc3Qf9B9TFMFpx6exTdGqMWuYIT2miNzkdMPutVvT9YuMFaEovXWke1Gb6z8NxYaQbbGF38vYLuSg1JCeui5Q==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0", + "OpenTelemetry.Api": "1.17.0" + } + }, + "Polly.Core": { + "type": "Transitive", + "resolved": "8.6.6", + "contentHash": "lCBL9mmhF9TZxHG3beVRkyjlLohkIC464xIAq7J7Y59C+z42hmsdUaeCKl2SIAYertOUU5TeBXyQDLDQGIKePQ==" + }, + "PolyType": { + "type": "Transitive", + "resolved": "1.3.1", + "contentHash": "GFdJvsN/VczpP0GfdPIi0jDudGH2Emk3rcIJHdqwU2SL2zQm1xSl6OTYvQSUxvzHu3ClWo096ICdWXVkpifQUA==" + }, + "Semver": { + "type": "Transitive", + "resolved": "3.0.0", + "contentHash": "9jZCicsVgTebqkAujRWtC9J1A5EQVlu0TVKHcgoCuv345ve5DYf4D1MjhKEnQjdRZo6x/vdv6QQrYFs7ilGzLA==", + "dependencies": { + "Microsoft.Extensions.Primitives": "5.0.1" + } + }, + "StreamJsonRpc": { + "type": "Transitive", + "resolved": "2.25.29", + "contentHash": "ebP0ScWRtbd1EWayLRJ6bjM7aPwYZoJIIU1DApmn/cYl2dydR9f4p6Mj3eY77qzAywy6IbZWB9sJPSWeO5hmrg==", + "dependencies": { + "MessagePack": "2.5.302", + "Microsoft.VisualStudio.Threading.Only": "17.14.15", + "Microsoft.VisualStudio.Validation": "17.13.22", + "Nerdbank.MessagePack": "1.2.4", + "Nerdbank.Streams": "2.13.16", + "Newtonsoft.Json": "13.0.3" + } + }, + "System.Diagnostics.EventLog": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "+Ro7WgIom+BDNH+YhTuZKL6QJ0ctfOpTyfUG/h3aU5KwXt3OaNf0wYWrTvoBUj+34Dy5V8dN9yCco1hAJQ4txw==" + }, + "System.IO.Hashing": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "+dJsbPJ3FyUbTZNplFj0RCKePFizmv6ewDV46JE9q/IVH4c3xTCftHfHelLsAKf0jryIPqgMb5GpS0x7TAY3mg==" + }, + "YamlDotNet": { + "type": "Transitive", + "resolved": "16.3.0", + "contentHash": "SgMOdxbz8X65z8hraIs6hOEdnkH6hESTAIUa7viEngHOYaH+6q5XJmwr1+yb9vJpNQ19hCQY69xbFsLtXpobQA==" + }, + "Npgsql": { + "type": "CentralTransitive", + "requested": "[9.0.4, )", + "resolved": "9.0.4", + "contentHash": "68BASXH0FAEuL/J4J0eRfYC8/3vzqQTmoW8zDzNf0JgaVxc7LZeEkS6jaG0ib3voFLxY5ZiCwJG+uQM+mzuu0Q==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "8.0.2" + } + }, + "OpenTelemetry.Exporter.OpenTelemetryProtocol": { + "type": "CentralTransitive", + "requested": "[1.17.0, )", + "resolved": "1.17.0", + "contentHash": "R1omQOrQpGlS0Cp5UIr/TAiuEA48JrPlgr1NPV5gESiTU7HhWU+ILe2EBSYb1fKdsSavZ7nZkHcUxAzofPqr2A==", + "dependencies": { + "OpenTelemetry": "1.17.0" + } + }, + "OpenTelemetry.Extensions.Hosting": { + "type": "CentralTransitive", + "requested": "[1.17.0, )", + "resolved": "1.17.0", + "contentHash": "t1OwL/4qgboGMobYVT+UV5zgWnFqCp4Pw8lcsmzh8m2K8PQsTKkyxrC32tqYTMYny3GOW4q5cltE3dTVzLmRew==", + "dependencies": { + "Microsoft.Extensions.Hosting.Abstractions": "10.0.0", + "OpenTelemetry": "1.17.0" + } + } + } + } +} \ No newline at end of file diff --git a/tests/AndreGoepel.AppFoundation.Aspire.Tests/AndreGoepel.AppFoundation.Aspire.Tests.csproj b/tests/AndreGoepel.AppFoundation.Aspire.Tests/AndreGoepel.AppFoundation.Aspire.Tests.csproj new file mode 100644 index 0000000..eb4e83d --- /dev/null +++ b/tests/AndreGoepel.AppFoundation.Aspire.Tests/AndreGoepel.AppFoundation.Aspire.Tests.csproj @@ -0,0 +1,27 @@ + + + net10.0 + enable + enable + false + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + diff --git a/tests/AndreGoepel.AppFoundation.Aspire.Tests/AppFoundationAspireExtensionsTests.cs b/tests/AndreGoepel.AppFoundation.Aspire.Tests/AppFoundationAspireExtensionsTests.cs new file mode 100644 index 0000000..526659a --- /dev/null +++ b/tests/AndreGoepel.AppFoundation.Aspire.Tests/AppFoundationAspireExtensionsTests.cs @@ -0,0 +1,98 @@ +using AndreGoepel.AppFoundation.Aspire; +using Aspire.Hosting; +using Aspire.Hosting.ApplicationModel; + +namespace AndreGoepel.AppFoundation.Aspire.Tests; + +public sealed class AppFoundationAspireExtensionsTests +{ + [Fact] + public void AddStandardMailHog_Defaults_ExposesSmtpAndHttpEndpoints() + { + // Arrange + var builder = DistributedApplication.CreateBuilder([]); + + // Act + var mailhog = builder.AddStandardMailHog(); + + // Assert + Assert.Equal("mailhog", mailhog.Resource.Name); + var endpoints = mailhog.Resource.Annotations.OfType().ToList(); + var smtp = Assert.Single(endpoints, e => e.Name == "smtp"); + Assert.Equal(1025, smtp.Port); + Assert.Equal(1025, smtp.TargetPort); + var http = Assert.Single(endpoints, e => e.Name == "http"); + Assert.Equal(8025, http.Port); + Assert.Equal(8025, http.TargetPort); + Assert.Equal("http", http.UriScheme); + } + + [Fact] + public void AddStandardMailHog_CustomPorts_AppliesThemToTheHostSide() + { + // Arrange + var builder = DistributedApplication.CreateBuilder([]); + + // Act + var mailhog = builder.AddStandardMailHog(smtpPort: 11025, httpPort: 18025); + + // Assert + var endpoints = mailhog.Resource.Annotations.OfType().ToList(); + var smtp = Assert.Single(endpoints, e => e.Name == "smtp"); + Assert.Equal(11025, smtp.Port); + Assert.Equal(1025, smtp.TargetPort); + var http = Assert.Single(endpoints, e => e.Name == "http"); + Assert.Equal(18025, http.Port); + Assert.Equal(8025, http.TargetPort); + } + + [Fact] + public void AddStandardPostgres_NotE2E_KeepsDataVolumeAndPersistentLifetime() + { + // Arrange + var builder = DistributedApplication.CreateBuilder([]); + + // Act + var (server, database) = builder.AddStandardPostgres(isE2E: false); + + // Assert + Assert.Contains(server.Resource.Annotations, a => a is ContainerMountAnnotation); + var lifetime = server.Resource.Annotations.OfType().Single(); + Assert.Equal(ContainerLifetime.Persistent, lifetime.Lifetime); + Assert.Equal("appfoundation-database", database.Resource.Name); + Assert.Equal("appfoundation-database", database.Resource.DatabaseName); + } + + [Fact] + public void AddStandardPostgres_E2E_SkipsDataVolumeAndPersistentLifetime() + { + // Arrange — E2E runs must get a fresh, throwaway database, never a developer's + // persistent local data (mirrors the finance-app/marten-identity AppHost pattern). + var builder = DistributedApplication.CreateBuilder([]); + + // Act + var (server, _) = builder.AddStandardPostgres(isE2E: true); + + // Assert + Assert.DoesNotContain(server.Resource.Annotations, a => a is ContainerMountAnnotation); + Assert.DoesNotContain(server.Resource.Annotations, a => a is ContainerLifetimeAnnotation); + } + + [Fact] + public void AddStandardPostgres_ExplicitDatabaseName_DiffersFromResourceName() + { + // Arrange + var builder = DistributedApplication.CreateBuilder([]); + + // Act + var (_, database) = builder.AddStandardPostgres( + isE2E: false, + databaseResourceName: "appfoundation-database", + databaseName: "appfoundation" + ); + + // Assert + Assert.Equal("appfoundation-database", database.Resource.Name); + Assert.Equal("appfoundation", database.Resource.DatabaseName); + } +} diff --git a/tests/AndreGoepel.AppFoundation.Aspire.Tests/GlobalUsings.cs b/tests/AndreGoepel.AppFoundation.Aspire.Tests/GlobalUsings.cs new file mode 100644 index 0000000..c802f44 --- /dev/null +++ b/tests/AndreGoepel.AppFoundation.Aspire.Tests/GlobalUsings.cs @@ -0,0 +1 @@ +global using Xunit; diff --git a/tests/AndreGoepel.AppFoundation.Aspire.Tests/packages.lock.json b/tests/AndreGoepel.AppFoundation.Aspire.Tests/packages.lock.json new file mode 100644 index 0000000..452d6db --- /dev/null +++ b/tests/AndreGoepel.AppFoundation.Aspire.Tests/packages.lock.json @@ -0,0 +1,870 @@ +{ + "version": 2, + "dependencies": { + "net10.0": { + "Aspire.Hosting": { + "type": "Direct", + "requested": "[13.4.6, )", + "resolved": "13.4.6", + "contentHash": "YJEvsrgcVLPQ88aJ3aFMIEJue0ZFmyH8RfyQu0PnHdZzjBAiK0c8BaYUAycWu35QpTe4hHxEYaY0wW4gpy/kwg==", + "dependencies": { + "AspNetCore.HealthChecks.Uris": "9.0.0", + "Google.Protobuf": "3.34.1", + "Grpc.AspNetCore": "2.80.0", + "Grpc.Net.ClientFactory": "2.80.0", + "Humanizer.Core": "3.0.10", + "JsonPatch.Net": "3.3.0", + "KubernetesClient": "19.0.2", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.Configuration.Binder": "10.0.8", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Diagnostics.HealthChecks": "8.0.27", + "Microsoft.Extensions.FileSystemGlobbing": "10.0.8", + "Microsoft.Extensions.Hosting": "10.0.8", + "Microsoft.Extensions.Hosting.Abstractions": "10.0.8", + "Microsoft.Extensions.Http": "10.0.8", + "Microsoft.Extensions.Logging": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8", + "Microsoft.Extensions.Primitives": "10.0.8", + "ModelContextProtocol": "1.3.0", + "Newtonsoft.Json": "13.0.4", + "OpenTelemetry.Exporter.OpenTelemetryProtocol": "1.15.3", + "OpenTelemetry.Extensions.Hosting": "1.15.3", + "Polly.Core": "8.6.6", + "Semver": "3.0.0", + "StreamJsonRpc": "2.25.29", + "System.IO.Hashing": "10.0.8" + } + }, + "Aspire.Hosting.PostgreSQL": { + "type": "Direct", + "requested": "[13.4.6, )", + "resolved": "13.4.6", + "contentHash": "NyL7O7e7DcpZSF0sAz332GIJ3S7X/66NoqhPqzVMPbNYfF97bTrk7C7Yq1tuilffHfq2SV2xi6aHbhGOmSoGqw==", + "dependencies": { + "AspNetCore.HealthChecks.NpgSql": "9.0.0", + "AspNetCore.HealthChecks.Uris": "9.0.0", + "Aspire.Hosting": "13.4.6", + "Google.Protobuf": "3.34.1", + "Grpc.AspNetCore": "2.80.0", + "Grpc.Net.ClientFactory": "2.80.0", + "Grpc.Tools": "2.80.0", + "Humanizer.Core": "3.0.10", + "JsonPatch.Net": "3.3.0", + "KubernetesClient": "19.0.2", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.Configuration.Binder": "10.0.8", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Diagnostics.HealthChecks": "8.0.27", + "Microsoft.Extensions.FileSystemGlobbing": "10.0.8", + "Microsoft.Extensions.Hosting": "10.0.8", + "Microsoft.Extensions.Hosting.Abstractions": "10.0.8", + "Microsoft.Extensions.Http": "10.0.8", + "Microsoft.Extensions.Logging": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8", + "Microsoft.Extensions.Primitives": "10.0.8", + "ModelContextProtocol": "1.3.0", + "Newtonsoft.Json": "13.0.4", + "OpenTelemetry.Exporter.OpenTelemetryProtocol": "1.15.3", + "OpenTelemetry.Extensions.Hosting": "1.15.3", + "Polly.Core": "8.6.6", + "Semver": "3.0.0", + "StreamJsonRpc": "2.25.29", + "System.IO.Hashing": "10.0.8" + } + }, + "coverlet.collector": { + "type": "Direct", + "requested": "[10.0.1, )", + "resolved": "10.0.1", + "contentHash": "27jXSV/0DbVqF5jDrAxuQFZ9oaz6gmG03p8ttxAFk+X0M4woFYj7MoWDLCna5EGLb0CE6OE7X6ZH3Wt5smTtaA==" + }, + "Microsoft.NET.Test.Sdk": { + "type": "Direct", + "requested": "[18.8.1, )", + "resolved": "18.8.1", + "contentHash": "dknJL3/9Y3t4XuCBqnc0PevPxgLsUMmVhjwup/b1HNovA8zWcj3XsfIf7c6p05363DWcqL7X/YhDL9B+Zymv1w==", + "dependencies": { + "Microsoft.CodeCoverage": "18.8.1", + "Microsoft.TestPlatform.TestHost": "18.8.1" + } + }, + "xunit.runner.visualstudio": { + "type": "Direct", + "requested": "[3.1.5, )", + "resolved": "3.1.5", + "contentHash": "tKi7dSTwP4m5m9eXPM2Ime4Kn7xNf4x4zT9sdLO/G4hZVnQCRiMTWoSZqI/pYTVeI27oPPqHBKYI/DjJ9GsYgA==" + }, + "xunit.v3": { + "type": "Direct", + "requested": "[3.2.2, )", + "resolved": "3.2.2", + "contentHash": "L+4/4y0Uqcg8/d6hfnxhnwh4j9FaeULvefTwrk30rr1o4n/vdPfyUQ8k0yzH8VJx7bmFEkDdcRfbtbjEHlaYcA==", + "dependencies": { + "xunit.v3.mtp-v1": "[3.2.2]" + } + }, + "AspNetCore.HealthChecks.NpgSql": { + "type": "Transitive", + "resolved": "9.0.0", + "contentHash": "npc58/AD5zuVxERdhCl2Kb7WnL37mwX42SJcXIwvmEig0/dugOLg3SIwtfvvh3TnvTwR/sk5LYNkkPaBdks61A==", + "dependencies": { + "Microsoft.Extensions.Diagnostics.HealthChecks": "8.0.11", + "Npgsql": "8.0.3" + } + }, + "AspNetCore.HealthChecks.Uris": { + "type": "Transitive", + "resolved": "9.0.0", + "contentHash": "XYdNlA437KeF8p9qOpZFyNqAN+c0FXt/JjTvzH/Qans0q0O3pPE8KPnn39ucQQjR/Roum1vLTP3kXiUs8VHyuA==", + "dependencies": { + "Microsoft.Extensions.Diagnostics.HealthChecks": "8.0.11", + "Microsoft.Extensions.Http": "8.0.0" + } + }, + "Fractions": { + "type": "Transitive", + "resolved": "7.3.0", + "contentHash": "2bETFWLBc8b7Ut2SVi+bxhGVwiSpknHYGBh2PADyGWONLkTxT7bKyDRhF8ao+XUv90tq8Fl7GTPxSI5bacIRJw==" + }, + "Google.Protobuf": { + "type": "Transitive", + "resolved": "3.34.1", + "contentHash": "212vdYxRuVopGE5bess6Jg5oXWyizA6hcLPTI7G+qA4PthQEvfeof3njT+7VSY5v/+O0P22xTydiP5fSJJpGEA==" + }, + "Grpc.AspNetCore": { + "type": "Transitive", + "resolved": "2.80.0", + "contentHash": "ASbJbdtCUlGiKxe9NsN/QeG1PdibYoN0pEgP9U87cvS6HV0XsT+VdO/g2M6Ri8zZURfX5c7MBTaFVP/YCrC72A==", + "dependencies": { + "Google.Protobuf": "3.31.1", + "Grpc.AspNetCore.Server.ClientFactory": "2.80.0", + "Grpc.Tools": "2.80.0" + } + }, + "Grpc.AspNetCore.Server": { + "type": "Transitive", + "resolved": "2.80.0", + "contentHash": "lbK7z1sZP5imPdQ035f/CZ61iIaBWouY6A580E9JNo7vzXYX/Qo+GQtSjOzhP9VFbxk7mtLoMhn/v1fT2U7kTw==", + "dependencies": { + "Grpc.Net.Common": "2.80.0" + } + }, + "Grpc.AspNetCore.Server.ClientFactory": { + "type": "Transitive", + "resolved": "2.80.0", + "contentHash": "7JdfxQZv/pO9qU5Ild2mrkzYA7PmVGDKVmWqKVCZNRSDN/RluRN4S4utYgBSwAcYgUBWQDHNb1Ll7wm3BdHfqw==", + "dependencies": { + "Grpc.AspNetCore.Server": "2.80.0", + "Grpc.Net.ClientFactory": "2.80.0" + } + }, + "Grpc.Core.Api": { + "type": "Transitive", + "resolved": "2.80.0", + "contentHash": "i/8s+MOrYa6n7BmZ5bilcbHk+EMJDQHm2MKLhwGAT+urQqlZ6cpjvSivYvuULjebuX+UKieLYZbLRCmVQxFRkw==" + }, + "Grpc.Net.Client": { + "type": "Transitive", + "resolved": "2.80.0", + "contentHash": "I1Aa24nTRMHqx0pmQfvthFsOpejquDjiJV6092KBqjw6EEr3wA9CMXlrdkoEgHartOiJrpKyZiQRl7n0NVlfBg==", + "dependencies": { + "Grpc.Net.Common": "2.80.0", + "Microsoft.Extensions.Logging.Abstractions": "8.0.0" + } + }, + "Grpc.Net.ClientFactory": { + "type": "Transitive", + "resolved": "2.80.0", + "contentHash": "YtY1DWID2phwiGc8qBG7+wf00Do5jE7BkJgCc6nbu5b50OsD89mSd73oCE8fCnUo7IjtDAEYFOYI3NSzgn28gw==", + "dependencies": { + "Grpc.Net.Client": "2.80.0", + "Microsoft.Extensions.Http": "8.0.0" + } + }, + "Grpc.Net.Common": { + "type": "Transitive", + "resolved": "2.80.0", + "contentHash": "E2ERsx+9IXlry4yjBl8btx0XMIKzymGNSvX5jmBS/uSwYyYDoKIDcIREyLqFLvd8vcJdcoRlycpvn9YRXutFpQ==", + "dependencies": { + "Grpc.Core.Api": "2.80.0" + } + }, + "Grpc.Tools": { + "type": "Transitive", + "resolved": "2.80.0", + "contentHash": "NS1AxwVZnrdbBoMf5L5ruGjBjoLBej9avhqxWNsgfu2GU6FhpxEVJOwLJsdljlDCjvquJiAH2zf/WodIWMvf2w==" + }, + "Humanizer.Core": { + "type": "Transitive", + "resolved": "3.0.10", + "contentHash": "yZIhtw8sYuvsONzQbZxWpR60tMWYHXoo0DL6nyOqSFiU5POjBTSEyWFpTQtJEZuy+oqiYTXKXY/Mjx7KnqIQFw==" + }, + "Json.More.Net": { + "type": "Transitive", + "resolved": "2.1.0", + "contentHash": "qtwsyAsL55y2vB2/sK4Pjg3ZyVzD5KKSpV3lOAMHlnjFfsjQ/86eHJfQT9aV1YysVXzF4+xyHOZbh7Iu3YQ7Lg==" + }, + "JsonPatch.Net": { + "type": "Transitive", + "resolved": "3.3.0", + "contentHash": "GIcMMDtzfzVfIpQgey8w7dhzcw6jG5nD4DDAdQCTmHfblkCvN7mI8K03to8YyUhKMl4PTR6D6nLSvWmyOGFNTg==", + "dependencies": { + "JsonPointer.Net": "5.2.0" + } + }, + "JsonPointer.Net": { + "type": "Transitive", + "resolved": "5.2.0", + "contentHash": "qe1F7Tr/p4mgwLPU9P60MbYkp+xnL2uCPnWXGgzfR/AZCunAZIC0RZ32dLGJJEhSuLEfm0YF/1R3u5C7mEVq+w==", + "dependencies": { + "Humanizer.Core": "2.14.1", + "Json.More.Net": "2.1.0" + } + }, + "KubernetesClient": { + "type": "Transitive", + "resolved": "19.0.2", + "contentHash": "0m8FuzCDBygaXMbsb7qVapNZzTm4ftM7ECp/waTRh/XOUQziRF2rKJCRmsvYbBXgJkQvU+FBbkoa40hexzDC+g==", + "dependencies": { + "Fractions": "7.3.0", + "YamlDotNet": "16.3.0" + } + }, + "MessagePack": { + "type": "Transitive", + "resolved": "2.5.302", + "contentHash": "5DZsKli4dMEpm/glcMAheuO8/IesfaTskbfsuvgnQwWFKS5FN7Z6yNx+5F+UW94E+9N2qt8Zs63/XVzpLsElgA==", + "dependencies": { + "MessagePack.Annotations": "2.5.302", + "Microsoft.NET.StringTools": "17.6.3" + } + }, + "MessagePack.Annotations": { + "type": "Transitive", + "resolved": "2.5.302", + "contentHash": "PTHQHbMJzx1VtUUCpnvPavD7o5X9s2dAJ4uQHAP2kBCwJKICpPTZq0qxzbB4/6iJJiIxem8zlxyfldGAx1SjSQ==" + }, + "Microsoft.ApplicationInsights": { + "type": "Transitive", + "resolved": "2.23.0", + "contentHash": "nWArUZTdU7iqZLycLKWe0TDms48KKGE6pONH2terYNa8REXiqixrMOkf1sk5DHGMaUTqONU2YkS4SAXBhLStgw==" + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "UcSjPsst+DfAdJGVDsu346FX0ci0ah+lw3WRtn18NUwEqRt70HaOQ7lI72vy3+1LxtqI3T5GWwV39rQSrCzAeg==" + }, + "Microsoft.CodeCoverage": { + "type": "Transitive", + "resolved": "18.8.1", + "contentHash": "Eclse/ZZjr4lmWzZFNN9h/OluhKL+SK/QbUyKUewgX139aGeyMEO/DkMPwuFs2MixvanTnz6891rF8UHDg+W4Q==" + }, + "Microsoft.Extensions.AI.Abstractions": { + "type": "Transitive", + "resolved": "10.5.2", + "contentHash": "Ei+YWV9Ybnps7pR1dgjlG29gelXEwZkhLVAcWmKe6HvXS6LNBYgSdWiY3Hk9OZXYtK34rv/NtLWBQYQGOBQYPQ==" + }, + "Microsoft.Extensions.Caching.Abstractions": { + "type": "Transitive", + "resolved": "10.0.7", + "contentHash": "pUDgQKEqNUFlerDIFRg7zzoDVRPEWIG7nR40h8Gzg8RXza4Ry0lWZ7u91bmwu3iUDCxw3Dv6TLHVFoAgY0gy7Q==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.7" + } + }, + "Microsoft.Extensions.Configuration": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "ehZcoPbjzWzS4XFvuz7R3V55SmpdkyMqFURLH3yXaN9NtXd9tR6CGB7pd49HYtCkenl+G7ctXSFLhNI08xLfRg==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.Primitives": "10.0.8" + } + }, + "Microsoft.Extensions.Configuration.Abstractions": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "I63esIFbL3h5pSt7gXpXOlmcwDmYBUoYNEglKfDPFUqtYvSV84f2l28hO2lfVXsV0wdlplgAM7IVz16matapSg==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.8" + } + }, + "Microsoft.Extensions.Configuration.Binder": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "R3NN1X+kVu14uoxLEW6sBSQyhogDSbaOQzILnCtuXxBN4hx22AgjWPwZX6v/suERFkEDgU1lk12AglHTrUxhlw==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8" + } + }, + "Microsoft.Extensions.Configuration.CommandLine": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "nQXq1a4MiInYh+0VF9fguxAl06q2ftmOyYQ+5e933s4rk57xjgkbTjUdFUySzjrcrvDeWsSqlZB+TE8+TbM2HA==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8" + } + }, + "Microsoft.Extensions.Configuration.EnvironmentVariables": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "bVGqctAfPGfTxJvNp8pMshtvpsUj6r6JkeiCNVIGVYO5gBxuxdN0Lbr25kEvE/zXdctkEc44g8HssnPgDnFGVA==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8" + } + }, + "Microsoft.Extensions.Configuration.FileExtensions": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "1g9mzuu8gIHkjYb0jLxOTQVl/QDG5nn0b0JzgT/gbgNKr6gXZzxOHRAsdYRc1eDApB7LdHR8uK5vQrNjIQdRrQ==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.8", + "Microsoft.Extensions.FileProviders.Physical": "10.0.8", + "Microsoft.Extensions.Primitives": "10.0.8" + } + }, + "Microsoft.Extensions.Configuration.Json": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "KLtAZ6A38s1pIfCO2ns6aG14NNGMYNZ4PBYfFK4M+R4A+xuSc6oklhqDcpHZxvDpyBWeFtR5C8iQBw2ng8tUHQ==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.Configuration.FileExtensions": "10.0.8", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.8" + } + }, + "Microsoft.Extensions.Configuration.UserSecrets": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "6XTfFOnf27WY8kEeZkTZ4YNn0t+imgvdQ0YaAdR4vgURKATo9bCaVJ1KB71IOJAQtJP7Elb53VHlTNXg2CtSsA==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.Configuration.Json": "10.0.8", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.8", + "Microsoft.Extensions.FileProviders.Physical": "10.0.8" + } + }, + "Microsoft.Extensions.DependencyInjection": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "daf62xHIrq8pnE709hgaZZN9tSam9TGGepWe1+bE6V3GEuVwJiMs6ib+38lfMCyAJAHiX0vapxBhsuMSV7U+cg==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8" + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "21nbDV60SRPWGIivsyl6lqBeEJNG1sginhhfWgRrr3Ais7aQ12To25OAHQxgoiJkjqy1aQ6RxpZBGYuTi7Ge6A==" + }, + "Microsoft.Extensions.Diagnostics": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "uduyw9d3Fi+sbredO5drA1S44AQS2FRNFyn72UmB2vmQIO1qaXprpp1U/2lYhYi8yFdVERfY9sy/pxw/qPOU9w==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.8", + "Microsoft.Extensions.Diagnostics.Abstractions": "10.0.8", + "Microsoft.Extensions.Options.ConfigurationExtensions": "10.0.8" + } + }, + "Microsoft.Extensions.Diagnostics.Abstractions": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "+f4C5g78QCGNyxzUfrTYsB7qYx06Zca0e88s3qFlea9/lQhgPImYdNprlgzl1uHhRU3fVHLfmbijayU2sJEZ6w==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8" + } + }, + "Microsoft.Extensions.Diagnostics.HealthChecks": { + "type": "Transitive", + "resolved": "8.0.27", + "contentHash": "NzhCnD8d9fQz4QzMjCS64Yu+zeqtvJDeSIWBdgp2n3ySj/3DKH6JC5txzvWi5evh3AQ8pYVvBQAoCh/opEruVQ==", + "dependencies": { + "Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions": "8.0.27", + "Microsoft.Extensions.Hosting.Abstractions": "8.0.1", + "Microsoft.Extensions.Logging.Abstractions": "8.0.3", + "Microsoft.Extensions.Options": "8.0.2" + } + }, + "Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions": { + "type": "Transitive", + "resolved": "8.0.27", + "contentHash": "jnnmIxGWNKE40xjGdDuRHXRHAqF5gMsmyY4BB/WMddSZMb4rLLzKENdZ+t2rw0bBW9MDjdPTxUFx7NsuGy7Uvg==" + }, + "Microsoft.Extensions.FileProviders.Abstractions": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "U+oquaPxFdY8lYeEIWO/AD7jDIl9sPW6aVWMQRHU/pZ/SWpLcOrAj2fcLe1HwXl4sYw1ONI56K/eELT3xr4RRQ==", + "dependencies": { + "Microsoft.Extensions.Primitives": "10.0.8" + } + }, + "Microsoft.Extensions.FileProviders.Physical": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "GkPvQe6IdidLu6Q3Lw6+B8NJpW8feW8czZ5mBKt5rXM/x8MvZfEp5WvAsjznzDGd23chIDrW0b2mmt+ScnEgiw==", + "dependencies": { + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.8", + "Microsoft.Extensions.FileSystemGlobbing": "10.0.8", + "Microsoft.Extensions.Primitives": "10.0.8" + } + }, + "Microsoft.Extensions.FileSystemGlobbing": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "IUQet3SY51xIFcFZKtAB6a54/Zdxs7T3SQ84kJtOD6yeXfZgiOMksACWD5qtTmXGQGFH4QYGBOT0KIO8Uy/dJw==" + }, + "Microsoft.Extensions.Hosting": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "VfEyM2BipThcSd0GG/FS2ZPCVCTiosVq2zLKEDsfeMIg78sOVZPEmS7CgWlb+dqTlgXvLSL4OG2q6sM4xRhHNg==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.Configuration.Binder": "10.0.8", + "Microsoft.Extensions.Configuration.CommandLine": "10.0.8", + "Microsoft.Extensions.Configuration.EnvironmentVariables": "10.0.8", + "Microsoft.Extensions.Configuration.FileExtensions": "10.0.8", + "Microsoft.Extensions.Configuration.Json": "10.0.8", + "Microsoft.Extensions.Configuration.UserSecrets": "10.0.8", + "Microsoft.Extensions.DependencyInjection": "10.0.8", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Diagnostics": "10.0.8", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.8", + "Microsoft.Extensions.FileProviders.Physical": "10.0.8", + "Microsoft.Extensions.Hosting.Abstractions": "10.0.8", + "Microsoft.Extensions.Logging": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8", + "Microsoft.Extensions.Logging.Configuration": "10.0.8", + "Microsoft.Extensions.Logging.Console": "10.0.8", + "Microsoft.Extensions.Logging.Debug": "10.0.8", + "Microsoft.Extensions.Logging.EventLog": "10.0.8", + "Microsoft.Extensions.Logging.EventSource": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8" + } + }, + "Microsoft.Extensions.Hosting.Abstractions": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "MoOWFPT88/pDfmWpbU9PydKRX/rJFQkliowE/L9wbQcl94IicUphb5BFgepkWiDkYYxPnuEqjN4buzOGW4vJpQ==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Diagnostics.Abstractions": "10.0.8", + "Microsoft.Extensions.FileProviders.Abstractions": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8" + } + }, + "Microsoft.Extensions.Http": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "/9LU/KWJOrtZJB9ymPjcARDyjp679BvBA/aSncv2Kt84WlSKz767HtxHg8EFsu8n21BMLZi+5XxlkKbLwfn4iA==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Diagnostics": "10.0.8", + "Microsoft.Extensions.Logging": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8" + } + }, + "Microsoft.Extensions.Logging": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "K60JhWC2hN/Gi7TP68tBxSzk5ACWOs7lkmPzsfA8Bcf/IXTajujt2ORMf9rSMk1bsng6Lv4Y3fuxp3bm1+15ug==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8" + } + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "fdVadZmsC8jRP0KvKy8mO8f6GV/HyBvElfcSxEhd+5FM5boAw/01iSaCto5G3G37ApJira4A3pNaVvBv8cUiLQ==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8" + } + }, + "Microsoft.Extensions.Logging.Configuration": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "rxSLTO7xTbcC3DuEJHNEijBr8g14Jj62zQ+DeFu68bsoTYoU8jLcMhc1735PV21bESXsATlL5LsfaWH71FOWAg==", + "dependencies": { + "Microsoft.Extensions.Configuration": "10.0.8", + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.Configuration.Binder": "10.0.8", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Logging": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8", + "Microsoft.Extensions.Options.ConfigurationExtensions": "10.0.8" + } + }, + "Microsoft.Extensions.Logging.Console": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "6cv53sHsPnFS56PJw8X4GbNcjeX1KGyFJRxJWvxOgK63cnqeSB1k1eRwjUdkse0tBhwlH6qc9EOYDlan+CYTuw==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Logging": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8", + "Microsoft.Extensions.Logging.Configuration": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8" + } + }, + "Microsoft.Extensions.Logging.Debug": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "4HW3M1lGHHDwEYcDZHRNptBQ48LCI2yW+XV4vuxdfQUqafTpVT8j9RqAsez08krZKhIiaArWu8iQq5uRKZ9Ffg==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Logging": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8" + } + }, + "Microsoft.Extensions.Logging.EventLog": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "kK/C3SLIoGrcZvddYQw4eMm6YaROiSYBO7YgUR5Hdv5l+GIjBmbvQK5cST2FqjeubiAOPqFEimBT2N/8wVI+3A==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Logging": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8", + "System.Diagnostics.EventLog": "10.0.8" + } + }, + "Microsoft.Extensions.Logging.EventSource": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "HX2M0MgzwQM8jpLe3AYAEMd0YsUfOP5RgGrDuk+Ki9n7HSuMbvLm9TEV3qRI3Pg9aqxc56GfgK/KdMRBhfWwKw==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Logging": "10.0.8", + "Microsoft.Extensions.Logging.Abstractions": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8", + "Microsoft.Extensions.Primitives": "10.0.8" + } + }, + "Microsoft.Extensions.Options": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "VBD+131DpTNCNDfA4kIyKTiCySvJGNhwibdWBSdFRu7GMfXLXcXODkgA+KStKbbhzraLglZWUN4nXyHgW4JIRA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Primitives": "10.0.8" + } + }, + "Microsoft.Extensions.Options.ConfigurationExtensions": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "VOapXeO3lhBH0zYoyAH7tjapuo4V5pTHlevPpiSHueEquAajqd5nF0mttm+h/uE/exwAEuM5s26SzOJtletE3w==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "10.0.8", + "Microsoft.Extensions.Configuration.Binder": "10.0.8", + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.8", + "Microsoft.Extensions.Options": "10.0.8", + "Microsoft.Extensions.Primitives": "10.0.8" + } + }, + "Microsoft.Extensions.Primitives": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "OBPo4nYhMyIbtueoC10CBm6AGAbo/A9IV8QQ/6ryZS7VvmqpGT7hunazeHLxFawRzn3oLOq4jhqhpBX4tfswWQ==" + }, + "Microsoft.NET.StringTools": { + "type": "Transitive", + "resolved": "18.4.0", + "contentHash": "iQWOKi3L5QStmWqDjDubcr1KlTDy88qBTe88I0etlUUo1l0zSNebGJXl1Xetyl+ACA+ujP3YUtxo3Nz54JPriw==" + }, + "Microsoft.Testing.Extensions.Telemetry": { + "type": "Transitive", + "resolved": "1.9.1", + "contentHash": "No5AudZMmSb+uNXjlgL2y3/stHD2IT4uxqc5yHwkE+/nNux9jbKcaJMvcp9SwgP4DVD8L9/P3OUz8mmmcvEIdQ==", + "dependencies": { + "Microsoft.ApplicationInsights": "2.23.0", + "Microsoft.Testing.Platform": "1.9.1" + } + }, + "Microsoft.Testing.Extensions.TrxReport.Abstractions": { + "type": "Transitive", + "resolved": "1.9.1", + "contentHash": "AL46Xe1WBi85Ntd4mNPvat5ZSsZ2uejiVqoKCypr8J3wK0elA5xJ3AN4G/Q4GIwzUFnggZoH/DBjnr9J18IO/g==", + "dependencies": { + "Microsoft.Testing.Platform": "1.9.1" + } + }, + "Microsoft.Testing.Platform": { + "type": "Transitive", + "resolved": "1.9.1", + "contentHash": "QafNtNSmEI0zazdebnsIkDKmFtTSpmx/5PLOjURWwozcPb3tvRxzosQSL8xwYNM1iPhhKiBksXZyRSE2COisrA==" + }, + "Microsoft.Testing.Platform.MSBuild": { + "type": "Transitive", + "resolved": "1.9.1", + "contentHash": "oTUtyR4X/s9ytuiNA29FGsNCCH0rNmY5Wdm14NCKLjTM1cT9edVSlA+rGS/mVmusPqcP0l/x9qOnMXg16v87RQ==", + "dependencies": { + "Microsoft.Testing.Platform": "1.9.1" + } + }, + "Microsoft.TestPlatform.ObjectModel": { + "type": "Transitive", + "resolved": "18.8.1", + "contentHash": "qLbktNB1+b1XZLNJBTzaWVVJAd6PEzD7cgD406geMb6PcFZhp3EDNa1tctWx1+mtMU6MP/6ozVvFPC9vs2a9rw==" + }, + "Microsoft.TestPlatform.TestHost": { + "type": "Transitive", + "resolved": "18.8.1", + "contentHash": "FaQHPDTUOcE+SFTjssNPfrub2lT9Zyon4J2W/KLHt/efLJACb1TCeWXyOgh0D/4Q1e4n+S3E6mOKud+9nLZlEA==", + "dependencies": { + "Microsoft.TestPlatform.ObjectModel": "18.8.1" + } + }, + "Microsoft.VisualStudio.Threading.Only": { + "type": "Transitive", + "resolved": "17.14.15", + "contentHash": "NqONyw1RXyj9P3k5e1uU2k9kc1ptwuU5NJQzG+MPq7vQVHUzBY8HLuJf/N2Rw5H/myD96CVxziDxmjawPuzntw==", + "dependencies": { + "Microsoft.VisualStudio.Validation": "17.8.8" + } + }, + "Microsoft.VisualStudio.Validation": { + "type": "Transitive", + "resolved": "17.13.22", + "contentHash": "fC20ITOxlUpGQ0ltAxITQbeFxwuB6OjLT3lByC4+/Gm46o/Mwv9hlIVrBhiUhnqdQzUUvr4EHkdiYe7WOSMLmw==" + }, + "Microsoft.Win32.Registry": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==" + }, + "ModelContextProtocol": { + "type": "Transitive", + "resolved": "1.3.0", + "contentHash": "WDaD6z9KkkCUHSo15xK7tYBERHy8uqP+cIUp8uIxhR0yrlpJLXTRcJcUUVqpXlBkV7MK9Eo3mTrAnctLnJuHDQ==", + "dependencies": { + "Microsoft.Extensions.Caching.Abstractions": "10.0.7", + "Microsoft.Extensions.Hosting.Abstractions": "10.0.7", + "ModelContextProtocol.Core": "1.3.0" + } + }, + "ModelContextProtocol.Core": { + "type": "Transitive", + "resolved": "1.3.0", + "contentHash": "OWmdxDSwA7K9pNNg4t98MXNIssHG/wOQEr/G8pG5B7synDdw4MnmZ/IIVeb3yUdeznPqnDHvd3FBCK0jRk4IZQ==", + "dependencies": { + "Microsoft.Extensions.AI.Abstractions": "10.5.2", + "Microsoft.Extensions.Logging.Abstractions": "10.0.7" + } + }, + "Nerdbank.MessagePack": { + "type": "Transitive", + "resolved": "1.2.4", + "contentHash": "9NKlDsKkOV5zQFkZZnQmssdV6npFNs0Of1Nz5mvAJA4uANxCge2TfXQ9nCYUet58bEWQ00a/aNHdjmcXEI7iuQ==", + "dependencies": { + "Microsoft.NET.StringTools": "18.4.0", + "Microsoft.VisualStudio.Validation": "17.13.22", + "PolyType": "1.3.1" + } + }, + "Nerdbank.Streams": { + "type": "Transitive", + "resolved": "2.13.16", + "contentHash": "GjifQ5M4IpQWjGNNbIrsj8M/M7ESb2328OeoGeqxk5rOJiuaAJ5zFc6CyqB+5UWKr1KEGK23hKoxA+z1gooAKA==", + "dependencies": { + "Microsoft.VisualStudio.Threading.Only": "17.13.61", + "Microsoft.VisualStudio.Validation": "17.8.8" + } + }, + "Newtonsoft.Json": { + "type": "Transitive", + "resolved": "13.0.4", + "contentHash": "pdgNNMai3zv51W5aq268sujXUyx7SNdE2bj1wZcWjAQrKMFZV260lbqYop1d2GM67JI1huLRwxo9ZqnfF/lC6A==" + }, + "OpenTelemetry": { + "type": "Transitive", + "resolved": "1.17.0", + "contentHash": "rMLOTftlMlTm7+MSrvXDHnJRjVkROFNKXHZrYjOsX+LankaFG7QSflx7qRRGjoqZoirohnxmJQ7GEb9occO4Gg==", + "dependencies": { + "Microsoft.Extensions.Configuration.EnvironmentVariables": "10.0.0", + "Microsoft.Extensions.Diagnostics.Abstractions": "10.0.0", + "Microsoft.Extensions.Logging.Configuration": "10.0.0", + "OpenTelemetry.Api.ProviderBuilderExtensions": "1.17.0" + } + }, + "OpenTelemetry.Api": { + "type": "Transitive", + "resolved": "1.17.0", + "contentHash": "mSBxzomZgHIJu9CyVNqyDu/n2JHEtqVgfcCD1Br0cV5iLYogjZOMqhlVLt99PEp+0KGBNUR3GXgeOdN2GR3F9g==" + }, + "OpenTelemetry.Api.ProviderBuilderExtensions": { + "type": "Transitive", + "resolved": "1.17.0", + "contentHash": "Xgc3Qf9B9TFMFpx6exTdGqMWuYIT2miNzkdMPutVvT9YuMFaEovXWke1Gb6z8NxYaQbbGF38vYLuSg1JCeui5Q==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "10.0.0", + "OpenTelemetry.Api": "1.17.0" + } + }, + "Polly.Core": { + "type": "Transitive", + "resolved": "8.6.6", + "contentHash": "lCBL9mmhF9TZxHG3beVRkyjlLohkIC464xIAq7J7Y59C+z42hmsdUaeCKl2SIAYertOUU5TeBXyQDLDQGIKePQ==" + }, + "PolyType": { + "type": "Transitive", + "resolved": "1.3.1", + "contentHash": "GFdJvsN/VczpP0GfdPIi0jDudGH2Emk3rcIJHdqwU2SL2zQm1xSl6OTYvQSUxvzHu3ClWo096ICdWXVkpifQUA==" + }, + "Semver": { + "type": "Transitive", + "resolved": "3.0.0", + "contentHash": "9jZCicsVgTebqkAujRWtC9J1A5EQVlu0TVKHcgoCuv345ve5DYf4D1MjhKEnQjdRZo6x/vdv6QQrYFs7ilGzLA==", + "dependencies": { + "Microsoft.Extensions.Primitives": "5.0.1" + } + }, + "StreamJsonRpc": { + "type": "Transitive", + "resolved": "2.25.29", + "contentHash": "ebP0ScWRtbd1EWayLRJ6bjM7aPwYZoJIIU1DApmn/cYl2dydR9f4p6Mj3eY77qzAywy6IbZWB9sJPSWeO5hmrg==", + "dependencies": { + "MessagePack": "2.5.302", + "Microsoft.VisualStudio.Threading.Only": "17.14.15", + "Microsoft.VisualStudio.Validation": "17.13.22", + "Nerdbank.MessagePack": "1.2.4", + "Nerdbank.Streams": "2.13.16", + "Newtonsoft.Json": "13.0.3" + } + }, + "System.Diagnostics.EventLog": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "+Ro7WgIom+BDNH+YhTuZKL6QJ0ctfOpTyfUG/h3aU5KwXt3OaNf0wYWrTvoBUj+34Dy5V8dN9yCco1hAJQ4txw==" + }, + "System.IO.Hashing": { + "type": "Transitive", + "resolved": "10.0.8", + "contentHash": "+dJsbPJ3FyUbTZNplFj0RCKePFizmv6ewDV46JE9q/IVH4c3xTCftHfHelLsAKf0jryIPqgMb5GpS0x7TAY3mg==" + }, + "xunit.analyzers": { + "type": "Transitive", + "resolved": "1.27.0", + "contentHash": "y/pxIQaLvk/kxAoDkZW9GnHLCEqzwl5TW0vtX3pweyQpjizB9y3DXhb9pkw2dGeUqhLjsxvvJM1k89JowU6z3g==" + }, + "xunit.v3.assert": { + "type": "Transitive", + "resolved": "3.2.2", + "contentHash": "BPciBghgEEaJN/JG00QfCYDfEfnLgQhfnYEy+j1izoeHVNYd5+3Wm8GJ6JgYysOhpBPYGE+sbf75JtrRc7jrdA==" + }, + "xunit.v3.common": { + "type": "Transitive", + "resolved": "3.2.2", + "contentHash": "Hj775PEH6GTbbg0wfKRvG2hNspDCvTH9irXhH4qIWgdrOSV1sQlqPie+DOvFeigsFg2fxSM3ZAaaCDQs+KreFA==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "6.0.0" + } + }, + "xunit.v3.core.mtp-v1": { + "type": "Transitive", + "resolved": "3.2.2", + "contentHash": "Ga5aA2Ca9ktz+5k3g5ukzwfexwoqwDUpV6z7atSEUvqtd6JuybU1XopHqg1oFd78QdTfZgZE9h5sHpO4qYIi5w==", + "dependencies": { + "Microsoft.Testing.Extensions.Telemetry": "1.9.1", + "Microsoft.Testing.Extensions.TrxReport.Abstractions": "1.9.1", + "Microsoft.Testing.Platform": "1.9.1", + "Microsoft.Testing.Platform.MSBuild": "1.9.1", + "xunit.v3.extensibility.core": "[3.2.2]", + "xunit.v3.runner.inproc.console": "[3.2.2]" + } + }, + "xunit.v3.extensibility.core": { + "type": "Transitive", + "resolved": "3.2.2", + "contentHash": "srY8z/oMPvh/t8axtO2DwrHajhFMH7tnqKildvYrVQIfICi8fOn3yIBWkVPAcrKmHMwvXRJ/XsQM3VMR6DOYfQ==", + "dependencies": { + "xunit.v3.common": "[3.2.2]" + } + }, + "xunit.v3.mtp-v1": { + "type": "Transitive", + "resolved": "3.2.2", + "contentHash": "O41aAzYKBT5PWqATa1oEWVNCyEUypFQ4va6K0kz37dduV3EKzXNMaV2UnEhufzU4Cce1I33gg0oldS8tGL5I0A==", + "dependencies": { + "xunit.analyzers": "1.27.0", + "xunit.v3.assert": "[3.2.2]", + "xunit.v3.core.mtp-v1": "[3.2.2]" + } + }, + "xunit.v3.runner.common": { + "type": "Transitive", + "resolved": "3.2.2", + "contentHash": "/hkHkQCzGrugelOAehprm7RIWdsUFVmIVaD6jDH/8DNGCymTlKKPTbGokD5czbAfqfex47mBP0sb0zbHYwrO/g==", + "dependencies": { + "Microsoft.Win32.Registry": "[5.0.0]", + "xunit.v3.common": "[3.2.2]" + } + }, + "xunit.v3.runner.inproc.console": { + "type": "Transitive", + "resolved": "3.2.2", + "contentHash": "ulWOdSvCk+bPXijJZ73bth9NyoOHsAs1ZOvamYbCkD4DNLX/Bd29Ve2ZNUwBbK0MqfIYWXHZViy/HKrdEC/izw==", + "dependencies": { + "xunit.v3.extensibility.core": "[3.2.2]", + "xunit.v3.runner.common": "[3.2.2]" + } + }, + "YamlDotNet": { + "type": "Transitive", + "resolved": "16.3.0", + "contentHash": "SgMOdxbz8X65z8hraIs6hOEdnkH6hESTAIUa7viEngHOYaH+6q5XJmwr1+yb9vJpNQ19hCQY69xbFsLtXpobQA==" + }, + "andregoepel.appfoundation.aspire": { + "type": "Project", + "dependencies": { + "Aspire.Hosting": "[13.4.6, )", + "Aspire.Hosting.PostgreSQL": "[13.4.6, )" + } + }, + "Npgsql": { + "type": "CentralTransitive", + "requested": "[9.0.4, )", + "resolved": "9.0.4", + "contentHash": "68BASXH0FAEuL/J4J0eRfYC8/3vzqQTmoW8zDzNf0JgaVxc7LZeEkS6jaG0ib3voFLxY5ZiCwJG+uQM+mzuu0Q==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "8.0.2" + } + }, + "OpenTelemetry.Exporter.OpenTelemetryProtocol": { + "type": "CentralTransitive", + "requested": "[1.17.0, )", + "resolved": "1.17.0", + "contentHash": "R1omQOrQpGlS0Cp5UIr/TAiuEA48JrPlgr1NPV5gESiTU7HhWU+ILe2EBSYb1fKdsSavZ7nZkHcUxAzofPqr2A==", + "dependencies": { + "OpenTelemetry": "1.17.0" + } + }, + "OpenTelemetry.Extensions.Hosting": { + "type": "CentralTransitive", + "requested": "[1.17.0, )", + "resolved": "1.17.0", + "contentHash": "t1OwL/4qgboGMobYVT+UV5zgWnFqCp4Pw8lcsmzh8m2K8PQsTKkyxrC32tqYTMYny3GOW4q5cltE3dTVzLmRew==", + "dependencies": { + "Microsoft.Extensions.Hosting.Abstractions": "10.0.0", + "OpenTelemetry": "1.17.0" + } + } + } + } +} \ No newline at end of file