From 7ff86d2d6fd5ba479889cfa5a789f641ba434596 Mon Sep 17 00:00:00 2001 From: Copilot <223556219+Copilot@users.noreply.github.com> Date: Fri, 14 Aug 2026 09:12:15 -0500 Subject: [PATCH 1/2] Add MailDev and MailKit custom integration sample --- README.md | 1 + samples/maildev-mailkit/.gitignore | 3 + .../CSharpAppHost/CSharpAppHost.csproj | 18 + .../maildev-mailkit/CSharpAppHost/Program.cs | 13 + .../MailDev.Hosting.Tests.csproj | 20 + .../MailDevResourceTests.cs | 84 + .../MailDev.Hosting/MailDev.Hosting.csproj | 14 + .../MailDev.Hosting/MailDevResource.cs | 36 + .../MailDevResourceBuilderExtensions.cs | 56 + .../MailKit.Client.Tests.csproj | 21 + .../MailKitClientSettingsTests.cs | 43 + .../MailKitExtensionsTests.cs | 59 + .../MailKit.Client/MailKit.Client.csproj | 17 + .../MailKit.Client/MailKitClientFactory.cs | 57 + .../MailKit.Client/MailKitClientSettings.cs | 54 + .../MailKit.Client/MailKitExtensions.cs | 106 + .../MailKit.Client/MailKitHealthCheck.cs | 21 + .../MailKit.Client/Properties/AssemblyInfo.cs | 3 + .../NewsletterService.csproj | 20 + .../NewsletterService/Program.cs | 61 + .../Properties/launchSettings.json | 23 + samples/maildev-mailkit/README.md | 90 + .../ServiceDefaults/Extensions.cs | 67 + .../ServiceDefaults/ServiceDefaults.csproj | 24 + samples/maildev-mailkit/apphost.mts | 13 + samples/maildev-mailkit/aspire.config.json | 13 + samples/maildev-mailkit/eslint.config.mjs | 16 + samples/maildev-mailkit/package-lock.json | 2036 +++++++++++++++++ samples/maildev-mailkit/package.json | 26 + samples/maildev-mailkit/tsconfig.apphost.json | 15 + 30 files changed, 3030 insertions(+) create mode 100644 samples/maildev-mailkit/.gitignore create mode 100644 samples/maildev-mailkit/CSharpAppHost/CSharpAppHost.csproj create mode 100644 samples/maildev-mailkit/CSharpAppHost/Program.cs create mode 100644 samples/maildev-mailkit/MailDev.Hosting.Tests/MailDev.Hosting.Tests.csproj create mode 100644 samples/maildev-mailkit/MailDev.Hosting.Tests/MailDevResourceTests.cs create mode 100644 samples/maildev-mailkit/MailDev.Hosting/MailDev.Hosting.csproj create mode 100644 samples/maildev-mailkit/MailDev.Hosting/MailDevResource.cs create mode 100644 samples/maildev-mailkit/MailDev.Hosting/MailDevResourceBuilderExtensions.cs create mode 100644 samples/maildev-mailkit/MailKit.Client.Tests/MailKit.Client.Tests.csproj create mode 100644 samples/maildev-mailkit/MailKit.Client.Tests/MailKitClientSettingsTests.cs create mode 100644 samples/maildev-mailkit/MailKit.Client.Tests/MailKitExtensionsTests.cs create mode 100644 samples/maildev-mailkit/MailKit.Client/MailKit.Client.csproj create mode 100644 samples/maildev-mailkit/MailKit.Client/MailKitClientFactory.cs create mode 100644 samples/maildev-mailkit/MailKit.Client/MailKitClientSettings.cs create mode 100644 samples/maildev-mailkit/MailKit.Client/MailKitExtensions.cs create mode 100644 samples/maildev-mailkit/MailKit.Client/MailKitHealthCheck.cs create mode 100644 samples/maildev-mailkit/MailKit.Client/Properties/AssemblyInfo.cs create mode 100644 samples/maildev-mailkit/NewsletterService/NewsletterService.csproj create mode 100644 samples/maildev-mailkit/NewsletterService/Program.cs create mode 100644 samples/maildev-mailkit/NewsletterService/Properties/launchSettings.json create mode 100644 samples/maildev-mailkit/README.md create mode 100644 samples/maildev-mailkit/ServiceDefaults/Extensions.cs create mode 100644 samples/maildev-mailkit/ServiceDefaults/ServiceDefaults.csproj create mode 100644 samples/maildev-mailkit/apphost.mts create mode 100644 samples/maildev-mailkit/aspire.config.json create mode 100644 samples/maildev-mailkit/eslint.config.mjs create mode 100644 samples/maildev-mailkit/package-lock.json create mode 100644 samples/maildev-mailkit/package.json create mode 100644 samples/maildev-mailkit/tsconfig.apphost.json diff --git a/README.md b/README.md index c9b1edd2d..7e48e399e 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ Samples for [Aspire](https://aspire.dev). | Sample | Workload languages | AppHost | Deploy | Description | | --- | --- | --- | --- | --- | | [Integrating a Go App](./samples/container-build) | Go | C# AppHost | Docker Compose | Builds and runs a Go Gin app from a Dockerfile with Aspire. | +| [Custom MailDev and MailKit integrations](./samples/maildev-mailkit) | C#, TypeScript | TypeScript AppHost | Run only | Authors custom hosting and client integrations with ATS-generated TypeScript APIs. | | [Go API](./samples/golang-api) | Go | TypeScript AppHost | Docker Compose | Go + chi API with Aspire-managed run and publish flows. | | [Python FastAPI + PostgreSQL](./samples/python-fastapi-postgres) | Python | TypeScript AppHost | Docker Compose | FastAPI CRUD API wired to PostgreSQL and pgAdmin. | | [Python OpenAI Agent](./samples/python-openai-agent) | Python | TypeScript AppHost | Docker Compose | FastAPI AI agent sample with OpenAI integration. | diff --git a/samples/maildev-mailkit/.gitignore b/samples/maildev-mailkit/.gitignore new file mode 100644 index 000000000..da67b2f63 --- /dev/null +++ b/samples/maildev-mailkit/.gitignore @@ -0,0 +1,3 @@ +.aspire/ +**/bin/ +**/obj/ \ No newline at end of file diff --git a/samples/maildev-mailkit/CSharpAppHost/CSharpAppHost.csproj b/samples/maildev-mailkit/CSharpAppHost/CSharpAppHost.csproj new file mode 100644 index 000000000..fba2d2d75 --- /dev/null +++ b/samples/maildev-mailkit/CSharpAppHost/CSharpAppHost.csproj @@ -0,0 +1,18 @@ + + + + Exe + net10.0 + enable + enable + + + + + + + + + + + \ No newline at end of file diff --git a/samples/maildev-mailkit/CSharpAppHost/Program.cs b/samples/maildev-mailkit/CSharpAppHost/Program.cs new file mode 100644 index 000000000..5b7731590 --- /dev/null +++ b/samples/maildev-mailkit/CSharpAppHost/Program.cs @@ -0,0 +1,13 @@ +using Aspire.Hosting; + +var builder = DistributedApplication.CreateBuilder(args); + +var maildev = builder.AddMailDev("maildev"); + +builder.AddProject("newsletterservice", "../NewsletterService/NewsletterService.csproj") + .WithHttpHealthCheck("/health") + .WithExternalHttpEndpoints() + .WithReference(maildev) + .WaitFor(maildev); + +builder.Build().Run(); \ No newline at end of file diff --git a/samples/maildev-mailkit/MailDev.Hosting.Tests/MailDev.Hosting.Tests.csproj b/samples/maildev-mailkit/MailDev.Hosting.Tests/MailDev.Hosting.Tests.csproj new file mode 100644 index 000000000..e63689c3c --- /dev/null +++ b/samples/maildev-mailkit/MailDev.Hosting.Tests/MailDev.Hosting.Tests.csproj @@ -0,0 +1,20 @@ + + + + net10.0 + enable + enable + false + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/maildev-mailkit/MailDev.Hosting.Tests/MailDevResourceTests.cs b/samples/maildev-mailkit/MailDev.Hosting.Tests/MailDevResourceTests.cs new file mode 100644 index 000000000..02a0670e9 --- /dev/null +++ b/samples/maildev-mailkit/MailDev.Hosting.Tests/MailDevResourceTests.cs @@ -0,0 +1,84 @@ +using Aspire.Hosting; +using Aspire.Hosting.ApplicationModel; +using System.Reflection; +using Xunit; + +namespace MailDev.Hosting.Tests; + +public sealed class MailDevResourceTests +{ + [Fact] + public void MailDevHostingSurfaceIsExportedForAts() + { + var method = typeof(MailDevResourceBuilderExtensions).GetMethod( + nameof(MailDevResourceBuilderExtensions.AddMailDev), + BindingFlags.Public | BindingFlags.Static); + + Assert.NotNull(method); + Assert.Contains( + method.GetCustomAttributes(), + attribute => attribute.GetType().Name == "AspireExportAttribute"); + Assert.Contains( + typeof(MailDevResource).GetCustomAttributes(), + attribute => attribute.GetType().Name == "AspireExportAttribute"); + + var nameParameter = Assert.Single( + method.GetParameters(), + parameter => parameter.Name == "name"); + Assert.Contains( + nameParameter.GetCustomAttributes(), + attribute => attribute.GetType().Name == "ResourceNameAttribute"); + } + + [Fact] + public void AddMailDevConfiguresContainerAndEndpoints() + { + var builder = DistributedApplication.CreateBuilder(); + + var maildev = builder.AddMailDev("maildev"); + + var image = Assert.Single(maildev.Resource.Annotations.OfType()); + Assert.Equal("docker.io", image.Registry); + Assert.Equal("maildev/maildev", image.Image); + Assert.Equal("2.2.1", image.Tag); + + var endpoints = maildev.Resource.Annotations.OfType().ToArray(); + var http = Assert.Single(endpoints, endpoint => endpoint.Name == "http"); + var smtp = Assert.Single(endpoints, endpoint => endpoint.Name == "smtp"); + Assert.Equal(1080, http.TargetPort); + Assert.Equal(1025, smtp.TargetPort); + } + + [Fact] + public void AddMailDevCreatesSecretPasswordAndDeferredConnectionString() + { + var builder = DistributedApplication.CreateBuilder(); + + var maildev = builder.AddMailDev("maildev"); + + Assert.True(maildev.Resource.PasswordParameter.Secret); + Assert.Null(maildev.Resource.UsernameParameter); + Assert.Equal( + "Endpoint=smtp://{maildev.bindings.smtp.host}:{maildev.bindings.smtp.port};Username=mail-dev;Password={maildev-password.value}", + maildev.Resource.ConnectionStringExpression.ValueExpression); + } + + [Fact] + public void AddMailDevUsesProvidedCredentialParameters() + { + var builder = DistributedApplication.CreateBuilder(); + var username = builder.AddParameter("smtp-user"); + var password = builder.AddParameter("smtp-password", secret: true); + + var maildev = builder.AddMailDev( + "maildev", + username: username, + password: password); + + Assert.Same(username.Resource, maildev.Resource.UsernameParameter); + Assert.Same(password.Resource, maildev.Resource.PasswordParameter); + Assert.Equal( + "Endpoint=smtp://{maildev.bindings.smtp.host}:{maildev.bindings.smtp.port};Username={smtp-user.value};Password={smtp-password.value}", + maildev.Resource.ConnectionStringExpression.ValueExpression); + } +} \ No newline at end of file diff --git a/samples/maildev-mailkit/MailDev.Hosting/MailDev.Hosting.csproj b/samples/maildev-mailkit/MailDev.Hosting/MailDev.Hosting.csproj new file mode 100644 index 000000000..cf75a679f --- /dev/null +++ b/samples/maildev-mailkit/MailDev.Hosting/MailDev.Hosting.csproj @@ -0,0 +1,14 @@ + + + + net10.0 + enable + enable + true + + + + + + + \ No newline at end of file diff --git a/samples/maildev-mailkit/MailDev.Hosting/MailDevResource.cs b/samples/maildev-mailkit/MailDev.Hosting/MailDevResource.cs new file mode 100644 index 000000000..246e6bc4b --- /dev/null +++ b/samples/maildev-mailkit/MailDev.Hosting/MailDevResource.cs @@ -0,0 +1,36 @@ +namespace Aspire.Hosting.ApplicationModel; + +/// Represents a MailDev container resource. +[AspireExport] +public sealed class MailDevResource( + [ResourceName] string name, + ParameterResource? username, + ParameterResource password) + : ContainerResource(name), IResourceWithConnectionString +{ + internal const string HttpEndpointName = "http"; + internal const string SmtpEndpointName = "smtp"; + + private const string DefaultUsername = "mail-dev"; + private EndpointReference? _smtpEndpoint; + + /// Gets the optional MailDev SMTP username parameter. + public ParameterResource? UsernameParameter { get; } = username; + + /// Gets the MailDev SMTP password parameter. + public ParameterResource PasswordParameter { get; } = password; + + internal ReferenceExpression UsernameReference => + UsernameParameter is not null + ? ReferenceExpression.Create($"{UsernameParameter}") + : ReferenceExpression.Create($"{DefaultUsername}"); + + /// Gets the MailDev SMTP endpoint. + public EndpointReference SmtpEndpoint => + _smtpEndpoint ??= new(this, SmtpEndpointName); + + /// + public ReferenceExpression ConnectionStringExpression => + ReferenceExpression.Create( + $"Endpoint=smtp://{SmtpEndpoint.Property(EndpointProperty.HostAndPort)};Username={UsernameReference};Password={PasswordParameter}"); +} \ No newline at end of file diff --git a/samples/maildev-mailkit/MailDev.Hosting/MailDevResourceBuilderExtensions.cs b/samples/maildev-mailkit/MailDev.Hosting/MailDevResourceBuilderExtensions.cs new file mode 100644 index 000000000..3b934df54 --- /dev/null +++ b/samples/maildev-mailkit/MailDev.Hosting/MailDevResourceBuilderExtensions.cs @@ -0,0 +1,56 @@ +using Aspire.Hosting.ApplicationModel; + +namespace Aspire.Hosting; + +/// Provides extension methods for adding MailDev resources. +public static class MailDevResourceBuilderExtensions +{ + private const string Registry = "docker.io"; + private const string Image = "maildev/maildev"; + private const string Tag = "2.2.1"; + private const string UsernameEnvironmentVariable = "MAILDEV_INCOMING_USER"; + private const string PasswordEnvironmentVariable = "MAILDEV_INCOMING_PASS"; + + /// Adds a MailDev container resource. + /// The distributed application builder. + /// The resource name. + /// The optional host port for the MailDev web interface. + /// The optional host port for SMTP. + /// The optional SMTP username parameter. + /// The optional SMTP password parameter. + /// The MailDev resource builder. + [AspireExport] + public static IResourceBuilder AddMailDev( + this IDistributedApplicationBuilder builder, + [ResourceName] string name, + int? httpPort = null, + int? smtpPort = null, + IResourceBuilder? username = null, + IResourceBuilder? password = null) + { + ArgumentNullException.ThrowIfNull(builder); + + var passwordParameter = password?.Resource ?? + ParameterResourceBuilderExtensions.CreateDefaultPasswordParameter( + builder, $"{name}-password"); + var resource = new MailDevResource(name, username?.Resource, passwordParameter); + + return builder.AddResource(resource) + .WithImage(Image) + .WithImageRegistry(Registry) + .WithImageTag(Tag) + .WithHttpEndpoint( + targetPort: 1080, + port: httpPort, + name: MailDevResource.HttpEndpointName) + .WithEndpoint( + targetPort: 1025, + port: smtpPort, + name: MailDevResource.SmtpEndpointName) + .WithEnvironment(context => + { + context.EnvironmentVariables[UsernameEnvironmentVariable] = resource.UsernameReference; + context.EnvironmentVariables[PasswordEnvironmentVariable] = resource.PasswordParameter; + }); + } +} \ No newline at end of file diff --git a/samples/maildev-mailkit/MailKit.Client.Tests/MailKit.Client.Tests.csproj b/samples/maildev-mailkit/MailKit.Client.Tests/MailKit.Client.Tests.csproj new file mode 100644 index 000000000..bac29a321 --- /dev/null +++ b/samples/maildev-mailkit/MailKit.Client.Tests/MailKit.Client.Tests.csproj @@ -0,0 +1,21 @@ + + + + net10.0 + enable + enable + false + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/maildev-mailkit/MailKit.Client.Tests/MailKitClientSettingsTests.cs b/samples/maildev-mailkit/MailKit.Client.Tests/MailKitClientSettingsTests.cs new file mode 100644 index 000000000..ff3f08521 --- /dev/null +++ b/samples/maildev-mailkit/MailKit.Client.Tests/MailKitClientSettingsTests.cs @@ -0,0 +1,43 @@ +using MailKit.Client; +using Xunit; + +namespace MailKit.Client.Tests; + +public sealed class MailKitClientSettingsTests +{ + [Fact] + public void ParseConnectionStringAcceptsUri() + { + var settings = new MailKitClientSettings(); + + settings.ParseConnectionString("smtp://localhost:1025"); + + Assert.Equal(new Uri("smtp://localhost:1025"), settings.Endpoint); + Assert.Null(settings.Credentials); + } + + [Fact] + public void ParseConnectionStringAcceptsEndpointAndCredentials() + { + var settings = new MailKitClientSettings(); + + settings.ParseConnectionString( + "Endpoint=smtp://localhost:1025;Username=mail-dev;Password=secret"); + + Assert.Equal(new Uri("smtp://localhost:1025"), settings.Endpoint); + Assert.Equal("mail-dev", settings.Credentials?.UserName); + Assert.Equal("secret", settings.Credentials?.Password); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("Host=localhost")] + public void ParseConnectionStringRejectsMissingEndpoint(string? connectionString) + { + var settings = new MailKitClientSettings(); + + Assert.Throws( + () => settings.ParseConnectionString(connectionString)); + } +} \ No newline at end of file diff --git a/samples/maildev-mailkit/MailKit.Client.Tests/MailKitExtensionsTests.cs b/samples/maildev-mailkit/MailKit.Client.Tests/MailKitExtensionsTests.cs new file mode 100644 index 000000000..35de9e247 --- /dev/null +++ b/samples/maildev-mailkit/MailKit.Client.Tests/MailKitExtensionsTests.cs @@ -0,0 +1,59 @@ +using MailKit.Client; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using Microsoft.Extensions.Hosting; +using Xunit; + +namespace MailKit.Client.Tests; + +public sealed class MailKitExtensionsTests +{ + [Fact] + public void AddMailKitClientRegistersOneFactoryPerScope() + { + var builder = Host.CreateApplicationBuilder(); + builder.Configuration["ConnectionStrings:maildev"] = "smtp://localhost:1025"; + builder.AddMailKitClient("maildev"); + using var provider = builder.Services.BuildServiceProvider(); + + using var firstScope = provider.CreateScope(); + using var secondScope = provider.CreateScope(); + + var first = firstScope.ServiceProvider.GetRequiredService(); + Assert.Same(first, firstScope.ServiceProvider.GetRequiredService()); + Assert.NotSame(first, secondScope.ServiceProvider.GetRequiredService()); + Assert.NotNull(provider.GetRequiredService()); + } + + [Fact] + public void AddKeyedMailKitClientRegistersNamedFactory() + { + var builder = Host.CreateApplicationBuilder(); + builder.Configuration["ConnectionStrings:transactional"] = "smtp://localhost:1025"; + builder.AddKeyedMailKitClient("transactional"); + using var provider = builder.Services.BuildServiceProvider(); + using var scope = provider.CreateScope(); + + Assert.NotNull( + scope.ServiceProvider.GetRequiredKeyedService("transactional")); + Assert.Null(scope.ServiceProvider.GetService()); + } + + [Fact] + public void FactoryValidationIsDeferredUntilResolution() + { + var builder = Host.CreateApplicationBuilder(); + + builder.AddMailKitClient("maildev", settings => + { + settings.DisableHealthChecks = true; + settings.DisableTracing = true; + settings.DisableMetrics = true; + }); + + using var provider = builder.Services.BuildServiceProvider(); + using var scope = provider.CreateScope(); + Assert.Throws( + scope.ServiceProvider.GetRequiredService); + } +} \ No newline at end of file diff --git a/samples/maildev-mailkit/MailKit.Client/MailKit.Client.csproj b/samples/maildev-mailkit/MailKit.Client/MailKit.Client.csproj new file mode 100644 index 000000000..3d27f28e3 --- /dev/null +++ b/samples/maildev-mailkit/MailKit.Client/MailKit.Client.csproj @@ -0,0 +1,17 @@ + + + + net10.0 + enable + enable + + + + + + + + + + + \ No newline at end of file diff --git a/samples/maildev-mailkit/MailKit.Client/MailKitClientFactory.cs b/samples/maildev-mailkit/MailKit.Client/MailKitClientFactory.cs new file mode 100644 index 000000000..2df0b1936 --- /dev/null +++ b/samples/maildev-mailkit/MailKit.Client/MailKitClientFactory.cs @@ -0,0 +1,57 @@ +using MailKit.Net.Smtp; + +namespace MailKit.Client; + +/// Creates and reuses a connected SMTP client for the current scope. +public sealed class MailKitClientFactory(MailKitClientSettings settings) : IDisposable +{ + private readonly SemaphoreSlim _semaphore = new(1, 1); + private SmtpClient? _client; + + /// Gets a connected and, when configured, authenticated SMTP client. + public async Task GetSmtpClientAsync( + CancellationToken cancellationToken = default) + { + await _semaphore.WaitAsync(cancellationToken).ConfigureAwait(false); + try + { + if (_client is not null) + { + return _client; + } + + var endpoint = settings.Endpoint ?? + throw new InvalidOperationException("The MailKit SMTP endpoint is not configured."); + var client = new SmtpClient(); + + try + { + await client.ConnectAsync(endpoint, cancellationToken).ConfigureAwait(false); + if (settings.Credentials is not null) + { + await client.AuthenticateAsync(settings.Credentials, cancellationToken) + .ConfigureAwait(false); + } + + _client = client; + return client; + } + catch + { + client.Dispose(); + throw; + } + } + finally + { + _semaphore.Release(); + } + } + + /// + public void Dispose() + { + _client?.Dispose(); + _semaphore.Dispose(); + } +} \ No newline at end of file diff --git a/samples/maildev-mailkit/MailKit.Client/MailKitClientSettings.cs b/samples/maildev-mailkit/MailKit.Client/MailKitClientSettings.cs new file mode 100644 index 000000000..bc4923e77 --- /dev/null +++ b/samples/maildev-mailkit/MailKit.Client/MailKitClientSettings.cs @@ -0,0 +1,54 @@ +using System.Data.Common; +using System.Net; + +namespace MailKit.Client; + +/// Provides settings for connecting a MailKit SMTP client. +public sealed class MailKitClientSettings +{ + internal const string DefaultConfigSectionName = "MailKit:Client"; + + /// Gets or sets the SMTP endpoint. + public Uri? Endpoint { get; set; } + + /// Gets or sets optional SMTP credentials. + public NetworkCredential? Credentials { get; set; } + + /// Gets or sets whether health checks are disabled. + public bool DisableHealthChecks { get; set; } + + /// Gets or sets whether tracing is disabled. + public bool DisableTracing { get; set; } + + /// Gets or sets whether metrics are disabled. + public bool DisableMetrics { get; set; } + + internal void ParseConnectionString(string? connectionString) + { + if (string.IsNullOrWhiteSpace(connectionString)) + { + throw new InvalidOperationException( + $"A connection string must be provided through ConnectionStrings: or {DefaultConfigSectionName}:Endpoint."); + } + + if (Uri.TryCreate(connectionString, UriKind.Absolute, out var uri)) + { + Endpoint = uri; + return; + } + + var values = new DbConnectionStringBuilder { ConnectionString = connectionString }; + if (!values.TryGetValue("Endpoint", out var endpoint) || + !Uri.TryCreate(endpoint?.ToString(), UriKind.Absolute, out uri)) + { + throw new InvalidOperationException("The SMTP connection string must contain a valid Endpoint value."); + } + + Endpoint = uri; + if (values.TryGetValue("Username", out var username) && + values.TryGetValue("Password", out var password)) + { + Credentials = new NetworkCredential(username?.ToString(), password?.ToString()); + } + } +} \ No newline at end of file diff --git a/samples/maildev-mailkit/MailKit.Client/MailKitExtensions.cs b/samples/maildev-mailkit/MailKit.Client/MailKitExtensions.cs new file mode 100644 index 000000000..7c657c60f --- /dev/null +++ b/samples/maildev-mailkit/MailKit.Client/MailKitExtensions.cs @@ -0,0 +1,106 @@ +using MailKit.Client; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; + +namespace Microsoft.Extensions.Hosting; + +/// Provides MailKit client registration extensions. +public static class MailKitExtensions +{ + /// Registers a scoped MailKit SMTP client factory. + public static void AddMailKitClient( + this IHostApplicationBuilder builder, + string connectionName, + Action? configureSettings = null) => + AddMailKitClient( + builder, + MailKitClientSettings.DefaultConfigSectionName, + connectionName, + serviceKey: null, + configureSettings); + + /// Registers a keyed scoped MailKit SMTP client factory. + public static void AddKeyedMailKitClient( + this IHostApplicationBuilder builder, + string name, + Action? configureSettings = null) + { + ArgumentException.ThrowIfNullOrWhiteSpace(name); + AddMailKitClient( + builder, + $"{MailKitClientSettings.DefaultConfigSectionName}:{name}", + name, + name, + configureSettings); + } + + private static void AddMailKitClient( + IHostApplicationBuilder builder, + string configurationSectionName, + string connectionName, + object? serviceKey, + Action? configureSettings) + { + ArgumentNullException.ThrowIfNull(builder); + ArgumentException.ThrowIfNullOrWhiteSpace(connectionName); + + var settings = new MailKitClientSettings(); + builder.Configuration.GetSection(configurationSectionName).Bind(settings); + + if (builder.Configuration.GetConnectionString(connectionName) is { } connectionString) + { + settings.ParseConnectionString(connectionString); + } + + configureSettings?.Invoke(settings); + + if (serviceKey is null) + { + builder.Services.AddScoped(_ => CreateFactory(settings)); + } + else + { + builder.Services.AddKeyedScoped( + serviceKey, + (_, _) => CreateFactory(settings)); + } + + if (!settings.DisableHealthChecks) + { + builder.Services.AddHealthChecks().Add(new HealthCheckRegistration( + serviceKey is null ? "MailKit" : $"MailKit_{connectionName}", + serviceProvider => new MailKitHealthCheck( + serviceKey is null + ? serviceProvider.GetRequiredService() + : serviceProvider.GetRequiredKeyedService(serviceKey)), + failureStatus: null, + tags: [])); + } + + if (!settings.DisableTracing) + { + builder.Services.AddOpenTelemetry() + .WithTracing(tracing => tracing.AddSource(MailKit.Telemetry.SmtpClient.ActivitySourceName)); + } + + if (!settings.DisableMetrics) + { + MailKit.Telemetry.SmtpClient.Configure(); + builder.Services.AddOpenTelemetry() + .WithMetrics(metrics => metrics.AddMeter(MailKit.Telemetry.SmtpClient.MeterName)); + } + } + + private static MailKitClientFactory CreateFactory(MailKitClientSettings settings) + { + if (settings.Endpoint is null) + { + throw new InvalidOperationException("The MailKit SMTP endpoint is not configured."); + } + + return new MailKitClientFactory(settings); + } +} \ No newline at end of file diff --git a/samples/maildev-mailkit/MailKit.Client/MailKitHealthCheck.cs b/samples/maildev-mailkit/MailKit.Client/MailKitHealthCheck.cs new file mode 100644 index 000000000..bfc2327d2 --- /dev/null +++ b/samples/maildev-mailkit/MailKit.Client/MailKitHealthCheck.cs @@ -0,0 +1,21 @@ +using Microsoft.Extensions.Diagnostics.HealthChecks; + +namespace MailKit.Client; + +internal sealed class MailKitHealthCheck(MailKitClientFactory factory) : IHealthCheck +{ + public async Task CheckHealthAsync( + HealthCheckContext context, + CancellationToken cancellationToken = default) + { + try + { + _ = await factory.GetSmtpClientAsync(cancellationToken).ConfigureAwait(false); + return HealthCheckResult.Healthy(); + } + catch (Exception exception) + { + return HealthCheckResult.Unhealthy(exception: exception); + } + } +} \ No newline at end of file diff --git a/samples/maildev-mailkit/MailKit.Client/Properties/AssemblyInfo.cs b/samples/maildev-mailkit/MailKit.Client/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..11e4e3f8b --- /dev/null +++ b/samples/maildev-mailkit/MailKit.Client/Properties/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("MailKit.Client.Tests")] \ No newline at end of file diff --git a/samples/maildev-mailkit/NewsletterService/NewsletterService.csproj b/samples/maildev-mailkit/NewsletterService/NewsletterService.csproj new file mode 100644 index 000000000..58879a439 --- /dev/null +++ b/samples/maildev-mailkit/NewsletterService/NewsletterService.csproj @@ -0,0 +1,20 @@ + + + + net10.0 + enable + enable + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/maildev-mailkit/NewsletterService/Program.cs b/samples/maildev-mailkit/NewsletterService/Program.cs new file mode 100644 index 000000000..dcf93e109 --- /dev/null +++ b/samples/maildev-mailkit/NewsletterService/Program.cs @@ -0,0 +1,61 @@ +using MailKit.Client; +using MimeKit; +using Scalar.AspNetCore; + +var builder = WebApplication.CreateBuilder(args); + +builder.AddServiceDefaults(); +builder.AddMailKitClient("maildev"); +builder.Services.AddOpenApi(); + +var app = builder.Build(); + +app.MapOpenApi(); +app.MapScalarApiReference(); +app.MapDefaultEndpoints(); + +app.MapPost("/subscribe", async ( + SubscriptionRequest request, + MailKitClientFactory mailKit, + CancellationToken cancellationToken) => +{ + var message = CreateMessage( + request.Email, + "Welcome to the Aspire newsletter", + "You are now subscribed to the Aspire newsletter."); + var client = await mailKit.GetSmtpClientAsync(cancellationToken); + await client.SendAsync(message, cancellationToken); + + return Results.Accepted(value: new { request.Email, Status = "subscribed" }); +}) +.WithName("Subscribe"); + +app.MapPost("/unsubscribe", async ( + SubscriptionRequest request, + MailKitClientFactory mailKit, + CancellationToken cancellationToken) => +{ + var message = CreateMessage( + request.Email, + "Aspire newsletter subscription ended", + "You have been unsubscribed from the Aspire newsletter."); + var client = await mailKit.GetSmtpClientAsync(cancellationToken); + await client.SendAsync(message, cancellationToken); + + return Results.Ok(new { request.Email, Status = "unsubscribed" }); +}) +.WithName("Unsubscribe"); + +app.Run(); + +static MimeMessage CreateMessage(string email, string subject, string body) +{ + var message = new MimeMessage(); + message.From.Add(new MailboxAddress("Aspire Newsletter", "newsletter@example.com")); + message.To.Add(MailboxAddress.Parse(email)); + message.Subject = subject; + message.Body = new TextPart("plain") { Text = body }; + return message; +} + +internal sealed record SubscriptionRequest(string Email); \ No newline at end of file diff --git a/samples/maildev-mailkit/NewsletterService/Properties/launchSettings.json b/samples/maildev-mailkit/NewsletterService/Properties/launchSettings.json new file mode 100644 index 000000000..a7c26e31f --- /dev/null +++ b/samples/maildev-mailkit/NewsletterService/Properties/launchSettings.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "http://localhost:5274", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "https://localhost:7274;http://localhost:5274", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/samples/maildev-mailkit/README.md b/samples/maildev-mailkit/README.md new file mode 100644 index 000000000..3efc90aef --- /dev/null +++ b/samples/maildev-mailkit/README.md @@ -0,0 +1,90 @@ +# MailDev and MailKit custom integrations + +This sample demonstrates how to build custom .NET Aspire hosting and client integrations with Aspire 13.5. The runnable AppHost is written in TypeScript and consumes the C# hosting integration through the Aspire Type System (ATS). + +## Projects + +- `MailDev.Hosting` models a MailDev container, its web and SMTP endpoints, and a deferred connection string. +- `MailKit.Client` registers a scoped MailKit SMTP client, health checks, tracing, and metrics in a consuming service. +- `NewsletterService` sends subscription and unsubscription messages through the integrations. +- `ServiceDefaults` configures standard Aspire health checks and OpenTelemetry. +- `CSharpAppHost` is a compile-validated C# equivalent of the runnable TypeScript AppHost. + +## Aspire Type System + +The hosting integration marks `MailDevResource` and `AddMailDev` with `[AspireExport]`. The local project reference in `aspire.config.json` lets `aspire restore` inspect those exports and generate the TypeScript `addMailDev` API under `.aspire/modules`. + +Generated files under `.aspire/modules` are not source files and must not be edited or committed. + +```json +"packages": { + "MailDev.Hosting": "MailDev.Hosting/MailDev.Hosting.csproj" +} +``` + +The TypeScript AppHost uses the generated API: + +```typescript +const maildev = await builder.addMailDev("maildev"); + +await builder.addCSharpApp("newsletterservice", "./NewsletterService") + .withHttpHealthCheck({ path: "/health" }) + .withExternalHttpEndpoints() + .withReference(maildev) + .waitFor(maildev); +``` + +The equivalent C# AppHost code is: + +```csharp +var maildev = builder.AddMailDev("maildev"); + +builder.AddProject("newsletterservice", "../NewsletterService/NewsletterService.csproj") + .WithHttpHealthCheck("/health") + .WithExternalHttpEndpoints() + .WithReference(maildev) + .WaitFor(maildev); +``` + +## Secure credentials + +`AddMailDev` creates a secret password parameter by default. The password is passed to MailDev through `MAILDEV_INCOMING_PASS` and to the newsletter service through a deferred connection string: + +```text +Endpoint=smtp://{maildev.bindings.smtp.host}:{maildev.bindings.smtp.port};Username=mail-dev;Password={maildev-password.value} +``` + +The AppHost model retains parameter and endpoint references instead of embedding a password or allocated port in source code. MailKit parses the resolved connection string, connects to SMTP, and authenticates for each service scope. + +## Run the sample + +Prerequisites are .NET 10, Node.js 24 or a supported Node.js 20/22 release, Docker, and Aspire CLI 13.5. + +```powershell +aspire update --self --channel staging +aspire restore +npm install +npm run aspire:build +aspire run +``` + +Use the newsletter service endpoint shown in the Aspire dashboard: + +```http +POST /subscribe +Content-Type: application/json + +{ "email": "reader@example.com" } +``` + +Open the MailDev web endpoint from the dashboard to inspect the generated message. Use `POST /unsubscribe` with the same payload to send the unsubscription message. + +## Tests + +```powershell +dotnet test MailDev.Hosting.Tests/MailDev.Hosting.Tests.csproj +dotnet test MailKit.Client.Tests/MailKit.Client.Tests.csproj +npm run aspire:build +npm run aspire:lint +dotnet build CSharpAppHost/CSharpAppHost.csproj +``` \ No newline at end of file diff --git a/samples/maildev-mailkit/ServiceDefaults/Extensions.cs b/samples/maildev-mailkit/ServiceDefaults/Extensions.cs new file mode 100644 index 000000000..771bf0b37 --- /dev/null +++ b/samples/maildev-mailkit/ServiceDefaults/Extensions.cs @@ -0,0 +1,67 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Diagnostics.HealthChecks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using Microsoft.Extensions.Logging; +using OpenTelemetry; +using OpenTelemetry.Logs; +using OpenTelemetry.Metrics; +using OpenTelemetry.Trace; + +namespace Microsoft.Extensions.Hosting; + +public static class Extensions +{ + private const string HealthEndpointPath = "/health"; + private const string AlivenessEndpointPath = "/alive"; + + public static TBuilder AddServiceDefaults(this TBuilder builder) + where TBuilder : IHostApplicationBuilder + { + builder.Logging.AddOpenTelemetry(logging => + { + logging.IncludeFormattedMessage = true; + logging.IncludeScopes = true; + }); + + builder.Services.AddOpenTelemetry() + .WithMetrics(metrics => metrics + .AddAspNetCoreInstrumentation() + .AddHttpClientInstrumentation() + .AddRuntimeInstrumentation()) + .WithTracing(tracing => tracing + .AddSource(builder.Environment.ApplicationName) + .AddAspNetCoreInstrumentation(options => + options.Filter = context => + !context.Request.Path.StartsWithSegments(HealthEndpointPath) && + !context.Request.Path.StartsWithSegments(AlivenessEndpointPath)) + .AddHttpClientInstrumentation()); + + if (!string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"])) + { + builder.Services.AddOpenTelemetry().UseOtlpExporter(); + } + + builder.Services.AddHealthChecks() + .AddCheck("self", () => HealthCheckResult.Healthy(), ["live"]); + builder.Services.AddServiceDiscovery(); + builder.Services.ConfigureHttpClientDefaults(http => + { + http.AddStandardResilienceHandler(); + http.AddServiceDiscovery(); + }); + + return builder; + } + + public static WebApplication MapDefaultEndpoints(this WebApplication app) + { + app.MapHealthChecks(HealthEndpointPath); + app.MapHealthChecks(AlivenessEndpointPath, new HealthCheckOptions + { + Predicate = check => check.Tags.Contains("live") + }); + + return app; + } +} \ No newline at end of file diff --git a/samples/maildev-mailkit/ServiceDefaults/ServiceDefaults.csproj b/samples/maildev-mailkit/ServiceDefaults/ServiceDefaults.csproj new file mode 100644 index 000000000..f3f1bcf36 --- /dev/null +++ b/samples/maildev-mailkit/ServiceDefaults/ServiceDefaults.csproj @@ -0,0 +1,24 @@ + + + + net10.0 + enable + enable + false + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/maildev-mailkit/apphost.mts b/samples/maildev-mailkit/apphost.mts new file mode 100644 index 000000000..a44a25295 --- /dev/null +++ b/samples/maildev-mailkit/apphost.mts @@ -0,0 +1,13 @@ +import { createBuilder } from "./.aspire/modules/aspire.mjs"; + +const builder = await createBuilder(); + +const maildev = await builder.addMailDev("maildev"); + +await builder.addCSharpApp("newsletterservice", "./NewsletterService") + .withHttpHealthCheck({ path: "/health" }) + .withExternalHttpEndpoints() + .withReference(maildev) + .waitFor(maildev); + +await builder.build().run(); \ No newline at end of file diff --git a/samples/maildev-mailkit/aspire.config.json b/samples/maildev-mailkit/aspire.config.json new file mode 100644 index 000000000..415ba6d49 --- /dev/null +++ b/samples/maildev-mailkit/aspire.config.json @@ -0,0 +1,13 @@ +{ + "appHost": { + "path": "apphost.mts", + "language": "typescript/nodejs" + }, + "sdk": { + "version": "13.5.0" + }, + "channel": "staging", + "packages": { + "MailDev.Hosting": "MailDev.Hosting/MailDev.Hosting.csproj" + } +} \ No newline at end of file diff --git a/samples/maildev-mailkit/eslint.config.mjs b/samples/maildev-mailkit/eslint.config.mjs new file mode 100644 index 000000000..60b180dcf --- /dev/null +++ b/samples/maildev-mailkit/eslint.config.mjs @@ -0,0 +1,16 @@ +import { defineConfig } from "eslint/config"; +import tseslint from "typescript-eslint"; + +export default defineConfig({ + files: ["apphost.mts"], + extends: [tseslint.configs.base], + languageOptions: { + parserOptions: { + project: "./tsconfig.apphost.json", + tsconfigRootDir: import.meta.dirname + } + }, + rules: { + "@typescript-eslint/no-floating-promises": ["error", { checkThenables: true }] + } +}); \ No newline at end of file diff --git a/samples/maildev-mailkit/package-lock.json b/samples/maildev-mailkit/package-lock.json new file mode 100644 index 000000000..970958860 --- /dev/null +++ b/samples/maildev-mailkit/package-lock.json @@ -0,0 +1,2036 @@ +{ + "name": "aspire-maildev-apphost", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "aspire-maildev-apphost", + "version": "1.0.0", + "dependencies": { + "vscode-jsonrpc": "^8.2.1" + }, + "devDependencies": { + "@types/node": "^25.8.0", + "eslint": "^10.3.0", + "nodemon": "^3.1.14", + "tsx": "^4.22.0", + "typescript": "^6.0.3", + "typescript-eslint": "^8.59.3" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.1", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha1-egGo0uwvuy2seK2tCbD6eB5Agr4=", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.1", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha1-cEvSl95tdi3lTqu+r79V9nVqvi8=", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.1", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha1-tUCifRTkr9BYSWpNvsTT9BTbEQo=", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.1", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha1-0csWbTSw+/D+irRgpVlPJKN4cB4=", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.1", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha1-EDSyZFf8iGNo/mG70J9lP2r6jlQ=", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.1", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha1-ZVVqQyoeTXIDLYIYwZMvzKGkl3I=", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.1", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha1-LmHgWS+QMNfj2uGO4l68U1kYrvY=", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.1", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha1-yV7CiZWe+AecTcqBeh4sS+Zrm9M=", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.1", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha1-wJoPZ5F1kqwN6JKpvk04FN69Kmw=", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.1", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha1-QLIhdd2gYYLz7oFBGGxf8wTEpxc=", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.1", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha1-pYD5xnZ5eDOJHlGfx6EzfIr9jbM=", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.1", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha1-RkUs8yHcf56Rwvp4Cla7Vuec1os=", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.1", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha1-QhGzGE3WYI9T3LIuOfXTTuCIUsg=", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.1", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha1-aXhXwqYcubC2u2ZS5AwdxeHKjl0=", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.1", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha1-0ZKUPrFGpArExkl9DPe+NbmGvwg=", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.1", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha1-rOoDVtoODrwI+Xz3ucLkAeHmSNw=", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.1", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha1-bww84MtkxTS3DExF7LLBbTTjXf0=", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.1", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha1-i813B3oNzjN4tXT+2ybSolO3PTY=", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.1", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha1-5/sqAemcgwyU5mI82f77TI+1g0c=", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.1", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha1-xSkJNy24uG4sVeBaiUADO1Zgo7I=", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.1", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha1-xCe5vlpkwmL/mn63C1+7qt9EbGw=", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.1", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha1-3JsUe6yi5sSzyFVxdB70hgpIkJc=", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.1", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha1-zoZtEt8TwV5MmfBzo9Rm9uBkmzo=", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.1", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha1-dGjjaS0B1inVlB5dg4F7uA+eObQ=", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.1", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha1-pbwAY/sryrbQ7WPyoVN5WLwmnsY=", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.1", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha1-EAZO5E9DR7kMmgK0Rrv4CpFjKxI=", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.10.1", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", + "integrity": "sha1-iRG9crLDZApUNgngQAuMTS5+fLY=", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha1-DNcv6FUOPC6uFWqWpN3c0cisWAA=", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha1-vM32Fbz3tujbgw7AuNIcmiXeWXs=", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.5", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint/config-array/-/config-array-0.23.5.tgz", + "integrity": "sha1-VuhtJDBJGV2KzAwGobPf3D+j3pU=", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.5", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.7.0", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint/config-helpers/-/config-helpers-0.7.0.tgz", + "integrity": "sha1-Ce5KoHtz8FnsLUx0v0sv8CsyI3c=", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.2.1", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint/core/-/core-1.2.1.tgz", + "integrity": "sha1-wdp80bgvqHh/mLVin7gRhIobY84=", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.5", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint/object-schema/-/object-schema-3.0.5.tgz", + "integrity": "sha1-iOm/TRHSsZwILnjr586IckpesJE=", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.7.2", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz", + "integrity": "sha1-Swli8/LHzovJiz7P40UlwJ0styk=", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha1-qCcsoDsqz0kmcCIrIyC2xCG/3mA=", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha1-j4AMzME/T4zTEW4tnAqUk52j4+0=", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha1-8qCfYgEjkLK/8/xvskjd7IwJoJA=", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha1-r1smkaIrRL6EewyoFkHF+2rQFyw=", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha1-wrnS43TuYsWG062+qHGZsdenpro=", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha1-b2Nq+WL75hkbgwvWdrpZhpJrzOw=", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha1-zz8Oh2177hWpOrkluCv1cKOQSiQ=", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha1-WWoXRyM2lNUPatinhp/Lb1bPWEE=", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "25.9.5", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/node/-/node-25.9.5.tgz", + "integrity": "sha1-D+/Anm6C6UzeKRus9DUi6YnrAaQ=", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": ">=7.24.0 <7.24.7" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.66.0", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.66.0.tgz", + "integrity": "sha1-duhqpaJFn79bvXqDnA3AzOHVYiQ=", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.66.0", + "@typescript-eslint/type-utils": "8.66.0", + "@typescript-eslint/utils": "8.66.0", + "@typescript-eslint/visitor-keys": "8.66.0", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.66.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.6", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ignore/-/ignore-7.0.6.tgz", + "integrity": "sha1-aleq70yQ3yesNZCHXSno8RmIyI4=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.66.0", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/parser/-/parser-8.66.0.tgz", + "integrity": "sha1-iOOGXs9zsBGBNOfLgx2oepYaV6E=", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.66.0", + "@typescript-eslint/types": "8.66.0", + "@typescript-eslint/typescript-estree": "8.66.0", + "@typescript-eslint/visitor-keys": "8.66.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.66.0", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/project-service/-/project-service-8.66.0.tgz", + "integrity": "sha1-go94iJXfUtnrK1Q0RaOloT41q04=", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.66.0", + "@typescript-eslint/types": "^8.66.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.66.0", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/scope-manager/-/scope-manager-8.66.0.tgz", + "integrity": "sha1-T//Mbr0N+f55g8AlaWdWfqb1rGM=", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.66.0", + "@typescript-eslint/visitor-keys": "8.66.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.66.0", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.66.0.tgz", + "integrity": "sha1-OokGbFB6owVB3BdoBGhbS0ROHlI=", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.66.0", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/type-utils/-/type-utils-8.66.0.tgz", + "integrity": "sha1-sjFTA+ynL62a+nvk9Y8FPI8qBHk=", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.66.0", + "@typescript-eslint/typescript-estree": "8.66.0", + "@typescript-eslint/utils": "8.66.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.66.0", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/types/-/types-8.66.0.tgz", + "integrity": "sha1-PKyrlNO1ZMHUjFbrN7ifiabUhHk=", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.66.0", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/typescript-estree/-/typescript-estree-8.66.0.tgz", + "integrity": "sha1-GjjDqX3Gxmm2bVhdf5DrxPuzKlA=", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.66.0", + "@typescript-eslint/tsconfig-utils": "8.66.0", + "@typescript-eslint/types": "8.66.0", + "@typescript-eslint/visitor-keys": "8.66.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.66.0", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/utils/-/utils-8.66.0.tgz", + "integrity": "sha1-4nfWdCcEPNyiWA7pGqYpIeRomWk=", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.66.0", + "@typescript-eslint/types": "8.66.0", + "@typescript-eslint/typescript-estree": "8.66.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.66.0", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/visitor-keys/-/visitor-keys-8.66.0.tgz", + "integrity": "sha1-TElOlHRfsnJKTzejEAkeVrZE0Yo=", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.66.0", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/acorn": { + "version": "8.18.0", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha1-T68BstbTJr/u2XrqH1IiC19MGUA=", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha1-ftW7VZCLOy8bxVxq8WU7rafweTc=", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha1-B+mCx0YmFnqnoklcU4F4ktcTlJI=", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha1-eQxYsZuhcgqEIFtXxhjVrYUklz4=", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha1-v7EGYv7tgZaixi58aOF3IMJ0F5o=", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha1-9uFKl4WNMnJSIAJC1Mz+UixEVSI=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.9", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha1-fHJDiAm1+lur9UGZofHCgaaYT88=", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/braces/-/braces-3.0.3.tgz", + "integrity": "sha1-SQMy9AkZRSJy1VqEgK3AxEE1h4k=", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha1-GXxsxmnvKo3F57TZfuTgksPrDVs=", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha1-hpgyxYA0/mikCTwX3BXoNA2EAcQ=", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha1-ilj+ePANzXDDcEUXWd+/rwPo7p8=", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/debug/-/debug-4.4.3.tgz", + "integrity": "sha1-xq5DLZvZZiWC/OCHCbA4xY6ePWo=", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha1-pvLc5hL63S7x9Rm3NVHxfoUZmDE=", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.28.1", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha1-70W0Y0ycnZeilq6kEUpfmED5VXg=", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha1-FLqDpdNz49MR5a/KKc9b+tllvzQ=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "10.8.0", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/eslint/-/eslint-10.8.0.tgz", + "integrity": "sha1-5tGZB6PwkKU6AiJhujTF/20EkIs=", + "dev": true, + "license": "MIT", + "workspaces": [ + "packages/*" + ], + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.5", + "@eslint/config-helpers": "^0.7.0", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.2", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha1-ud5qzi+rHP8k0uWNhbdMj86jmAI=", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha1-njyUiWl4JNLUzjqK0SYo+R6fWb4=", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "11.2.0", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/espree/-/espree-11.2.0.tgz", + "integrity": "sha1-AdXkfcMyqrowWQCDYkVKjMNMyqU=", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha1-CNBI8mHw3e21uulfRoCUY9nJSW0=", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha1-eteWTWeauyi+5yzsY3WLHF0smSE=", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha1-LupSkHAvJquP5TcDcP+GyWXSESM=", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q=", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU=", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM=", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true, + "license": "MIT" + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha1-d4e93PETG/+5JjbGlFe7wO3W2B8=", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha1-RCZdPKwH4+p9wkdRY4BkN1SgUpI=", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha1-TJKBnstwg1YeT0okCoa+UZj1Nvw=", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha1-Ds45/LFO4BL0sEEL0z3ZwfAREnw=", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.4", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/flatted/-/flatted-3.4.4.tgz", + "integrity": "sha1-ruyipQYwPwzuYcWebJ8qiNLyn8Y=", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha1-ysZAd4XQNnWipeGlMFxpezR9kNY=", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha1-bSN9mQg5UMeSkPJMdkKj3poo+eM=", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha1-PNQOcp82Q/2HywTlC/DrcivFlvU=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true, + "license": "ISC" + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha1-6h9/O4DwZCNug0cPhsCcJU+0Wwk=", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha1-ZPYeQsu7LuwgcanawLKLoeZdUIQ=", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true, + "license": "ISC" + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha1-kziAKjDTtmBfvgYT4JQAjKjAWhM=", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true, + "license": "MIT" + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha1-qHmpnilFL5QkOfKkBeOvizHU3pM=", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/levn/-/levn-0.4.1.tgz", + "integrity": "sha1-rkViwAdHO5MqYgDUAyaN0v/8at4=", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha1-VTIeswn+u8WcSAHZMackUqaB0oY=", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "version": "10.2.6", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha1-/ZVrvgt3JB6fFaxdzLHGOAYJaO8=", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.8" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ms/-/ms-2.1.3.tgz", + "integrity": "sha1-V0yBOM4dK1hh8LRFedut1gxmFbI=", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true, + "license": "MIT" + }, + "node_modules/nodemon": { + "version": "3.1.14", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/nodemon/-/nodemon-3.1.14.tgz", + "integrity": "sha1-hIfKN5xRUwHSIewAfyfyTsr6K1E=", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^10.2.1", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha1-fqHBpdkddk+yghOciP4R4YKjpzQ=", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha1-4drMvnjQ0TiMoYxk/qOOPlfjcGs=", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha1-g8gxXGeFAF470CGDlBHJ4RDm2DQ=", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha1-WpQpFeJrNy3A8OZ1MUmhbmscVgE=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha1-3rxkidem5rDnYRiIzsiAM30xY5Y=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha1-wkIiT0pnwh9oaDm720rCgrg3PTo=", + "dev": true, + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha1-AnQi4vrsCyXhVJw+G9gwm5EztuU=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha1-dKNwvYVxFuJFspzJc0DNQxoCpsc=", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/semver/-/semver-7.8.5.tgz", + "integrity": "sha1-ObZGA33VDBT7RR5+TKxY7YuGP2k=", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo=", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha1-1wuSvat9bZDf1zkxGVowtuPXzrs=", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha1-ViqabJ6ys7Ej05cZ+a9btE/NdjE=", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha1-7Sq5Z6MxreYvGNB32uGSaE1Q01A=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha1-UepXoX2G9gX4EDlZX7xA7QalX6s=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/touch": { + "version": "3.1.1", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/touch/-/touch-3.1.1.tgz", + "integrity": "sha1-CXoj17FhR2Q15cE0SpXA91tKVpQ=", + "dev": true, + "license": "ISC", + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha1-Ss1KFV4ic0mQpe0f6el/ETvLN8E=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tsx": { + "version": "4.23.11", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/tsx/-/tsx-4.23.11.tgz", + "integrity": "sha1-gqfLzOFntXUGDbA+94moTGh8f5c=", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.28.0" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha1-B7ggO/pwVsBlcFDjzNLDdzC6uPE=", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha1-kCUdwAeRbpcnhsuU100VsYVXfSE=", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.66.0", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/typescript-eslint/-/typescript-eslint-8.66.0.tgz", + "integrity": "sha1-CAm20lyKCSRpC6MNwfBWBwk8Efs=", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.66.0", + "@typescript-eslint/parser": "8.66.0", + "@typescript-eslint/typescript-estree": "8.66.0", + "@typescript-eslint/utils": "8.66.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha1-OHM7kye9zSJtuIn7cjpu/RYubiw=", + "dev": true, + "license": "MIT" + }, + "node_modules/undici-types": { + "version": "7.24.6", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/undici-types/-/undici-types-7.24.6.tgz", + "integrity": "sha1-YSdbSF1/1OnSacfPBOwoc8nMD5E=", + "dev": true, + "license": "MIT" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha1-mxpSWVIlhZ5V9mnZKPiMbFfyp34=", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vscode-jsonrpc": { + "version": "8.2.1", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/vscode-jsonrpc/-/vscode-jsonrpc-8.2.1.tgz", + "integrity": "sha1-oyLMDx2X95T/2cTNKomKC94JfzQ=", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/which/-/which-2.0.2.tgz", + "integrity": "sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE=", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha1-0sRcbdT7zmIaZvE2y+Mor9BBCzQ=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha1-ApTrPe4FAo0x7hpfosVWpqrxChs=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/samples/maildev-mailkit/package.json b/samples/maildev-mailkit/package.json new file mode 100644 index 000000000..f794f797f --- /dev/null +++ b/samples/maildev-mailkit/package.json @@ -0,0 +1,26 @@ +{ + "name": "aspire-maildev-apphost", + "version": "1.0.0", + "private": true, + "type": "module", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "scripts": { + "aspire:lint": "eslint apphost.mts", + "aspire:start": "aspire run", + "aspire:build": "tsc -p tsconfig.apphost.json", + "aspire:dev": "tsc --watch -p tsconfig.apphost.json" + }, + "dependencies": { + "vscode-jsonrpc": "^8.2.1" + }, + "devDependencies": { + "@types/node": "^25.8.0", + "eslint": "^10.3.0", + "nodemon": "^3.1.14", + "tsx": "^4.22.0", + "typescript": "^6.0.3", + "typescript-eslint": "^8.59.3" + } +} \ No newline at end of file diff --git a/samples/maildev-mailkit/tsconfig.apphost.json b/samples/maildev-mailkit/tsconfig.apphost.json new file mode 100644 index 000000000..139b67749 --- /dev/null +++ b/samples/maildev-mailkit/tsconfig.apphost.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true, + "outDir": "./dist/apphost", + "rootDir": "." + }, + "include": ["apphost.mts", ".aspire/modules/**/*.mts"], + "exclude": ["node_modules"] +} \ No newline at end of file From f42053eba958712e3bfbb14c8cf46d43b9e40b99 Mon Sep 17 00:00:00 2001 From: Copilot <223556219+Copilot@users.noreply.github.com> Date: Fri, 14 Aug 2026 11:42:26 -0500 Subject: [PATCH 2/2] Address MailDev sample review feedback --- .github/workflows/ci.yml | 4 +- .../MailKitExtensionsTests.cs | 20 +++ .../MailKit.Client/MailKitExtensions.cs | 2 +- samples/maildev-mailkit/NuGet.Config | 8 + .../ServiceDefaults/Extensions.cs | 11 +- samples/maildev-mailkit/package-lock.json | 139 ------------------ 6 files changed, 38 insertions(+), 146 deletions(-) create mode 100644 samples/maildev-mailkit/NuGet.Config diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3a487612b..0537ff002 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: shell: bash run: | install_path="$RUNNER_TEMP/aspire-cli" - curl -sSL https://aspire.dev/install.sh | bash -s -- --install-path "$install_path" --skip-path + curl -sSL https://aspire.dev/install.sh | bash -s -- --install-path "$install_path" --skip-path --quality staging echo "$install_path" >> "$GITHUB_PATH" echo "ASPIRE_CLI=$install_path/aspire" >> "$GITHUB_ENV" "$install_path/aspire" --version @@ -78,7 +78,7 @@ jobs: $aspirePath = Join-Path $installPath 'aspire.exe' Invoke-RestMethod 'https://aspire.dev/install.ps1' -OutFile $installScript - & $installScript -InstallPath $installPath -SkipPath + & $installScript -InstallPath $installPath -SkipPath -Quality staging $installPath | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append "ASPIRE_CLI=$aspirePath" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append diff --git a/samples/maildev-mailkit/MailKit.Client.Tests/MailKitExtensionsTests.cs b/samples/maildev-mailkit/MailKit.Client.Tests/MailKitExtensionsTests.cs index 35de9e247..b1160fb32 100644 --- a/samples/maildev-mailkit/MailKit.Client.Tests/MailKitExtensionsTests.cs +++ b/samples/maildev-mailkit/MailKit.Client.Tests/MailKitExtensionsTests.cs @@ -2,6 +2,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.HealthChecks; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Options; using Xunit; namespace MailKit.Client.Tests; @@ -39,6 +40,25 @@ public void AddKeyedMailKitClientRegistersNamedFactory() Assert.Null(scope.ServiceProvider.GetService()); } + [Fact] + public void AddMailKitClientUsesConnectionNameForHealthCheck() + { + var builder = Host.CreateApplicationBuilder(); + builder.Configuration["ConnectionStrings:primary"] = "smtp://localhost:1025"; + builder.Configuration["ConnectionStrings:secondary"] = "smtp://localhost:1026"; + + builder.AddMailKitClient("primary"); + builder.AddMailKitClient("secondary"); + + using var provider = builder.Services.BuildServiceProvider(); + var options = provider.GetRequiredService>().Value; + + Assert.Collection( + options.Registrations, + registration => Assert.Equal("MailKit_primary", registration.Name), + registration => Assert.Equal("MailKit_secondary", registration.Name)); + } + [Fact] public void FactoryValidationIsDeferredUntilResolution() { diff --git a/samples/maildev-mailkit/MailKit.Client/MailKitExtensions.cs b/samples/maildev-mailkit/MailKit.Client/MailKitExtensions.cs index 7c657c60f..0a8068f3e 100644 --- a/samples/maildev-mailkit/MailKit.Client/MailKitExtensions.cs +++ b/samples/maildev-mailkit/MailKit.Client/MailKitExtensions.cs @@ -71,7 +71,7 @@ private static void AddMailKitClient( if (!settings.DisableHealthChecks) { builder.Services.AddHealthChecks().Add(new HealthCheckRegistration( - serviceKey is null ? "MailKit" : $"MailKit_{connectionName}", + $"MailKit_{connectionName}", serviceProvider => new MailKitHealthCheck( serviceKey is null ? serviceProvider.GetRequiredService() diff --git a/samples/maildev-mailkit/NuGet.Config b/samples/maildev-mailkit/NuGet.Config new file mode 100644 index 000000000..149e76950 --- /dev/null +++ b/samples/maildev-mailkit/NuGet.Config @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/samples/maildev-mailkit/ServiceDefaults/Extensions.cs b/samples/maildev-mailkit/ServiceDefaults/Extensions.cs index 771bf0b37..a663419b3 100644 --- a/samples/maildev-mailkit/ServiceDefaults/Extensions.cs +++ b/samples/maildev-mailkit/ServiceDefaults/Extensions.cs @@ -56,11 +56,14 @@ public static TBuilder AddServiceDefaults(this TBuilder builder) public static WebApplication MapDefaultEndpoints(this WebApplication app) { - app.MapHealthChecks(HealthEndpointPath); - app.MapHealthChecks(AlivenessEndpointPath, new HealthCheckOptions + if (app.Environment.IsDevelopment()) { - Predicate = check => check.Tags.Contains("live") - }); + app.MapHealthChecks(HealthEndpointPath); + app.MapHealthChecks(AlivenessEndpointPath, new HealthCheckOptions + { + Predicate = check => check.Tags.Contains("live") + }); + } return app; } diff --git a/samples/maildev-mailkit/package-lock.json b/samples/maildev-mailkit/package-lock.json index 970958860..9e1a8266e 100644 --- a/samples/maildev-mailkit/package-lock.json +++ b/samples/maildev-mailkit/package-lock.json @@ -24,7 +24,6 @@ }, "node_modules/@esbuild/aix-ppc64": { "version": "0.28.1", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", "integrity": "sha1-egGo0uwvuy2seK2tCbD6eB5Agr4=", "cpu": [ "ppc64" @@ -41,7 +40,6 @@ }, "node_modules/@esbuild/android-arm": { "version": "0.28.1", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/android-arm/-/android-arm-0.28.1.tgz", "integrity": "sha1-cEvSl95tdi3lTqu+r79V9nVqvi8=", "cpu": [ "arm" @@ -58,7 +56,6 @@ }, "node_modules/@esbuild/android-arm64": { "version": "0.28.1", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", "integrity": "sha1-tUCifRTkr9BYSWpNvsTT9BTbEQo=", "cpu": [ "arm64" @@ -75,7 +72,6 @@ }, "node_modules/@esbuild/android-x64": { "version": "0.28.1", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/android-x64/-/android-x64-0.28.1.tgz", "integrity": "sha1-0csWbTSw+/D+irRgpVlPJKN4cB4=", "cpu": [ "x64" @@ -92,7 +88,6 @@ }, "node_modules/@esbuild/darwin-arm64": { "version": "0.28.1", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", "integrity": "sha1-EDSyZFf8iGNo/mG70J9lP2r6jlQ=", "cpu": [ "arm64" @@ -109,7 +104,6 @@ }, "node_modules/@esbuild/darwin-x64": { "version": "0.28.1", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", "integrity": "sha1-ZVVqQyoeTXIDLYIYwZMvzKGkl3I=", "cpu": [ "x64" @@ -126,7 +120,6 @@ }, "node_modules/@esbuild/freebsd-arm64": { "version": "0.28.1", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", "integrity": "sha1-LmHgWS+QMNfj2uGO4l68U1kYrvY=", "cpu": [ "arm64" @@ -143,7 +136,6 @@ }, "node_modules/@esbuild/freebsd-x64": { "version": "0.28.1", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", "integrity": "sha1-yV7CiZWe+AecTcqBeh4sS+Zrm9M=", "cpu": [ "x64" @@ -160,7 +152,6 @@ }, "node_modules/@esbuild/linux-arm": { "version": "0.28.1", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", "integrity": "sha1-wJoPZ5F1kqwN6JKpvk04FN69Kmw=", "cpu": [ "arm" @@ -177,7 +168,6 @@ }, "node_modules/@esbuild/linux-arm64": { "version": "0.28.1", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", "integrity": "sha1-QLIhdd2gYYLz7oFBGGxf8wTEpxc=", "cpu": [ "arm64" @@ -194,7 +184,6 @@ }, "node_modules/@esbuild/linux-ia32": { "version": "0.28.1", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", "integrity": "sha1-pYD5xnZ5eDOJHlGfx6EzfIr9jbM=", "cpu": [ "ia32" @@ -211,7 +200,6 @@ }, "node_modules/@esbuild/linux-loong64": { "version": "0.28.1", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", "integrity": "sha1-RkUs8yHcf56Rwvp4Cla7Vuec1os=", "cpu": [ "loong64" @@ -228,7 +216,6 @@ }, "node_modules/@esbuild/linux-mips64el": { "version": "0.28.1", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", "integrity": "sha1-QhGzGE3WYI9T3LIuOfXTTuCIUsg=", "cpu": [ "mips64el" @@ -245,7 +232,6 @@ }, "node_modules/@esbuild/linux-ppc64": { "version": "0.28.1", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", "integrity": "sha1-aXhXwqYcubC2u2ZS5AwdxeHKjl0=", "cpu": [ "ppc64" @@ -262,7 +248,6 @@ }, "node_modules/@esbuild/linux-riscv64": { "version": "0.28.1", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", "integrity": "sha1-0ZKUPrFGpArExkl9DPe+NbmGvwg=", "cpu": [ "riscv64" @@ -279,7 +264,6 @@ }, "node_modules/@esbuild/linux-s390x": { "version": "0.28.1", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", "integrity": "sha1-rOoDVtoODrwI+Xz3ucLkAeHmSNw=", "cpu": [ "s390x" @@ -296,7 +280,6 @@ }, "node_modules/@esbuild/linux-x64": { "version": "0.28.1", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", "integrity": "sha1-bww84MtkxTS3DExF7LLBbTTjXf0=", "cpu": [ "x64" @@ -313,7 +296,6 @@ }, "node_modules/@esbuild/netbsd-arm64": { "version": "0.28.1", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", "integrity": "sha1-i813B3oNzjN4tXT+2ybSolO3PTY=", "cpu": [ "arm64" @@ -330,7 +312,6 @@ }, "node_modules/@esbuild/netbsd-x64": { "version": "0.28.1", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", "integrity": "sha1-5/sqAemcgwyU5mI82f77TI+1g0c=", "cpu": [ "x64" @@ -347,7 +328,6 @@ }, "node_modules/@esbuild/openbsd-arm64": { "version": "0.28.1", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", "integrity": "sha1-xSkJNy24uG4sVeBaiUADO1Zgo7I=", "cpu": [ "arm64" @@ -364,7 +344,6 @@ }, "node_modules/@esbuild/openbsd-x64": { "version": "0.28.1", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", "integrity": "sha1-xCe5vlpkwmL/mn63C1+7qt9EbGw=", "cpu": [ "x64" @@ -381,7 +360,6 @@ }, "node_modules/@esbuild/openharmony-arm64": { "version": "0.28.1", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", "integrity": "sha1-3JsUe6yi5sSzyFVxdB70hgpIkJc=", "cpu": [ "arm64" @@ -398,7 +376,6 @@ }, "node_modules/@esbuild/sunos-x64": { "version": "0.28.1", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", "integrity": "sha1-zoZtEt8TwV5MmfBzo9Rm9uBkmzo=", "cpu": [ "x64" @@ -415,7 +392,6 @@ }, "node_modules/@esbuild/win32-arm64": { "version": "0.28.1", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", "integrity": "sha1-dGjjaS0B1inVlB5dg4F7uA+eObQ=", "cpu": [ "arm64" @@ -432,7 +408,6 @@ }, "node_modules/@esbuild/win32-ia32": { "version": "0.28.1", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", "integrity": "sha1-pbwAY/sryrbQ7WPyoVN5WLwmnsY=", "cpu": [ "ia32" @@ -449,7 +424,6 @@ }, "node_modules/@esbuild/win32-x64": { "version": "0.28.1", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", "integrity": "sha1-EAZO5E9DR7kMmgK0Rrv4CpFjKxI=", "cpu": [ "x64" @@ -466,7 +440,6 @@ }, "node_modules/@eslint-community/eslint-utils": { "version": "4.10.1", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", "integrity": "sha1-iRG9crLDZApUNgngQAuMTS5+fLY=", "dev": true, "license": "MIT", @@ -485,7 +458,6 @@ }, "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { "version": "3.4.3", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha1-DNcv6FUOPC6uFWqWpN3c0cisWAA=", "dev": true, "license": "Apache-2.0", @@ -498,7 +470,6 @@ }, "node_modules/@eslint-community/regexpp": { "version": "4.12.2", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", "integrity": "sha1-vM32Fbz3tujbgw7AuNIcmiXeWXs=", "dev": true, "license": "MIT", @@ -508,7 +479,6 @@ }, "node_modules/@eslint/config-array": { "version": "0.23.5", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint/config-array/-/config-array-0.23.5.tgz", "integrity": "sha1-VuhtJDBJGV2KzAwGobPf3D+j3pU=", "dev": true, "license": "Apache-2.0", @@ -523,7 +493,6 @@ }, "node_modules/@eslint/config-helpers": { "version": "0.7.0", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint/config-helpers/-/config-helpers-0.7.0.tgz", "integrity": "sha1-Ce5KoHtz8FnsLUx0v0sv8CsyI3c=", "dev": true, "license": "Apache-2.0", @@ -536,7 +505,6 @@ }, "node_modules/@eslint/core": { "version": "1.2.1", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint/core/-/core-1.2.1.tgz", "integrity": "sha1-wdp80bgvqHh/mLVin7gRhIobY84=", "dev": true, "license": "Apache-2.0", @@ -549,7 +517,6 @@ }, "node_modules/@eslint/object-schema": { "version": "3.0.5", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint/object-schema/-/object-schema-3.0.5.tgz", "integrity": "sha1-iOm/TRHSsZwILnjr586IckpesJE=", "dev": true, "license": "Apache-2.0", @@ -559,7 +526,6 @@ }, "node_modules/@eslint/plugin-kit": { "version": "0.7.2", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz", "integrity": "sha1-Swli8/LHzovJiz7P40UlwJ0styk=", "dev": true, "license": "Apache-2.0", @@ -573,7 +539,6 @@ }, "node_modules/@humanfs/core": { "version": "0.19.2", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@humanfs/core/-/core-0.19.2.tgz", "integrity": "sha1-qCcsoDsqz0kmcCIrIyC2xCG/3mA=", "dev": true, "license": "Apache-2.0", @@ -586,7 +551,6 @@ }, "node_modules/@humanfs/node": { "version": "0.16.8", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@humanfs/node/-/node-0.16.8.tgz", "integrity": "sha1-j4AMzME/T4zTEW4tnAqUk52j4+0=", "dev": true, "license": "Apache-2.0", @@ -601,7 +565,6 @@ }, "node_modules/@humanfs/types": { "version": "0.15.0", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@humanfs/types/-/types-0.15.0.tgz", "integrity": "sha1-8qCfYgEjkLK/8/xvskjd7IwJoJA=", "dev": true, "license": "Apache-2.0", @@ -611,7 +574,6 @@ }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha1-r1smkaIrRL6EewyoFkHF+2rQFyw=", "dev": true, "license": "Apache-2.0", @@ -625,7 +587,6 @@ }, "node_modules/@humanwhocodes/retry": { "version": "0.4.3", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@humanwhocodes/retry/-/retry-0.4.3.tgz", "integrity": "sha1-wrnS43TuYsWG062+qHGZsdenpro=", "dev": true, "license": "Apache-2.0", @@ -639,28 +600,24 @@ }, "node_modules/@types/esrecurse": { "version": "4.3.1", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/esrecurse/-/esrecurse-4.3.1.tgz", "integrity": "sha1-b2Nq+WL75hkbgwvWdrpZhpJrzOw=", "dev": true, "license": "MIT" }, "node_modules/@types/estree": { "version": "1.0.9", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/estree/-/estree-1.0.9.tgz", "integrity": "sha1-zz8Oh2177hWpOrkluCv1cKOQSiQ=", "dev": true, "license": "MIT" }, "node_modules/@types/json-schema": { "version": "7.0.15", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha1-WWoXRyM2lNUPatinhp/Lb1bPWEE=", "dev": true, "license": "MIT" }, "node_modules/@types/node": { "version": "25.9.5", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@types/node/-/node-25.9.5.tgz", "integrity": "sha1-D+/Anm6C6UzeKRus9DUi6YnrAaQ=", "dev": true, "license": "MIT", @@ -670,7 +627,6 @@ }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.66.0", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.66.0.tgz", "integrity": "sha1-duhqpaJFn79bvXqDnA3AzOHVYiQ=", "dev": true, "license": "MIT", @@ -699,7 +655,6 @@ }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { "version": "7.0.6", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ignore/-/ignore-7.0.6.tgz", "integrity": "sha1-aleq70yQ3yesNZCHXSno8RmIyI4=", "dev": true, "license": "MIT", @@ -709,7 +664,6 @@ }, "node_modules/@typescript-eslint/parser": { "version": "8.66.0", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/parser/-/parser-8.66.0.tgz", "integrity": "sha1-iOOGXs9zsBGBNOfLgx2oepYaV6E=", "dev": true, "license": "MIT", @@ -734,7 +688,6 @@ }, "node_modules/@typescript-eslint/project-service": { "version": "8.66.0", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/project-service/-/project-service-8.66.0.tgz", "integrity": "sha1-go94iJXfUtnrK1Q0RaOloT41q04=", "dev": true, "license": "MIT", @@ -756,7 +709,6 @@ }, "node_modules/@typescript-eslint/scope-manager": { "version": "8.66.0", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/scope-manager/-/scope-manager-8.66.0.tgz", "integrity": "sha1-T//Mbr0N+f55g8AlaWdWfqb1rGM=", "dev": true, "license": "MIT", @@ -774,7 +726,6 @@ }, "node_modules/@typescript-eslint/tsconfig-utils": { "version": "8.66.0", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.66.0.tgz", "integrity": "sha1-OokGbFB6owVB3BdoBGhbS0ROHlI=", "dev": true, "license": "MIT", @@ -791,7 +742,6 @@ }, "node_modules/@typescript-eslint/type-utils": { "version": "8.66.0", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/type-utils/-/type-utils-8.66.0.tgz", "integrity": "sha1-sjFTA+ynL62a+nvk9Y8FPI8qBHk=", "dev": true, "license": "MIT", @@ -816,7 +766,6 @@ }, "node_modules/@typescript-eslint/types": { "version": "8.66.0", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/types/-/types-8.66.0.tgz", "integrity": "sha1-PKyrlNO1ZMHUjFbrN7ifiabUhHk=", "dev": true, "license": "MIT", @@ -830,7 +779,6 @@ }, "node_modules/@typescript-eslint/typescript-estree": { "version": "8.66.0", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/typescript-estree/-/typescript-estree-8.66.0.tgz", "integrity": "sha1-GjjDqX3Gxmm2bVhdf5DrxPuzKlA=", "dev": true, "license": "MIT", @@ -858,7 +806,6 @@ }, "node_modules/@typescript-eslint/utils": { "version": "8.66.0", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/utils/-/utils-8.66.0.tgz", "integrity": "sha1-4nfWdCcEPNyiWA7pGqYpIeRomWk=", "dev": true, "license": "MIT", @@ -882,7 +829,6 @@ }, "node_modules/@typescript-eslint/visitor-keys": { "version": "8.66.0", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@typescript-eslint/visitor-keys/-/visitor-keys-8.66.0.tgz", "integrity": "sha1-TElOlHRfsnJKTzejEAkeVrZE0Yo=", "dev": true, "license": "MIT", @@ -900,7 +846,6 @@ }, "node_modules/acorn": { "version": "8.18.0", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/acorn/-/acorn-8.18.0.tgz", "integrity": "sha1-T68BstbTJr/u2XrqH1IiC19MGUA=", "dev": true, "license": "MIT", @@ -913,7 +858,6 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha1-ftW7VZCLOy8bxVxq8WU7rafweTc=", "dev": true, "license": "MIT", @@ -923,7 +867,6 @@ }, "node_modules/ajv": { "version": "6.15.0", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ajv/-/ajv-6.15.0.tgz", "integrity": "sha1-B+mCx0YmFnqnoklcU4F4ktcTlJI=", "dev": true, "license": "MIT", @@ -940,7 +883,6 @@ }, "node_modules/anymatch": { "version": "3.1.3", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha1-eQxYsZuhcgqEIFtXxhjVrYUklz4=", "dev": true, "license": "ISC", @@ -954,7 +896,6 @@ }, "node_modules/balanced-match": { "version": "4.0.4", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/balanced-match/-/balanced-match-4.0.4.tgz", "integrity": "sha1-v7EGYv7tgZaixi58aOF3IMJ0F5o=", "dev": true, "license": "MIT", @@ -964,7 +905,6 @@ }, "node_modules/binary-extensions": { "version": "2.3.0", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/binary-extensions/-/binary-extensions-2.3.0.tgz", "integrity": "sha1-9uFKl4WNMnJSIAJC1Mz+UixEVSI=", "dev": true, "license": "MIT", @@ -977,7 +917,6 @@ }, "node_modules/brace-expansion": { "version": "5.0.9", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/brace-expansion/-/brace-expansion-5.0.9.tgz", "integrity": "sha1-fHJDiAm1+lur9UGZofHCgaaYT88=", "dev": true, "license": "MIT", @@ -990,7 +929,6 @@ }, "node_modules/braces": { "version": "3.0.3", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/braces/-/braces-3.0.3.tgz", "integrity": "sha1-SQMy9AkZRSJy1VqEgK3AxEE1h4k=", "dev": true, "license": "MIT", @@ -1003,7 +941,6 @@ }, "node_modules/chokidar": { "version": "3.6.0", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha1-GXxsxmnvKo3F57TZfuTgksPrDVs=", "dev": true, "license": "MIT", @@ -1028,7 +965,6 @@ }, "node_modules/chokidar/node_modules/glob-parent": { "version": "5.1.2", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha1-hpgyxYA0/mikCTwX3BXoNA2EAcQ=", "dev": true, "license": "ISC", @@ -1041,7 +977,6 @@ }, "node_modules/cross-spawn": { "version": "7.0.6", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha1-ilj+ePANzXDDcEUXWd+/rwPo7p8=", "dev": true, "license": "MIT", @@ -1056,7 +991,6 @@ }, "node_modules/debug": { "version": "4.4.3", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/debug/-/debug-4.4.3.tgz", "integrity": "sha1-xq5DLZvZZiWC/OCHCbA4xY6ePWo=", "dev": true, "license": "MIT", @@ -1074,14 +1008,12 @@ }, "node_modules/deep-is": { "version": "0.1.4", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha1-pvLc5hL63S7x9Rm3NVHxfoUZmDE=", "dev": true, "license": "MIT" }, "node_modules/esbuild": { "version": "0.28.1", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/esbuild/-/esbuild-0.28.1.tgz", "integrity": "sha1-70W0Y0ycnZeilq6kEUpfmED5VXg=", "dev": true, "hasInstallScript": true, @@ -1123,7 +1055,6 @@ }, "node_modules/escape-string-regexp": { "version": "4.0.0", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha1-FLqDpdNz49MR5a/KKc9b+tllvzQ=", "dev": true, "license": "MIT", @@ -1136,7 +1067,6 @@ }, "node_modules/eslint": { "version": "10.8.0", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/eslint/-/eslint-10.8.0.tgz", "integrity": "sha1-5tGZB6PwkKU6AiJhujTF/20EkIs=", "dev": true, "license": "MIT", @@ -1195,7 +1125,6 @@ }, "node_modules/eslint-scope": { "version": "9.1.2", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/eslint-scope/-/eslint-scope-9.1.2.tgz", "integrity": "sha1-ud5qzi+rHP8k0uWNhbdMj86jmAI=", "dev": true, "license": "BSD-2-Clause", @@ -1214,7 +1143,6 @@ }, "node_modules/eslint-visitor-keys": { "version": "5.0.1", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", "integrity": "sha1-njyUiWl4JNLUzjqK0SYo+R6fWb4=", "dev": true, "license": "Apache-2.0", @@ -1227,7 +1155,6 @@ }, "node_modules/espree": { "version": "11.2.0", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/espree/-/espree-11.2.0.tgz", "integrity": "sha1-AdXkfcMyqrowWQCDYkVKjMNMyqU=", "dev": true, "license": "BSD-2-Clause", @@ -1245,7 +1172,6 @@ }, "node_modules/esquery": { "version": "1.7.0", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/esquery/-/esquery-1.7.0.tgz", "integrity": "sha1-CNBI8mHw3e21uulfRoCUY9nJSW0=", "dev": true, "license": "BSD-3-Clause", @@ -1258,7 +1184,6 @@ }, "node_modules/esrecurse": { "version": "4.3.0", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha1-eteWTWeauyi+5yzsY3WLHF0smSE=", "dev": true, "license": "BSD-2-Clause", @@ -1271,7 +1196,6 @@ }, "node_modules/estraverse": { "version": "5.3.0", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha1-LupSkHAvJquP5TcDcP+GyWXSESM=", "dev": true, "license": "BSD-2-Clause", @@ -1281,7 +1205,6 @@ }, "node_modules/esutils": { "version": "2.0.3", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/esutils/-/esutils-2.0.3.tgz", "integrity": "sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q=", "dev": true, "license": "BSD-2-Clause", @@ -1291,28 +1214,24 @@ }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU=", "dev": true, "license": "MIT" }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM=", "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true, "license": "MIT" }, "node_modules/file-entry-cache": { "version": "8.0.0", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/file-entry-cache/-/file-entry-cache-8.0.0.tgz", "integrity": "sha1-d4e93PETG/+5JjbGlFe7wO3W2B8=", "dev": true, "license": "MIT", @@ -1325,7 +1244,6 @@ }, "node_modules/fill-range": { "version": "7.1.1", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha1-RCZdPKwH4+p9wkdRY4BkN1SgUpI=", "dev": true, "license": "MIT", @@ -1338,7 +1256,6 @@ }, "node_modules/find-up": { "version": "5.0.0", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/find-up/-/find-up-5.0.0.tgz", "integrity": "sha1-TJKBnstwg1YeT0okCoa+UZj1Nvw=", "dev": true, "license": "MIT", @@ -1355,7 +1272,6 @@ }, "node_modules/flat-cache": { "version": "4.0.1", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/flat-cache/-/flat-cache-4.0.1.tgz", "integrity": "sha1-Ds45/LFO4BL0sEEL0z3ZwfAREnw=", "dev": true, "license": "MIT", @@ -1369,14 +1285,12 @@ }, "node_modules/flatted": { "version": "3.4.4", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/flatted/-/flatted-3.4.4.tgz", "integrity": "sha1-ruyipQYwPwzuYcWebJ8qiNLyn8Y=", "dev": true, "license": "ISC" }, "node_modules/fsevents": { "version": "2.3.3", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha1-ysZAd4XQNnWipeGlMFxpezR9kNY=", "dev": true, "license": "MIT", @@ -1390,7 +1304,6 @@ }, "node_modules/glob-parent": { "version": "6.0.2", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha1-bSN9mQg5UMeSkPJMdkKj3poo+eM=", "dev": true, "license": "ISC", @@ -1403,7 +1316,6 @@ }, "node_modules/has-flag": { "version": "3.0.0", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true, "license": "MIT", @@ -1413,7 +1325,6 @@ }, "node_modules/ignore": { "version": "5.3.2", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ignore/-/ignore-5.3.2.tgz", "integrity": "sha1-PNQOcp82Q/2HywTlC/DrcivFlvU=", "dev": true, "license": "MIT", @@ -1423,14 +1334,12 @@ }, "node_modules/ignore-by-default": { "version": "1.0.1", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ignore-by-default/-/ignore-by-default-1.0.1.tgz", "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", "dev": true, "license": "ISC" }, "node_modules/imurmurhash": { "version": "0.1.4", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true, "license": "MIT", @@ -1440,7 +1349,6 @@ }, "node_modules/is-binary-path": { "version": "2.1.0", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha1-6h9/O4DwZCNug0cPhsCcJU+0Wwk=", "dev": true, "license": "MIT", @@ -1453,7 +1361,6 @@ }, "node_modules/is-extglob": { "version": "2.1.1", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true, "license": "MIT", @@ -1463,7 +1370,6 @@ }, "node_modules/is-glob": { "version": "4.0.3", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha1-ZPYeQsu7LuwgcanawLKLoeZdUIQ=", "dev": true, "license": "MIT", @@ -1476,7 +1382,6 @@ }, "node_modules/is-number": { "version": "7.0.0", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/is-number/-/is-number-7.0.0.tgz", "integrity": "sha1-dTU0W4lnNNX4DE0GxQlVUnoU8Ss=", "dev": true, "license": "MIT", @@ -1486,35 +1391,30 @@ }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true, "license": "ISC" }, "node_modules/json-buffer": { "version": "3.0.1", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha1-kziAKjDTtmBfvgYT4JQAjKjAWhM=", "dev": true, "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=", "dev": true, "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true, "license": "MIT" }, "node_modules/keyv": { "version": "4.5.4", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/keyv/-/keyv-4.5.4.tgz", "integrity": "sha1-qHmpnilFL5QkOfKkBeOvizHU3pM=", "dev": true, "license": "MIT", @@ -1524,7 +1424,6 @@ }, "node_modules/levn": { "version": "0.4.1", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/levn/-/levn-0.4.1.tgz", "integrity": "sha1-rkViwAdHO5MqYgDUAyaN0v/8at4=", "dev": true, "license": "MIT", @@ -1538,7 +1437,6 @@ }, "node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha1-VTIeswn+u8WcSAHZMackUqaB0oY=", "dev": true, "license": "MIT", @@ -1554,7 +1452,6 @@ }, "node_modules/minimatch": { "version": "10.2.6", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/minimatch/-/minimatch-10.2.6.tgz", "integrity": "sha1-/ZVrvgt3JB6fFaxdzLHGOAYJaO8=", "dev": true, "license": "BlueOak-1.0.0", @@ -1570,21 +1467,18 @@ }, "node_modules/ms": { "version": "2.1.3", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ms/-/ms-2.1.3.tgz", "integrity": "sha1-V0yBOM4dK1hh8LRFedut1gxmFbI=", "dev": true, "license": "MIT" }, "node_modules/natural-compare": { "version": "1.4.0", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true, "license": "MIT" }, "node_modules/nodemon": { "version": "3.1.14", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/nodemon/-/nodemon-3.1.14.tgz", "integrity": "sha1-hIfKN5xRUwHSIewAfyfyTsr6K1E=", "dev": true, "license": "MIT", @@ -1613,7 +1507,6 @@ }, "node_modules/normalize-path": { "version": "3.0.0", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha1-Dc1p/yOhybEf0JeDFmRKA4ghamU=", "dev": true, "license": "MIT", @@ -1623,7 +1516,6 @@ }, "node_modules/optionator": { "version": "0.9.4", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/optionator/-/optionator-0.9.4.tgz", "integrity": "sha1-fqHBpdkddk+yghOciP4R4YKjpzQ=", "dev": true, "license": "MIT", @@ -1641,7 +1533,6 @@ }, "node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha1-4drMvnjQ0TiMoYxk/qOOPlfjcGs=", "dev": true, "license": "MIT", @@ -1657,7 +1548,6 @@ }, "node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha1-g8gxXGeFAF470CGDlBHJ4RDm2DQ=", "dev": true, "license": "MIT", @@ -1673,7 +1563,6 @@ }, "node_modules/path-exists": { "version": "4.0.0", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha1-UTvb4tO5XXdi6METfvoZXGxhtbM=", "dev": true, "license": "MIT", @@ -1683,7 +1572,6 @@ }, "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/path-key/-/path-key-3.1.1.tgz", "integrity": "sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U=", "dev": true, "license": "MIT", @@ -1693,7 +1581,6 @@ }, "node_modules/picomatch": { "version": "2.3.2", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/picomatch/-/picomatch-2.3.2.tgz", "integrity": "sha1-WpQpFeJrNy3A8OZ1MUmhbmscVgE=", "dev": true, "license": "MIT", @@ -1706,7 +1593,6 @@ }, "node_modules/prelude-ls": { "version": "1.2.1", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha1-3rxkidem5rDnYRiIzsiAM30xY5Y=", "dev": true, "license": "MIT", @@ -1716,14 +1602,12 @@ }, "node_modules/pstree.remy": { "version": "1.1.8", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/pstree.remy/-/pstree.remy-1.1.8.tgz", "integrity": "sha1-wkIiT0pnwh9oaDm720rCgrg3PTo=", "dev": true, "license": "MIT" }, "node_modules/punycode": { "version": "2.3.1", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/punycode/-/punycode-2.3.1.tgz", "integrity": "sha1-AnQi4vrsCyXhVJw+G9gwm5EztuU=", "dev": true, "license": "MIT", @@ -1733,7 +1617,6 @@ }, "node_modules/readdirp": { "version": "3.6.0", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha1-dKNwvYVxFuJFspzJc0DNQxoCpsc=", "dev": true, "license": "MIT", @@ -1746,7 +1629,6 @@ }, "node_modules/semver": { "version": "7.8.5", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/semver/-/semver-7.8.5.tgz", "integrity": "sha1-ObZGA33VDBT7RR5+TKxY7YuGP2k=", "dev": true, "license": "ISC", @@ -1759,7 +1641,6 @@ }, "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo=", "dev": true, "license": "MIT", @@ -1772,7 +1653,6 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI=", "dev": true, "license": "MIT", @@ -1782,7 +1662,6 @@ }, "node_modules/simple-update-notifier": { "version": "2.0.0", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", "integrity": "sha1-1wuSvat9bZDf1zkxGVowtuPXzrs=", "dev": true, "license": "MIT", @@ -1795,7 +1674,6 @@ }, "node_modules/supports-color": { "version": "5.5.0", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=", "dev": true, "license": "MIT", @@ -1808,7 +1686,6 @@ }, "node_modules/tinyglobby": { "version": "0.2.17", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/tinyglobby/-/tinyglobby-0.2.17.tgz", "integrity": "sha1-ViqabJ6ys7Ej05cZ+a9btE/NdjE=", "dev": true, "license": "MIT", @@ -1825,7 +1702,6 @@ }, "node_modules/tinyglobby/node_modules/fdir": { "version": "6.5.0", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fdir/-/fdir-6.5.0.tgz", "integrity": "sha1-7Sq5Z6MxreYvGNB32uGSaE1Q01A=", "dev": true, "license": "MIT", @@ -1843,7 +1719,6 @@ }, "node_modules/tinyglobby/node_modules/picomatch": { "version": "4.0.5", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/picomatch/-/picomatch-4.0.5.tgz", "integrity": "sha1-UepXoX2G9gX4EDlZX7xA7QalX6s=", "dev": true, "license": "MIT", @@ -1856,7 +1731,6 @@ }, "node_modules/to-regex-range": { "version": "5.0.1", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha1-FkjESq58jZiKMmAY7XL1tN0DkuQ=", "dev": true, "license": "MIT", @@ -1869,7 +1743,6 @@ }, "node_modules/touch": { "version": "3.1.1", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/touch/-/touch-3.1.1.tgz", "integrity": "sha1-CXoj17FhR2Q15cE0SpXA91tKVpQ=", "dev": true, "license": "ISC", @@ -1879,7 +1752,6 @@ }, "node_modules/ts-api-utils": { "version": "2.5.0", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/ts-api-utils/-/ts-api-utils-2.5.0.tgz", "integrity": "sha1-Ss1KFV4ic0mQpe0f6el/ETvLN8E=", "dev": true, "license": "MIT", @@ -1892,7 +1764,6 @@ }, "node_modules/tsx": { "version": "4.23.11", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/tsx/-/tsx-4.23.11.tgz", "integrity": "sha1-gqfLzOFntXUGDbA+94moTGh8f5c=", "dev": true, "license": "MIT", @@ -1911,7 +1782,6 @@ }, "node_modules/type-check": { "version": "0.4.0", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/type-check/-/type-check-0.4.0.tgz", "integrity": "sha1-B7ggO/pwVsBlcFDjzNLDdzC6uPE=", "dev": true, "license": "MIT", @@ -1924,7 +1794,6 @@ }, "node_modules/typescript": { "version": "6.0.3", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/typescript/-/typescript-6.0.3.tgz", "integrity": "sha1-kCUdwAeRbpcnhsuU100VsYVXfSE=", "dev": true, "license": "Apache-2.0", @@ -1938,7 +1807,6 @@ }, "node_modules/typescript-eslint": { "version": "8.66.0", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/typescript-eslint/-/typescript-eslint-8.66.0.tgz", "integrity": "sha1-CAm20lyKCSRpC6MNwfBWBwk8Efs=", "dev": true, "license": "MIT", @@ -1962,21 +1830,18 @@ }, "node_modules/undefsafe": { "version": "2.0.5", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/undefsafe/-/undefsafe-2.0.5.tgz", "integrity": "sha1-OHM7kye9zSJtuIn7cjpu/RYubiw=", "dev": true, "license": "MIT" }, "node_modules/undici-types": { "version": "7.24.6", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/undici-types/-/undici-types-7.24.6.tgz", "integrity": "sha1-YSdbSF1/1OnSacfPBOwoc8nMD5E=", "dev": true, "license": "MIT" }, "node_modules/uri-js": { "version": "4.4.1", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha1-mxpSWVIlhZ5V9mnZKPiMbFfyp34=", "dev": true, "license": "BSD-2-Clause", @@ -1986,7 +1851,6 @@ }, "node_modules/vscode-jsonrpc": { "version": "8.2.1", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/vscode-jsonrpc/-/vscode-jsonrpc-8.2.1.tgz", "integrity": "sha1-oyLMDx2X95T/2cTNKomKC94JfzQ=", "license": "MIT", "engines": { @@ -1995,7 +1859,6 @@ }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/which/-/which-2.0.2.tgz", "integrity": "sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE=", "dev": true, "license": "ISC", @@ -2011,7 +1874,6 @@ }, "node_modules/word-wrap": { "version": "1.2.5", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha1-0sRcbdT7zmIaZvE2y+Mor9BBCzQ=", "dev": true, "license": "MIT", @@ -2021,7 +1883,6 @@ }, "node_modules/yocto-queue": { "version": "0.1.0", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha1-ApTrPe4FAo0x7hpfosVWpqrxChs=", "dev": true, "license": "MIT",